Home | History | Annotate | Download | only in include
      1 /*
      2  * Copyright (c) 2015, Intel Corporation
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without modification,
      6  * are permitted provided that the following conditions are met:
      7  *
      8  * 1. Redistributions of source code must retain the above copyright notice, this
      9  * list of conditions and the following disclaimer.
     10  *
     11  * 2. Redistributions in binary form must reproduce the above copyright notice,
     12  * this list of conditions and the following disclaimer in the documentation and/or
     13  * other materials provided with the distribution.
     14  *
     15  * 3. Neither the name of the copyright holder nor the names of its contributors
     16  * may be used to endorse or promote products derived from this software without
     17  * specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
     23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #pragma once
     32 
     33 #include "Config.hpp"
     34 #include "ParameterFramework.hpp"
     35 
     36 #include <catch.hpp>
     37 
     38 #include <string>
     39 
     40 #ifndef SCENARIO_METHOD
     41 /** SCENARIO_METHOD is not available in catch on ubuntu 12.04 */
     42 #define SCENARIO_METHOD(className, ...) TEST_CASE_METHOD(className, "Scenario: " __VA_ARGS__)
     43 #endif
     44 
     45 namespace parameterFramework
     46 {
     47 
     48 /** Value to test with a title.
     49  *
     50  * When testing code it is often useful to have an list of possible
     51  * values and run the test for each of them.
     52  * This class represents one element of this list. For the complete list
     53  * see Tests.
     54  *
     55  * Catch has no build-in support for such need
     56  * (in fact it has but it is still experimental, look for "generators")
     57  * but it can be emulated with a loop over Tests.
     58  *
     59  * Each Test MUST specify a unique title, Ie all titles of a Tests MUST
     60  * be different. This is dued to the way that catch detects that a SECTION
     61  * has already been run. For more explanation see Tests.
     62  */
     63 template <class Value>
     64 struct Test
     65 {
     66     std::string title;
     67     Value payload;
     68 };
     69 
     70 /** Use a vector to represent a collection of test input.
     71  *
     72  * This type is designed to be used to parametrize tests.
     73  * Use it as follow:
     74  *     for (auto &test : Tests<std::string>{
     75  *     //                      ^~~~~~~~~~~ Test parameter type
     76  *             {"an invalid tag", "<invalid tag\"/> "},
     77  *           //^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Test parameters
     78  *             {"an unknown tag", "<unknown_tag/>"},
     79  *           // ^~~~~~~~~~~~~~~~ Unique title across the tests
     80  *             {"an unclosed tag", "<unclosed>"} }) {
     81  *           //                    ^~~~~~~~~~~ Value to test
     82  *         SECTION("Testing: " + test.title) {
     83  *         //                     ^~~~~~~~~~ Section title MUST unique
     84  *            test.payload //< value to test
     85  *            REQUIRE(getTag() != test.payload); // Example
     86  *            ...
     87  *         }
     88  *     }
     89  *
     90  *
     91  * Beware that if Value is not copyable, only movable this will
     92  * fail to compile as initializer_list does not support move semantic
     93  * (lets hope it will be fix in C++17).
     94  *
     95  * If a new test vector needs to support move, define:
     96  *     template <class Value>
     97  *     using MovableTests = Test<value>[];
     98  * This could be the default but VS2013 does not support it.
     99  * VS requires that an array size be defined. Thus define
    100  *     template <class Value, size_t size>
    101  *     using MovableTests = Test<value>[size];
    102  * will fix the VS compilation. Nevertheless this means that
    103  * all move only test vector will need to specify their size
    104  * which is redondant.
    105  * This is why it is not the default.
    106  * Hopefully it will be when VS will support deducing the size.
    107  */
    108 template <class Value>
    109 using Tests = std::vector<Test<Value>>;
    110 
    111 /** Defer Parameter Framework creation.
    112  * A custom configuration can be provided.
    113  */
    114 class LazyPF
    115 {
    116 public:
    117     using PF = ParameterFramework;
    118 
    119     void create(Config &&configFile) { mPf.reset(new PF{std::move(configFile)}); }
    120     std::unique_ptr<PF> mPf;
    121 };
    122 
    123 /** PF that will log a warning at start. */
    124 struct WarningPF : public ParameterFramework
    125 {
    126     WarningPF() : ParameterFramework{{&Config::domains, "<InvalidDomain/>"}}
    127     {
    128         setFailureOnFailedSettingsLoad(false);
    129     }
    130 };
    131 } // namespace parameterFramework
    132