Line data Source code
1 : // Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/csspp
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 2 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 along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 :
20 : /** \file
21 : * \brief Test the expression.cpp file: "**" operator.
22 : *
23 : * This test runs a battery of tests agains the expression.cpp "**" (power)
24 : * operator to ensure full coverage and that all possible left
25 : * hand side and right hand side types are checked for the power
26 : * CSS Preprocessor extensions.
27 : *
28 : * Note that all the tests use the full chain: lexer, parser, compiler,
29 : * and assembler to make sure the results are correct. So these tests
30 : * exercise the assembler even more than the assembler tests, except that
31 : * it only checks that compressed results are correct instead of all
32 : * output modes, since its only goal is covering all the possible
33 : * expression cases and not the assembler, compiler, parser, and lexer
34 : * classes.
35 : */
36 :
37 : // csspp
38 : //
39 : #include <csspp/assembler.h>
40 : #include <csspp/compiler.h>
41 : #include <csspp/exception.h>
42 : #include <csspp/parser.h>
43 :
44 :
45 : // self
46 : //
47 : #include "catch_main.h"
48 :
49 : // C++
50 : //
51 : #include <sstream>
52 :
53 :
54 : // last include
55 : //
56 : #include <snapdev/poison.h>
57 :
58 :
59 :
60 15 : CATCH_TEST_CASE("Expression number ** number", "[expression] [power]")
61 : {
62 15 : CATCH_START_SECTION("no units, integers")
63 : {
64 1 : std::stringstream ss;
65 1 : ss << "div { z-index: 10 ** 3; }";
66 3 : csspp::position pos("test.css");
67 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
68 :
69 2 : csspp::parser p(l);
70 :
71 1 : csspp::node::pointer_t n(p.stylesheet());
72 :
73 1 : csspp::compiler c;
74 1 : c.set_root(n);
75 1 : c.set_date_time_variables(csspp_test::get_now());
76 1 : c.add_path(csspp_test::get_script_path());
77 1 : c.add_path(csspp_test::get_version_script_path());
78 :
79 1 : c.compile(false);
80 :
81 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
82 :
83 : // to verify that the result is still an INTEGER we have to
84 : // test the root node here
85 1 : std::stringstream compiler_out;
86 1 : compiler_out << *n;
87 1 : VERIFY_TREES(compiler_out.str(),
88 :
89 : "LIST\n"
90 : + csspp_test::get_default_variables() +
91 : " COMPONENT_VALUE\n"
92 : " ARG\n"
93 : " IDENTIFIER \"div\"\n"
94 : " OPEN_CURLYBRACKET B:true\n"
95 : " DECLARATION \"z-index\"\n"
96 : " ARG\n"
97 : " INTEGER \"\" I:1000\n"
98 : + csspp_test::get_close_comment(true)
99 :
100 : );
101 :
102 1 : std::stringstream assembler_out;
103 1 : csspp::assembler a(assembler_out);
104 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
105 :
106 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
107 :
108 1 : CATCH_REQUIRE(assembler_out.str() ==
109 : "div{z-index:1000}\n"
110 : + csspp_test::get_close_comment()
111 : );
112 :
113 1 : CATCH_REQUIRE(c.get_root() == n);
114 1 : }
115 15 : CATCH_END_SECTION()
116 :
117 15 : CATCH_START_SECTION("no units, integers two powers, parenthesis right")
118 : {
119 1 : std::stringstream ss;
120 1 : ss << "div { z-index: 4 ** (3 ** 2); }";
121 3 : csspp::position pos("test.css");
122 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
123 :
124 2 : csspp::parser p(l);
125 :
126 1 : csspp::node::pointer_t n(p.stylesheet());
127 :
128 1 : csspp::compiler c;
129 1 : c.set_root(n);
130 1 : c.set_date_time_variables(csspp_test::get_now());
131 1 : c.add_path(csspp_test::get_script_path());
132 1 : c.add_path(csspp_test::get_version_script_path());
133 :
134 1 : c.compile(false);
135 :
136 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
137 :
138 : // to verify that the result is still an INTEGER we have to
139 : // test the root node here
140 1 : std::stringstream compiler_out;
141 1 : compiler_out << *n;
142 1 : VERIFY_TREES(compiler_out.str(),
143 :
144 : "LIST\n"
145 : + csspp_test::get_default_variables() +
146 : " COMPONENT_VALUE\n"
147 : " ARG\n"
148 : " IDENTIFIER \"div\"\n"
149 : " OPEN_CURLYBRACKET B:true\n"
150 : " DECLARATION \"z-index\"\n"
151 : " ARG\n"
152 : " INTEGER \"\" I:262144\n"
153 : + csspp_test::get_close_comment(true)
154 :
155 : );
156 :
157 1 : std::stringstream assembler_out;
158 1 : csspp::assembler a(assembler_out);
159 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
160 :
161 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
162 :
163 1 : CATCH_REQUIRE(assembler_out.str() ==
164 : "div{z-index:262144}\n"
165 : + csspp_test::get_close_comment()
166 : );
167 :
168 1 : CATCH_REQUIRE(c.get_root() == n);
169 1 : }
170 15 : CATCH_END_SECTION()
171 :
172 15 : CATCH_START_SECTION("no units, integers two powers, parenthesis left")
173 : {
174 1 : std::stringstream ss;
175 1 : ss << "div { z-index: (4 ** 3) ** 2; }";
176 3 : csspp::position pos("test.css");
177 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
178 :
179 2 : csspp::parser p(l);
180 :
181 1 : csspp::node::pointer_t n(p.stylesheet());
182 :
183 1 : csspp::compiler c;
184 1 : c.set_root(n);
185 1 : c.set_date_time_variables(csspp_test::get_now());
186 1 : c.add_path(csspp_test::get_script_path());
187 1 : c.add_path(csspp_test::get_version_script_path());
188 :
189 1 : c.compile(false);
190 :
191 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
192 :
193 : // to verify that the result is still an INTEGER we have to
194 : // test the root node here
195 1 : std::stringstream compiler_out;
196 1 : compiler_out << *n;
197 1 : VERIFY_TREES(compiler_out.str(),
198 :
199 : "LIST\n"
200 : + csspp_test::get_default_variables() +
201 : " COMPONENT_VALUE\n"
202 : " ARG\n"
203 : " IDENTIFIER \"div\"\n"
204 : " OPEN_CURLYBRACKET B:true\n"
205 : " DECLARATION \"z-index\"\n"
206 : " ARG\n"
207 : " INTEGER \"\" I:4096\n"
208 : + csspp_test::get_close_comment(true)
209 :
210 : );
211 :
212 1 : std::stringstream assembler_out;
213 1 : csspp::assembler a(assembler_out);
214 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
215 :
216 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
217 :
218 1 : CATCH_REQUIRE(assembler_out.str() ==
219 : "div{z-index:4096}\n"
220 : + csspp_test::get_close_comment()
221 : );
222 :
223 1 : CATCH_REQUIRE(c.get_root() == n);
224 1 : }
225 15 : CATCH_END_SECTION()
226 :
227 15 : CATCH_START_SECTION("px unit, integers")
228 : {
229 1 : std::stringstream ss;
230 1 : ss << "div { width: 10px ** 3 / 2px\\*px; }";
231 3 : csspp::position pos("test.css");
232 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
233 :
234 2 : csspp::parser p(l);
235 :
236 1 : csspp::node::pointer_t n(p.stylesheet());
237 :
238 1 : csspp::compiler c;
239 1 : c.set_root(n);
240 1 : c.set_date_time_variables(csspp_test::get_now());
241 1 : c.add_path(csspp_test::get_script_path());
242 1 : c.add_path(csspp_test::get_version_script_path());
243 :
244 1 : c.compile(false);
245 :
246 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
247 :
248 : // to verify that the result is still an INTEGER we have to
249 : // test the root node here
250 1 : std::stringstream compiler_out;
251 1 : compiler_out << *n;
252 1 : VERIFY_TREES(compiler_out.str(),
253 :
254 : "LIST\n"
255 : + csspp_test::get_default_variables() +
256 : " COMPONENT_VALUE\n"
257 : " ARG\n"
258 : " IDENTIFIER \"div\"\n"
259 : " OPEN_CURLYBRACKET B:true\n"
260 : " DECLARATION \"width\"\n"
261 : " ARG\n"
262 : " INTEGER \"px\" I:500\n"
263 : + csspp_test::get_close_comment(true)
264 :
265 : );
266 :
267 1 : std::stringstream assembler_out;
268 1 : csspp::assembler a(assembler_out);
269 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
270 :
271 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
272 :
273 1 : CATCH_REQUIRE(assembler_out.str() ==
274 : "div{width:500px}\n"
275 : + csspp_test::get_close_comment()
276 : );
277 :
278 1 : CATCH_REQUIRE(c.get_root() == n);
279 1 : }
280 15 : CATCH_END_SECTION()
281 :
282 15 : CATCH_START_SECTION("no units, decimal number / integer")
283 : {
284 1 : std::stringstream ss;
285 1 : ss << "div { z-index: 7.3 ** 3; }";
286 3 : csspp::position pos("test.css");
287 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
288 :
289 2 : csspp::parser p(l);
290 :
291 1 : csspp::node::pointer_t n(p.stylesheet());
292 :
293 1 : csspp::compiler c;
294 1 : c.set_root(n);
295 1 : c.set_date_time_variables(csspp_test::get_now());
296 1 : c.add_path(csspp_test::get_script_path());
297 1 : c.add_path(csspp_test::get_version_script_path());
298 :
299 1 : c.compile(false);
300 :
301 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
302 :
303 : // to verify that the result is still an INTEGER we have to
304 : // test the root node here
305 1 : std::stringstream compiler_out;
306 1 : compiler_out << *n;
307 1 : VERIFY_TREES(compiler_out.str(),
308 :
309 : "LIST\n"
310 : + csspp_test::get_default_variables() +
311 : " COMPONENT_VALUE\n"
312 : " ARG\n"
313 : " IDENTIFIER \"div\"\n"
314 : " OPEN_CURLYBRACKET B:true\n"
315 : " DECLARATION \"z-index\"\n"
316 : " ARG\n"
317 : " DECIMAL_NUMBER \"\" D:389.017\n"
318 : + csspp_test::get_close_comment(true)
319 :
320 : );
321 :
322 1 : std::stringstream assembler_out;
323 1 : csspp::assembler a(assembler_out);
324 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
325 :
326 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
327 :
328 1 : CATCH_REQUIRE(assembler_out.str() ==
329 : "div{z-index:389.017}\n"
330 : + csspp_test::get_close_comment()
331 : );
332 :
333 1 : CATCH_REQUIRE(c.get_root() == n);
334 1 : }
335 15 : CATCH_END_SECTION()
336 :
337 15 : CATCH_START_SECTION("no units, integer and decimal number")
338 : {
339 1 : std::stringstream ss;
340 1 : ss << "div { z-index: 7 ** 3.1; }";
341 3 : csspp::position pos("test.css");
342 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
343 :
344 2 : csspp::parser p(l);
345 :
346 1 : csspp::node::pointer_t n(p.stylesheet());
347 :
348 1 : csspp::compiler c;
349 1 : c.set_root(n);
350 1 : c.set_date_time_variables(csspp_test::get_now());
351 1 : c.add_path(csspp_test::get_script_path());
352 1 : c.add_path(csspp_test::get_version_script_path());
353 :
354 1 : c.compile(false);
355 :
356 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
357 :
358 : // to verify that the result is still an INTEGER we have to
359 : // test the root node here
360 1 : std::stringstream compiler_out;
361 1 : compiler_out << *n;
362 1 : VERIFY_TREES(compiler_out.str(),
363 :
364 : "LIST\n"
365 : + csspp_test::get_default_variables() +
366 : " COMPONENT_VALUE\n"
367 : " ARG\n"
368 : " IDENTIFIER \"div\"\n"
369 : " OPEN_CURLYBRACKET B:true\n"
370 : " DECLARATION \"z-index\"\n"
371 : " ARG\n"
372 : " DECIMAL_NUMBER \"\" D:416.681\n"
373 : + csspp_test::get_close_comment(true)
374 :
375 : );
376 :
377 1 : std::stringstream assembler_out;
378 1 : csspp::assembler a(assembler_out);
379 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
380 :
381 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
382 :
383 1 : CATCH_REQUIRE(assembler_out.str() ==
384 : "div{z-index:416.681}\n"
385 : + csspp_test::get_close_comment()
386 : );
387 :
388 1 : CATCH_REQUIRE(c.get_root() == n);
389 1 : }
390 15 : CATCH_END_SECTION()
391 :
392 15 : CATCH_START_SECTION("no units, decimal number / negative power")
393 : {
394 1 : std::stringstream ss;
395 1 : ss << "div { z-index: 0.3 ** -3.2; }";
396 3 : csspp::position pos("test.css");
397 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
398 :
399 2 : csspp::parser p(l);
400 :
401 1 : csspp::node::pointer_t n(p.stylesheet());
402 :
403 1 : csspp::compiler c;
404 1 : c.set_root(n);
405 1 : c.set_date_time_variables(csspp_test::get_now());
406 1 : c.add_path(csspp_test::get_script_path());
407 1 : c.add_path(csspp_test::get_version_script_path());
408 :
409 1 : c.compile(false);
410 :
411 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
412 :
413 : // to verify that the result is still an INTEGER we have to
414 : // test the root node here
415 1 : std::stringstream compiler_out;
416 1 : compiler_out << *n;
417 1 : VERIFY_TREES(compiler_out.str(),
418 :
419 : "LIST\n"
420 : + csspp_test::get_default_variables() +
421 : " COMPONENT_VALUE\n"
422 : " ARG\n"
423 : " IDENTIFIER \"div\"\n"
424 : " OPEN_CURLYBRACKET B:true\n"
425 : " DECLARATION \"z-index\"\n"
426 : " ARG\n"
427 : " DECIMAL_NUMBER \"\" D:47.121\n"
428 : + csspp_test::get_close_comment(true)
429 :
430 : );
431 :
432 1 : std::stringstream assembler_out;
433 1 : csspp::assembler a(assembler_out);
434 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
435 :
436 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
437 :
438 1 : CATCH_REQUIRE(assembler_out.str() ==
439 : "div{z-index:47.121}\n"
440 : + csspp_test::get_close_comment()
441 : );
442 :
443 1 : CATCH_REQUIRE(c.get_root() == n);
444 1 : }
445 15 : CATCH_END_SECTION()
446 :
447 15 : CATCH_START_SECTION("px unit, decimal number / integer")
448 : {
449 1 : std::stringstream ss;
450 1 : ss << "div { width: 7.5px pow 3 / 3px\\*px; }";
451 3 : csspp::position pos("test.css");
452 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
453 :
454 2 : csspp::parser p(l);
455 :
456 1 : csspp::node::pointer_t n(p.stylesheet());
457 :
458 1 : csspp::compiler c;
459 1 : c.set_root(n);
460 1 : c.set_date_time_variables(csspp_test::get_now());
461 1 : c.add_path(csspp_test::get_script_path());
462 1 : c.add_path(csspp_test::get_version_script_path());
463 :
464 1 : c.compile(false);
465 :
466 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
467 :
468 : // to verify that the result is still an INTEGER we have to
469 : // test the root node here
470 1 : std::stringstream compiler_out;
471 1 : compiler_out << *n;
472 1 : VERIFY_TREES(compiler_out.str(),
473 :
474 : "LIST\n"
475 : + csspp_test::get_default_variables() +
476 : " COMPONENT_VALUE\n"
477 : " ARG\n"
478 : " IDENTIFIER \"div\"\n"
479 : " OPEN_CURLYBRACKET B:true\n"
480 : " DECLARATION \"width\"\n"
481 : " ARG\n"
482 : " DECIMAL_NUMBER \"px\" D:140.625\n"
483 : + csspp_test::get_close_comment(true)
484 :
485 : );
486 :
487 1 : std::stringstream assembler_out;
488 1 : csspp::assembler a(assembler_out);
489 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
490 :
491 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
492 :
493 1 : CATCH_REQUIRE(assembler_out.str() ==
494 : "div{width:140.625px}\n"
495 : + csspp_test::get_close_comment()
496 : );
497 :
498 1 : CATCH_REQUIRE(c.get_root() == n);
499 1 : }
500 15 : CATCH_END_SECTION()
501 :
502 15 : CATCH_START_SECTION("px/em unit, decimal number / integer")
503 : {
504 1 : std::stringstream ss;
505 1 : ss << "div { width: (15.0px div 2.0em) pow 3; }";
506 3 : csspp::position pos("test.css");
507 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
508 :
509 2 : csspp::parser p(l);
510 :
511 1 : csspp::node::pointer_t n(p.stylesheet());
512 :
513 1 : csspp::compiler c;
514 1 : c.set_root(n);
515 1 : c.set_date_time_variables(csspp_test::get_now());
516 1 : c.add_path(csspp_test::get_script_path());
517 1 : c.add_path(csspp_test::get_version_script_path());
518 :
519 1 : c.compile(false);
520 :
521 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
522 :
523 : // to verify that the result is still an INTEGER we have to
524 : // test the root node here
525 1 : std::stringstream compiler_out;
526 1 : compiler_out << *n;
527 1 : VERIFY_TREES(compiler_out.str(),
528 :
529 : "LIST\n"
530 : + csspp_test::get_default_variables() +
531 : " COMPONENT_VALUE\n"
532 : " ARG\n"
533 : " IDENTIFIER \"div\"\n"
534 : " OPEN_CURLYBRACKET B:true\n"
535 : " DECLARATION \"width\"\n"
536 : " ARG\n"
537 : " DECIMAL_NUMBER \"px * px * px / em * em * em\" D:421.875\n"
538 : + csspp_test::get_close_comment(true)
539 :
540 : );
541 :
542 : // std::stringstream assembler_out;
543 : // csspp::assembler a(assembler_out);
544 : // a.output(n, csspp::output_mode_t::COMPRESSED);
545 : //
546 : // //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
547 : //
548 : // CATCH_REQUIRE(assembler_out.str() ==
549 : // "div{width:421.875px}\n"
550 : // + csspp_test::get_close_comment()
551 : // );
552 :
553 1 : CATCH_REQUIRE(c.get_root() == n);
554 1 : }
555 15 : CATCH_END_SECTION()
556 :
557 15 : CATCH_START_SECTION("px/em unit, decimal number / integer")
558 : {
559 1 : std::stringstream ss;
560 1 : ss << "div { width: (50.0px div 2.0em) pow -2; }";
561 3 : csspp::position pos("test.css");
562 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
563 :
564 2 : csspp::parser p(l);
565 :
566 1 : csspp::node::pointer_t n(p.stylesheet());
567 :
568 1 : csspp::compiler c;
569 1 : c.set_root(n);
570 1 : c.set_date_time_variables(csspp_test::get_now());
571 1 : c.add_path(csspp_test::get_script_path());
572 1 : c.add_path(csspp_test::get_version_script_path());
573 :
574 1 : c.compile(false);
575 :
576 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
577 :
578 : // to verify that the result is still an INTEGER we have to
579 : // test the root node here
580 1 : std::stringstream compiler_out;
581 1 : compiler_out << *n;
582 1 : VERIFY_TREES(compiler_out.str(),
583 :
584 : "LIST\n"
585 : + csspp_test::get_default_variables() +
586 : " COMPONENT_VALUE\n"
587 : " ARG\n"
588 : " IDENTIFIER \"div\"\n"
589 : " OPEN_CURLYBRACKET B:true\n"
590 : " DECLARATION \"width\"\n"
591 : " ARG\n"
592 : " DECIMAL_NUMBER \"em * em / px * px\" D:0.002\n"
593 : + csspp_test::get_close_comment(true)
594 :
595 : );
596 :
597 : // std::stringstream assembler_out;
598 : // csspp::assembler a(assembler_out);
599 : // a.output(n, csspp::output_mode_t::COMPRESSED);
600 : //
601 : // //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
602 : //
603 : // CATCH_REQUIRE(assembler_out.str() ==
604 : // "div{width:421.875px}\n"
605 : // + csspp_test::get_close_comment()
606 : // );
607 :
608 1 : CATCH_REQUIRE(c.get_root() == n);
609 1 : }
610 15 : CATCH_END_SECTION()
611 :
612 15 : CATCH_START_SECTION("px unit, decimal number / -integer")
613 : {
614 1 : std::stringstream ss;
615 1 : ss << "div { width: .75px pow -3 * 3px\\*px\\*px\\*px; }";
616 3 : csspp::position pos("test.css");
617 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
618 :
619 2 : csspp::parser p(l);
620 :
621 1 : csspp::node::pointer_t n(p.stylesheet());
622 :
623 1 : csspp::compiler c;
624 1 : c.set_root(n);
625 1 : c.set_date_time_variables(csspp_test::get_now());
626 1 : c.add_path(csspp_test::get_script_path());
627 1 : c.add_path(csspp_test::get_version_script_path());
628 :
629 1 : c.compile(false);
630 :
631 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
632 :
633 : // to verify that the result is still an INTEGER we have to
634 : // test the root node here
635 1 : std::stringstream compiler_out;
636 1 : compiler_out << *n;
637 1 : VERIFY_TREES(compiler_out.str(),
638 :
639 : "LIST\n"
640 : + csspp_test::get_default_variables() +
641 : " COMPONENT_VALUE\n"
642 : " ARG\n"
643 : " IDENTIFIER \"div\"\n"
644 : " OPEN_CURLYBRACKET B:true\n"
645 : " DECLARATION \"width\"\n"
646 : " ARG\n"
647 : " DECIMAL_NUMBER \"px\" D:7.111\n"
648 : + csspp_test::get_close_comment(true)
649 :
650 : );
651 :
652 1 : std::stringstream assembler_out;
653 1 : csspp::assembler a(assembler_out);
654 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
655 :
656 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
657 :
658 1 : CATCH_REQUIRE(assembler_out.str() ==
659 : "div{width:7.111px}\n"
660 : + csspp_test::get_close_comment()
661 : );
662 :
663 1 : CATCH_REQUIRE(c.get_root() == n);
664 1 : }
665 15 : CATCH_END_SECTION()
666 :
667 15 : CATCH_START_SECTION("no units, decimal numbers")
668 : {
669 1 : std::stringstream ss;
670 1 : ss << "div { z-index: 7.3 ** 3.1; }";
671 3 : csspp::position pos("test.css");
672 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
673 :
674 2 : csspp::parser p(l);
675 :
676 1 : csspp::node::pointer_t n(p.stylesheet());
677 :
678 1 : csspp::compiler c;
679 1 : c.set_root(n);
680 1 : c.set_date_time_variables(csspp_test::get_now());
681 1 : c.add_path(csspp_test::get_script_path());
682 1 : c.add_path(csspp_test::get_version_script_path());
683 :
684 1 : c.compile(false);
685 :
686 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
687 :
688 : // to verify that the result is still an INTEGER we have to
689 : // test the root node here
690 1 : std::stringstream compiler_out;
691 1 : compiler_out << *n;
692 1 : VERIFY_TREES(compiler_out.str(),
693 :
694 : "LIST\n"
695 : + csspp_test::get_default_variables() +
696 : " COMPONENT_VALUE\n"
697 : " ARG\n"
698 : " IDENTIFIER \"div\"\n"
699 : " OPEN_CURLYBRACKET B:true\n"
700 : " DECLARATION \"z-index\"\n"
701 : " ARG\n"
702 : " DECIMAL_NUMBER \"\" D:474.571\n"
703 : + csspp_test::get_close_comment(true)
704 :
705 : );
706 :
707 1 : std::stringstream assembler_out;
708 1 : csspp::assembler a(assembler_out);
709 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
710 :
711 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
712 :
713 1 : CATCH_REQUIRE(assembler_out.str() ==
714 : "div{z-index:474.571}\n"
715 : + csspp_test::get_close_comment()
716 : );
717 :
718 1 : CATCH_REQUIRE(c.get_root() == n);
719 1 : }
720 15 : CATCH_END_SECTION()
721 :
722 15 : CATCH_START_SECTION("px unit, decimal numbers")
723 : {
724 1 : std::stringstream ss;
725 1 : ss << "div { width: 7.5px pow 3.0 / 3px\\*px; }";
726 3 : csspp::position pos("test.css");
727 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
728 :
729 2 : csspp::parser p(l);
730 :
731 1 : csspp::node::pointer_t n(p.stylesheet());
732 :
733 1 : csspp::compiler c;
734 1 : c.set_root(n);
735 1 : c.set_date_time_variables(csspp_test::get_now());
736 1 : c.add_path(csspp_test::get_script_path());
737 1 : c.add_path(csspp_test::get_version_script_path());
738 :
739 1 : c.compile(false);
740 :
741 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
742 :
743 : // to verify that the result is still an INTEGER we have to
744 : // test the root node here
745 1 : std::stringstream compiler_out;
746 1 : compiler_out << *n;
747 1 : VERIFY_TREES(compiler_out.str(),
748 :
749 : "LIST\n"
750 : + csspp_test::get_default_variables() +
751 : " COMPONENT_VALUE\n"
752 : " ARG\n"
753 : " IDENTIFIER \"div\"\n"
754 : " OPEN_CURLYBRACKET B:true\n"
755 : " DECLARATION \"width\"\n"
756 : " ARG\n"
757 : " DECIMAL_NUMBER \"px\" D:140.625\n"
758 : + csspp_test::get_close_comment(true)
759 :
760 : );
761 :
762 1 : std::stringstream assembler_out;
763 1 : csspp::assembler a(assembler_out);
764 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
765 :
766 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
767 :
768 1 : CATCH_REQUIRE(assembler_out.str() ==
769 : "div{width:140.625px}\n"
770 : + csspp_test::get_close_comment()
771 : );
772 :
773 1 : CATCH_REQUIRE(c.get_root() == n);
774 1 : }
775 15 : CATCH_END_SECTION()
776 :
777 15 : CATCH_START_SECTION("% and integer")
778 : {
779 1 : std::stringstream ss;
780 1 : ss << "div { width: 105% pow 4; }";
781 3 : csspp::position pos("test.css");
782 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
783 :
784 2 : csspp::parser p(l);
785 :
786 1 : csspp::node::pointer_t n(p.stylesheet());
787 :
788 1 : csspp::compiler c;
789 1 : c.set_root(n);
790 1 : c.set_date_time_variables(csspp_test::get_now());
791 1 : c.add_path(csspp_test::get_script_path());
792 1 : c.add_path(csspp_test::get_version_script_path());
793 :
794 1 : c.compile(false);
795 :
796 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
797 :
798 : // to verify that the result is still an INTEGER we have to
799 : // test the root node here
800 1 : std::stringstream compiler_out;
801 1 : compiler_out << *n;
802 1 : VERIFY_TREES(compiler_out.str(),
803 :
804 : "LIST\n"
805 : + csspp_test::get_default_variables() +
806 : " COMPONENT_VALUE\n"
807 : " ARG\n"
808 : " IDENTIFIER \"div\"\n"
809 : " OPEN_CURLYBRACKET B:true\n"
810 : " DECLARATION \"width\"\n"
811 : " ARG\n"
812 : " PERCENT D:1.216\n"
813 : + csspp_test::get_close_comment(true)
814 :
815 : );
816 :
817 1 : std::stringstream assembler_out;
818 1 : csspp::assembler a(assembler_out);
819 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
820 :
821 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
822 :
823 1 : CATCH_REQUIRE(assembler_out.str() ==
824 : "div{width:121.551%}\n"
825 : + csspp_test::get_close_comment()
826 : );
827 :
828 1 : CATCH_REQUIRE(c.get_root() == n);
829 1 : }
830 15 : CATCH_END_SECTION()
831 :
832 15 : CATCH_START_SECTION("% and decimal numbers")
833 : {
834 1 : std::stringstream ss;
835 1 : ss << "div { width: 107.5% pow 5.3; }";
836 3 : csspp::position pos("test.css");
837 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
838 :
839 2 : csspp::parser p(l);
840 :
841 1 : csspp::node::pointer_t n(p.stylesheet());
842 :
843 1 : csspp::compiler c;
844 1 : c.set_root(n);
845 1 : c.set_date_time_variables(csspp_test::get_now());
846 1 : c.add_path(csspp_test::get_script_path());
847 1 : c.add_path(csspp_test::get_version_script_path());
848 :
849 1 : c.compile(false);
850 :
851 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
852 :
853 : // to verify that the result is still an INTEGER we have to
854 : // test the root node here
855 1 : std::stringstream compiler_out;
856 1 : compiler_out << *n;
857 1 : VERIFY_TREES(compiler_out.str(),
858 :
859 : "LIST\n"
860 : + csspp_test::get_default_variables() +
861 : " COMPONENT_VALUE\n"
862 : " ARG\n"
863 : " IDENTIFIER \"div\"\n"
864 : " OPEN_CURLYBRACKET B:true\n"
865 : " DECLARATION \"width\"\n"
866 : " ARG\n"
867 : " PERCENT D:1.467\n"
868 : + csspp_test::get_close_comment(true)
869 :
870 : );
871 :
872 1 : std::stringstream assembler_out;
873 1 : csspp::assembler a(assembler_out);
874 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
875 :
876 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
877 :
878 1 : CATCH_REQUIRE(assembler_out.str() ==
879 : "div{width:146.712%}\n"
880 : + csspp_test::get_close_comment()
881 : );
882 :
883 1 : CATCH_REQUIRE(c.get_root() == n);
884 1 : }
885 15 : CATCH_END_SECTION()
886 :
887 : // no error left over
888 15 : VERIFY_ERRORS("");
889 15 : }
890 :
891 2 : CATCH_TEST_CASE("Expression number/invalid ** number/invalid", "[expression] [power] [invalid]")
892 : {
893 2 : CATCH_START_SECTION("just ? is not a valid number")
894 : {
895 1 : std::stringstream ss;
896 1 : ss << "div { border: ?; }";
897 3 : csspp::position pos("test.css");
898 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
899 :
900 2 : csspp::parser p(l);
901 :
902 1 : csspp::node::pointer_t n(p.stylesheet());
903 :
904 1 : csspp::compiler c;
905 1 : c.set_root(n);
906 1 : c.set_date_time_variables(csspp_test::get_now());
907 1 : c.add_path(csspp_test::get_script_path());
908 1 : c.add_path(csspp_test::get_version_script_path());
909 :
910 1 : c.compile(false);
911 :
912 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
913 :
914 1 : VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
915 :
916 1 : CATCH_REQUIRE(c.get_root() == n);
917 1 : }
918 2 : CATCH_END_SECTION()
919 :
920 2 : CATCH_START_SECTION("number ** ? is invalid")
921 : {
922 1 : std::stringstream ss;
923 1 : ss << "div { width: 10px ** ?; }";
924 3 : csspp::position pos("test.css");
925 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
926 :
927 2 : csspp::parser p(l);
928 :
929 1 : csspp::node::pointer_t n(p.stylesheet());
930 :
931 1 : csspp::compiler c;
932 1 : c.set_root(n);
933 1 : c.set_date_time_variables(csspp_test::get_now());
934 1 : c.add_path(csspp_test::get_script_path());
935 1 : c.add_path(csspp_test::get_version_script_path());
936 :
937 1 : c.compile(false);
938 :
939 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
940 :
941 1 : VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
942 :
943 1 : CATCH_REQUIRE(c.get_root() == n);
944 1 : }
945 2 : CATCH_END_SECTION()
946 :
947 : // no error left over
948 2 : VERIFY_ERRORS("");
949 2 : }
950 :
951 6 : CATCH_TEST_CASE("Power expressions with invalid dimensions or decimal numbers", "[expression] [power] [invalid]")
952 : {
953 6 : CATCH_START_SECTION("right hand side cannot have a dimension")
954 : {
955 1 : std::stringstream ss;
956 1 : ss << "div { border: 3px ** 2em; }";
957 3 : csspp::position pos("test.css");
958 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
959 :
960 2 : csspp::parser p(l);
961 :
962 1 : csspp::node::pointer_t n(p.stylesheet());
963 :
964 1 : csspp::compiler c;
965 1 : c.set_root(n);
966 1 : c.set_date_time_variables(csspp_test::get_now());
967 1 : c.add_path(csspp_test::get_script_path());
968 1 : c.add_path(csspp_test::get_version_script_path());
969 :
970 1 : c.compile(false);
971 :
972 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
973 :
974 1 : VERIFY_ERRORS("test.css(1): error: the number representing the power cannot be a dimension (em); it has to be unitless.\n");
975 :
976 1 : CATCH_REQUIRE(c.get_root() == n);
977 1 : }
978 6 : CATCH_END_SECTION()
979 :
980 6 : CATCH_START_SECTION("power cannot be a percent")
981 : {
982 1 : std::stringstream ss;
983 1 : ss << "div { z-index: 10 ** 5%; }";
984 3 : csspp::position pos("test.css");
985 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
986 :
987 2 : csspp::parser p(l);
988 :
989 1 : csspp::node::pointer_t n(p.stylesheet());
990 :
991 1 : csspp::compiler c;
992 1 : c.set_root(n);
993 1 : c.set_date_time_variables(csspp_test::get_now());
994 1 : c.add_path(csspp_test::get_script_path());
995 1 : c.add_path(csspp_test::get_version_script_path());
996 :
997 1 : c.compile(false);
998 :
999 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1000 :
1001 1 : VERIFY_ERRORS("test.css(1): error: incompatible types between INTEGER and PERCENT for operator '**'.\n");
1002 :
1003 1 : CATCH_REQUIRE(c.get_root() == n);
1004 1 : }
1005 6 : CATCH_END_SECTION()
1006 :
1007 6 : CATCH_START_SECTION("power must be integral if left hand side has a dimension")
1008 : {
1009 1 : std::stringstream ss;
1010 1 : ss << "div { width: 7.3px ** 3.1; }";
1011 3 : csspp::position pos("test.css");
1012 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1013 :
1014 2 : csspp::parser p(l);
1015 :
1016 1 : csspp::node::pointer_t n(p.stylesheet());
1017 :
1018 1 : csspp::compiler c;
1019 1 : c.set_root(n);
1020 1 : c.set_date_time_variables(csspp_test::get_now());
1021 1 : c.add_path(csspp_test::get_script_path());
1022 1 : c.add_path(csspp_test::get_version_script_path());
1023 :
1024 1 : c.compile(false);
1025 :
1026 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1027 :
1028 1 : VERIFY_ERRORS("test.css(1): error: a number with a dimension only supports integers as their power (i.e. 3px ** 2 is fine, 3px ** 2.1 is not supported).\n");
1029 :
1030 1 : CATCH_REQUIRE(c.get_root() == n);
1031 1 : }
1032 6 : CATCH_END_SECTION()
1033 :
1034 6 : CATCH_START_SECTION("power zero with a dimension is not allowed")
1035 : {
1036 1 : std::stringstream ss;
1037 1 : ss << "div { width: 7.5px ** 0.0; }";
1038 3 : csspp::position pos("test.css");
1039 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1040 :
1041 2 : csspp::parser p(l);
1042 :
1043 1 : csspp::node::pointer_t n(p.stylesheet());
1044 :
1045 1 : csspp::compiler c;
1046 1 : c.set_root(n);
1047 1 : c.set_date_time_variables(csspp_test::get_now());
1048 1 : c.add_path(csspp_test::get_script_path());
1049 1 : c.add_path(csspp_test::get_version_script_path());
1050 :
1051 1 : c.compile(false);
1052 :
1053 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1054 :
1055 1 : VERIFY_ERRORS("test.css(1): error: a number with a dimension power zero cannot be calculated (i.e. 3px ** 0 = 1 what?).\n");
1056 :
1057 1 : CATCH_REQUIRE(c.get_root() == n);
1058 1 : }
1059 6 : CATCH_END_SECTION()
1060 :
1061 6 : CATCH_START_SECTION("power too large")
1062 : {
1063 1 : std::stringstream ss;
1064 1 : ss << "div { width: 7.5px ** 1584.000; }";
1065 3 : csspp::position pos("test.css");
1066 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1067 :
1068 2 : csspp::parser p(l);
1069 :
1070 1 : csspp::node::pointer_t n(p.stylesheet());
1071 :
1072 1 : csspp::compiler c;
1073 1 : c.set_root(n);
1074 1 : c.set_date_time_variables(csspp_test::get_now());
1075 1 : c.add_path(csspp_test::get_script_path());
1076 1 : c.add_path(csspp_test::get_version_script_path());
1077 :
1078 1 : c.compile(false);
1079 :
1080 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1081 :
1082 1 : VERIFY_ERRORS("test.css(1): error: a number with a dimension power 101 or more would generate a very large string so we refuse it at this time. You may use unitless numbers instead.\n");
1083 :
1084 1 : CATCH_REQUIRE(c.get_root() == n);
1085 1 : }
1086 6 : CATCH_END_SECTION()
1087 :
1088 6 : CATCH_START_SECTION("'a ** b ** c' is not valid")
1089 : {
1090 1 : std::stringstream ss;
1091 1 : ss << "div { z-index: 4 ** 3 ** 2; }";
1092 3 : csspp::position pos("test.css");
1093 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1094 :
1095 2 : csspp::parser p(l);
1096 :
1097 1 : csspp::node::pointer_t n(p.stylesheet());
1098 :
1099 1 : csspp::compiler c;
1100 1 : c.set_root(n);
1101 1 : c.set_date_time_variables(csspp_test::get_now());
1102 1 : c.add_path(csspp_test::get_script_path());
1103 1 : c.add_path(csspp_test::get_version_script_path());
1104 :
1105 1 : c.compile(false);
1106 :
1107 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1108 :
1109 1 : VERIFY_ERRORS("test.css(1): error: unsupported type POWER as a unary expression token.\n");
1110 :
1111 1 : CATCH_REQUIRE(c.get_root() == n);
1112 1 : }
1113 6 : CATCH_END_SECTION()
1114 :
1115 : // no error left over
1116 6 : VERIFY_ERRORS("");
1117 6 : }
1118 :
1119 : // vim: ts=4 sw=4 et
|