1 /* 2 * Copyright (c) 2011-2014, 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 #include "Utility.h" 32 #include "BinaryCopy.hpp" 33 34 #include <catch.hpp> 35 #include <functional> 36 #include <map> 37 38 using std::list; 39 using std::string; 40 41 namespace utility 42 { 43 44 SCENARIO("join<int>") 45 { 46 struct Test 47 { 48 list<int> input; 49 std::function<int(int, int)> binaryOpt; 50 int empty; 51 int result; 52 int resultNoEmpty; 53 }; 54 const list<Test> tests = {{{}, nullptr, 21, 21, 0}, 55 {{5}, nullptr, -1, 5, 5}, 56 {{5, 2}, [](int, int) { return 73; }, -1, 73, 73}, 57 {{2, 3, 7}, [](int l, int r) { return l * r; }, -1, 42, 42}, 58 {{1, 10, 100}, [](int l, int r) { return l + r; }, -1, 111, 111}}; 59 for (auto &test : tests) { 60 CAPTURE(Catch::toString(test.input)); 61 const auto &first = begin(test.input); 62 const auto &last = end(test.input); 63 REQUIRE(join(first, last, test.binaryOpt, test.empty) == test.result); 64 REQUIRE(join<int>(first, last, test.binaryOpt) == test.resultNoEmpty); 65 } 66 } 67 68 SCENARIO("asString(list)") 69 { 70 struct Test 71 { 72 string title; 73 list<string> input; 74 string separator; 75 string result; 76 string resultNoSep; 77 }; 78 const list<Test> tests = { 79 {"Empty list", {}, "aa", "", ""}, 80 {"One element", {"a"}, "<>", "a", "a"}, 81 {"Three elem list", {"1", "2", "3"}, "**", "1**2**3", "1\n2\n3"}, 82 {"No separator", {"12", "ab", "+-"}, "", "12ab+-", "12\nab\n+-"}, 83 {"empty elem list", {"a", "b", "", "d"}, "|", "a|b||d", "a\nb\n\nd"}, 84 }; 85 for (auto &test : tests) { 86 CAPTURE(Catch::toString(test.input)); 87 WHEN ("Separator, " + test.title) { 88 CAPTURE(test.separator); 89 REQUIRE(asString(test.input, test.separator) == test.result); 90 } 91 THEN ("No separator, " + test.title) { 92 REQUIRE(asString(test.input) == test.resultNoSep); 93 } 94 } 95 } 96 97 SCENARIO("asString(map)") 98 { 99 using std::map; 100 101 using Map = map<string, string>; 102 struct Test 103 { 104 Map input; 105 string itemSep; 106 string keyValueSep; 107 string result; 108 string resultNoKeyValueSep; 109 string resultNoSep; 110 }; 111 const list<Test> tests = {{{}, "itemSep", "keyValueSep", "", "", ""}, 112 { 113 Map{{"a", "b"}, {"c", "d"}, {"e", "f"}}, // input 114 " - ", "\n", // item & keyValue sep 115 "a - b\nc - d\ne - f", // result 116 "a:b\nc:d\ne:f", // resultNoKeyValueSep 117 "a:b, c:d, e:f" // resultNoSep 118 }}; 119 for (const auto &test : tests) { 120 CAPTURE(Catch::toString(test.input)); 121 CAPTURE(test.keyValueSep); 122 CAPTURE(test.itemSep); 123 REQUIRE(asString(test.input, test.keyValueSep, test.itemSep) == test.result); 124 REQUIRE(asString(test.input, test.keyValueSep) == test.resultNoKeyValueSep); 125 REQUIRE(asString(test.input) == test.resultNoSep); 126 } 127 } 128 129 SCENARIO("appendTitle") 130 { 131 struct Test 132 { 133 string initial; 134 string title; 135 string result; 136 }; 137 const list<Test> tests = {{"", "abc", "\nabc\n===\n"}, 138 {"start", "title", "start\ntitle\n=====\n"}}; 139 for (auto &test : tests) { 140 auto quote = [](std::string toQuote) { return '"' + toQuote + '"'; }; 141 142 GIVEN ("A title: " + quote(test.title)) { 143 CAPTURE(test.initial); 144 CAPTURE(test.title); 145 146 WHEN ("Appending to: " + quote(test.initial)) { 147 string output = test.initial; 148 THEN ("Result should be:\n" + quote(test.result)) { 149 appendTitle(output, test.title); 150 CHECK(output == test.result); 151 } 152 } 153 } 154 } 155 } 156 157 SCENARIO("isNotHexadecimal") 158 { 159 for (auto &str : {"a", "0", "012", "13", "ABC", "Oxa"}) { 160 CAPTURE(str); 161 CHECK(not isHexadecimal(str)); 162 } 163 } 164 165 SCENARIO("isHexadecimal") 166 { 167 for (auto str : {"0xa", "0X0", "0x012", "0x13", "0xConsider as hexa as starting with 0x"}) { 168 CAPTURE(str); 169 CHECK(isHexadecimal(str)); 170 } 171 } 172 173 template <class T1, class T2> 174 void checkBinaryEqual(T1 v1, T2 v2) 175 { 176 // For some yet-unknown reason, GCC 4.8 complains about 177 // CHECK(a == b); 178 // and suggests that parentheses should be added. This is related to catch 179 // internals but such construcuts have been used without problem in lots of 180 // other places... 181 // Besides, GCC 4.9 does not seem to have a problem with that either. 182 // As a workaround, captures variables and parenthesize the expressions. 183 184 auto v2AsT1 = utility::binaryCopy<T1>(v2); 185 CAPTURE(v1); 186 CAPTURE(v2AsT1); 187 CHECK((v1 == v2AsT1)); 188 189 auto v1AsT2 = utility::binaryCopy<T2>(v1); 190 CAPTURE(v2); 191 CAPTURE(v1AsT2); 192 CHECK((v2 == v1AsT2)); 193 } 194 195 SCENARIO("binaryCopy bit exactness") 196 { 197 GIVEN ("Integer representations computed using http://babbage.cs.qc.cuny.edu/IEEE-754/") { 198 199 THEN ("Floats should be coded on 32bits and fulfill IEEE-754." 200 " That assumption is made in the Parameter Framework.") { 201 REQUIRE(sizeof(float) == sizeof(uint32_t)); 202 REQUIRE(std::numeric_limits<float>::is_iec559); 203 } 204 WHEN ("Testing float <=> uint32_t conversion") { 205 checkBinaryEqual<float, uint32_t>(1.23456f, 0x3f9e0610); 206 } 207 208 THEN ("Doubles should be coded on 64bits and fulfill IEEE-754." 209 " That assumption is made in the Parameter Framework.") { 210 REQUIRE(sizeof(double) == sizeof(uint64_t)); 211 REQUIRE(std::numeric_limits<double>::is_iec559); 212 } 213 WHEN ("Testing double <=> uint64_t conversion") { 214 checkBinaryEqual<double, uint64_t>(987.65432109876, 0x408edd3c0cb3420e); 215 } 216 } 217 218 WHEN ("Testing int8_t <=> uint8_t conversion") { 219 checkBinaryEqual<int8_t, uint8_t>(-1, 0xff); 220 } 221 } 222 223 } // namespace utility 224