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 assembler.cpp file.
22 : *
23 : * This test runs a battery of tests agains the assembler.cpp file to ensure
24 : * full coverage and many edge cases of CSS encoding.
25 : */
26 :
27 : // csspp
28 : //
29 : #include <csspp/assembler.h>
30 :
31 : #include <csspp/compiler.h>
32 : #include <csspp/exception.h>
33 : #include <csspp/parser.h>
34 :
35 :
36 : // self
37 : //
38 : #include "catch_main.h"
39 :
40 :
41 : // C++
42 : //
43 : #include <fstream>
44 : #include <iostream>
45 : #include <sstream>
46 :
47 :
48 : // C
49 : //
50 : #include <string.h>
51 : #include <string.h>
52 : #include <unistd.h>
53 : #include <sys/stat.h>
54 :
55 :
56 : // last include
57 : //
58 : #include <snapdev/poison.h>
59 :
60 :
61 :
62 : namespace
63 : {
64 :
65 100 : bool is_valid_mode(csspp::output_mode_t const mode)
66 : {
67 100 : switch(mode)
68 : {
69 0 : case csspp::output_mode_t::COMPACT:
70 : case csspp::output_mode_t::COMPRESSED:
71 : case csspp::output_mode_t::EXPANDED:
72 : case csspp::output_mode_t::TIDY:
73 0 : return true;
74 :
75 100 : default:
76 100 : return false;
77 :
78 : }
79 : }
80 :
81 64 : bool is_valid_char(csspp::wide_char_t c)
82 : {
83 64 : switch(c)
84 : {
85 0 : case 0:
86 : case 0xFFFD:
87 0 : return false;
88 :
89 64 : default:
90 64 : if(c >= 0xD800 && c <= 0xDFFF)
91 : {
92 : // UTF-16 surrogates are not valid wide characters
93 0 : return false;
94 : }
95 64 : return true;
96 :
97 : }
98 : }
99 :
100 : } // no name namespace
101 :
102 10 : CATCH_TEST_CASE("Assemble rules", "[assembler]")
103 : {
104 10 : CATCH_START_SECTION("with many spaces")
105 : {
106 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
107 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
108 : ++i)
109 : {
110 4 : std::stringstream ss;
111 : ss << "div { color: black; }"
112 : << "span { border: 3px solid complement(#f7d0cf); }"
113 : << "p { font: 13px/135% sans-serif; }"
114 4 : << "section { width: calc(30px - 5%); }";
115 12 : csspp::position pos("test.css");
116 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
117 :
118 8 : csspp::parser p(l);
119 :
120 4 : csspp::node::pointer_t n(p.stylesheet());
121 :
122 4 : csspp::compiler c;
123 4 : c.set_root(n);
124 4 : c.set_date_time_variables(csspp_test::get_now());
125 4 : c.add_path(csspp_test::get_script_path());
126 4 : c.add_path(csspp_test::get_version_script_path());
127 :
128 4 : c.compile(false);
129 :
130 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
131 :
132 4 : std::stringstream out;
133 4 : csspp::assembler a(out);
134 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
135 :
136 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
137 :
138 4 : switch(static_cast<csspp::output_mode_t>(i))
139 : {
140 1 : case csspp::output_mode_t::COMPACT:
141 1 : CATCH_REQUIRE(out.str() ==
142 : "div { color: #000 }\n"
143 : "span { border: 3px solid #cff6f7 }\n"
144 : "p { font: 13px/135% sans-serif }\n"
145 : "section { width: calc(30px - 5%) }\n"
146 : + csspp_test::get_close_comment()
147 : );
148 1 : break;
149 :
150 1 : case csspp::output_mode_t::COMPRESSED:
151 1 : CATCH_REQUIRE(out.str() ==
152 : "div{color:#000}span{border:3px solid #cff6f7}p{font:13px/135% sans-serif}section{width:calc(30px - 5%)}\n"
153 : + csspp_test::get_close_comment()
154 : );
155 1 : break;
156 :
157 1 : case csspp::output_mode_t::EXPANDED:
158 1 : CATCH_REQUIRE(out.str() ==
159 : "div\n"
160 : "{\n"
161 : " color: #000;\n"
162 : "}\n"
163 : "span\n"
164 : "{\n"
165 : " border: 3px solid #cff6f7;\n"
166 : "}\n"
167 : "p\n"
168 : "{\n"
169 : " font: 13px/135% sans-serif;\n"
170 : "}\n"
171 : "section\n"
172 : "{\n"
173 : " width: calc(30px - 5%);\n"
174 : "}\n"
175 : + csspp_test::get_close_comment()
176 : );
177 1 : break;
178 :
179 1 : case csspp::output_mode_t::TIDY:
180 1 : CATCH_REQUIRE(out.str() ==
181 : "div{color:#000}\n"
182 : "span{border:3px solid #cff6f7}\n"
183 : "p{font:13px/135% sans-serif}\n"
184 : "section{width:calc(30px - 5%)}\n"
185 : + csspp_test::get_close_comment()
186 : );
187 1 : break;
188 :
189 : }
190 :
191 4 : CATCH_REQUIRE(c.get_root() == n);
192 4 : }
193 : }
194 10 : CATCH_END_SECTION()
195 :
196 10 : CATCH_START_SECTION("with a calc including a divide after parenthesis")
197 : {
198 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
199 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
200 : ++i)
201 : {
202 4 : std::stringstream ss;
203 4 : ss << "#left-margin { width: calc((100% - 300px) / 2); }";
204 12 : csspp::position pos("test.css");
205 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
206 :
207 8 : csspp::parser p(l);
208 :
209 4 : csspp::node::pointer_t n(p.stylesheet());
210 :
211 4 : csspp::compiler c;
212 4 : c.set_root(n);
213 4 : c.set_date_time_variables(csspp_test::get_now());
214 4 : c.add_path(csspp_test::get_script_path());
215 4 : c.add_path(csspp_test::get_version_script_path());
216 :
217 4 : c.compile(false);
218 :
219 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
220 :
221 4 : std::stringstream out;
222 4 : csspp::assembler a(out);
223 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
224 :
225 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
226 :
227 4 : switch(static_cast<csspp::output_mode_t>(i))
228 : {
229 1 : case csspp::output_mode_t::COMPACT:
230 1 : CATCH_REQUIRE(out.str() ==
231 : "#left-margin { width: calc( (100% - 300px) / 2) }\n"
232 : + csspp_test::get_close_comment()
233 : );
234 1 : break;
235 :
236 1 : case csspp::output_mode_t::COMPRESSED:
237 1 : CATCH_REQUIRE(out.str() ==
238 : "#left-margin{width:calc( (100% - 300px) / 2)}\n"
239 : + csspp_test::get_close_comment()
240 : );
241 1 : break;
242 :
243 1 : case csspp::output_mode_t::EXPANDED:
244 1 : CATCH_REQUIRE(out.str() ==
245 : "#left-margin\n"
246 : "{\n"
247 : " width: calc( (100% - 300px) / 2);\n"
248 : "}\n"
249 : + csspp_test::get_close_comment()
250 : );
251 1 : break;
252 :
253 1 : case csspp::output_mode_t::TIDY:
254 1 : CATCH_REQUIRE(out.str() ==
255 : "#left-margin{width:calc( (100% - 300px) / 2)}\n"
256 : + csspp_test::get_close_comment()
257 : );
258 1 : break;
259 :
260 : }
261 :
262 4 : CATCH_REQUIRE(c.get_root() == n);
263 4 : }
264 : }
265 10 : CATCH_END_SECTION()
266 :
267 10 : CATCH_START_SECTION("test multiple declarations in one rule")
268 : {
269 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
270 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
271 : ++i)
272 : {
273 4 : std::stringstream ss;
274 : ss << "div\n"
275 : << "{\n"
276 : << " color: invert(black);\n"
277 : << " font-size: 1.3rem;\n"
278 : << "}\n"
279 : << "\n"
280 : << "span\n"
281 : << "{\n"
282 : << " border: 3px solid darken(#f7d0cf, 3%);\n"
283 : << "\tborder-bottom-width: 1px;\n"
284 : << "\tbox-shadow: 1px 0px 7px #88aa11, 0px 3px 1px #aa8833;\n"
285 : << " font: 17.2px/1.35em\tArial;\n"
286 : << "}\n"
287 4 : << "\n";
288 12 : csspp::position pos("test.css");
289 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
290 :
291 8 : csspp::parser p(l);
292 :
293 4 : csspp::node::pointer_t n(p.stylesheet());
294 :
295 4 : csspp::compiler c;
296 4 : c.set_root(n);
297 4 : c.set_date_time_variables(csspp_test::get_now());
298 4 : c.add_path(csspp_test::get_script_path());
299 4 : c.add_path(csspp_test::get_version_script_path());
300 :
301 4 : c.compile(false);
302 :
303 : //std::cerr << "Compiler result is: [" << *n << "]\n";
304 :
305 4 : std::stringstream out;
306 4 : csspp::assembler a(out);
307 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
308 :
309 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
310 :
311 4 : switch(static_cast<csspp::output_mode_t>(i))
312 : {
313 1 : case csspp::output_mode_t::COMPACT:
314 1 : CATCH_REQUIRE(out.str() ==
315 : "div { color: #fff; font-size: 1.3rem }\n"
316 : "span { border: 3px solid #f5c3c2; border-bottom-width: 1px; box-shadow: 1px 0px 7px #8a1, 0px 3px 1px #a83; font: 17.2px/1.35em Arial }\n"
317 : + csspp_test::get_close_comment()
318 : );
319 1 : break;
320 :
321 1 : case csspp::output_mode_t::COMPRESSED:
322 1 : CATCH_REQUIRE(out.str() ==
323 : "div{color:#fff;font-size:1.3rem}span{border:3px solid #f5c3c2;border-bottom-width:1px;box-shadow:1px 0px 7px #8a1,0px 3px 1px #a83;font:17.2px/1.35em Arial}\n"
324 : + csspp_test::get_close_comment()
325 : );
326 1 : break;
327 :
328 1 : case csspp::output_mode_t::EXPANDED:
329 1 : CATCH_REQUIRE(out.str() ==
330 : "div\n"
331 : "{\n"
332 : " color: #fff;\n"
333 : " font-size: 1.3rem;\n"
334 : "}\n"
335 : "span\n"
336 : "{\n"
337 : " border: 3px solid #f5c3c2;\n"
338 : " border-bottom-width: 1px;\n"
339 : " box-shadow: 1px 0px 7px #8a1, 0px 3px 1px #a83;\n"
340 : " font: 17.2px/1.35em Arial;\n"
341 : "}\n"
342 : + csspp_test::get_close_comment()
343 : );
344 1 : break;
345 :
346 1 : case csspp::output_mode_t::TIDY:
347 1 : CATCH_REQUIRE(out.str() ==
348 : "div{color:#fff;font-size:1.3rem}\n"
349 : "span{border:3px solid #f5c3c2;border-bottom-width:1px;box-shadow:1px 0px 7px #8a1,0px 3px 1px #a83;font:17.2px/1.35em Arial}\n"
350 : + csspp_test::get_close_comment()
351 : );
352 1 : break;
353 :
354 : }
355 :
356 4 : CATCH_REQUIRE(c.get_root() == n);
357 4 : }
358 : }
359 10 : CATCH_END_SECTION()
360 :
361 10 : CATCH_START_SECTION("test multiple selector lists")
362 : {
363 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
364 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
365 : ++i)
366 : {
367 4 : std::stringstream ss;
368 : ss << "div a b,\n"
369 : << "p span i\n"
370 : << "{\n"
371 : << " color: mix(black, white);\n"
372 : << "\t font-size: 1.3em;\n"
373 : << " \n"
374 : << " border: 3px solid desaturate(#f7d0cf, 5%);\n"
375 : << " \tbox-shadow: 1px 0px 7px #88aa11, 0px 3px 1px #aa8833, 1px 2px 3px #92af54;\n"
376 : << "\tborder-bottom-width: 1px;\n"
377 : << "}\n"
378 4 : << "\n";
379 12 : csspp::position pos("test.css");
380 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
381 :
382 8 : csspp::parser p(l);
383 :
384 4 : csspp::node::pointer_t n(p.stylesheet());
385 :
386 4 : csspp::compiler c;
387 4 : c.set_root(n);
388 4 : c.set_date_time_variables(csspp_test::get_now());
389 4 : c.add_path(csspp_test::get_script_path());
390 4 : c.add_path(csspp_test::get_version_script_path());
391 :
392 4 : c.compile(false);
393 :
394 : //std::cerr << "Compiler result is: [" << *n << "]\n";
395 :
396 4 : std::stringstream out;
397 4 : csspp::assembler a(out);
398 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
399 :
400 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
401 :
402 4 : switch(static_cast<csspp::output_mode_t>(i))
403 : {
404 1 : case csspp::output_mode_t::COMPACT:
405 1 : CATCH_REQUIRE(out.str() ==
406 : "div a b, p span i { color: gray; font-size: 1.3em; border: 3px solid #f6d1d0; box-shadow: 1px 0px 7px #8a1, 0px 3px 1px #a83, 1px 2px 3px #92af54; border-bottom-width: 1px }\n"
407 : + csspp_test::get_close_comment()
408 : );
409 1 : break;
410 :
411 1 : case csspp::output_mode_t::COMPRESSED:
412 1 : CATCH_REQUIRE(out.str() ==
413 : "div a b,p span i{color:gray;font-size:1.3em;border:3px solid #f6d1d0;box-shadow:1px 0px 7px #8a1,0px 3px 1px #a83,1px 2px 3px #92af54;border-bottom-width:1px}\n"
414 : + csspp_test::get_close_comment()
415 : );
416 1 : break;
417 :
418 1 : case csspp::output_mode_t::EXPANDED:
419 1 : CATCH_REQUIRE(out.str() ==
420 : "div a b, p span i\n"
421 : "{\n"
422 : " color: gray;\n"
423 : " font-size: 1.3em;\n"
424 : " border: 3px solid #f6d1d0;\n"
425 : " box-shadow: 1px 0px 7px #8a1, 0px 3px 1px #a83, 1px 2px 3px #92af54;\n"
426 : " border-bottom-width: 1px;\n"
427 : "}\n"
428 : + csspp_test::get_close_comment()
429 : );
430 1 : break;
431 :
432 1 : case csspp::output_mode_t::TIDY:
433 1 : CATCH_REQUIRE(out.str() ==
434 : "div a b,p span i{color:gray;font-size:1.3em;border:3px solid #f6d1d0;box-shadow:1px 0px 7px #8a1,0px 3px 1px #a83,1px 2px 3px #92af54;border-bottom-width:1px}\n"
435 : + csspp_test::get_close_comment()
436 : );
437 1 : break;
438 :
439 : }
440 :
441 4 : CATCH_REQUIRE(c.get_root() == n);
442 4 : }
443 : }
444 10 : CATCH_END_SECTION()
445 :
446 10 : CATCH_START_SECTION("test set_unit() to various numbers")
447 : {
448 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
449 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
450 : ++i)
451 : {
452 4 : std::stringstream ss;
453 : ss << "div \n"
454 : << "{\n"
455 : << " width: set_unit(33, px);\n"
456 : << " height: set_unit(3.3, em);\n"
457 : << " margin-left: set_unit(33px, 'cm');\n"
458 : << " margin-right: set_unit(3.3em, mm);\n"
459 : //<< " content: unit(123%);\n"
460 : //<< " z-index: remove_unit(12.3%);\n"
461 : << " margin-top: set_unit(123%, \"px\");\n"
462 : << " margin-bottom: set_unit(45, \"%\");\n"
463 : << " border-bottom-width: set_unit(4.5, \"%\");\n"
464 : << " border-top-width: set_unit(45cm, \"%\");\n"
465 : << " border-left-width: set_unit(.45vm, \"%\");\n"
466 : << " border-right-width: set_unit(68, \"\");\n"
467 : << " background-x: set_unit(68vm, \"\");\n"
468 : << " background-y: set_unit(6.8cm, \"\");\n"
469 : << " padding-left: set_unit(63.81%, \"\");\n"
470 : << "}\n"
471 4 : << "\n";
472 12 : csspp::position pos("test.css");
473 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
474 :
475 8 : csspp::parser p(l);
476 :
477 4 : csspp::node::pointer_t n(p.stylesheet());
478 :
479 4 : csspp::compiler c;
480 4 : c.set_root(n);
481 4 : c.set_date_time_variables(csspp_test::get_now());
482 4 : c.add_path(csspp_test::get_script_path());
483 4 : c.add_path(csspp_test::get_version_script_path());
484 :
485 4 : c.compile(false);
486 :
487 : //std::cerr << "Compiler result is: [" << *n << "]\n";
488 :
489 4 : std::stringstream out;
490 4 : csspp::assembler a(out);
491 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
492 :
493 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
494 :
495 4 : switch(static_cast<csspp::output_mode_t>(i))
496 : {
497 1 : case csspp::output_mode_t::COMPACT:
498 1 : CATCH_REQUIRE(out.str() ==
499 : "div { width: 33px; height: 3.3em; margin-left: 33cm; margin-right: 3.3mm; margin-top: 1.23px; margin-bottom: 4500%; border-bottom-width: 450%; border-top-width: 4500%; border-left-width: 45%; border-right-width: 68; background-x: 68; background-y: 6.8; padding-left: .638 }\n"
500 : + csspp_test::get_close_comment()
501 : );
502 1 : break;
503 :
504 1 : case csspp::output_mode_t::COMPRESSED:
505 1 : CATCH_REQUIRE(out.str() ==
506 : "div{width:33px;height:3.3em;margin-left:33cm;margin-right:3.3mm;margin-top:1.23px;margin-bottom:4500%;border-bottom-width:450%;border-top-width:4500%;border-left-width:45%;border-right-width:68;background-x:68;background-y:6.8;padding-left:.638}\n"
507 : + csspp_test::get_close_comment()
508 : );
509 1 : break;
510 :
511 1 : case csspp::output_mode_t::EXPANDED:
512 1 : CATCH_REQUIRE(out.str() ==
513 : "div\n"
514 : "{\n"
515 : " width: 33px;\n"
516 : " height: 3.3em;\n"
517 : " margin-left: 33cm;\n"
518 : " margin-right: 3.3mm;\n"
519 : " margin-top: 1.23px;\n"
520 : " margin-bottom: 4500%;\n"
521 : " border-bottom-width: 450%;\n"
522 : " border-top-width: 4500%;\n"
523 : " border-left-width: 45%;\n"
524 : " border-right-width: 68;\n"
525 : " background-x: 68;\n"
526 : " background-y: 6.8;\n"
527 : " padding-left: .638;\n"
528 : "}\n"
529 : + csspp_test::get_close_comment()
530 : );
531 1 : break;
532 :
533 1 : case csspp::output_mode_t::TIDY:
534 1 : CATCH_REQUIRE(out.str() ==
535 : "div{width:33px;height:3.3em;margin-left:33cm;margin-right:3.3mm;margin-top:1.23px;margin-bottom:4500%;border-bottom-width:450%;border-top-width:4500%;border-left-width:45%;border-right-width:68;background-x:68;background-y:6.8;padding-left:.638}\n"
536 : + csspp_test::get_close_comment()
537 : );
538 1 : break;
539 :
540 : }
541 :
542 4 : CATCH_REQUIRE(c.get_root() == n);
543 4 : }
544 : }
545 10 : CATCH_END_SECTION()
546 :
547 10 : CATCH_START_SECTION("test unitless() to various numbers")
548 : {
549 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
550 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
551 : ++i)
552 : {
553 4 : std::stringstream ss;
554 : ss << "div \n"
555 : << "{\n"
556 : << " width: unitless(33px) ? 15px : 3em;\n"
557 : << " height: unitless(3.3em) ? 5cm : 3mm;\n"
558 : << " content: unitless(123%) ? 'incorrect' : 'correct';\n"
559 : << " border-bottom-width: unitless(4.5) ? 30vm : 45%;\n"
560 : << " border-left-width: unitless(45) ? 131px : 4.15cm;\n"
561 : << "}\n"
562 4 : << "\n";
563 12 : csspp::position pos("test.css");
564 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
565 :
566 8 : csspp::parser p(l);
567 :
568 4 : csspp::node::pointer_t n(p.stylesheet());
569 :
570 4 : csspp::compiler c;
571 4 : c.set_root(n);
572 4 : c.set_date_time_variables(csspp_test::get_now());
573 4 : c.add_path(csspp_test::get_script_path());
574 4 : c.add_path(csspp_test::get_version_script_path());
575 :
576 4 : c.compile(false);
577 :
578 : //std::cerr << "Compiler result is: [" << *n << "]\n";
579 :
580 4 : std::stringstream out;
581 4 : csspp::assembler a(out);
582 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
583 :
584 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
585 :
586 4 : switch(static_cast<csspp::output_mode_t>(i))
587 : {
588 1 : case csspp::output_mode_t::COMPACT:
589 1 : CATCH_REQUIRE(out.str() ==
590 : "div { width: 3em; height: 3mm; content: \"correct\"; border-bottom-width: 30vm; border-left-width: 131px }\n"
591 : + csspp_test::get_close_comment()
592 : );
593 1 : break;
594 :
595 1 : case csspp::output_mode_t::COMPRESSED:
596 1 : CATCH_REQUIRE(out.str() ==
597 : "div{width:3em;height:3mm;content:\"correct\";border-bottom-width:30vm;border-left-width:131px}\n"
598 : + csspp_test::get_close_comment()
599 : );
600 1 : break;
601 :
602 1 : case csspp::output_mode_t::EXPANDED:
603 1 : CATCH_REQUIRE(out.str() ==
604 : "div\n"
605 : "{\n"
606 : " width: 3em;\n"
607 : " height: 3mm;\n"
608 : " content: \"correct\";\n"
609 : " border-bottom-width: 30vm;\n"
610 : " border-left-width: 131px;\n"
611 : "}\n"
612 : + csspp_test::get_close_comment()
613 : );
614 1 : break;
615 :
616 1 : case csspp::output_mode_t::TIDY:
617 1 : CATCH_REQUIRE(out.str() ==
618 : "div{width:3em;height:3mm;content:\"correct\";border-bottom-width:30vm;border-left-width:131px}\n"
619 : + csspp_test::get_close_comment()
620 : );
621 1 : break;
622 :
623 : }
624 :
625 4 : CATCH_REQUIRE(c.get_root() == n);
626 4 : }
627 : }
628 10 : CATCH_END_SECTION()
629 :
630 10 : CATCH_START_SECTION("test unique_id()")
631 : {
632 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
633 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
634 : ++i)
635 : {
636 4 : std::stringstream ss;
637 : ss << "div\n"
638 : << "{\n"
639 : << " content: string(unique_id());\n"
640 : << " border: 3px unique_id() lightsteelblue;\n"
641 : << "}\n"
642 : << "a.withColor\n"
643 : << "{\n"
644 : << " padding: unique_id();\n"
645 : << "}\n"
646 4 : << "\n";
647 12 : csspp::position pos("test.css");
648 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
649 :
650 8 : csspp::parser p(l);
651 :
652 4 : csspp::node::pointer_t n(p.stylesheet());
653 :
654 : // reset counter so we can compare with 1, 2, 3 each time
655 4 : csspp::expression::set_unique_id_counter(0);
656 :
657 4 : csspp::compiler c;
658 4 : c.set_root(n);
659 4 : c.set_date_time_variables(csspp_test::get_now());
660 4 : c.add_path(csspp_test::get_script_path());
661 4 : c.add_path(csspp_test::get_version_script_path());
662 :
663 4 : c.compile(false);
664 :
665 : //std::cerr << "Compiler result is: [" << *n << "]\n";
666 :
667 4 : std::stringstream out;
668 4 : csspp::assembler a(out);
669 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
670 :
671 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
672 :
673 4 : switch(static_cast<csspp::output_mode_t>(i))
674 : {
675 1 : case csspp::output_mode_t::COMPACT:
676 1 : CATCH_REQUIRE(out.str() ==
677 : "div { content: \"_csspp_unique1\"; border: 3px _csspp_unique2 #b0c4de }\n"
678 : "a.withColor { padding: _csspp_unique3 }\n"
679 : + csspp_test::get_close_comment()
680 : );
681 1 : break;
682 :
683 1 : case csspp::output_mode_t::COMPRESSED:
684 1 : CATCH_REQUIRE(out.str() ==
685 : "div{content:\"_csspp_unique1\";border:3px _csspp_unique2 #b0c4de}a.withColor{padding:_csspp_unique3}\n"
686 : + csspp_test::get_close_comment()
687 : );
688 1 : break;
689 :
690 1 : case csspp::output_mode_t::EXPANDED:
691 1 : CATCH_REQUIRE(out.str() ==
692 : "div\n"
693 : "{\n"
694 : " content: \"_csspp_unique1\";\n"
695 : " border: 3px _csspp_unique2 #b0c4de;\n"
696 : "}\n"
697 : "a.withColor\n"
698 : "{\n"
699 : " padding: _csspp_unique3;\n"
700 : "}\n"
701 : + csspp_test::get_close_comment()
702 : );
703 1 : break;
704 :
705 1 : case csspp::output_mode_t::TIDY:
706 1 : CATCH_REQUIRE(out.str() ==
707 : "div{content:\"_csspp_unique1\";border:3px _csspp_unique2 #b0c4de}\n"
708 : "a.withColor{padding:_csspp_unique3}\n"
709 : + csspp_test::get_close_comment()
710 : );
711 1 : break;
712 :
713 : }
714 :
715 4 : CATCH_REQUIRE(c.get_root() == n);
716 4 : }
717 : }
718 10 : CATCH_END_SECTION()
719 :
720 10 : CATCH_START_SECTION("identifier with unicode characters and starting with a digit and including a period")
721 : {
722 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
723 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
724 : ++i)
725 : {
726 4 : std::stringstream ss;
727 : // word "e'te'" (summer in French)
728 : ss << "\xc3\xa9t\xc3\xa9 { color: fade_in(gold, 0.2); }\n"
729 : << "\\33 21 { color: fade_out(tan, 0.2); }\n"
730 : << "\\36 face { color: orchid; }\n"
731 : << "\\30 BLUR { color: thistle; }\n"
732 : << "this\\.and\\.that { color: honeydew; }\n"
733 : << "\xe4\x96\x82 { color: dimgray; }\n"
734 : << "\xf0\x90\x90\x94\xf0\x90\x90\xa9\xf0\x90\x91\x85\xf0\x90\x90\xaf\xf0\x90\x91\x89\xf0\x90\x90\xaf\xf0\x90\x90\xbb { color: darkred; }\n"
735 4 : << "normal { color: mix(darkseagreen, lavender, 0.3); }\n";
736 12 : csspp::position pos("test.css");
737 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
738 :
739 8 : csspp::parser p(l);
740 :
741 4 : csspp::node::pointer_t n(p.stylesheet());
742 :
743 4 : csspp::compiler c;
744 4 : c.set_root(n);
745 4 : c.set_date_time_variables(csspp_test::get_now());
746 4 : c.add_path(csspp_test::get_script_path());
747 4 : c.add_path(csspp_test::get_version_script_path());
748 :
749 4 : c.compile(false);
750 :
751 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
752 :
753 4 : std::stringstream out;
754 4 : csspp::assembler a(out);
755 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
756 :
757 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
758 :
759 4 : switch(static_cast<csspp::output_mode_t>(i))
760 : {
761 1 : case csspp::output_mode_t::COMPACT:
762 1 : CATCH_REQUIRE(out.str() ==
763 : "\xc3\xa9t\xc3\xa9 { color: #ffd700 }\n"
764 : "\\33 21 { color: rgba(210,180,140,.8) }\n"
765 : "\\36 face { color: #da70d6 }\n"
766 : "\\30 BLUR { color: #d8bfd8 }\n"
767 : "this\\.and\\.that { color: #f0fff0 }\n"
768 : "\xe4\x96\x82 { color: #696969 }\n"
769 : "\xf0\x90\x90\x94\xf0\x90\x90\xa9\xf0\x90\x91\x85\xf0\x90\x90\xaf\xf0\x90\x91\x89\xf0\x90\x90\xaf\xf0\x90\x90\xbb { color: #8b0000 }\n"
770 : "normal { color: #ccd9da }\n"
771 : + csspp_test::get_close_comment()
772 : );
773 1 : break;
774 :
775 1 : case csspp::output_mode_t::COMPRESSED:
776 1 : CATCH_REQUIRE(out.str() ==
777 : "\xc3\xa9t\xc3\xa9{color:#ffd700}"
778 : "\\33 21{color:rgba(210,180,140,.8)}"
779 : "\\36 face{color:#da70d6}"
780 : "\\30 BLUR{color:#d8bfd8}"
781 : "this\\.and\\.that{color:#f0fff0}"
782 : "\xe4\x96\x82{color:#696969}"
783 : "\xf0\x90\x90\x94\xf0\x90\x90\xa9\xf0\x90\x91\x85\xf0\x90\x90\xaf\xf0\x90\x91\x89\xf0\x90\x90\xaf\xf0\x90\x90\xbb{color:#8b0000}"
784 : "normal{color:#ccd9da}"
785 : "\n"
786 : + csspp_test::get_close_comment()
787 : );
788 1 : break;
789 :
790 1 : case csspp::output_mode_t::EXPANDED:
791 1 : CATCH_REQUIRE(out.str() ==
792 : "\xc3\xa9t\xc3\xa9\n"
793 : "{\n"
794 : " color: #ffd700;\n"
795 : "}\n"
796 : "\\33 21\n"
797 : "{\n"
798 : " color: rgba(210,180,140,.8);\n"
799 : "}\n"
800 : "\\36 face\n"
801 : "{\n"
802 : " color: #da70d6;\n"
803 : "}\n"
804 : "\\30 BLUR\n"
805 : "{\n"
806 : " color: #d8bfd8;\n"
807 : "}\n"
808 : "this\\.and\\.that\n"
809 : "{\n"
810 : " color: #f0fff0;\n"
811 : "}\n"
812 : "\xe4\x96\x82\n"
813 : "{\n"
814 : " color: #696969;\n"
815 : "}\n"
816 : "\xf0\x90\x90\x94\xf0\x90\x90\xa9\xf0\x90\x91\x85\xf0\x90\x90\xaf\xf0\x90\x91\x89\xf0\x90\x90\xaf\xf0\x90\x90\xbb\n"
817 : "{\n"
818 : " color: #8b0000;\n"
819 : "}\n"
820 : "normal\n"
821 : "{\n"
822 : " color: #ccd9da;\n"
823 : "}\n"
824 : + csspp_test::get_close_comment()
825 : );
826 1 : break;
827 :
828 1 : case csspp::output_mode_t::TIDY:
829 1 : CATCH_REQUIRE(out.str() ==
830 : "\xc3\xa9t\xc3\xa9{color:#ffd700}\n"
831 : "\\33 21{color:rgba(210,180,140,.8)}\n"
832 : "\\36 face{color:#da70d6}\n"
833 : "\\30 BLUR{color:#d8bfd8}\n"
834 : "this\\.and\\.that{color:#f0fff0}\n"
835 : "\xe4\x96\x82{color:#696969}\n"
836 : "\xf0\x90\x90\x94\xf0\x90\x90\xa9\xf0\x90\x91\x85\xf0\x90\x90\xaf\xf0\x90\x91\x89\xf0\x90\x90\xaf\xf0\x90\x90\xbb{color:#8b0000}\n"
837 : "normal{color:#ccd9da}\n"
838 : + csspp_test::get_close_comment()
839 : );
840 1 : break;
841 :
842 : }
843 :
844 4 : CATCH_REQUIRE(c.get_root() == n);
845 4 : }
846 : }
847 10 : CATCH_END_SECTION()
848 :
849 10 : CATCH_START_SECTION("whitespace at the beginning of a rule")
850 : {
851 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
852 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
853 : ++i)
854 : {
855 4 : std::stringstream ss;
856 : ss << " // spaces before a comment will produce problems\n"
857 : << " // and such comments are not preserved as expected\n"
858 : << " // @preserve this comment\n"
859 : << "\n"
860 : << ".face { content: quote(\xe4\x96\x82); }\n"
861 : << ".hair { color: fade_in(rgba(50, 100, 150, 0.14), 0.46); }\n"
862 4 : << ".plan { opacity: opacity(fade_in(rgba(50, 100, 150, 0.14), 0.46)); }\n";
863 12 : csspp::position pos("test.css");
864 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
865 :
866 8 : csspp::parser p(l);
867 :
868 4 : csspp::node::pointer_t n(p.stylesheet());
869 :
870 4 : csspp::compiler c;
871 4 : c.set_root(n);
872 4 : c.set_date_time_variables(csspp_test::get_now());
873 4 : c.add_path(csspp_test::get_script_path());
874 4 : c.add_path(csspp_test::get_version_script_path());
875 :
876 4 : c.compile(false);
877 :
878 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
879 :
880 4 : std::stringstream out;
881 4 : csspp::assembler a(out);
882 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
883 :
884 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
885 :
886 4 : VERIFY_ERRORS("test.css(3): warning: C++ comments should not be preserved as they are not supported by most CSS parsers.\n");
887 :
888 4 : switch(static_cast<csspp::output_mode_t>(i))
889 : {
890 1 : case csspp::output_mode_t::COMPACT:
891 1 : CATCH_REQUIRE(out.str() ==
892 : "/* @preserve this comment */\n"
893 : ".face { content: \"\xe4\x96\x82\" }\n"
894 : ".hair { color: rgba(50,100,150,.6) }\n"
895 : ".plan { opacity: .6 }\n"
896 : + csspp_test::get_close_comment()
897 : );
898 1 : break;
899 :
900 1 : case csspp::output_mode_t::COMPRESSED:
901 1 : CATCH_REQUIRE(out.str() ==
902 : "/* @preserve this comment */\n"
903 : ".face{content:\"\xe4\x96\x82\"}"
904 : ".hair{color:rgba(50,100,150,.6)}"
905 : ".plan{opacity:.6}"
906 : "\n"
907 : + csspp_test::get_close_comment()
908 : );
909 1 : break;
910 :
911 1 : case csspp::output_mode_t::EXPANDED:
912 1 : CATCH_REQUIRE(out.str() ==
913 : "/* @preserve this comment */\n"
914 : ".face\n"
915 : "{\n"
916 : " content: \"\xe4\x96\x82\";\n"
917 : "}\n"
918 : ".hair\n"
919 : "{\n"
920 : " color: rgba(50,100,150,.6);\n"
921 : "}\n"
922 : ".plan\n"
923 : "{\n"
924 : " opacity: .6;\n"
925 : "}\n"
926 : + csspp_test::get_close_comment()
927 : );
928 1 : break;
929 :
930 1 : case csspp::output_mode_t::TIDY:
931 1 : CATCH_REQUIRE(out.str() ==
932 : "/* @preserve this comment */\n"
933 : ".face{content:\"\xe4\x96\x82\"}\n"
934 : ".hair{color:rgba(50,100,150,.6)}\n"
935 : ".plan{opacity:.6}\n"
936 : + csspp_test::get_close_comment()
937 : );
938 1 : break;
939 :
940 : }
941 :
942 4 : CATCH_REQUIRE(c.get_root() == n);
943 4 : }
944 : }
945 10 : CATCH_END_SECTION()
946 :
947 10 : CATCH_START_SECTION("whitespace at the beginning of a variable")
948 : {
949 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
950 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
951 : ++i)
952 : {
953 4 : std::stringstream ss;
954 : ss << " // an empty comment was creating trouble!\n"
955 : << " //\n"
956 : << "\n"
957 : << "$color: #329182;\n"
958 : << "$image: url(\"images/ladybug.jpeg\");\n"
959 : << "$width: 300px;\n"
960 : << "\n"
961 : << " p\n"
962 : << " {\n"
963 : << " // background color defined in variable\n"
964 : << " background-color: grayscale($color);\n"
965 : << "\n"
966 : << " // this is like \"body div.flowers\"\n"
967 : << " div.flowers\n"
968 : << " {\n"
969 : << " background-image: $image;\n"
970 : << " z-index: remove_unit($width);\n"
971 : << " }\n"
972 : << " }\n"
973 4 : << "\n";
974 12 : csspp::position pos("test.css");
975 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
976 :
977 8 : csspp::parser p(l);
978 :
979 4 : csspp::node::pointer_t n(p.stylesheet());
980 :
981 : //std::cerr << "Parser result is: [" << *n << "]\n";
982 :
983 4 : csspp::compiler c;
984 4 : c.set_root(n);
985 4 : c.set_date_time_variables(csspp_test::get_now());
986 4 : c.add_path(csspp_test::get_script_path());
987 4 : c.add_path(csspp_test::get_version_script_path());
988 :
989 4 : c.compile(false);
990 :
991 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
992 :
993 4 : std::stringstream out;
994 4 : csspp::assembler a(out);
995 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
996 :
997 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
998 :
999 4 : VERIFY_ERRORS("");
1000 :
1001 4 : switch(static_cast<csspp::output_mode_t>(i))
1002 : {
1003 1 : case csspp::output_mode_t::COMPACT:
1004 1 : CATCH_REQUIRE(out.str() ==
1005 : "p { background-color: #626262 }\n"
1006 : "p div.flowers { background-image: url( images/ladybug.jpeg ); z-index: 300 }\n"
1007 : + csspp_test::get_close_comment()
1008 : );
1009 1 : break;
1010 :
1011 1 : case csspp::output_mode_t::COMPRESSED:
1012 1 : CATCH_REQUIRE(out.str() ==
1013 : "p{background-color:#626262}"
1014 : "p div.flowers{background-image:url(images/ladybug.jpeg);z-index:300}"
1015 : "\n"
1016 : + csspp_test::get_close_comment()
1017 : );
1018 1 : break;
1019 :
1020 1 : case csspp::output_mode_t::EXPANDED:
1021 1 : CATCH_REQUIRE(out.str() ==
1022 : "p\n"
1023 : "{\n"
1024 : " background-color: #626262;\n"
1025 : "}\n"
1026 : "p div.flowers\n"
1027 : "{\n"
1028 : " background-image: url( images/ladybug.jpeg );\n"
1029 : " z-index: 300;\n"
1030 : "}\n"
1031 : + csspp_test::get_close_comment()
1032 : );
1033 1 : break;
1034 :
1035 1 : case csspp::output_mode_t::TIDY:
1036 1 : CATCH_REQUIRE(out.str() ==
1037 : "p{background-color:#626262}\n"
1038 : "p div.flowers{background-image:url(images/ladybug.jpeg);z-index:300}\n"
1039 : + csspp_test::get_close_comment()
1040 : );
1041 1 : break;
1042 :
1043 : }
1044 :
1045 4 : CATCH_REQUIRE(c.get_root() == n);
1046 4 : }
1047 : }
1048 10 : CATCH_END_SECTION()
1049 :
1050 : // no error left over
1051 10 : VERIFY_ERRORS("");
1052 10 : }
1053 :
1054 1 : CATCH_TEST_CASE("Assemble selectors", "[assembler] [selectors]")
1055 : {
1056 : // check various selectors without the operators
1057 :
1058 : // simple identifiers
1059 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1060 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1061 : ++i)
1062 : {
1063 4 : std::stringstream ss;
1064 4 : ss << "div span a { color: black; }";
1065 12 : csspp::position pos("test.css");
1066 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1067 :
1068 8 : csspp::parser p(l);
1069 :
1070 4 : csspp::node::pointer_t n(p.stylesheet());
1071 :
1072 4 : csspp::compiler c;
1073 4 : c.set_root(n);
1074 4 : c.set_date_time_variables(csspp_test::get_now());
1075 4 : c.add_path(csspp_test::get_script_path());
1076 4 : c.add_path(csspp_test::get_version_script_path());
1077 :
1078 4 : c.compile(false);
1079 :
1080 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1081 :
1082 4 : std::stringstream out;
1083 4 : csspp::assembler a(out);
1084 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
1085 :
1086 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1087 :
1088 4 : switch(static_cast<csspp::output_mode_t>(i))
1089 : {
1090 1 : case csspp::output_mode_t::COMPACT:
1091 1 : CATCH_REQUIRE(out.str() ==
1092 : "div span a { color: #000 }\n"
1093 : + csspp_test::get_close_comment()
1094 : );
1095 1 : break;
1096 :
1097 1 : case csspp::output_mode_t::COMPRESSED:
1098 1 : CATCH_REQUIRE(out.str() ==
1099 : "div span a{color:#000}\n"
1100 : + csspp_test::get_close_comment()
1101 : );
1102 1 : break;
1103 :
1104 1 : case csspp::output_mode_t::EXPANDED:
1105 1 : CATCH_REQUIRE(out.str() ==
1106 : "div span a\n"
1107 : "{\n"
1108 : " color: #000;\n"
1109 : "}\n"
1110 : + csspp_test::get_close_comment()
1111 : );
1112 1 : break;
1113 :
1114 1 : case csspp::output_mode_t::TIDY:
1115 1 : CATCH_REQUIRE(out.str() ==
1116 : "div span a{color:#000}\n"
1117 : + csspp_test::get_close_comment()
1118 : );
1119 1 : break;
1120 :
1121 : }
1122 :
1123 4 : CATCH_REQUIRE(c.get_root() == n);
1124 4 : }
1125 :
1126 : // test a simple attribute
1127 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1128 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1129 : ++i)
1130 : {
1131 4 : std::stringstream ss;
1132 4 : ss << "div[foo] {color: black}\n";
1133 12 : csspp::position pos("test.css");
1134 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1135 :
1136 8 : csspp::parser p(l);
1137 :
1138 4 : csspp::node::pointer_t n(p.stylesheet());
1139 :
1140 4 : csspp::compiler c;
1141 4 : c.set_root(n);
1142 4 : c.set_date_time_variables(csspp_test::get_now());
1143 4 : c.add_path(csspp_test::get_script_path());
1144 4 : c.add_path(csspp_test::get_version_script_path());
1145 :
1146 4 : c.compile(false);
1147 :
1148 : //std::cerr << "Compiler result is: [" << *n << "]\n";
1149 :
1150 4 : std::stringstream out;
1151 4 : csspp::assembler a(out);
1152 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
1153 :
1154 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1155 :
1156 4 : switch(static_cast<csspp::output_mode_t>(i))
1157 : {
1158 1 : case csspp::output_mode_t::COMPACT:
1159 1 : CATCH_REQUIRE(out.str() ==
1160 : "div[foo] { color: #000 }\n"
1161 : + csspp_test::get_close_comment()
1162 : );
1163 1 : break;
1164 :
1165 1 : case csspp::output_mode_t::COMPRESSED:
1166 1 : CATCH_REQUIRE(out.str() ==
1167 : "div[foo]{color:#000}\n"
1168 : + csspp_test::get_close_comment()
1169 : );
1170 1 : break;
1171 :
1172 1 : case csspp::output_mode_t::EXPANDED:
1173 1 : CATCH_REQUIRE(out.str() ==
1174 : "div[foo]\n"
1175 : "{\n"
1176 : " color: #000;\n"
1177 : "}\n"
1178 : + csspp_test::get_close_comment()
1179 : );
1180 1 : break;
1181 :
1182 1 : case csspp::output_mode_t::TIDY:
1183 1 : CATCH_REQUIRE(out.str() ==
1184 : "div[foo]{color:#000}\n"
1185 : + csspp_test::get_close_comment()
1186 : );
1187 1 : break;
1188 :
1189 : }
1190 :
1191 4 : CATCH_REQUIRE(c.get_root() == n);
1192 4 : }
1193 :
1194 : // Test with a class
1195 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1196 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1197 : ++i)
1198 : {
1199 4 : std::stringstream ss;
1200 4 : ss << "div.foo{color:black}\n";
1201 12 : csspp::position pos("test.css");
1202 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1203 :
1204 8 : csspp::parser p(l);
1205 :
1206 4 : csspp::node::pointer_t n(p.stylesheet());
1207 :
1208 4 : csspp::compiler c;
1209 4 : c.set_root(n);
1210 4 : c.set_date_time_variables(csspp_test::get_now());
1211 4 : c.add_path(csspp_test::get_script_path());
1212 4 : c.add_path(csspp_test::get_version_script_path());
1213 :
1214 4 : c.compile(false);
1215 :
1216 : //std::cerr << "Compiler result is: [" << *n << "]\n";
1217 :
1218 4 : std::stringstream out;
1219 4 : csspp::assembler a(out);
1220 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
1221 :
1222 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1223 :
1224 4 : switch(static_cast<csspp::output_mode_t>(i))
1225 : {
1226 1 : case csspp::output_mode_t::COMPACT:
1227 1 : CATCH_REQUIRE(out.str() ==
1228 : "div.foo { color: #000 }\n"
1229 : + csspp_test::get_close_comment()
1230 : );
1231 1 : break;
1232 :
1233 1 : case csspp::output_mode_t::COMPRESSED:
1234 1 : CATCH_REQUIRE(out.str() ==
1235 : "div.foo{color:#000}\n"
1236 : + csspp_test::get_close_comment()
1237 : );
1238 1 : break;
1239 :
1240 1 : case csspp::output_mode_t::EXPANDED:
1241 1 : CATCH_REQUIRE(out.str() ==
1242 : "div.foo\n"
1243 : "{\n"
1244 : " color: #000;\n"
1245 : "}\n"
1246 : + csspp_test::get_close_comment()
1247 : );
1248 1 : break;
1249 :
1250 1 : case csspp::output_mode_t::TIDY:
1251 1 : CATCH_REQUIRE(out.str() ==
1252 : "div.foo{color:#000}\n"
1253 : + csspp_test::get_close_comment()
1254 : );
1255 1 : break;
1256 :
1257 : }
1258 :
1259 4 : CATCH_REQUIRE(c.get_root() == n);
1260 4 : }
1261 :
1262 : // Test with an identifier
1263 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1264 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1265 : ++i)
1266 : {
1267 4 : std::stringstream ss;
1268 4 : ss << "#foo div{color:black}\n";
1269 12 : csspp::position pos("test.css");
1270 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1271 :
1272 8 : csspp::parser p(l);
1273 :
1274 4 : csspp::node::pointer_t n(p.stylesheet());
1275 :
1276 4 : csspp::compiler c;
1277 4 : c.set_root(n);
1278 4 : c.set_date_time_variables(csspp_test::get_now());
1279 4 : c.add_path(csspp_test::get_script_path());
1280 4 : c.add_path(csspp_test::get_version_script_path());
1281 :
1282 4 : c.compile(false);
1283 :
1284 : //std::cerr << "Compiler result is: [" << *n << "]\n";
1285 :
1286 4 : std::stringstream out;
1287 4 : csspp::assembler a(out);
1288 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
1289 :
1290 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1291 :
1292 4 : switch(static_cast<csspp::output_mode_t>(i))
1293 : {
1294 1 : case csspp::output_mode_t::COMPACT:
1295 1 : CATCH_REQUIRE(out.str() ==
1296 : "#foo div { color: #000 }\n"
1297 : + csspp_test::get_close_comment()
1298 : );
1299 1 : break;
1300 :
1301 1 : case csspp::output_mode_t::COMPRESSED:
1302 1 : CATCH_REQUIRE(out.str() ==
1303 : "#foo div{color:#000}\n"
1304 : + csspp_test::get_close_comment()
1305 : );
1306 1 : break;
1307 :
1308 1 : case csspp::output_mode_t::EXPANDED:
1309 1 : CATCH_REQUIRE(out.str() ==
1310 : "#foo div\n"
1311 : "{\n"
1312 : " color: #000;\n"
1313 : "}\n"
1314 : + csspp_test::get_close_comment()
1315 : );
1316 1 : break;
1317 :
1318 1 : case csspp::output_mode_t::TIDY:
1319 1 : CATCH_REQUIRE(out.str() ==
1320 : "#foo div{color:#000}\n"
1321 : + csspp_test::get_close_comment()
1322 : );
1323 1 : break;
1324 :
1325 : }
1326 :
1327 4 : CATCH_REQUIRE(c.get_root() == n);
1328 4 : }
1329 :
1330 : // test an attribute with a test
1331 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1332 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1333 : ++i)
1334 : {
1335 4 : std::stringstream ss;
1336 4 : ss << "div[foo=\"a b c\"] {color: black}\n";
1337 12 : csspp::position pos("test.css");
1338 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1339 :
1340 8 : csspp::parser p(l);
1341 :
1342 4 : csspp::node::pointer_t n(p.stylesheet());
1343 :
1344 4 : csspp::compiler c;
1345 4 : c.set_root(n);
1346 4 : c.set_date_time_variables(csspp_test::get_now());
1347 4 : c.add_path(csspp_test::get_script_path());
1348 4 : c.add_path(csspp_test::get_version_script_path());
1349 :
1350 4 : c.compile(false);
1351 :
1352 : //std::cerr << "Compiler result is: [" << *n << "]\n";
1353 :
1354 4 : std::stringstream out;
1355 4 : csspp::assembler a(out);
1356 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
1357 :
1358 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1359 :
1360 4 : switch(static_cast<csspp::output_mode_t>(i))
1361 : {
1362 1 : case csspp::output_mode_t::COMPACT:
1363 1 : CATCH_REQUIRE(out.str() ==
1364 : "div[foo = \"a b c\"] { color: #000 }\n"
1365 : + csspp_test::get_close_comment()
1366 : );
1367 1 : break;
1368 :
1369 1 : case csspp::output_mode_t::COMPRESSED:
1370 1 : CATCH_REQUIRE(out.str() ==
1371 : "div[foo=\"a b c\"]{color:#000}\n"
1372 : + csspp_test::get_close_comment()
1373 : );
1374 1 : break;
1375 :
1376 1 : case csspp::output_mode_t::EXPANDED:
1377 1 : CATCH_REQUIRE(out.str() ==
1378 : "div[foo = \"a b c\"]\n"
1379 : "{\n"
1380 : " color: #000;\n"
1381 : "}\n"
1382 : + csspp_test::get_close_comment()
1383 : );
1384 1 : break;
1385 :
1386 1 : case csspp::output_mode_t::TIDY:
1387 1 : CATCH_REQUIRE(out.str() ==
1388 : "div[foo=\"a b c\"]{color:#000}\n"
1389 : + csspp_test::get_close_comment()
1390 : );
1391 1 : break;
1392 :
1393 : }
1394 :
1395 4 : CATCH_REQUIRE(c.get_root() == n);
1396 4 : }
1397 :
1398 : // test an :lang() pseudo function
1399 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1400 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1401 : ++i)
1402 : {
1403 4 : std::stringstream ss;
1404 4 : ss << "div:lang(fr) {color: black}\n";
1405 12 : csspp::position pos("test.css");
1406 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1407 :
1408 8 : csspp::parser p(l);
1409 :
1410 4 : csspp::node::pointer_t n(p.stylesheet());
1411 :
1412 4 : csspp::compiler c;
1413 4 : c.set_root(n);
1414 4 : c.set_date_time_variables(csspp_test::get_now());
1415 4 : c.add_path(csspp_test::get_script_path());
1416 4 : c.add_path(csspp_test::get_version_script_path());
1417 :
1418 4 : c.compile(false);
1419 :
1420 : //std::cerr << "Compiler result is: [" << *n << "]\n";
1421 :
1422 4 : std::stringstream out;
1423 4 : csspp::assembler a(out);
1424 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
1425 :
1426 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1427 :
1428 4 : switch(static_cast<csspp::output_mode_t>(i))
1429 : {
1430 1 : case csspp::output_mode_t::COMPACT:
1431 1 : CATCH_REQUIRE(out.str() ==
1432 : "div:lang(fr) { color: #000 }\n"
1433 : + csspp_test::get_close_comment()
1434 : );
1435 1 : break;
1436 :
1437 1 : case csspp::output_mode_t::COMPRESSED:
1438 1 : CATCH_REQUIRE(out.str() ==
1439 : "div:lang(fr){color:#000}\n"
1440 : + csspp_test::get_close_comment()
1441 : );
1442 1 : break;
1443 :
1444 1 : case csspp::output_mode_t::EXPANDED:
1445 1 : CATCH_REQUIRE(out.str() ==
1446 : "div:lang(fr)\n"
1447 : "{\n"
1448 : " color: #000;\n"
1449 : "}\n"
1450 : + csspp_test::get_close_comment()
1451 : );
1452 1 : break;
1453 :
1454 1 : case csspp::output_mode_t::TIDY:
1455 1 : CATCH_REQUIRE(out.str() ==
1456 : "div:lang(fr){color:#000}\n"
1457 : + csspp_test::get_close_comment()
1458 : );
1459 1 : break;
1460 :
1461 : }
1462 :
1463 4 : CATCH_REQUIRE(c.get_root() == n);
1464 4 : }
1465 :
1466 : // test an :not() pseudo function
1467 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1468 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1469 : ++i)
1470 : {
1471 4 : std::stringstream ss;
1472 4 : ss << "div:not(:lang(fr)):not(:nth-child(2n+1)) {color: black}\n";
1473 12 : csspp::position pos("test.css");
1474 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1475 :
1476 8 : csspp::parser p(l);
1477 :
1478 4 : csspp::node::pointer_t n(p.stylesheet());
1479 :
1480 4 : csspp::compiler c;
1481 4 : c.set_root(n);
1482 4 : c.set_date_time_variables(csspp_test::get_now());
1483 4 : c.add_path(csspp_test::get_script_path());
1484 4 : c.add_path(csspp_test::get_version_script_path());
1485 :
1486 4 : c.compile(false);
1487 :
1488 : //std::cerr << "Compiler result is: [" << *n << "]\n";
1489 :
1490 4 : std::stringstream out;
1491 4 : csspp::assembler a(out);
1492 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
1493 :
1494 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1495 :
1496 4 : switch(static_cast<csspp::output_mode_t>(i))
1497 : {
1498 1 : case csspp::output_mode_t::COMPACT:
1499 1 : CATCH_REQUIRE(out.str() ==
1500 : "div:not(:lang(fr)):not(:nth-child(odd)) { color: #000 }\n"
1501 : + csspp_test::get_close_comment()
1502 : );
1503 1 : break;
1504 :
1505 1 : case csspp::output_mode_t::COMPRESSED:
1506 1 : CATCH_REQUIRE(out.str() ==
1507 : "div:not(:lang(fr)):not(:nth-child(odd)){color:#000}\n"
1508 : + csspp_test::get_close_comment()
1509 : );
1510 1 : break;
1511 :
1512 1 : case csspp::output_mode_t::EXPANDED:
1513 1 : CATCH_REQUIRE(out.str() ==
1514 : "div:not(:lang(fr)):not(:nth-child(odd))\n"
1515 : "{\n"
1516 : " color: #000;\n"
1517 : "}\n"
1518 : + csspp_test::get_close_comment()
1519 : );
1520 1 : break;
1521 :
1522 1 : case csspp::output_mode_t::TIDY:
1523 1 : CATCH_REQUIRE(out.str() ==
1524 : "div:not(:lang(fr)):not(:nth-child(odd)){color:#000}\n"
1525 : + csspp_test::get_close_comment()
1526 : );
1527 1 : break;
1528 :
1529 : }
1530 :
1531 4 : CATCH_REQUIRE(c.get_root() == n);
1532 4 : }
1533 :
1534 : // test the pseudo classes
1535 1 : char const * pseudo_classes[] =
1536 : {
1537 : "root",
1538 : "first-child",
1539 : "last-child",
1540 : "first-of-type",
1541 : "last-of-type",
1542 : "only-child",
1543 : "only-of-type",
1544 : "empty",
1545 : "link",
1546 : "visited",
1547 : "active",
1548 : "hover",
1549 : "focus",
1550 : "target",
1551 : "enabled",
1552 : "disabled",
1553 : "checked"
1554 : };
1555 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1556 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1557 : ++i)
1558 : {
1559 72 : for(size_t j(0); j < sizeof(pseudo_classes) / sizeof(pseudo_classes[0]); ++j)
1560 : {
1561 68 : std::stringstream ss;
1562 68 : ss << "div:" << pseudo_classes[j] << " {color: black}\n";
1563 204 : csspp::position pos("test.css");
1564 68 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1565 :
1566 136 : csspp::parser p(l);
1567 :
1568 68 : csspp::node::pointer_t n(p.stylesheet());
1569 :
1570 68 : csspp::compiler c;
1571 68 : c.set_root(n);
1572 68 : c.set_date_time_variables(csspp_test::get_now());
1573 68 : c.add_path(csspp_test::get_script_path());
1574 68 : c.add_path(csspp_test::get_version_script_path());
1575 :
1576 68 : c.compile(false);
1577 :
1578 : //std::cerr << "Compiler result is: [" << *n << "]\n";
1579 :
1580 68 : std::stringstream out;
1581 68 : csspp::assembler a(out);
1582 68 : a.output(n, static_cast<csspp::output_mode_t>(i));
1583 :
1584 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1585 :
1586 68 : std::stringstream expected;
1587 68 : switch(static_cast<csspp::output_mode_t>(i))
1588 : {
1589 17 : case csspp::output_mode_t::COMPACT:
1590 : expected << "div:" << pseudo_classes[j] << " { color: #000 }\n"
1591 17 : << csspp_test::get_close_comment();
1592 17 : break;
1593 :
1594 17 : case csspp::output_mode_t::COMPRESSED:
1595 : expected << "div:" << pseudo_classes[j] << "{color:#000}\n"
1596 17 : << csspp_test::get_close_comment();
1597 17 : break;
1598 :
1599 17 : case csspp::output_mode_t::EXPANDED:
1600 : expected << "div:" << pseudo_classes[j] << "\n"
1601 : "{\n"
1602 : " color: #000;\n"
1603 : "}\n"
1604 17 : << csspp_test::get_close_comment();
1605 17 : break;
1606 :
1607 17 : case csspp::output_mode_t::TIDY:
1608 : expected << "div:" << pseudo_classes[j] << "{color:#000}\n"
1609 17 : << csspp_test::get_close_comment();
1610 17 : break;
1611 :
1612 : }
1613 :
1614 68 : CATCH_REQUIRE(out.str() == expected.str());
1615 68 : CATCH_REQUIRE(c.get_root() == n);
1616 68 : }
1617 : }
1618 :
1619 : // test the pseudo classes
1620 1 : char const * pseudo_elements[] =
1621 : {
1622 : "first-line",
1623 : "first-letter",
1624 : "before",
1625 : "after"
1626 : };
1627 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1628 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1629 : ++i)
1630 : {
1631 20 : for(size_t j(0); j < sizeof(pseudo_elements) / sizeof(pseudo_elements[0]); ++j)
1632 : {
1633 16 : std::stringstream ss;
1634 16 : ss << "div::" << pseudo_elements[j] << " {color: black}\n";
1635 48 : csspp::position pos("test.css");
1636 16 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1637 :
1638 32 : csspp::parser p(l);
1639 :
1640 16 : csspp::node::pointer_t n(p.stylesheet());
1641 :
1642 16 : csspp::compiler c;
1643 16 : c.set_root(n);
1644 16 : c.set_date_time_variables(csspp_test::get_now());
1645 16 : c.add_path(csspp_test::get_script_path());
1646 16 : c.add_path(csspp_test::get_version_script_path());
1647 :
1648 16 : c.compile(false);
1649 :
1650 : //std::cerr << "Compiler result is: [" << *n << "]\n";
1651 :
1652 16 : std::stringstream out;
1653 16 : csspp::assembler a(out);
1654 16 : a.output(n, static_cast<csspp::output_mode_t>(i));
1655 :
1656 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1657 :
1658 16 : std::stringstream expected;
1659 16 : switch(static_cast<csspp::output_mode_t>(i))
1660 : {
1661 4 : case csspp::output_mode_t::COMPACT:
1662 : expected << "div::" << pseudo_elements[j] << " { color: #000 }\n"
1663 4 : << csspp_test::get_close_comment();
1664 4 : break;
1665 :
1666 4 : case csspp::output_mode_t::COMPRESSED:
1667 : expected << "div::" << pseudo_elements[j] << "{color:#000}\n"
1668 4 : << csspp_test::get_close_comment();
1669 4 : break;
1670 :
1671 4 : case csspp::output_mode_t::EXPANDED:
1672 : expected << "div::" << pseudo_elements[j] << "\n"
1673 : "{\n"
1674 : " color: #000;\n"
1675 : "}\n"
1676 4 : << csspp_test::get_close_comment();
1677 4 : break;
1678 :
1679 4 : case csspp::output_mode_t::TIDY:
1680 : expected << "div::" << pseudo_elements[j] << "{color:#000}\n"
1681 4 : << csspp_test::get_close_comment();
1682 4 : break;
1683 :
1684 : }
1685 :
1686 16 : CATCH_REQUIRE(out.str() == expected.str());
1687 16 : CATCH_REQUIRE(c.get_root() == n);
1688 16 : }
1689 : }
1690 :
1691 : // test the An+B pseudo classes
1692 1 : char const * pseudo_functions[] =
1693 : {
1694 : "nth-child",
1695 : "nth-last-child",
1696 : "nth-of-type",
1697 : "nth-last-of-type"
1698 : };
1699 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1700 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1701 : ++i)
1702 : {
1703 20 : for(size_t j(0); j < sizeof(pseudo_functions) / sizeof(pseudo_functions[0]); ++j)
1704 : {
1705 16 : std::stringstream ss;
1706 16 : ss << "div:" << pseudo_functions[j] << "(5n+2) {color: black}\n";
1707 48 : csspp::position pos("test.css");
1708 16 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1709 :
1710 32 : csspp::parser p(l);
1711 :
1712 16 : csspp::node::pointer_t n(p.stylesheet());
1713 :
1714 16 : csspp::compiler c;
1715 16 : c.set_root(n);
1716 16 : c.set_date_time_variables(csspp_test::get_now());
1717 16 : c.add_path(csspp_test::get_script_path());
1718 16 : c.add_path(csspp_test::get_version_script_path());
1719 :
1720 16 : c.compile(false);
1721 :
1722 : //std::cerr << "Compiler result is: [" << *n << "]\n";
1723 :
1724 16 : std::stringstream out;
1725 16 : csspp::assembler a(out);
1726 16 : a.output(n, static_cast<csspp::output_mode_t>(i));
1727 :
1728 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1729 :
1730 16 : std::stringstream expected;
1731 16 : switch(static_cast<csspp::output_mode_t>(i))
1732 : {
1733 4 : case csspp::output_mode_t::COMPACT:
1734 : expected << "div:" << pseudo_functions[j] << "(5n+2) { color: #000 }\n"
1735 4 : << csspp_test::get_close_comment();
1736 4 : break;
1737 :
1738 4 : case csspp::output_mode_t::COMPRESSED:
1739 : expected << "div:" << pseudo_functions[j] << "(5n+2){color:#000}\n"
1740 4 : << csspp_test::get_close_comment();
1741 4 : break;
1742 :
1743 4 : case csspp::output_mode_t::EXPANDED:
1744 : expected << "div:" << pseudo_functions[j] << "(5n+2)\n"
1745 : "{\n"
1746 : " color: #000;\n"
1747 : "}\n"
1748 4 : << csspp_test::get_close_comment();
1749 4 : break;
1750 :
1751 4 : case csspp::output_mode_t::TIDY:
1752 : expected << "div:" << pseudo_functions[j] << "(5n+2){color:#000}\n"
1753 4 : << csspp_test::get_close_comment();
1754 4 : break;
1755 :
1756 : }
1757 :
1758 16 : CATCH_REQUIRE(out.str() == expected.str());
1759 16 : CATCH_REQUIRE(c.get_root() == n);
1760 16 : }
1761 : }
1762 :
1763 : // test the scope operator
1764 1 : char const * scope[] =
1765 : {
1766 : "*|div",
1767 : "*|*",
1768 : "div|*",
1769 : "|div",
1770 : "|*"
1771 : };
1772 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1773 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1774 : ++i)
1775 : {
1776 24 : for(size_t j(0); j < sizeof(scope) / sizeof(scope[0]); ++j)
1777 : {
1778 20 : std::stringstream ss;
1779 20 : ss << "with " << scope[j] << " scope {color: black}\n";
1780 60 : csspp::position pos("test.css");
1781 20 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1782 :
1783 40 : csspp::parser p(l);
1784 :
1785 20 : csspp::node::pointer_t n(p.stylesheet());
1786 :
1787 20 : csspp::compiler c;
1788 20 : c.set_root(n);
1789 20 : c.set_date_time_variables(csspp_test::get_now());
1790 20 : c.add_path(csspp_test::get_script_path());
1791 20 : c.add_path(csspp_test::get_version_script_path());
1792 :
1793 20 : c.compile(false);
1794 :
1795 : //std::cerr << "Compiler result is: [" << *n << "]\n";
1796 :
1797 20 : std::stringstream out;
1798 20 : csspp::assembler a(out);
1799 20 : a.output(n, static_cast<csspp::output_mode_t>(i));
1800 :
1801 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1802 :
1803 20 : std::stringstream expected;
1804 20 : switch(static_cast<csspp::output_mode_t>(i))
1805 : {
1806 5 : case csspp::output_mode_t::COMPACT:
1807 : expected << "with " << scope[j] << " scope { color: #000 }\n"
1808 5 : << csspp_test::get_close_comment();
1809 5 : break;
1810 :
1811 5 : case csspp::output_mode_t::COMPRESSED:
1812 : expected << "with " << scope[j] << " scope{color:#000}\n"
1813 5 : << csspp_test::get_close_comment();
1814 5 : break;
1815 :
1816 5 : case csspp::output_mode_t::EXPANDED:
1817 : expected << "with " << scope[j] << " scope\n"
1818 : "{\n"
1819 : " color: #000;\n"
1820 : "}\n"
1821 5 : << csspp_test::get_close_comment();
1822 5 : break;
1823 :
1824 5 : case csspp::output_mode_t::TIDY:
1825 : expected << "with " << scope[j] << " scope{color:#000}\n"
1826 5 : << csspp_test::get_close_comment();
1827 5 : break;
1828 :
1829 : }
1830 :
1831 20 : CATCH_REQUIRE(out.str() == expected.str());
1832 20 : CATCH_REQUIRE(c.get_root() == n);
1833 20 : }
1834 : }
1835 :
1836 : // no error left over
1837 1 : VERIFY_ERRORS("");
1838 1 : }
1839 :
1840 1 : CATCH_TEST_CASE("Assemble numbers", "[assembler] [numbers]")
1841 : {
1842 : // create strings with more single quotes (')
1843 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1844 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1845 : ++i)
1846 : {
1847 4 : std::stringstream ss;
1848 12 : csspp::position pos("test.css");
1849 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1850 :
1851 4 : csspp::integer_t integer(rand() % 10000);
1852 4 : csspp::decimal_number_t decimal_number(static_cast<csspp::decimal_number_t>(rand() % 10000) / 100.0);
1853 4 : csspp::decimal_number_t percent(static_cast<csspp::decimal_number_t>(rand() % 10000) / 100.0);
1854 :
1855 : ss << "#wrapper div * span a:hover {\n"
1856 4 : << " width: " << integer << ";\n"
1857 4 : << " height: " << decimal_number << ";\n"
1858 4 : << " font-size: " << percent << "%;\n"
1859 4 : << "}\n";
1860 :
1861 8 : csspp::parser p(l);
1862 :
1863 4 : csspp::node::pointer_t n(p.stylesheet());
1864 :
1865 4 : csspp::compiler c;
1866 4 : c.set_root(n);
1867 4 : c.set_date_time_variables(csspp_test::get_now());
1868 4 : c.add_path(csspp_test::get_script_path());
1869 4 : c.add_path(csspp_test::get_version_script_path());
1870 :
1871 4 : c.compile(false);
1872 :
1873 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
1874 :
1875 4 : std::stringstream out;
1876 4 : csspp::assembler a(out);
1877 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
1878 :
1879 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1880 :
1881 4 : std::stringstream percent_stream;
1882 4 : percent_stream << percent;
1883 4 : std::string percent_str(percent_stream.str());
1884 4 : if(percent_str.length() > 1
1885 4 : && percent_str[0] == '0'
1886 8 : && percent_str[1] == '.')
1887 : {
1888 0 : percent_str = percent_str.substr(1);
1889 : }
1890 :
1891 4 : std::stringstream decimal_number_stream;
1892 4 : decimal_number_stream << decimal_number;
1893 4 : std::string decimal_number_str(decimal_number_stream.str());
1894 4 : if(decimal_number_str.length() > 1
1895 4 : && decimal_number_str[0] == '0'
1896 8 : && decimal_number_str[1] == '.')
1897 : {
1898 0 : decimal_number_str = decimal_number_str.substr(1);
1899 : }
1900 :
1901 4 : std::stringstream expected;
1902 4 : switch(static_cast<csspp::output_mode_t>(i))
1903 : {
1904 1 : case csspp::output_mode_t::COMPACT:
1905 : expected << "#wrapper div * span a:hover {"
1906 1 : << " width: " << integer << ";"
1907 : << " height: " << decimal_number_str << ";"
1908 : << " font-size: " << percent_str << "%"
1909 : << " }\n"
1910 1 : << csspp_test::get_close_comment();
1911 1 : break;
1912 :
1913 1 : case csspp::output_mode_t::COMPRESSED:
1914 : expected << "#wrapper div * span a:hover{"
1915 1 : << "width:" << integer << ";"
1916 : << "height:" << decimal_number_str << ";"
1917 : << "font-size:" << percent_str << "%"
1918 : << "}\n"
1919 1 : << csspp_test::get_close_comment();
1920 1 : break;
1921 :
1922 1 : case csspp::output_mode_t::EXPANDED:
1923 : expected << "#wrapper div * span a:hover\n"
1924 : << "{\n"
1925 1 : << " width: " << integer << ";\n"
1926 : << " height: " << decimal_number_str << ";\n"
1927 : << " font-size: " << percent_str << "%;\n"
1928 : << "}\n"
1929 1 : << csspp_test::get_close_comment();
1930 1 : break;
1931 :
1932 1 : case csspp::output_mode_t::TIDY:
1933 : expected << "#wrapper div * span a:hover{"
1934 1 : << "width:" << integer << ";"
1935 : << "height:" << decimal_number_str << ";"
1936 : << "font-size:" << percent_str << "%"
1937 : << "}\n"
1938 1 : << csspp_test::get_close_comment();
1939 1 : break;
1940 :
1941 : }
1942 :
1943 4 : CATCH_REQUIRE(out.str() == expected.str());
1944 4 : CATCH_REQUIRE(c.get_root() == n);
1945 4 : }
1946 :
1947 : // no error left over
1948 1 : VERIFY_ERRORS("");
1949 1 : }
1950 :
1951 1 : CATCH_TEST_CASE("Assemble unicode range", "[assembler] [unicode-range-value] [at-keyword]")
1952 : {
1953 : // a valid @supports
1954 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
1955 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
1956 : ++i)
1957 : {
1958 4 : std::stringstream ss;
1959 : ss << "@font-face\n"
1960 : << "{\n"
1961 : << " unicode-range: U+400-4fF;\n"
1962 : << " font-style: italic;\n"
1963 4 : << "}\n";
1964 12 : csspp::position pos("test.css");
1965 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
1966 :
1967 8 : csspp::parser p(l);
1968 :
1969 4 : csspp::node::pointer_t n(p.stylesheet());
1970 :
1971 : // no errors so far
1972 4 : VERIFY_ERRORS("");
1973 :
1974 4 : csspp::compiler c;
1975 4 : c.set_root(n);
1976 4 : c.clear_paths();
1977 4 : c.set_date_time_variables(csspp_test::get_now());
1978 4 : c.add_path(csspp_test::get_script_path());
1979 4 : c.add_path(csspp_test::get_version_script_path());
1980 :
1981 4 : c.compile(false);
1982 :
1983 : //std::cerr << "Result is: [" << *c.get_root() << "]\n";
1984 :
1985 4 : VERIFY_ERRORS("");
1986 :
1987 : //std::cerr << "Compiler result is: [" << *n << "]\n";
1988 :
1989 4 : std::stringstream out;
1990 4 : csspp::assembler a(out);
1991 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
1992 :
1993 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
1994 :
1995 4 : switch(static_cast<csspp::output_mode_t>(i))
1996 : {
1997 1 : case csspp::output_mode_t::COMPACT:
1998 1 : CATCH_REQUIRE(out.str() ==
1999 : "@font-face \n"
2000 : "{\n"
2001 : "unicode-range: U+4??; "
2002 : "font-style: italic"
2003 : "}\n"
2004 : "\n"
2005 : + csspp_test::get_close_comment()
2006 : );
2007 1 : break;
2008 :
2009 1 : case csspp::output_mode_t::COMPRESSED:
2010 1 : CATCH_REQUIRE(out.str() ==
2011 : "@font-face {unicode-range:U+4??;font-style:italic}\n"
2012 : + csspp_test::get_close_comment()
2013 : );
2014 1 : break;
2015 :
2016 1 : case csspp::output_mode_t::EXPANDED:
2017 1 : CATCH_REQUIRE(out.str() ==
2018 : "@font-face \n"
2019 : "{\n"
2020 : " unicode-range: U+4??;\n"
2021 : " font-style: italic}\n"
2022 : "\n"
2023 : + csspp_test::get_close_comment()
2024 : );
2025 1 : break;
2026 :
2027 1 : case csspp::output_mode_t::TIDY:
2028 1 : CATCH_REQUIRE(out.str() ==
2029 : "@font-face \n"
2030 : "{\n"
2031 : "unicode-range:U+4??;font-style:italic}\n"
2032 : "\n"
2033 : + csspp_test::get_close_comment()
2034 : );
2035 1 : break;
2036 :
2037 : }
2038 :
2039 4 : CATCH_REQUIRE(c.get_root() == n);
2040 4 : }
2041 :
2042 : // no left over?
2043 1 : VERIFY_ERRORS("");
2044 1 : }
2045 :
2046 1 : CATCH_TEST_CASE("Assemble strings", "[assembler] [strings]")
2047 : {
2048 : // create strings with more single quotes (')
2049 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
2050 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
2051 : ++i)
2052 : {
2053 4 : std::stringstream ss;
2054 12 : csspp::position pos("test.css");
2055 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
2056 :
2057 4 : std::string str;
2058 4 : int const size(rand() % 20 + 1);
2059 4 : int dq(rand() % 5 + 1);
2060 4 : int sq(rand() % 8 + dq); // if sq >= dq use " for strings
2061 42 : for(int j(0); j < size; ++j)
2062 : {
2063 38 : if(dq > 0 && rand() % 1 == 0)
2064 : {
2065 15 : --dq;
2066 15 : str += '\\';
2067 15 : str += '"';
2068 : }
2069 38 : if(sq > 0 && rand() % 1 == 0)
2070 : {
2071 21 : --sq;
2072 21 : str += '\'';
2073 : }
2074 38 : str += static_cast<char>(rand() % 26 + 'a');
2075 : }
2076 8 : while(dq + sq > 0)
2077 : {
2078 4 : if(dq > 0 && rand() % 1 == 0)
2079 : {
2080 0 : --dq;
2081 0 : str += '\\';
2082 0 : str += '"';
2083 : }
2084 4 : if(sq > 0 && rand() % 1 == 0)
2085 : {
2086 4 : --sq;
2087 4 : str += '\'';
2088 : }
2089 : }
2090 : ss << "div::before { content: \""
2091 : << str
2092 4 : << "\" }";
2093 :
2094 8 : csspp::parser p(l);
2095 :
2096 4 : csspp::node::pointer_t n(p.stylesheet());
2097 :
2098 4 : csspp::compiler c;
2099 4 : c.set_root(n);
2100 4 : c.set_date_time_variables(csspp_test::get_now());
2101 4 : c.add_path(csspp_test::get_script_path());
2102 4 : c.add_path(csspp_test::get_version_script_path());
2103 :
2104 4 : c.compile(false);
2105 :
2106 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
2107 :
2108 4 : std::stringstream out;
2109 4 : csspp::assembler a(out);
2110 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
2111 :
2112 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
2113 :
2114 4 : switch(static_cast<csspp::output_mode_t>(i))
2115 : {
2116 1 : case csspp::output_mode_t::COMPACT:
2117 1 : CATCH_REQUIRE(out.str() ==
2118 : "div::before { content: \"" + str + "\" }\n"
2119 : + csspp_test::get_close_comment()
2120 : );
2121 1 : break;
2122 :
2123 1 : case csspp::output_mode_t::COMPRESSED:
2124 1 : CATCH_REQUIRE(out.str() ==
2125 : "div::before{content:\"" + str + "\"}\n"
2126 : + csspp_test::get_close_comment()
2127 : );
2128 1 : break;
2129 :
2130 1 : case csspp::output_mode_t::EXPANDED:
2131 1 : CATCH_REQUIRE(out.str() ==
2132 : "div::before\n"
2133 : "{\n"
2134 : " content: \"" + str + "\";\n"
2135 : "}\n"
2136 : + csspp_test::get_close_comment()
2137 : );
2138 1 : break;
2139 :
2140 1 : case csspp::output_mode_t::TIDY:
2141 1 : CATCH_REQUIRE(out.str() ==
2142 : "div::before{content:\"" + str + "\"}\n"
2143 : + csspp_test::get_close_comment()
2144 : );
2145 1 : break;
2146 :
2147 : }
2148 :
2149 4 : CATCH_REQUIRE(c.get_root() == n);
2150 4 : }
2151 :
2152 : // create strings with more double quotes (")
2153 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
2154 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
2155 : ++i)
2156 : {
2157 4 : std::stringstream ss;
2158 12 : csspp::position pos("test.css");
2159 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
2160 :
2161 4 : std::string str;
2162 4 : int const size(rand() % 20 + 1);
2163 4 : int sq(rand() % 5 + 1);
2164 4 : int dq(rand() % 8 + 1 + sq); // we need dq > sq
2165 36 : for(int j(0); j < size; ++j)
2166 : {
2167 32 : if(dq > 0 && rand() % 1 == 0)
2168 : {
2169 14 : --dq;
2170 14 : str += '"';
2171 : }
2172 32 : if(sq > 0 && rand() % 1 == 0)
2173 : {
2174 8 : --sq;
2175 8 : str += '\\';
2176 8 : str += '\'';
2177 : }
2178 32 : str += static_cast<char>(rand() % 26 + 'a');
2179 : }
2180 14 : while(dq + sq > 0)
2181 : {
2182 10 : if(dq > 0 && rand() % 1 == 0)
2183 : {
2184 10 : --dq;
2185 10 : str += '"';
2186 : }
2187 10 : if(sq > 0 && rand() % 1 == 0)
2188 : {
2189 1 : --sq;
2190 1 : str += '\\';
2191 1 : str += '\'';
2192 : }
2193 : }
2194 : ss << "div::after { content: '"
2195 : << str
2196 4 : << "' }";
2197 :
2198 8 : csspp::parser p(l);
2199 :
2200 4 : csspp::node::pointer_t n(p.stylesheet());
2201 :
2202 4 : csspp::compiler c;
2203 4 : c.set_root(n);
2204 4 : c.set_date_time_variables(csspp_test::get_now());
2205 4 : c.add_path(csspp_test::get_script_path());
2206 4 : c.add_path(csspp_test::get_version_script_path());
2207 :
2208 4 : c.compile(false);
2209 :
2210 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
2211 :
2212 4 : std::stringstream out;
2213 4 : csspp::assembler a(out);
2214 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
2215 :
2216 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
2217 :
2218 4 : switch(static_cast<csspp::output_mode_t>(i))
2219 : {
2220 1 : case csspp::output_mode_t::COMPACT:
2221 1 : CATCH_REQUIRE(out.str() ==
2222 : "div::after { content: '" + str + "' }\n"
2223 : + csspp_test::get_close_comment()
2224 : );
2225 1 : break;
2226 :
2227 1 : case csspp::output_mode_t::COMPRESSED:
2228 1 : CATCH_REQUIRE(out.str() ==
2229 : "div::after{content:'" + str + "'}\n"
2230 : + csspp_test::get_close_comment()
2231 : );
2232 1 : break;
2233 :
2234 1 : case csspp::output_mode_t::EXPANDED:
2235 1 : CATCH_REQUIRE(out.str() ==
2236 : "div::after\n"
2237 : "{\n"
2238 : " content: '" + str + "';\n"
2239 : "}\n"
2240 : + csspp_test::get_close_comment()
2241 : );
2242 1 : break;
2243 :
2244 1 : case csspp::output_mode_t::TIDY:
2245 1 : CATCH_REQUIRE(out.str() ==
2246 : "div::after{content:'" + str + "'}\n"
2247 : + csspp_test::get_close_comment()
2248 : );
2249 1 : break;
2250 :
2251 : }
2252 :
2253 4 : CATCH_REQUIRE(c.get_root() == n);
2254 4 : }
2255 :
2256 : // no error left over
2257 1 : VERIFY_ERRORS("");
2258 1 : }
2259 :
2260 1 : CATCH_TEST_CASE("Assemble URI", "[assembler] [uri]")
2261 : {
2262 : // all characters can be inserted as is (no switching to string)
2263 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
2264 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
2265 : ++i)
2266 : {
2267 4 : std::stringstream ss;
2268 12 : csspp::position pos("test.css");
2269 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
2270 :
2271 4 : std::string name;
2272 4 : int const size(rand() % 20 + 1);
2273 55 : for(int j(0); j < size; ++j)
2274 : {
2275 51 : csspp::wide_char_t c(rand() % 0x110000);
2276 51 : while(!is_valid_char(c)
2277 51 : || c == '\''
2278 51 : || c == '"'
2279 51 : || c == '('
2280 51 : || c == ')'
2281 102 : || l->is_non_printable(c))
2282 : {
2283 0 : c = rand() % 0x110000;
2284 : }
2285 51 : name += l->wctomb(c);
2286 : }
2287 : ss << "div { background-image: url(/images/"
2288 : << name
2289 4 : << ".png); }";
2290 :
2291 8 : csspp::parser p(l);
2292 :
2293 4 : csspp::node::pointer_t n(p.stylesheet());
2294 :
2295 4 : csspp::compiler c;
2296 4 : c.set_root(n);
2297 4 : c.set_date_time_variables(csspp_test::get_now());
2298 4 : c.add_path(csspp_test::get_script_path());
2299 4 : c.add_path(csspp_test::get_version_script_path());
2300 :
2301 4 : c.compile(false);
2302 :
2303 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
2304 :
2305 4 : std::stringstream out;
2306 4 : csspp::assembler a(out);
2307 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
2308 :
2309 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
2310 :
2311 4 : switch(static_cast<csspp::output_mode_t>(i))
2312 : {
2313 1 : case csspp::output_mode_t::COMPACT:
2314 1 : CATCH_REQUIRE(out.str() ==
2315 : "div { background-image: url( /images/" + name + ".png ) }\n"
2316 : + csspp_test::get_close_comment()
2317 : );
2318 1 : break;
2319 :
2320 1 : case csspp::output_mode_t::COMPRESSED:
2321 1 : CATCH_REQUIRE(out.str() ==
2322 : "div{background-image:url(/images/" + name + ".png)}\n"
2323 : + csspp_test::get_close_comment()
2324 : );
2325 1 : break;
2326 :
2327 1 : case csspp::output_mode_t::EXPANDED:
2328 1 : CATCH_REQUIRE(out.str() ==
2329 : "div\n"
2330 : "{\n"
2331 : " background-image: url( /images/" + name + ".png );\n"
2332 : "}\n"
2333 : + csspp_test::get_close_comment()
2334 : );
2335 1 : break;
2336 :
2337 1 : case csspp::output_mode_t::TIDY:
2338 1 : CATCH_REQUIRE(out.str() ==
2339 : "div{background-image:url(/images/" + name + ".png)}\n"
2340 : + csspp_test::get_close_comment()
2341 : );
2342 1 : break;
2343 :
2344 : }
2345 :
2346 4 : CATCH_REQUIRE(c.get_root() == n);
2347 4 : }
2348 :
2349 : // at least one character requires the use of a string
2350 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
2351 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
2352 : ++i)
2353 : {
2354 4 : std::stringstream ss;
2355 12 : csspp::position pos("test.css");
2356 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
2357 :
2358 4 : std::string name;
2359 4 : csspp::wide_char_t special(L'\0');
2360 4 : int const size(rand() % 20 + 1);
2361 21 : for(int j(0); j < size; ++j)
2362 : {
2363 : csspp::wide_char_t c;
2364 17 : if(j == size / 2)
2365 : {
2366 : // this happens only once and is mandatory since 'size > 0'
2367 : // is always true
2368 4 : c = special = "'\"()"[rand() % 4];
2369 : }
2370 : else
2371 : {
2372 13 : c = rand() % 0x110000;
2373 13 : while(!is_valid_char(c)
2374 13 : || c == '\''
2375 13 : || c == '"'
2376 13 : || c == '('
2377 13 : || c == ')'
2378 26 : || l->is_non_printable(c))
2379 : {
2380 0 : c = rand() % 0x110000;
2381 : }
2382 : }
2383 17 : name += l->wctomb(c);
2384 : }
2385 4 : std::string quote;
2386 4 : quote += special == '"' ? '\'' : '"';
2387 : ss << "div { background-image: url("
2388 : << quote
2389 : << "/images/"
2390 : << name
2391 : << ".png"
2392 : << quote
2393 4 : << "); }";
2394 :
2395 8 : csspp::parser p(l);
2396 :
2397 4 : csspp::node::pointer_t n(p.stylesheet());
2398 :
2399 4 : csspp::compiler c;
2400 4 : c.set_root(n);
2401 4 : c.set_date_time_variables(csspp_test::get_now());
2402 4 : c.add_path(csspp_test::get_script_path());
2403 4 : c.add_path(csspp_test::get_version_script_path());
2404 :
2405 4 : c.compile(false);
2406 :
2407 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
2408 :
2409 4 : std::stringstream out;
2410 4 : csspp::assembler a(out);
2411 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
2412 :
2413 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
2414 :
2415 4 : switch(static_cast<csspp::output_mode_t>(i))
2416 : {
2417 1 : case csspp::output_mode_t::COMPACT:
2418 1 : CATCH_REQUIRE(out.str() ==
2419 : "div { background-image: url( " + quote + "/images/" + name + ".png" + quote + " ) }\n"
2420 : + csspp_test::get_close_comment()
2421 : );
2422 1 : break;
2423 :
2424 1 : case csspp::output_mode_t::COMPRESSED:
2425 1 : CATCH_REQUIRE(out.str() ==
2426 : "div{background-image:url(" + quote + "/images/" + name + ".png" + quote + ")}\n"
2427 : + csspp_test::get_close_comment()
2428 : );
2429 1 : break;
2430 :
2431 1 : case csspp::output_mode_t::EXPANDED:
2432 1 : CATCH_REQUIRE(out.str() ==
2433 : "div\n"
2434 : "{\n"
2435 : " background-image: url( " + quote + "/images/" + name + ".png" + quote + " );\n"
2436 : "}\n"
2437 : + csspp_test::get_close_comment()
2438 : );
2439 1 : break;
2440 :
2441 1 : case csspp::output_mode_t::TIDY:
2442 1 : CATCH_REQUIRE(out.str() ==
2443 : "div{background-image:url(" + quote + "/images/" + name + ".png" + quote + ")}\n"
2444 : + csspp_test::get_close_comment()
2445 : );
2446 1 : break;
2447 :
2448 : }
2449 :
2450 4 : CATCH_REQUIRE(c.get_root() == n);
2451 4 : }
2452 :
2453 : // no error left over
2454 1 : VERIFY_ERRORS("");
2455 1 : }
2456 :
2457 1 : CATCH_TEST_CASE("Assemble C++ comment", "[assembler] [comment]")
2458 : {
2459 : // One line C++ comment
2460 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
2461 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
2462 : ++i)
2463 : {
2464 4 : std::stringstream ss;
2465 : ss << "// Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved. -- Assembler Test Version {$_csspp_version} -- @preserve\n"
2466 4 : << "body.error { color: red }\n";
2467 12 : csspp::position pos("test.css");
2468 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
2469 :
2470 8 : csspp::parser p(l);
2471 :
2472 4 : csspp::node::pointer_t n(p.stylesheet());
2473 :
2474 4 : VERIFY_ERRORS("test.css(1): warning: C++ comments should not be preserved as they are not supported by most CSS parsers.\n");
2475 :
2476 4 : csspp::compiler c;
2477 4 : c.set_root(n);
2478 4 : c.set_date_time_variables(csspp_test::get_now());
2479 4 : c.add_path(csspp_test::get_script_path());
2480 4 : c.add_path(csspp_test::get_version_script_path());
2481 :
2482 4 : c.compile(false);
2483 :
2484 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
2485 :
2486 4 : std::stringstream out;
2487 4 : csspp::assembler a(out);
2488 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
2489 :
2490 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
2491 :
2492 4 : switch(static_cast<csspp::output_mode_t>(i))
2493 : {
2494 1 : case csspp::output_mode_t::COMPACT:
2495 1 : CATCH_REQUIRE(out.str() ==
2496 : "/* Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved. -- Assembler Test Version " CSSPP_VERSION " -- @preserve */\n"
2497 : "body.error { color: red }\n"
2498 : + csspp_test::get_close_comment()
2499 : );
2500 1 : break;
2501 :
2502 1 : case csspp::output_mode_t::COMPRESSED:
2503 1 : CATCH_REQUIRE(out.str() ==
2504 : "/* Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved. -- Assembler Test Version " CSSPP_VERSION " -- @preserve */\n"
2505 : "body.error{color:red}\n"
2506 : + csspp_test::get_close_comment()
2507 : );
2508 1 : break;
2509 :
2510 1 : case csspp::output_mode_t::EXPANDED:
2511 1 : CATCH_REQUIRE(out.str() ==
2512 : "/* Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved. -- Assembler Test Version " CSSPP_VERSION " -- @preserve */\n"
2513 : "body.error\n"
2514 : "{\n"
2515 : " color: red;\n"
2516 : "}\n"
2517 : + csspp_test::get_close_comment()
2518 : );
2519 1 : break;
2520 :
2521 1 : case csspp::output_mode_t::TIDY:
2522 1 : CATCH_REQUIRE(out.str() ==
2523 : "/* Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved. -- Assembler Test Version " CSSPP_VERSION " -- @preserve */\n"
2524 : "body.error{color:red}\n"
2525 : + csspp_test::get_close_comment()
2526 : );
2527 1 : break;
2528 :
2529 : }
2530 :
2531 4 : CATCH_REQUIRE(c.get_root() == n);
2532 4 : }
2533 :
2534 : // Multi-line C++ comment
2535 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
2536 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
2537 : ++i)
2538 : {
2539 4 : std::stringstream ss;
2540 : ss << "// Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved.\n"
2541 : << "// Assembler Test\n"
2542 : << "// @preserve\n"
2543 4 : << "body.error { color: red }\n";
2544 12 : csspp::position pos("test.css");
2545 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
2546 :
2547 8 : csspp::parser p(l);
2548 :
2549 4 : csspp::node::pointer_t n(p.stylesheet());
2550 :
2551 4 : VERIFY_ERRORS("test.css(1): warning: C++ comments should not be preserved as they are not supported by most CSS parsers.\n");
2552 :
2553 4 : csspp::compiler c;
2554 4 : c.set_root(n);
2555 4 : c.set_date_time_variables(csspp_test::get_now());
2556 4 : c.add_path(csspp_test::get_script_path());
2557 4 : c.add_path(csspp_test::get_version_script_path());
2558 :
2559 4 : c.compile(false);
2560 :
2561 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
2562 :
2563 4 : std::stringstream out;
2564 4 : csspp::assembler a(out);
2565 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
2566 :
2567 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
2568 :
2569 4 : switch(static_cast<csspp::output_mode_t>(i))
2570 : {
2571 1 : case csspp::output_mode_t::COMPACT:
2572 1 : CATCH_REQUIRE(out.str() ==
2573 : "/* Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved.\n"
2574 : " * Assembler Test\n"
2575 : " * @preserve\n"
2576 : " */\n"
2577 : "body.error { color: red }\n"
2578 : + csspp_test::get_close_comment()
2579 : );
2580 1 : break;
2581 :
2582 1 : case csspp::output_mode_t::COMPRESSED:
2583 1 : CATCH_REQUIRE(out.str() ==
2584 : "/* Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved.\n"
2585 : " * Assembler Test\n"
2586 : " * @preserve\n"
2587 : " */\n"
2588 : "body.error{color:red}\n"
2589 : + csspp_test::get_close_comment()
2590 : );
2591 1 : break;
2592 :
2593 1 : case csspp::output_mode_t::EXPANDED:
2594 1 : CATCH_REQUIRE(out.str() ==
2595 : "/* Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved.\n"
2596 : " * Assembler Test\n"
2597 : " * @preserve\n"
2598 : " */\n"
2599 : "body.error\n"
2600 : "{\n"
2601 : " color: red;\n"
2602 : "}\n"
2603 : + csspp_test::get_close_comment()
2604 : );
2605 1 : break;
2606 :
2607 1 : case csspp::output_mode_t::TIDY:
2608 1 : CATCH_REQUIRE(out.str() ==
2609 : "/* Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved.\n"
2610 : " * Assembler Test\n"
2611 : " * @preserve\n"
2612 : " */\n"
2613 : "body.error{color:red}\n"
2614 : + csspp_test::get_close_comment()
2615 : );
2616 1 : break;
2617 :
2618 : }
2619 :
2620 4 : CATCH_REQUIRE(c.get_root() == n);
2621 4 : }
2622 :
2623 : // no error left over
2624 1 : VERIFY_ERRORS("");
2625 1 : }
2626 :
2627 1 : CATCH_TEST_CASE("Assemble @-keyword", "[assembler] [at-keyword]")
2628 : {
2629 : // Standard @document with a sub-rule
2630 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
2631 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
2632 : ++i)
2633 : {
2634 4 : std::stringstream ss;
2635 : ss << "@document url(http://www.example.com/), regexp(\"https://.*\")\n"
2636 : << "{\n"
2637 : << " body { width: 8.5in; height: 9in; }\n"
2638 : << " div { border: .25in unquote(\"solid\") lightgray }\n"
2639 : << "}\n"
2640 4 : << "#edge { border: 1px unquote('solid') black }\n";
2641 12 : csspp::position pos("test.css");
2642 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
2643 :
2644 8 : csspp::parser p(l);
2645 :
2646 4 : csspp::node::pointer_t n(p.stylesheet());
2647 :
2648 4 : csspp::compiler c;
2649 4 : c.set_root(n);
2650 4 : c.set_date_time_variables(csspp_test::get_now());
2651 4 : c.add_path(csspp_test::get_script_path());
2652 4 : c.add_path(csspp_test::get_version_script_path());
2653 :
2654 4 : c.compile(false);
2655 :
2656 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
2657 :
2658 4 : std::stringstream out;
2659 4 : csspp::assembler a(out);
2660 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
2661 :
2662 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
2663 :
2664 4 : switch(static_cast<csspp::output_mode_t>(i))
2665 : {
2666 1 : case csspp::output_mode_t::COMPACT:
2667 1 : CATCH_REQUIRE(out.str() ==
2668 : "@document url( http://www.example.com/ ), regexp(\"https://.*\")\n"
2669 : "{\n"
2670 : "body { width: 8.5in; height: 9in }\n"
2671 : "div { border: .25in solid #d3d3d3 }\n"
2672 : "}\n"
2673 : "\n"
2674 : "#edge { border: 1px solid #000 }\n"
2675 : + csspp_test::get_close_comment()
2676 : );
2677 1 : break;
2678 :
2679 1 : case csspp::output_mode_t::COMPRESSED:
2680 1 : CATCH_REQUIRE(out.str() ==
2681 : "@document url(http://www.example.com/),regexp(\"https://.*\"){body{width:8.5in;height:9in}div{border:.25in solid #d3d3d3}}#edge{border:1px solid #000}\n"
2682 : + csspp_test::get_close_comment()
2683 : );
2684 1 : break;
2685 :
2686 1 : case csspp::output_mode_t::EXPANDED:
2687 1 : CATCH_REQUIRE(out.str() ==
2688 : "@document url( http://www.example.com/ ), regexp(\"https://.*\")\n"
2689 : "{\n"
2690 : "body\n"
2691 : "{\n"
2692 : " width: 8.5in;\n"
2693 : " height: 9in;\n"
2694 : "}\n"
2695 : "div\n"
2696 : "{\n"
2697 : " border: .25in solid #d3d3d3;\n"
2698 : "}\n"
2699 : "}\n"
2700 : "\n"
2701 : "#edge\n"
2702 : "{\n"
2703 : " border: 1px solid #000;\n"
2704 : "}\n"
2705 : + csspp_test::get_close_comment()
2706 : );
2707 1 : break;
2708 :
2709 1 : case csspp::output_mode_t::TIDY:
2710 1 : CATCH_REQUIRE(out.str() ==
2711 : "@document url(http://www.example.com/),regexp(\"https://.*\")\n"
2712 : "{\n"
2713 : "body{width:8.5in;height:9in}\n"
2714 : "div{border:.25in solid #d3d3d3}\n"
2715 : "}\n"
2716 : "\n"
2717 : "#edge{border:1px solid #000}\n"
2718 : + csspp_test::get_close_comment()
2719 : );
2720 1 : break;
2721 :
2722 : }
2723 :
2724 4 : CATCH_REQUIRE(c.get_root() == n);
2725 4 : }
2726 :
2727 : // Standard @media with a sub-rule
2728 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
2729 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
2730 : ++i)
2731 : {
2732 4 : std::stringstream ss;
2733 : ss << "@media screen or (printer and color) { body { width: 8.5in; height: 9in; } }\n"
2734 4 : << "#edge { border: 1px solid black }\n";
2735 12 : csspp::position pos("test.css");
2736 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
2737 :
2738 8 : csspp::parser p(l);
2739 :
2740 4 : csspp::node::pointer_t n(p.stylesheet());
2741 :
2742 4 : csspp::compiler c;
2743 4 : c.set_root(n);
2744 4 : c.set_date_time_variables(csspp_test::get_now());
2745 4 : c.add_path(csspp_test::get_script_path());
2746 4 : c.add_path(csspp_test::get_version_script_path());
2747 :
2748 4 : c.compile(false);
2749 :
2750 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
2751 :
2752 4 : std::stringstream out;
2753 4 : csspp::assembler a(out);
2754 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
2755 :
2756 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
2757 :
2758 4 : switch(static_cast<csspp::output_mode_t>(i))
2759 : {
2760 1 : case csspp::output_mode_t::COMPACT:
2761 1 : CATCH_REQUIRE(out.str() ==
2762 : "@media screen or (printer and color) \n"
2763 : "{\n"
2764 : "body { width: 8.5in; height: 9in }\n"
2765 : "}\n"
2766 : "\n"
2767 : "#edge { border: 1px solid #000 }\n"
2768 : + csspp_test::get_close_comment()
2769 : );
2770 1 : break;
2771 :
2772 1 : case csspp::output_mode_t::COMPRESSED:
2773 1 : CATCH_REQUIRE(out.str() ==
2774 : "@media screen or (printer and color){body{width:8.5in;height:9in}}#edge{border:1px solid #000}\n"
2775 : + csspp_test::get_close_comment()
2776 : );
2777 1 : break;
2778 :
2779 1 : case csspp::output_mode_t::EXPANDED:
2780 1 : CATCH_REQUIRE(out.str() ==
2781 : "@media screen or (printer and color) \n"
2782 : "{\n"
2783 : "body\n"
2784 : "{\n"
2785 : " width: 8.5in;\n"
2786 : " height: 9in;\n"
2787 : "}\n"
2788 : "}\n"
2789 : "\n"
2790 : "#edge\n"
2791 : "{\n"
2792 : " border: 1px solid #000;\n"
2793 : "}\n"
2794 : + csspp_test::get_close_comment()
2795 : );
2796 1 : break;
2797 :
2798 1 : case csspp::output_mode_t::TIDY:
2799 1 : CATCH_REQUIRE(out.str() ==
2800 : "@media screen or (printer and color)\n"
2801 : "{\n"
2802 : "body{width:8.5in;height:9in}\n"
2803 : "}\n"
2804 : "\n"
2805 : "#edge{border:1px solid #000}\n"
2806 : + csspp_test::get_close_comment()
2807 : );
2808 1 : break;
2809 :
2810 : }
2811 :
2812 4 : CATCH_REQUIRE(c.get_root() == n);
2813 4 : }
2814 :
2815 : // @media with many parenthesis and multiple sub-rules
2816 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
2817 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
2818 : ++i)
2819 : {
2820 4 : std::stringstream ss;
2821 : ss << "@media not (screen or ((laser or matrix or jet-printer) and color)) {\n"
2822 : << " body { width: 8.5in; height: 9in; }\n"
2823 : << " div { margin: .15in; padding: .07in; }\n"
2824 : << " p { margin-bottom: 2em; }\n"
2825 : << "}\n"
2826 4 : << "#edge { border: 1px solid black }\n";
2827 12 : csspp::position pos("test.css");
2828 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
2829 :
2830 8 : csspp::parser p(l);
2831 :
2832 4 : csspp::node::pointer_t n(p.stylesheet());
2833 :
2834 4 : csspp::compiler c;
2835 4 : c.set_root(n);
2836 4 : c.set_date_time_variables(csspp_test::get_now());
2837 4 : c.add_path(csspp_test::get_script_path());
2838 4 : c.add_path(csspp_test::get_version_script_path());
2839 :
2840 4 : c.compile(false);
2841 :
2842 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
2843 :
2844 4 : std::stringstream out;
2845 4 : csspp::assembler a(out);
2846 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
2847 :
2848 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
2849 :
2850 4 : switch(static_cast<csspp::output_mode_t>(i))
2851 : {
2852 1 : case csspp::output_mode_t::COMPACT:
2853 1 : CATCH_REQUIRE(out.str() ==
2854 : "@media not (screen or ((laser or matrix or jet-printer) and color)) \n"
2855 : "{\n"
2856 : "body { width: 8.5in; height: 9in }\n"
2857 : "div { margin: .15in; padding: .07in }\n"
2858 : "p { margin-bottom: 2em }\n"
2859 : "}\n"
2860 : "\n"
2861 : "#edge { border: 1px solid #000 }\n"
2862 : + csspp_test::get_close_comment()
2863 : );
2864 1 : break;
2865 :
2866 1 : case csspp::output_mode_t::COMPRESSED:
2867 1 : CATCH_REQUIRE(out.str() ==
2868 : "@media not (screen or ((laser or matrix or jet-printer) and color)){body{width:8.5in;height:9in}div{margin:.15in;padding:.07in}p{margin-bottom:2em}}#edge{border:1px solid #000}\n"
2869 : + csspp_test::get_close_comment()
2870 : );
2871 1 : break;
2872 :
2873 1 : case csspp::output_mode_t::EXPANDED:
2874 1 : CATCH_REQUIRE(out.str() ==
2875 : "@media not (screen or ((laser or matrix or jet-printer) and color)) \n"
2876 : "{\n"
2877 : "body\n"
2878 : "{\n"
2879 : " width: 8.5in;\n"
2880 : " height: 9in;\n"
2881 : "}\n"
2882 : "div\n"
2883 : "{\n"
2884 : " margin: .15in;\n"
2885 : " padding: .07in;\n"
2886 : "}\n"
2887 : "p\n"
2888 : "{\n"
2889 : " margin-bottom: 2em;\n"
2890 : "}\n"
2891 : "}\n"
2892 : "\n"
2893 : "#edge\n"
2894 : "{\n"
2895 : " border: 1px solid #000;\n"
2896 : "}\n"
2897 : + csspp_test::get_close_comment()
2898 : );
2899 1 : break;
2900 :
2901 1 : case csspp::output_mode_t::TIDY:
2902 1 : CATCH_REQUIRE(out.str() ==
2903 : "@media not (screen or ((laser or matrix or jet-printer) and color))\n"
2904 : "{\n"
2905 : "body{width:8.5in;height:9in}\n"
2906 : "div{margin:.15in;padding:.07in}\n"
2907 : "p{margin-bottom:2em}\n"
2908 : "}\n"
2909 : "\n"
2910 : "#edge{border:1px solid #000}\n"
2911 : + csspp_test::get_close_comment()
2912 : );
2913 1 : break;
2914 :
2915 : }
2916 :
2917 4 : CATCH_REQUIRE(c.get_root() == n);
2918 4 : }
2919 :
2920 : // simple @import to see the ';' at the end of the line
2921 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
2922 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
2923 : ++i)
2924 : {
2925 4 : std::stringstream ss;
2926 4 : ss << "@import url(//css.m2osw.com/store/colors.css) only screen or (printer and color);\n";
2927 12 : csspp::position pos("test.css");
2928 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
2929 :
2930 8 : csspp::parser p(l);
2931 :
2932 4 : csspp::node::pointer_t n(p.stylesheet());
2933 :
2934 4 : csspp::compiler c;
2935 4 : c.set_root(n);
2936 4 : c.set_date_time_variables(csspp_test::get_now());
2937 4 : c.add_path(csspp_test::get_script_path());
2938 4 : c.add_path(csspp_test::get_version_script_path());
2939 :
2940 4 : c.compile(false);
2941 :
2942 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
2943 :
2944 4 : std::stringstream out;
2945 4 : csspp::assembler a(out);
2946 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
2947 :
2948 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
2949 :
2950 4 : switch(static_cast<csspp::output_mode_t>(i))
2951 : {
2952 1 : case csspp::output_mode_t::COMPACT:
2953 1 : CATCH_REQUIRE(out.str() ==
2954 : "@import url( //css.m2osw.com/store/colors.css ) only screen or (printer and color) ;\n"
2955 : + csspp_test::get_close_comment()
2956 : );
2957 1 : break;
2958 :
2959 1 : case csspp::output_mode_t::COMPRESSED:
2960 1 : CATCH_REQUIRE(out.str() ==
2961 : "@import url(//css.m2osw.com/store/colors.css) only screen or (printer and color);\n"
2962 : + csspp_test::get_close_comment()
2963 : );
2964 1 : break;
2965 :
2966 1 : case csspp::output_mode_t::EXPANDED:
2967 1 : CATCH_REQUIRE(out.str() ==
2968 : "@import url( //css.m2osw.com/store/colors.css ) only screen or (printer and color) ;\n"
2969 : + csspp_test::get_close_comment()
2970 : );
2971 1 : break;
2972 :
2973 1 : case csspp::output_mode_t::TIDY:
2974 1 : CATCH_REQUIRE(out.str() ==
2975 : "@import url(//css.m2osw.com/store/colors.css) only screen or (printer and color);\n"
2976 : + csspp_test::get_close_comment()
2977 : );
2978 1 : break;
2979 :
2980 : }
2981 :
2982 4 : CATCH_REQUIRE(c.get_root() == n);
2983 4 : }
2984 :
2985 : // @keyframes
2986 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
2987 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
2988 : ++i)
2989 : {
2990 4 : std::stringstream ss;
2991 : ss << "@keyframes name {\n"
2992 : << " from {\n"
2993 : << " left: 0;\n"
2994 : << " }\n"
2995 : << " 33% {\n"
2996 : << " left: 5px;\n"
2997 : << " }\n"
2998 : << " 67% {\n"
2999 : << " left: 45px;\n"
3000 : << " }\n"
3001 : << " to {\n"
3002 : << " left: 50px;\n"
3003 : << " }\n"
3004 4 : << "};\n";
3005 12 : csspp::position pos("test.css");
3006 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
3007 :
3008 8 : csspp::parser p(l);
3009 :
3010 4 : csspp::node::pointer_t n(p.stylesheet());
3011 :
3012 4 : csspp::compiler c;
3013 4 : c.set_root(n);
3014 4 : c.set_date_time_variables(csspp_test::get_now());
3015 4 : c.add_path(csspp_test::get_script_path());
3016 4 : c.add_path(csspp_test::get_version_script_path());
3017 :
3018 4 : c.compile(false);
3019 :
3020 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
3021 :
3022 4 : std::stringstream out;
3023 4 : csspp::assembler a(out);
3024 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
3025 :
3026 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
3027 :
3028 4 : switch(static_cast<csspp::output_mode_t>(i))
3029 : {
3030 1 : case csspp::output_mode_t::COMPACT:
3031 1 : CATCH_REQUIRE(out.str() ==
3032 : "@keyframes name {\n"
3033 : "0% { left: 0 }\n"
3034 : "33% { left: 5px }\n"
3035 : "67% { left: 45px }\n"
3036 : "to { left: 50px }\n"
3037 : "}\n"
3038 : + csspp_test::get_close_comment()
3039 : );
3040 1 : break;
3041 :
3042 1 : case csspp::output_mode_t::COMPRESSED:
3043 1 : CATCH_REQUIRE(out.str() ==
3044 : "@keyframes name{0%{left:0}33%{left:5px}67%{left:45px}to{left:50px}}\n"
3045 : + csspp_test::get_close_comment()
3046 : );
3047 1 : break;
3048 :
3049 1 : case csspp::output_mode_t::EXPANDED:
3050 1 : CATCH_REQUIRE(out.str() ==
3051 : "@keyframes name {\n"
3052 : "0%\n"
3053 : "{\n"
3054 : " left: 0;\n"
3055 : "}\n"
3056 : "33%\n"
3057 : "{\n"
3058 : " left: 5px;\n"
3059 : "}\n"
3060 : "67%\n"
3061 : "{\n"
3062 : " left: 45px;\n"
3063 : "}\n"
3064 : "to\n"
3065 : "{\n"
3066 : " left: 50px;\n"
3067 : "}\n"
3068 : "}\n"
3069 : + csspp_test::get_close_comment()
3070 : );
3071 1 : break;
3072 :
3073 1 : case csspp::output_mode_t::TIDY:
3074 1 : CATCH_REQUIRE(out.str() ==
3075 : "@keyframes name{\n"
3076 : "0%{left:0}\n"
3077 : "33%{left:5px}\n"
3078 : "67%{left:45px}\n"
3079 : "to{left:50px}\n"
3080 : "}\n"
3081 : + csspp_test::get_close_comment()
3082 : );
3083 1 : break;
3084 :
3085 : }
3086 :
3087 4 : CATCH_REQUIRE(c.get_root() == n);
3088 4 : }
3089 :
3090 : // no error left over
3091 1 : VERIFY_ERRORS("");
3092 1 : }
3093 :
3094 1 : CATCH_TEST_CASE("Assemble functions", "[assembler] [function]")
3095 : {
3096 : // Test with gradient() function
3097 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
3098 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
3099 : ++i)
3100 : {
3101 4 : std::stringstream ss;
3102 : ss << "$box($color, $width, $height): { border: 1px * 3 solid $color; width: $width * 1.5; height: $height };\n"
3103 4 : << "a ~ b { -csspp-null: $box(#39458A, 300px, 200px); }\n";
3104 12 : csspp::position pos("test.css");
3105 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
3106 :
3107 8 : csspp::parser p(l);
3108 :
3109 4 : csspp::node::pointer_t n(p.stylesheet());
3110 :
3111 : //std::cerr << "Parser result is: [" << *n << "]\n";
3112 :
3113 4 : csspp::compiler c;
3114 4 : c.set_root(n);
3115 4 : c.set_date_time_variables(csspp_test::get_now());
3116 4 : c.add_path(csspp_test::get_script_path());
3117 4 : c.add_path(csspp_test::get_version_script_path());
3118 :
3119 4 : c.compile(false);
3120 :
3121 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
3122 :
3123 4 : std::stringstream out;
3124 4 : csspp::assembler a(out);
3125 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
3126 :
3127 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
3128 :
3129 4 : std::stringstream expected;
3130 4 : switch(static_cast<csspp::output_mode_t>(i))
3131 : {
3132 1 : case csspp::output_mode_t::COMPACT:
3133 1 : expected << "a ~ b { border: 3px solid #39458a; width: 450px; height: 200px }\n";
3134 1 : break;
3135 :
3136 1 : case csspp::output_mode_t::COMPRESSED:
3137 1 : expected << "a~b{border:3px solid #39458a;width:450px;height:200px}\n";
3138 1 : break;
3139 :
3140 1 : case csspp::output_mode_t::EXPANDED:
3141 : expected << "a ~ b\n"
3142 : << "{\n"
3143 : << " border: 3px solid #39458a;\n"
3144 : << " width: 450px;\n"
3145 : << " height: 200px;\n"
3146 1 : << "}\n";
3147 1 : break;
3148 :
3149 1 : case csspp::output_mode_t::TIDY:
3150 1 : expected << "a~b{border:3px solid #39458a;width:450px;height:200px}\n";
3151 1 : break;
3152 :
3153 : }
3154 4 : expected << csspp_test::get_close_comment();
3155 4 : CATCH_REQUIRE(out.str() == expected.str());
3156 :
3157 4 : CATCH_REQUIRE(c.get_root() == n);
3158 4 : }
3159 :
3160 : // CSS Function which is an internal CSS Preprocess function
3161 : // (meaning that it gets interpreted and replaced by a value)
3162 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
3163 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
3164 : ++i)
3165 : {
3166 4 : std::stringstream ss;
3167 4 : ss << "a b { color: rgba(1 * 7, 2, 3, .5); }\n";
3168 12 : csspp::position pos("test.css");
3169 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
3170 :
3171 8 : csspp::parser p(l);
3172 :
3173 4 : csspp::node::pointer_t n(p.stylesheet());
3174 :
3175 : //std::cerr << "Parser result is: [" << *n << "]\n";
3176 :
3177 4 : csspp::compiler c;
3178 4 : c.set_root(n);
3179 4 : c.set_date_time_variables(csspp_test::get_now());
3180 4 : c.add_path(csspp_test::get_script_path());
3181 4 : c.add_path(csspp_test::get_version_script_path());
3182 :
3183 4 : c.compile(false);
3184 :
3185 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
3186 :
3187 4 : std::stringstream out;
3188 4 : csspp::assembler a(out);
3189 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
3190 :
3191 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
3192 :
3193 4 : std::stringstream expected;
3194 4 : switch(static_cast<csspp::output_mode_t>(i))
3195 : {
3196 1 : case csspp::output_mode_t::COMPACT:
3197 1 : expected << "a b { color: rgba(7,2,3,.5) }\n"; // TODO: add support for spaces in the color::to_string() function?
3198 1 : break;
3199 :
3200 1 : case csspp::output_mode_t::COMPRESSED:
3201 1 : expected << "a b{color:rgba(7,2,3,.5)}\n";
3202 1 : break;
3203 :
3204 1 : case csspp::output_mode_t::EXPANDED:
3205 : expected << "a b\n"
3206 : << "{\n"
3207 : << " color: rgba(7,2,3,.5);\n" // TODO: add support for spaces in the color::to_string() function?
3208 1 : << "}\n";
3209 1 : break;
3210 :
3211 1 : case csspp::output_mode_t::TIDY:
3212 1 : expected << "a b{color:rgba(7,2,3,.5)}\n";
3213 1 : break;
3214 :
3215 : }
3216 4 : expected << csspp_test::get_close_comment();
3217 4 : CATCH_REQUIRE(out.str() == expected.str());
3218 :
3219 4 : CATCH_REQUIRE(c.get_root() == n);
3220 4 : }
3221 :
3222 : // CSS Function which is not replaced by CSS Proprocessor
3223 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
3224 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
3225 : ++i)
3226 : {
3227 4 : std::stringstream ss;
3228 4 : ss << "a b { transform: translate(percentage(-.50px), 0); }\n";
3229 12 : csspp::position pos("test.css");
3230 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
3231 :
3232 8 : csspp::parser p(l);
3233 :
3234 4 : csspp::node::pointer_t n(p.stylesheet());
3235 :
3236 : //std::cerr << "Parser result is: [" << *n << "]\n";
3237 :
3238 4 : csspp::compiler c;
3239 4 : c.set_root(n);
3240 4 : c.set_date_time_variables(csspp_test::get_now());
3241 4 : c.add_path(csspp_test::get_script_path());
3242 4 : c.add_path(csspp_test::get_version_script_path());
3243 :
3244 4 : c.compile(false);
3245 :
3246 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
3247 :
3248 4 : std::stringstream out;
3249 4 : csspp::assembler a(out);
3250 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
3251 :
3252 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
3253 :
3254 4 : std::stringstream expected;
3255 4 : switch(static_cast<csspp::output_mode_t>(i))
3256 : {
3257 1 : case csspp::output_mode_t::COMPACT:
3258 1 : expected << "a b { transform: translate(-50%, 0) }\n";
3259 1 : break;
3260 :
3261 1 : case csspp::output_mode_t::COMPRESSED:
3262 1 : expected << "a b{transform:translate(-50%,0)}\n";
3263 1 : break;
3264 :
3265 1 : case csspp::output_mode_t::EXPANDED:
3266 : expected << "a b\n"
3267 : << "{\n"
3268 : << " transform: translate(-50%, 0);\n"
3269 1 : << "}\n";
3270 1 : break;
3271 :
3272 1 : case csspp::output_mode_t::TIDY:
3273 1 : expected << "a b{transform:translate(-50%,0)}\n";
3274 1 : break;
3275 :
3276 : }
3277 4 : expected << csspp_test::get_close_comment();
3278 4 : CATCH_REQUIRE(out.str() == expected.str());
3279 :
3280 4 : CATCH_REQUIRE(c.get_root() == n);
3281 4 : }
3282 :
3283 : // no error left over
3284 1 : VERIFY_ERRORS("");
3285 1 : }
3286 :
3287 1 : CATCH_TEST_CASE("Assemble placeholder", "[assembler] [placeholder]")
3288 : {
3289 : // Test with gradient() function
3290 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
3291 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
3292 : ++i)
3293 : {
3294 4 : std::stringstream ss;
3295 : ss << "$reddish: #e09756;\n"
3296 : << "#context a%extreme { color: blue; font-weight: bold; font-size: 2em }\n"
3297 4 : << ".error { color: $reddish }\n";
3298 12 : csspp::position pos("test.css");
3299 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
3300 :
3301 8 : csspp::parser p(l);
3302 :
3303 4 : csspp::node::pointer_t n(p.stylesheet());
3304 :
3305 : //std::cerr << "Parser result is: [" << *n << "]\n";
3306 :
3307 4 : csspp::compiler c;
3308 4 : c.set_root(n);
3309 4 : c.set_date_time_variables(csspp_test::get_now());
3310 4 : c.add_path(csspp_test::get_script_path());
3311 4 : c.add_path(csspp_test::get_version_script_path());
3312 :
3313 4 : c.compile(false);
3314 :
3315 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
3316 :
3317 4 : std::stringstream out;
3318 4 : csspp::assembler a(out);
3319 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
3320 :
3321 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
3322 :
3323 4 : std::stringstream expected;
3324 4 : switch(static_cast<csspp::output_mode_t>(i))
3325 : {
3326 1 : case csspp::output_mode_t::COMPACT:
3327 1 : expected << ".error { color: #e09756 }\n";
3328 1 : break;
3329 :
3330 1 : case csspp::output_mode_t::COMPRESSED:
3331 1 : expected << ".error{color:#e09756}\n";
3332 1 : break;
3333 :
3334 1 : case csspp::output_mode_t::EXPANDED:
3335 : expected << ".error\n"
3336 : << "{\n"
3337 : << " color: #e09756;\n"
3338 1 : << "}\n";
3339 1 : break;
3340 :
3341 1 : case csspp::output_mode_t::TIDY:
3342 1 : expected << ".error{color:#e09756}\n";
3343 1 : break;
3344 :
3345 : }
3346 4 : expected << csspp_test::get_close_comment();
3347 4 : CATCH_REQUIRE(out.str() == expected.str());
3348 :
3349 4 : CATCH_REQUIRE(c.get_root() == n);
3350 4 : }
3351 :
3352 : // no error left over
3353 1 : VERIFY_ERRORS("");
3354 1 : }
3355 :
3356 1 : CATCH_TEST_CASE("Assemble operators", "[assembler] [operators]")
3357 : {
3358 : // Selector unary operator
3359 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
3360 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
3361 : ++i)
3362 : {
3363 4 : std::stringstream ss;
3364 4 : ss << "a * b { color: red; }\n";
3365 12 : csspp::position pos("test.css");
3366 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
3367 :
3368 8 : csspp::parser p(l);
3369 :
3370 4 : csspp::node::pointer_t n(p.stylesheet());
3371 :
3372 4 : csspp::compiler c;
3373 4 : c.set_root(n);
3374 4 : c.set_date_time_variables(csspp_test::get_now());
3375 4 : c.add_path(csspp_test::get_script_path());
3376 4 : c.add_path(csspp_test::get_version_script_path());
3377 :
3378 4 : c.compile(false);
3379 :
3380 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
3381 :
3382 4 : std::stringstream out;
3383 4 : csspp::assembler a(out);
3384 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
3385 :
3386 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
3387 :
3388 4 : std::stringstream expected;
3389 4 : switch(static_cast<csspp::output_mode_t>(i))
3390 : {
3391 1 : case csspp::output_mode_t::COMPACT:
3392 1 : expected << "a * b { color: red }\n";
3393 1 : break;
3394 :
3395 1 : case csspp::output_mode_t::COMPRESSED:
3396 1 : expected << "a * b{color:red}\n";
3397 1 : break;
3398 :
3399 1 : case csspp::output_mode_t::EXPANDED:
3400 : expected << "a * b\n"
3401 : << "{\n"
3402 : << " color: red;\n"
3403 1 : << "}\n";
3404 1 : break;
3405 :
3406 1 : case csspp::output_mode_t::TIDY:
3407 1 : expected << "a * b{color:red}\n";
3408 1 : break;
3409 :
3410 : }
3411 4 : expected << csspp_test::get_close_comment();
3412 4 : CATCH_REQUIRE(out.str() == expected.str());
3413 :
3414 4 : CATCH_REQUIRE(c.get_root() == n);
3415 4 : }
3416 :
3417 : // Selector binary operators
3418 : {
3419 1 : char const * selector_operator[] =
3420 : {
3421 : "+",
3422 : "~",
3423 : ">"
3424 : };
3425 :
3426 4 : for(size_t op(0); op < sizeof(selector_operator) / sizeof(selector_operator[0]); ++op)
3427 : {
3428 15 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
3429 15 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
3430 : ++i)
3431 : {
3432 12 : std::stringstream ss;
3433 : ss << "a"
3434 24 : << ((rand() % 2) == 0 ? " " : "")
3435 : << selector_operator[op]
3436 24 : << ((rand() % 2) == 0 ? " " : "")
3437 12 : << "b { color: red; }\n";
3438 36 : csspp::position pos("test.css");
3439 12 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
3440 :
3441 24 : csspp::parser p(l);
3442 :
3443 12 : csspp::node::pointer_t n(p.stylesheet());
3444 :
3445 12 : csspp::compiler c;
3446 12 : c.set_root(n);
3447 12 : c.set_date_time_variables(csspp_test::get_now());
3448 12 : c.add_path(csspp_test::get_script_path());
3449 12 : c.add_path(csspp_test::get_version_script_path());
3450 :
3451 12 : c.compile(false);
3452 :
3453 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
3454 :
3455 12 : std::stringstream out;
3456 12 : csspp::assembler a(out);
3457 12 : a.output(n, static_cast<csspp::output_mode_t>(i));
3458 :
3459 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
3460 :
3461 12 : std::stringstream expected;
3462 12 : switch(static_cast<csspp::output_mode_t>(i))
3463 : {
3464 3 : case csspp::output_mode_t::COMPACT:
3465 3 : expected << "a " << selector_operator[op] << " b { color: red }\n";
3466 3 : break;
3467 :
3468 3 : case csspp::output_mode_t::COMPRESSED:
3469 3 : expected << "a" << selector_operator[op] << "b{color:red}\n";
3470 3 : break;
3471 :
3472 3 : case csspp::output_mode_t::EXPANDED:
3473 : expected << "a " << selector_operator[op] << " b\n"
3474 : << "{\n"
3475 : << " color: red;\n"
3476 3 : << "}\n";
3477 3 : break;
3478 :
3479 3 : case csspp::output_mode_t::TIDY:
3480 3 : expected << "a" << selector_operator[op] << "b{color:red}\n";
3481 3 : break;
3482 :
3483 : }
3484 12 : expected << csspp_test::get_close_comment();
3485 12 : CATCH_REQUIRE(out.str() == expected.str());
3486 :
3487 12 : CATCH_REQUIRE(c.get_root() == n);
3488 12 : }
3489 : }
3490 : }
3491 :
3492 : // Attributes binary operators
3493 : {
3494 1 : char const * attribute_operator[] =
3495 : {
3496 : "=",
3497 : "~=",
3498 : "^=",
3499 : "$=",
3500 : "*=",
3501 : "|="
3502 : };
3503 :
3504 7 : for(size_t op(0); op < sizeof(attribute_operator) / sizeof(attribute_operator[0]); ++op)
3505 : {
3506 30 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
3507 30 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
3508 : ++i)
3509 : {
3510 24 : std::stringstream ss;
3511 : ss << "a["
3512 48 : << ((rand() % 2) != 0 ? " " : "")
3513 : << "b"
3514 48 : << ((rand() % 2) != 0 ? " " : "")
3515 : << attribute_operator[op]
3516 48 : << ((rand() % 2) != 0 ? " " : "")
3517 : << "3"
3518 48 : << ((rand() % 2) != 0 ? " " : "")
3519 : << "]"
3520 48 : << ((rand() % 2) != 0 ? "\n" : "")
3521 : << "{"
3522 48 : << ((rand() % 2) != 0 ? " " : "")
3523 : << "color"
3524 48 : << ((rand() % 2) != 0 ? " " : "")
3525 : << ":"
3526 48 : << ((rand() % 2) != 0 ? " " : "")
3527 : << "red"
3528 48 : << ((rand() % 2) != 0 ? " " : "")
3529 24 : << "}\n";
3530 72 : csspp::position pos("test.css");
3531 24 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
3532 :
3533 48 : csspp::parser p(l);
3534 :
3535 24 : csspp::node::pointer_t n(p.stylesheet());
3536 :
3537 24 : csspp::compiler c;
3538 24 : c.set_root(n);
3539 24 : c.set_date_time_variables(csspp_test::get_now());
3540 24 : c.add_path(csspp_test::get_script_path());
3541 24 : c.add_path(csspp_test::get_version_script_path());
3542 :
3543 24 : c.compile(false);
3544 :
3545 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
3546 :
3547 24 : std::stringstream out;
3548 24 : csspp::assembler a(out);
3549 24 : a.output(n, static_cast<csspp::output_mode_t>(i));
3550 :
3551 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
3552 :
3553 24 : std::stringstream expected;
3554 24 : switch(static_cast<csspp::output_mode_t>(i))
3555 : {
3556 6 : case csspp::output_mode_t::COMPACT:
3557 6 : expected << "a[b " << attribute_operator[op] << " 3] { color: red }\n";
3558 6 : break;
3559 :
3560 6 : case csspp::output_mode_t::COMPRESSED:
3561 6 : expected << "a[b" << attribute_operator[op] << "3]{color:red}\n";
3562 6 : break;
3563 :
3564 6 : case csspp::output_mode_t::EXPANDED:
3565 : expected << "a[b " << attribute_operator[op] << " 3]\n"
3566 : "{\n"
3567 : " color: red;\n"
3568 6 : "}\n";
3569 6 : break;
3570 :
3571 6 : case csspp::output_mode_t::TIDY:
3572 6 : expected << "a[b" << attribute_operator[op] << "3]{color:red}\n";
3573 6 : break;
3574 :
3575 : }
3576 24 : expected << csspp_test::get_close_comment();
3577 24 : CATCH_REQUIRE(out.str() == expected.str());
3578 :
3579 24 : CATCH_REQUIRE(c.get_root() == n);
3580 24 : }
3581 : }
3582 : }
3583 :
3584 : // '!' -- EXCLAMATION
3585 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
3586 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
3587 : ++i)
3588 : {
3589 4 : std::stringstream ss;
3590 : ss << "*[b = 3] { color : red !"
3591 8 : << ((rand() % 2) == 0 ? " " : "")
3592 4 : << "important; }";
3593 12 : csspp::position pos("test.css");
3594 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
3595 :
3596 8 : csspp::parser p(l);
3597 :
3598 4 : csspp::node::pointer_t n(p.stylesheet());
3599 :
3600 4 : csspp::compiler c;
3601 4 : c.set_root(n);
3602 4 : c.set_date_time_variables(csspp_test::get_now());
3603 4 : c.add_path(csspp_test::get_script_path());
3604 4 : c.add_path(csspp_test::get_version_script_path());
3605 :
3606 4 : c.compile(false);
3607 :
3608 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
3609 :
3610 4 : std::stringstream out;
3611 4 : csspp::assembler a(out);
3612 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
3613 :
3614 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
3615 :
3616 4 : switch(static_cast<csspp::output_mode_t>(i))
3617 : {
3618 1 : case csspp::output_mode_t::COMPACT:
3619 1 : CATCH_REQUIRE(out.str() ==
3620 : "[b = 3] { color: red !important }\n"
3621 : + csspp_test::get_close_comment()
3622 : );
3623 1 : break;
3624 :
3625 1 : case csspp::output_mode_t::COMPRESSED:
3626 1 : CATCH_REQUIRE(out.str() ==
3627 : "[b=3]{color:red!important}\n"
3628 : + csspp_test::get_close_comment()
3629 : );
3630 1 : break;
3631 :
3632 1 : case csspp::output_mode_t::EXPANDED:
3633 1 : CATCH_REQUIRE(out.str() ==
3634 : "[b = 3]\n"
3635 : "{\n"
3636 : " color: red !important;\n"
3637 : "}\n"
3638 : + csspp_test::get_close_comment()
3639 : );
3640 1 : break;
3641 :
3642 1 : case csspp::output_mode_t::TIDY:
3643 1 : CATCH_REQUIRE(out.str() ==
3644 : "[b=3]{color:red!important}\n"
3645 : + csspp_test::get_close_comment()
3646 : );
3647 1 : break;
3648 :
3649 : }
3650 :
3651 4 : CATCH_REQUIRE(c.get_root() == n);
3652 4 : }
3653 :
3654 : // no error left over
3655 1 : VERIFY_ERRORS("");
3656 1 : }
3657 :
3658 1 : CATCH_TEST_CASE("Assembler modes", "[assembler] [mode]")
3659 : {
3660 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
3661 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
3662 : ++i)
3663 : {
3664 4 : std::stringstream ss;
3665 4 : ss << static_cast<csspp::output_mode_t>(i);
3666 :
3667 4 : switch(static_cast<csspp::output_mode_t>(i))
3668 : {
3669 1 : case csspp::output_mode_t::COMPACT:
3670 1 : CATCH_REQUIRE(ss.str() == "COMPACT");
3671 1 : break;
3672 :
3673 1 : case csspp::output_mode_t::COMPRESSED:
3674 1 : CATCH_REQUIRE(ss.str() == "COMPRESSED");
3675 1 : break;
3676 :
3677 1 : case csspp::output_mode_t::EXPANDED:
3678 1 : CATCH_REQUIRE(ss.str() == "EXPANDED");
3679 1 : break;
3680 :
3681 1 : case csspp::output_mode_t::TIDY:
3682 1 : CATCH_REQUIRE(ss.str() == "TIDY");
3683 1 : break;
3684 :
3685 : }
3686 4 : }
3687 :
3688 : // no error left over
3689 1 : VERIFY_ERRORS("");
3690 1 : }
3691 :
3692 1 : CATCH_TEST_CASE("Invalid assembler mode", "[assembler] [mode] [invalid]")
3693 : {
3694 : // with many spaces
3695 101 : for(int i(0); i < 100; ++i)
3696 : {
3697 100 : std::stringstream out;
3698 100 : csspp::assembler a(out);
3699 300 : csspp::position pos("test.css");
3700 100 : csspp::node::pointer_t n(new csspp::node(csspp::node_type_t::LIST, pos));
3701 100 : csspp::output_mode_t mode(static_cast<csspp::output_mode_t>(rand()));
3702 100 : while(is_valid_mode(mode))
3703 : {
3704 0 : mode = static_cast<csspp::output_mode_t>(rand());
3705 : }
3706 300 : CATCH_REQUIRE_THROWS_AS(a.output(n, mode), csspp::csspp_exception_logic);
3707 100 : }
3708 :
3709 : // no error left over
3710 1 : VERIFY_ERRORS("");
3711 1 : }
3712 :
3713 1 : CATCH_TEST_CASE("Inacceptable nodes", "[assembler] [invalid]")
3714 : {
3715 : // list of "invalid" nodes in the assembler
3716 1 : csspp::node_type_t node_types[] =
3717 : {
3718 : csspp::node_type_t::UNKNOWN,
3719 : csspp::node_type_t::AND,
3720 : csspp::node_type_t::ASSIGNMENT,
3721 : csspp::node_type_t::BOOLEAN,
3722 : csspp::node_type_t::CDC,
3723 : csspp::node_type_t::CDO,
3724 : csspp::node_type_t::CLOSE_CURLYBRACKET,
3725 : csspp::node_type_t::CLOSE_PARENTHESIS,
3726 : csspp::node_type_t::CLOSE_SQUAREBRACKET,
3727 : csspp::node_type_t::COLUMN,
3728 : csspp::node_type_t::COMMA,
3729 : csspp::node_type_t::CONDITIONAL,
3730 : csspp::node_type_t::DOLLAR,
3731 : csspp::node_type_t::EOF_TOKEN,
3732 : csspp::node_type_t::EXCLAMATION,
3733 : csspp::node_type_t::GREATER_EQUAL,
3734 : csspp::node_type_t::LESS_EQUAL,
3735 : csspp::node_type_t::LESS_THAN,
3736 : csspp::node_type_t::MODULO,
3737 : csspp::node_type_t::NOT_EQUAL,
3738 : csspp::node_type_t::NULL_TOKEN,
3739 : csspp::node_type_t::PLACEHOLDER,
3740 : csspp::node_type_t::POWER,
3741 : csspp::node_type_t::REFERENCE,
3742 : csspp::node_type_t::SEMICOLON,
3743 : csspp::node_type_t::VARIABLE,
3744 : csspp::node_type_t::VARIABLE_FUNCTION,
3745 : csspp::node_type_t::max_type
3746 : };
3747 :
3748 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
3749 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
3750 : ++i)
3751 : {
3752 116 : for(size_t j(0); j < sizeof(node_types) / sizeof(node_types[0]); ++j)
3753 : {
3754 336 : csspp::position pos("test.css");
3755 112 : csspp::node::pointer_t root(new csspp::node(node_types[j], pos));
3756 :
3757 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
3758 :
3759 112 : std::stringstream out;
3760 112 : csspp::assembler a(out);
3761 336 : CATCH_REQUIRE_THROWS_AS(a.output(root, static_cast<csspp::output_mode_t>(i)), csspp::csspp_exception_logic);
3762 112 : }
3763 : }
3764 1 : }
3765 :
3766 1 : CATCH_TEST_CASE("CSS incompatible dimensions", "[assembler] [invalid] [dimension]")
3767 : {
3768 5 : for(int i(static_cast<int>(csspp::output_mode_t::COMPACT));
3769 5 : i <= static_cast<int>(csspp::output_mode_t::TIDY);
3770 : ++i)
3771 : {
3772 4 : std::stringstream ss;
3773 4 : ss << "span { border: 3px * 5px solid #f7d0cf; }";
3774 12 : csspp::position pos("test.css");
3775 4 : csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
3776 :
3777 8 : csspp::parser p(l);
3778 :
3779 4 : csspp::node::pointer_t n(p.stylesheet());
3780 :
3781 4 : csspp::compiler c;
3782 4 : c.set_root(n);
3783 4 : c.set_date_time_variables(csspp_test::get_now());
3784 4 : c.add_path(csspp_test::get_script_path());
3785 4 : c.add_path(csspp_test::get_version_script_path());
3786 :
3787 4 : c.compile(false);
3788 :
3789 : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
3790 :
3791 : // no errors yet
3792 4 : VERIFY_ERRORS("");
3793 :
3794 4 : std::stringstream out;
3795 4 : csspp::assembler a(out);
3796 4 : a.output(n, static_cast<csspp::output_mode_t>(i));
3797 :
3798 : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
3799 :
3800 4 : VERIFY_ERRORS("test.css(1): error: \"px * px\" is not a valid CSS dimension.\n");
3801 :
3802 4 : CATCH_REQUIRE(c.get_root() == n);
3803 4 : }
3804 :
3805 : // no error left over
3806 1 : VERIFY_ERRORS("");
3807 1 : }
3808 :
3809 : // vim: ts=4 sw=4 et
|