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: "(..., ..., ...)" (list) operator.
22 : *
23 : * This test runs a battery of tests agains the expression.cpp "," (list)
24 : * operator to ensure full coverage and that all possible left
25 : * hand side and right hand side types are checked for the equality
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 :
50 : // C++
51 : //
52 : #include <sstream>
53 :
54 :
55 : // last include
56 : //
57 : #include <snapdev/poison.h>
58 :
59 :
60 :
61 3 : CATCH_TEST_CASE("Expression arrays", "[expression] [list] [array]")
62 : {
63 3 : CATCH_START_SECTION("test a compiled array")
64 : {
65 1 : std::stringstream ss;
66 1 : ss << "div { z-index: (15, 1, -39, 44, 10); }";
67 3 : csspp::position pos("test.css");
68 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
69 :
70 2 : csspp::parser p(l);
71 :
72 1 : csspp::node::pointer_t n(p.stylesheet());
73 :
74 1 : csspp::compiler c;
75 1 : c.set_root(n);
76 1 : c.set_date_time_variables(csspp_test::get_now());
77 1 : c.add_path(csspp_test::get_script_path());
78 1 : c.add_path(csspp_test::get_version_script_path());
79 :
80 1 : c.compile(false);
81 :
82 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
83 :
84 : // to verify that the result is still an INTEGER we have to
85 : // test the root node here
86 1 : std::stringstream compiler_out;
87 1 : compiler_out << *n;
88 1 : VERIFY_TREES(compiler_out.str(),
89 :
90 : "LIST\n"
91 : + csspp_test::get_default_variables() +
92 : " COMPONENT_VALUE\n"
93 : " ARG\n"
94 : " IDENTIFIER \"div\"\n"
95 : " OPEN_CURLYBRACKET B:true\n"
96 : " DECLARATION \"z-index\"\n"
97 : " ARG\n"
98 : " ARRAY\n"
99 : " INTEGER \"\" I:15\n"
100 : " INTEGER \"\" I:1\n"
101 : " INTEGER \"\" I:-39\n"
102 : " INTEGER \"\" I:44\n"
103 : " INTEGER \"\" I:10\n"
104 : + csspp_test::get_close_comment(true)
105 :
106 : );
107 :
108 1 : CATCH_REQUIRE(c.get_root() == n);
109 1 : }
110 3 : CATCH_END_SECTION()
111 :
112 3 : CATCH_START_SECTION("create an array and retrieve each element")
113 : {
114 1 : int const results[6] =
115 : {
116 : // first number is unused, just makes it more practical to have it
117 : 0, 15, 1, -39, 44, 10
118 : };
119 :
120 6 : for(int idx(1); idx <= 5; ++idx)
121 : {
122 5 : std::stringstream ss;
123 5 : ss << "div { z-index: (15, 1, -39, 44, 10)["
124 : << idx
125 : << "]; }"
126 5 : << "span { z-index: (15, 1, -39, 44, 10)["
127 : << -idx
128 5 : << "]; }";
129 15 : csspp::position pos("test.css");
130 5 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
131 :
132 10 : csspp::parser p(l);
133 :
134 5 : csspp::node::pointer_t n(p.stylesheet());
135 :
136 5 : csspp::compiler c;
137 5 : c.set_root(n);
138 5 : c.set_date_time_variables(csspp_test::get_now());
139 5 : c.add_path(csspp_test::get_script_path());
140 5 : c.add_path(csspp_test::get_version_script_path());
141 :
142 5 : c.compile(false);
143 :
144 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
145 :
146 : // to verify that the result is still an INTEGER we have to
147 : // test the root node here
148 5 : std::stringstream compiler_out;
149 5 : compiler_out << *n;
150 5 : VERIFY_TREES(compiler_out.str(),
151 :
152 : "LIST\n"
153 : + csspp_test::get_default_variables() +
154 : " COMPONENT_VALUE\n"
155 : " ARG\n"
156 : " IDENTIFIER \"div\"\n"
157 : " OPEN_CURLYBRACKET B:true\n"
158 : " DECLARATION \"z-index\"\n"
159 : " ARG\n"
160 : " INTEGER \"\" I:" + std::to_string(results[idx]) + "\n"
161 : " COMPONENT_VALUE\n"
162 : " ARG\n"
163 : " IDENTIFIER \"span\"\n"
164 : " OPEN_CURLYBRACKET B:true\n"
165 : " DECLARATION \"z-index\"\n"
166 : " ARG\n"
167 : " INTEGER \"\" I:" + std::to_string(results[6 - idx]) + "\n"
168 : + csspp_test::get_close_comment(true)
169 :
170 : );
171 :
172 5 : std::stringstream assembler_out;
173 5 : csspp::assembler a(assembler_out);
174 5 : a.output(n, csspp::output_mode_t::COMPRESSED);
175 :
176 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
177 :
178 5 : CATCH_REQUIRE(assembler_out.str() ==
179 :
180 : "div{z-index:" + std::to_string(results[idx]) + "}"
181 : "span{z-index:" + std::to_string(results[6 - idx]) + "}"
182 : "\n"
183 : + csspp_test::get_close_comment()
184 :
185 : );
186 :
187 5 : CATCH_REQUIRE(c.get_root() == n);
188 5 : }
189 : }
190 3 : CATCH_END_SECTION()
191 :
192 3 : CATCH_START_SECTION("use list to do some computation and retrieve the last result")
193 : {
194 1 : std::stringstream ss;
195 : ss << "div {\n"
196 : << " border: (v := 3px, w := 51px, x := v + w, x / 2.7)[-1] solid #f1a932;\n"
197 1 : << "}\n";
198 3 : csspp::position pos("test.css");
199 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
200 :
201 2 : csspp::parser p(l);
202 :
203 1 : csspp::node::pointer_t n(p.stylesheet());
204 :
205 1 : csspp::compiler c;
206 1 : c.set_root(n);
207 1 : c.set_date_time_variables(csspp_test::get_now());
208 1 : c.add_path(csspp_test::get_script_path());
209 1 : c.add_path(csspp_test::get_version_script_path());
210 :
211 1 : c.compile(false);
212 :
213 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
214 :
215 : // to verify that the result is still an INTEGER we have to
216 : // test the root node here
217 1 : std::stringstream compiler_out;
218 1 : compiler_out << *n;
219 1 : VERIFY_TREES(compiler_out.str(),
220 :
221 : "LIST\n"
222 : + csspp_test::get_default_variables() +
223 : " COMPONENT_VALUE\n"
224 : " ARG\n"
225 : " IDENTIFIER \"div\"\n"
226 : " OPEN_CURLYBRACKET B:true\n"
227 : " DECLARATION \"border\"\n"
228 : " ARG\n"
229 : " DECIMAL_NUMBER \"px\" D:20\n"
230 : " WHITESPACE\n"
231 : " IDENTIFIER \"solid\"\n"
232 : " WHITESPACE\n"
233 : " COLOR H:ff32a9f1\n"
234 : + csspp_test::get_close_comment(true)
235 :
236 : );
237 :
238 1 : std::stringstream assembler_out;
239 1 : csspp::assembler a(assembler_out);
240 1 : a.output(n, csspp::output_mode_t::COMPRESSED);
241 :
242 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
243 :
244 1 : CATCH_REQUIRE(assembler_out.str() ==
245 :
246 : "div{"
247 : "border:20px solid #f1a932"
248 : "}\n"
249 : + csspp_test::get_close_comment()
250 :
251 : );
252 :
253 1 : CATCH_REQUIRE(c.get_root() == n);
254 1 : }
255 3 : CATCH_END_SECTION()
256 :
257 : // no error left over
258 3 : VERIFY_ERRORS("");
259 3 : }
260 :
261 4 : CATCH_TEST_CASE("Expression maps", "[expression] [list] [map]")
262 : {
263 4 : CATCH_START_SECTION("test a compiled map")
264 : {
265 1 : std::stringstream ss;
266 1 : ss << "div { z-index: (a: 15, b:1,c: -39,d:44, e : 10 ); }";
267 3 : csspp::position pos("test.css");
268 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
269 :
270 2 : csspp::parser p(l);
271 :
272 1 : csspp::node::pointer_t n(p.stylesheet());
273 :
274 1 : csspp::compiler c;
275 1 : c.set_root(n);
276 1 : c.set_date_time_variables(csspp_test::get_now());
277 1 : c.add_path(csspp_test::get_script_path());
278 1 : c.add_path(csspp_test::get_version_script_path());
279 :
280 1 : c.compile(false);
281 :
282 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
283 :
284 : // to verify that the result is still an INTEGER we have to
285 : // test the root node here
286 1 : std::stringstream compiler_out;
287 1 : compiler_out << *n;
288 1 : VERIFY_TREES(compiler_out.str(),
289 :
290 : "LIST\n"
291 : + csspp_test::get_default_variables() +
292 : " COMPONENT_VALUE\n"
293 : " ARG\n"
294 : " IDENTIFIER \"div\"\n"
295 : " OPEN_CURLYBRACKET B:true\n"
296 : " DECLARATION \"z-index\"\n"
297 : " ARG\n"
298 : " MAP\n"
299 : " IDENTIFIER \"a\"\n"
300 : " INTEGER \"\" I:15\n"
301 : " IDENTIFIER \"b\"\n"
302 : " INTEGER \"\" I:1\n"
303 : " IDENTIFIER \"c\"\n"
304 : " INTEGER \"\" I:-39\n"
305 : " IDENTIFIER \"d\"\n"
306 : " INTEGER \"\" I:44\n"
307 : " IDENTIFIER \"e\"\n"
308 : " INTEGER \"\" I:10\n"
309 : + csspp_test::get_close_comment(true)
310 :
311 : );
312 :
313 1 : CATCH_REQUIRE(c.get_root() == n);
314 1 : }
315 4 : CATCH_END_SECTION()
316 :
317 4 : CATCH_START_SECTION("create a map and retrieve each element with block-[] (number and name) and '.<name>'")
318 : {
319 1 : int const results[6] =
320 : {
321 : // first number is unused, just makes it more practical to have it
322 : 0, 15, 1, -39, 44, 10
323 : };
324 1 : char const * names[6] =
325 : {
326 : "", "abc", "bear", "charly", "dear", "electric"
327 : };
328 :
329 : // retrieve using an index
330 6 : for(int idx(1); idx <= 5; ++idx)
331 : {
332 5 : std::stringstream ss;
333 5 : ss << "div { z-index: (abc: 15, bear: 1, charly : -39, dear: 44, electric: 10)["
334 : << idx
335 : << "]; }"
336 5 : << "span { z-index: (abc : 15, bear:1, charly: -39, dear:44, electric : 10)["
337 : << -idx
338 5 : << "]; }";
339 15 : csspp::position pos("test.css");
340 5 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
341 :
342 10 : csspp::parser p(l);
343 :
344 5 : csspp::node::pointer_t n(p.stylesheet());
345 :
346 5 : csspp::compiler c;
347 5 : c.set_root(n);
348 5 : c.set_date_time_variables(csspp_test::get_now());
349 5 : c.add_path(csspp_test::get_script_path());
350 5 : c.add_path(csspp_test::get_version_script_path());
351 :
352 5 : c.compile(false);
353 :
354 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
355 :
356 : // to verify that the result is still an INTEGER we have to
357 : // test the root node here
358 5 : std::stringstream compiler_out;
359 5 : compiler_out << *n;
360 5 : VERIFY_TREES(compiler_out.str(),
361 :
362 : "LIST\n"
363 : + csspp_test::get_default_variables() +
364 : " COMPONENT_VALUE\n"
365 : " ARG\n"
366 : " IDENTIFIER \"div\"\n"
367 : " OPEN_CURLYBRACKET B:true\n"
368 : " DECLARATION \"z-index\"\n"
369 : " ARG\n"
370 : " INTEGER \"\" I:" + std::to_string(results[idx]) + "\n"
371 : " COMPONENT_VALUE\n"
372 : " ARG\n"
373 : " IDENTIFIER \"span\"\n"
374 : " OPEN_CURLYBRACKET B:true\n"
375 : " DECLARATION \"z-index\"\n"
376 : " ARG\n"
377 : " INTEGER \"\" I:" + std::to_string(results[6 - idx]) + "\n"
378 : + csspp_test::get_close_comment(true)
379 :
380 : );
381 :
382 5 : std::stringstream assembler_out;
383 5 : csspp::assembler a(assembler_out);
384 5 : a.output(n, csspp::output_mode_t::COMPRESSED);
385 :
386 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
387 :
388 5 : CATCH_REQUIRE(assembler_out.str() ==
389 :
390 : "div{z-index:" + std::to_string(results[idx]) + "}"
391 : "span{z-index:" + std::to_string(results[6 - idx]) + "}"
392 : "\n"
393 : + csspp_test::get_close_comment()
394 :
395 : );
396 :
397 5 : CATCH_REQUIRE(c.get_root() == n);
398 5 : }
399 :
400 : // retrieve using an identifier, a string, and the period syntax
401 6 : for(int idx(1); idx <= 5; ++idx)
402 : {
403 5 : std::stringstream ss;
404 : ss << "div { z-index: (abc: 15, bear: 1, charly: -39, dear: 44, electric: 10)"
405 10 : << (rand() % 4 ? "" : " ")
406 : << "["
407 10 : << (rand() % 4 ? "" : " ")
408 : << names[idx]
409 10 : << (rand() % 4 ? "" : " ")
410 : << "]; }"
411 : << "p { z-index: (abc: 15, bear: 1, charly: -39, dear: 44, electric: 10)"
412 10 : << (rand() % 4 ? "" : " ")
413 : << "["
414 10 : << (rand() % 4 ? "" : " ")
415 : << "'"
416 : << names[idx]
417 : << "'"
418 10 : << (rand() % 4 ? "" : " ")
419 : << "]; }"
420 : << "span { z-index: (abc: 15, bear: 1, charly: -39, dear: 44, electric: 10)"
421 10 : << (rand() % 4 ? "" : " ")
422 : << "."
423 10 : << (rand() % 4 ? "" : " ")
424 : << names[idx]
425 5 : << "; }";
426 15 : csspp::position pos("test.css");
427 5 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
428 :
429 10 : csspp::parser p(l);
430 :
431 5 : csspp::node::pointer_t n(p.stylesheet());
432 :
433 5 : csspp::compiler c;
434 5 : c.set_root(n);
435 5 : c.set_date_time_variables(csspp_test::get_now());
436 5 : c.add_path(csspp_test::get_script_path());
437 5 : c.add_path(csspp_test::get_version_script_path());
438 :
439 5 : c.compile(false);
440 :
441 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
442 :
443 : // to verify that the result is still an INTEGER we have to
444 : // test the root node here
445 5 : std::stringstream compiler_out;
446 5 : compiler_out << *n;
447 5 : VERIFY_TREES(compiler_out.str(),
448 :
449 : "LIST\n"
450 : + csspp_test::get_default_variables() +
451 : " COMPONENT_VALUE\n"
452 : " ARG\n"
453 : " IDENTIFIER \"div\"\n"
454 : " OPEN_CURLYBRACKET B:true\n"
455 : " DECLARATION \"z-index\"\n"
456 : " ARG\n"
457 : " INTEGER \"\" I:" + std::to_string(results[idx]) + "\n"
458 : " COMPONENT_VALUE\n"
459 : " ARG\n"
460 : " IDENTIFIER \"p\"\n"
461 : " OPEN_CURLYBRACKET B:true\n"
462 : " DECLARATION \"z-index\"\n"
463 : " ARG\n"
464 : " INTEGER \"\" I:" + std::to_string(results[idx]) + "\n"
465 : " COMPONENT_VALUE\n"
466 : " ARG\n"
467 : " IDENTIFIER \"span\"\n"
468 : " OPEN_CURLYBRACKET B:true\n"
469 : " DECLARATION \"z-index\"\n"
470 : " ARG\n"
471 : " INTEGER \"\" I:" + std::to_string(results[idx]) + "\n"
472 : + csspp_test::get_close_comment(true)
473 :
474 : );
475 :
476 5 : std::stringstream assembler_out;
477 5 : csspp::assembler a(assembler_out);
478 5 : a.output(n, csspp::output_mode_t::COMPRESSED);
479 :
480 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
481 :
482 5 : CATCH_REQUIRE(assembler_out.str() ==
483 :
484 : "div{z-index:" + std::to_string(results[idx]) + "}"
485 : "p{z-index:" + std::to_string(results[idx]) + "}"
486 : "span{z-index:" + std::to_string(results[idx]) + "}"
487 : "\n"
488 : + csspp_test::get_close_comment()
489 :
490 : );
491 :
492 5 : CATCH_REQUIRE(c.get_root() == n);
493 5 : }
494 : }
495 4 : CATCH_END_SECTION()
496 :
497 4 : CATCH_START_SECTION("test with empty entries in a map")
498 : {
499 1 : char const * results[6] =
500 : {
501 : // first number is unused, just makes it more practical to have it
502 : "", "15", "-3", "", "44", "11"
503 : };
504 1 : char const * names[6] =
505 : {
506 : "", "fab", "kangoroo", "angles", "style", "more"
507 : };
508 :
509 : // retrieve using an index
510 6 : for(int idx(1); idx <= 5; ++idx)
511 : {
512 5 : std::stringstream ss;
513 5 : ss << "div { z-index: (fab: 15, kangoroo: -3, angles: , style: 44, more: 11)["
514 : << idx
515 : << "]; }"
516 5 : << "span { z-index: (fab: 15, kangoroo: -3, angles: , style: 44, more: 11)["
517 : << -idx
518 5 : << "]; }";
519 15 : csspp::position pos("test.css");
520 5 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
521 :
522 10 : csspp::parser p(l);
523 :
524 5 : csspp::node::pointer_t n(p.stylesheet());
525 :
526 5 : csspp::compiler c;
527 5 : c.set_root(n);
528 5 : c.set_date_time_variables(csspp_test::get_now());
529 5 : c.add_path(csspp_test::get_script_path());
530 5 : c.add_path(csspp_test::get_version_script_path());
531 :
532 5 : c.compile(false);
533 :
534 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
535 :
536 : // to verify that the result is still an INTEGER we have to
537 : // test the root node here
538 5 : std::stringstream compiler_out;
539 5 : compiler_out << *n;
540 :
541 5 : if(idx == 3)
542 : {
543 1 : VERIFY_TREES(compiler_out.str(),
544 :
545 : "LIST\n"
546 : + csspp_test::get_default_variables() +
547 : " COMPONENT_VALUE\n"
548 : " ARG\n"
549 : " IDENTIFIER \"div\"\n"
550 : " OPEN_CURLYBRACKET B:true\n"
551 : " DECLARATION \"z-index\"\n"
552 : " ARG\n"
553 : " NULL_TOKEN\n"
554 : " COMPONENT_VALUE\n"
555 : " ARG\n"
556 : " IDENTIFIER \"span\"\n"
557 : " OPEN_CURLYBRACKET B:true\n"
558 : " DECLARATION \"z-index\"\n"
559 : " ARG\n"
560 : " NULL_TOKEN\n"
561 : + csspp_test::get_close_comment(true)
562 :
563 : );
564 : }
565 : else
566 : {
567 4 : VERIFY_TREES(compiler_out.str(),
568 :
569 : "LIST\n"
570 : + csspp_test::get_default_variables() +
571 : " COMPONENT_VALUE\n"
572 : " ARG\n"
573 : " IDENTIFIER \"div\"\n"
574 : " OPEN_CURLYBRACKET B:true\n"
575 : " DECLARATION \"z-index\"\n"
576 : " ARG\n"
577 : " INTEGER \"\" I:" + results[idx] + "\n"
578 : " COMPONENT_VALUE\n"
579 : " ARG\n"
580 : " IDENTIFIER \"span\"\n"
581 : " OPEN_CURLYBRACKET B:true\n"
582 : " DECLARATION \"z-index\"\n"
583 : " ARG\n"
584 : " INTEGER \"\" I:" + results[6 - idx] + "\n"
585 : + csspp_test::get_close_comment(true)
586 :
587 : );
588 :
589 4 : std::stringstream assembler_out;
590 4 : csspp::assembler a(assembler_out);
591 4 : a.output(n, csspp::output_mode_t::COMPRESSED);
592 :
593 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
594 :
595 4 : CATCH_REQUIRE(assembler_out.str() ==
596 :
597 : std::string("div{z-index:") + results[idx] + "}"
598 : "span{z-index:" + results[6 - idx] + "}"
599 : "\n"
600 : + csspp_test::get_close_comment()
601 :
602 : );
603 4 : }
604 :
605 5 : CATCH_REQUIRE(c.get_root() == n);
606 5 : }
607 :
608 : // retrieve using an identifier, a string, and the period syntax
609 6 : for(int idx(1); idx <= 5; ++idx)
610 : {
611 5 : std::stringstream ss;
612 : ss << "div { z-index: (fab: 15, kangoroo: -3, angles: , style: 44, more: 11)"
613 10 : << (rand() % 4 ? "" : " ")
614 : << "["
615 10 : << (rand() % 4 ? "" : " ")
616 : << names[idx]
617 10 : << (rand() % 4 ? "" : " ")
618 : << "]; }"
619 : << "p { z-index: (fab: 15, kangoroo: -3, angles: , style: 44, more: 11)"
620 10 : << (rand() % 4 ? "" : " ")
621 : << "["
622 10 : << (rand() % 4 ? "" : " ")
623 : << "'"
624 : << names[idx]
625 : << "'"
626 10 : << (rand() % 4 ? "" : " ")
627 : << "]; }"
628 : << "span { z-index: (fab: 15, kangoroo: -3, angles: , style: 44, more: 11)"
629 10 : << (rand() % 4 ? "" : " ")
630 : << "."
631 10 : << (rand() % 4 ? "" : " ")
632 : << names[idx]
633 5 : << "; }";
634 15 : csspp::position pos("test.css");
635 5 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
636 :
637 10 : csspp::parser p(l);
638 :
639 5 : csspp::node::pointer_t n(p.stylesheet());
640 :
641 5 : csspp::compiler c;
642 5 : c.set_root(n);
643 5 : c.set_date_time_variables(csspp_test::get_now());
644 5 : c.add_path(csspp_test::get_script_path());
645 5 : c.add_path(csspp_test::get_version_script_path());
646 :
647 5 : c.compile(false);
648 :
649 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
650 :
651 : // to verify that the result is still an INTEGER we have to
652 : // test the root node here
653 5 : std::stringstream compiler_out;
654 5 : compiler_out << *n;
655 :
656 5 : if(idx == 3)
657 : {
658 1 : VERIFY_TREES(compiler_out.str(),
659 :
660 : "LIST\n"
661 : + csspp_test::get_default_variables() +
662 : " COMPONENT_VALUE\n"
663 : " ARG\n"
664 : " IDENTIFIER \"div\"\n"
665 : " OPEN_CURLYBRACKET B:true\n"
666 : " DECLARATION \"z-index\"\n"
667 : " ARG\n"
668 : " NULL_TOKEN\n"
669 : " COMPONENT_VALUE\n"
670 : " ARG\n"
671 : " IDENTIFIER \"p\"\n"
672 : " OPEN_CURLYBRACKET B:true\n"
673 : " DECLARATION \"z-index\"\n"
674 : " ARG\n"
675 : " NULL_TOKEN\n"
676 : " COMPONENT_VALUE\n"
677 : " ARG\n"
678 : " IDENTIFIER \"span\"\n"
679 : " OPEN_CURLYBRACKET B:true\n"
680 : " DECLARATION \"z-index\"\n"
681 : " ARG\n"
682 : " NULL_TOKEN\n"
683 : + csspp_test::get_close_comment(true)
684 :
685 : );
686 : }
687 : else
688 : {
689 4 : VERIFY_TREES(compiler_out.str(),
690 :
691 : "LIST\n"
692 : + csspp_test::get_default_variables() +
693 : " COMPONENT_VALUE\n"
694 : " ARG\n"
695 : " IDENTIFIER \"div\"\n"
696 : " OPEN_CURLYBRACKET B:true\n"
697 : " DECLARATION \"z-index\"\n"
698 : " ARG\n"
699 : " INTEGER \"\" I:" + results[idx] + "\n"
700 : " COMPONENT_VALUE\n"
701 : " ARG\n"
702 : " IDENTIFIER \"p\"\n"
703 : " OPEN_CURLYBRACKET B:true\n"
704 : " DECLARATION \"z-index\"\n"
705 : " ARG\n"
706 : " INTEGER \"\" I:" + results[idx] + "\n"
707 : " COMPONENT_VALUE\n"
708 : " ARG\n"
709 : " IDENTIFIER \"span\"\n"
710 : " OPEN_CURLYBRACKET B:true\n"
711 : " DECLARATION \"z-index\"\n"
712 : " ARG\n"
713 : " INTEGER \"\" I:" + results[idx] + "\n"
714 : + csspp_test::get_close_comment(true)
715 :
716 : );
717 :
718 4 : std::stringstream assembler_out;
719 4 : csspp::assembler a(assembler_out);
720 4 : a.output(n, csspp::output_mode_t::COMPRESSED);
721 :
722 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
723 :
724 4 : CATCH_REQUIRE(assembler_out.str() ==
725 :
726 : std::string("div{z-index:") + results[idx] + "}"
727 : "p{z-index:" + results[idx] + "}"
728 : "span{z-index:" + results[idx] + "}"
729 : "\n"
730 : + csspp_test::get_close_comment()
731 :
732 : );
733 4 : }
734 :
735 5 : CATCH_REQUIRE(c.get_root() == n);
736 5 : }
737 : }
738 4 : CATCH_END_SECTION()
739 :
740 4 : CATCH_START_SECTION("test once more with no ending value")
741 : {
742 1 : char const * results[6] =
743 : {
744 : // first number is unused, just makes it more practical to have it
745 : "", "15", "-3", "-19", "44", ""
746 : };
747 1 : char const * names[6] =
748 : {
749 : "", "fab", "kangoroo", "angles", "style", "more"
750 : };
751 :
752 : // retrieve using an index
753 6 : for(int idx(1); idx <= 5; ++idx)
754 : {
755 5 : std::stringstream ss;
756 5 : ss << "div { z-index: (fab: 15, kangoroo: -3, angles: -19, style: 44, more: )["
757 : << idx
758 : << "]; }"
759 5 : << "span { z-index: (fab: 15, kangoroo: -3, angles: -19, style: 44, more: )["
760 : << -idx
761 5 : << "]; }";
762 15 : csspp::position pos("test.css");
763 5 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
764 :
765 10 : csspp::parser p(l);
766 :
767 5 : csspp::node::pointer_t n(p.stylesheet());
768 :
769 5 : csspp::compiler c;
770 5 : c.set_root(n);
771 5 : c.set_date_time_variables(csspp_test::get_now());
772 5 : c.add_path(csspp_test::get_script_path());
773 5 : c.add_path(csspp_test::get_version_script_path());
774 :
775 5 : c.compile(false);
776 :
777 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
778 :
779 : // to verify that the result is still an INTEGER we have to
780 : // test the root node here
781 5 : std::stringstream compiler_out;
782 5 : compiler_out << *n;
783 :
784 5 : VERIFY_TREES(compiler_out.str(),
785 :
786 : "LIST\n"
787 : + csspp_test::get_default_variables() +
788 : " COMPONENT_VALUE\n"
789 : " ARG\n"
790 : " IDENTIFIER \"div\"\n"
791 : " OPEN_CURLYBRACKET B:true\n"
792 : " DECLARATION \"z-index\"\n"
793 : " ARG\n"
794 :
795 : + (idx == 5 ?
796 : " NULL_TOKEN\n" :
797 : " INTEGER \"\" I:" + std::string(results[idx]) + "\n") +
798 :
799 : " COMPONENT_VALUE\n"
800 : " ARG\n"
801 : " IDENTIFIER \"span\"\n"
802 : " OPEN_CURLYBRACKET B:true\n"
803 : " DECLARATION \"z-index\"\n"
804 : " ARG\n"
805 :
806 : + (idx == 1 ?
807 : " NULL_TOKEN\n" :
808 : " INTEGER \"\" I:" + std::string(results[6 - idx]) + "\n")
809 :
810 : + csspp_test::get_close_comment(true)
811 :
812 : );
813 :
814 : // 1 and 5 have NULL_TOKEN that the assembler would barf on
815 5 : if(idx != 1 && idx != 5)
816 : {
817 3 : std::stringstream assembler_out;
818 3 : csspp::assembler a(assembler_out);
819 3 : 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 3 : CATCH_REQUIRE(assembler_out.str() ==
824 :
825 : std::string("div{z-index:") + results[idx] + "}"
826 : "span{z-index:" + results[6 - idx] + "}"
827 : "\n"
828 : + csspp_test::get_close_comment()
829 :
830 : );
831 3 : }
832 :
833 5 : CATCH_REQUIRE(c.get_root() == n);
834 5 : }
835 :
836 : // retrieve using an identifier, a string, and the period syntax
837 6 : for(int idx(1); idx <= 5; ++idx)
838 : {
839 5 : std::stringstream ss;
840 : ss << "div { z-index: (fab: 15, kangoroo: -3, angles: -19, style: 44, more: )"
841 10 : << (rand() % 4 ? "" : " ")
842 : << "["
843 10 : << (rand() % 4 ? "" : " ")
844 : << names[idx]
845 10 : << (rand() % 4 ? "" : " ")
846 : << "]; }"
847 : << "p { z-index: (fab: 15, kangoroo: -3, angles: -19, style: 44, more: )"
848 10 : << (rand() % 4 ? "" : " ")
849 : << "["
850 10 : << (rand() % 4 ? "" : " ")
851 : << "'"
852 : << names[idx]
853 : << "'"
854 10 : << (rand() % 4 ? "" : " ")
855 : << "]; }"
856 : << "span { z-index: (fab: 15, kangoroo: -3, angles: -19, style: 44, more: )"
857 10 : << (rand() % 4 ? "" : " ")
858 : << "."
859 10 : << (rand() % 4 ? "" : " ")
860 : << names[idx]
861 5 : << "; }";
862 15 : csspp::position pos("test.css");
863 5 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
864 :
865 10 : csspp::parser p(l);
866 :
867 5 : csspp::node::pointer_t n(p.stylesheet());
868 :
869 5 : csspp::compiler c;
870 5 : c.set_root(n);
871 5 : c.set_date_time_variables(csspp_test::get_now());
872 5 : c.add_path(csspp_test::get_script_path());
873 5 : c.add_path(csspp_test::get_version_script_path());
874 :
875 5 : c.compile(false);
876 :
877 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
878 :
879 : // to verify that the result is still an INTEGER we have to
880 : // test the root node here
881 5 : std::stringstream compiler_out;
882 5 : compiler_out << *n;
883 :
884 5 : if(idx == 5)
885 : {
886 1 : VERIFY_TREES(compiler_out.str(),
887 :
888 : "LIST\n"
889 : + csspp_test::get_default_variables() +
890 : " COMPONENT_VALUE\n"
891 : " ARG\n"
892 : " IDENTIFIER \"div\"\n"
893 : " OPEN_CURLYBRACKET B:true\n"
894 : " DECLARATION \"z-index\"\n"
895 : " ARG\n"
896 : " NULL_TOKEN\n"
897 : " COMPONENT_VALUE\n"
898 : " ARG\n"
899 : " IDENTIFIER \"p\"\n"
900 : " OPEN_CURLYBRACKET B:true\n"
901 : " DECLARATION \"z-index\"\n"
902 : " ARG\n"
903 : " NULL_TOKEN\n"
904 : " COMPONENT_VALUE\n"
905 : " ARG\n"
906 : " IDENTIFIER \"span\"\n"
907 : " OPEN_CURLYBRACKET B:true\n"
908 : " DECLARATION \"z-index\"\n"
909 : " ARG\n"
910 : " NULL_TOKEN\n"
911 : + csspp_test::get_close_comment(true)
912 :
913 : );
914 : }
915 : else
916 : {
917 4 : VERIFY_TREES(compiler_out.str(),
918 :
919 : "LIST\n"
920 : + csspp_test::get_default_variables() +
921 : " COMPONENT_VALUE\n"
922 : " ARG\n"
923 : " IDENTIFIER \"div\"\n"
924 : " OPEN_CURLYBRACKET B:true\n"
925 : " DECLARATION \"z-index\"\n"
926 : " ARG\n"
927 : " INTEGER \"\" I:" + results[idx] + "\n"
928 : " COMPONENT_VALUE\n"
929 : " ARG\n"
930 : " IDENTIFIER \"p\"\n"
931 : " OPEN_CURLYBRACKET B:true\n"
932 : " DECLARATION \"z-index\"\n"
933 : " ARG\n"
934 : " INTEGER \"\" I:" + results[idx] + "\n"
935 : " COMPONENT_VALUE\n"
936 : " ARG\n"
937 : " IDENTIFIER \"span\"\n"
938 : " OPEN_CURLYBRACKET B:true\n"
939 : " DECLARATION \"z-index\"\n"
940 : " ARG\n"
941 : " INTEGER \"\" I:" + results[idx] + "\n"
942 : + csspp_test::get_close_comment(true)
943 :
944 : );
945 :
946 4 : std::stringstream assembler_out;
947 4 : csspp::assembler a(assembler_out);
948 4 : a.output(n, csspp::output_mode_t::COMPRESSED);
949 :
950 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
951 :
952 4 : CATCH_REQUIRE(assembler_out.str() ==
953 :
954 : std::string("div{z-index:") + results[idx] + "}"
955 : "p{z-index:" + results[idx] + "}"
956 : "span{z-index:" + results[idx] + "}"
957 : "\n"
958 : + csspp_test::get_close_comment()
959 :
960 : );
961 4 : }
962 :
963 5 : CATCH_REQUIRE(c.get_root() == n);
964 5 : }
965 : }
966 4 : CATCH_END_SECTION()
967 :
968 : // no error left over
969 4 : VERIFY_ERRORS("");
970 4 : }
971 :
972 14 : CATCH_TEST_CASE("Expression invalid lists", "[expression] [list] [array] [map] [invalid]")
973 : {
974 14 : CATCH_START_SECTION("array was an invalid number")
975 : {
976 1 : std::stringstream ss;
977 1 : ss << "div { border: (1, ?, 3); }";
978 3 : csspp::position pos("test.css");
979 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
980 :
981 2 : csspp::parser p(l);
982 :
983 1 : csspp::node::pointer_t n(p.stylesheet());
984 :
985 1 : csspp::compiler c;
986 1 : c.set_root(n);
987 1 : c.set_date_time_variables(csspp_test::get_now());
988 1 : c.add_path(csspp_test::get_script_path());
989 1 : c.add_path(csspp_test::get_version_script_path());
990 :
991 1 : c.compile(false);
992 :
993 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
994 :
995 1 : VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
996 :
997 1 : CATCH_REQUIRE(c.get_root() == n);
998 1 : }
999 14 : CATCH_END_SECTION()
1000 :
1001 14 : CATCH_START_SECTION("array accessed with an invalid index")
1002 : {
1003 1 : std::stringstream ss;
1004 1 : ss << "div { border: (1, 2, 3)[?]; }";
1005 3 : csspp::position pos("test.css");
1006 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1007 :
1008 2 : csspp::parser p(l);
1009 :
1010 1 : csspp::node::pointer_t n(p.stylesheet());
1011 :
1012 1 : csspp::compiler c;
1013 1 : c.set_root(n);
1014 1 : c.set_date_time_variables(csspp_test::get_now());
1015 1 : c.add_path(csspp_test::get_script_path());
1016 1 : c.add_path(csspp_test::get_version_script_path());
1017 :
1018 1 : c.compile(false);
1019 :
1020 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1021 :
1022 1 : VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
1023 :
1024 1 : CATCH_REQUIRE(c.get_root() == n);
1025 1 : }
1026 14 : CATCH_END_SECTION()
1027 :
1028 14 : CATCH_START_SECTION("dereferencing something which cannot be dereferenced")
1029 : {
1030 1 : std::stringstream ss;
1031 1 : ss << "div { border: U+A??[1]; }";
1032 3 : csspp::position pos("test.css");
1033 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1034 :
1035 2 : csspp::parser p(l);
1036 :
1037 1 : csspp::node::pointer_t n(p.stylesheet());
1038 :
1039 1 : csspp::compiler c;
1040 1 : c.set_root(n);
1041 1 : c.set_date_time_variables(csspp_test::get_now());
1042 1 : c.add_path(csspp_test::get_script_path());
1043 1 : c.add_path(csspp_test::get_version_script_path());
1044 :
1045 1 : c.compile(false);
1046 :
1047 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1048 :
1049 1 : VERIFY_ERRORS("test.css(1): error: unsupported type UNICODE_RANGE for the 'array[<index>]' operation.\n");
1050 :
1051 1 : CATCH_REQUIRE(c.get_root() == n);
1052 1 : }
1053 14 : CATCH_END_SECTION()
1054 :
1055 14 : CATCH_START_SECTION("array accessed with a decimal number index")
1056 : {
1057 1 : std::stringstream ss;
1058 1 : ss << "div { border: (1, 2, 3)[3.4]; }";
1059 3 : csspp::position pos("test.css");
1060 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1061 :
1062 2 : csspp::parser p(l);
1063 :
1064 1 : csspp::node::pointer_t n(p.stylesheet());
1065 :
1066 1 : csspp::compiler c;
1067 1 : c.set_root(n);
1068 1 : c.set_date_time_variables(csspp_test::get_now());
1069 1 : c.add_path(csspp_test::get_script_path());
1070 1 : c.add_path(csspp_test::get_version_script_path());
1071 :
1072 1 : c.compile(false);
1073 :
1074 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1075 :
1076 1 : VERIFY_ERRORS("test.css(1): error: an integer, an identifier, or a string was expected as the index (defined in '[ ... ]'). A DECIMAL_NUMBER was not expected.\n");
1077 :
1078 1 : CATCH_REQUIRE(c.get_root() == n);
1079 1 : }
1080 14 : CATCH_END_SECTION()
1081 :
1082 14 : CATCH_START_SECTION("array[0] is invalid")
1083 : {
1084 1 : std::stringstream ss;
1085 1 : ss << "div { border: (1, 2, 3)[0]; }";
1086 3 : csspp::position pos("test.css");
1087 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1088 :
1089 2 : csspp::parser p(l);
1090 :
1091 1 : csspp::node::pointer_t n(p.stylesheet());
1092 :
1093 1 : csspp::compiler c;
1094 1 : c.set_root(n);
1095 1 : c.set_date_time_variables(csspp_test::get_now());
1096 1 : c.add_path(csspp_test::get_script_path());
1097 1 : c.add_path(csspp_test::get_version_script_path());
1098 :
1099 1 : c.compile(false);
1100 :
1101 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1102 :
1103 1 : VERIFY_ERRORS("test.css(1): error: index 0 is out of range. The allowed range is 1 to 3.\n");
1104 :
1105 1 : CATCH_REQUIRE(c.get_root() == n);
1106 1 : }
1107 14 : CATCH_END_SECTION()
1108 :
1109 14 : CATCH_START_SECTION("array[-x or +y] are invalid when out of range")
1110 : {
1111 98 : for(int idx(4); idx <= 100; ++idx)
1112 : {
1113 : // from the front
1114 : {
1115 97 : std::stringstream ss;
1116 97 : ss << "div { border: (1, 2, 3)["
1117 : << idx
1118 97 : << "]; }";
1119 291 : csspp::position pos("test.css");
1120 97 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1121 :
1122 194 : csspp::parser p(l);
1123 :
1124 97 : csspp::node::pointer_t n(p.stylesheet());
1125 :
1126 97 : csspp::compiler c;
1127 97 : c.set_root(n);
1128 97 : c.set_date_time_variables(csspp_test::get_now());
1129 97 : c.add_path(csspp_test::get_script_path());
1130 97 : c.add_path(csspp_test::get_version_script_path());
1131 :
1132 97 : c.compile(false);
1133 :
1134 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1135 :
1136 97 : std::stringstream errmsg;
1137 97 : errmsg << "test.css(1): error: index "
1138 : << idx
1139 97 : << " is out of range. The allowed range is 1 to 3.\n";
1140 97 : VERIFY_ERRORS(errmsg.str());
1141 :
1142 97 : CATCH_REQUIRE(c.get_root() == n);
1143 97 : }
1144 :
1145 : // from the back
1146 : {
1147 97 : std::stringstream ss;
1148 97 : ss << "div { border: (1, 2, 3)[-"
1149 : << idx
1150 97 : << "]; }";
1151 291 : csspp::position pos("test.css");
1152 97 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1153 :
1154 194 : csspp::parser p(l);
1155 :
1156 97 : csspp::node::pointer_t n(p.stylesheet());
1157 :
1158 97 : csspp::compiler c;
1159 97 : c.set_root(n);
1160 97 : c.set_date_time_variables(csspp_test::get_now());
1161 97 : c.add_path(csspp_test::get_script_path());
1162 97 : c.add_path(csspp_test::get_version_script_path());
1163 :
1164 97 : c.compile(false);
1165 :
1166 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1167 :
1168 97 : std::stringstream errmsg;
1169 97 : errmsg << "test.css(1): error: index "
1170 : << -idx
1171 97 : << " is out of range. The allowed range is 1 to 3.\n";
1172 97 : VERIFY_ERRORS(errmsg.str());
1173 :
1174 97 : CATCH_REQUIRE(c.get_root() == n);
1175 97 : }
1176 : }
1177 : }
1178 14 : CATCH_END_SECTION()
1179 :
1180 14 : CATCH_START_SECTION("array.field is not invalid")
1181 : {
1182 1 : std::stringstream ss;
1183 1 : ss << "div { border: (1, 2, 3).unexpected; }";
1184 3 : csspp::position pos("test.css");
1185 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1186 :
1187 2 : csspp::parser p(l);
1188 :
1189 1 : csspp::node::pointer_t n(p.stylesheet());
1190 :
1191 1 : csspp::compiler c;
1192 1 : c.set_root(n);
1193 1 : c.set_date_time_variables(csspp_test::get_now());
1194 1 : c.add_path(csspp_test::get_script_path());
1195 1 : c.add_path(csspp_test::get_version_script_path());
1196 :
1197 1 : c.compile(false);
1198 :
1199 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1200 :
1201 1 : VERIFY_ERRORS("test.css(1): error: unsupported left handside type ARRAY for the '<map>.<identifier>' operation.\n");
1202 :
1203 1 : CATCH_REQUIRE(c.get_root() == n);
1204 1 : }
1205 14 : CATCH_END_SECTION()
1206 :
1207 14 : CATCH_START_SECTION("map with an invalid number")
1208 : {
1209 1 : std::stringstream ss;
1210 1 : ss << "div { border: (aaa: 1, bbb: ?, ccc: 3); }";
1211 3 : csspp::position pos("test.css");
1212 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1213 :
1214 2 : csspp::parser p(l);
1215 :
1216 1 : csspp::node::pointer_t n(p.stylesheet());
1217 :
1218 1 : csspp::compiler c;
1219 1 : c.set_root(n);
1220 1 : c.set_date_time_variables(csspp_test::get_now());
1221 1 : c.add_path(csspp_test::get_script_path());
1222 1 : c.add_path(csspp_test::get_version_script_path());
1223 :
1224 1 : c.compile(false);
1225 :
1226 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1227 :
1228 1 : VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
1229 :
1230 1 : CATCH_REQUIRE(c.get_root() == n);
1231 1 : }
1232 14 : CATCH_END_SECTION()
1233 :
1234 14 : CATCH_START_SECTION("map accessed with an invalid index")
1235 : {
1236 1 : std::stringstream ss;
1237 1 : ss << "div { border: (poors: 1, man: 2, test: 3)[?]; }";
1238 3 : csspp::position pos("test.css");
1239 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1240 :
1241 2 : csspp::parser p(l);
1242 :
1243 1 : csspp::node::pointer_t n(p.stylesheet());
1244 :
1245 1 : csspp::compiler c;
1246 1 : c.set_root(n);
1247 1 : c.set_date_time_variables(csspp_test::get_now());
1248 1 : c.add_path(csspp_test::get_script_path());
1249 1 : c.add_path(csspp_test::get_version_script_path());
1250 :
1251 1 : c.compile(false);
1252 :
1253 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1254 :
1255 1 : VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
1256 :
1257 1 : CATCH_REQUIRE(c.get_root() == n);
1258 1 : }
1259 14 : CATCH_END_SECTION()
1260 :
1261 14 : CATCH_START_SECTION("map accessed with a decimal number index")
1262 : {
1263 1 : std::stringstream ss;
1264 1 : ss << "div { border: (map: 1, and: 2, decimal_number: 3)[3.4]; }";
1265 3 : csspp::position pos("test.css");
1266 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1267 :
1268 2 : csspp::parser p(l);
1269 :
1270 1 : csspp::node::pointer_t n(p.stylesheet());
1271 :
1272 1 : csspp::compiler c;
1273 1 : c.set_root(n);
1274 1 : c.set_date_time_variables(csspp_test::get_now());
1275 1 : c.add_path(csspp_test::get_script_path());
1276 1 : c.add_path(csspp_test::get_version_script_path());
1277 :
1278 1 : c.compile(false);
1279 :
1280 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1281 :
1282 1 : VERIFY_ERRORS("test.css(1): error: an integer, an identifier, or a string was expected as the index (defined in '[ ... ]'). A DECIMAL_NUMBER was not expected.\n");
1283 :
1284 1 : CATCH_REQUIRE(c.get_root() == n);
1285 1 : }
1286 14 : CATCH_END_SECTION()
1287 :
1288 14 : CATCH_START_SECTION("map[0] is invalid")
1289 : {
1290 1 : std::stringstream ss;
1291 1 : ss << "div { border: (zero: 1, as: 2, index: 3)[0]; }";
1292 3 : csspp::position pos("test.css");
1293 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1294 :
1295 2 : csspp::parser p(l);
1296 :
1297 1 : csspp::node::pointer_t n(p.stylesheet());
1298 :
1299 1 : csspp::compiler c;
1300 1 : c.set_root(n);
1301 1 : c.set_date_time_variables(csspp_test::get_now());
1302 1 : c.add_path(csspp_test::get_script_path());
1303 1 : c.add_path(csspp_test::get_version_script_path());
1304 :
1305 1 : c.compile(false);
1306 :
1307 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1308 :
1309 1 : VERIFY_ERRORS("test.css(1): error: index 0 is out of range. The allowed range is 1 to 3.\n");
1310 :
1311 1 : CATCH_REQUIRE(c.get_root() == n);
1312 1 : }
1313 14 : CATCH_END_SECTION()
1314 :
1315 14 : CATCH_START_SECTION("map[-x or +y] are invalid when out of range")
1316 : {
1317 98 : for(int idx(4); idx <= 100; ++idx)
1318 : {
1319 : // from the front
1320 : {
1321 97 : std::stringstream ss;
1322 97 : ss << "div { border: (large: 1, index: 2, out-of-range: 3)["
1323 : << idx
1324 97 : << "]; }";
1325 291 : csspp::position pos("test.css");
1326 97 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1327 :
1328 194 : csspp::parser p(l);
1329 :
1330 97 : csspp::node::pointer_t n(p.stylesheet());
1331 :
1332 97 : csspp::compiler c;
1333 97 : c.set_root(n);
1334 97 : c.set_date_time_variables(csspp_test::get_now());
1335 97 : c.add_path(csspp_test::get_script_path());
1336 97 : c.add_path(csspp_test::get_version_script_path());
1337 :
1338 97 : c.compile(false);
1339 :
1340 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1341 :
1342 97 : std::stringstream errmsg;
1343 97 : errmsg << "test.css(1): error: index "
1344 : << idx
1345 97 : << " is out of range. The allowed range is 1 to 3.\n";
1346 97 : VERIFY_ERRORS(errmsg.str());
1347 :
1348 97 : CATCH_REQUIRE(c.get_root() == n);
1349 97 : }
1350 :
1351 : // from the back
1352 : {
1353 97 : std::stringstream ss;
1354 97 : ss << "div { border: (negative: 1, offset: 2, out-of-range-too: 3)[-"
1355 : << idx
1356 97 : << "]; }";
1357 291 : csspp::position pos("test.css");
1358 97 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1359 :
1360 194 : csspp::parser p(l);
1361 :
1362 97 : csspp::node::pointer_t n(p.stylesheet());
1363 :
1364 97 : csspp::compiler c;
1365 97 : c.set_root(n);
1366 97 : c.set_date_time_variables(csspp_test::get_now());
1367 97 : c.add_path(csspp_test::get_script_path());
1368 97 : c.add_path(csspp_test::get_version_script_path());
1369 :
1370 97 : c.compile(false);
1371 :
1372 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1373 :
1374 97 : std::stringstream errmsg;
1375 97 : errmsg << "test.css(1): error: index "
1376 : << -idx
1377 97 : << " is out of range. The allowed range is 1 to 3.\n";
1378 97 : VERIFY_ERRORS(errmsg.str());
1379 :
1380 97 : CATCH_REQUIRE(c.get_root() == n);
1381 97 : }
1382 : }
1383 : }
1384 14 : CATCH_END_SECTION()
1385 :
1386 14 : CATCH_START_SECTION("map[unknown] is similar to an 'out of range' error")
1387 : {
1388 1 : std::stringstream ss;
1389 1 : ss << "div { border: (large: 1, index: 2, out-of-range: 3)['unknown']; }";
1390 3 : csspp::position pos("test.css");
1391 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1392 :
1393 2 : csspp::parser p(l);
1394 :
1395 1 : csspp::node::pointer_t n(p.stylesheet());
1396 :
1397 1 : csspp::compiler c;
1398 1 : c.set_root(n);
1399 1 : c.set_date_time_variables(csspp_test::get_now());
1400 1 : c.add_path(csspp_test::get_script_path());
1401 1 : c.add_path(csspp_test::get_version_script_path());
1402 :
1403 1 : c.compile(false);
1404 :
1405 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1406 :
1407 1 : VERIFY_ERRORS("test.css(1): error: 'map[\"unknown\"]' is not set.\n");
1408 :
1409 1 : CATCH_REQUIRE(c.get_root() == n);
1410 1 : }
1411 14 : CATCH_END_SECTION()
1412 :
1413 14 : CATCH_START_SECTION("map . 123 is not possible")
1414 : {
1415 1 : std::stringstream ss;
1416 1 : ss << "div { border: (large: 1, index: 2, out-of-range: 3) . 123; }";
1417 3 : csspp::position pos("test.css");
1418 1 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1419 :
1420 2 : csspp::parser p(l);
1421 :
1422 1 : csspp::node::pointer_t n(p.stylesheet());
1423 :
1424 1 : csspp::compiler c;
1425 1 : c.set_root(n);
1426 1 : c.set_date_time_variables(csspp_test::get_now());
1427 1 : c.add_path(csspp_test::get_script_path());
1428 1 : c.add_path(csspp_test::get_version_script_path());
1429 :
1430 1 : c.compile(false);
1431 :
1432 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1433 :
1434 1 : VERIFY_ERRORS("test.css(1): error: only an identifier is expected after a '.'.\n");
1435 :
1436 1 : CATCH_REQUIRE(c.get_root() == n);
1437 1 : }
1438 14 : CATCH_END_SECTION()
1439 :
1440 : // no error left over
1441 14 : VERIFY_ERRORS("");
1442 14 : }
1443 :
1444 : // vim: ts=4 sw=4 et
|