Line data Source code
1 : // Copyright (c) 2011-2023 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/as2js
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 : // as2js
20 : //
21 : #include <as2js/binary.h>
22 :
23 :
24 :
25 : // self
26 : //
27 : #include "catch_main.h"
28 :
29 :
30 : // snapdev
31 : //
32 : #include <snapdev/file_contents.h>
33 : #include <snapdev/glob_to_list.h>
34 : #include <snapdev/pathinfo.h>
35 : #include <snapdev/to_lower.h>
36 :
37 :
38 : // C++
39 : //
40 : #include <iomanip>
41 :
42 :
43 : // C
44 : //
45 : #include <math.h>
46 :
47 :
48 : // last include
49 : //
50 : #include <snapdev/poison.h>
51 :
52 :
53 :
54 : namespace
55 : {
56 :
57 :
58 :
59 33 : void run_script(std::string const & s)
60 : {
61 66 : std::string cmd("export AS2JS_RC='");
62 33 : cmd += SNAP_CATCH2_NAMESPACE::g_binary_dir();
63 33 : cmd += "' && ";
64 : //cmd += "gdb -ex \"catch throws\" -ex \"run\" -args ";
65 33 : cmd += SNAP_CATCH2_NAMESPACE::g_binary_dir();
66 33 : cmd += "/tools/as2js -b -o ";
67 33 : cmd += SNAP_CATCH2_NAMESPACE::g_binary_dir();
68 33 : cmd += "/tests/a.out ";
69 33 : cmd += s;
70 :
71 : // for the script to work, the compiler must find the scripts directory
72 : // which is defined in the rc file
73 : //
74 : {
75 33 : std::ofstream rc("as2js/as2js.rc");
76 : rc << "{\"scripts\":\""
77 33 : << SNAP_CATCH2_NAMESPACE::g_source_dir()
78 33 : << "/scripts\"}\n";
79 33 : }
80 :
81 : // first compile the file
82 : //
83 : std::cout
84 : << "--- compile script to binary with command \""
85 : << cmd
86 33 : << "\".\n";
87 33 : int const r(system(cmd.c_str()));
88 33 : std::cerr << "-------------- system() called returned from binary test (" << r << ")\n";
89 33 : CATCH_REQUIRE(r == 0);
90 66 : }
91 :
92 :
93 :
94 : enum class value_type_t : std::uint16_t
95 : {
96 : VALUE_TYPE_UNDEFINED,
97 : VALUE_TYPE_BOOLEAN,
98 : VALUE_TYPE_INTEGER,
99 : VALUE_TYPE_FLOATING_POINT,
100 : VALUE_TYPE_STRING,
101 : };
102 :
103 : typedef std::uint16_t flags_t;
104 :
105 : constexpr flags_t const VALUE_FLAG_IN = 0x0000;
106 : constexpr flags_t const VALUE_FLAG_OUT = 0x0001;
107 :
108 : struct value_flags
109 : {
110 : std::string f_value = std::string();
111 : value_type_t f_type = value_type_t::VALUE_TYPE_UNDEFINED;
112 : flags_t f_flags = 0;
113 :
114 732 : void set_type(value_type_t t)
115 : {
116 732 : CATCH_REQUIRE(f_type == value_type_t::VALUE_TYPE_UNDEFINED); // trying to set the type more than once?
117 732 : f_type = t;
118 732 : }
119 :
120 1437 : void set_type(std::string t)
121 : {
122 1437 : t = snapdev::to_lower(t);
123 1437 : if(t == "boolean")
124 : {
125 222 : set_type(value_type_t::VALUE_TYPE_BOOLEAN);
126 : }
127 1215 : else if(t == "integer")
128 : {
129 23 : set_type(value_type_t::VALUE_TYPE_INTEGER);
130 : }
131 1192 : else if(t == "double")
132 : {
133 289 : set_type(value_type_t::VALUE_TYPE_FLOATING_POINT);
134 : }
135 903 : else if(t == "string")
136 : {
137 93 : set_type(value_type_t::VALUE_TYPE_STRING);
138 : }
139 810 : else if(t == "in")
140 : {
141 0 : f_flags |= VALUE_FLAG_IN;
142 : }
143 810 : else if(t == "out")
144 : {
145 810 : f_flags |= VALUE_FLAG_OUT;
146 : }
147 : else
148 : {
149 0 : CATCH_REQUIRE(t == "");
150 : }
151 1437 : }
152 :
153 2095 : value_type_t get_type() const
154 : {
155 2095 : return f_type == value_type_t::VALUE_TYPE_UNDEFINED
156 2095 : ? value_type_t::VALUE_TYPE_INTEGER
157 2095 : : f_type;
158 : }
159 :
160 2746 : bool is_out() const
161 : {
162 2746 : return (f_flags & VALUE_FLAG_OUT) != 0;
163 : }
164 : };
165 :
166 :
167 : typedef std::map<std::string, value_flags> variable_t;
168 :
169 : struct meta
170 : {
171 : variable_t f_variables = variable_t();
172 : value_flags f_result = value_flags();
173 : };
174 :
175 :
176 33 : meta load_script_meta(std::string const & s)
177 : {
178 33 : meta result;
179 :
180 165 : std::string const filename(snapdev::pathinfo::replace_suffix(s, ".ajs", ".meta"));
181 :
182 33 : snapdev::file_contents meta(filename);
183 33 : CATCH_REQUIRE(meta.read_all());
184 :
185 33 : std::string const & str(meta.contents());
186 :
187 33 : char const * m(str.c_str());
188 2316 : while(*m != '\0')
189 : {
190 2283 : while(*m == ' ' || *m == '\t')
191 : {
192 0 : ++m;
193 : }
194 2283 : if(*m == '\0')
195 : {
196 0 : return result;
197 : }
198 2283 : if(*m == '#')
199 : {
200 : // skip comments
201 : //
202 1061 : while(*m != '\n')
203 : {
204 978 : if(*m == '\0')
205 : {
206 0 : return result;
207 : }
208 978 : ++m;
209 : }
210 83 : continue;
211 : }
212 :
213 2200 : if(*m == '\n')
214 : {
215 : // empty line
216 : //
217 1251 : ++m;
218 1251 : continue;
219 : }
220 :
221 : // we have either a variable or a result preceeded by keywords:
222 : //
223 : // [<keyword>] (<result>)
224 : // [<keyword>] <name>=<value>
225 : //
226 949 : std::string name;
227 949 : value_flags value;
228 19492 : while(*m != '=' && *m != '(')
229 : {
230 18543 : CATCH_REQUIRE(*m != '\n');
231 18543 : CATCH_REQUIRE(*m != '\0');
232 18543 : if(isspace(*m))
233 : {
234 : // skip all spaces
235 : //
236 : do
237 : {
238 1437 : ++m;
239 : }
240 1437 : while(*m == ' ' || *m == '\t');
241 :
242 : // check whether it is the last word before the '=', if so,
243 : // it is taken as the variable name and not a <keyword>
244 : //
245 1437 : if(*m == '=')
246 : {
247 0 : break;
248 : }
249 :
250 : // parse as a type or flag
251 : //
252 1437 : value.set_type(name);
253 1437 : name.clear();
254 : }
255 : else
256 : {
257 17106 : name += *m;
258 17106 : ++m;
259 : }
260 : }
261 :
262 949 : if(*m == '(')
263 : {
264 33 : CATCH_REQUIRE(name.empty());
265 33 : result.f_result = value;
266 :
267 : // expected result
268 : // (<value>)
269 : //
270 33 : ++m;
271 33 : CATCH_REQUIRE(result.f_result.f_value.empty()); // prevent double definition
272 434 : while(*m != ')')
273 : {
274 401 : CATCH_REQUIRE(*m != '\n');
275 401 : CATCH_REQUIRE(*m != '\0');
276 401 : result.f_result.f_value += *m;
277 401 : ++m;
278 : }
279 33 : ++m;
280 :
281 33 : if(result.f_result.f_value.length() >= 2
282 33 : && (result.f_result.f_value[0] == '"' || result.f_result.f_value[0] == '\'')
283 11 : && result.f_result.f_value[0] == result.f_result.f_value.back()
284 66 : && result.f_result.get_type() == value_type_t::VALUE_TYPE_INTEGER)
285 : {
286 : // default to INTEGER, unless value is surrounded by quotes
287 : //
288 1 : result.f_result.set_type(value_type_t::VALUE_TYPE_STRING);
289 : }
290 :
291 33 : if(result.f_result.get_type() == value_type_t::VALUE_TYPE_STRING
292 11 : && result.f_result.f_value.length() >= 2
293 11 : && (result.f_result.f_value[0] == '"' || result.f_result.f_value[0] == '\'')
294 44 : && result.f_result.f_value[0] == result.f_result.f_value.back())
295 : {
296 : // remove quotes around string
297 : //
298 11 : result.f_result.f_value = result.f_result.f_value.substr(1, result.f_result.f_value.length() - 2);
299 : }
300 :
301 33 : while(*m == ' ' || *m == '\t')
302 : {
303 : //std::cerr << "--- result [" << result.f_result << "] -> skipping [" << static_cast<int>(*m) << "]\n";
304 0 : ++m;
305 : }
306 33 : if(*m != '\n')
307 : {
308 0 : CATCH_REQUIRE(*m == '\0');
309 0 : return result;
310 : }
311 33 : ++m;
312 33 : continue;
313 33 : }
314 916 : ++m; // skip '='
315 :
316 916 : CATCH_REQUIRE_FALSE(name.empty());
317 :
318 8420 : while(*m != '\n' && *m != '\0')
319 : {
320 7504 : value.f_value += *m;
321 7504 : ++m;
322 : }
323 :
324 : // TODO: add support for spaces/tabs after the closing quotation
325 : //
326 916 : if(value.f_value.length() >= 2
327 843 : && (value.f_value[0] == '"' || value.f_value[0] == '\'')
328 187 : && value.f_value[0] == value.f_value.back()
329 1759 : && value.get_type() == value_type_t::VALUE_TYPE_INTEGER)
330 : {
331 : // default to INTEGER, unless value is surrounded by quotes
332 : //
333 104 : value.set_type(value_type_t::VALUE_TYPE_STRING);
334 : }
335 :
336 916 : if(value.get_type() == value_type_t::VALUE_TYPE_STRING
337 187 : && value.f_value.length() >= 2
338 187 : && (value.f_value[0] == '"' || value.f_value[0] == '\'')
339 1103 : && value.f_value[0] == value.f_value.back())
340 : {
341 : // remove quotes around string
342 : //
343 187 : value.f_value = value.f_value.substr(1, value.f_value.length() - 2);
344 : }
345 :
346 : // when defining an "out" the name must be distinct otherwise it would
347 : // smash the "in"
348 : //
349 916 : if(value.is_out())
350 : {
351 810 : name = "<-" + name;
352 : }
353 : //std::cerr << "--- found name [" << name << "]\n";
354 916 : result.f_variables[name] = value;
355 982 : }
356 :
357 33 : return result;
358 33 : }
359 :
360 :
361 33 : void execute(meta const & m)
362 : {
363 33 : std::string filename(SNAP_CATCH2_NAMESPACE::g_binary_dir());
364 33 : filename += "/tests/a.out";
365 :
366 33 : as2js::running_file script;
367 33 : CATCH_REQUIRE(script.load(filename));
368 :
369 948 : for(auto const & var : m.f_variables)
370 : {
371 915 : if(!var.second.is_out())
372 : {
373 : // TODO: support all types of variables
374 : //
375 106 : switch(var.second.get_type())
376 : {
377 11 : case value_type_t::VALUE_TYPE_BOOLEAN:
378 : {
379 11 : bool value(false);
380 11 : if(var.second.f_value == "true")
381 : {
382 7 : value = true;
383 : }
384 : else
385 : {
386 : // value must be "true" or "false"
387 : //
388 4 : CATCH_REQUIRE(var.second.f_value == "false");
389 : }
390 11 : script.set_variable(var.first, value);
391 : }
392 11 : break;
393 :
394 37 : case value_type_t::VALUE_TYPE_INTEGER:
395 : {
396 37 : std::int64_t const value(std::stoll(var.second.f_value, nullptr, 0));
397 37 : script.set_variable(var.first, value);
398 : }
399 37 : break;
400 :
401 29 : case value_type_t::VALUE_TYPE_FLOATING_POINT:
402 : {
403 29 : double value(0.0);
404 29 : if(m.f_result.f_value == "MIN_VALUE")
405 : {
406 0 : value = std::numeric_limits<double>::min();
407 : }
408 29 : else if(m.f_result.f_value == "MAX_VALUE")
409 : {
410 0 : value = std::numeric_limits<double>::max();
411 : }
412 29 : else if(var.second.f_value == "POSITIVE_INFINITY")
413 : {
414 0 : value = std::numeric_limits<double>::infinity();
415 : }
416 29 : else if(var.second.f_value == "NEGATIVE_INFINITY")
417 : {
418 0 : value = -std::numeric_limits<double>::infinity();
419 : }
420 29 : else if(var.second.f_value == "EPSILON")
421 : {
422 0 : value = 2.220446049250313e-16;
423 : }
424 : else
425 : {
426 29 : value = std::stod(var.second.f_value, nullptr);
427 : }
428 29 : script.set_variable(var.first, value);
429 : }
430 29 : break;
431 :
432 29 : case value_type_t::VALUE_TYPE_STRING:
433 29 : script.set_variable(var.first, var.second.f_value);
434 29 : break;
435 :
436 : //case value_type_t::VALUE_TYPE_UNDEFINED:
437 0 : default:
438 0 : CATCH_REQUIRE(!"variable type not yet implemented or somehow set to UNDEFINED.");
439 0 : break;
440 :
441 : }
442 : }
443 : }
444 :
445 66 : as2js::binary_result result;
446 :
447 33 : script.run(result);
448 :
449 33 : switch(m.f_result.get_type())
450 : {
451 6 : case value_type_t::VALUE_TYPE_BOOLEAN:
452 : {
453 6 : bool expected_result(false);
454 6 : if(m.f_result.f_value == "true")
455 : {
456 0 : expected_result = true;
457 : }
458 : else
459 : {
460 : // value must be "true" or "false"
461 : //
462 6 : CATCH_REQUIRE(m.f_result.f_value == "false");
463 : }
464 6 : CATCH_REQUIRE(result.get_boolean() == expected_result);
465 : }
466 6 : break;
467 :
468 8 : case value_type_t::VALUE_TYPE_INTEGER:
469 : {
470 8 : std::int64_t const expected_result(std::stoll(m.f_result.f_value, nullptr, 0));
471 8 : if(result.get_integer() != expected_result)
472 : {
473 0 : std::cerr << "--- (integer result) differs: " << result.get_integer() << " != " << expected_result << "\n";
474 : }
475 8 : CATCH_REQUIRE(result.get_integer() == expected_result);
476 : }
477 8 : break;
478 :
479 8 : case value_type_t::VALUE_TYPE_FLOATING_POINT:
480 : {
481 8 : double expected_result(0.0);
482 8 : if(m.f_result.f_value == "MIN_VALUE")
483 : {
484 0 : expected_result = std::numeric_limits<double>::min();
485 : }
486 8 : else if(m.f_result.f_value == "MAX_VALUE")
487 : {
488 0 : expected_result = std::numeric_limits<double>::max();
489 : }
490 8 : else if(m.f_result.f_value == "POSITIVE_INFINITY")
491 : {
492 0 : expected_result = std::numeric_limits<double>::infinity();
493 : }
494 8 : else if(m.f_result.f_value == "NEGATIVE_INFINITY")
495 : {
496 0 : expected_result = -std::numeric_limits<double>::infinity();
497 : }
498 8 : else if(m.f_result.f_value == "EPSILON")
499 : {
500 0 : expected_result = 2.220446049250313e-16;
501 : }
502 : else
503 : {
504 8 : expected_result = std::stod(m.f_result.f_value, nullptr);
505 : }
506 8 : double const final_result(result.get_floating_point());
507 8 : if(!SNAP_CATCH2_NAMESPACE::nearly_equal(final_result, expected_result))
508 : {
509 0 : double const * result_ptr(&final_result);
510 0 : double const * expected_ptr(&expected_result);
511 : std::cerr
512 0 : << "--- (double result) differs: "
513 0 : << final_result
514 0 : << " != "
515 0 : << expected_result
516 : << " (0x"
517 0 : << std::setw(16) << std::setfill('0') << std::hex
518 0 : << *reinterpret_cast<std::uint64_t const *>(result_ptr)
519 : << " != 0x"
520 0 : << std::setw(16)
521 0 : << *reinterpret_cast<std::uint64_t const *>(expected_ptr)
522 0 : << std::dec
523 0 : << ")\n";
524 : }
525 8 : CATCH_REQUIRE(SNAP_CATCH2_NAMESPACE::nearly_equal(final_result, expected_result));
526 : }
527 : break;
528 :
529 11 : case value_type_t::VALUE_TYPE_STRING:
530 : {
531 11 : std::string const expected_result(m.f_result.f_value);
532 11 : if(result.get_string() != expected_result)
533 : {
534 0 : std::cerr << "--- (string result) differs: " << result.get_string() << " != " << expected_result << "\n";
535 : }
536 11 : CATCH_REQUIRE(result.get_string() == expected_result);
537 11 : }
538 : break;
539 :
540 : //case value_type_t::VALUE_TYPE_UNDEFINED:
541 0 : default:
542 0 : CATCH_REQUIRE(!"variable type not yet implemented or somehow set to UNDEFINED.");
543 0 : break;
544 :
545 : }
546 :
547 948 : for(auto const & var : m.f_variables)
548 : {
549 915 : if(var.second.is_out())
550 : {
551 : // TODO: support all types of variables
552 : //
553 809 : std::string const name(var.first.substr(2));
554 809 : switch(var.second.get_type())
555 : {
556 204 : case value_type_t::VALUE_TYPE_BOOLEAN:
557 : {
558 204 : bool expected_value(false);
559 204 : if(var.second.f_value == "true")
560 : {
561 101 : expected_value = true;
562 : }
563 : else
564 : {
565 : // value must be "true" or "false"
566 : //
567 103 : CATCH_REQUIRE(var.second.f_value == "false");
568 : }
569 204 : bool returned_value(0);
570 204 : script.get_variable(name, returned_value);
571 204 : if(returned_value != expected_value)
572 : {
573 : std::cerr
574 : << "--- invalid boolean result in \""
575 0 : << var.first
576 0 : << "\".\n";
577 : }
578 204 : CATCH_REQUIRE(returned_value == expected_value);
579 : }
580 : break;
581 :
582 195 : case value_type_t::VALUE_TYPE_INTEGER:
583 : {
584 195 : std::int64_t const expected_value(std::stoll(var.second.f_value, nullptr, 0));
585 195 : std::int64_t returned_value(0);
586 195 : script.get_variable(name, returned_value);
587 195 : if(returned_value != expected_value)
588 : {
589 : std::cerr
590 : << "--- invalid integer result in \""
591 0 : << var.first
592 0 : << "\".\n";
593 : }
594 195 : CATCH_REQUIRE(returned_value == expected_value);
595 : }
596 : break;
597 :
598 252 : case value_type_t::VALUE_TYPE_FLOATING_POINT:
599 : {
600 252 : double returned_value(0.0);
601 252 : script.get_variable(name, returned_value);
602 252 : if(var.second.f_value == "NaN")
603 : {
604 16 : CATCH_REQUIRE(std::isnan(returned_value));
605 : }
606 236 : else if(var.second.f_value == "+NaN")
607 : {
608 3 : bool const positive_nan(std::isnan(returned_value) && signbit(returned_value) == 0);
609 3 : CATCH_REQUIRE(positive_nan);
610 : }
611 233 : else if(var.second.f_value == "-NaN")
612 : {
613 5 : bool const negative_nan(std::isnan(returned_value) && signbit(returned_value) == 1);
614 5 : CATCH_REQUIRE(negative_nan);
615 : }
616 : else
617 : {
618 228 : double epsilon(0.0000000000000033);
619 228 : double expected_result(0.0);
620 228 : if(var.second.f_value == "MIN_VALUE")
621 : {
622 2 : epsilon = 0.0;
623 2 : expected_result = std::numeric_limits<double>::min();
624 : }
625 226 : else if(var.second.f_value == "MAX_VALUE")
626 : {
627 2 : epsilon = 0.0;
628 2 : expected_result = std::numeric_limits<double>::max();
629 : }
630 224 : else if(var.second.f_value == "POSITIVE_INFINITY")
631 : {
632 9 : epsilon = 0.0;
633 9 : expected_result = std::numeric_limits<double>::infinity();
634 : }
635 215 : else if(var.second.f_value == "NEGATIVE_INFINITY")
636 : {
637 5 : epsilon = 0.0;
638 5 : expected_result = -std::numeric_limits<double>::infinity();
639 : }
640 210 : else if(var.second.f_value == "EPSILON")
641 : {
642 2 : epsilon = 0.0;
643 2 : expected_result = 2.220446049250313e-16;
644 : }
645 : else
646 : {
647 : try
648 : {
649 208 : expected_result = std::stod(var.second.f_value, nullptr);
650 : }
651 0 : catch(...)
652 : {
653 : std::cerr << "error: could not convert \""
654 0 : << var.second.f_value
655 0 : << "\" to a floating point number.\n";
656 0 : throw;
657 0 : }
658 : }
659 228 : if(!SNAP_CATCH2_NAMESPACE::nearly_equal(returned_value, expected_result, epsilon))
660 : {
661 0 : double const * value_ptr(&returned_value);
662 0 : double const * expected_ptr(&expected_result);
663 : std::cerr
664 : << "--- invalid floating point result in \""
665 0 : << var.first
666 : << "\" -- "
667 0 : << std::setprecision(20)
668 0 : << returned_value
669 0 : << " != "
670 0 : << expected_result
671 : << " (0x"
672 0 : << std::setw(16) << std::setfill('0') << std::hex
673 0 : << *reinterpret_cast<std::uint64_t const *>(value_ptr)
674 : << " != 0x"
675 0 : << std::setw(16)
676 0 : << *reinterpret_cast<std::uint64_t const *>(expected_ptr)
677 0 : << std::dec
678 0 : << ")\n";
679 : }
680 228 : CATCH_REQUIRE(SNAP_CATCH2_NAMESPACE::nearly_equal(returned_value, expected_result, epsilon));
681 : }
682 : }
683 : break;
684 :
685 158 : case value_type_t::VALUE_TYPE_STRING:
686 : {
687 158 : std::string const expected_value(var.second.f_value);
688 158 : std::string returned_value;
689 158 : script.get_variable(name, returned_value);
690 158 : if(returned_value != expected_value)
691 : {
692 : std::cerr
693 : << "--- invalid string result in \""
694 0 : << var.first
695 0 : << "\".\n";
696 : }
697 158 : CATCH_REQUIRE(returned_value == expected_value);
698 158 : }
699 : break;
700 :
701 : //case value_type_t::VALUE_TYPE_UNDEFINED,
702 0 : default:
703 : std::cerr
704 0 : << "variable type "
705 0 : << static_cast<int>(var.second.get_type())
706 : << " not yet implemented in catch_binary.cpp ("
707 : << __FILE__
708 0 : << ':'
709 : << __LINE__
710 0 : << ")\n";
711 0 : CATCH_REQUIRE(!"variable type not yet implemented or somehow set to UNDEFINED.");
712 0 : break;
713 :
714 : }
715 809 : }
716 : }
717 66 : }
718 :
719 :
720 :
721 : }
722 :
723 :
724 :
725 :
726 :
727 :
728 :
729 1 : CATCH_TEST_CASE("binary_integer_operators", "[binary][integer]")
730 : {
731 1 : CATCH_START_SECTION("binary_integer_operators: test binary operators for integers")
732 : {
733 1 : snapdev::glob_to_list<std::list<std::string>> scripts;
734 1 : CATCH_REQUIRE(scripts.read_path<snapdev::glob_to_list_flag_t::GLOB_FLAG_NONE>
735 : (SNAP_CATCH2_NAMESPACE::g_source_dir()
736 : + "/tests/binary/integer_operator_*.ajs"));
737 10 : for(auto const & s : scripts)
738 : {
739 9 : run_script(s);
740 9 : meta m(load_script_meta(s));
741 9 : execute(m);
742 9 : }
743 1 : }
744 1 : CATCH_END_SECTION()
745 1 : }
746 :
747 1 : CATCH_TEST_CASE("binary_double_operators", "[binary][double][floating_point]")
748 : {
749 1 : CATCH_START_SECTION("binary_double_operators: test binary operators for doubles")
750 : {
751 1 : snapdev::glob_to_list<std::list<std::string>> scripts;
752 1 : CATCH_REQUIRE(scripts.read_path<snapdev::glob_to_list_flag_t::GLOB_FLAG_NONE>
753 : (SNAP_CATCH2_NAMESPACE::g_source_dir()
754 : + "/tests/binary/double_operator_*.ajs"));
755 10 : for(auto const & s : scripts)
756 : {
757 9 : run_script(s);
758 9 : meta m(load_script_meta(s));
759 9 : execute(m);
760 9 : }
761 1 : }
762 1 : CATCH_END_SECTION()
763 1 : }
764 :
765 1 : CATCH_TEST_CASE("binary_boolean_operators", "[binary][boolean]")
766 : {
767 1 : CATCH_START_SECTION("binary_boolean_operators: test binary operators for booleans")
768 : {
769 1 : snapdev::glob_to_list<std::list<std::string>> scripts;
770 1 : CATCH_REQUIRE(scripts.read_path<snapdev::glob_to_list_flag_t::GLOB_FLAG_NONE>
771 : (SNAP_CATCH2_NAMESPACE::g_source_dir()
772 : + "/tests/binary/boolean_operator_*.ajs"));
773 5 : for(auto const & s : scripts)
774 : {
775 4 : run_script(s);
776 4 : meta m(load_script_meta(s));
777 4 : execute(m);
778 4 : }
779 1 : }
780 1 : CATCH_END_SECTION()
781 1 : }
782 :
783 1 : CATCH_TEST_CASE("binary_math_operators", "[binary][binary_math]")
784 : {
785 1 : CATCH_START_SECTION("binary_math_operators: test binary operators for math")
786 : {
787 1 : snapdev::glob_to_list<std::list<std::string>> scripts;
788 1 : CATCH_REQUIRE(scripts.read_path<snapdev::glob_to_list_flag_t::GLOB_FLAG_NONE>
789 : (SNAP_CATCH2_NAMESPACE::g_source_dir()
790 : + "/tests/binary/math_operator_*.ajs"));
791 2 : for(auto const & s : scripts)
792 : {
793 1 : run_script(s);
794 1 : meta m(load_script_meta(s));
795 1 : execute(m);
796 1 : }
797 1 : }
798 1 : CATCH_END_SECTION()
799 1 : }
800 :
801 1 : CATCH_TEST_CASE("binary_string_operators", "[binary][binary_string]")
802 : {
803 1 : CATCH_START_SECTION("binary_string_operators: test binary operators for strings")
804 : {
805 1 : snapdev::glob_to_list<std::list<std::string>> scripts;
806 1 : CATCH_REQUIRE(scripts.read_path<snapdev::glob_to_list_flag_t::GLOB_FLAG_NONE>
807 : (SNAP_CATCH2_NAMESPACE::g_source_dir()
808 : + "/tests/binary/string_operator_*.ajs"));
809 11 : for(auto const & s : scripts)
810 : {
811 10 : run_script(s);
812 10 : meta m(load_script_meta(s));
813 10 : execute(m);
814 10 : }
815 1 : }
816 1 : CATCH_END_SECTION()
817 1 : }
818 :
819 :
820 :
821 : // vim: ts=4 sw=4 et
|