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
|