LCOV - code coverage report
Current view: top level - tests - catch_pbql_node.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 98.7 % 668 659
Test Date: 2025-06-19 11:28:46 Functions: 100.0 % 2 2
Legend: Lines: hit not hit

            Line data    Source code
       1              : // Copyright (c) 2019-2025  Made to Order Software Corp.  All Rights Reserved
       2              : //
       3              : // https://snapwebsites.org/project/prinbee
       4              : // contact@m2osw.com
       5              : //
       6              : // This program is free software: you can redistribute it and/or modify
       7              : // it under the terms of the GNU General Public License as published by
       8              : // the Free Software Foundation, either version 3 of the License, or
       9              : // (at your option) any later version.
      10              : //
      11              : // This program is distributed in the hope that it will be useful,
      12              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : // GNU General Public License for more details.
      15              : //
      16              : // You should have received a copy of the GNU General Public License
      17              : // along with this program.  If not, see <https://www.gnu.org/licenses/>.
      18              : 
      19              : // prinbee
      20              : //
      21              : #include    <prinbee/pbql/node.h>
      22              : 
      23              : #include    <prinbee/exception.h>
      24              : 
      25              : 
      26              : // self
      27              : //
      28              : #include    "catch_main.h"
      29              : 
      30              : 
      31              : // snaplogger
      32              : //
      33              : #include    <snaplogger/message.h>
      34              : 
      35              : 
      36              : // snapdev
      37              : //
      38              : #include    <snapdev/floating_point_to_string.h>
      39              : 
      40              : 
      41              : // last include
      42              : //
      43              : #include    <snapdev/poison.h>
      44              : 
      45              : 
      46              : 
      47              : namespace
      48              : {
      49              : 
      50              : 
      51              : 
      52              : 
      53              : 
      54              : } // no name namespace
      55              : 
      56              : 
      57              : 
      58           13 : CATCH_TEST_CASE("node", "[node][pbql]")
      59              : {
      60           15 :     CATCH_START_SECTION("node: verify defaults")
      61              :     {
      62            1 :         prinbee::pbql::location l;
      63            1 :         std::string const filename(SNAP_CATCH2_NAMESPACE::random_string(1, 25));
      64            1 :         l.set_filename(filename);
      65              : 
      66            1 :         unsigned int line(0);
      67            1 :         SNAP_CATCH2_NAMESPACE::random(line);
      68            1 :         line %= 100;
      69           22 :         for(unsigned int idx(0); idx < line; ++idx)
      70              :         {
      71           21 :             l.next_line();
      72              :         }
      73            1 :         ++line;
      74              : 
      75            1 :         unsigned int column(0);
      76            1 :         SNAP_CATCH2_NAMESPACE::random(column);
      77            1 :         column %= 90;
      78            3 :         for(unsigned int idx(0); idx < column; ++idx)
      79              :         {
      80            2 :             l.next_column();
      81              :         }
      82            1 :         ++column;
      83              : 
      84            1 :         prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_IDENTIFIER, l));
      85              : 
      86            1 :         CATCH_REQUIRE(n->get_token() == prinbee::pbql::token_t::TOKEN_IDENTIFIER);
      87              : 
      88            1 :         prinbee::pbql::location const & loc(n->get_location());
      89            1 :         CATCH_REQUIRE(loc.get_filename() == filename);
      90            1 :         CATCH_REQUIRE(loc.get_column() == static_cast<int>(column));
      91            1 :         CATCH_REQUIRE(loc.get_line() == static_cast<int>(line));
      92              : 
      93            1 :         CATCH_REQUIRE(n->get_string() == std::string());
      94            1 :         CATCH_REQUIRE(n->get_integer() == prinbee::int512_t());
      95            1 :         CATCH_REQUIRE(SNAP_CATCH2_NAMESPACE::nearly_equal(n->get_floating_point(), 0.0L, 0.0L));
      96            1 :         CATCH_REQUIRE(n->get_parent() == nullptr);
      97            1 :         CATCH_REQUIRE(n->get_children_size() == 0);
      98            1 :     }
      99           14 :     CATCH_END_SECTION()
     100              : 
     101           15 :     CATCH_START_SECTION("node: verify string")
     102              :     {
     103            1 :         prinbee::pbql::location l;
     104            1 :         prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_IDENTIFIER, l));
     105              : 
     106           11 :         for(int i(0); i < 10; ++i)
     107              :         {
     108           10 :             std::string const identifier(SNAP_CATCH2_NAMESPACE::random_string(1, 25));
     109           10 :             n->set_string(identifier);
     110           10 :             CATCH_REQUIRE(n->get_string() == identifier);
     111           10 :         }
     112            1 :     }
     113           14 :     CATCH_END_SECTION()
     114              : 
     115           15 :     CATCH_START_SECTION("node: verify integer")
     116              :     {
     117            1 :         prinbee::pbql::location l;
     118            1 :         prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_IDENTIFIER, l));
     119              : 
     120           11 :         for(int i(0); i < 10; ++i)
     121              :         {
     122           10 :             prinbee::int512_t a;
     123           10 :             SNAP_CATCH2_NAMESPACE::rand512(a);
     124           10 :             n->set_integer(a);
     125           10 :             CATCH_REQUIRE(n->get_integer() == a);
     126              :         }
     127            1 :     }
     128           14 :     CATCH_END_SECTION()
     129              : 
     130           15 :     CATCH_START_SECTION("node: verify floating point")
     131              :     {
     132            1 :         prinbee::pbql::location l;
     133            1 :         prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_IDENTIFIER, l));
     134              : 
     135           11 :         for(int i(0); i < 10; ++i)
     136              :         {
     137           10 :             double const a(drand48());
     138           10 :             n->set_floating_point(a);
     139           10 :             CATCH_REQUIRE(SNAP_CATCH2_NAMESPACE::nearly_equal(n->get_floating_point(), static_cast<long double>(a), 0.0L));
     140              :         }
     141            1 :     }
     142           14 :     CATCH_END_SECTION()
     143              : 
     144           15 :     CATCH_START_SECTION("node: verify cast types")
     145              :     {
     146              :         struct type_name_t
     147              :         {
     148              :             prinbee::pbql::type_t   f_type = static_cast<prinbee::pbql::type_t>(-1);
     149              :             char const *            f_name = nullptr;
     150              :         };
     151              : 
     152            1 :         type_name_t names[] =
     153              :         {
     154              :             { prinbee::pbql::type_t::TYPE_BOOLEAN,          "Boolean"   },
     155              :             { prinbee::pbql::type_t::TYPE_INT1,             "Integer"   },
     156              :             { prinbee::pbql::type_t::TYPE_INT2,             "Integer"   },
     157              :             { prinbee::pbql::type_t::TYPE_INT4,             "Integer"   },
     158              :             { prinbee::pbql::type_t::TYPE_INT8,             "Integer"   },
     159              :             { prinbee::pbql::type_t::TYPE_INT16,            "Integer"   },
     160              :             { prinbee::pbql::type_t::TYPE_INT32,            "Integer"   },
     161              :             { prinbee::pbql::type_t::TYPE_INT64,            "Integer"   },
     162              :             { prinbee::pbql::type_t::TYPE_UNSIGNED_INT1,    "Integer"   },
     163              :             { prinbee::pbql::type_t::TYPE_UNSIGNED_INT2,    "Integer"   },
     164              :             { prinbee::pbql::type_t::TYPE_UNSIGNED_INT4,    "Integer"   },
     165              :             { prinbee::pbql::type_t::TYPE_UNSIGNED_INT8,    "Integer"   },
     166              :             { prinbee::pbql::type_t::TYPE_UNSIGNED_INT16,   "Integer"   },
     167              :             { prinbee::pbql::type_t::TYPE_UNSIGNED_INT32,   "Integer"   },
     168              :             { prinbee::pbql::type_t::TYPE_UNSIGNED_INT64,   "Integer"   },
     169              :             { prinbee::pbql::type_t::TYPE_FLOAT4,           "Number"    },
     170              :             { prinbee::pbql::type_t::TYPE_FLOAT8,           "Number"    },
     171              :             { prinbee::pbql::type_t::TYPE_FLOAT10,          "Number"    },
     172              :             { prinbee::pbql::type_t::TYPE_TEXT,             "String"    },
     173              :             { static_cast<prinbee::pbql::type_t>(-1),       "undefined" },
     174              :         };
     175              : 
     176           21 :         for(auto const & n : names)
     177              :         {
     178           20 :             char const * name_from_lib(cast_type_to_as2js_type(n.f_type));
     179           20 :             CATCH_REQUIRE(name_from_lib != nullptr);
     180           20 :             CATCH_REQUIRE(strcmp(name_from_lib, n.f_name) == 0);
     181              :         }
     182              :     }
     183           14 :     CATCH_END_SECTION()
     184              : 
     185           15 :     CATCH_START_SECTION("node: verify tree")
     186              :     {
     187            1 :         prinbee::pbql::location l;
     188              : 
     189              :         // prepare nodes
     190              :         //
     191            1 :         prinbee::pbql::node::pointer_t root(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_IDENTIFIER, l));
     192            1 :         prinbee::pbql::node::pointer_t i32(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_INTEGER, l));
     193            1 :         i32->set_integer(32);
     194            1 :         prinbee::pbql::node::pointer_t i54(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_INTEGER, l));
     195            1 :         i54->set_integer(54);
     196            1 :         prinbee::pbql::node::pointer_t plus(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_PLUS, l));
     197              : 
     198              :         // build tree
     199              :         //
     200            1 :         root->insert_child(-1, plus);
     201            1 :         plus->insert_child(-1, i54);
     202            1 :         plus->insert_child(0, i32);    // using the index, we can insert before/after another item
     203              : 
     204            1 :         CATCH_REQUIRE(root->get_children_size() == 1);
     205            1 :         CATCH_REQUIRE(root->get_child(0) == plus);
     206            1 :         CATCH_REQUIRE(plus->get_children_size() == 2);
     207            1 :         CATCH_REQUIRE(plus->get_child(0) == i32);
     208            1 :         CATCH_REQUIRE(plus->get_child(0)->get_integer() == 32UL);
     209            1 :         CATCH_REQUIRE(plus->get_child(1) == i54);
     210            1 :         CATCH_REQUIRE(plus->get_child(1)->get_integer() == 54UL);
     211              : 
     212            1 :         prinbee::pbql::node::pointer_t i1067(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_INTEGER, l));
     213            1 :         i1067->set_integer(1067);
     214            1 :         plus->set_child(0, i1067);    // using the index, we can insert before/after another item
     215              : 
     216            1 :         CATCH_REQUIRE(plus->get_children_size() == 2);
     217            1 :         CATCH_REQUIRE(plus->get_child(0) == i1067);
     218            1 :         CATCH_REQUIRE(plus->get_child(0)->get_integer() == 1067UL);
     219            1 :         CATCH_REQUIRE(plus->get_child(1) == i54);
     220            1 :         CATCH_REQUIRE(plus->get_child(1)->get_integer() == 54UL);
     221            1 :     }
     222           14 :     CATCH_END_SECTION()
     223              : 
     224           15 :     CATCH_START_SECTION("node: check node names")
     225              :     {
     226              :         struct token_name_t
     227              :         {
     228              :             prinbee::pbql::token_t const    f_token = prinbee::pbql::token_t::TOKEN_UNKNOWN;
     229              :             char const * const              f_name = nullptr;
     230              :         };
     231            1 :         token_name_t token_names[] =
     232              :         {
     233              :             { prinbee::pbql::token_t::TOKEN_EOF, "EOF" },
     234              :             { prinbee::pbql::token_t::TOKEN_UNKNOWN, "UNKNOWN" },
     235              :             { prinbee::pbql::token_t::TOKEN_BITWISE_XOR, "#" },
     236              :             { prinbee::pbql::token_t::TOKEN_MODULO, "%" },
     237              :             { prinbee::pbql::token_t::TOKEN_BITWISE_AND, "&" },
     238              :             { prinbee::pbql::token_t::TOKEN_OPEN_PARENTHESIS, "(" },
     239              :             { prinbee::pbql::token_t::TOKEN_CLOSE_PARENTHESIS, ")" },
     240              :             { prinbee::pbql::token_t::TOKEN_MULTIPLY, "*" },
     241              :             { prinbee::pbql::token_t::TOKEN_PLUS, "+" },
     242              :             { prinbee::pbql::token_t::TOKEN_COMMA, "," },
     243              :             { prinbee::pbql::token_t::TOKEN_MINUS, "-" },
     244              :             { prinbee::pbql::token_t::TOKEN_PERIOD, "." },
     245              :             { prinbee::pbql::token_t::TOKEN_DIVIDE, "/" },
     246              :             { prinbee::pbql::token_t::TOKEN_COLON, ":" },
     247              :             { prinbee::pbql::token_t::TOKEN_SEMI_COLON, ";" },
     248              :             { prinbee::pbql::token_t::TOKEN_LESS, "<" },
     249              :             { prinbee::pbql::token_t::TOKEN_EQUAL, "=" },
     250              :             { prinbee::pbql::token_t::TOKEN_GREATER, ">" },
     251              :             { prinbee::pbql::token_t::TOKEN_ABSOLUTE_VALUE, "@" },
     252              :             { prinbee::pbql::token_t::TOKEN_OPEN_BRACKET, "[" },
     253              :             { prinbee::pbql::token_t::TOKEN_CLOSE_BRACKET, "]" },
     254              :             { prinbee::pbql::token_t::TOKEN_POWER, "^" },
     255              :             { prinbee::pbql::token_t::TOKEN_BITWISE_OR, "|" },
     256              :             { prinbee::pbql::token_t::TOKEN_REGULAR_EXPRESSION, "~" },
     257              :             { prinbee::pbql::token_t::TOKEN_IDENTIFIER, "IDENTIFIER" },
     258              :             { prinbee::pbql::token_t::TOKEN_STRING, "STRING" },
     259              :             { prinbee::pbql::token_t::TOKEN_INTEGER, "INTEGER" },
     260              :             { prinbee::pbql::token_t::TOKEN_FLOATING_POINT, "FLOATING_POINT" },
     261              :             { prinbee::pbql::token_t::TOKEN_NOT_EQUAL, "NOT_EQUAL" },
     262              :             { prinbee::pbql::token_t::TOKEN_LESS_EQUAL, "LESS_EQUAL" },
     263              :             { prinbee::pbql::token_t::TOKEN_GREATER_EQUAL, "GREATER_EQUAL" },
     264              :             { prinbee::pbql::token_t::TOKEN_SQUARE_ROOT, "SQUARE_ROOT" },
     265              :             { prinbee::pbql::token_t::TOKEN_CUBE_ROOT, "CUBE_ROOT" },
     266              :             { prinbee::pbql::token_t::TOKEN_SCOPE, "SCOPE" },
     267              :             { prinbee::pbql::token_t::TOKEN_SHIFT_LEFT, "SHIFT_LEFT" },
     268              :             { prinbee::pbql::token_t::TOKEN_SHIFT_RIGHT, "SHIFT_RIGHT" },
     269              :             { prinbee::pbql::token_t::TOKEN_STRING_CONCAT, "STRING_CONCAT" },
     270              :             { prinbee::pbql::token_t::TOKEN_ALL_FIELDS, "ALL_FIELDS" },
     271              :             { prinbee::pbql::token_t::TOKEN_AT, "AT" },
     272              :             { prinbee::pbql::token_t::TOKEN_BETWEEN, "BETWEEN" },
     273              :             { prinbee::pbql::token_t::TOKEN_CAST, "CAST" },
     274              :             { prinbee::pbql::token_t::TOKEN_FALSE, "FALSE" },
     275              :             { prinbee::pbql::token_t::TOKEN_FUNCTION_CALL, "FUNCTION_CALL" },
     276              :             { prinbee::pbql::token_t::TOKEN_ILIKE, "ILIKE" },
     277              :             { prinbee::pbql::token_t::TOKEN_LIKE, "LIKE" },
     278              :             { prinbee::pbql::token_t::TOKEN_LIST, "LIST" },
     279              :             { prinbee::pbql::token_t::TOKEN_LOGICAL_OR, "LOGICAL_OR" },
     280              :             { prinbee::pbql::token_t::TOKEN_LOGICAL_AND, "LOGICAL_AND" },
     281              :             { prinbee::pbql::token_t::TOKEN_LOGICAL_NOT, "LOGICAL_NOT" },
     282              :             { prinbee::pbql::token_t::TOKEN_NULL, "NULL" },
     283              :             { prinbee::pbql::token_t::TOKEN_TRUE, "TRUE" },
     284              :             { prinbee::pbql::token_t::TOKEN_TYPE, "TYPE" },
     285              :             { prinbee::pbql::token_t::TOKEN_BOOLEAN, "BOOLEAN" },
     286              :             { prinbee::pbql::token_t::TOKEN_NUMBER, "NUMBER" },
     287              :         };
     288              : 
     289            1 :         std::string previous;
     290           55 :         for(auto const & t : token_names)
     291              :         {
     292           54 :             std::string const s(prinbee::pbql::to_string(t.f_token, false));
     293           54 :             if(s.empty())
     294              :             {
     295            0 :                 SNAP_LOG_FATAL
     296            0 :                     << "token number "
     297            0 :                     << static_cast<int>(t.f_token)
     298              :                     << " is not defined in prinbee::pbql::to_string() (previous token was: "
     299            0 :                     << (previous.empty() ? "<no previous token>" : previous)
     300              :                     << ")."
     301              :                     << SNAP_LOG_SEND;
     302              :             }
     303           54 :             CATCH_REQUIRE_FALSE(s.empty());    // token missing?
     304           54 :             CATCH_REQUIRE(s == t.f_name);
     305           54 :             if(s.length() == 1)
     306              :             {
     307           22 :                 CATCH_REQUIRE(prinbee::pbql::to_string(t.f_token, true) == "'" + s + "'");
     308           22 :                 CATCH_REQUIRE(prinbee::pbql::to_string(t.f_token) == "'" + s + "'");
     309              :             }
     310           54 :             previous = s;
     311           54 :         }
     312              : 
     313              :         // also test the two "not a token" enums
     314              :         {
     315            1 :             std::string p(prinbee::pbql::to_string(prinbee::pbql::token_t::TOKEN_other));
     316            1 :             CATCH_REQUIRE(p.empty());
     317            1 :             p = prinbee::pbql::to_string(prinbee::pbql::token_t::TOKEN_max, false);
     318            1 :             CATCH_REQUIRE(p.empty());
     319            1 :         }
     320            1 :     }
     321           14 :     CATCH_END_SECTION()
     322              : 
     323           15 :     CATCH_START_SECTION("node: constructor & literals")
     324              :     {
     325              :         struct token_name_t
     326              :         {
     327              :             prinbee::pbql::token_t const    f_token = prinbee::pbql::token_t::TOKEN_UNKNOWN;
     328              :             bool                            f_literal = false;
     329              :         };
     330            1 :         token_name_t token_literals[] =
     331              :         {
     332              :             { prinbee::pbql::token_t::TOKEN_EOF,                false },
     333              :             { prinbee::pbql::token_t::TOKEN_BITWISE_XOR,        false },
     334              :             { prinbee::pbql::token_t::TOKEN_MODULO,             false },
     335              :             { prinbee::pbql::token_t::TOKEN_BITWISE_AND,        false },
     336              :             { prinbee::pbql::token_t::TOKEN_OPEN_PARENTHESIS,   false },
     337              :             { prinbee::pbql::token_t::TOKEN_CLOSE_PARENTHESIS,  false },
     338              :             { prinbee::pbql::token_t::TOKEN_MULTIPLY,           false },
     339              :             { prinbee::pbql::token_t::TOKEN_PLUS,               false },
     340              :             { prinbee::pbql::token_t::TOKEN_COMMA,              false },
     341              :             { prinbee::pbql::token_t::TOKEN_MINUS,              false },
     342              :             { prinbee::pbql::token_t::TOKEN_PERIOD,             false },
     343              :             { prinbee::pbql::token_t::TOKEN_DIVIDE,             false },
     344              :             { prinbee::pbql::token_t::TOKEN_COLON,              false },
     345              :             { prinbee::pbql::token_t::TOKEN_SEMI_COLON,         false },
     346              :             { prinbee::pbql::token_t::TOKEN_LESS,               false },
     347              :             { prinbee::pbql::token_t::TOKEN_EQUAL,              false },
     348              :             { prinbee::pbql::token_t::TOKEN_GREATER,            false },
     349              :             { prinbee::pbql::token_t::TOKEN_ABSOLUTE_VALUE,     false },
     350              :             { prinbee::pbql::token_t::TOKEN_OPEN_BRACKET,       false },
     351              :             { prinbee::pbql::token_t::TOKEN_CLOSE_BRACKET,      false },
     352              :             { prinbee::pbql::token_t::TOKEN_POWER,              false },
     353              :             { prinbee::pbql::token_t::TOKEN_BITWISE_OR,         false },
     354              :             { prinbee::pbql::token_t::TOKEN_REGULAR_EXPRESSION, false },
     355              :             { prinbee::pbql::token_t::TOKEN_IDENTIFIER,         false },
     356              :             { prinbee::pbql::token_t::TOKEN_STRING,             true },
     357              :             { prinbee::pbql::token_t::TOKEN_INTEGER,            true },
     358              :             { prinbee::pbql::token_t::TOKEN_FLOATING_POINT,     true },
     359              :             { prinbee::pbql::token_t::TOKEN_NOT_EQUAL,          false },
     360              :             { prinbee::pbql::token_t::TOKEN_LESS_EQUAL,         false },
     361              :             { prinbee::pbql::token_t::TOKEN_GREATER_EQUAL,      false },
     362              :             { prinbee::pbql::token_t::TOKEN_SQUARE_ROOT,        false },
     363              :             { prinbee::pbql::token_t::TOKEN_CUBE_ROOT,          false },
     364              :             { prinbee::pbql::token_t::TOKEN_SCOPE,              false },
     365              :             { prinbee::pbql::token_t::TOKEN_SHIFT_LEFT,         false },
     366              :             { prinbee::pbql::token_t::TOKEN_SHIFT_RIGHT,        false },
     367              :             { prinbee::pbql::token_t::TOKEN_STRING_CONCAT,      false },
     368              :             { prinbee::pbql::token_t::TOKEN_ALL_FIELDS,         false },
     369              :             { prinbee::pbql::token_t::TOKEN_AT,                 false },
     370              :             { prinbee::pbql::token_t::TOKEN_BETWEEN,            false },
     371              :             { prinbee::pbql::token_t::TOKEN_CAST,               false },
     372              :             { prinbee::pbql::token_t::TOKEN_FALSE,              true },
     373              :             { prinbee::pbql::token_t::TOKEN_FUNCTION_CALL,      false },
     374              :             { prinbee::pbql::token_t::TOKEN_ILIKE,              false },
     375              :             { prinbee::pbql::token_t::TOKEN_LIKE,               false },
     376              :             { prinbee::pbql::token_t::TOKEN_LIST,               false },
     377              :             { prinbee::pbql::token_t::TOKEN_LOGICAL_OR,         false },
     378              :             { prinbee::pbql::token_t::TOKEN_LOGICAL_AND,        false },
     379              :             { prinbee::pbql::token_t::TOKEN_LOGICAL_NOT,        false },
     380              :             { prinbee::pbql::token_t::TOKEN_NULL,               true },
     381              :             { prinbee::pbql::token_t::TOKEN_TRUE,               true },
     382              :             { prinbee::pbql::token_t::TOKEN_TYPE,               false },
     383              :         };
     384              : 
     385           52 :         for(auto const & t : token_literals)
     386              :         {
     387              :             //char const * const name(prinbee::pbql::to_string(t.f_token));
     388           51 :             prinbee::pbql::location l;
     389           51 :             prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(t.f_token, l));
     390           51 :             if(t.f_literal)
     391              :             {
     392            6 :                 CATCH_REQUIRE(n->is_literal());
     393            6 :                 CATCH_REQUIRE_FALSE(n->is_literal(prinbee::pbql::token_t::TOKEN_EOF));
     394            6 :                 switch(t.f_token)
     395              :                 {
     396            1 :                 case prinbee::pbql::token_t::TOKEN_STRING:
     397            1 :                     CATCH_REQUIRE(n->is_literal(t.f_token));
     398            3 :                     n->set_string("this is the string being tested");
     399            1 :                     n->set_integer(1018);
     400            1 :                     n->set_floating_point(3.14159);
     401            1 :                     CATCH_REQUIRE(n->get_string_auto_convert() == "this is the string being tested");
     402            1 :                     break;
     403              : 
     404            1 :                 case prinbee::pbql::token_t::TOKEN_INTEGER:
     405            1 :                     CATCH_REQUIRE(n->is_literal(t.f_token));
     406            3 :                     n->set_string("this string must be ignored");
     407            1 :                     n->set_integer(7081);
     408            1 :                     n->set_floating_point(1.141);
     409            1 :                     CATCH_REQUIRE(n->get_string_auto_convert() == "7081");
     410            1 :                     break;
     411              : 
     412            1 :                 case prinbee::pbql::token_t::TOKEN_FLOATING_POINT:
     413            1 :                     CATCH_REQUIRE(n->is_literal(t.f_token));
     414            3 :                     n->set_string("ignore this with floating points");
     415            1 :                     n->set_integer(19362);
     416            1 :                     n->set_floating_point(101.994);
     417            1 :                     CATCH_REQUIRE(n->get_string_auto_convert() == "101.994");
     418            1 :                     break;
     419              : 
     420            1 :                 case prinbee::pbql::token_t::TOKEN_TRUE:
     421            1 :                     CATCH_REQUIRE(n->is_literal(prinbee::pbql::token_t::TOKEN_BOOLEAN));
     422            3 :                     n->set_string("strings are not Boolean");
     423            1 :                     n->set_integer(320);
     424            1 :                     n->set_floating_point(91.321);
     425            1 :                     CATCH_REQUIRE(n->get_string_auto_convert() == "true");
     426            1 :                     break;
     427              : 
     428            1 :                 case prinbee::pbql::token_t::TOKEN_FALSE:
     429            1 :                     CATCH_REQUIRE(n->is_literal(prinbee::pbql::token_t::TOKEN_BOOLEAN));
     430            3 :                     n->set_string("strings are still not Boolean");
     431            1 :                     n->set_integer(60320);
     432            1 :                     n->set_floating_point(3291.02501);
     433            1 :                     CATCH_REQUIRE(n->get_string_auto_convert() == "false");
     434            1 :                     break;
     435              : 
     436            1 :                 case prinbee::pbql::token_t::TOKEN_NULL:
     437            1 :                     CATCH_REQUIRE(n->is_literal(t.f_token));
     438            3 :                     n->set_string("strings are still not NULL");
     439            1 :                     n->set_integer(90021);
     440            1 :                     n->set_floating_point(412.10328);
     441            1 :                     CATCH_REQUIRE(n->get_string_auto_convert() == "null");
     442            1 :                     break;
     443              : 
     444            0 :                 default:
     445            0 :                     CATCH_FAIL();
     446              : 
     447              :                 }
     448              :             }
     449              :             else
     450              :             {
     451           45 :                 CATCH_REQUIRE_FALSE(n->is_literal());
     452           45 :                 CATCH_REQUIRE_FALSE(n->is_literal(prinbee::pbql::token_t::TOKEN_EOF));
     453           45 :                 CATCH_REQUIRE_FALSE(n->is_literal(t.f_token));
     454          180 :                 CATCH_REQUIRE_THROWS_MATCHES(
     455              :                           n->get_string_auto_convert()
     456              :                         , prinbee::logic_error
     457              :                         , Catch::Matchers::ExceptionMessage(
     458              :                                   "logic_error: node is not a literal and it cannot be converted to a string."));
     459              :             }
     460           51 :         }
     461              :     }
     462           14 :     CATCH_END_SECTION()
     463              : 
     464           15 :     CATCH_START_SECTION("node: to_as2js()")
     465              :     {
     466            1 :         constexpr std::int64_t const value_parent_integer(987);
     467            1 :         constexpr std::int64_t const value_left_integer(1191);
     468            1 :         constexpr std::int64_t const value_right_integer(6731);
     469            1 :         constexpr std::int64_t const value_extra_integer(92426);
     470            1 :         constexpr double const value_parent_double(0.0238);
     471            1 :         constexpr double const value_left_double(9.3321);
     472            1 :         constexpr double const value_right_double(11.65103);
     473            1 :         constexpr double const value_extra_double(151.5931);
     474            3 :         std::string const value_parent_string("the parent string value");
     475            3 :         std::string const value_left_string("the left side string value");
     476            3 :         std::string const value_right_string("the right side string value");
     477            3 :         std::string const value_extra_string("the extra string value");
     478            3 :         std::string const value_parent_identifier("top_identifier");
     479            3 :         std::string const value_left_identifier("left_identifier");
     480            3 :         std::string const value_right_identifier("right_identifier");
     481            3 :         std::string const value_extra_identifier("extra_identifier");
     482              :         struct expression_t
     483              :         {
     484              :             prinbee::pbql::token_t const    f_parent = prinbee::pbql::token_t::TOKEN_UNKNOWN;
     485              :             prinbee::pbql::token_t const    f_left = prinbee::pbql::token_t::TOKEN_UNKNOWN;
     486              :             prinbee::pbql::token_t const    f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN;
     487              :             prinbee::pbql::token_t const    f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN;
     488              :             std::string const               f_output = std::string();
     489              :         };
     490            1 :         expression_t const expressions[] =
     491              :         {
     492              :             {
     493              :                 .f_parent = prinbee::pbql::token_t::TOKEN_BITWISE_XOR,
     494              :                 .f_left = prinbee::pbql::token_t::TOKEN_INTEGER,
     495              :                 .f_right = prinbee::pbql::token_t::TOKEN_INTEGER,
     496              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     497            3 :                 .f_output = std::to_string(value_left_integer) + '^' + std::to_string(value_right_integer),
     498              :             },
     499              :             {
     500              :                 .f_parent = prinbee::pbql::token_t::TOKEN_MODULO,
     501              :                 .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     502              :                 .f_right = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     503              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     504            2 :                 .f_output = snapdev::floating_point_to_string<double, char>(value_left_double)
     505            4 :                           + '%'
     506            2 :                           + snapdev::floating_point_to_string<double, char>(value_right_double),
     507              :             },
     508              :             {
     509              :                 .f_parent = prinbee::pbql::token_t::TOKEN_BITWISE_AND,
     510              :                 .f_left = prinbee::pbql::token_t::TOKEN_INTEGER,
     511              :                 .f_right = prinbee::pbql::token_t::TOKEN_INTEGER,
     512              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     513            3 :                 .f_output = std::to_string(value_left_integer) + '&' + std::to_string(value_right_integer),
     514              :             },
     515              :             {
     516              :                 .f_parent = prinbee::pbql::token_t::TOKEN_MULTIPLY,
     517              :                 .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     518              :                 .f_right = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     519              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     520            2 :                 .f_output = snapdev::floating_point_to_string<double, char>(value_left_double)
     521            4 :                           + '*'
     522            2 :                           + snapdev::floating_point_to_string<double, char>(value_right_double),
     523              :             },
     524              :             {
     525              :                 .f_parent = prinbee::pbql::token_t::TOKEN_MINUS,
     526              :                 .f_left = prinbee::pbql::token_t::TOKEN_INTEGER,
     527              :                 .f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     528              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     529            2 :                 .f_output = '-' + std::to_string(value_left_integer),
     530              :             },
     531              :             {
     532              :                 .f_parent = prinbee::pbql::token_t::TOKEN_MINUS,
     533              :                 .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     534              :                 .f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     535              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     536            2 :                 .f_output = '-' + snapdev::floating_point_to_string<double, char>(value_left_double),
     537              :             },
     538              :             {
     539              :                 .f_parent = prinbee::pbql::token_t::TOKEN_PERIOD,
     540              :                 .f_left = prinbee::pbql::token_t::TOKEN_IDENTIFIER,
     541              :                 .f_right = prinbee::pbql::token_t::TOKEN_IDENTIFIER,
     542              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     543            1 :                 .f_output = value_left_identifier + '.' + value_right_identifier,
     544              :             },
     545              :             {
     546              :                 .f_parent = prinbee::pbql::token_t::TOKEN_DIVIDE,
     547              :                 .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     548              :                 .f_right = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     549              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     550            2 :                 .f_output = snapdev::floating_point_to_string<double, char>(value_left_double)
     551            4 :                           + '/'
     552            2 :                           + snapdev::floating_point_to_string<double, char>(value_right_double),
     553              :             },
     554              :             {
     555              :                 .f_parent = prinbee::pbql::token_t::TOKEN_LESS,
     556              :                 .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     557              :                 .f_right = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     558              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     559            2 :                 .f_output = snapdev::floating_point_to_string<double, char>(value_left_double)
     560            4 :                           + '<'
     561            2 :                           + snapdev::floating_point_to_string<double, char>(value_right_double),
     562              :             },
     563              :             {
     564              :                 .f_parent = prinbee::pbql::token_t::TOKEN_EQUAL,
     565              :                 .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     566              :                 .f_right = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     567              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     568            2 :                 .f_output = snapdev::floating_point_to_string<double, char>(value_left_double)
     569            4 :                           + "=="
     570            2 :                           + snapdev::floating_point_to_string<double, char>(value_right_double),
     571              :             },
     572              :             {
     573              :                 .f_parent = prinbee::pbql::token_t::TOKEN_GREATER,
     574              :                 .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     575              :                 .f_right = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     576              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     577            2 :                 .f_output = snapdev::floating_point_to_string<double, char>(value_left_double)
     578            4 :                           + '>'
     579            2 :                           + snapdev::floating_point_to_string<double, char>(value_right_double),
     580              :             },
     581              :             {
     582              :                 .f_parent = prinbee::pbql::token_t::TOKEN_POWER,
     583              :                 .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     584              :                 .f_right = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     585              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     586              :                 .f_output = '('
     587            2 :                           + snapdev::floating_point_to_string<double, char>(value_left_double)
     588            4 :                           + "**"
     589            4 :                           + snapdev::floating_point_to_string<double, char>(value_right_double)
     590              :                           + ')',
     591              :             },
     592              :             {
     593              :                 .f_parent = prinbee::pbql::token_t::TOKEN_BITWISE_OR,
     594              :                 .f_left = prinbee::pbql::token_t::TOKEN_INTEGER,
     595              :                 .f_right = prinbee::pbql::token_t::TOKEN_INTEGER,
     596              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     597            3 :                 .f_output = std::to_string(value_left_integer) + '|' + std::to_string(value_right_integer),
     598              :             },
     599              :             {
     600              :                 .f_parent = prinbee::pbql::token_t::TOKEN_REGULAR_EXPRESSION,
     601              :                 .f_left = prinbee::pbql::token_t::TOKEN_STRING,
     602              :                 .f_right = prinbee::pbql::token_t::TOKEN_STRING,
     603              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     604              :                 .f_output = "new RegExp(\""
     605            1 :                           + value_right_string
     606            4 :                           + "\").test(\""
     607            4 :                           + value_left_string
     608              :                           + "\")",
     609              :             },
     610              :             {
     611              :                 .f_parent = prinbee::pbql::token_t::TOKEN_IDENTIFIER,
     612              :                 .f_left = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     613              :                 .f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     614              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     615              :                 .f_output = value_parent_identifier,
     616              :             },
     617              :             {
     618              :                 .f_parent = prinbee::pbql::token_t::TOKEN_STRING,
     619              :                 .f_left = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     620              :                 .f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     621              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     622            1 :                 .f_output = '"' + value_parent_string + '"',
     623              :             },
     624              :             {
     625              :                 .f_parent = prinbee::pbql::token_t::TOKEN_INTEGER,
     626              :                 .f_left = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     627              :                 .f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     628              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     629              :                 .f_output = "987",
     630              :             },
     631              :             {
     632              :                 .f_parent = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     633              :                 .f_left = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     634              :                 .f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     635              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     636              :                 .f_output = "0.0238",
     637              :             },
     638              :             {
     639              :                 .f_parent = prinbee::pbql::token_t::TOKEN_NOT_EQUAL,
     640              :                 .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     641              :                 .f_right = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     642              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     643            2 :                 .f_output = snapdev::floating_point_to_string<double, char>(value_left_double)
     644            4 :                           + "!="
     645            2 :                           + snapdev::floating_point_to_string<double, char>(value_right_double),
     646              :             },
     647              :             {
     648              :                 .f_parent = prinbee::pbql::token_t::TOKEN_LESS_EQUAL,
     649              :                 .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     650              :                 .f_right = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     651              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     652            2 :                 .f_output = snapdev::floating_point_to_string<double, char>(value_left_double)
     653            4 :                           + "<="
     654            2 :                           + snapdev::floating_point_to_string<double, char>(value_right_double),
     655              :             },
     656              :             {
     657              :                 .f_parent = prinbee::pbql::token_t::TOKEN_GREATER_EQUAL,
     658              :                 .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     659              :                 .f_right = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     660              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     661            2 :                 .f_output = snapdev::floating_point_to_string<double, char>(value_left_double)
     662            4 :                           + ">="
     663            2 :                           + snapdev::floating_point_to_string<double, char>(value_right_double),
     664              :             },
     665              :             {
     666              :                 .f_parent = prinbee::pbql::token_t::TOKEN_SHIFT_LEFT,
     667              :                 .f_left = prinbee::pbql::token_t::TOKEN_INTEGER,
     668              :                 .f_right = prinbee::pbql::token_t::TOKEN_INTEGER,
     669              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     670            2 :                 .f_output = std::to_string(value_left_integer)
     671            4 :                           + "<<"
     672            2 :                           + std::to_string(value_right_integer),
     673              :             },
     674              :             {
     675              :                 .f_parent = prinbee::pbql::token_t::TOKEN_SHIFT_RIGHT,
     676              :                 .f_left = prinbee::pbql::token_t::TOKEN_INTEGER,
     677              :                 .f_right = prinbee::pbql::token_t::TOKEN_INTEGER,
     678              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     679            2 :                 .f_output = std::to_string(value_left_integer)
     680            4 :                           + ">>"
     681            2 :                           + std::to_string(value_right_integer),
     682              :             },
     683              :             {
     684              :                 .f_parent = prinbee::pbql::token_t::TOKEN_ALL_FIELDS,
     685              :                 .f_left = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     686              :                 .f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     687              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     688              :                 .f_output = "ALL_FIELDS",
     689              :             },
     690              :             {
     691              :                 .f_parent = prinbee::pbql::token_t::TOKEN_AT,
     692              :                 .f_left = prinbee::pbql::token_t::TOKEN_IDENTIFIER,
     693              :                 .f_right = prinbee::pbql::token_t::TOKEN_INTEGER,
     694              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     695            2 :                 .f_output = value_left_identifier + '[' + std::to_string(value_right_integer) + ']',
     696              :             },
     697              :             {
     698              :                 .f_parent = prinbee::pbql::token_t::TOKEN_BETWEEN,
     699              :                 .f_left = prinbee::pbql::token_t::TOKEN_IDENTIFIER,
     700              :                 .f_right = prinbee::pbql::token_t::TOKEN_INTEGER,
     701              :                 .f_extra = prinbee::pbql::token_t::TOKEN_INTEGER,
     702              :                 .f_output = "(_t1="
     703            2 :                           + value_left_identifier
     704            4 :                           + ",_t1>="
     705            4 :                           + std::to_string(value_right_integer)
     706            4 :                           + "&&_t1<="
     707            4 :                           + std::to_string(value_extra_integer)
     708              :                           + ')',
     709              :             },
     710              :             {
     711              :                 .f_parent = prinbee::pbql::token_t::TOKEN_BETWEEN,
     712              :                 .f_left = prinbee::pbql::token_t::TOKEN_IDENTIFIER,
     713              :                 .f_right = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     714              :                 .f_extra = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     715              :                 .f_output = "(_t1="
     716            2 :                           + value_left_identifier
     717            4 :                           + ",_t1>="
     718            4 :                           + snapdev::floating_point_to_string<double, char>(value_right_double)
     719            4 :                           + "&&_t1<="
     720            4 :                           + snapdev::floating_point_to_string<double, char>(value_extra_double)
     721              :                           + ')',
     722              :             },
     723              :             {
     724              :                 .f_parent = prinbee::pbql::token_t::TOKEN_BETWEEN,
     725              :                 .f_left = prinbee::pbql::token_t::TOKEN_IDENTIFIER,
     726              :                 .f_right = prinbee::pbql::token_t::TOKEN_STRING,
     727              :                 .f_extra = prinbee::pbql::token_t::TOKEN_STRING,
     728              :                 .f_output = "(_t1="
     729            1 :                           + value_left_identifier
     730            4 :                           + ",_t1>=\""
     731            4 :                           + value_right_string
     732            4 :                           + "\"&&_t1<=\""
     733            4 :                           + value_extra_string
     734              :                           + "\")",
     735              :             },
     736              :             {
     737              :                 .f_parent = prinbee::pbql::token_t::TOKEN_CAST,
     738              :                 .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     739              :                 .f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     740              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     741              :                 .f_output = "new Integer("
     742            2 :                           + snapdev::floating_point_to_string<double, char>(value_left_double)
     743              :                           + ')',
     744              :             },
     745              :             {
     746              :                 .f_parent = prinbee::pbql::token_t::TOKEN_FALSE,
     747              :                 .f_left = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     748              :                 .f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     749              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     750              :                 .f_output = "false",
     751              :             },
     752              :             //{
     753              :             //    .f_parent = prinbee::pbql::token_t::TOKEN_FUNCTION_CALL,
     754              :             //    .f_left = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     755              :             //    .f_right = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
     756              :             //    .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     757              :             //    .f_output = snapdev::floating_point_to_string<double, char>(value_left_double)
     758              :             //              + "<="
     759              :             //              + snapdev::floating_point_to_string<double, char>(value_right_double),
     760              :             //},
     761              :             {
     762              :                 .f_parent = prinbee::pbql::token_t::TOKEN_LOGICAL_OR,
     763              :                 .f_left = prinbee::pbql::token_t::TOKEN_TRUE,
     764              :                 .f_right = prinbee::pbql::token_t::TOKEN_FALSE,
     765              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     766              :                 .f_output = "true||false",
     767              :             },
     768              :             {
     769              :                 .f_parent = prinbee::pbql::token_t::TOKEN_LOGICAL_AND,
     770              :                 .f_left = prinbee::pbql::token_t::TOKEN_FALSE,
     771              :                 .f_right = prinbee::pbql::token_t::TOKEN_TRUE,
     772              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     773              :                 .f_output = "false&&true",
     774              :             },
     775              :             {
     776              :                 .f_parent = prinbee::pbql::token_t::TOKEN_LOGICAL_NOT,
     777              :                 .f_left = prinbee::pbql::token_t::TOKEN_FALSE,
     778              :                 .f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     779              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     780              :                 .f_output = "!false",
     781              :             },
     782              :             {
     783              :                 .f_parent = prinbee::pbql::token_t::TOKEN_NULL,
     784              :                 .f_left = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     785              :                 .f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     786              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     787              :                 .f_output = "null",
     788              :             },
     789              :             {
     790              :                 .f_parent = prinbee::pbql::token_t::TOKEN_TRUE,
     791              :                 .f_left = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     792              :                 .f_right = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     793              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     794              :                 .f_output = "true",
     795              :             },
     796              :             {
     797              :                 .f_parent = prinbee::pbql::token_t::TOKEN_ILIKE,
     798              :                 .f_left = prinbee::pbql::token_t::TOKEN_STRING,
     799              :                 .f_right = prinbee::pbql::token_t::TOKEN_STRING,
     800              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     801              :                 .f_output = "new RegExp(\"^"
     802            1 :                           + value_right_string
     803            4 :                           + "$\",\"i\").test(\""
     804            4 :                           + value_left_string
     805              :                           + "\")",
     806              :             },
     807              :             {
     808              :                 .f_parent = prinbee::pbql::token_t::TOKEN_LIKE,
     809              :                 .f_left = prinbee::pbql::token_t::TOKEN_STRING,
     810              :                 .f_right = prinbee::pbql::token_t::TOKEN_STRING,
     811              :                 .f_extra = prinbee::pbql::token_t::TOKEN_UNKNOWN,
     812              :                 .f_output = "new RegExp(\"^"
     813            1 :                           + value_right_string
     814            4 :                           + "$\").test(\""
     815            3 :                           + value_left_string
     816              :                           + "\")",
     817              :             },
     818           84 :         };
     819              : 
     820           38 :         for(auto const & e : expressions)
     821              :         {
     822           37 :             prinbee::pbql::location l;
     823              : 
     824           37 :             prinbee::pbql::node::pointer_t parent(std::make_shared<prinbee::pbql::node>(e.f_parent, l));
     825           37 :             if(e.f_parent == prinbee::pbql::token_t::TOKEN_CAST)
     826              :             {
     827            1 :                 parent->set_integer(static_cast<int>(prinbee::pbql::type_t::TYPE_INT4));
     828              :             }
     829              :             else
     830              :             {
     831           36 :                 parent->set_integer(value_parent_integer);
     832              :             }
     833           37 :             parent->set_floating_point(value_parent_double);
     834           37 :             if(e.f_parent == prinbee::pbql::token_t::TOKEN_IDENTIFIER)
     835              :             {
     836            1 :                 parent->set_string(value_parent_identifier);
     837              :             }
     838              :             else
     839              :             {
     840           36 :                 parent->set_string(value_parent_string);
     841              :             }
     842              : 
     843           37 :             if(e.f_left != prinbee::pbql::token_t::TOKEN_UNKNOWN)
     844              :             {
     845           29 :                 prinbee::pbql::node::pointer_t left(std::make_shared<prinbee::pbql::node>(e.f_left, l));
     846           29 :                 left->set_integer(value_left_integer);
     847           29 :                 left->set_floating_point(value_left_double);
     848           29 :                 if(e.f_left == prinbee::pbql::token_t::TOKEN_IDENTIFIER)
     849              :                 {
     850            5 :                     left->set_string(value_left_identifier);
     851              :                 }
     852              :                 else
     853              :                 {
     854           24 :                     left->set_string(value_left_string);
     855              :                 }
     856              : 
     857           29 :                 parent->insert_child(-1, left);
     858              : 
     859           29 :                 if(e.f_right != prinbee::pbql::token_t::TOKEN_UNKNOWN)
     860              :                 {
     861           25 :                     prinbee::pbql::node::pointer_t right(std::make_shared<prinbee::pbql::node>(e.f_right, l));
     862           25 :                     right->set_integer(value_right_integer);
     863           25 :                     right->set_floating_point(value_right_double);
     864           25 :                     if(e.f_right == prinbee::pbql::token_t::TOKEN_IDENTIFIER)
     865              :                     {
     866            1 :                         right->set_string(value_right_identifier);
     867              :                     }
     868              :                     else
     869              :                     {
     870           24 :                         right->set_string(value_right_string);
     871              :                     }
     872              : 
     873           25 :                     parent->insert_child(-1, right);
     874              : 
     875           25 :                     if(e.f_extra != prinbee::pbql::token_t::TOKEN_UNKNOWN)
     876              :                     {
     877            3 :                         prinbee::pbql::node::pointer_t extra(std::make_shared<prinbee::pbql::node>(e.f_extra, l));
     878            3 :                         extra->set_integer(value_extra_integer);
     879            3 :                         extra->set_floating_point(value_extra_double);
     880            3 :                         if(e.f_extra == prinbee::pbql::token_t::TOKEN_IDENTIFIER)
     881              :                         {
     882            0 :                             right->set_string(value_extra_identifier);
     883              :                         }
     884              :                         else
     885              :                         {
     886            3 :                             extra->set_string(value_extra_string);
     887              :                         }
     888              : 
     889            3 :                         parent->insert_child(-1, extra);
     890            3 :                     }
     891           25 :                 }
     892            4 :                 else if(e.f_extra != prinbee::pbql::token_t::TOKEN_UNKNOWN)
     893              :                 {
     894              :                     // you need a right to have an extra
     895              :                     //
     896            0 :                     CATCH_FAIL();
     897              :                 }
     898           29 :             }
     899            8 :             else if(e.f_right != prinbee::pbql::token_t::TOKEN_UNKNOWN)
     900              :             {
     901              :                 // you need a left to have a right
     902              :                 //
     903            0 :                 CATCH_FAIL();
     904              :             }
     905           37 :             std::string const result(parent->to_as2js());
     906           37 :             CATCH_REQUIRE(result == e.f_output);
     907           37 :         }
     908           39 :     }
     909           14 :     CATCH_END_SECTION()
     910              : 
     911           15 :     CATCH_START_SECTION("node: string with escape codes to_as2js()")
     912              :     {
     913              :         struct string_expression_t
     914              :         {
     915              :             char const *        f_in = nullptr;
     916              :             char const *        f_out = nullptr;
     917              :         };
     918            1 :         string_expression_t const strings[] =
     919              :         {
     920              :             {
     921              :                 .f_in = "test",
     922              :                 .f_out = "\"test\"",
     923              :             },
     924              :             {
     925              :                 .f_in = "double \" quote",
     926              :                 .f_out = "\"double \\\" quote\"",
     927              :             },
     928              :             {
     929              :                 .f_in = "\back",
     930              :                 .f_out = "\"\\back\"",
     931              :             },
     932              :             {
     933              :                 .f_in = "\forward",
     934              :                 .f_out = "\"\\forward\"",
     935              :             },
     936              :             {
     937              :                 .f_in = "\newline",
     938              :                 .f_out = "\"\\newline\"",
     939              :             },
     940              :             {
     941              :                 .f_in = "\return",
     942              :                 .f_out = "\"\\return\"",
     943              :             },
     944              :             {
     945              :                 .f_in = "\tab",
     946              :                 .f_out = "\"\\tab\"",
     947              :             },
     948              :             {
     949              :                 .f_in = "\vertical",
     950              :                 .f_out = "\"\\vertical\"",
     951              :             },
     952              :             { // kept as is
     953              :                 .f_in = "\001 Ctrl-A",
     954              :                 .f_out = "\"\001 Ctrl-A\"",
     955              :             },
     956              :         };
     957              : 
     958           10 :         for(auto const & s : strings)
     959              :         {
     960            9 :             prinbee::pbql::location l;
     961              : 
     962            9 :             prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
     963           27 :             n->set_string(s.f_in);
     964            9 :             std::string const result(n->to_as2js());
     965            9 :             CATCH_REQUIRE(result == s.f_out);
     966            9 :         }
     967              :     }
     968           14 :     CATCH_END_SECTION()
     969              : 
     970           15 :     CATCH_START_SECTION("node: function calls 0 to 10 parameters")
     971              :     {
     972            1 :         prinbee::pbql::location l;
     973              : 
     974              :         // 0 parameters
     975              :         {
     976            1 :             prinbee::pbql::node::pointer_t f(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FUNCTION_CALL, l));
     977            3 :             f->set_string("myFunc");
     978            1 :             prinbee::pbql::node::pointer_t list(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_LIST, l));
     979            1 :             f->insert_child(-1, list);
     980            1 :             std::string const result(f->to_as2js());
     981            1 :             CATCH_REQUIRE(result == "myFunc()");
     982            1 :         }
     983              : 
     984              :         // 1 parameter
     985              :         {
     986            1 :             prinbee::pbql::node::pointer_t f(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FUNCTION_CALL, l));
     987            3 :             f->set_string("sin");
     988            1 :             prinbee::pbql::node::pointer_t list(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_LIST, l));
     989            1 :             f->insert_child(-1, list);
     990            1 :             prinbee::pbql::node::pointer_t p1(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
     991            1 :             p1->set_floating_point(3.14159);
     992            1 :             list->insert_child(-1, p1);
     993            1 :             std::string const result(f->to_as2js());
     994            1 :             CATCH_REQUIRE(result == "sin(3.14159)");
     995            1 :         }
     996              : 
     997              :         // 2 parameters
     998              :         {
     999            1 :             prinbee::pbql::node::pointer_t f(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FUNCTION_CALL, l));
    1000            3 :             f->set_string("Math.atan2");
    1001            1 :             prinbee::pbql::node::pointer_t list(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_LIST, l));
    1002            1 :             f->insert_child(-1, list);
    1003            1 :             prinbee::pbql::node::pointer_t p1(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1004            1 :             p1->set_floating_point(0.56172);
    1005            1 :             list->insert_child(-1, p1);
    1006            1 :             prinbee::pbql::node::pointer_t p2(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1007            1 :             p2->set_floating_point(0.29819);
    1008            1 :             list->insert_child(-1, p2);
    1009            1 :             std::string const result(f->to_as2js());
    1010            1 :             CATCH_REQUIRE(result == "Math.atan2(0.56172,0.29819)");
    1011            1 :         }
    1012              : 
    1013              :         // 3 parameters
    1014              :         {
    1015            1 :             prinbee::pbql::node::pointer_t f(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FUNCTION_CALL, l));
    1016            3 :             f->set_string("String.concat");
    1017            1 :             prinbee::pbql::node::pointer_t list(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_LIST, l));
    1018            1 :             f->insert_child(-1, list);
    1019            1 :             prinbee::pbql::node::pointer_t p1(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1020            3 :             p1->set_string("prefix");
    1021            1 :             list->insert_child(-1, p1);
    1022            1 :             prinbee::pbql::node::pointer_t p2(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1023            1 :             p2->set_floating_point(9180.21911);
    1024            1 :             list->insert_child(-1, p2);
    1025            1 :             prinbee::pbql::node::pointer_t p3(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_INTEGER, l));
    1026            1 :             p3->set_integer(290119);
    1027            1 :             list->insert_child(-1, p3);
    1028            1 :             std::string const result(f->to_as2js());
    1029            1 :             CATCH_REQUIRE(result == "String.concat(\"prefix\",9180.21911,290119)");
    1030            1 :         }
    1031              : 
    1032              :         // 4 parameters
    1033              :         {
    1034            1 :             prinbee::pbql::node::pointer_t f(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FUNCTION_CALL, l));
    1035            3 :             f->set_string("hisFunc");
    1036            1 :             prinbee::pbql::node::pointer_t list(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_LIST, l));
    1037            1 :             f->insert_child(-1, list);
    1038            1 :             prinbee::pbql::node::pointer_t p1(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1039            3 :             p1->set_string("prefix");
    1040            1 :             list->insert_child(-1, p1);
    1041            1 :             prinbee::pbql::node::pointer_t p2(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1042            3 :             p2->set_string("left");
    1043            1 :             list->insert_child(-1, p2);
    1044            1 :             prinbee::pbql::node::pointer_t p3(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1045            3 :             p3->set_string("right");
    1046            1 :             list->insert_child(-1, p3);
    1047            1 :             prinbee::pbql::node::pointer_t p4(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1048            3 :             p4->set_string("suffix");
    1049            1 :             list->insert_child(-1, p4);
    1050            1 :             std::string const result(f->to_as2js());
    1051            1 :             CATCH_REQUIRE(result == "hisFunc(\"prefix\",\"left\",\"right\",\"suffix\")");
    1052            1 :         }
    1053              : 
    1054              :         // 5 parameters
    1055              :         {
    1056            1 :             prinbee::pbql::node::pointer_t f(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FUNCTION_CALL, l));
    1057            3 :             f->set_string("Math.min");
    1058            1 :             prinbee::pbql::node::pointer_t list(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_LIST, l));
    1059            1 :             f->insert_child(-1, list);
    1060            1 :             prinbee::pbql::node::pointer_t p1(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_INTEGER, l));
    1061            1 :             p1->set_integer(55);
    1062            1 :             list->insert_child(-1, p1);
    1063            1 :             prinbee::pbql::node::pointer_t p2(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_INTEGER, l));
    1064            1 :             p2->set_integer(101);
    1065            1 :             list->insert_child(-1, p2);
    1066            1 :             prinbee::pbql::node::pointer_t p3(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_INTEGER, l));
    1067            1 :             p3->set_integer(-67);
    1068            1 :             list->insert_child(-1, p3);
    1069            1 :             prinbee::pbql::node::pointer_t p4(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_INTEGER, l));
    1070            1 :             p4->set_integer(31);
    1071            1 :             list->insert_child(-1, p4);
    1072            1 :             prinbee::pbql::node::pointer_t p5(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_INTEGER, l));
    1073            1 :             p5->set_integer(-96);
    1074            1 :             list->insert_child(-1, p5);
    1075            1 :             std::string const result(f->to_as2js());
    1076            1 :             CATCH_REQUIRE(result == "Math.min(55,101,-67,31,-96)");
    1077            1 :         }
    1078              : 
    1079              :         // 6 parameters
    1080              :         {
    1081            1 :             prinbee::pbql::node::pointer_t f(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FUNCTION_CALL, l));
    1082            3 :             f->set_string("Math.max");
    1083            1 :             prinbee::pbql::node::pointer_t list(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_LIST, l));
    1084            1 :             f->insert_child(-1, list);
    1085            1 :             prinbee::pbql::node::pointer_t p1(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1086            1 :             p1->set_floating_point(5.5);
    1087            1 :             list->insert_child(-1, p1);
    1088            1 :             prinbee::pbql::node::pointer_t p2(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1089            1 :             p2->set_floating_point(10.21);
    1090            1 :             list->insert_child(-1, p2);
    1091            1 :             prinbee::pbql::node::pointer_t p3(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1092            1 :             p3->set_floating_point(-6.7);
    1093            1 :             list->insert_child(-1, p3);
    1094            1 :             prinbee::pbql::node::pointer_t p4(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1095            1 :             p4->set_floating_point(3.1);
    1096            1 :             list->insert_child(-1, p4);
    1097            1 :             prinbee::pbql::node::pointer_t p5(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1098            1 :             p5->set_floating_point(-0.96);
    1099            1 :             list->insert_child(-1, p5);
    1100            1 :             prinbee::pbql::node::pointer_t p6(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1101            1 :             p6->set_floating_point(96.689);
    1102            1 :             list->insert_child(-1, p6);
    1103            1 :             std::string const result(f->to_as2js());
    1104            1 :             CATCH_REQUIRE(result == "Math.max(5.5,10.21,-6.7,3.1,-0.96,96.689)");
    1105            1 :         }
    1106              : 
    1107              :         // 7 parameters
    1108              :         {
    1109            1 :             prinbee::pbql::node::pointer_t f(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FUNCTION_CALL, l));
    1110            3 :             f->set_string("yourFunction");
    1111            1 :             prinbee::pbql::node::pointer_t list(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_LIST, l));
    1112            1 :             f->insert_child(-1, list);
    1113            1 :             prinbee::pbql::node::pointer_t p1(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_INTEGER, l));
    1114            1 :             p1->set_integer(159);
    1115            1 :             list->insert_child(-1, p1);
    1116            1 :             prinbee::pbql::node::pointer_t p2(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1117            1 :             p2->set_floating_point(10.21);
    1118            1 :             list->insert_child(-1, p2);
    1119            1 :             prinbee::pbql::node::pointer_t p3(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1120            1 :             p3->set_floating_point(-6.7);
    1121            1 :             list->insert_child(-1, p3);
    1122            1 :             prinbee::pbql::node::pointer_t p4(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1123            3 :             p4->set_string("this string");
    1124            1 :             list->insert_child(-1, p4);
    1125            1 :             prinbee::pbql::node::pointer_t p5(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1126            1 :             p5->set_floating_point(-0.96);
    1127            1 :             list->insert_child(-1, p5);
    1128            1 :             prinbee::pbql::node::pointer_t p6(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1129            1 :             p6->set_floating_point(96.689);
    1130            1 :             list->insert_child(-1, p6);
    1131            1 :             prinbee::pbql::node::pointer_t p7(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_TRUE, l));
    1132            1 :             list->insert_child(-1, p7);
    1133            1 :             std::string const result(f->to_as2js());
    1134            1 :             CATCH_REQUIRE(result == "yourFunction(159,10.21,-6.7,\"this string\",-0.96,96.689,true)");
    1135            1 :         }
    1136              : 
    1137              :         // 8 parameters
    1138              :         {
    1139            1 :             prinbee::pbql::node::pointer_t f(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FUNCTION_CALL, l));
    1140            3 :             f->set_string("getProperties");
    1141            1 :             prinbee::pbql::node::pointer_t list(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_LIST, l));
    1142            1 :             f->insert_child(-1, list);
    1143            1 :             prinbee::pbql::node::pointer_t p1(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1144            3 :             p1->set_string("x");
    1145            1 :             list->insert_child(-1, p1);
    1146            1 :             prinbee::pbql::node::pointer_t p2(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_INTEGER, l));
    1147            1 :             p2->set_integer(1012);
    1148            1 :             list->insert_child(-1, p2);
    1149            1 :             prinbee::pbql::node::pointer_t p3(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FALSE, l));
    1150            1 :             list->insert_child(-1, p3);
    1151            1 :             prinbee::pbql::node::pointer_t p4(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1152            1 :             p4->set_floating_point(3.1);
    1153            1 :             list->insert_child(-1, p4);
    1154            1 :             prinbee::pbql::node::pointer_t p5(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_TRUE, l));
    1155            1 :             list->insert_child(-1, p5);
    1156            1 :             prinbee::pbql::node::pointer_t p6(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1157            1 :             p6->set_floating_point(96.689);
    1158            1 :             list->insert_child(-1, p6);
    1159            1 :             prinbee::pbql::node::pointer_t p7(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1160            3 :             p7->set_string("one before last");
    1161            1 :             list->insert_child(-1, p7);
    1162            1 :             prinbee::pbql::node::pointer_t p8(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1163            1 :             p8->set_floating_point(0.002);
    1164            1 :             list->insert_child(-1, p8);
    1165            1 :             std::string const result(f->to_as2js());
    1166            1 :             CATCH_REQUIRE(result == "getProperties(\"x\",1012,false,3.1,true,96.689,\"one before last\",0.002)");
    1167            1 :         }
    1168              : 
    1169              :         // 9 parameters
    1170              :         {
    1171            1 :             prinbee::pbql::node::pointer_t f(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FUNCTION_CALL, l));
    1172            3 :             f->set_string("Math.average");
    1173            1 :             prinbee::pbql::node::pointer_t list(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_LIST, l));
    1174            1 :             f->insert_child(-1, list);
    1175            1 :             prinbee::pbql::node::pointer_t p1(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1176            1 :             p1->set_floating_point(501.3);
    1177            1 :             list->insert_child(-1, p1);
    1178            1 :             prinbee::pbql::node::pointer_t p2(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1179            1 :             p2->set_floating_point(1.012);
    1180            1 :             list->insert_child(-1, p2);
    1181            1 :             prinbee::pbql::node::pointer_t p3(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1182            1 :             p3->set_floating_point(7.902);
    1183            1 :             list->insert_child(-1, p3);
    1184            1 :             prinbee::pbql::node::pointer_t p4(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1185            1 :             p4->set_floating_point(3.1);
    1186            1 :             list->insert_child(-1, p4);
    1187            1 :             prinbee::pbql::node::pointer_t p5(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1188            1 :             p5->set_floating_point(907.231);
    1189            1 :             list->insert_child(-1, p5);
    1190            1 :             prinbee::pbql::node::pointer_t p6(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1191            1 :             p6->set_floating_point(96.689);
    1192            1 :             list->insert_child(-1, p6);
    1193            1 :             prinbee::pbql::node::pointer_t p7(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1194            1 :             p7->set_floating_point(1.0216);
    1195            1 :             list->insert_child(-1, p7);
    1196            1 :             prinbee::pbql::node::pointer_t p8(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1197            1 :             p8->set_floating_point(0.002);
    1198            1 :             list->insert_child(-1, p8);
    1199            1 :             prinbee::pbql::node::pointer_t p9(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1200            1 :             p9->set_floating_point(0.202);
    1201            1 :             list->insert_child(-1, p9);
    1202            1 :             std::string const result(f->to_as2js());
    1203            1 :             CATCH_REQUIRE(result == "Math.average(501.3,1.012,7.902,3.1,907.231,96.689,1.0216,0.002,0.202)");
    1204            1 :         }
    1205              : 
    1206              :         // 10 parameters
    1207              :         {
    1208            1 :             prinbee::pbql::node::pointer_t f(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FUNCTION_CALL, l));
    1209            3 :             f->set_string("Math.sum");
    1210            1 :             prinbee::pbql::node::pointer_t list(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_LIST, l));
    1211            1 :             f->insert_child(-1, list);
    1212            1 :             prinbee::pbql::node::pointer_t p1(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1213            1 :             p1->set_floating_point(501.3);
    1214            1 :             list->insert_child(-1, p1);
    1215            1 :             prinbee::pbql::node::pointer_t p2(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1216            1 :             p2->set_floating_point(1.012);
    1217            1 :             list->insert_child(-1, p2);
    1218            1 :             prinbee::pbql::node::pointer_t p3(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1219            1 :             p3->set_floating_point(7.902);
    1220            1 :             list->insert_child(-1, p3);
    1221            1 :             prinbee::pbql::node::pointer_t p4(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1222            1 :             p4->set_floating_point(3.1);
    1223            1 :             list->insert_child(-1, p4);
    1224            1 :             prinbee::pbql::node::pointer_t p5(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1225            1 :             p5->set_floating_point(907.231);
    1226            1 :             list->insert_child(-1, p5);
    1227            1 :             prinbee::pbql::node::pointer_t p6(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1228            1 :             p6->set_floating_point(96.689);
    1229            1 :             list->insert_child(-1, p6);
    1230            1 :             prinbee::pbql::node::pointer_t p7(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1231            1 :             p7->set_floating_point(1.0216);
    1232            1 :             list->insert_child(-1, p7);
    1233            1 :             prinbee::pbql::node::pointer_t p8(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1234            1 :             p8->set_floating_point(0.002);
    1235            1 :             list->insert_child(-1, p8);
    1236            1 :             prinbee::pbql::node::pointer_t p9(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1237            1 :             p9->set_floating_point(0.202);
    1238            1 :             list->insert_child(-1, p9);
    1239            1 :             prinbee::pbql::node::pointer_t p10(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_FLOATING_POINT, l));
    1240            1 :             p10->set_floating_point(0.202);
    1241            1 :             list->insert_child(-1, p10);
    1242            1 :             std::string const result(f->to_as2js());
    1243            1 :             CATCH_REQUIRE(result == "Math.sum(501.3,1.012,7.902,3.1,907.231,96.689,1.0216,0.002,0.202,0.202)");
    1244            1 :         }
    1245            1 :     }
    1246           14 :     CATCH_END_SECTION()
    1247              : 
    1248           15 :     CATCH_START_SECTION("node: LIKE and ILIKE to regex")
    1249              :     {
    1250            1 :         prinbee::pbql::location l;
    1251              : 
    1252              :         // make sure all the characters except '%' are properly escaped (LIKE)
    1253              :         {
    1254            1 :             prinbee::pbql::node::pointer_t like(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_LIKE, l));
    1255            1 :             prinbee::pbql::node::pointer_t value(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1256            3 :             value->set_string("value being checked using ILIKE");
    1257            1 :             like->insert_child(-1, value);
    1258            1 :             prinbee::pbql::node::pointer_t pattern(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1259            3 :             pattern->set_string("/(LIKE+ | p_a_t_t_e_r_n? \\with* % and [nothing] {el,se}.)/");
    1260            1 :             like->insert_child(-1, pattern);
    1261            1 :             std::string const result(like->to_as2js());
    1262            1 :             CATCH_REQUIRE(result == "new RegExp(\"^\\/\\(LIKE\\+ \\| p_a_t_t_e_r_n\\? \\\\with\\* .* and \\[nothing\\] \\{el,se\\}\\.\\)\\/$\").test(\"value being checked using ILIKE\")");
    1263            1 :         }
    1264              : 
    1265              :         // make sure all the characters except '%' are properly escaped (ILIKE)
    1266              :         {
    1267            1 :             prinbee::pbql::node::pointer_t ilike(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_ILIKE, l));
    1268            1 :             prinbee::pbql::node::pointer_t value(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1269            3 :             value->set_string("value being checked using ILIKE");
    1270            1 :             ilike->insert_child(-1, value);
    1271            1 :             prinbee::pbql::node::pointer_t pattern(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1272            3 :             pattern->set_string("/(LIKE+ | p_a_t_t_e_r_n? \\with* % and [nothing] {el,se}.)/");
    1273            1 :             ilike->insert_child(-1, pattern);
    1274            1 :             std::string const result(ilike->to_as2js());
    1275            1 :             CATCH_REQUIRE(result == "new RegExp(\"^\\/\\(LIKE\\+ \\| p_a_t_t_e_r_n\\? \\\\with\\* .* and \\[nothing\\] \\{el,se\\}\\.\\)\\/$\",\"i\").test(\"value being checked using ILIKE\")");
    1276            1 :         }
    1277            1 :     }
    1278           14 :     CATCH_END_SECTION()
    1279              : 
    1280           15 :     CATCH_START_SECTION("node: convert to tree")
    1281              :     {
    1282              :         struct token_to_tree_t
    1283              :         {
    1284              :             prinbee::pbql::token_t      f_token = prinbee::pbql::token_t::TOKEN_UNKNOWN;
    1285              :             std::string                 f_tree = std::string();
    1286              :         };
    1287              : 
    1288            1 :         token_to_tree_t token_to_tree[] =
    1289              :         {
    1290              :             {
    1291              :                 .f_token = prinbee::pbql::token_t::TOKEN_EOF,
    1292              :                 .f_tree = "EOF",
    1293              :             },
    1294              :             {
    1295              :                 .f_token = prinbee::pbql::token_t::TOKEN_BITWISE_XOR,
    1296              :                 .f_tree = "#",
    1297              :             },
    1298              :             {
    1299              :                 .f_token = prinbee::pbql::token_t::TOKEN_MODULO,
    1300              :                 .f_tree = "%",
    1301              :             },
    1302              :             {
    1303              :                 .f_token = prinbee::pbql::token_t::TOKEN_BITWISE_AND,
    1304              :                 .f_tree = "&",
    1305              :             },
    1306              :             {
    1307              :                 .f_token = prinbee::pbql::token_t::TOKEN_OPEN_PARENTHESIS,
    1308              :                 .f_tree = "(",
    1309              :             },
    1310              :             {
    1311              :                 .f_token = prinbee::pbql::token_t::TOKEN_CLOSE_PARENTHESIS,
    1312              :                 .f_tree = ")",
    1313              :             },
    1314              :             {
    1315              :                 .f_token = prinbee::pbql::token_t::TOKEN_MULTIPLY,
    1316              :                 .f_tree = "*",
    1317              :             },
    1318              :             {
    1319              :                 .f_token = prinbee::pbql::token_t::TOKEN_PLUS,
    1320              :                 .f_tree = "+",
    1321              :             },
    1322              :             {
    1323              :                 .f_token = prinbee::pbql::token_t::TOKEN_COMMA,
    1324              :                 .f_tree = ",",
    1325              :             },
    1326              :             {
    1327              :                 .f_token = prinbee::pbql::token_t::TOKEN_MINUS,
    1328              :                 .f_tree = "-",
    1329              :             },
    1330              :             {
    1331              :                 .f_token = prinbee::pbql::token_t::TOKEN_PERIOD,
    1332              :                 .f_tree = ".",
    1333              :             },
    1334              :             {
    1335              :                 .f_token = prinbee::pbql::token_t::TOKEN_DIVIDE,
    1336              :                 .f_tree = "/",
    1337              :             },
    1338              :             {
    1339              :                 .f_token = prinbee::pbql::token_t::TOKEN_COLON,
    1340              :                 .f_tree = ":",
    1341              :             },
    1342              :             {
    1343              :                 .f_token = prinbee::pbql::token_t::TOKEN_SEMI_COLON,
    1344              :                 .f_tree = ";",
    1345              :             },
    1346              :             {
    1347              :                 .f_token = prinbee::pbql::token_t::TOKEN_LESS,
    1348              :                 .f_tree = "<",
    1349              :             },
    1350              :             {
    1351              :                 .f_token = prinbee::pbql::token_t::TOKEN_EQUAL,
    1352              :                 .f_tree = "=",
    1353              :             },
    1354              :             {
    1355              :                 .f_token = prinbee::pbql::token_t::TOKEN_GREATER,
    1356              :                 .f_tree = ">",
    1357              :             },
    1358              :             {
    1359              :                 .f_token = prinbee::pbql::token_t::TOKEN_ABSOLUTE_VALUE,
    1360              :                 .f_tree = "@",
    1361              :             },
    1362              :             {
    1363              :                 .f_token = prinbee::pbql::token_t::TOKEN_OPEN_BRACKET,
    1364              :                 .f_tree = "[",
    1365              :             },
    1366              :             {
    1367              :                 .f_token = prinbee::pbql::token_t::TOKEN_CLOSE_BRACKET,
    1368              :                 .f_tree = "]",
    1369              :             },
    1370              :             {
    1371              :                 .f_token = prinbee::pbql::token_t::TOKEN_POWER,
    1372              :                 .f_tree = "^",
    1373              :             },
    1374              :             {
    1375              :                 .f_token = prinbee::pbql::token_t::TOKEN_BITWISE_OR,
    1376              :                 .f_tree = "|",
    1377              :             },
    1378              :             {
    1379              :                 .f_token = prinbee::pbql::token_t::TOKEN_REGULAR_EXPRESSION,
    1380              :                 .f_tree = "~",
    1381              :             },
    1382              :             {
    1383              :                 .f_token = prinbee::pbql::token_t::TOKEN_IDENTIFIER,
    1384              :                 .f_tree = "IDENTIFIER S:\"\"",
    1385              :             },
    1386              :             {
    1387              :                 .f_token = prinbee::pbql::token_t::TOKEN_STRING,
    1388              :                 .f_tree = "STRING S:\"\"",
    1389              :             },
    1390              :             {
    1391              :                 .f_token = prinbee::pbql::token_t::TOKEN_INTEGER,
    1392              :                 .f_tree = "INTEGER I:0",
    1393              :             },
    1394              :             {
    1395              :                 .f_token = prinbee::pbql::token_t::TOKEN_FLOATING_POINT,
    1396              :                 .f_tree = "FLOATING_POINT F:0.000000",
    1397              :             },
    1398              :             {
    1399              :                 .f_token = prinbee::pbql::token_t::TOKEN_NOT_EQUAL,
    1400              :                 .f_tree = "NOT_EQUAL",
    1401              :             },
    1402              :             {
    1403              :                 .f_token = prinbee::pbql::token_t::TOKEN_LESS_EQUAL,
    1404              :                 .f_tree = "LESS_EQUAL",
    1405              :             },
    1406              :             {
    1407              :                 .f_token = prinbee::pbql::token_t::TOKEN_GREATER_EQUAL,
    1408              :                 .f_tree = "GREATER_EQUAL",
    1409              :             },
    1410              :             {
    1411              :                 .f_token = prinbee::pbql::token_t::TOKEN_SQUARE_ROOT,
    1412              :                 .f_tree = "SQUARE_ROOT",
    1413              :             },
    1414              :             {
    1415              :                 .f_token = prinbee::pbql::token_t::TOKEN_CUBE_ROOT,
    1416              :                 .f_tree = "CUBE_ROOT",
    1417              :             },
    1418              :             {
    1419              :                 .f_token = prinbee::pbql::token_t::TOKEN_SCOPE,
    1420              :                 .f_tree = "SCOPE",
    1421              :             },
    1422              :             {
    1423              :                 .f_token = prinbee::pbql::token_t::TOKEN_SHIFT_LEFT,
    1424              :                 .f_tree = "SHIFT_LEFT",
    1425              :             },
    1426              :             {
    1427              :                 .f_token = prinbee::pbql::token_t::TOKEN_SHIFT_RIGHT,
    1428              :                 .f_tree = "SHIFT_RIGHT",
    1429              :             },
    1430              :             {
    1431              :                 .f_token = prinbee::pbql::token_t::TOKEN_UNMATCHED_REGULAR_EXPRESSION,
    1432              :                 .f_tree = "UNMATCHED_REGULAR_EXPRESSION",
    1433              :             },
    1434              :             {
    1435              :                 .f_token = prinbee::pbql::token_t::TOKEN_STRING_CONCAT,
    1436              :                 .f_tree = "STRING_CONCAT",
    1437              :             },
    1438              :             {
    1439              :                 .f_token = prinbee::pbql::token_t::TOKEN_ALL_FIELDS,
    1440              :                 .f_tree = "ALL_FIELDS",
    1441              :             },
    1442              :             {
    1443              :                 .f_token = prinbee::pbql::token_t::TOKEN_AT,
    1444              :                 .f_tree = "AT",
    1445              :             },
    1446              :             {
    1447              :                 .f_token = prinbee::pbql::token_t::TOKEN_BETWEEN,
    1448              :                 .f_tree = "BETWEEN",
    1449              :             },
    1450              :             {
    1451              :                 .f_token = prinbee::pbql::token_t::TOKEN_CAST,
    1452              :                 .f_tree = "CAST",
    1453              :             },
    1454              :             {
    1455              :                 .f_token = prinbee::pbql::token_t::TOKEN_FALSE,
    1456              :                 .f_tree = "FALSE",
    1457              :             },
    1458              :             {
    1459              :                 .f_token = prinbee::pbql::token_t::TOKEN_FUNCTION_CALL,
    1460              :                 .f_tree = "FUNCTION_CALL S:\"\"",
    1461              :             },
    1462              :             {
    1463              :                 .f_token = prinbee::pbql::token_t::TOKEN_ILIKE,
    1464              :                 .f_tree = "ILIKE",
    1465              :             },
    1466              :             {
    1467              :                 .f_token = prinbee::pbql::token_t::TOKEN_LIKE,
    1468              :                 .f_tree = "LIKE",
    1469              :             },
    1470              :             {
    1471              :                 .f_token = prinbee::pbql::token_t::TOKEN_LIST,
    1472              :                 .f_tree = "LIST",
    1473              :             },
    1474              :             {
    1475              :                 .f_token = prinbee::pbql::token_t::TOKEN_LOGICAL_OR,
    1476              :                 .f_tree = "LOGICAL_OR",
    1477              :             },
    1478              :             {
    1479              :                 .f_token = prinbee::pbql::token_t::TOKEN_LOGICAL_AND,
    1480              :                 .f_tree = "LOGICAL_AND",
    1481              :             },
    1482              :             {
    1483              :                 .f_token = prinbee::pbql::token_t::TOKEN_LOGICAL_NOT,
    1484              :                 .f_tree = "LOGICAL_NOT",
    1485              :             },
    1486              :             {
    1487              :                 .f_token = prinbee::pbql::token_t::TOKEN_NULL,
    1488              :                 .f_tree = "NULL",
    1489              :             },
    1490              :             {
    1491              :                 .f_token = prinbee::pbql::token_t::TOKEN_TRUE,
    1492              :                 .f_tree = "TRUE",
    1493              :             },
    1494              :             {
    1495              :                 .f_token = prinbee::pbql::token_t::TOKEN_TYPE,
    1496              :                 .f_tree = "TYPE T:0",
    1497              :             },
    1498           55 :         };
    1499              : 
    1500            1 :         prinbee::pbql::location l;
    1501           53 :         for(auto const & t : token_to_tree)
    1502              :         {
    1503           52 :             prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(t.f_token, l));
    1504           52 :             std::string const tree(n->to_tree(0));
    1505           52 :             if(t.f_tree.length() == 1)
    1506              :             {
    1507           22 :                 CATCH_REQUIRE('\'' + t.f_tree + "'\n" == tree);
    1508              :             }
    1509              :             else
    1510              :             {
    1511           30 :                 CATCH_REQUIRE(t.f_tree + '\n' == tree);
    1512              :             }
    1513           52 :         }
    1514           54 :     }
    1515           14 :     CATCH_END_SECTION()
    1516           13 : }
    1517              : 
    1518              : 
    1519            6 : CATCH_TEST_CASE("node_error", "[node][pbql][error]")
    1520              : {
    1521            8 :     CATCH_START_SECTION("node_error: invalid token")
    1522              :     {
    1523            1 :         prinbee::pbql::token_t const invalid_token[] = {
    1524              :             prinbee::pbql::token_t::TOKEN_UNKNOWN,
    1525              :             prinbee::pbql::token_t::TOKEN_other,
    1526              :             prinbee::pbql::token_t::TOKEN_max,
    1527              :         };
    1528              : 
    1529            1 :         prinbee::pbql::location l;
    1530            8 :         for(std::size_t idx(0); idx < std::size(invalid_token); ++idx)
    1531              :         {
    1532            6 :             CATCH_REQUIRE_THROWS_MATCHES(
    1533              :                       std::make_shared<prinbee::pbql::node>(invalid_token[idx], l)
    1534              :                     , prinbee::invalid_token
    1535              :                     , Catch::Matchers::ExceptionMessage(
    1536              :                               "prinbee_exception: node created with an invalid token ("
    1537              :                             + std::to_string(static_cast<int>(invalid_token[idx]))
    1538              :                             + ")."));
    1539              :         }
    1540            1 :     }
    1541            7 :     CATCH_END_SECTION()
    1542              : 
    1543            8 :     CATCH_START_SECTION("node_error: child not found")
    1544              :     {
    1545            1 :         prinbee::pbql::location l;
    1546            1 :         prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_IDENTIFIER, l));
    1547            4 :         CATCH_REQUIRE_THROWS_MATCHES(
    1548              :                   n->get_child(0)
    1549              :                 , prinbee::out_of_range
    1550              :                 , Catch::Matchers::ExceptionMessage(
    1551              :                           "out_of_range: child 0 does not exist."));
    1552            1 :     }
    1553            7 :     CATCH_END_SECTION()
    1554              : 
    1555            8 :     CATCH_START_SECTION("node_error: insert child at wrong position")
    1556              :     {
    1557            1 :         prinbee::pbql::location l;
    1558            1 :         prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_IDENTIFIER, l));
    1559            1 :         prinbee::pbql::node::pointer_t c(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_IDENTIFIER, l));
    1560            5 :         CATCH_REQUIRE_THROWS_MATCHES(
    1561              :                   n->insert_child(3, c)
    1562              :                 , prinbee::out_of_range
    1563              :                 , Catch::Matchers::ExceptionMessage(
    1564              :                           "out_of_range: child 3 does not exist."));
    1565            1 :     }
    1566            7 :     CATCH_END_SECTION()
    1567              : 
    1568            8 :     CATCH_START_SECTION("node_error: set child at wrong position")
    1569              :     {
    1570            1 :         prinbee::pbql::location l;
    1571            1 :         prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_IDENTIFIER, l));
    1572            1 :         prinbee::pbql::node::pointer_t c1(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_IDENTIFIER, l));
    1573            1 :         n->insert_child(-1, c1);
    1574            1 :         prinbee::pbql::node::pointer_t c2(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_IDENTIFIER, l));
    1575            1 :         n->set_child(0, c2);
    1576              : 
    1577           10 :         for(int i(1); i < 10; ++i)
    1578              :         {
    1579            9 :             prinbee::pbql::node::pointer_t c3(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_IDENTIFIER, l));
    1580           27 :             CATCH_REQUIRE_THROWS_MATCHES(
    1581              :                       n->set_child(i, c3)
    1582              :                     , prinbee::out_of_range
    1583              :                     , Catch::Matchers::ExceptionMessage(
    1584              :                               "out_of_range: child "
    1585              :                             + std::to_string(i)
    1586              :                             + " does not exist, it cannot be replaced."));
    1587            9 :         }
    1588            1 :     }
    1589            7 :     CATCH_END_SECTION()
    1590              : 
    1591            8 :     CATCH_START_SECTION("node_error: tokens that cannot be converted to as2js script")
    1592              :     {
    1593              :         struct unexpected_token_t
    1594              :         {
    1595              :             prinbee::pbql::token_t      f_token = prinbee::pbql::token_t::TOKEN_UNKNOWN;
    1596              :             char const *                f_name = nullptr;
    1597              :         };
    1598            1 :         unexpected_token_t unexpected_tokens[] =
    1599              :         {
    1600              :             {
    1601              :                 .f_token = prinbee::pbql::token_t::TOKEN_EOF,
    1602              :                 .f_name = "EOF",
    1603              :             },
    1604              :             {
    1605              :                 .f_token = prinbee::pbql::token_t::TOKEN_OPEN_PARENTHESIS,
    1606              :                 .f_name = "(",
    1607              :             },
    1608              :             {
    1609              :                 .f_token = prinbee::pbql::token_t::TOKEN_CLOSE_PARENTHESIS,
    1610              :                 .f_name = ")",
    1611              :             },
    1612              :             {
    1613              :                 .f_token = prinbee::pbql::token_t::TOKEN_COMMA,
    1614              :                 .f_name = ",",
    1615              :             },
    1616              :             {
    1617              :                 .f_token = prinbee::pbql::token_t::TOKEN_COLON,
    1618              :                 .f_name = ":",
    1619              :             },
    1620              :             {
    1621              :                 .f_token = prinbee::pbql::token_t::TOKEN_SEMI_COLON,
    1622              :                 .f_name = ";",
    1623              :             },
    1624              :             {
    1625              :                 .f_token = prinbee::pbql::token_t::TOKEN_ABSOLUTE_VALUE,
    1626              :                 .f_name = "@",
    1627              :             },
    1628              :             {
    1629              :                 .f_token = prinbee::pbql::token_t::TOKEN_OPEN_BRACKET,
    1630              :                 .f_name = "[",
    1631              :             },
    1632              :             {
    1633              :                 .f_token = prinbee::pbql::token_t::TOKEN_CLOSE_BRACKET,
    1634              :                 .f_name = "]",
    1635              :             },
    1636              :             {
    1637              :                 .f_token = prinbee::pbql::token_t::TOKEN_SCOPE,
    1638              :                 .f_name = "SCOPE",
    1639              :             },
    1640              :             {
    1641              :                 .f_token = prinbee::pbql::token_t::TOKEN_STRING_CONCAT,
    1642              :                 .f_name = "STRING_CONCAT",
    1643              :             },
    1644              :             {
    1645              :                 .f_token = prinbee::pbql::token_t::TOKEN_LIST,
    1646              :                 .f_name = "LIST",
    1647              :             },
    1648              :         };
    1649           13 :         for(auto const & u : unexpected_tokens)
    1650              :         {
    1651           12 :             prinbee::pbql::location l;
    1652           12 :             prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(u.f_token, l));
    1653           48 :             CATCH_REQUIRE_THROWS_MATCHES(
    1654              :                       n->to_as2js()
    1655              :                     , prinbee::invalid_token
    1656              :                     , Catch::Matchers::ExceptionMessage(
    1657              :                               "prinbee_exception: node with token type "
    1658              :                             + (u.f_name[1] == '\0' ? std::string(1, '\'') + u.f_name + '\'' : std::string(u.f_name))
    1659              :                             + " cannot directly be converted to as2js script."));
    1660           12 :         }
    1661              :     }
    1662            7 :     CATCH_END_SECTION()
    1663              : 
    1664            8 :     CATCH_START_SECTION("node_error: invalid nodes for auto-convert")
    1665              :     {
    1666              :         { // totally wrong node
    1667            1 :             prinbee::pbql::location l;
    1668            1 :             prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_SHIFT_LEFT, l));
    1669              : 
    1670            4 :             CATCH_REQUIRE_THROWS_MATCHES(
    1671              :                       n->get_string_auto_convert()
    1672              :                     , prinbee::logic_error
    1673              :                     , Catch::Matchers::ExceptionMessage(
    1674              :                               "logic_error: node is not a literal and it cannot be converted to a string."));
    1675              : 
    1676            3 :             CATCH_REQUIRE_THROWS_MATCHES(
    1677              :                       n->get_boolean_auto_convert()
    1678              :                     , prinbee::logic_error
    1679              :                     , Catch::Matchers::ExceptionMessage(
    1680              :                               "logic_error: node is not a literal representing a Boolean and as a result it cannot be converted to a Boolean."));
    1681              : 
    1682            4 :             CATCH_REQUIRE_THROWS_MATCHES(
    1683              :                       n->get_integer_auto_convert()
    1684              :                     , prinbee::logic_error
    1685              :                     , Catch::Matchers::ExceptionMessage(
    1686              :                               "logic_error: node is not a literal representing a number and it cannot be converted to an integer."));
    1687              : 
    1688            3 :             CATCH_REQUIRE_THROWS_MATCHES(
    1689              :                       n->get_floating_point_auto_convert()
    1690              :                     , prinbee::logic_error
    1691              :                     , Catch::Matchers::ExceptionMessage(
    1692              :                               "logic_error: node is not a literal representing a number and it cannot be converted to a floating point."));
    1693            1 :         }
    1694              : 
    1695              :         { // string not representing a valid boolean
    1696            1 :             prinbee::pbql::location l;
    1697            1 :             prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1698              : 
    1699            3 :             n->set_string("not-boolean");
    1700            3 :             CATCH_REQUIRE_THROWS_MATCHES(
    1701              :                       n->get_boolean_auto_convert()
    1702              :                     , prinbee::logic_error
    1703              :                     , Catch::Matchers::ExceptionMessage(
    1704              :                               "logic_error: node is not a literal representing a Boolean and as a result it cannot be converted to a Boolean."));
    1705              : 
    1706            3 :             n->set_string("trues");
    1707            3 :             CATCH_REQUIRE_THROWS_MATCHES(
    1708              :                       n->get_boolean_auto_convert()
    1709              :                     , prinbee::logic_error
    1710              :                     , Catch::Matchers::ExceptionMessage(
    1711              :                               "logic_error: node is not a literal representing a Boolean and as a result it cannot be converted to a Boolean."));
    1712              : 
    1713            3 :             n->set_string("falses");
    1714            3 :             CATCH_REQUIRE_THROWS_MATCHES(
    1715              :                       n->get_boolean_auto_convert()
    1716              :                     , prinbee::logic_error
    1717              :                     , Catch::Matchers::ExceptionMessage(
    1718              :                               "logic_error: node is not a literal representing a Boolean and as a result it cannot be converted to a Boolean."));
    1719            1 :         }
    1720              : 
    1721              :         { // string not representing a valid numbers (empty)
    1722            1 :             prinbee::pbql::location l;
    1723            1 :             prinbee::pbql::node::pointer_t n(std::make_shared<prinbee::pbql::node>(prinbee::pbql::token_t::TOKEN_STRING, l));
    1724              : 
    1725            4 :             CATCH_REQUIRE_THROWS_MATCHES(
    1726              :                       n->get_integer_auto_convert()
    1727              :                     , prinbee::invalid_number
    1728              :                     , Catch::Matchers::ExceptionMessage(
    1729              :                               "prinbee_exception: string \"\" does not represent a valid integer."));
    1730              : 
    1731            3 :             CATCH_REQUIRE_THROWS_MATCHES(
    1732              :                       n->get_floating_point_auto_convert()
    1733              :                     , prinbee::invalid_number
    1734              :                     , Catch::Matchers::ExceptionMessage(
    1735              :                               "prinbee_exception: string \"\" does not represent a valid floating point number."));
    1736            1 :         }
    1737              :     }
    1738            7 :     CATCH_END_SECTION()
    1739            6 : }
    1740              : 
    1741              : 
    1742              : 
    1743              : // vim: ts=4 sw=4 et
        

Generated by: LCOV version 2.0-1

Snap C++ | List of projects | List of versions