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},
__anona8aa82380102() 56 {{5, 2}, [](int, int) { return 73; }, -1, 73, 73},
__anona8aa82380202() 57 {{2, 3, 7}, [](int l, int r) { return l * r; }, -1, 42, 42},
__anona8aa82380302() 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) {
__anona8aa82380402(std::string toQuote) 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>
checkBinaryEqual(T1 v1,T2 v2)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