xref: /aosp_15_r20/external/parameter-framework/upstream/utility/test/utility.cpp (revision c33452fb792a5495ec310a9626f2638b053af5dd)
1*c33452fbSAndroid Build Coastguard Worker /*
2*c33452fbSAndroid Build Coastguard Worker  * Copyright (c) 2011-2014, Intel Corporation
3*c33452fbSAndroid Build Coastguard Worker  * All rights reserved.
4*c33452fbSAndroid Build Coastguard Worker  *
5*c33452fbSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without modification,
6*c33452fbSAndroid Build Coastguard Worker  * are permitted provided that the following conditions are met:
7*c33452fbSAndroid Build Coastguard Worker  *
8*c33452fbSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright notice, this
9*c33452fbSAndroid Build Coastguard Worker  * list of conditions and the following disclaimer.
10*c33452fbSAndroid Build Coastguard Worker  *
11*c33452fbSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright notice,
12*c33452fbSAndroid Build Coastguard Worker  * this list of conditions and the following disclaimer in the documentation and/or
13*c33452fbSAndroid Build Coastguard Worker  * other materials provided with the distribution.
14*c33452fbSAndroid Build Coastguard Worker  *
15*c33452fbSAndroid Build Coastguard Worker  * 3. Neither the name of the copyright holder nor the names of its contributors
16*c33452fbSAndroid Build Coastguard Worker  * may be used to endorse or promote products derived from this software without
17*c33452fbSAndroid Build Coastguard Worker  * specific prior written permission.
18*c33452fbSAndroid Build Coastguard Worker  *
19*c33452fbSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20*c33452fbSAndroid Build Coastguard Worker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21*c33452fbSAndroid Build Coastguard Worker  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22*c33452fbSAndroid Build Coastguard Worker  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23*c33452fbSAndroid Build Coastguard Worker  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24*c33452fbSAndroid Build Coastguard Worker  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25*c33452fbSAndroid Build Coastguard Worker  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26*c33452fbSAndroid Build Coastguard Worker  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27*c33452fbSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28*c33452fbSAndroid Build Coastguard Worker  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*c33452fbSAndroid Build Coastguard Worker  */
30*c33452fbSAndroid Build Coastguard Worker 
31*c33452fbSAndroid Build Coastguard Worker #include "Utility.h"
32*c33452fbSAndroid Build Coastguard Worker #include "BinaryCopy.hpp"
33*c33452fbSAndroid Build Coastguard Worker 
34*c33452fbSAndroid Build Coastguard Worker #include <catch.hpp>
35*c33452fbSAndroid Build Coastguard Worker #include <functional>
36*c33452fbSAndroid Build Coastguard Worker #include <map>
37*c33452fbSAndroid Build Coastguard Worker 
38*c33452fbSAndroid Build Coastguard Worker using std::list;
39*c33452fbSAndroid Build Coastguard Worker using std::string;
40*c33452fbSAndroid Build Coastguard Worker 
41*c33452fbSAndroid Build Coastguard Worker namespace utility
42*c33452fbSAndroid Build Coastguard Worker {
43*c33452fbSAndroid Build Coastguard Worker 
44*c33452fbSAndroid Build Coastguard Worker SCENARIO("join<int>")
45*c33452fbSAndroid Build Coastguard Worker {
46*c33452fbSAndroid Build Coastguard Worker     struct Test
47*c33452fbSAndroid Build Coastguard Worker     {
48*c33452fbSAndroid Build Coastguard Worker         list<int> input;
49*c33452fbSAndroid Build Coastguard Worker         std::function<int(int, int)> binaryOpt;
50*c33452fbSAndroid Build Coastguard Worker         int empty;
51*c33452fbSAndroid Build Coastguard Worker         int result;
52*c33452fbSAndroid Build Coastguard Worker         int resultNoEmpty;
53*c33452fbSAndroid Build Coastguard Worker     };
54*c33452fbSAndroid Build Coastguard Worker     const list<Test> tests = {{{}, nullptr, 21, 21, 0},
55*c33452fbSAndroid Build Coastguard Worker                               {{5}, nullptr, -1, 5, 5},
__anonece532a90102() 56*c33452fbSAndroid Build Coastguard Worker                               {{5, 2}, [](int, int) { return 73; }, -1, 73, 73},
__anonece532a90202() 57*c33452fbSAndroid Build Coastguard Worker                               {{2, 3, 7}, [](int l, int r) { return l * r; }, -1, 42, 42},
__anonece532a90302() 58*c33452fbSAndroid Build Coastguard Worker                               {{1, 10, 100}, [](int l, int r) { return l + r; }, -1, 111, 111}};
59*c33452fbSAndroid Build Coastguard Worker     for (auto &test : tests) {
60*c33452fbSAndroid Build Coastguard Worker         CAPTURE(Catch::toString(test.input));
61*c33452fbSAndroid Build Coastguard Worker         const auto &first = begin(test.input);
62*c33452fbSAndroid Build Coastguard Worker         const auto &last = end(test.input);
63*c33452fbSAndroid Build Coastguard Worker         REQUIRE(join(first, last, test.binaryOpt, test.empty) == test.result);
64*c33452fbSAndroid Build Coastguard Worker         REQUIRE(join<int>(first, last, test.binaryOpt) == test.resultNoEmpty);
65*c33452fbSAndroid Build Coastguard Worker     }
66*c33452fbSAndroid Build Coastguard Worker }
67*c33452fbSAndroid Build Coastguard Worker 
68*c33452fbSAndroid Build Coastguard Worker SCENARIO("asString(list)")
69*c33452fbSAndroid Build Coastguard Worker {
70*c33452fbSAndroid Build Coastguard Worker     struct Test
71*c33452fbSAndroid Build Coastguard Worker     {
72*c33452fbSAndroid Build Coastguard Worker         string title;
73*c33452fbSAndroid Build Coastguard Worker         list<string> input;
74*c33452fbSAndroid Build Coastguard Worker         string separator;
75*c33452fbSAndroid Build Coastguard Worker         string result;
76*c33452fbSAndroid Build Coastguard Worker         string resultNoSep;
77*c33452fbSAndroid Build Coastguard Worker     };
78*c33452fbSAndroid Build Coastguard Worker     const list<Test> tests = {
79*c33452fbSAndroid Build Coastguard Worker         {"Empty list", {}, "aa", "", ""},
80*c33452fbSAndroid Build Coastguard Worker         {"One element", {"a"}, "<>", "a", "a"},
81*c33452fbSAndroid Build Coastguard Worker         {"Three elem list", {"1", "2", "3"}, "**", "1**2**3", "1\n2\n3"},
82*c33452fbSAndroid Build Coastguard Worker         {"No separator", {"12", "ab", "+-"}, "", "12ab+-", "12\nab\n+-"},
83*c33452fbSAndroid Build Coastguard Worker         {"empty elem list", {"a", "b", "", "d"}, "|", "a|b||d", "a\nb\n\nd"},
84*c33452fbSAndroid Build Coastguard Worker     };
85*c33452fbSAndroid Build Coastguard Worker     for (auto &test : tests) {
86*c33452fbSAndroid Build Coastguard Worker         CAPTURE(Catch::toString(test.input));
87*c33452fbSAndroid Build Coastguard Worker         WHEN ("Separator, " + test.title) {
88*c33452fbSAndroid Build Coastguard Worker             CAPTURE(test.separator);
89*c33452fbSAndroid Build Coastguard Worker             REQUIRE(asString(test.input, test.separator) == test.result);
90*c33452fbSAndroid Build Coastguard Worker         }
91*c33452fbSAndroid Build Coastguard Worker         THEN ("No separator, " + test.title) {
92*c33452fbSAndroid Build Coastguard Worker             REQUIRE(asString(test.input) == test.resultNoSep);
93*c33452fbSAndroid Build Coastguard Worker         }
94*c33452fbSAndroid Build Coastguard Worker     }
95*c33452fbSAndroid Build Coastguard Worker }
96*c33452fbSAndroid Build Coastguard Worker 
97*c33452fbSAndroid Build Coastguard Worker SCENARIO("asString(map)")
98*c33452fbSAndroid Build Coastguard Worker {
99*c33452fbSAndroid Build Coastguard Worker     using std::map;
100*c33452fbSAndroid Build Coastguard Worker 
101*c33452fbSAndroid Build Coastguard Worker     using Map = map<string, string>;
102*c33452fbSAndroid Build Coastguard Worker     struct Test
103*c33452fbSAndroid Build Coastguard Worker     {
104*c33452fbSAndroid Build Coastguard Worker         Map input;
105*c33452fbSAndroid Build Coastguard Worker         string itemSep;
106*c33452fbSAndroid Build Coastguard Worker         string keyValueSep;
107*c33452fbSAndroid Build Coastguard Worker         string result;
108*c33452fbSAndroid Build Coastguard Worker         string resultNoKeyValueSep;
109*c33452fbSAndroid Build Coastguard Worker         string resultNoSep;
110*c33452fbSAndroid Build Coastguard Worker     };
111*c33452fbSAndroid Build Coastguard Worker     const list<Test> tests = {{{}, "itemSep", "keyValueSep", "", "", ""},
112*c33452fbSAndroid Build Coastguard Worker                               {
113*c33452fbSAndroid Build Coastguard Worker                                   Map{{"a", "b"}, {"c", "d"}, {"e", "f"}}, // input
114*c33452fbSAndroid Build Coastguard Worker                                   " - ", "\n",                             // item & keyValue sep
115*c33452fbSAndroid Build Coastguard Worker                                   "a - b\nc - d\ne - f",                   // result
116*c33452fbSAndroid Build Coastguard Worker                                   "a:b\nc:d\ne:f",                         // resultNoKeyValueSep
117*c33452fbSAndroid Build Coastguard Worker                                   "a:b, c:d, e:f"                          // resultNoSep
118*c33452fbSAndroid Build Coastguard Worker                               }};
119*c33452fbSAndroid Build Coastguard Worker     for (const auto &test : tests) {
120*c33452fbSAndroid Build Coastguard Worker         CAPTURE(Catch::toString(test.input));
121*c33452fbSAndroid Build Coastguard Worker         CAPTURE(test.keyValueSep);
122*c33452fbSAndroid Build Coastguard Worker         CAPTURE(test.itemSep);
123*c33452fbSAndroid Build Coastguard Worker         REQUIRE(asString(test.input, test.keyValueSep, test.itemSep) == test.result);
124*c33452fbSAndroid Build Coastguard Worker         REQUIRE(asString(test.input, test.keyValueSep) == test.resultNoKeyValueSep);
125*c33452fbSAndroid Build Coastguard Worker         REQUIRE(asString(test.input) == test.resultNoSep);
126*c33452fbSAndroid Build Coastguard Worker     }
127*c33452fbSAndroid Build Coastguard Worker }
128*c33452fbSAndroid Build Coastguard Worker 
129*c33452fbSAndroid Build Coastguard Worker SCENARIO("appendTitle")
130*c33452fbSAndroid Build Coastguard Worker {
131*c33452fbSAndroid Build Coastguard Worker     struct Test
132*c33452fbSAndroid Build Coastguard Worker     {
133*c33452fbSAndroid Build Coastguard Worker         string initial;
134*c33452fbSAndroid Build Coastguard Worker         string title;
135*c33452fbSAndroid Build Coastguard Worker         string result;
136*c33452fbSAndroid Build Coastguard Worker     };
137*c33452fbSAndroid Build Coastguard Worker     const list<Test> tests = {{"", "abc", "\nabc\n===\n"},
138*c33452fbSAndroid Build Coastguard Worker                               {"start", "title", "start\ntitle\n=====\n"}};
139*c33452fbSAndroid Build Coastguard Worker     for (auto &test : tests) {
__anonece532a90402(std::string toQuote) 140*c33452fbSAndroid Build Coastguard Worker         auto quote = [](std::string toQuote) { return '"' + toQuote + '"'; };
141*c33452fbSAndroid Build Coastguard Worker 
142*c33452fbSAndroid Build Coastguard Worker         GIVEN ("A title: " + quote(test.title)) {
143*c33452fbSAndroid Build Coastguard Worker             CAPTURE(test.initial);
144*c33452fbSAndroid Build Coastguard Worker             CAPTURE(test.title);
145*c33452fbSAndroid Build Coastguard Worker 
146*c33452fbSAndroid Build Coastguard Worker             WHEN ("Appending to: " + quote(test.initial)) {
147*c33452fbSAndroid Build Coastguard Worker                 string output = test.initial;
148*c33452fbSAndroid Build Coastguard Worker                 THEN ("Result should be:\n" + quote(test.result)) {
149*c33452fbSAndroid Build Coastguard Worker                     appendTitle(output, test.title);
150*c33452fbSAndroid Build Coastguard Worker                     CHECK(output == test.result);
151*c33452fbSAndroid Build Coastguard Worker                 }
152*c33452fbSAndroid Build Coastguard Worker             }
153*c33452fbSAndroid Build Coastguard Worker         }
154*c33452fbSAndroid Build Coastguard Worker     }
155*c33452fbSAndroid Build Coastguard Worker }
156*c33452fbSAndroid Build Coastguard Worker 
157*c33452fbSAndroid Build Coastguard Worker SCENARIO("isNotHexadecimal")
158*c33452fbSAndroid Build Coastguard Worker {
159*c33452fbSAndroid Build Coastguard Worker     for (auto &str : {"a", "0", "012", "13", "ABC", "Oxa"}) {
160*c33452fbSAndroid Build Coastguard Worker         CAPTURE(str);
161*c33452fbSAndroid Build Coastguard Worker         CHECK(not isHexadecimal(str));
162*c33452fbSAndroid Build Coastguard Worker     }
163*c33452fbSAndroid Build Coastguard Worker }
164*c33452fbSAndroid Build Coastguard Worker 
165*c33452fbSAndroid Build Coastguard Worker SCENARIO("isHexadecimal")
166*c33452fbSAndroid Build Coastguard Worker {
167*c33452fbSAndroid Build Coastguard Worker     for (auto str : {"0xa", "0X0", "0x012", "0x13", "0xConsider as hexa as starting with 0x"}) {
168*c33452fbSAndroid Build Coastguard Worker         CAPTURE(str);
169*c33452fbSAndroid Build Coastguard Worker         CHECK(isHexadecimal(str));
170*c33452fbSAndroid Build Coastguard Worker     }
171*c33452fbSAndroid Build Coastguard Worker }
172*c33452fbSAndroid Build Coastguard Worker 
173*c33452fbSAndroid Build Coastguard Worker template <class T1, class T2>
checkBinaryEqual(T1 v1,T2 v2)174*c33452fbSAndroid Build Coastguard Worker void checkBinaryEqual(T1 v1, T2 v2)
175*c33452fbSAndroid Build Coastguard Worker {
176*c33452fbSAndroid Build Coastguard Worker     // For some yet-unknown reason, GCC 4.8 complains about
177*c33452fbSAndroid Build Coastguard Worker     //     CHECK(a == b);
178*c33452fbSAndroid Build Coastguard Worker     // and suggests that parentheses should be added. This is related to catch
179*c33452fbSAndroid Build Coastguard Worker     // internals but such construcuts have been used without problem in lots of
180*c33452fbSAndroid Build Coastguard Worker     // other places...
181*c33452fbSAndroid Build Coastguard Worker     // Besides, GCC 4.9 does not seem to have a problem with that either.
182*c33452fbSAndroid Build Coastguard Worker     // As a workaround, captures variables and parenthesize the expressions.
183*c33452fbSAndroid Build Coastguard Worker 
184*c33452fbSAndroid Build Coastguard Worker     auto v2AsT1 = utility::binaryCopy<T1>(v2);
185*c33452fbSAndroid Build Coastguard Worker     CAPTURE(v1);
186*c33452fbSAndroid Build Coastguard Worker     CAPTURE(v2AsT1);
187*c33452fbSAndroid Build Coastguard Worker     CHECK((v1 == v2AsT1));
188*c33452fbSAndroid Build Coastguard Worker 
189*c33452fbSAndroid Build Coastguard Worker     auto v1AsT2 = utility::binaryCopy<T2>(v1);
190*c33452fbSAndroid Build Coastguard Worker     CAPTURE(v2);
191*c33452fbSAndroid Build Coastguard Worker     CAPTURE(v1AsT2);
192*c33452fbSAndroid Build Coastguard Worker     CHECK((v2 == v1AsT2));
193*c33452fbSAndroid Build Coastguard Worker }
194*c33452fbSAndroid Build Coastguard Worker 
195*c33452fbSAndroid Build Coastguard Worker SCENARIO("binaryCopy bit exactness")
196*c33452fbSAndroid Build Coastguard Worker {
197*c33452fbSAndroid Build Coastguard Worker     GIVEN ("Integer representations computed using http://babbage.cs.qc.cuny.edu/IEEE-754/") {
198*c33452fbSAndroid Build Coastguard Worker 
199*c33452fbSAndroid Build Coastguard Worker         THEN ("Floats should be coded on 32bits and fulfill IEEE-754."
200*c33452fbSAndroid Build Coastguard Worker               " That assumption is made in the Parameter Framework.") {
201*c33452fbSAndroid Build Coastguard Worker             REQUIRE(sizeof(float) == sizeof(uint32_t));
202*c33452fbSAndroid Build Coastguard Worker             REQUIRE(std::numeric_limits<float>::is_iec559);
203*c33452fbSAndroid Build Coastguard Worker         }
204*c33452fbSAndroid Build Coastguard Worker         WHEN ("Testing float <=> uint32_t conversion") {
205*c33452fbSAndroid Build Coastguard Worker             checkBinaryEqual<float, uint32_t>(1.23456f, 0x3f9e0610);
206*c33452fbSAndroid Build Coastguard Worker         }
207*c33452fbSAndroid Build Coastguard Worker 
208*c33452fbSAndroid Build Coastguard Worker         THEN ("Doubles should be coded on 64bits and fulfill IEEE-754."
209*c33452fbSAndroid Build Coastguard Worker               " That assumption is made in the Parameter Framework.") {
210*c33452fbSAndroid Build Coastguard Worker             REQUIRE(sizeof(double) == sizeof(uint64_t));
211*c33452fbSAndroid Build Coastguard Worker             REQUIRE(std::numeric_limits<double>::is_iec559);
212*c33452fbSAndroid Build Coastguard Worker         }
213*c33452fbSAndroid Build Coastguard Worker         WHEN ("Testing double <=> uint64_t conversion") {
214*c33452fbSAndroid Build Coastguard Worker             checkBinaryEqual<double, uint64_t>(987.65432109876, 0x408edd3c0cb3420e);
215*c33452fbSAndroid Build Coastguard Worker         }
216*c33452fbSAndroid Build Coastguard Worker     }
217*c33452fbSAndroid Build Coastguard Worker 
218*c33452fbSAndroid Build Coastguard Worker     WHEN ("Testing int8_t <=> uint8_t conversion") {
219*c33452fbSAndroid Build Coastguard Worker         checkBinaryEqual<int8_t, uint8_t>(-1, 0xff);
220*c33452fbSAndroid Build Coastguard Worker     }
221*c33452fbSAndroid Build Coastguard Worker }
222*c33452fbSAndroid Build Coastguard Worker 
223*c33452fbSAndroid Build Coastguard Worker } // namespace utility
224