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 create(Config && configFile)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 { WarningPFparameterFramework::WarningPF126 WarningPF() : ParameterFramework{{&Config::domains, "<InvalidDomain/>"}} 127 { 128 setFailureOnFailedSettingsLoad(false); 129 } 130 }; 131 } 132