Home | History | Annotate | Download | only in test
      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