LCOV - code coverage report
Current view: top level - tests - catch_expr_multiplicative.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2507 2507 100.0 %
Date: 2023-11-01 21:56:19 Functions: 13 13 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2015-2022  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // This program is free software; you can redistribute it and/or modify
       4             : // it under the terms of the GNU General Public License as published by
       5             : // the Free Software Foundation; either version 2 of the License, or
       6             : // (at your option) any later version.
       7             : //
       8             : // This program is distributed in the hope that it will be useful,
       9             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      10             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      11             : // GNU General Public License for more details.
      12             : //
      13             : // You should have received a copy of the GNU General Public License along
      14             : // with this program; if not, write to the Free Software Foundation, Inc.,
      15             : // 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      16             : 
      17             : /** \file
      18             :  * \brief Test the expression.cpp file: "*", "/", and "%" operators.
      19             :  *
      20             :  * This test runs a battery of tests agains the expression.cpp "*", "/",
      21             :  * and "%" operators to ensure full coverage and that all possible left
      22             :  * hand side and right hand side types are checked for the multiplicative
      23             :  * CSS Preprocessor extensions.
      24             :  *
      25             :  * Note that all the tests use the full chain: lexer, parser, compiler,
      26             :  * and assembler to make sure the results are correct. So these tests
      27             :  * exercise the assembler even more than the assembler tests, except that
      28             :  * it only checks that compressed results are correct instead of all
      29             :  * output modes, since its only goal is covering all the possible
      30             :  * expression cases and not the assembler, compiler, parser, and lexer
      31             :  * classes.
      32             :  */
      33             : 
      34             : // csspp
      35             : //
      36             : #include    <csspp/assembler.h>
      37             : #include    <csspp/compiler.h>
      38             : #include    <csspp/exception.h>
      39             : #include    <csspp/parser.h>
      40             : 
      41             : 
      42             : // self
      43             : //
      44             : #include    "catch_main.h"
      45             : 
      46             : 
      47             : // C++
      48             : //
      49             : #include    <sstream>
      50             : 
      51             : 
      52             : // last include
      53             : //
      54             : #include    <snapdev/poison.h>
      55             : 
      56             : 
      57             : 
      58          13 : CATCH_TEST_CASE("Expression integer *,/,% integer", "[expression] [multiplicative]")
      59             : {
      60          13 :     CATCH_START_SECTION("multiple sizes without dimensions (*)")
      61             :     {
      62           1 :         std::stringstream ss;
      63           1 :         ss << "div { z-index: 3 * 10; }";
      64           3 :         csspp::position pos("test.css");
      65           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
      66             : 
      67           2 :         csspp::parser p(l);
      68             : 
      69           1 :         csspp::node::pointer_t n(p.stylesheet());
      70             : 
      71           1 :         csspp::compiler c;
      72           1 :         c.set_root(n);
      73           1 :         c.set_date_time_variables(csspp_test::get_now());
      74           1 :         c.add_path(csspp_test::get_script_path());
      75           1 :         c.add_path(csspp_test::get_version_script_path());
      76             : 
      77           1 :         c.compile(false);
      78             : 
      79             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
      80             : 
      81             :         // to verify that the result is still an INTEGER we have to
      82             :         // test the root node here
      83           1 :         std::stringstream compiler_out;
      84           1 :         compiler_out << *n;
      85           1 :         VERIFY_TREES(compiler_out.str(),
      86             : 
      87             : "LIST\n"
      88             : + csspp_test::get_default_variables() +
      89             : "  COMPONENT_VALUE\n"
      90             : "    ARG\n"
      91             : "      IDENTIFIER \"div\"\n"
      92             : "    OPEN_CURLYBRACKET B:true\n"
      93             : "      DECLARATION \"z-index\"\n"
      94             : "        ARG\n"
      95             : "          INTEGER \"\" I:30\n"
      96             : + csspp_test::get_close_comment(true)
      97             : 
      98             :             );
      99             : 
     100           1 :         std::stringstream assembler_out;
     101           1 :         csspp::assembler a(assembler_out);
     102           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     103             : 
     104             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     105             : 
     106           1 :         CATCH_REQUIRE(assembler_out.str() ==
     107             : "div{z-index:30}\n"
     108             : + csspp_test::get_close_comment()
     109             :                 );
     110             : 
     111           1 :         CATCH_REQUIRE(c.get_root() == n);
     112           1 :     }
     113          13 :     CATCH_END_SECTION()
     114             : 
     115          13 :     CATCH_START_SECTION("multiple sizes without dimensions (mul)")
     116             :     {
     117           1 :         std::stringstream ss;
     118           1 :         ss << "div { z-index: 3 mul 10; }";
     119           3 :         csspp::position pos("test.css");
     120           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     121             : 
     122           2 :         csspp::parser p(l);
     123             : 
     124           1 :         csspp::node::pointer_t n(p.stylesheet());
     125             : 
     126           1 :         csspp::compiler c;
     127           1 :         c.set_root(n);
     128           1 :         c.set_date_time_variables(csspp_test::get_now());
     129           1 :         c.add_path(csspp_test::get_script_path());
     130           1 :         c.add_path(csspp_test::get_version_script_path());
     131             : 
     132           1 :         c.compile(false);
     133             : 
     134             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     135             : 
     136             :         // to verify that the result is still an INTEGER we have to
     137             :         // test the root node here
     138           1 :         std::stringstream compiler_out;
     139           1 :         compiler_out << *n;
     140           1 :         VERIFY_TREES(compiler_out.str(),
     141             : 
     142             : "LIST\n"
     143             : + csspp_test::get_default_variables() +
     144             : "  COMPONENT_VALUE\n"
     145             : "    ARG\n"
     146             : "      IDENTIFIER \"div\"\n"
     147             : "    OPEN_CURLYBRACKET B:true\n"
     148             : "      DECLARATION \"z-index\"\n"
     149             : "        ARG\n"
     150             : "          INTEGER \"\" I:30\n"
     151             : + csspp_test::get_close_comment(true)
     152             : 
     153             :             );
     154             : 
     155           1 :         std::stringstream assembler_out;
     156           1 :         csspp::assembler a(assembler_out);
     157           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     158             : 
     159             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     160             : 
     161           1 :         CATCH_REQUIRE(assembler_out.str() ==
     162             : "div{z-index:30}\n"
     163             : + csspp_test::get_close_comment()
     164             :                 );
     165             : 
     166           1 :         CATCH_REQUIRE(c.get_root() == n);
     167           1 :     }
     168          13 :     CATCH_END_SECTION()
     169             : 
     170          13 :     CATCH_START_SECTION("divide sizes without dimensions (/)")
     171             :     {
     172           1 :         std::stringstream ss;
     173           1 :         ss << "div { z-index: 10 / 3; }";
     174           3 :         csspp::position pos("test.css");
     175           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     176             : 
     177           2 :         csspp::parser p(l);
     178             : 
     179           1 :         csspp::node::pointer_t n(p.stylesheet());
     180             : 
     181           1 :         csspp::compiler c;
     182           1 :         c.set_root(n);
     183           1 :         c.set_date_time_variables(csspp_test::get_now());
     184           1 :         c.add_path(csspp_test::get_script_path());
     185           1 :         c.add_path(csspp_test::get_version_script_path());
     186             : 
     187           1 :         c.compile(false);
     188             : 
     189             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     190             : 
     191             :         // to verify that the result is still an INTEGER we have to
     192             :         // test the root node here
     193           1 :         std::stringstream compiler_out;
     194           1 :         compiler_out << *n;
     195           1 :         VERIFY_TREES(compiler_out.str(),
     196             : 
     197             : "LIST\n"
     198             : + csspp_test::get_default_variables() +
     199             : "  COMPONENT_VALUE\n"
     200             : "    ARG\n"
     201             : "      IDENTIFIER \"div\"\n"
     202             : "    OPEN_CURLYBRACKET B:true\n"
     203             : "      DECLARATION \"z-index\"\n"
     204             : "        ARG\n"
     205             : "          INTEGER \"\" I:3\n"
     206             : + csspp_test::get_close_comment(true)
     207             : 
     208             :             );
     209             : 
     210           1 :         std::stringstream assembler_out;
     211           1 :         csspp::assembler a(assembler_out);
     212           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     213             : 
     214             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     215             : 
     216           1 :         CATCH_REQUIRE(assembler_out.str() ==
     217             : "div{z-index:3}\n"
     218             : + csspp_test::get_close_comment()
     219             :                 );
     220             : 
     221           1 :         CATCH_REQUIRE(c.get_root() == n);
     222           1 :     }
     223          13 :     CATCH_END_SECTION()
     224             : 
     225          13 :     CATCH_START_SECTION("divide sizes without dimensions (div)")
     226             :     {
     227           1 :         std::stringstream ss;
     228           1 :         ss << "div { z-index: 10 div 3; }";
     229           3 :         csspp::position pos("test.css");
     230           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     231             : 
     232           2 :         csspp::parser p(l);
     233             : 
     234           1 :         csspp::node::pointer_t n(p.stylesheet());
     235             : 
     236           1 :         csspp::compiler c;
     237           1 :         c.set_root(n);
     238           1 :         c.set_date_time_variables(csspp_test::get_now());
     239           1 :         c.add_path(csspp_test::get_script_path());
     240           1 :         c.add_path(csspp_test::get_version_script_path());
     241             : 
     242           1 :         c.compile(false);
     243             : 
     244             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     245             : 
     246             :         // to verify that the result is still an INTEGER we have to
     247             :         // test the root node here
     248           1 :         std::stringstream compiler_out;
     249           1 :         compiler_out << *n;
     250           1 :         VERIFY_TREES(compiler_out.str(),
     251             : 
     252             : "LIST\n"
     253             : + csspp_test::get_default_variables() +
     254             : "  COMPONENT_VALUE\n"
     255             : "    ARG\n"
     256             : "      IDENTIFIER \"div\"\n"
     257             : "    OPEN_CURLYBRACKET B:true\n"
     258             : "      DECLARATION \"z-index\"\n"
     259             : "        ARG\n"
     260             : "          INTEGER \"\" I:3\n"
     261             : + csspp_test::get_close_comment(true)
     262             : 
     263             :             );
     264             : 
     265           1 :         std::stringstream assembler_out;
     266           1 :         csspp::assembler a(assembler_out);
     267           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     268             : 
     269             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     270             : 
     271           1 :         CATCH_REQUIRE(assembler_out.str() ==
     272             : "div{z-index:3}\n"
     273             : + csspp_test::get_close_comment()
     274             :                 );
     275             : 
     276           1 :         CATCH_REQUIRE(c.get_root() == n);
     277           1 :     }
     278          13 :     CATCH_END_SECTION()
     279             : 
     280          13 :     CATCH_START_SECTION("modulo sizes without dimensions (%)")
     281             :     {
     282           1 :         std::stringstream ss;
     283           1 :         ss << "div { z-index: 10 % 3; }";
     284           3 :         csspp::position pos("test.css");
     285           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     286             : 
     287           2 :         csspp::parser p(l);
     288             : 
     289           1 :         csspp::node::pointer_t n(p.stylesheet());
     290             : 
     291           1 :         csspp::compiler c;
     292           1 :         c.set_root(n);
     293           1 :         c.set_date_time_variables(csspp_test::get_now());
     294           1 :         c.add_path(csspp_test::get_script_path());
     295           1 :         c.add_path(csspp_test::get_version_script_path());
     296             : 
     297           1 :         c.compile(false);
     298             : 
     299             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     300             : 
     301             :         // to verify that the result is still an INTEGER we have to
     302             :         // test the root node here
     303           1 :         std::stringstream compiler_out;
     304           1 :         compiler_out << *n;
     305           1 :         VERIFY_TREES(compiler_out.str(),
     306             : 
     307             : "LIST\n"
     308             : + csspp_test::get_default_variables() +
     309             : "  COMPONENT_VALUE\n"
     310             : "    ARG\n"
     311             : "      IDENTIFIER \"div\"\n"
     312             : "    OPEN_CURLYBRACKET B:true\n"
     313             : "      DECLARATION \"z-index\"\n"
     314             : "        ARG\n"
     315             : "          INTEGER \"\" I:1\n"
     316             : + csspp_test::get_close_comment(true)
     317             : 
     318             :             );
     319             : 
     320           1 :         std::stringstream assembler_out;
     321           1 :         csspp::assembler a(assembler_out);
     322           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     323             : 
     324             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     325             : 
     326           1 :         CATCH_REQUIRE(assembler_out.str() ==
     327             : "div{z-index:1}\n"
     328             : + csspp_test::get_close_comment()
     329             :                 );
     330             : 
     331           1 :         CATCH_REQUIRE(c.get_root() == n);
     332           1 :     }
     333          13 :     CATCH_END_SECTION()
     334             : 
     335          13 :     CATCH_START_SECTION("modulo sizes without dimensions (mod)")
     336             :     {
     337           1 :         std::stringstream ss;
     338           1 :         ss << "div { z-index: 10 mod 3; }";
     339           3 :         csspp::position pos("test.css");
     340           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     341             : 
     342           2 :         csspp::parser p(l);
     343             : 
     344           1 :         csspp::node::pointer_t n(p.stylesheet());
     345             : 
     346           1 :         csspp::compiler c;
     347           1 :         c.set_root(n);
     348           1 :         c.set_date_time_variables(csspp_test::get_now());
     349           1 :         c.add_path(csspp_test::get_script_path());
     350           1 :         c.add_path(csspp_test::get_version_script_path());
     351             : 
     352           1 :         c.compile(false);
     353             : 
     354             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     355             : 
     356             :         // to verify that the result is still an INTEGER we have to
     357             :         // test the root node here
     358           1 :         std::stringstream compiler_out;
     359           1 :         compiler_out << *n;
     360           1 :         VERIFY_TREES(compiler_out.str(),
     361             : 
     362             : "LIST\n"
     363             : + csspp_test::get_default_variables() +
     364             : "  COMPONENT_VALUE\n"
     365             : "    ARG\n"
     366             : "      IDENTIFIER \"div\"\n"
     367             : "    OPEN_CURLYBRACKET B:true\n"
     368             : "      DECLARATION \"z-index\"\n"
     369             : "        ARG\n"
     370             : "          INTEGER \"\" I:1\n"
     371             : + csspp_test::get_close_comment(true)
     372             : 
     373             :             );
     374             : 
     375           1 :         std::stringstream assembler_out;
     376           1 :         csspp::assembler a(assembler_out);
     377           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     378             : 
     379             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     380             : 
     381           1 :         CATCH_REQUIRE(assembler_out.str() ==
     382             : "div{z-index:1}\n"
     383             : + csspp_test::get_close_comment()
     384             :                 );
     385             : 
     386           1 :         CATCH_REQUIRE(c.get_root() == n);
     387           1 :     }
     388          13 :     CATCH_END_SECTION()
     389             : 
     390          13 :     CATCH_START_SECTION("remove dimension (simple divide)")
     391             :     {
     392           1 :         std::stringstream ss;
     393           1 :         ss << "div { width: 3px / 1px; }";
     394           3 :         csspp::position pos("test.css");
     395           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     396             : 
     397           2 :         csspp::parser p(l);
     398             : 
     399           1 :         csspp::node::pointer_t n(p.stylesheet());
     400             : 
     401           1 :         csspp::compiler c;
     402           1 :         c.set_root(n);
     403           1 :         c.set_date_time_variables(csspp_test::get_now());
     404           1 :         c.add_path(csspp_test::get_script_path());
     405           1 :         c.add_path(csspp_test::get_version_script_path());
     406             : 
     407           1 :         c.compile(false);
     408             : 
     409             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     410             : 
     411             :         // to verify that the result is still an INTEGER we have to
     412             :         // test the root node here
     413           1 :         std::stringstream compiler_out;
     414           1 :         compiler_out << *n;
     415           1 :         VERIFY_TREES(compiler_out.str(),
     416             : 
     417             : "LIST\n"
     418             : + csspp_test::get_default_variables() +
     419             : "  COMPONENT_VALUE\n"
     420             : "    ARG\n"
     421             : "      IDENTIFIER \"div\"\n"
     422             : "    OPEN_CURLYBRACKET B:true\n"
     423             : "      DECLARATION \"width\"\n"
     424             : "        ARG\n"
     425             : "          INTEGER \"\" I:3\n"
     426             : + csspp_test::get_close_comment(true)
     427             : 
     428             :             );
     429             : 
     430           1 :         std::stringstream out;
     431           1 :         csspp::assembler a(out);
     432           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     433             : 
     434             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     435             : 
     436           1 :         CATCH_REQUIRE(out.str() ==
     437             : "div{width:3}\n"
     438             : + csspp_test::get_close_comment()
     439             :                 );
     440             : 
     441           1 :         CATCH_REQUIRE(c.get_root() == n);
     442           1 :     }
     443          13 :     CATCH_END_SECTION()
     444             : 
     445          13 :     CATCH_START_SECTION("convert px to em (multiple + divide)")
     446             :     {
     447           1 :         std::stringstream ss;
     448           1 :         ss << "div { width: 3px * 10em / 1px; }";
     449           3 :         csspp::position pos("test.css");
     450           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     451             : 
     452           2 :         csspp::parser p(l);
     453             : 
     454           1 :         csspp::node::pointer_t n(p.stylesheet());
     455             : 
     456           1 :         csspp::compiler c;
     457           1 :         c.set_root(n);
     458           1 :         c.set_date_time_variables(csspp_test::get_now());
     459           1 :         c.add_path(csspp_test::get_script_path());
     460           1 :         c.add_path(csspp_test::get_version_script_path());
     461             : 
     462           1 :         c.compile(false);
     463             : 
     464             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     465             : 
     466             :         // to verify that the result is still an INTEGER we have to
     467             :         // test the root node here
     468           1 :         std::stringstream compiler_out;
     469           1 :         compiler_out << *n;
     470           1 :         VERIFY_TREES(compiler_out.str(),
     471             : 
     472             : "LIST\n"
     473             : + csspp_test::get_default_variables() +
     474             : "  COMPONENT_VALUE\n"
     475             : "    ARG\n"
     476             : "      IDENTIFIER \"div\"\n"
     477             : "    OPEN_CURLYBRACKET B:true\n"
     478             : "      DECLARATION \"width\"\n"
     479             : "        ARG\n"
     480             : "          INTEGER \"em\" I:30\n"
     481             : + csspp_test::get_close_comment(true)
     482             : 
     483             :             );
     484             : 
     485           1 :         std::stringstream out;
     486           1 :         csspp::assembler a(out);
     487           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     488             : 
     489             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     490             : 
     491           1 :         CATCH_REQUIRE(out.str() ==
     492             : "div{width:30em}\n"
     493             : + csspp_test::get_close_comment()
     494             :                 );
     495             : 
     496           1 :         CATCH_REQUIRE(c.get_root() == n);
     497           1 :     }
     498          13 :     CATCH_END_SECTION()
     499             : 
     500          13 :     CATCH_START_SECTION("operation going through a unit less dividend")
     501             :     {
     502           1 :         std::stringstream ss;
     503           1 :         ss << "div { width: 30px / 1px / 10 * 10cm; }";
     504           3 :         csspp::position pos("test.css");
     505           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     506             : 
     507           2 :         csspp::parser p(l);
     508             : 
     509           1 :         csspp::node::pointer_t n(p.stylesheet());
     510             : 
     511           1 :         csspp::compiler c;
     512           1 :         c.set_root(n);
     513           1 :         c.set_date_time_variables(csspp_test::get_now());
     514           1 :         c.add_path(csspp_test::get_script_path());
     515           1 :         c.add_path(csspp_test::get_version_script_path());
     516             : 
     517           1 :         c.compile(false);
     518             : 
     519             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     520             : 
     521             :         // to verify that the result is still an INTEGER we have to
     522             :         // test the root node here
     523           1 :         std::stringstream compiler_out;
     524           1 :         compiler_out << *n;
     525           1 :         VERIFY_TREES(compiler_out.str(),
     526             : 
     527             : "LIST\n"
     528             : + csspp_test::get_default_variables() +
     529             : "  COMPONENT_VALUE\n"
     530             : "    ARG\n"
     531             : "      IDENTIFIER \"div\"\n"
     532             : "    OPEN_CURLYBRACKET B:true\n"
     533             : "      DECLARATION \"width\"\n"
     534             : "        ARG\n"
     535             : "          INTEGER \"cm\" I:30\n"
     536             : + csspp_test::get_close_comment(true)
     537             : 
     538             :             );
     539             : 
     540           1 :         std::stringstream out;
     541           1 :         csspp::assembler a(out);
     542           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     543             : 
     544             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     545             : 
     546           1 :         CATCH_REQUIRE(out.str() ==
     547             : "div{width:30cm}\n"
     548             : + csspp_test::get_close_comment()
     549             :                 );
     550             : 
     551           1 :         CATCH_REQUIRE(c.get_root() == n);
     552           1 :     }
     553          13 :     CATCH_END_SECTION()
     554             : 
     555          13 :     CATCH_START_SECTION("complex operations with unitless dividend")
     556             :     {
     557           1 :         std::stringstream ss;
     558           1 :         ss << "div { width: 3px * 10em / 1px / 5em / 2vw * 3em * 5vw; }";
     559           3 :         csspp::position pos("test.css");
     560           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     561             : 
     562           2 :         csspp::parser p(l);
     563             : 
     564           1 :         csspp::node::pointer_t n(p.stylesheet());
     565             : 
     566           1 :         csspp::compiler c;
     567           1 :         c.set_root(n);
     568           1 :         c.set_date_time_variables(csspp_test::get_now());
     569           1 :         c.add_path(csspp_test::get_script_path());
     570           1 :         c.add_path(csspp_test::get_version_script_path());
     571             : 
     572           1 :         c.compile(false);
     573             : 
     574             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     575             : 
     576             :         // to verify that the result is still an INTEGER we have to
     577             :         // test the root node here
     578           1 :         std::stringstream compiler_out;
     579           1 :         compiler_out << *n;
     580           1 :         VERIFY_TREES(compiler_out.str(),
     581             : 
     582             : "LIST\n"
     583             : + csspp_test::get_default_variables() +
     584             : "  COMPONENT_VALUE\n"
     585             : "    ARG\n"
     586             : "      IDENTIFIER \"div\"\n"
     587             : "    OPEN_CURLYBRACKET B:true\n"
     588             : "      DECLARATION \"width\"\n"
     589             : "        ARG\n"
     590             : "          INTEGER \"em\" I:45\n"
     591             : + csspp_test::get_close_comment(true)
     592             : 
     593             :             );
     594             : 
     595           1 :         std::stringstream out;
     596           1 :         csspp::assembler a(out);
     597           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     598             : 
     599             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     600             : 
     601           1 :         CATCH_REQUIRE(out.str() ==
     602             : "div{width:45em}\n"
     603             : + csspp_test::get_close_comment()
     604             :                 );
     605             : 
     606           1 :         CATCH_REQUIRE(c.get_root() == n);
     607           1 :     }
     608          13 :     CATCH_END_SECTION()
     609             : 
     610          13 :     CATCH_START_SECTION("many divisions with many dimension, then multiplications")
     611             :     {
     612           1 :         std::stringstream ss;
     613           1 :         ss << "div { width: 60 / 5px / 3em / 2vw * 3em * 5vw * 2px * 3px; }";
     614           3 :         csspp::position pos("test.css");
     615           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     616             : 
     617           2 :         csspp::parser p(l);
     618             : 
     619           1 :         csspp::node::pointer_t n(p.stylesheet());
     620             : 
     621           1 :         csspp::compiler c;
     622           1 :         c.set_root(n);
     623           1 :         c.set_date_time_variables(csspp_test::get_now());
     624           1 :         c.add_path(csspp_test::get_script_path());
     625           1 :         c.add_path(csspp_test::get_version_script_path());
     626             : 
     627           1 :         c.compile(false);
     628             : 
     629             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     630             : 
     631             :         // to verify that the result is still an INTEGER we have to
     632             :         // test the root node here
     633           1 :         std::stringstream compiler_out;
     634           1 :         compiler_out << *n;
     635           1 :         VERIFY_TREES(compiler_out.str(),
     636             : 
     637             : "LIST\n"
     638             : + csspp_test::get_default_variables() +
     639             : "  COMPONENT_VALUE\n"
     640             : "    ARG\n"
     641             : "      IDENTIFIER \"div\"\n"
     642             : "    OPEN_CURLYBRACKET B:true\n"
     643             : "      DECLARATION \"width\"\n"
     644             : "        ARG\n"
     645             : "          INTEGER \"px\" I:180\n"
     646             : + csspp_test::get_close_comment(true)
     647             : 
     648             :             );
     649             : 
     650           1 :         std::stringstream out;
     651           1 :         csspp::assembler a(out);
     652           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     653             : 
     654             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     655             : 
     656           1 :         CATCH_REQUIRE(out.str() ==
     657             : "div{width:180px}\n"
     658             : + csspp_test::get_close_comment()
     659             :                 );
     660             : 
     661           1 :         CATCH_REQUIRE(c.get_root() == n);
     662           1 :     }
     663          13 :     CATCH_END_SECTION()
     664             : 
     665          13 :     CATCH_START_SECTION("many multiplications and divisions with differen dimensions")
     666             :     {
     667           1 :         std::stringstream ss;
     668             :         // first we get "deg * px * em * vw / pt * rad * cm * mm" then
     669             :         // we clean that up and get 1
     670           1 :         ss << "div { width: (60deg * 5px * 3em * 2vw / 3pt / 5rad / 2cm / 3mm) / (60deg * 5px * 3em * 2vw / 3pt / 5rad / 2cm / 3mm); }";
     671           3 :         csspp::position pos("test.css");
     672           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     673             : 
     674           2 :         csspp::parser p(l);
     675             : 
     676           1 :         csspp::node::pointer_t n(p.stylesheet());
     677             : 
     678             : //std::cerr << "Parser result is: [" << *n << "]\n";
     679             : 
     680           1 :         csspp::compiler c;
     681           1 :         c.set_root(n);
     682           1 :         c.set_date_time_variables(csspp_test::get_now());
     683           1 :         c.add_path(csspp_test::get_script_path());
     684           1 :         c.add_path(csspp_test::get_version_script_path());
     685             : 
     686           1 :         c.compile(false);
     687             : 
     688             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     689             : 
     690             :         // to verify that the result is still an INTEGER we have to
     691             :         // test the root node here
     692           1 :         std::stringstream compiler_out;
     693           1 :         compiler_out << *n;
     694           1 :         VERIFY_TREES(compiler_out.str(),
     695             : 
     696             : "LIST\n"
     697             : + csspp_test::get_default_variables() +
     698             : "  COMPONENT_VALUE\n"
     699             : "    ARG\n"
     700             : "      IDENTIFIER \"div\"\n"
     701             : "    OPEN_CURLYBRACKET B:true\n"
     702             : "      DECLARATION \"width\"\n"
     703             : "        ARG\n"
     704             : "          INTEGER \"\" I:1\n"
     705             : + csspp_test::get_close_comment(true)
     706             : 
     707             :             );
     708             : 
     709           1 :         std::stringstream out;
     710           1 :         csspp::assembler a(out);
     711           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     712             : 
     713             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     714             : 
     715           1 :         CATCH_REQUIRE(out.str() ==
     716             : "div{width:1}\n"
     717             : + csspp_test::get_close_comment()
     718             :                 );
     719             : 
     720           1 :         CATCH_REQUIRE(c.get_root() == n);
     721           1 :     }
     722          13 :     CATCH_END_SECTION()
     723             : 
     724          13 :     CATCH_START_SECTION("modulo of a distance, require same dimension")
     725             :     {
     726           1 :         std::stringstream ss;
     727           1 :         ss << "div { width: 10px % 3px; }";
     728           3 :         csspp::position pos("test.css");
     729           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     730             : 
     731           2 :         csspp::parser p(l);
     732             : 
     733           1 :         csspp::node::pointer_t n(p.stylesheet());
     734             : 
     735           1 :         csspp::compiler c;
     736           1 :         c.set_root(n);
     737           1 :         c.set_date_time_variables(csspp_test::get_now());
     738           1 :         c.add_path(csspp_test::get_script_path());
     739           1 :         c.add_path(csspp_test::get_version_script_path());
     740             : 
     741           1 :         c.compile(false);
     742             : 
     743             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     744             : 
     745             :         // to verify that the result is still an INTEGER we have to
     746             :         // test the root node here
     747           1 :         std::stringstream compiler_out;
     748           1 :         compiler_out << *n;
     749           1 :         VERIFY_TREES(compiler_out.str(),
     750             : 
     751             : "LIST\n"
     752             : + csspp_test::get_default_variables() +
     753             : "  COMPONENT_VALUE\n"
     754             : "    ARG\n"
     755             : "      IDENTIFIER \"div\"\n"
     756             : "    OPEN_CURLYBRACKET B:true\n"
     757             : "      DECLARATION \"width\"\n"
     758             : "        ARG\n"
     759             : "          INTEGER \"px\" I:1\n"
     760             : + csspp_test::get_close_comment(true)
     761             : 
     762             :             );
     763             : 
     764           1 :         std::stringstream out;
     765           1 :         csspp::assembler a(out);
     766           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     767             : 
     768             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     769             : 
     770           1 :         CATCH_REQUIRE(out.str() ==
     771             : "div{width:1px}\n"
     772             : + csspp_test::get_close_comment()
     773             :                 );
     774             : 
     775           1 :         CATCH_REQUIRE(c.get_root() == n);
     776           1 :     }
     777          13 :     CATCH_END_SECTION()
     778             : 
     779             :     // no error left over
     780          13 :     VERIFY_ERRORS("");
     781          13 : }
     782             : 
     783           1 : CATCH_TEST_CASE("Expression integer *,/,% integer with incompatible dimensions", "[expression] [multiplicative] [invalid]")
     784             : {
     785             :     // px * px -- cannot output
     786             :     {
     787           1 :         std::stringstream ss;
     788           1 :         ss << "div { width: 3px * 10px; }";
     789           3 :         csspp::position pos("test.css");
     790           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     791             : 
     792           2 :         csspp::parser p(l);
     793             : 
     794           1 :         csspp::node::pointer_t n(p.stylesheet());
     795             : 
     796           1 :         csspp::compiler c;
     797           1 :         c.set_root(n);
     798           1 :         c.set_date_time_variables(csspp_test::get_now());
     799           1 :         c.add_path(csspp_test::get_script_path());
     800           1 :         c.add_path(csspp_test::get_version_script_path());
     801             : 
     802           1 :         c.compile(false);
     803             : 
     804             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     805             : 
     806             :         // to verify that the result is still an INTEGER we have to
     807             :         // test the root node here
     808           1 :         std::stringstream compiler_out;
     809           1 :         compiler_out << *n;
     810           1 :         VERIFY_TREES(compiler_out.str(),
     811             : 
     812             : "LIST\n"
     813             : + csspp_test::get_default_variables() +
     814             : "  COMPONENT_VALUE\n"
     815             : "    ARG\n"
     816             : "      IDENTIFIER \"div\"\n"
     817             : "    OPEN_CURLYBRACKET B:true\n"
     818             : "      DECLARATION \"width\"\n"
     819             : "        ARG\n"
     820             : "          INTEGER \"px * px\" I:30\n"
     821             : + csspp_test::get_close_comment(true)
     822             : 
     823             :             );
     824             : 
     825             :         // no errors so far
     826           1 :         VERIFY_ERRORS("");
     827             : 
     828           1 :         std::stringstream out;
     829           1 :         csspp::assembler a(out);
     830           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     831             : 
     832             : //std::cerr << "----------------- Result is [" << out.str() << "]\n";
     833             : 
     834           1 :         VERIFY_ERRORS("test.css(1): error: \"px * px\" is not a valid CSS dimension.\n");
     835             : 
     836           1 :         CATCH_REQUIRE(c.get_root() == n);
     837           1 :     }
     838             : 
     839             :     // px / em -- cannot output
     840             :     {
     841           1 :         std::stringstream ss;
     842           1 :         ss << "div { width: 10px / 3em; }";
     843           3 :         csspp::position pos("test.css");
     844           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     845             : 
     846           2 :         csspp::parser p(l);
     847             : 
     848           1 :         csspp::node::pointer_t n(p.stylesheet());
     849             : 
     850           1 :         csspp::compiler c;
     851           1 :         c.set_root(n);
     852           1 :         c.set_date_time_variables(csspp_test::get_now());
     853           1 :         c.add_path(csspp_test::get_script_path());
     854           1 :         c.add_path(csspp_test::get_version_script_path());
     855             : 
     856           1 :         c.compile(false);
     857             : 
     858             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     859             : 
     860             :         // to verify that the result is still an INTEGER we have to
     861             :         // test the root node here
     862           1 :         std::stringstream compiler_out;
     863           1 :         compiler_out << *n;
     864           1 :         VERIFY_TREES(compiler_out.str(),
     865             : 
     866             : "LIST\n"
     867             : + csspp_test::get_default_variables() +
     868             : "  COMPONENT_VALUE\n"
     869             : "    ARG\n"
     870             : "      IDENTIFIER \"div\"\n"
     871             : "    OPEN_CURLYBRACKET B:true\n"
     872             : "      DECLARATION \"width\"\n"
     873             : "        ARG\n"
     874             : "          INTEGER \"px / em\" I:3\n"
     875             : + csspp_test::get_close_comment(true)
     876             : 
     877             :             );
     878             : 
     879             :         // no errors so far
     880           1 :         VERIFY_ERRORS("");
     881             : 
     882           1 :         std::stringstream out;
     883           1 :         csspp::assembler a(out);
     884           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     885             : 
     886             : //std::cerr << "----------------- Result is [" << out.str() << "]\n";
     887             : 
     888           1 :         VERIFY_ERRORS("test.css(1): error: \"px / em\" is not a valid CSS dimension.\n");
     889             : 
     890           1 :         CATCH_REQUIRE(c.get_root() == n);
     891           1 :     }
     892             : 
     893             :     // px % em -- cannot calculate
     894             :     {
     895           1 :         std::stringstream ss;
     896           1 :         ss << "div { width: 10px % 3em; }";
     897           3 :         csspp::position pos("test.css");
     898           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     899             : 
     900           2 :         csspp::parser p(l);
     901             : 
     902           1 :         csspp::node::pointer_t n(p.stylesheet());
     903             : 
     904           1 :         csspp::compiler c;
     905           1 :         c.set_root(n);
     906           1 :         c.set_date_time_variables(csspp_test::get_now());
     907           1 :         c.add_path(csspp_test::get_script_path());
     908           1 :         c.add_path(csspp_test::get_version_script_path());
     909             : 
     910           1 :         c.compile(false);
     911             : 
     912             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     913             : 
     914           1 :         VERIFY_ERRORS("test.css(1): error: incompatible dimensions (\"px\" and \"em\") cannot be used with operator '%'.\n");
     915             : 
     916           1 :         CATCH_REQUIRE(c.get_root() == n);
     917           1 :     }
     918             : 
     919             :     // string * -integer
     920             :     {
     921           1 :         std::stringstream ss;
     922           1 :         ss << "div { width: \"lhs\" * -2; }";
     923           3 :         csspp::position pos("test.css");
     924           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     925             : 
     926           2 :         csspp::parser p(l);
     927             : 
     928           1 :         csspp::node::pointer_t n(p.stylesheet());
     929             : 
     930           1 :         csspp::compiler c;
     931           1 :         c.set_root(n);
     932           1 :         c.set_date_time_variables(csspp_test::get_now());
     933           1 :         c.add_path(csspp_test::get_script_path());
     934           1 :         c.add_path(csspp_test::get_version_script_path());
     935             : 
     936           1 :         c.compile(false);
     937             : 
     938             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     939             : 
     940           1 :         VERIFY_ERRORS("test.css(1): error: string * integer requires that the integer not be negative (-2).\n");
     941             : 
     942           1 :         CATCH_REQUIRE(c.get_root() == n);
     943           1 :     }
     944             : 
     945             :     // string / integer
     946             :     {
     947           1 :         std::stringstream ss;
     948           1 :         ss << "div { width: \"lhs\" / 3; }";
     949           3 :         csspp::position pos("test.css");
     950           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     951             : 
     952           2 :         csspp::parser p(l);
     953             : 
     954           1 :         csspp::node::pointer_t n(p.stylesheet());
     955             : 
     956           1 :         csspp::compiler c;
     957           1 :         c.set_root(n);
     958           1 :         c.set_date_time_variables(csspp_test::get_now());
     959           1 :         c.add_path(csspp_test::get_script_path());
     960           1 :         c.add_path(csspp_test::get_version_script_path());
     961             : 
     962           1 :         c.compile(false);
     963             : 
     964             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     965             : 
     966           1 :         VERIFY_ERRORS("test.css(1): error: incompatible types between STRING and INTEGER for operator '/' or '%'.\n");
     967             : 
     968           1 :         CATCH_REQUIRE(c.get_root() == n);
     969           1 :     }
     970             : 
     971             :     // string % integer
     972             :     {
     973           1 :         std::stringstream ss;
     974           1 :         ss << "div { width: \"lhs\" % 5; }";
     975           3 :         csspp::position pos("test.css");
     976           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     977             : 
     978           2 :         csspp::parser p(l);
     979             : 
     980           1 :         csspp::node::pointer_t n(p.stylesheet());
     981             : 
     982           1 :         csspp::compiler c;
     983           1 :         c.set_root(n);
     984           1 :         c.set_date_time_variables(csspp_test::get_now());
     985           1 :         c.add_path(csspp_test::get_script_path());
     986           1 :         c.add_path(csspp_test::get_version_script_path());
     987             : 
     988           1 :         c.compile(false);
     989             : 
     990             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     991             : 
     992           1 :         VERIFY_ERRORS("test.css(1): error: incompatible types between STRING and INTEGER for operator '/' or '%'.\n");
     993             : 
     994           1 :         CATCH_REQUIRE(c.get_root() == n);
     995           1 :     }
     996             : 
     997             :     // string * decimal-number
     998             :     {
     999           1 :         std::stringstream ss;
    1000           1 :         ss << "div { width: \"lhs\" * 3.14; }";
    1001           3 :         csspp::position pos("test.css");
    1002           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1003             : 
    1004           2 :         csspp::parser p(l);
    1005             : 
    1006           1 :         csspp::node::pointer_t n(p.stylesheet());
    1007             : 
    1008           1 :         csspp::compiler c;
    1009           1 :         c.set_root(n);
    1010           1 :         c.set_date_time_variables(csspp_test::get_now());
    1011           1 :         c.add_path(csspp_test::get_script_path());
    1012           1 :         c.add_path(csspp_test::get_version_script_path());
    1013             : 
    1014           1 :         c.compile(false);
    1015             : 
    1016             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1017             : 
    1018           1 :         VERIFY_ERRORS("test.css(1): error: incompatible types between STRING and DECIMAL_NUMBER for operator '*', '/', or '%'.\n");
    1019             : 
    1020           1 :         CATCH_REQUIRE(c.get_root() == n);
    1021           1 :     }
    1022             : 
    1023             :     // string * percent
    1024             :     {
    1025           1 :         std::stringstream ss;
    1026           1 :         ss << "div { width: \"lhs\" / 31%; }";
    1027           3 :         csspp::position pos("test.css");
    1028           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1029             : 
    1030           2 :         csspp::parser p(l);
    1031             : 
    1032           1 :         csspp::node::pointer_t n(p.stylesheet());
    1033             : 
    1034           1 :         csspp::compiler c;
    1035           1 :         c.set_root(n);
    1036           1 :         c.set_date_time_variables(csspp_test::get_now());
    1037           1 :         c.add_path(csspp_test::get_script_path());
    1038           1 :         c.add_path(csspp_test::get_version_script_path());
    1039             : 
    1040           1 :         c.compile(false);
    1041             : 
    1042             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1043             : 
    1044           1 :         VERIFY_ERRORS("test.css(1): error: incompatible types between STRING and PERCENT for operator '*', '/', or '%'.\n");
    1045             : 
    1046           1 :         CATCH_REQUIRE(c.get_root() == n);
    1047           1 :     }
    1048             : 
    1049           1 :     CATCH_START_SECTION("unicode-range % string")
    1050             :     {
    1051           1 :         std::stringstream ss;
    1052           1 :         ss << "div { width: U+5?? % \"rhs\"; }";
    1053           3 :         csspp::position pos("test.css");
    1054           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1055             : 
    1056           2 :         csspp::parser p(l);
    1057             : 
    1058           1 :         csspp::node::pointer_t n(p.stylesheet());
    1059             : 
    1060           1 :         csspp::compiler c;
    1061           1 :         c.set_root(n);
    1062           1 :         c.set_date_time_variables(csspp_test::get_now());
    1063           1 :         c.add_path(csspp_test::get_script_path());
    1064           1 :         c.add_path(csspp_test::get_version_script_path());
    1065             : 
    1066           1 :         c.compile(false);
    1067             : 
    1068             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1069             : 
    1070           1 :         VERIFY_ERRORS("test.css(1): error: incompatible types between UNICODE_RANGE and STRING for operator '*', '/', or '%'.\n");
    1071             : 
    1072           1 :         CATCH_REQUIRE(c.get_root() == n);
    1073           1 :     }
    1074           1 :     CATCH_END_SECTION()
    1075             : 
    1076             :     // string * string
    1077             :     {
    1078           1 :         std::stringstream ss;
    1079           1 :         ss << "div { width: \"lhs\" * 'rhs'; }";
    1080           3 :         csspp::position pos("test.css");
    1081           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1082             : 
    1083           2 :         csspp::parser p(l);
    1084             : 
    1085           1 :         csspp::node::pointer_t n(p.stylesheet());
    1086             : 
    1087           1 :         csspp::compiler c;
    1088           1 :         c.set_root(n);
    1089           1 :         c.set_date_time_variables(csspp_test::get_now());
    1090           1 :         c.add_path(csspp_test::get_script_path());
    1091           1 :         c.add_path(csspp_test::get_version_script_path());
    1092             : 
    1093           1 :         c.compile(false);
    1094             : 
    1095             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1096             : 
    1097           1 :         VERIFY_ERRORS("test.css(1): error: incompatible types between STRING and STRING for operator '*', '/', or '%'.\n");
    1098             : 
    1099           1 :         CATCH_REQUIRE(c.get_root() == n);
    1100           1 :     }
    1101             : 
    1102             :     // string / string
    1103             :     {
    1104           1 :         std::stringstream ss;
    1105           1 :         ss << "div { width: \"lhs\" / 'rhs'; }";
    1106           3 :         csspp::position pos("test.css");
    1107           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1108             : 
    1109           2 :         csspp::parser p(l);
    1110             : 
    1111           1 :         csspp::node::pointer_t n(p.stylesheet());
    1112             : 
    1113           1 :         csspp::compiler c;
    1114           1 :         c.set_root(n);
    1115           1 :         c.set_date_time_variables(csspp_test::get_now());
    1116           1 :         c.add_path(csspp_test::get_script_path());
    1117           1 :         c.add_path(csspp_test::get_version_script_path());
    1118             : 
    1119           1 :         c.compile(false);
    1120             : 
    1121             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1122             : 
    1123           1 :         VERIFY_ERRORS("test.css(1): error: incompatible types between STRING and STRING for operator '*', '/', or '%'.\n");
    1124             : 
    1125           1 :         CATCH_REQUIRE(c.get_root() == n);
    1126           1 :     }
    1127             : 
    1128             :     // string % string
    1129             :     {
    1130           1 :         std::stringstream ss;
    1131           1 :         ss << "div { width: \"lhs\" % 'rhs'; }";
    1132           3 :         csspp::position pos("test.css");
    1133           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1134             : 
    1135           2 :         csspp::parser p(l);
    1136             : 
    1137           1 :         csspp::node::pointer_t n(p.stylesheet());
    1138             : 
    1139           1 :         csspp::compiler c;
    1140           1 :         c.set_root(n);
    1141           1 :         c.set_date_time_variables(csspp_test::get_now());
    1142           1 :         c.add_path(csspp_test::get_script_path());
    1143           1 :         c.add_path(csspp_test::get_version_script_path());
    1144             : 
    1145           1 :         c.compile(false);
    1146             : 
    1147             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1148             : 
    1149           1 :         VERIFY_ERRORS("test.css(1): error: incompatible types between STRING and STRING for operator '*', '/', or '%'.\n");
    1150             : 
    1151           1 :         CATCH_REQUIRE(c.get_root() == n);
    1152           1 :     }
    1153             : 
    1154             :     // no error left over
    1155           1 :     VERIFY_ERRORS("");
    1156           1 : }
    1157             : 
    1158           1 : CATCH_TEST_CASE("Expression string * integer", "[expression] [multiplicative] [string]")
    1159             : {
    1160             :     // duplicate a string (string x integer)
    1161             :     {
    1162           1 :         std::stringstream ss;
    1163           1 :         ss << "div::before { content: \"str\" * 3; }";
    1164           3 :         csspp::position pos("test.css");
    1165           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1166             : 
    1167           2 :         csspp::parser p(l);
    1168             : 
    1169           1 :         csspp::node::pointer_t n(p.stylesheet());
    1170             : 
    1171           1 :         csspp::compiler c;
    1172           1 :         c.set_root(n);
    1173           1 :         c.set_date_time_variables(csspp_test::get_now());
    1174           1 :         c.add_path(csspp_test::get_script_path());
    1175           1 :         c.add_path(csspp_test::get_version_script_path());
    1176             : 
    1177           1 :         c.compile(false);
    1178             : 
    1179             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1180             : 
    1181             :         // to verify that the result is still an INTEGER we have to
    1182             :         // test the root node here
    1183           1 :         std::stringstream compiler_out;
    1184           1 :         compiler_out << *n;
    1185           1 :         VERIFY_TREES(compiler_out.str(),
    1186             : 
    1187             : "LIST\n"
    1188             : + csspp_test::get_default_variables() +
    1189             : "  COMPONENT_VALUE\n"
    1190             : "    ARG\n"
    1191             : "      IDENTIFIER \"div\"\n"
    1192             : "      COLON\n"
    1193             : "      COLON\n"
    1194             : "      IDENTIFIER \"before\"\n"
    1195             : "    OPEN_CURLYBRACKET B:true\n"
    1196             : "      DECLARATION \"content\"\n"
    1197             : "        ARG\n"
    1198             : "          STRING \"strstrstr\"\n"
    1199             : + csspp_test::get_close_comment(true)
    1200             : 
    1201             :             );
    1202             : 
    1203           1 :         std::stringstream assembler_out;
    1204           1 :         csspp::assembler a(assembler_out);
    1205           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    1206             : 
    1207             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1208             : 
    1209           1 :         CATCH_REQUIRE(assembler_out.str() ==
    1210             : "div::before{content:\"strstrstr\"}\n"
    1211             : + csspp_test::get_close_comment()
    1212             :                 );
    1213             : 
    1214           1 :         CATCH_REQUIRE(c.get_root() == n);
    1215           1 :     }
    1216             : 
    1217             :     // duplicate a string (integer x string)
    1218             :     {
    1219           1 :         std::stringstream ss;
    1220           1 :         ss << "div::before { content: 3 * \"str\"; }";
    1221           3 :         csspp::position pos("test.css");
    1222           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1223             : 
    1224           2 :         csspp::parser p(l);
    1225             : 
    1226           1 :         csspp::node::pointer_t n(p.stylesheet());
    1227             : 
    1228           1 :         csspp::compiler c;
    1229           1 :         c.set_root(n);
    1230           1 :         c.set_date_time_variables(csspp_test::get_now());
    1231           1 :         c.add_path(csspp_test::get_script_path());
    1232           1 :         c.add_path(csspp_test::get_version_script_path());
    1233             : 
    1234           1 :         c.compile(false);
    1235             : 
    1236             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1237             : 
    1238             :         // to verify that the result is still an INTEGER we have to
    1239             :         // test the root node here
    1240           1 :         std::stringstream compiler_out;
    1241           1 :         compiler_out << *n;
    1242           1 :         VERIFY_TREES(compiler_out.str(),
    1243             : 
    1244             : "LIST\n"
    1245             : + csspp_test::get_default_variables() +
    1246             : "  COMPONENT_VALUE\n"
    1247             : "    ARG\n"
    1248             : "      IDENTIFIER \"div\"\n"
    1249             : "      COLON\n"
    1250             : "      COLON\n"
    1251             : "      IDENTIFIER \"before\"\n"
    1252             : "    OPEN_CURLYBRACKET B:true\n"
    1253             : "      DECLARATION \"content\"\n"
    1254             : "        ARG\n"
    1255             : "          STRING \"strstrstr\"\n"
    1256             : + csspp_test::get_close_comment(true)
    1257             : 
    1258             :             );
    1259             : 
    1260           1 :         std::stringstream assembler_out;
    1261           1 :         csspp::assembler a(assembler_out);
    1262           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    1263             : 
    1264             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1265             : 
    1266           1 :         CATCH_REQUIRE(assembler_out.str() ==
    1267             : "div::before{content:\"strstrstr\"}\n"
    1268             : + csspp_test::get_close_comment()
    1269             :                 );
    1270             : 
    1271           1 :         CATCH_REQUIRE(c.get_root() == n);
    1272           1 :     }
    1273             : 
    1274             :     // duplicate a string (string x 0)
    1275             :     {
    1276           1 :         std::stringstream ss;
    1277           1 :         ss << "div::before { content: \"str\" * 0; }";
    1278           3 :         csspp::position pos("test.css");
    1279           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1280             : 
    1281           2 :         csspp::parser p(l);
    1282             : 
    1283           1 :         csspp::node::pointer_t n(p.stylesheet());
    1284             : 
    1285           1 :         csspp::compiler c;
    1286           1 :         c.set_root(n);
    1287           1 :         c.set_date_time_variables(csspp_test::get_now());
    1288           1 :         c.add_path(csspp_test::get_script_path());
    1289           1 :         c.add_path(csspp_test::get_version_script_path());
    1290             : 
    1291           1 :         c.compile(false);
    1292             : 
    1293             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1294             : 
    1295             :         // to verify that the result is still an INTEGER we have to
    1296             :         // test the root node here
    1297           1 :         std::stringstream compiler_out;
    1298           1 :         compiler_out << *n;
    1299           1 :         VERIFY_TREES(compiler_out.str(),
    1300             : 
    1301             : "LIST\n"
    1302             : + csspp_test::get_default_variables() +
    1303             : "  COMPONENT_VALUE\n"
    1304             : "    ARG\n"
    1305             : "      IDENTIFIER \"div\"\n"
    1306             : "      COLON\n"
    1307             : "      COLON\n"
    1308             : "      IDENTIFIER \"before\"\n"
    1309             : "    OPEN_CURLYBRACKET B:true\n"
    1310             : "      DECLARATION \"content\"\n"
    1311             : "        ARG\n"
    1312             : "          STRING \"\"\n"
    1313             : + csspp_test::get_close_comment(true)
    1314             : 
    1315             :             );
    1316             : 
    1317           1 :         std::stringstream assembler_out;
    1318           1 :         csspp::assembler a(assembler_out);
    1319           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    1320             : 
    1321             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1322             : 
    1323           1 :         CATCH_REQUIRE(assembler_out.str() ==
    1324             : "div::before{content:\"\"}\n"
    1325             : + csspp_test::get_close_comment()
    1326             :                 );
    1327             : 
    1328           1 :         CATCH_REQUIRE(c.get_root() == n);
    1329           1 :     }
    1330             : 
    1331             :     // duplicate a string (0 x string)
    1332             :     {
    1333           1 :         std::stringstream ss;
    1334           1 :         ss << "div::before { content: 0 * \"str\"; }";
    1335           3 :         csspp::position pos("test.css");
    1336           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1337             : 
    1338           2 :         csspp::parser p(l);
    1339             : 
    1340           1 :         csspp::node::pointer_t n(p.stylesheet());
    1341             : 
    1342           1 :         csspp::compiler c;
    1343           1 :         c.set_root(n);
    1344           1 :         c.set_date_time_variables(csspp_test::get_now());
    1345           1 :         c.add_path(csspp_test::get_script_path());
    1346           1 :         c.add_path(csspp_test::get_version_script_path());
    1347             : 
    1348           1 :         c.compile(false);
    1349             : 
    1350             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1351             : 
    1352             :         // to verify that the result is still an INTEGER we have to
    1353             :         // test the root node here
    1354           1 :         std::stringstream compiler_out;
    1355           1 :         compiler_out << *n;
    1356           1 :         VERIFY_TREES(compiler_out.str(),
    1357             : 
    1358             : "LIST\n"
    1359             : + csspp_test::get_default_variables() +
    1360             : "  COMPONENT_VALUE\n"
    1361             : "    ARG\n"
    1362             : "      IDENTIFIER \"div\"\n"
    1363             : "      COLON\n"
    1364             : "      COLON\n"
    1365             : "      IDENTIFIER \"before\"\n"
    1366             : "    OPEN_CURLYBRACKET B:true\n"
    1367             : "      DECLARATION \"content\"\n"
    1368             : "        ARG\n"
    1369             : "          STRING \"\"\n"
    1370             : + csspp_test::get_close_comment(true)
    1371             : 
    1372             :             );
    1373             : 
    1374           1 :         std::stringstream assembler_out;
    1375           1 :         csspp::assembler a(assembler_out);
    1376           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    1377             : 
    1378             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1379             : 
    1380           1 :         CATCH_REQUIRE(assembler_out.str() ==
    1381             : "div::before{content:\"\"}\n"
    1382             : + csspp_test::get_close_comment()
    1383             :                 );
    1384             : 
    1385           1 :         CATCH_REQUIRE(c.get_root() == n);
    1386           1 :     }
    1387             : 
    1388             :     // no error left over
    1389           1 :     VERIFY_ERRORS("");
    1390           1 : }
    1391             : 
    1392           8 : CATCH_TEST_CASE("Expression multiplicative errors", "[expression] [multiplicative] [invalid]")
    1393             : {
    1394           8 :     CATCH_START_SECTION("? is not a valid unary")
    1395             :     {
    1396           1 :         std::stringstream ss;
    1397           1 :         ss << "div { width: ?; }";
    1398           3 :         csspp::position pos("test.css");
    1399           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1400             : 
    1401           2 :         csspp::parser p(l);
    1402             : 
    1403           1 :         csspp::node::pointer_t n(p.stylesheet());
    1404             : 
    1405           1 :         csspp::compiler c;
    1406           1 :         c.set_root(n);
    1407           1 :         c.set_date_time_variables(csspp_test::get_now());
    1408           1 :         c.add_path(csspp_test::get_script_path());
    1409           1 :         c.add_path(csspp_test::get_version_script_path());
    1410             : 
    1411           1 :         c.compile(false);
    1412             : 
    1413             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1414             : 
    1415           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
    1416             : 
    1417           1 :         CATCH_REQUIRE(c.get_root() == n);
    1418           1 :     }
    1419           8 :     CATCH_END_SECTION()
    1420             : 
    1421           8 :     CATCH_START_SECTION("5 * ? is not valid")
    1422             :     {
    1423           1 :         std::stringstream ss;
    1424           1 :         ss << "div { width: 5 * ?; }";
    1425           3 :         csspp::position pos("test.css");
    1426           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1427             : 
    1428           2 :         csspp::parser p(l);
    1429             : 
    1430           1 :         csspp::node::pointer_t n(p.stylesheet());
    1431             : 
    1432           1 :         csspp::compiler c;
    1433           1 :         c.set_root(n);
    1434           1 :         c.set_date_time_variables(csspp_test::get_now());
    1435           1 :         c.add_path(csspp_test::get_script_path());
    1436           1 :         c.add_path(csspp_test::get_version_script_path());
    1437             : 
    1438           1 :         c.compile(false);
    1439             : 
    1440             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1441             : 
    1442           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
    1443             : 
    1444           1 :         CATCH_REQUIRE(c.get_root() == n);
    1445           1 :     }
    1446           8 :     CATCH_END_SECTION()
    1447             : 
    1448           8 :     CATCH_START_SECTION("3 / ? is not valid")
    1449             :     {
    1450           1 :         std::stringstream ss;
    1451           1 :         ss << "div { width: 3 / ?; }";
    1452           3 :         csspp::position pos("test.css");
    1453           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1454             : 
    1455           2 :         csspp::parser p(l);
    1456             : 
    1457           1 :         csspp::node::pointer_t n(p.stylesheet());
    1458             : 
    1459           1 :         csspp::compiler c;
    1460           1 :         c.set_root(n);
    1461           1 :         c.set_date_time_variables(csspp_test::get_now());
    1462           1 :         c.add_path(csspp_test::get_script_path());
    1463           1 :         c.add_path(csspp_test::get_version_script_path());
    1464             : 
    1465           1 :         c.compile(false);
    1466             : 
    1467             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1468             : 
    1469           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
    1470             : 
    1471           1 :         CATCH_REQUIRE(c.get_root() == n);
    1472           1 :     }
    1473           8 :     CATCH_END_SECTION()
    1474             : 
    1475           8 :     CATCH_START_SECTION("3 % ? is not valid")
    1476             :     {
    1477           1 :         std::stringstream ss;
    1478           1 :         ss << "div { width: 3 % ?; }";
    1479           3 :         csspp::position pos("test.css");
    1480           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1481             : 
    1482           2 :         csspp::parser p(l);
    1483             : 
    1484           1 :         csspp::node::pointer_t n(p.stylesheet());
    1485             : 
    1486           1 :         csspp::compiler c;
    1487           1 :         c.set_root(n);
    1488           1 :         c.set_date_time_variables(csspp_test::get_now());
    1489           1 :         c.add_path(csspp_test::get_script_path());
    1490           1 :         c.add_path(csspp_test::get_version_script_path());
    1491             : 
    1492           1 :         c.compile(false);
    1493             : 
    1494             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1495             : 
    1496           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
    1497             : 
    1498           1 :         CATCH_REQUIRE(c.get_root() == n);
    1499           1 :     }
    1500           8 :     CATCH_END_SECTION()
    1501             : 
    1502           8 :     CATCH_START_SECTION("3 / 0 is not accepted")
    1503             :     {
    1504           1 :         std::stringstream ss;
    1505           1 :         ss << "div { width: 3 / 0; }";
    1506           3 :         csspp::position pos("test.css");
    1507           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1508             : 
    1509           2 :         csspp::parser p(l);
    1510             : 
    1511           1 :         csspp::node::pointer_t n(p.stylesheet());
    1512             : 
    1513           1 :         csspp::compiler c;
    1514           1 :         c.set_root(n);
    1515           1 :         c.set_date_time_variables(csspp_test::get_now());
    1516           1 :         c.add_path(csspp_test::get_script_path());
    1517           1 :         c.add_path(csspp_test::get_version_script_path());
    1518             : 
    1519           1 :         c.compile(false);
    1520             : 
    1521             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1522             : 
    1523           1 :         VERIFY_ERRORS("test.css(1): error: division by zero.\n");
    1524             : 
    1525           1 :         CATCH_REQUIRE(c.get_root() == n);
    1526           1 :     }
    1527           8 :     CATCH_END_SECTION()
    1528             : 
    1529           8 :     CATCH_START_SECTION("3.3 / 0.0 is not accepted")
    1530             :     {
    1531           1 :         std::stringstream ss;
    1532           1 :         ss << "div { width: 3.3 / 0.0; }";
    1533           3 :         csspp::position pos("test.css");
    1534           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1535             : 
    1536           2 :         csspp::parser p(l);
    1537             : 
    1538           1 :         csspp::node::pointer_t n(p.stylesheet());
    1539             : 
    1540           1 :         csspp::compiler c;
    1541           1 :         c.set_root(n);
    1542           1 :         c.set_date_time_variables(csspp_test::get_now());
    1543           1 :         c.add_path(csspp_test::get_script_path());
    1544           1 :         c.add_path(csspp_test::get_version_script_path());
    1545             : 
    1546           1 :         c.compile(false);
    1547             : 
    1548             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1549             : 
    1550           1 :         VERIFY_ERRORS("test.css(1): error: division by zero.\n");
    1551             : 
    1552           1 :         CATCH_REQUIRE(c.get_root() == n);
    1553           1 :     }
    1554           8 :     CATCH_END_SECTION()
    1555             : 
    1556           8 :     CATCH_START_SECTION("3 % 0 is not accepted")
    1557             :     {
    1558           1 :         std::stringstream ss;
    1559           1 :         ss << "div { width: 3 % 0; }";
    1560           3 :         csspp::position pos("test.css");
    1561           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1562             : 
    1563           2 :         csspp::parser p(l);
    1564             : 
    1565           1 :         csspp::node::pointer_t n(p.stylesheet());
    1566             : 
    1567           1 :         csspp::compiler c;
    1568           1 :         c.set_root(n);
    1569           1 :         c.set_date_time_variables(csspp_test::get_now());
    1570           1 :         c.add_path(csspp_test::get_script_path());
    1571           1 :         c.add_path(csspp_test::get_version_script_path());
    1572             : 
    1573           1 :         c.compile(false);
    1574             : 
    1575             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1576             : 
    1577           1 :         VERIFY_ERRORS("test.css(1): error: modulo by zero.\n");
    1578             : 
    1579           1 :         CATCH_REQUIRE(c.get_root() == n);
    1580           1 :     }
    1581           8 :     CATCH_END_SECTION()
    1582             : 
    1583           8 :     CATCH_START_SECTION("3.9 % 0.0 is not accepted")
    1584             :     {
    1585           1 :         std::stringstream ss;
    1586           1 :         ss << "div { width: 3.9 % 0.0; }";
    1587           3 :         csspp::position pos("test.css");
    1588           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1589             : 
    1590           2 :         csspp::parser p(l);
    1591             : 
    1592           1 :         csspp::node::pointer_t n(p.stylesheet());
    1593             : 
    1594           1 :         csspp::compiler c;
    1595           1 :         c.set_root(n);
    1596           1 :         c.set_date_time_variables(csspp_test::get_now());
    1597           1 :         c.add_path(csspp_test::get_script_path());
    1598           1 :         c.add_path(csspp_test::get_version_script_path());
    1599             : 
    1600           1 :         c.compile(false);
    1601             : 
    1602             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1603             : 
    1604           1 :         VERIFY_ERRORS("test.css(1): error: modulo by zero.\n");
    1605             : 
    1606           1 :         CATCH_REQUIRE(c.get_root() == n);
    1607           1 :     }
    1608           8 :     CATCH_END_SECTION()
    1609             : 
    1610             :     // no error left over
    1611           8 :     VERIFY_ERRORS("");
    1612           8 : }
    1613             : 
    1614          18 : CATCH_TEST_CASE("Expression decimal number or integer *,/,% decimal number or integer", "[expression] [multiplicative]")
    1615             : {
    1616          18 :     CATCH_START_SECTION("multiply two decimal numbers")
    1617             :     {
    1618           1 :         std::stringstream ss;
    1619           1 :         ss << "div { z-index: 3.5 * 10.2; }";
    1620           3 :         csspp::position pos("test.css");
    1621           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1622             : 
    1623           2 :         csspp::parser p(l);
    1624             : 
    1625           1 :         csspp::node::pointer_t n(p.stylesheet());
    1626             : 
    1627           1 :         csspp::compiler c;
    1628           1 :         c.set_root(n);
    1629           1 :         c.set_date_time_variables(csspp_test::get_now());
    1630           1 :         c.add_path(csspp_test::get_script_path());
    1631           1 :         c.add_path(csspp_test::get_version_script_path());
    1632             : 
    1633           1 :         c.compile(false);
    1634             : 
    1635           1 :         VERIFY_ERRORS("");
    1636             : 
    1637             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1638             : 
    1639             :         // to verify that the result is still an INTEGER we have to
    1640             :         // test the root node here
    1641           1 :         std::stringstream compiler_out;
    1642           1 :         compiler_out << *n;
    1643           1 :         VERIFY_TREES(compiler_out.str(),
    1644             : 
    1645             : "LIST\n"
    1646             : + csspp_test::get_default_variables() +
    1647             : "  COMPONENT_VALUE\n"
    1648             : "    ARG\n"
    1649             : "      IDENTIFIER \"div\"\n"
    1650             : "    OPEN_CURLYBRACKET B:true\n"
    1651             : "      DECLARATION \"z-index\"\n"
    1652             : "        ARG\n"
    1653             : "          DECIMAL_NUMBER \"\" D:35.7\n"
    1654             : + csspp_test::get_close_comment(true)
    1655             : 
    1656             :             );
    1657             : 
    1658           1 :         std::stringstream assembler_out;
    1659           1 :         csspp::assembler a(assembler_out);
    1660           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    1661             : 
    1662             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1663             : 
    1664           1 :         CATCH_REQUIRE(assembler_out.str() ==
    1665             : "div{z-index:35.7}\n"
    1666             : + csspp_test::get_close_comment()
    1667             :                 );
    1668             : 
    1669           1 :         CATCH_REQUIRE(c.get_root() == n);
    1670           1 :     }
    1671          18 :     CATCH_END_SECTION()
    1672             : 
    1673          18 :     CATCH_START_SECTION("multiply an integer with a decimal number")
    1674             :     {
    1675           1 :         std::stringstream ss;
    1676           1 :         ss << "div { z-index: 3 * 10.2; }";
    1677           3 :         csspp::position pos("test.css");
    1678           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1679             : 
    1680           2 :         csspp::parser p(l);
    1681             : 
    1682           1 :         csspp::node::pointer_t n(p.stylesheet());
    1683             : 
    1684           1 :         csspp::compiler c;
    1685           1 :         c.set_root(n);
    1686           1 :         c.set_date_time_variables(csspp_test::get_now());
    1687           1 :         c.add_path(csspp_test::get_script_path());
    1688           1 :         c.add_path(csspp_test::get_version_script_path());
    1689             : 
    1690           1 :         c.compile(false);
    1691             : 
    1692           1 :         VERIFY_ERRORS("");
    1693             : 
    1694             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1695             : 
    1696             :         // to verify that the result is still an INTEGER we have to
    1697             :         // test the root node here
    1698           1 :         std::stringstream compiler_out;
    1699           1 :         compiler_out << *n;
    1700           1 :         VERIFY_TREES(compiler_out.str(),
    1701             : 
    1702             : "LIST\n"
    1703             : + csspp_test::get_default_variables() +
    1704             : "  COMPONENT_VALUE\n"
    1705             : "    ARG\n"
    1706             : "      IDENTIFIER \"div\"\n"
    1707             : "    OPEN_CURLYBRACKET B:true\n"
    1708             : "      DECLARATION \"z-index\"\n"
    1709             : "        ARG\n"
    1710             : "          DECIMAL_NUMBER \"\" D:30.6\n"
    1711             : + csspp_test::get_close_comment(true)
    1712             : 
    1713             :             );
    1714             : 
    1715           1 :         std::stringstream assembler_out;
    1716           1 :         csspp::assembler a(assembler_out);
    1717           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    1718             : 
    1719             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1720             : 
    1721           1 :         CATCH_REQUIRE(assembler_out.str() ==
    1722             : "div{z-index:30.6}\n"
    1723             : + csspp_test::get_close_comment()
    1724             :                 );
    1725             : 
    1726           1 :         CATCH_REQUIRE(c.get_root() == n);
    1727           1 :     }
    1728          18 :     CATCH_END_SECTION()
    1729             : 
    1730          18 :     CATCH_START_SECTION("multiply a decimal number with an integer")
    1731             :     {
    1732           1 :         std::stringstream ss;
    1733           1 :         ss << "div { z-index: 3.5 * 10; }";
    1734           3 :         csspp::position pos("test.css");
    1735           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1736             : 
    1737           2 :         csspp::parser p(l);
    1738             : 
    1739           1 :         csspp::node::pointer_t n(p.stylesheet());
    1740             : 
    1741           1 :         csspp::compiler c;
    1742           1 :         c.set_root(n);
    1743           1 :         c.set_date_time_variables(csspp_test::get_now());
    1744           1 :         c.add_path(csspp_test::get_script_path());
    1745           1 :         c.add_path(csspp_test::get_version_script_path());
    1746             : 
    1747           1 :         c.compile(false);
    1748             : 
    1749           1 :         VERIFY_ERRORS("");
    1750             : 
    1751             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1752             : 
    1753             :         // to verify that the result is still an INTEGER we have to
    1754             :         // test the root node here
    1755           1 :         std::stringstream compiler_out;
    1756           1 :         compiler_out << *n;
    1757           1 :         VERIFY_TREES(compiler_out.str(),
    1758             : 
    1759             : "LIST\n"
    1760             : + csspp_test::get_default_variables() +
    1761             : "  COMPONENT_VALUE\n"
    1762             : "    ARG\n"
    1763             : "      IDENTIFIER \"div\"\n"
    1764             : "    OPEN_CURLYBRACKET B:true\n"
    1765             : "      DECLARATION \"z-index\"\n"
    1766             : "        ARG\n"
    1767             : "          DECIMAL_NUMBER \"\" D:35\n"
    1768             : + csspp_test::get_close_comment(true)
    1769             : 
    1770             :             );
    1771             : 
    1772           1 :         std::stringstream assembler_out;
    1773           1 :         csspp::assembler a(assembler_out);
    1774           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    1775             : 
    1776             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1777             : 
    1778           1 :         CATCH_REQUIRE(assembler_out.str() ==
    1779             : "div{z-index:35}\n"
    1780             : + csspp_test::get_close_comment()
    1781             :                 );
    1782             : 
    1783           1 :         CATCH_REQUIRE(c.get_root() == n);
    1784           1 :     }
    1785          18 :     CATCH_END_SECTION()
    1786             : 
    1787          18 :     CATCH_START_SECTION("multiply decimal numbers with 0 in their fraction")
    1788             :     {
    1789           1 :         std::stringstream ss;
    1790           1 :         ss << "div { z-index: 3.0 * 10.0; }";
    1791           3 :         csspp::position pos("test.css");
    1792           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1793             : 
    1794           2 :         csspp::parser p(l);
    1795             : 
    1796           1 :         csspp::node::pointer_t n(p.stylesheet());
    1797             : 
    1798           1 :         csspp::compiler c;
    1799           1 :         c.set_root(n);
    1800           1 :         c.set_date_time_variables(csspp_test::get_now());
    1801           1 :         c.add_path(csspp_test::get_script_path());
    1802           1 :         c.add_path(csspp_test::get_version_script_path());
    1803             : 
    1804           1 :         c.compile(false);
    1805             : 
    1806           1 :         VERIFY_ERRORS("");
    1807             : 
    1808             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1809             : 
    1810             :         // to verify that the result is still an INTEGER we have to
    1811             :         // test the root node here
    1812           1 :         std::stringstream compiler_out;
    1813           1 :         compiler_out << *n;
    1814           1 :         VERIFY_TREES(compiler_out.str(),
    1815             : 
    1816             : "LIST\n"
    1817             : + csspp_test::get_default_variables() +
    1818             : "  COMPONENT_VALUE\n"
    1819             : "    ARG\n"
    1820             : "      IDENTIFIER \"div\"\n"
    1821             : "    OPEN_CURLYBRACKET B:true\n"
    1822             : "      DECLARATION \"z-index\"\n"
    1823             : "        ARG\n"
    1824             : "          DECIMAL_NUMBER \"\" D:30\n"
    1825             : + csspp_test::get_close_comment(true)
    1826             : 
    1827             :             );
    1828             : 
    1829           1 :         std::stringstream assembler_out;
    1830           1 :         csspp::assembler a(assembler_out);
    1831           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    1832             : 
    1833             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1834             : 
    1835           1 :         CATCH_REQUIRE(assembler_out.str() ==
    1836             : "div{z-index:30}\n"
    1837             : + csspp_test::get_close_comment()
    1838             :                 );
    1839             : 
    1840           1 :         CATCH_REQUIRE(c.get_root() == n);
    1841           1 :     }
    1842          18 :     CATCH_END_SECTION()
    1843             : 
    1844          18 :     CATCH_START_SECTION("multiply an integer and a decimal number with 0 in their fraction")
    1845             :     {
    1846           1 :         std::stringstream ss;
    1847           1 :         ss << "div { z-index: 3 * 10.0; }";
    1848           3 :         csspp::position pos("test.css");
    1849           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1850             : 
    1851           2 :         csspp::parser p(l);
    1852             : 
    1853           1 :         csspp::node::pointer_t n(p.stylesheet());
    1854             : 
    1855           1 :         csspp::compiler c;
    1856           1 :         c.set_root(n);
    1857           1 :         c.set_date_time_variables(csspp_test::get_now());
    1858           1 :         c.add_path(csspp_test::get_script_path());
    1859           1 :         c.add_path(csspp_test::get_version_script_path());
    1860             : 
    1861           1 :         c.compile(false);
    1862             : 
    1863           1 :         VERIFY_ERRORS("");
    1864             : 
    1865             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1866             : 
    1867             :         // to verify that the result is still an INTEGER we have to
    1868             :         // test the root node here
    1869           1 :         std::stringstream compiler_out;
    1870           1 :         compiler_out << *n;
    1871           1 :         VERIFY_TREES(compiler_out.str(),
    1872             : 
    1873             : "LIST\n"
    1874             : + csspp_test::get_default_variables() +
    1875             : "  COMPONENT_VALUE\n"
    1876             : "    ARG\n"
    1877             : "      IDENTIFIER \"div\"\n"
    1878             : "    OPEN_CURLYBRACKET B:true\n"
    1879             : "      DECLARATION \"z-index\"\n"
    1880             : "        ARG\n"
    1881             : "          DECIMAL_NUMBER \"\" D:30\n"
    1882             : + csspp_test::get_close_comment(true)
    1883             : 
    1884             :             );
    1885             : 
    1886           1 :         std::stringstream assembler_out;
    1887           1 :         csspp::assembler a(assembler_out);
    1888           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    1889             : 
    1890             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1891             : 
    1892           1 :         CATCH_REQUIRE(assembler_out.str() ==
    1893             : "div{z-index:30}\n"
    1894             : + csspp_test::get_close_comment()
    1895             :                 );
    1896             : 
    1897           1 :         CATCH_REQUIRE(c.get_root() == n);
    1898           1 :     }
    1899          18 :     CATCH_END_SECTION()
    1900             : 
    1901          18 :     CATCH_START_SECTION("multiply a decimal number with 0 in their fraction and an integer")
    1902             :     {
    1903           1 :         std::stringstream ss;
    1904           1 :         ss << "div { z-index: 3.0 * 10; }";
    1905           3 :         csspp::position pos("test.css");
    1906           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1907             : 
    1908           2 :         csspp::parser p(l);
    1909             : 
    1910           1 :         csspp::node::pointer_t n(p.stylesheet());
    1911             : 
    1912           1 :         csspp::compiler c;
    1913           1 :         c.set_root(n);
    1914           1 :         c.set_date_time_variables(csspp_test::get_now());
    1915           1 :         c.add_path(csspp_test::get_script_path());
    1916           1 :         c.add_path(csspp_test::get_version_script_path());
    1917             : 
    1918           1 :         c.compile(false);
    1919             : 
    1920           1 :         VERIFY_ERRORS("");
    1921             : 
    1922             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1923             : 
    1924             :         // to verify that the result is still an INTEGER we have to
    1925             :         // test the root node here
    1926           1 :         std::stringstream compiler_out;
    1927           1 :         compiler_out << *n;
    1928           1 :         VERIFY_TREES(compiler_out.str(),
    1929             : 
    1930             : "LIST\n"
    1931             : + csspp_test::get_default_variables() +
    1932             : "  COMPONENT_VALUE\n"
    1933             : "    ARG\n"
    1934             : "      IDENTIFIER \"div\"\n"
    1935             : "    OPEN_CURLYBRACKET B:true\n"
    1936             : "      DECLARATION \"z-index\"\n"
    1937             : "        ARG\n"
    1938             : "          DECIMAL_NUMBER \"\" D:30\n"
    1939             : + csspp_test::get_close_comment(true)
    1940             : 
    1941             :             );
    1942             : 
    1943           1 :         std::stringstream assembler_out;
    1944           1 :         csspp::assembler a(assembler_out);
    1945           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    1946             : 
    1947             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1948             : 
    1949           1 :         CATCH_REQUIRE(assembler_out.str() ==
    1950             : "div{z-index:30}\n"
    1951             : + csspp_test::get_close_comment()
    1952             :                 );
    1953             : 
    1954           1 :         CATCH_REQUIRE(c.get_root() == n);
    1955           1 :     }
    1956          18 :     CATCH_END_SECTION()
    1957             : 
    1958          18 :     CATCH_START_SECTION("divide two decimal numbers")
    1959             :     {
    1960           1 :         std::stringstream ss;
    1961           1 :         ss << "div { z-index: 3.2 / 12.5; }";
    1962           3 :         csspp::position pos("test.css");
    1963           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1964             : 
    1965           2 :         csspp::parser p(l);
    1966             : 
    1967           1 :         csspp::node::pointer_t n(p.stylesheet());
    1968             : 
    1969           1 :         csspp::compiler c;
    1970           1 :         c.set_root(n);
    1971           1 :         c.set_date_time_variables(csspp_test::get_now());
    1972           1 :         c.add_path(csspp_test::get_script_path());
    1973           1 :         c.add_path(csspp_test::get_version_script_path());
    1974             : 
    1975           1 :         c.compile(false);
    1976             : 
    1977           1 :         VERIFY_ERRORS("");
    1978             : 
    1979             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1980             : 
    1981             :         // to verify that the result is still an INTEGER we have to
    1982             :         // test the root node here
    1983           1 :         std::stringstream compiler_out;
    1984           1 :         compiler_out << *n;
    1985           1 :         VERIFY_TREES(compiler_out.str(),
    1986             : 
    1987             : "LIST\n"
    1988             : + csspp_test::get_default_variables() +
    1989             : "  COMPONENT_VALUE\n"
    1990             : "    ARG\n"
    1991             : "      IDENTIFIER \"div\"\n"
    1992             : "    OPEN_CURLYBRACKET B:true\n"
    1993             : "      DECLARATION \"z-index\"\n"
    1994             : "        ARG\n"
    1995             : "          DECIMAL_NUMBER \"\" D:0.256\n"
    1996             : + csspp_test::get_close_comment(true)
    1997             : 
    1998             :             );
    1999             : 
    2000           1 :         std::stringstream assembler_out;
    2001           1 :         csspp::assembler a(assembler_out);
    2002           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2003             : 
    2004             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2005             : 
    2006           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2007             : "div{z-index:.256}\n"
    2008             : + csspp_test::get_close_comment()
    2009             :                 );
    2010             : 
    2011           1 :         CATCH_REQUIRE(c.get_root() == n);
    2012           1 :     }
    2013          18 :     CATCH_END_SECTION()
    2014             : 
    2015          18 :     CATCH_START_SECTION("divide an integer with a decimal number")
    2016             :     {
    2017           1 :         std::stringstream ss;
    2018           1 :         ss << "div { z-index: 3 / 12.5; }";
    2019           3 :         csspp::position pos("test.css");
    2020           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2021             : 
    2022           2 :         csspp::parser p(l);
    2023             : 
    2024           1 :         csspp::node::pointer_t n(p.stylesheet());
    2025             : 
    2026           1 :         csspp::compiler c;
    2027           1 :         c.set_root(n);
    2028           1 :         c.set_date_time_variables(csspp_test::get_now());
    2029           1 :         c.add_path(csspp_test::get_script_path());
    2030           1 :         c.add_path(csspp_test::get_version_script_path());
    2031             : 
    2032           1 :         c.compile(false);
    2033             : 
    2034           1 :         VERIFY_ERRORS("");
    2035             : 
    2036             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2037             : 
    2038             :         // to verify that the result is still an INTEGER we have to
    2039             :         // test the root node here
    2040           1 :         std::stringstream compiler_out;
    2041           1 :         compiler_out << *n;
    2042           1 :         VERIFY_TREES(compiler_out.str(),
    2043             : 
    2044             : "LIST\n"
    2045             : + csspp_test::get_default_variables() +
    2046             : "  COMPONENT_VALUE\n"
    2047             : "    ARG\n"
    2048             : "      IDENTIFIER \"div\"\n"
    2049             : "    OPEN_CURLYBRACKET B:true\n"
    2050             : "      DECLARATION \"z-index\"\n"
    2051             : "        ARG\n"
    2052             : "          DECIMAL_NUMBER \"\" D:0.24\n"
    2053             : + csspp_test::get_close_comment(true)
    2054             : 
    2055             :             );
    2056             : 
    2057           1 :         std::stringstream assembler_out;
    2058           1 :         csspp::assembler a(assembler_out);
    2059           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2060             : 
    2061             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2062             : 
    2063           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2064             : "div{z-index:.24}\n"
    2065             : + csspp_test::get_close_comment()
    2066             :                 );
    2067             : 
    2068           1 :         CATCH_REQUIRE(c.get_root() == n);
    2069           1 :     }
    2070          18 :     CATCH_END_SECTION()
    2071             : 
    2072          18 :     CATCH_START_SECTION("divide a decimal number with an integer")
    2073             :     {
    2074           1 :         std::stringstream ss;
    2075           1 :         ss << "div { z-index: 3.5 / 10; }";
    2076           3 :         csspp::position pos("test.css");
    2077           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2078             : 
    2079           2 :         csspp::parser p(l);
    2080             : 
    2081           1 :         csspp::node::pointer_t n(p.stylesheet());
    2082             : 
    2083           1 :         csspp::compiler c;
    2084           1 :         c.set_root(n);
    2085           1 :         c.set_date_time_variables(csspp_test::get_now());
    2086           1 :         c.add_path(csspp_test::get_script_path());
    2087           1 :         c.add_path(csspp_test::get_version_script_path());
    2088             : 
    2089           1 :         c.compile(false);
    2090             : 
    2091           1 :         VERIFY_ERRORS("");
    2092             : 
    2093             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2094             : 
    2095             :         // to verify that the result is still an INTEGER we have to
    2096             :         // test the root node here
    2097           1 :         std::stringstream compiler_out;
    2098           1 :         compiler_out << *n;
    2099           1 :         VERIFY_TREES(compiler_out.str(),
    2100             : 
    2101             : "LIST\n"
    2102             : + csspp_test::get_default_variables() +
    2103             : "  COMPONENT_VALUE\n"
    2104             : "    ARG\n"
    2105             : "      IDENTIFIER \"div\"\n"
    2106             : "    OPEN_CURLYBRACKET B:true\n"
    2107             : "      DECLARATION \"z-index\"\n"
    2108             : "        ARG\n"
    2109             : "          DECIMAL_NUMBER \"\" D:0.35\n"
    2110             : + csspp_test::get_close_comment(true)
    2111             : 
    2112             :             );
    2113             : 
    2114           1 :         std::stringstream assembler_out;
    2115           1 :         csspp::assembler a(assembler_out);
    2116           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2117             : 
    2118             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2119             : 
    2120           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2121             : "div{z-index:.35}\n"
    2122             : + csspp_test::get_close_comment()
    2123             :                 );
    2124             : 
    2125           1 :         CATCH_REQUIRE(c.get_root() == n);
    2126           1 :     }
    2127          18 :     CATCH_END_SECTION()
    2128             : 
    2129          18 :     CATCH_START_SECTION("divide decimal numbers with 0 in their fraction")
    2130             :     {
    2131           1 :         std::stringstream ss;
    2132           1 :         ss << "div { z-index: 3.0 / 10.0; }";
    2133           3 :         csspp::position pos("test.css");
    2134           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2135             : 
    2136           2 :         csspp::parser p(l);
    2137             : 
    2138           1 :         csspp::node::pointer_t n(p.stylesheet());
    2139             : 
    2140           1 :         csspp::compiler c;
    2141           1 :         c.set_root(n);
    2142           1 :         c.set_date_time_variables(csspp_test::get_now());
    2143           1 :         c.add_path(csspp_test::get_script_path());
    2144           1 :         c.add_path(csspp_test::get_version_script_path());
    2145             : 
    2146           1 :         c.compile(false);
    2147             : 
    2148           1 :         VERIFY_ERRORS("");
    2149             : 
    2150             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2151             : 
    2152             :         // to verify that the result is still an INTEGER we have to
    2153             :         // test the root node here
    2154           1 :         std::stringstream compiler_out;
    2155           1 :         compiler_out << *n;
    2156           1 :         VERIFY_TREES(compiler_out.str(),
    2157             : 
    2158             : "LIST\n"
    2159             : + csspp_test::get_default_variables() +
    2160             : "  COMPONENT_VALUE\n"
    2161             : "    ARG\n"
    2162             : "      IDENTIFIER \"div\"\n"
    2163             : "    OPEN_CURLYBRACKET B:true\n"
    2164             : "      DECLARATION \"z-index\"\n"
    2165             : "        ARG\n"
    2166             : "          DECIMAL_NUMBER \"\" D:0.3\n"
    2167             : + csspp_test::get_close_comment(true)
    2168             : 
    2169             :             );
    2170             : 
    2171           1 :         std::stringstream assembler_out;
    2172           1 :         csspp::assembler a(assembler_out);
    2173           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2174             : 
    2175             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2176             : 
    2177           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2178             : "div{z-index:.3}\n"
    2179             : + csspp_test::get_close_comment()
    2180             :                 );
    2181             : 
    2182           1 :         CATCH_REQUIRE(c.get_root() == n);
    2183           1 :     }
    2184          18 :     CATCH_END_SECTION()
    2185             : 
    2186          18 :     CATCH_START_SECTION("divide an integer and a decimal number with 0 in their fraction")
    2187             :     {
    2188           1 :         std::stringstream ss;
    2189           1 :         ss << "div { z-index: 350 / 10.0; }";
    2190           3 :         csspp::position pos("test.css");
    2191           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2192             : 
    2193           2 :         csspp::parser p(l);
    2194             : 
    2195           1 :         csspp::node::pointer_t n(p.stylesheet());
    2196             : 
    2197           1 :         csspp::compiler c;
    2198           1 :         c.set_root(n);
    2199           1 :         c.set_date_time_variables(csspp_test::get_now());
    2200           1 :         c.add_path(csspp_test::get_script_path());
    2201           1 :         c.add_path(csspp_test::get_version_script_path());
    2202             : 
    2203           1 :         c.compile(false);
    2204             : 
    2205           1 :         VERIFY_ERRORS("");
    2206             : 
    2207             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2208             : 
    2209             :         // to verify that the result is still an INTEGER we have to
    2210             :         // test the root node here
    2211           1 :         std::stringstream compiler_out;
    2212           1 :         compiler_out << *n;
    2213           1 :         VERIFY_TREES(compiler_out.str(),
    2214             : 
    2215             : "LIST\n"
    2216             : + csspp_test::get_default_variables() +
    2217             : "  COMPONENT_VALUE\n"
    2218             : "    ARG\n"
    2219             : "      IDENTIFIER \"div\"\n"
    2220             : "    OPEN_CURLYBRACKET B:true\n"
    2221             : "      DECLARATION \"z-index\"\n"
    2222             : "        ARG\n"
    2223             : "          DECIMAL_NUMBER \"\" D:35\n"
    2224             : + csspp_test::get_close_comment(true)
    2225             : 
    2226             :             );
    2227             : 
    2228           1 :         std::stringstream assembler_out;
    2229           1 :         csspp::assembler a(assembler_out);
    2230           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2231             : 
    2232             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2233             : 
    2234           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2235             : "div{z-index:35}\n"
    2236             : + csspp_test::get_close_comment()
    2237             :                 );
    2238             : 
    2239           1 :         CATCH_REQUIRE(c.get_root() == n);
    2240           1 :     }
    2241          18 :     CATCH_END_SECTION()
    2242             : 
    2243          18 :     CATCH_START_SECTION("divide a decimal number with 0 in their fraction and an integer")
    2244             :     {
    2245           1 :         std::stringstream ss;
    2246           1 :         ss << "div { z-index: 30.0 / 10; }";
    2247           3 :         csspp::position pos("test.css");
    2248           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2249             : 
    2250           2 :         csspp::parser p(l);
    2251             : 
    2252           1 :         csspp::node::pointer_t n(p.stylesheet());
    2253             : 
    2254           1 :         csspp::compiler c;
    2255           1 :         c.set_root(n);
    2256           1 :         c.set_date_time_variables(csspp_test::get_now());
    2257           1 :         c.add_path(csspp_test::get_script_path());
    2258           1 :         c.add_path(csspp_test::get_version_script_path());
    2259             : 
    2260           1 :         c.compile(false);
    2261             : 
    2262           1 :         VERIFY_ERRORS("");
    2263             : 
    2264             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2265             : 
    2266             :         // to verify that the result is still an INTEGER we have to
    2267             :         // test the root node here
    2268           1 :         std::stringstream compiler_out;
    2269           1 :         compiler_out << *n;
    2270           1 :         VERIFY_TREES(compiler_out.str(),
    2271             : 
    2272             : "LIST\n"
    2273             : + csspp_test::get_default_variables() +
    2274             : "  COMPONENT_VALUE\n"
    2275             : "    ARG\n"
    2276             : "      IDENTIFIER \"div\"\n"
    2277             : "    OPEN_CURLYBRACKET B:true\n"
    2278             : "      DECLARATION \"z-index\"\n"
    2279             : "        ARG\n"
    2280             : "          DECIMAL_NUMBER \"\" D:3\n"
    2281             : + csspp_test::get_close_comment(true)
    2282             : 
    2283             :             );
    2284             : 
    2285           1 :         std::stringstream assembler_out;
    2286           1 :         csspp::assembler a(assembler_out);
    2287           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2288             : 
    2289             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2290             : 
    2291           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2292             : "div{z-index:3}\n"
    2293             : + csspp_test::get_close_comment()
    2294             :                 );
    2295             : 
    2296           1 :         CATCH_REQUIRE(c.get_root() == n);
    2297           1 :     }
    2298          18 :     CATCH_END_SECTION()
    2299             : 
    2300          18 :     CATCH_START_SECTION("modulo two decimal numbers")
    2301             :     {
    2302           1 :         std::stringstream ss;
    2303           1 :         ss << "div { z-index: 3.5 % 10.2; }";
    2304           3 :         csspp::position pos("test.css");
    2305           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2306             : 
    2307           2 :         csspp::parser p(l);
    2308             : 
    2309           1 :         csspp::node::pointer_t n(p.stylesheet());
    2310             : 
    2311           1 :         csspp::compiler c;
    2312           1 :         c.set_root(n);
    2313           1 :         c.set_date_time_variables(csspp_test::get_now());
    2314           1 :         c.add_path(csspp_test::get_script_path());
    2315           1 :         c.add_path(csspp_test::get_version_script_path());
    2316             : 
    2317           1 :         c.compile(false);
    2318             : 
    2319           1 :         VERIFY_ERRORS("");
    2320             : 
    2321             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2322             : 
    2323             :         // to verify that the result is still an INTEGER we have to
    2324             :         // test the root node here
    2325           1 :         std::stringstream compiler_out;
    2326           1 :         compiler_out << *n;
    2327           1 :         VERIFY_TREES(compiler_out.str(),
    2328             : 
    2329             : "LIST\n"
    2330             : + csspp_test::get_default_variables() +
    2331             : "  COMPONENT_VALUE\n"
    2332             : "    ARG\n"
    2333             : "      IDENTIFIER \"div\"\n"
    2334             : "    OPEN_CURLYBRACKET B:true\n"
    2335             : "      DECLARATION \"z-index\"\n"
    2336             : "        ARG\n"
    2337             : "          DECIMAL_NUMBER \"\" D:3.5\n"
    2338             : + csspp_test::get_close_comment(true)
    2339             : 
    2340             :             );
    2341             : 
    2342           1 :         std::stringstream assembler_out;
    2343           1 :         csspp::assembler a(assembler_out);
    2344           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2345             : 
    2346             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2347             : 
    2348           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2349             : "div{z-index:3.5}\n"
    2350             : + csspp_test::get_close_comment()
    2351             :                 );
    2352             : 
    2353           1 :         CATCH_REQUIRE(c.get_root() == n);
    2354           1 :     }
    2355          18 :     CATCH_END_SECTION()
    2356             : 
    2357          18 :     CATCH_START_SECTION("modulo an integer with a decimal number")
    2358             :     {
    2359           1 :         std::stringstream ss;
    2360           1 :         ss << "div { z-index: 33 % 10.2; }";
    2361           3 :         csspp::position pos("test.css");
    2362           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2363             : 
    2364           2 :         csspp::parser p(l);
    2365             : 
    2366           1 :         csspp::node::pointer_t n(p.stylesheet());
    2367             : 
    2368           1 :         csspp::compiler c;
    2369           1 :         c.set_root(n);
    2370           1 :         c.set_date_time_variables(csspp_test::get_now());
    2371           1 :         c.add_path(csspp_test::get_script_path());
    2372           1 :         c.add_path(csspp_test::get_version_script_path());
    2373             : 
    2374           1 :         c.compile(false);
    2375             : 
    2376           1 :         VERIFY_ERRORS("");
    2377             : 
    2378             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2379             : 
    2380             :         // to verify that the result is still an INTEGER we have to
    2381             :         // test the root node here
    2382           1 :         std::stringstream compiler_out;
    2383           1 :         compiler_out << *n;
    2384           1 :         VERIFY_TREES(compiler_out.str(),
    2385             : 
    2386             : "LIST\n"
    2387             : + csspp_test::get_default_variables() +
    2388             : "  COMPONENT_VALUE\n"
    2389             : "    ARG\n"
    2390             : "      IDENTIFIER \"div\"\n"
    2391             : "    OPEN_CURLYBRACKET B:true\n"
    2392             : "      DECLARATION \"z-index\"\n"
    2393             : "        ARG\n"
    2394             : "          DECIMAL_NUMBER \"\" D:2.4\n"
    2395             : + csspp_test::get_close_comment(true)
    2396             : 
    2397             :             );
    2398             : 
    2399           1 :         std::stringstream assembler_out;
    2400           1 :         csspp::assembler a(assembler_out);
    2401           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2402             : 
    2403             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2404             : 
    2405           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2406             : "div{z-index:2.4}\n"
    2407             : + csspp_test::get_close_comment()
    2408             :                 );
    2409             : 
    2410           1 :         CATCH_REQUIRE(c.get_root() == n);
    2411           1 :     }
    2412          18 :     CATCH_END_SECTION()
    2413             : 
    2414          18 :     CATCH_START_SECTION("modulo a decimal number with an integer")
    2415             :     {
    2416           1 :         std::stringstream ss;
    2417           1 :         ss << "div { z-index: 3.5 % 10; }";
    2418           3 :         csspp::position pos("test.css");
    2419           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2420             : 
    2421           2 :         csspp::parser p(l);
    2422             : 
    2423           1 :         csspp::node::pointer_t n(p.stylesheet());
    2424             : 
    2425           1 :         csspp::compiler c;
    2426           1 :         c.set_root(n);
    2427           1 :         c.set_date_time_variables(csspp_test::get_now());
    2428           1 :         c.add_path(csspp_test::get_script_path());
    2429           1 :         c.add_path(csspp_test::get_version_script_path());
    2430             : 
    2431           1 :         c.compile(false);
    2432             : 
    2433           1 :         VERIFY_ERRORS("");
    2434             : 
    2435             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2436             : 
    2437             :         // to verify that the result is still an INTEGER we have to
    2438             :         // test the root node here
    2439           1 :         std::stringstream compiler_out;
    2440           1 :         compiler_out << *n;
    2441           1 :         VERIFY_TREES(compiler_out.str(),
    2442             : 
    2443             : "LIST\n"
    2444             : + csspp_test::get_default_variables() +
    2445             : "  COMPONENT_VALUE\n"
    2446             : "    ARG\n"
    2447             : "      IDENTIFIER \"div\"\n"
    2448             : "    OPEN_CURLYBRACKET B:true\n"
    2449             : "      DECLARATION \"z-index\"\n"
    2450             : "        ARG\n"
    2451             : "          DECIMAL_NUMBER \"\" D:3.5\n"
    2452             : + csspp_test::get_close_comment(true)
    2453             : 
    2454             :             );
    2455             : 
    2456           1 :         std::stringstream assembler_out;
    2457           1 :         csspp::assembler a(assembler_out);
    2458           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2459             : 
    2460             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2461             : 
    2462           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2463             : "div{z-index:3.5}\n"
    2464             : + csspp_test::get_close_comment()
    2465             :                 );
    2466             : 
    2467           1 :         CATCH_REQUIRE(c.get_root() == n);
    2468           1 :     }
    2469          18 :     CATCH_END_SECTION()
    2470             : 
    2471          18 :     CATCH_START_SECTION("modulo decimal numbers with 0 in their fraction")
    2472             :     {
    2473           1 :         std::stringstream ss;
    2474           1 :         ss << "div { z-index: 3.0 % 10.0; }";
    2475           3 :         csspp::position pos("test.css");
    2476           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2477             : 
    2478           2 :         csspp::parser p(l);
    2479             : 
    2480           1 :         csspp::node::pointer_t n(p.stylesheet());
    2481             : 
    2482           1 :         csspp::compiler c;
    2483           1 :         c.set_root(n);
    2484           1 :         c.set_date_time_variables(csspp_test::get_now());
    2485           1 :         c.add_path(csspp_test::get_script_path());
    2486           1 :         c.add_path(csspp_test::get_version_script_path());
    2487             : 
    2488           1 :         c.compile(false);
    2489             : 
    2490           1 :         VERIFY_ERRORS("");
    2491             : 
    2492             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2493             : 
    2494             :         // to verify that the result is still an INTEGER we have to
    2495             :         // test the root node here
    2496           1 :         std::stringstream compiler_out;
    2497           1 :         compiler_out << *n;
    2498           1 :         VERIFY_TREES(compiler_out.str(),
    2499             : 
    2500             : "LIST\n"
    2501             : + csspp_test::get_default_variables() +
    2502             : "  COMPONENT_VALUE\n"
    2503             : "    ARG\n"
    2504             : "      IDENTIFIER \"div\"\n"
    2505             : "    OPEN_CURLYBRACKET B:true\n"
    2506             : "      DECLARATION \"z-index\"\n"
    2507             : "        ARG\n"
    2508             : "          DECIMAL_NUMBER \"\" D:3\n"
    2509             : + csspp_test::get_close_comment(true)
    2510             : 
    2511             :             );
    2512             : 
    2513           1 :         std::stringstream assembler_out;
    2514           1 :         csspp::assembler a(assembler_out);
    2515           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2516             : 
    2517             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2518             : 
    2519           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2520             : "div{z-index:3}\n"
    2521             : + csspp_test::get_close_comment()
    2522             :                 );
    2523             : 
    2524           1 :         CATCH_REQUIRE(c.get_root() == n);
    2525           1 :     }
    2526          18 :     CATCH_END_SECTION()
    2527             : 
    2528          18 :     CATCH_START_SECTION("modulo an integer and a decimal number with 0 in their fraction")
    2529             :     {
    2530           1 :         std::stringstream ss;
    2531           1 :         ss << "div { z-index: 3 % 10.0; }";
    2532           3 :         csspp::position pos("test.css");
    2533           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2534             : 
    2535           2 :         csspp::parser p(l);
    2536             : 
    2537           1 :         csspp::node::pointer_t n(p.stylesheet());
    2538             : 
    2539           1 :         csspp::compiler c;
    2540           1 :         c.set_root(n);
    2541           1 :         c.set_date_time_variables(csspp_test::get_now());
    2542           1 :         c.add_path(csspp_test::get_script_path());
    2543           1 :         c.add_path(csspp_test::get_version_script_path());
    2544             : 
    2545           1 :         c.compile(false);
    2546             : 
    2547           1 :         VERIFY_ERRORS("");
    2548             : 
    2549             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2550             : 
    2551             :         // to verify that the result is still an INTEGER we have to
    2552             :         // test the root node here
    2553           1 :         std::stringstream compiler_out;
    2554           1 :         compiler_out << *n;
    2555           1 :         VERIFY_TREES(compiler_out.str(),
    2556             : 
    2557             : "LIST\n"
    2558             : + csspp_test::get_default_variables() +
    2559             : "  COMPONENT_VALUE\n"
    2560             : "    ARG\n"
    2561             : "      IDENTIFIER \"div\"\n"
    2562             : "    OPEN_CURLYBRACKET B:true\n"
    2563             : "      DECLARATION \"z-index\"\n"
    2564             : "        ARG\n"
    2565             : "          DECIMAL_NUMBER \"\" D:3\n"
    2566             : + csspp_test::get_close_comment(true)
    2567             : 
    2568             :             );
    2569             : 
    2570           1 :         std::stringstream assembler_out;
    2571           1 :         csspp::assembler a(assembler_out);
    2572           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2573             : 
    2574             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2575             : 
    2576           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2577             : "div{z-index:3}\n"
    2578             : + csspp_test::get_close_comment()
    2579             :                 );
    2580             : 
    2581           1 :         CATCH_REQUIRE(c.get_root() == n);
    2582           1 :     }
    2583          18 :     CATCH_END_SECTION()
    2584             : 
    2585          18 :     CATCH_START_SECTION("modulo a decimal number with 0 in their fraction and an integer")
    2586             :     {
    2587           1 :         std::stringstream ss;
    2588           1 :         ss << "div { z-index: 3.0 % 10; }";
    2589           3 :         csspp::position pos("test.css");
    2590           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2591             : 
    2592           2 :         csspp::parser p(l);
    2593             : 
    2594           1 :         csspp::node::pointer_t n(p.stylesheet());
    2595             : 
    2596           1 :         csspp::compiler c;
    2597           1 :         c.set_root(n);
    2598           1 :         c.set_date_time_variables(csspp_test::get_now());
    2599           1 :         c.add_path(csspp_test::get_script_path());
    2600           1 :         c.add_path(csspp_test::get_version_script_path());
    2601             : 
    2602           1 :         c.compile(false);
    2603             : 
    2604           1 :         VERIFY_ERRORS("");
    2605             : 
    2606             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2607             : 
    2608             :         // to verify that the result is still an INTEGER we have to
    2609             :         // test the root node here
    2610           1 :         std::stringstream compiler_out;
    2611           1 :         compiler_out << *n;
    2612           1 :         VERIFY_TREES(compiler_out.str(),
    2613             : 
    2614             : "LIST\n"
    2615             : + csspp_test::get_default_variables() +
    2616             : "  COMPONENT_VALUE\n"
    2617             : "    ARG\n"
    2618             : "      IDENTIFIER \"div\"\n"
    2619             : "    OPEN_CURLYBRACKET B:true\n"
    2620             : "      DECLARATION \"z-index\"\n"
    2621             : "        ARG\n"
    2622             : "          DECIMAL_NUMBER \"\" D:3\n"
    2623             : + csspp_test::get_close_comment(true)
    2624             : 
    2625             :             );
    2626             : 
    2627           1 :         std::stringstream assembler_out;
    2628           1 :         csspp::assembler a(assembler_out);
    2629           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2630             : 
    2631             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2632             : 
    2633           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2634             : "div{z-index:3}\n"
    2635             : + csspp_test::get_close_comment()
    2636             :                 );
    2637             : 
    2638           1 :         CATCH_REQUIRE(c.get_root() == n);
    2639           1 :     }
    2640          18 :     CATCH_END_SECTION()
    2641             : 
    2642             :     // no error left over
    2643          18 :     VERIFY_ERRORS("");
    2644          18 : }
    2645             : 
    2646           7 : CATCH_TEST_CASE("Expression number *,/,% number with hand-made dimensions", "[expression] [multiplicative] [dimension]")
    2647             : {
    2648           7 :     CATCH_START_SECTION("px * px / px")
    2649             :     {
    2650           1 :         std::stringstream ss;
    2651           1 :         ss << "p.edged { border: { width: 25px\\ \\*\\ px / 1px; }; }";
    2652           3 :         csspp::position pos("test.css");
    2653           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2654             : 
    2655           2 :         csspp::parser p(l);
    2656             : 
    2657           1 :         csspp::node::pointer_t n(p.stylesheet());
    2658             : 
    2659             : //std::cerr << "Parser result is: [" << *n << "]\n";
    2660             : 
    2661           1 :         csspp::compiler c;
    2662           1 :         c.set_root(n);
    2663           1 :         c.set_date_time_variables(csspp_test::get_now());
    2664           1 :         c.add_path(csspp_test::get_script_path());
    2665           1 :         c.add_path(csspp_test::get_version_script_path());
    2666             : 
    2667           1 :         c.compile(false);
    2668             : 
    2669           1 :         VERIFY_ERRORS("");
    2670             : 
    2671             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2672             : 
    2673             :         // to verify that the result is still an INTEGER we have to
    2674             :         // test the root node here
    2675           1 :         std::stringstream compiler_out;
    2676           1 :         compiler_out << *n;
    2677           1 :         VERIFY_TREES(compiler_out.str(),
    2678             : 
    2679             : "LIST\n"
    2680             : + csspp_test::get_default_variables() +
    2681             : "  COMPONENT_VALUE\n"
    2682             : "    ARG\n"
    2683             : "      IDENTIFIER \"p\"\n"
    2684             : "      PERIOD\n"
    2685             : "      IDENTIFIER \"edged\"\n"
    2686             : "    OPEN_CURLYBRACKET B:true\n"
    2687             : "      DECLARATION \"border-width\"\n"
    2688             : "        ARG\n"
    2689             : "          INTEGER \"px\" I:25\n"
    2690             : + csspp_test::get_close_comment(true)
    2691             : 
    2692             :             );
    2693             : 
    2694           1 :         std::stringstream assembler_out;
    2695           1 :         csspp::assembler a(assembler_out);
    2696           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2697             : 
    2698             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2699             : 
    2700           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2701             : "p.edged{border-width:25px}\n"
    2702             : + csspp_test::get_close_comment()
    2703             :                 );
    2704             : 
    2705           1 :         CATCH_REQUIRE(c.get_root() == n);
    2706           1 :     }
    2707           7 :     CATCH_END_SECTION()
    2708             : 
    2709           7 :     CATCH_START_SECTION("px*px/px (i.e. not spaces this time)")
    2710             :     {
    2711           1 :         std::stringstream ss;
    2712           1 :         ss << "p.edged{border:{width:21px\\*px/7px};}";
    2713           3 :         csspp::position pos("test.css");
    2714           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2715             : 
    2716           2 :         csspp::parser p(l);
    2717             : 
    2718           1 :         csspp::node::pointer_t n(p.stylesheet());
    2719             : 
    2720             : //std::cerr << "Parser result is: [" << *n << "]\n";
    2721             : 
    2722           1 :         csspp::compiler c;
    2723           1 :         c.set_root(n);
    2724           1 :         c.set_date_time_variables(csspp_test::get_now());
    2725           1 :         c.add_path(csspp_test::get_script_path());
    2726           1 :         c.add_path(csspp_test::get_version_script_path());
    2727             : 
    2728           1 :         c.compile(false);
    2729             : 
    2730           1 :         VERIFY_ERRORS("");
    2731             : 
    2732             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2733             : 
    2734             :         // to verify that the result is still an INTEGER we have to
    2735             :         // test the root node here
    2736           1 :         std::stringstream compiler_out;
    2737           1 :         compiler_out << *n;
    2738           1 :         VERIFY_TREES(compiler_out.str(),
    2739             : 
    2740             : "LIST\n"
    2741             : + csspp_test::get_default_variables() +
    2742             : "  COMPONENT_VALUE\n"
    2743             : "    ARG\n"
    2744             : "      IDENTIFIER \"p\"\n"
    2745             : "      PERIOD\n"
    2746             : "      IDENTIFIER \"edged\"\n"
    2747             : "    OPEN_CURLYBRACKET B:true\n"
    2748             : "      DECLARATION \"border-width\"\n"
    2749             : "        ARG\n"
    2750             : "          INTEGER \"px\" I:3\n"
    2751             : + csspp_test::get_close_comment(true)
    2752             : 
    2753             :             );
    2754             : 
    2755           1 :         std::stringstream assembler_out;
    2756           1 :         csspp::assembler a(assembler_out);
    2757           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2758             : 
    2759             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2760             : 
    2761           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2762             : "p.edged{border-width:3px}\n"
    2763             : + csspp_test::get_close_comment()
    2764             :                 );
    2765             : 
    2766           1 :         CATCH_REQUIRE(c.get_root() == n);
    2767           1 :     }
    2768           7 :     CATCH_END_SECTION()
    2769             : 
    2770           7 :     CATCH_START_SECTION("px*px/px (i.e. not spaces this time)")
    2771             :     {
    2772           1 :         std::stringstream ss;
    2773           1 :         ss << "p.edged{border:{width:21px\\*px/7px};}";
    2774           3 :         csspp::position pos("test.css");
    2775           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2776             : 
    2777           2 :         csspp::parser p(l);
    2778             : 
    2779           1 :         csspp::node::pointer_t n(p.stylesheet());
    2780             : 
    2781             : //std::cerr << "Parser result is: [" << *n << "]\n";
    2782             : 
    2783           1 :         csspp::compiler c;
    2784           1 :         c.set_root(n);
    2785           1 :         c.set_date_time_variables(csspp_test::get_now());
    2786           1 :         c.add_path(csspp_test::get_script_path());
    2787           1 :         c.add_path(csspp_test::get_version_script_path());
    2788             : 
    2789           1 :         c.compile(false);
    2790             : 
    2791           1 :         VERIFY_ERRORS("");
    2792             : 
    2793             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2794             : 
    2795             :         // to verify that the result is still an INTEGER we have to
    2796             :         // test the root node here
    2797           1 :         std::stringstream compiler_out;
    2798           1 :         compiler_out << *n;
    2799           1 :         VERIFY_TREES(compiler_out.str(),
    2800             : 
    2801             : "LIST\n"
    2802             : + csspp_test::get_default_variables() +
    2803             : "  COMPONENT_VALUE\n"
    2804             : "    ARG\n"
    2805             : "      IDENTIFIER \"p\"\n"
    2806             : "      PERIOD\n"
    2807             : "      IDENTIFIER \"edged\"\n"
    2808             : "    OPEN_CURLYBRACKET B:true\n"
    2809             : "      DECLARATION \"border-width\"\n"
    2810             : "        ARG\n"
    2811             : "          INTEGER \"px\" I:3\n"
    2812             : + csspp_test::get_close_comment(true)
    2813             : 
    2814             :             );
    2815             : 
    2816           1 :         std::stringstream assembler_out;
    2817           1 :         csspp::assembler a(assembler_out);
    2818           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2819             : 
    2820             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2821             : 
    2822           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2823             : "p.edged{border-width:3px}\n"
    2824             : + csspp_test::get_close_comment()
    2825             :                 );
    2826             : 
    2827           1 :         CATCH_REQUIRE(c.get_root() == n);
    2828           1 :     }
    2829           7 :     CATCH_END_SECTION()
    2830             : 
    2831           7 :     CATCH_START_SECTION("em *px / px (missing one space")
    2832             :     {
    2833           1 :         std::stringstream ss;
    2834           1 :         ss << "p.edged{border:{width:28em\\ \\*px/7px};}";
    2835           3 :         csspp::position pos("test.css");
    2836           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2837             : 
    2838           2 :         csspp::parser p(l);
    2839             : 
    2840           1 :         csspp::node::pointer_t n(p.stylesheet());
    2841             : 
    2842             : //std::cerr << "Parser result is: [" << *n << "]\n";
    2843             : 
    2844           1 :         csspp::compiler c;
    2845           1 :         c.set_root(n);
    2846           1 :         c.set_date_time_variables(csspp_test::get_now());
    2847           1 :         c.add_path(csspp_test::get_script_path());
    2848           1 :         c.add_path(csspp_test::get_version_script_path());
    2849             : 
    2850           1 :         c.compile(false);
    2851             : 
    2852           1 :         VERIFY_ERRORS("");
    2853             : 
    2854             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2855             : 
    2856             :         // to verify that the result is still an INTEGER we have to
    2857             :         // test the root node here
    2858           1 :         std::stringstream compiler_out;
    2859           1 :         compiler_out << *n;
    2860           1 :         VERIFY_TREES(compiler_out.str(),
    2861             : 
    2862             : "LIST\n"
    2863             : + csspp_test::get_default_variables() +
    2864             : "  COMPONENT_VALUE\n"
    2865             : "    ARG\n"
    2866             : "      IDENTIFIER \"p\"\n"
    2867             : "      PERIOD\n"
    2868             : "      IDENTIFIER \"edged\"\n"
    2869             : "    OPEN_CURLYBRACKET B:true\n"
    2870             : "      DECLARATION \"border-width\"\n"
    2871             : "        ARG\n"
    2872             : "          INTEGER \"em\" I:4\n"
    2873             : + csspp_test::get_close_comment(true)
    2874             : 
    2875             :             );
    2876             : 
    2877           1 :         std::stringstream assembler_out;
    2878           1 :         csspp::assembler a(assembler_out);
    2879           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2880             : 
    2881             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2882             : 
    2883           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2884             : "p.edged{border-width:4em}\n"
    2885             : + csspp_test::get_close_comment()
    2886             :                 );
    2887             : 
    2888           1 :         CATCH_REQUIRE(c.get_root() == n);
    2889           1 :     }
    2890           7 :     CATCH_END_SECTION()
    2891             : 
    2892           7 :     CATCH_START_SECTION("em* px / px (missing the other space)")
    2893             :     {
    2894           1 :         std::stringstream ss;
    2895           1 :         ss << "p.edged{border:{width:28em\\*\\ px/7px};}";
    2896           3 :         csspp::position pos("test.css");
    2897           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2898             : 
    2899           2 :         csspp::parser p(l);
    2900             : 
    2901           1 :         csspp::node::pointer_t n(p.stylesheet());
    2902             : 
    2903             : //std::cerr << "Parser result is: [" << *n << "]\n";
    2904             : 
    2905           1 :         csspp::compiler c;
    2906           1 :         c.set_root(n);
    2907           1 :         c.set_date_time_variables(csspp_test::get_now());
    2908           1 :         c.add_path(csspp_test::get_script_path());
    2909           1 :         c.add_path(csspp_test::get_version_script_path());
    2910             : 
    2911           1 :         c.compile(false);
    2912             : 
    2913           1 :         VERIFY_ERRORS("");
    2914             : 
    2915             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2916             : 
    2917             :         // to verify that the result is still an INTEGER we have to
    2918             :         // test the root node here
    2919           1 :         std::stringstream compiler_out;
    2920           1 :         compiler_out << *n;
    2921           1 :         VERIFY_TREES(compiler_out.str(),
    2922             : 
    2923             : "LIST\n"
    2924             : + csspp_test::get_default_variables() +
    2925             : "  COMPONENT_VALUE\n"
    2926             : "    ARG\n"
    2927             : "      IDENTIFIER \"p\"\n"
    2928             : "      PERIOD\n"
    2929             : "      IDENTIFIER \"edged\"\n"
    2930             : "    OPEN_CURLYBRACKET B:true\n"
    2931             : "      DECLARATION \"border-width\"\n"
    2932             : "        ARG\n"
    2933             : "          INTEGER \"em\" I:4\n"
    2934             : + csspp_test::get_close_comment(true)
    2935             : 
    2936             :             );
    2937             : 
    2938           1 :         std::stringstream assembler_out;
    2939           1 :         csspp::assembler a(assembler_out);
    2940           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    2941             : 
    2942             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2943             : 
    2944           1 :         CATCH_REQUIRE(assembler_out.str() ==
    2945             : "p.edged{border-width:4em}\n"
    2946             : + csspp_test::get_close_comment()
    2947             :                 );
    2948             : 
    2949           1 :         CATCH_REQUIRE(c.get_root() == n);
    2950           1 :     }
    2951           7 :     CATCH_END_SECTION()
    2952             : 
    2953           7 :     CATCH_START_SECTION("one space after the dimension is ignored")
    2954             :     {
    2955           1 :         std::stringstream ss;
    2956           1 :         ss << "p.edged{border:{width:28em\\ *1px};}";
    2957           3 :         csspp::position pos("test.css");
    2958           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2959             : 
    2960           2 :         csspp::parser p(l);
    2961             : 
    2962           1 :         csspp::node::pointer_t n(p.stylesheet());
    2963             : 
    2964             : //std::cerr << "Parser result is: [" << *n << "]\n";
    2965             : 
    2966           1 :         csspp::compiler c;
    2967           1 :         c.set_root(n);
    2968           1 :         c.set_date_time_variables(csspp_test::get_now());
    2969           1 :         c.add_path(csspp_test::get_script_path());
    2970           1 :         c.add_path(csspp_test::get_version_script_path());
    2971             : 
    2972           1 :         c.compile(false);
    2973             : 
    2974           1 :         VERIFY_ERRORS("");
    2975             : 
    2976             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2977             : 
    2978             :         // to verify that the result is still an INTEGER we have to
    2979             :         // test the root node here
    2980           1 :         std::stringstream compiler_out;
    2981           1 :         compiler_out << *n;
    2982           1 :         VERIFY_TREES(compiler_out.str(),
    2983             : 
    2984             : "LIST\n"
    2985             : + csspp_test::get_default_variables() +
    2986             : "  COMPONENT_VALUE\n"
    2987             : "    ARG\n"
    2988             : "      IDENTIFIER \"p\"\n"
    2989             : "      PERIOD\n"
    2990             : "      IDENTIFIER \"edged\"\n"
    2991             : "    OPEN_CURLYBRACKET B:true\n"
    2992             : "      DECLARATION \"border-width\"\n"
    2993             : "        ARG\n"
    2994             : "          INTEGER \"em * px\" I:28\n"
    2995             : + csspp_test::get_close_comment(true)
    2996             : 
    2997             :             );
    2998             : 
    2999             : // Output would fail because of the double dimension...
    3000             : //         std::stringstream assembler_out;
    3001             : //         csspp::assembler a(assembler_out);
    3002             : //         a.output(n, csspp::output_mode_t::COMPRESSED);
    3003             : // 
    3004             : // //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3005             : // 
    3006             : //         CATCH_REQUIRE(assembler_out.str() ==
    3007             : // "p.edged{border-width:4em}\n"
    3008             : // + csspp_test::get_close_comment()
    3009             : //                 );
    3010             : 
    3011           1 :         CATCH_REQUIRE(c.get_root() == n);
    3012           1 :     }
    3013           7 :     CATCH_END_SECTION()
    3014             : 
    3015           7 :     CATCH_START_SECTION("\"1 / px\" test")
    3016             :     {
    3017           1 :         std::stringstream ss;
    3018             :         // IMPORTANT NOTE: to start the dimension with "1" we need to
    3019             :         //                 use escape character '\\31'
    3020           1 :         ss << "p .edged { border : { width : 28\\31 \\/\\ em * 3em * 5px; } ; }";
    3021           3 :         csspp::position pos("test.css");
    3022           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3023             : 
    3024           2 :         csspp::parser p(l);
    3025             : 
    3026           1 :         csspp::node::pointer_t n(p.stylesheet());
    3027             : 
    3028             : //std::cerr << "Parser result is: [" << *n << "]\n";
    3029             : 
    3030           1 :         csspp::compiler c;
    3031           1 :         c.set_root(n);
    3032           1 :         c.set_date_time_variables(csspp_test::get_now());
    3033           1 :         c.add_path(csspp_test::get_script_path());
    3034           1 :         c.add_path(csspp_test::get_version_script_path());
    3035             : 
    3036           1 :         c.compile(false);
    3037             : 
    3038           1 :         VERIFY_ERRORS("");
    3039             : 
    3040             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3041             : 
    3042             :         // to verify that the result is still an INTEGER we have to
    3043             :         // test the root node here
    3044           1 :         std::stringstream compiler_out;
    3045           1 :         compiler_out << *n;
    3046           1 :         VERIFY_TREES(compiler_out.str(),
    3047             : 
    3048             : "LIST\n"
    3049             : + csspp_test::get_default_variables() +
    3050             : "  COMPONENT_VALUE\n"
    3051             : "    ARG\n"
    3052             : "      IDENTIFIER \"p\"\n"
    3053             : "      WHITESPACE\n"
    3054             : "      PERIOD\n"
    3055             : "      IDENTIFIER \"edged\"\n"
    3056             : "    OPEN_CURLYBRACKET B:true\n"
    3057             : "      DECLARATION \"border-width\"\n"
    3058             : "        ARG\n"
    3059             : "          INTEGER \"px\" I:420\n"
    3060             : + csspp_test::get_close_comment(true)
    3061             : 
    3062             :             );
    3063             : 
    3064           1 :         std::stringstream assembler_out;
    3065           1 :         csspp::assembler a(assembler_out);
    3066           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3067             : 
    3068             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3069             : 
    3070           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3071             : "p .edged{border-width:420px}\n"
    3072             : + csspp_test::get_close_comment()
    3073             :                 );
    3074             : 
    3075           1 :         CATCH_REQUIRE(c.get_root() == n);
    3076           1 :     }
    3077           7 :     CATCH_END_SECTION()
    3078             : 
    3079             :     // make sure we really had no errors
    3080           7 :     VERIFY_ERRORS("");
    3081           7 : }
    3082             : 
    3083           8 : CATCH_TEST_CASE("Expression number *,/,% number with invalid hand-made dimensions", "[expression] [multiplicative] [invalid] [dimension]")
    3084             : {
    3085           8 :     CATCH_START_SECTION("\"25px *\" -- missing second dimension")
    3086             :     {
    3087           1 :         std::stringstream ss;
    3088           1 :         ss << "p.edged { width: 25px\\ \\* * 3px; }";
    3089           3 :         csspp::position pos("test.css");
    3090           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3091             : 
    3092           2 :         csspp::parser p(l);
    3093             : 
    3094           1 :         csspp::node::pointer_t n(p.stylesheet());
    3095             : 
    3096             : //std::cerr << "Parser result is: [" << *n << "]\n";
    3097             : 
    3098           1 :         csspp::compiler c;
    3099           1 :         c.set_root(n);
    3100           1 :         c.set_date_time_variables(csspp_test::get_now());
    3101           1 :         c.add_path(csspp_test::get_script_path());
    3102           1 :         c.add_path(csspp_test::get_version_script_path());
    3103             : 
    3104           1 :         c.compile(false);
    3105             : 
    3106           1 :         VERIFY_ERRORS("test.css(1): error: number dimension is missing a dimension name.\n");
    3107             : 
    3108             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3109             : 
    3110           1 :         CATCH_REQUIRE(c.get_root() == n);
    3111           1 :     }
    3112           8 :     CATCH_END_SECTION()
    3113             : 
    3114           8 :     CATCH_START_SECTION("\"25px*\" -- missing second dimension (no space)")
    3115             :     {
    3116           1 :         std::stringstream ss;
    3117           1 :         ss << "p.edged { width: 25px\\* * 3px; }";
    3118           3 :         csspp::position pos("test.css");
    3119           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3120             : 
    3121           2 :         csspp::parser p(l);
    3122             : 
    3123           1 :         csspp::node::pointer_t n(p.stylesheet());
    3124             : 
    3125             : //std::cerr << "Parser result is: [" << *n << "]\n";
    3126             : 
    3127           1 :         csspp::compiler c;
    3128           1 :         c.set_root(n);
    3129           1 :         c.set_date_time_variables(csspp_test::get_now());
    3130           1 :         c.add_path(csspp_test::get_script_path());
    3131           1 :         c.add_path(csspp_test::get_version_script_path());
    3132             : 
    3133           1 :         c.compile(false);
    3134             : 
    3135           1 :         VERIFY_ERRORS("test.css(1): error: number dimension is missing a dimension name.\n");
    3136             : 
    3137             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3138             : 
    3139           1 :         CATCH_REQUIRE(c.get_root() == n);
    3140           1 :     }
    3141           8 :     CATCH_END_SECTION()
    3142             : 
    3143           8 :     CATCH_START_SECTION("\"25\\ *\\ px\" -- missing first dimension")
    3144             :     {
    3145           1 :         std::stringstream ss;
    3146           1 :         ss << "p.edged { width: 25\\ \\*\\ px * 3px; }";
    3147           3 :         csspp::position pos("test.css");
    3148           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3149             : 
    3150           2 :         csspp::parser p(l);
    3151             : 
    3152           1 :         csspp::node::pointer_t n(p.stylesheet());
    3153             : 
    3154             : //std::cerr << "Parser result is: [" << *n << "]\n";
    3155             : 
    3156           1 :         csspp::compiler c;
    3157           1 :         c.set_root(n);
    3158           1 :         c.set_date_time_variables(csspp_test::get_now());
    3159           1 :         c.add_path(csspp_test::get_script_path());
    3160           1 :         c.add_path(csspp_test::get_version_script_path());
    3161             : 
    3162           1 :         c.compile(false);
    3163             : 
    3164           1 :         VERIFY_ERRORS("test.css(1): error: number dimension is missing a dimension name.\n");
    3165             : 
    3166             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3167             : 
    3168           1 :         CATCH_REQUIRE(c.get_root() == n);
    3169           1 :     }
    3170           8 :     CATCH_END_SECTION()
    3171             : 
    3172           8 :     CATCH_START_SECTION("\"25\\*px\" -- missing first dimension (no space)")
    3173             :     {
    3174           1 :         std::stringstream ss;
    3175           1 :         ss << "p.edged { width: 25\\*px * 3px; }";
    3176           3 :         csspp::position pos("test.css");
    3177           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3178             : 
    3179           2 :         csspp::parser p(l);
    3180             : 
    3181           1 :         csspp::node::pointer_t n(p.stylesheet());
    3182             : 
    3183             : //std::cerr << "Parser result is: [" << *n << "]\n";
    3184             : 
    3185           1 :         csspp::compiler c;
    3186           1 :         c.set_root(n);
    3187           1 :         c.set_date_time_variables(csspp_test::get_now());
    3188           1 :         c.add_path(csspp_test::get_script_path());
    3189           1 :         c.add_path(csspp_test::get_version_script_path());
    3190             : 
    3191           1 :         c.compile(false);
    3192             : 
    3193           1 :         VERIFY_ERRORS("test.css(1): error: number dimension is missing a dimension name.\n");
    3194             : 
    3195             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3196             : 
    3197           1 :         CATCH_REQUIRE(c.get_root() == n);
    3198           1 :     }
    3199           8 :     CATCH_END_SECTION()
    3200             : 
    3201           8 :     CATCH_START_SECTION("\"px / em / pt\" -- two slashes is not valid")
    3202             :     {
    3203           1 :         std::stringstream ss;
    3204           1 :         ss << "p.edged { width: 25px\\ \\/\\ em\\ \\/\\ pt * 3px; }";
    3205           3 :         csspp::position pos("test.css");
    3206           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3207             : 
    3208           2 :         csspp::parser p(l);
    3209             : 
    3210           1 :         csspp::node::pointer_t n(p.stylesheet());
    3211             : 
    3212             : //std::cerr << "Parser result is: [" << *n << "]\n";
    3213             : 
    3214           1 :         csspp::compiler c;
    3215           1 :         c.set_root(n);
    3216           1 :         c.set_date_time_variables(csspp_test::get_now());
    3217           1 :         c.add_path(csspp_test::get_script_path());
    3218           1 :         c.add_path(csspp_test::get_version_script_path());
    3219             : 
    3220           1 :         c.compile(false);
    3221             : 
    3222           1 :         VERIFY_ERRORS("test.css(1): error: a valid dimension can have any number of '*' operators and a single '/' operator, here we found a second '/'.\n");
    3223             : 
    3224             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3225             : 
    3226           1 :         CATCH_REQUIRE(c.get_root() == n);
    3227           1 :     }
    3228           8 :     CATCH_END_SECTION()
    3229             : 
    3230           8 :     CATCH_START_SECTION("\"1 / em / pt\" -- two slashes is not valid")
    3231             :     {
    3232           1 :         std::stringstream ss;
    3233             :         // IMPORTANT NOTE: to start the dimension with "1" we need to
    3234             :         //                 use escape character '\\31'
    3235           1 :         ss << "p.edged { width: 25\\31\\ \\/\\ em\\ \\/\\ pt * 3px; }";
    3236           3 :         csspp::position pos("test.css");
    3237           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3238             : 
    3239           2 :         csspp::parser p(l);
    3240             : 
    3241           1 :         csspp::node::pointer_t n(p.stylesheet());
    3242             : 
    3243             : //std::cerr << "Parser result is: [" << *n << "]\n";
    3244             : 
    3245           1 :         csspp::compiler c;
    3246           1 :         c.set_root(n);
    3247           1 :         c.set_date_time_variables(csspp_test::get_now());
    3248           1 :         c.add_path(csspp_test::get_script_path());
    3249           1 :         c.add_path(csspp_test::get_version_script_path());
    3250             : 
    3251           1 :         c.compile(false);
    3252             : 
    3253           1 :         VERIFY_ERRORS("test.css(1): error: a valid dimension can have any number of '*' operators and a single '/' operator, here we found a second '/'.\n");
    3254             : 
    3255             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3256             : 
    3257           1 :         CATCH_REQUIRE(c.get_root() == n);
    3258           1 :     }
    3259           8 :     CATCH_END_SECTION()
    3260             : 
    3261           8 :     CATCH_START_SECTION("\"1/em/pt\" -- two slashes is not valid (no spaces)")
    3262             :     {
    3263           1 :         std::stringstream ss;
    3264             :         // IMPORTANT NOTE: to start the dimension with "1" we need to
    3265             :         //                 use escape character '\\31'
    3266           1 :         ss << "p.edged { width: 25\\31\\/em\\/pt * 3px; }";
    3267           3 :         csspp::position pos("test.css");
    3268           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3269             : 
    3270           2 :         csspp::parser p(l);
    3271             : 
    3272           1 :         csspp::node::pointer_t n(p.stylesheet());
    3273             : 
    3274             : //std::cerr << "Parser result is: [" << *n << "]\n";
    3275             : 
    3276           1 :         csspp::compiler c;
    3277           1 :         c.set_root(n);
    3278           1 :         c.set_date_time_variables(csspp_test::get_now());
    3279           1 :         c.add_path(csspp_test::get_script_path());
    3280           1 :         c.add_path(csspp_test::get_version_script_path());
    3281             : 
    3282           1 :         c.compile(false);
    3283             : 
    3284           1 :         VERIFY_ERRORS("test.css(1): error: a valid dimension can have any number of '*' operators and a single '/' operator, here we found a second '/'.\n");
    3285             : 
    3286             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3287             : 
    3288           1 :         CATCH_REQUIRE(c.get_root() == n);
    3289           1 :     }
    3290           8 :     CATCH_END_SECTION()
    3291             : 
    3292           8 :     CATCH_START_SECTION("\"em % pt\" -- '%' is not a valid dimension separator")
    3293             :     {
    3294           1 :         std::stringstream ss;
    3295           1 :         ss << "p.edged { width: 25em\\ \\%\\ pt / 5pt; }";
    3296           3 :         csspp::position pos("test.css");
    3297           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3298             : 
    3299           2 :         csspp::parser p(l);
    3300             : 
    3301           1 :         csspp::node::pointer_t n(p.stylesheet());
    3302             : 
    3303             : //std::cerr << "Parser result is: [" << *n << "]\n";
    3304             : 
    3305           1 :         csspp::compiler c;
    3306           1 :         c.set_root(n);
    3307           1 :         c.set_date_time_variables(csspp_test::get_now());
    3308           1 :         c.add_path(csspp_test::get_script_path());
    3309           1 :         c.add_path(csspp_test::get_version_script_path());
    3310             : 
    3311           1 :         c.compile(false);
    3312             : 
    3313           1 :         VERIFY_ERRORS("test.css(1): error: multiple dimensions can only be separated by '*' or '/' not '%'.\n");
    3314             : 
    3315             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3316             : 
    3317           1 :         CATCH_REQUIRE(c.get_root() == n);
    3318           1 :     }
    3319           8 :     CATCH_END_SECTION()
    3320             : 
    3321             :     // make sure we really had no errors
    3322           8 :     VERIFY_ERRORS("");
    3323           8 : }
    3324             : 
    3325          15 : CATCH_TEST_CASE("Expression percent *,/,% percent", "[expression] [multiplicative]")
    3326             : {
    3327          15 :     CATCH_START_SECTION("percent multiplication")
    3328             :     {
    3329           1 :         std::stringstream ss;
    3330           1 :         ss << "div { height: 3.5% * 10.2%; }";
    3331           3 :         csspp::position pos("test.css");
    3332           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3333             : 
    3334           2 :         csspp::parser p(l);
    3335             : 
    3336           1 :         csspp::node::pointer_t n(p.stylesheet());
    3337             : 
    3338           1 :         csspp::compiler c;
    3339           1 :         c.set_root(n);
    3340           1 :         c.set_date_time_variables(csspp_test::get_now());
    3341           1 :         c.add_path(csspp_test::get_script_path());
    3342           1 :         c.add_path(csspp_test::get_version_script_path());
    3343             : 
    3344           1 :         c.compile(false);
    3345             : 
    3346           1 :         VERIFY_ERRORS("");
    3347             : 
    3348             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3349             : 
    3350             :         // to verify that the result is still an INTEGER we have to
    3351             :         // test the root node here
    3352           1 :         std::stringstream compiler_out;
    3353           1 :         compiler_out << *n;
    3354           1 :         VERIFY_TREES(compiler_out.str(),
    3355             : 
    3356             : "LIST\n"
    3357             : + csspp_test::get_default_variables() +
    3358             : "  COMPONENT_VALUE\n"
    3359             : "    ARG\n"
    3360             : "      IDENTIFIER \"div\"\n"
    3361             : "    OPEN_CURLYBRACKET B:true\n"
    3362             : "      DECLARATION \"height\"\n"
    3363             : "        ARG\n"
    3364             : "          PERCENT D:0.004\n"
    3365             : + csspp_test::get_close_comment(true)
    3366             : 
    3367             :             );
    3368             : 
    3369           1 :         std::stringstream assembler_out;
    3370           1 :         csspp::assembler a(assembler_out);
    3371           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3372             : 
    3373             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3374             : 
    3375           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3376             : "div{height:.357%}\n"
    3377             : + csspp_test::get_close_comment()
    3378             :                 );
    3379             : 
    3380           1 :         CATCH_REQUIRE(c.get_root() == n);
    3381           1 :     }
    3382          15 :     CATCH_END_SECTION()
    3383             : 
    3384          15 :     CATCH_START_SECTION("percent multiplication with what looks like an integer (lhs)")
    3385             :     {
    3386           1 :         std::stringstream ss;
    3387           1 :         ss << "div { height: 3% * 10.2%; }";
    3388           3 :         csspp::position pos("test.css");
    3389           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3390             : 
    3391           2 :         csspp::parser p(l);
    3392             : 
    3393           1 :         csspp::node::pointer_t n(p.stylesheet());
    3394             : 
    3395           1 :         csspp::compiler c;
    3396           1 :         c.set_root(n);
    3397           1 :         c.set_date_time_variables(csspp_test::get_now());
    3398           1 :         c.add_path(csspp_test::get_script_path());
    3399           1 :         c.add_path(csspp_test::get_version_script_path());
    3400             : 
    3401           1 :         c.compile(false);
    3402             : 
    3403           1 :         VERIFY_ERRORS("");
    3404             : 
    3405             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3406             : 
    3407             :         // to verify that the result is still an INTEGER we have to
    3408             :         // test the root node here
    3409           1 :         std::stringstream compiler_out;
    3410           1 :         compiler_out << *n;
    3411           1 :         VERIFY_TREES(compiler_out.str(),
    3412             : 
    3413             : "LIST\n"
    3414             : + csspp_test::get_default_variables() +
    3415             : "  COMPONENT_VALUE\n"
    3416             : "    ARG\n"
    3417             : "      IDENTIFIER \"div\"\n"
    3418             : "    OPEN_CURLYBRACKET B:true\n"
    3419             : "      DECLARATION \"height\"\n"
    3420             : "        ARG\n"
    3421             : "          PERCENT D:0.003\n"
    3422             : + csspp_test::get_close_comment(true)
    3423             : 
    3424             :             );
    3425             : 
    3426           1 :         std::stringstream assembler_out;
    3427           1 :         csspp::assembler a(assembler_out);
    3428           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3429             : 
    3430             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3431             : 
    3432           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3433             : "div{height:.306%}\n"
    3434             : + csspp_test::get_close_comment()
    3435             :                 );
    3436             : 
    3437           1 :         CATCH_REQUIRE(c.get_root() == n);
    3438           1 :     }
    3439          15 :     CATCH_END_SECTION()
    3440             : 
    3441          15 :     CATCH_START_SECTION("percent multiplication with what looks like an integer (rhs)")
    3442             :     {
    3443           1 :         std::stringstream ss;
    3444           1 :         ss << "div { height: 3.5% * 10%; }";
    3445           3 :         csspp::position pos("test.css");
    3446           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3447             : 
    3448           2 :         csspp::parser p(l);
    3449             : 
    3450           1 :         csspp::node::pointer_t n(p.stylesheet());
    3451             : 
    3452           1 :         csspp::compiler c;
    3453           1 :         c.set_root(n);
    3454           1 :         c.set_date_time_variables(csspp_test::get_now());
    3455           1 :         c.add_path(csspp_test::get_script_path());
    3456           1 :         c.add_path(csspp_test::get_version_script_path());
    3457             : 
    3458           1 :         c.compile(false);
    3459             : 
    3460           1 :         VERIFY_ERRORS("");
    3461             : 
    3462             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3463             : 
    3464             :         // to verify that the result is still an INTEGER we have to
    3465             :         // test the root node here
    3466           1 :         std::stringstream compiler_out;
    3467           1 :         compiler_out << *n;
    3468           1 :         VERIFY_TREES(compiler_out.str(),
    3469             : 
    3470             : "LIST\n"
    3471             : + csspp_test::get_default_variables() +
    3472             : "  COMPONENT_VALUE\n"
    3473             : "    ARG\n"
    3474             : "      IDENTIFIER \"div\"\n"
    3475             : "    OPEN_CURLYBRACKET B:true\n"
    3476             : "      DECLARATION \"height\"\n"
    3477             : "        ARG\n"
    3478             : "          PERCENT D:0.004\n"
    3479             : + csspp_test::get_close_comment(true)
    3480             : 
    3481             :             );
    3482             : 
    3483           1 :         std::stringstream assembler_out;
    3484           1 :         csspp::assembler a(assembler_out);
    3485           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3486             : 
    3487             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3488             : 
    3489           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3490             : "div{height:.35%}\n"
    3491             : + csspp_test::get_close_comment()
    3492             :                 );
    3493             : 
    3494           1 :         CATCH_REQUIRE(c.get_root() == n);
    3495           1 :     }
    3496          15 :     CATCH_END_SECTION()
    3497             : 
    3498          15 :     CATCH_START_SECTION("percent division")
    3499             :     {
    3500           1 :         std::stringstream ss;
    3501           1 :         ss << "div { height: 3.5% / 12.5%; }";
    3502           3 :         csspp::position pos("test.css");
    3503           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3504             : 
    3505           2 :         csspp::parser p(l);
    3506             : 
    3507           1 :         csspp::node::pointer_t n(p.stylesheet());
    3508             : 
    3509           1 :         csspp::compiler c;
    3510           1 :         c.set_root(n);
    3511           1 :         c.set_date_time_variables(csspp_test::get_now());
    3512           1 :         c.add_path(csspp_test::get_script_path());
    3513           1 :         c.add_path(csspp_test::get_version_script_path());
    3514             : 
    3515           1 :         c.compile(false);
    3516             : 
    3517           1 :         VERIFY_ERRORS("");
    3518             : 
    3519             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3520             : 
    3521             :         // to verify that the result is still an INTEGER we have to
    3522             :         // test the root node here
    3523           1 :         std::stringstream compiler_out;
    3524           1 :         compiler_out << *n;
    3525           1 :         VERIFY_TREES(compiler_out.str(),
    3526             : 
    3527             : "LIST\n"
    3528             : + csspp_test::get_default_variables() +
    3529             : "  COMPONENT_VALUE\n"
    3530             : "    ARG\n"
    3531             : "      IDENTIFIER \"div\"\n"
    3532             : "    OPEN_CURLYBRACKET B:true\n"
    3533             : "      DECLARATION \"height\"\n"
    3534             : "        ARG\n"
    3535             : "          PERCENT D:0.28\n"
    3536             : + csspp_test::get_close_comment(true)
    3537             : 
    3538             :             );
    3539             : 
    3540           1 :         std::stringstream assembler_out;
    3541           1 :         csspp::assembler a(assembler_out);
    3542           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3543             : 
    3544             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3545             : 
    3546           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3547             : "div{height:28%}\n"
    3548             : + csspp_test::get_close_comment()
    3549             :                 );
    3550             : 
    3551           1 :         CATCH_REQUIRE(c.get_root() == n);
    3552           1 :     }
    3553          15 :     CATCH_END_SECTION()
    3554             : 
    3555          15 :     CATCH_START_SECTION("percent division with what looks like an integer (lhs)")
    3556             :     {
    3557           1 :         std::stringstream ss;
    3558           1 :         ss << "div { height: 3% / 12.5%; }";
    3559           3 :         csspp::position pos("test.css");
    3560           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3561             : 
    3562           2 :         csspp::parser p(l);
    3563             : 
    3564           1 :         csspp::node::pointer_t n(p.stylesheet());
    3565             : 
    3566           1 :         csspp::compiler c;
    3567           1 :         c.set_root(n);
    3568           1 :         c.set_date_time_variables(csspp_test::get_now());
    3569           1 :         c.add_path(csspp_test::get_script_path());
    3570           1 :         c.add_path(csspp_test::get_version_script_path());
    3571             : 
    3572           1 :         c.compile(false);
    3573             : 
    3574           1 :         VERIFY_ERRORS("");
    3575             : 
    3576             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3577             : 
    3578             :         // to verify that the result is still an INTEGER we have to
    3579             :         // test the root node here
    3580           1 :         std::stringstream compiler_out;
    3581           1 :         compiler_out << *n;
    3582           1 :         VERIFY_TREES(compiler_out.str(),
    3583             : 
    3584             : "LIST\n"
    3585             : + csspp_test::get_default_variables() +
    3586             : "  COMPONENT_VALUE\n"
    3587             : "    ARG\n"
    3588             : "      IDENTIFIER \"div\"\n"
    3589             : "    OPEN_CURLYBRACKET B:true\n"
    3590             : "      DECLARATION \"height\"\n"
    3591             : "        ARG\n"
    3592             : "          PERCENT D:0.24\n"
    3593             : + csspp_test::get_close_comment(true)
    3594             : 
    3595             :             );
    3596             : 
    3597           1 :         std::stringstream assembler_out;
    3598           1 :         csspp::assembler a(assembler_out);
    3599           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3600             : 
    3601             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3602             : 
    3603           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3604             : "div{height:24%}\n"
    3605             : + csspp_test::get_close_comment()
    3606             :                 );
    3607             : 
    3608           1 :         CATCH_REQUIRE(c.get_root() == n);
    3609           1 :     }
    3610          15 :     CATCH_END_SECTION()
    3611             : 
    3612          15 :     CATCH_START_SECTION("percent division with what looks like an integer (rhs)")
    3613             :     {
    3614           1 :         std::stringstream ss;
    3615           1 :         ss << "div { height: 3.5% / 10%; }";
    3616           3 :         csspp::position pos("test.css");
    3617           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3618             : 
    3619           2 :         csspp::parser p(l);
    3620             : 
    3621           1 :         csspp::node::pointer_t n(p.stylesheet());
    3622             : 
    3623           1 :         csspp::compiler c;
    3624           1 :         c.set_root(n);
    3625           1 :         c.set_date_time_variables(csspp_test::get_now());
    3626           1 :         c.add_path(csspp_test::get_script_path());
    3627           1 :         c.add_path(csspp_test::get_version_script_path());
    3628             : 
    3629           1 :         c.compile(false);
    3630             : 
    3631           1 :         VERIFY_ERRORS("");
    3632             : 
    3633             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3634             : 
    3635             :         // to verify that the result is still an INTEGER we have to
    3636             :         // test the root node here
    3637           1 :         std::stringstream compiler_out;
    3638           1 :         compiler_out << *n;
    3639           1 :         VERIFY_TREES(compiler_out.str(),
    3640             : 
    3641             : "LIST\n"
    3642             : + csspp_test::get_default_variables() +
    3643             : "  COMPONENT_VALUE\n"
    3644             : "    ARG\n"
    3645             : "      IDENTIFIER \"div\"\n"
    3646             : "    OPEN_CURLYBRACKET B:true\n"
    3647             : "      DECLARATION \"height\"\n"
    3648             : "        ARG\n"
    3649             : "          PERCENT D:0.35\n"
    3650             : + csspp_test::get_close_comment(true)
    3651             : 
    3652             :             );
    3653             : 
    3654           1 :         std::stringstream assembler_out;
    3655           1 :         csspp::assembler a(assembler_out);
    3656           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3657             : 
    3658             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3659             : 
    3660           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3661             : "div{height:35%}\n"
    3662             : + csspp_test::get_close_comment()
    3663             :                 );
    3664             : 
    3665           1 :         CATCH_REQUIRE(c.get_root() == n);
    3666           1 :     }
    3667          15 :     CATCH_END_SECTION()
    3668             : 
    3669          15 :     CATCH_START_SECTION("percent modulo")
    3670             :     {
    3671           1 :         std::stringstream ss;
    3672           1 :         ss << "div { height: 13.5% mod 12.5%; }";
    3673           3 :         csspp::position pos("test.css");
    3674           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3675             : 
    3676           2 :         csspp::parser p(l);
    3677             : 
    3678           1 :         csspp::node::pointer_t n(p.stylesheet());
    3679             : 
    3680           1 :         csspp::compiler c;
    3681           1 :         c.set_root(n);
    3682           1 :         c.set_date_time_variables(csspp_test::get_now());
    3683           1 :         c.add_path(csspp_test::get_script_path());
    3684           1 :         c.add_path(csspp_test::get_version_script_path());
    3685             : 
    3686           1 :         c.compile(false);
    3687             : 
    3688           1 :         VERIFY_ERRORS("");
    3689             : 
    3690             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3691             : 
    3692             :         // to verify that the result is still an INTEGER we have to
    3693             :         // test the root node here
    3694           1 :         std::stringstream compiler_out;
    3695           1 :         compiler_out << *n;
    3696           1 :         VERIFY_TREES(compiler_out.str(),
    3697             : 
    3698             : "LIST\n"
    3699             : + csspp_test::get_default_variables() +
    3700             : "  COMPONENT_VALUE\n"
    3701             : "    ARG\n"
    3702             : "      IDENTIFIER \"div\"\n"
    3703             : "    OPEN_CURLYBRACKET B:true\n"
    3704             : "      DECLARATION \"height\"\n"
    3705             : "        ARG\n"
    3706             : "          PERCENT D:0.01\n"
    3707             : + csspp_test::get_close_comment(true)
    3708             : 
    3709             :             );
    3710             : 
    3711           1 :         std::stringstream assembler_out;
    3712           1 :         csspp::assembler a(assembler_out);
    3713           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3714             : 
    3715             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3716             : 
    3717           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3718             : "div{height:1%}\n"
    3719             : + csspp_test::get_close_comment()
    3720             :                 );
    3721             : 
    3722           1 :         CATCH_REQUIRE(c.get_root() == n);
    3723           1 :     }
    3724          15 :     CATCH_END_SECTION()
    3725             : 
    3726          15 :     CATCH_START_SECTION("percent modulo with what looks like an integer (lhs)")
    3727             :     {
    3728           1 :         std::stringstream ss;
    3729           1 :         ss << "div { height: 23% mod 12.5%; }";
    3730           3 :         csspp::position pos("test.css");
    3731           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3732             : 
    3733           2 :         csspp::parser p(l);
    3734             : 
    3735           1 :         csspp::node::pointer_t n(p.stylesheet());
    3736             : 
    3737           1 :         csspp::compiler c;
    3738           1 :         c.set_root(n);
    3739           1 :         c.set_date_time_variables(csspp_test::get_now());
    3740           1 :         c.add_path(csspp_test::get_script_path());
    3741           1 :         c.add_path(csspp_test::get_version_script_path());
    3742             : 
    3743           1 :         c.compile(false);
    3744             : 
    3745           1 :         VERIFY_ERRORS("");
    3746             : 
    3747             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3748             : 
    3749             :         // to verify that the result is still an INTEGER we have to
    3750             :         // test the root node here
    3751           1 :         std::stringstream compiler_out;
    3752           1 :         compiler_out << *n;
    3753           1 :         VERIFY_TREES(compiler_out.str(),
    3754             : 
    3755             : "LIST\n"
    3756             : + csspp_test::get_default_variables() +
    3757             : "  COMPONENT_VALUE\n"
    3758             : "    ARG\n"
    3759             : "      IDENTIFIER \"div\"\n"
    3760             : "    OPEN_CURLYBRACKET B:true\n"
    3761             : "      DECLARATION \"height\"\n"
    3762             : "        ARG\n"
    3763             : "          PERCENT D:0.105\n"
    3764             : + csspp_test::get_close_comment(true)
    3765             : 
    3766             :             );
    3767             : 
    3768           1 :         std::stringstream assembler_out;
    3769           1 :         csspp::assembler a(assembler_out);
    3770           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3771             : 
    3772             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3773             : 
    3774           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3775             : "div{height:10.5%}\n"
    3776             : + csspp_test::get_close_comment()
    3777             :                 );
    3778             : 
    3779           1 :         CATCH_REQUIRE(c.get_root() == n);
    3780           1 :     }
    3781          15 :     CATCH_END_SECTION()
    3782             : 
    3783          15 :     CATCH_START_SECTION("percent modulo with what looks like an integer (rhs)")
    3784             :     {
    3785           1 :         std::stringstream ss;
    3786           1 :         ss << "div { height: 3.5% mod 10%; }";
    3787           3 :         csspp::position pos("test.css");
    3788           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3789             : 
    3790           2 :         csspp::parser p(l);
    3791             : 
    3792           1 :         csspp::node::pointer_t n(p.stylesheet());
    3793             : 
    3794           1 :         csspp::compiler c;
    3795           1 :         c.set_root(n);
    3796           1 :         c.set_date_time_variables(csspp_test::get_now());
    3797           1 :         c.add_path(csspp_test::get_script_path());
    3798           1 :         c.add_path(csspp_test::get_version_script_path());
    3799             : 
    3800           1 :         c.compile(false);
    3801             : 
    3802           1 :         VERIFY_ERRORS("");
    3803             : 
    3804             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3805             : 
    3806             :         // to verify that the result is still an INTEGER we have to
    3807             :         // test the root node here
    3808           1 :         std::stringstream compiler_out;
    3809           1 :         compiler_out << *n;
    3810           1 :         VERIFY_TREES(compiler_out.str(),
    3811             : 
    3812             : "LIST\n"
    3813             : + csspp_test::get_default_variables() +
    3814             : "  COMPONENT_VALUE\n"
    3815             : "    ARG\n"
    3816             : "      IDENTIFIER \"div\"\n"
    3817             : "    OPEN_CURLYBRACKET B:true\n"
    3818             : "      DECLARATION \"height\"\n"
    3819             : "        ARG\n"
    3820             : "          PERCENT D:0.035\n"
    3821             : + csspp_test::get_close_comment(true)
    3822             : 
    3823             :             );
    3824             : 
    3825           1 :         std::stringstream assembler_out;
    3826           1 :         csspp::assembler a(assembler_out);
    3827           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3828             : 
    3829             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3830             : 
    3831           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3832             : "div{height:3.5%}\n"
    3833             : + csspp_test::get_close_comment()
    3834             :                 );
    3835             : 
    3836           1 :         CATCH_REQUIRE(c.get_root() == n);
    3837           1 :     }
    3838          15 :     CATCH_END_SECTION()
    3839             : 
    3840          15 :     CATCH_START_SECTION("percent and decimal number multiplication")
    3841             :     {
    3842           1 :         std::stringstream ss;
    3843           1 :         ss << "div { height: 3.5% * 10.2px; }";
    3844           3 :         csspp::position pos("test.css");
    3845           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3846             : 
    3847           2 :         csspp::parser p(l);
    3848             : 
    3849           1 :         csspp::node::pointer_t n(p.stylesheet());
    3850             : 
    3851           1 :         csspp::compiler c;
    3852           1 :         c.set_root(n);
    3853           1 :         c.set_date_time_variables(csspp_test::get_now());
    3854           1 :         c.add_path(csspp_test::get_script_path());
    3855           1 :         c.add_path(csspp_test::get_version_script_path());
    3856             : 
    3857           1 :         c.compile(false);
    3858             : 
    3859           1 :         VERIFY_ERRORS("");
    3860             : 
    3861             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3862             : 
    3863             :         // to verify that the result is still an INTEGER we have to
    3864             :         // test the root node here
    3865           1 :         std::stringstream compiler_out;
    3866           1 :         compiler_out << *n;
    3867           1 :         VERIFY_TREES(compiler_out.str(),
    3868             : 
    3869             : "LIST\n"
    3870             : + csspp_test::get_default_variables() +
    3871             : "  COMPONENT_VALUE\n"
    3872             : "    ARG\n"
    3873             : "      IDENTIFIER \"div\"\n"
    3874             : "    OPEN_CURLYBRACKET B:true\n"
    3875             : "      DECLARATION \"height\"\n"
    3876             : "        ARG\n"
    3877             : "          DECIMAL_NUMBER \"px\" D:0.357\n"
    3878             : + csspp_test::get_close_comment(true)
    3879             : 
    3880             :             );
    3881             : 
    3882           1 :         std::stringstream assembler_out;
    3883           1 :         csspp::assembler a(assembler_out);
    3884           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3885             : 
    3886             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3887             : 
    3888           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3889             : "div{height:.357px}\n"
    3890             : + csspp_test::get_close_comment()
    3891             :                 );
    3892             : 
    3893           1 :         CATCH_REQUIRE(c.get_root() == n);
    3894           1 :     }
    3895          15 :     CATCH_END_SECTION()
    3896             : 
    3897          15 :     CATCH_START_SECTION("percent multiplication with what looks like an integer (lhs)")
    3898             :     {
    3899           1 :         std::stringstream ss;
    3900           1 :         ss << "div { height: 3% * 10.2em; }";
    3901           3 :         csspp::position pos("test.css");
    3902           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3903             : 
    3904           2 :         csspp::parser p(l);
    3905             : 
    3906           1 :         csspp::node::pointer_t n(p.stylesheet());
    3907             : 
    3908           1 :         csspp::compiler c;
    3909           1 :         c.set_root(n);
    3910           1 :         c.set_date_time_variables(csspp_test::get_now());
    3911           1 :         c.add_path(csspp_test::get_script_path());
    3912           1 :         c.add_path(csspp_test::get_version_script_path());
    3913             : 
    3914           1 :         c.compile(false);
    3915             : 
    3916           1 :         VERIFY_ERRORS("");
    3917             : 
    3918             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3919             : 
    3920             :         // to verify that the result is still an INTEGER we have to
    3921             :         // test the root node here
    3922           1 :         std::stringstream compiler_out;
    3923           1 :         compiler_out << *n;
    3924           1 :         VERIFY_TREES(compiler_out.str(),
    3925             : 
    3926             : "LIST\n"
    3927             : + csspp_test::get_default_variables() +
    3928             : "  COMPONENT_VALUE\n"
    3929             : "    ARG\n"
    3930             : "      IDENTIFIER \"div\"\n"
    3931             : "    OPEN_CURLYBRACKET B:true\n"
    3932             : "      DECLARATION \"height\"\n"
    3933             : "        ARG\n"
    3934             : "          DECIMAL_NUMBER \"em\" D:0.306\n"
    3935             : + csspp_test::get_close_comment(true)
    3936             : 
    3937             :             );
    3938             : 
    3939           1 :         std::stringstream assembler_out;
    3940           1 :         csspp::assembler a(assembler_out);
    3941           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3942             : 
    3943             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3944             : 
    3945           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3946             : "div{height:.306em}\n"
    3947             : + csspp_test::get_close_comment()
    3948             :                 );
    3949             : 
    3950           1 :         CATCH_REQUIRE(c.get_root() == n);
    3951           1 :     }
    3952          15 :     CATCH_END_SECTION()
    3953             : 
    3954          15 :     CATCH_START_SECTION("percent multiplication with what looks like an integer (rhs)")
    3955             :     {
    3956           1 :         std::stringstream ss;
    3957           1 :         ss << "div { height: 3.5% * 10cm; }";
    3958           3 :         csspp::position pos("test.css");
    3959           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3960             : 
    3961           2 :         csspp::parser p(l);
    3962             : 
    3963           1 :         csspp::node::pointer_t n(p.stylesheet());
    3964             : 
    3965           1 :         csspp::compiler c;
    3966           1 :         c.set_root(n);
    3967           1 :         c.set_date_time_variables(csspp_test::get_now());
    3968           1 :         c.add_path(csspp_test::get_script_path());
    3969           1 :         c.add_path(csspp_test::get_version_script_path());
    3970             : 
    3971           1 :         c.compile(false);
    3972             : 
    3973           1 :         VERIFY_ERRORS("");
    3974             : 
    3975             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3976             : 
    3977             :         // to verify that the result is still an INTEGER we have to
    3978             :         // test the root node here
    3979           1 :         std::stringstream compiler_out;
    3980           1 :         compiler_out << *n;
    3981           1 :         VERIFY_TREES(compiler_out.str(),
    3982             : 
    3983             : "LIST\n"
    3984             : + csspp_test::get_default_variables() +
    3985             : "  COMPONENT_VALUE\n"
    3986             : "    ARG\n"
    3987             : "      IDENTIFIER \"div\"\n"
    3988             : "    OPEN_CURLYBRACKET B:true\n"
    3989             : "      DECLARATION \"height\"\n"
    3990             : "        ARG\n"
    3991             : "          DECIMAL_NUMBER \"cm\" D:0.35\n"
    3992             : + csspp_test::get_close_comment(true)
    3993             : 
    3994             :             );
    3995             : 
    3996           1 :         std::stringstream assembler_out;
    3997           1 :         csspp::assembler a(assembler_out);
    3998           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3999             : 
    4000             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4001             : 
    4002           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4003             : "div{height:.35cm}\n"
    4004             : + csspp_test::get_close_comment()
    4005             :                 );
    4006             : 
    4007           1 :         CATCH_REQUIRE(c.get_root() == n);
    4008           1 :     }
    4009          15 :     CATCH_END_SECTION()
    4010             : 
    4011          15 :     CATCH_START_SECTION("percent and decimal number division")
    4012             :     {
    4013           1 :         std::stringstream ss;
    4014           1 :         ss << "div { height: 70.0vw / 3.5%; }";
    4015           3 :         csspp::position pos("test.css");
    4016           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4017             : 
    4018           2 :         csspp::parser p(l);
    4019             : 
    4020           1 :         csspp::node::pointer_t n(p.stylesheet());
    4021             : 
    4022           1 :         csspp::compiler c;
    4023           1 :         c.set_root(n);
    4024           1 :         c.set_date_time_variables(csspp_test::get_now());
    4025           1 :         c.add_path(csspp_test::get_script_path());
    4026           1 :         c.add_path(csspp_test::get_version_script_path());
    4027             : 
    4028           1 :         c.compile(false);
    4029             : 
    4030           1 :         VERIFY_ERRORS("");
    4031             : 
    4032             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4033             : 
    4034             :         // to verify that the result is still an INTEGER we have to
    4035             :         // test the root node here
    4036           1 :         std::stringstream compiler_out;
    4037           1 :         compiler_out << *n;
    4038           1 :         VERIFY_TREES(compiler_out.str(),
    4039             : 
    4040             : "LIST\n"
    4041             : + csspp_test::get_default_variables() +
    4042             : "  COMPONENT_VALUE\n"
    4043             : "    ARG\n"
    4044             : "      IDENTIFIER \"div\"\n"
    4045             : "    OPEN_CURLYBRACKET B:true\n"
    4046             : "      DECLARATION \"height\"\n"
    4047             : "        ARG\n"
    4048             : "          DECIMAL_NUMBER \"vw\" D:2000\n"
    4049             : + csspp_test::get_close_comment(true)
    4050             : 
    4051             :             );
    4052             : 
    4053           1 :         std::stringstream assembler_out;
    4054           1 :         csspp::assembler a(assembler_out);
    4055           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4056             : 
    4057             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4058             : 
    4059           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4060             : "div{height:2000vw}\n"
    4061             : + csspp_test::get_close_comment()
    4062             :                 );
    4063             : 
    4064           1 :         CATCH_REQUIRE(c.get_root() == n);
    4065           1 :     }
    4066          15 :     CATCH_END_SECTION()
    4067             : 
    4068          15 :     CATCH_START_SECTION("percent division with what looks like an integer (lhs)")
    4069             :     {
    4070           1 :         std::stringstream ss;
    4071           1 :         ss << "div { height: 3px / 12.5%; }";
    4072           3 :         csspp::position pos("test.css");
    4073           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4074             : 
    4075           2 :         csspp::parser p(l);
    4076             : 
    4077           1 :         csspp::node::pointer_t n(p.stylesheet());
    4078             : 
    4079           1 :         csspp::compiler c;
    4080           1 :         c.set_root(n);
    4081           1 :         c.set_date_time_variables(csspp_test::get_now());
    4082           1 :         c.add_path(csspp_test::get_script_path());
    4083           1 :         c.add_path(csspp_test::get_version_script_path());
    4084             : 
    4085           1 :         c.compile(false);
    4086             : 
    4087           1 :         VERIFY_ERRORS("");
    4088             : 
    4089             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4090             : 
    4091             :         // to verify that the result is still an INTEGER we have to
    4092             :         // test the root node here
    4093           1 :         std::stringstream compiler_out;
    4094           1 :         compiler_out << *n;
    4095           1 :         VERIFY_TREES(compiler_out.str(),
    4096             : 
    4097             : "LIST\n"
    4098             : + csspp_test::get_default_variables() +
    4099             : "  COMPONENT_VALUE\n"
    4100             : "    ARG\n"
    4101             : "      IDENTIFIER \"div\"\n"
    4102             : "    OPEN_CURLYBRACKET B:true\n"
    4103             : "      DECLARATION \"height\"\n"
    4104             : "        ARG\n"
    4105             : "          DECIMAL_NUMBER \"px\" D:24\n"
    4106             : + csspp_test::get_close_comment(true)
    4107             : 
    4108             :             );
    4109             : 
    4110           1 :         std::stringstream assembler_out;
    4111           1 :         csspp::assembler a(assembler_out);
    4112           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4113             : 
    4114             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4115             : 
    4116           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4117             : "div{height:24px}\n"
    4118             : + csspp_test::get_close_comment()
    4119             :                 );
    4120             : 
    4121           1 :         CATCH_REQUIRE(c.get_root() == n);
    4122           1 :     }
    4123          15 :     CATCH_END_SECTION()
    4124             : 
    4125          15 :     CATCH_START_SECTION("percent division with what looks like an integer (rhs)")
    4126             :     {
    4127           1 :         std::stringstream ss;
    4128           1 :         ss << "div { height: 3.5em / 10%; }";
    4129           3 :         csspp::position pos("test.css");
    4130           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4131             : 
    4132           2 :         csspp::parser p(l);
    4133             : 
    4134           1 :         csspp::node::pointer_t n(p.stylesheet());
    4135             : 
    4136           1 :         csspp::compiler c;
    4137           1 :         c.set_root(n);
    4138           1 :         c.set_date_time_variables(csspp_test::get_now());
    4139           1 :         c.add_path(csspp_test::get_script_path());
    4140           1 :         c.add_path(csspp_test::get_version_script_path());
    4141             : 
    4142           1 :         c.compile(false);
    4143             : 
    4144           1 :         VERIFY_ERRORS("");
    4145             : 
    4146             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4147             : 
    4148             :         // to verify that the result is still an INTEGER we have to
    4149             :         // test the root node here
    4150           1 :         std::stringstream compiler_out;
    4151           1 :         compiler_out << *n;
    4152           1 :         VERIFY_TREES(compiler_out.str(),
    4153             : 
    4154             : "LIST\n"
    4155             : + csspp_test::get_default_variables() +
    4156             : "  COMPONENT_VALUE\n"
    4157             : "    ARG\n"
    4158             : "      IDENTIFIER \"div\"\n"
    4159             : "    OPEN_CURLYBRACKET B:true\n"
    4160             : "      DECLARATION \"height\"\n"
    4161             : "        ARG\n"
    4162             : "          DECIMAL_NUMBER \"em\" D:35\n"
    4163             : + csspp_test::get_close_comment(true)
    4164             : 
    4165             :             );
    4166             : 
    4167           1 :         std::stringstream assembler_out;
    4168           1 :         csspp::assembler a(assembler_out);
    4169           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4170             : 
    4171             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4172             : 
    4173           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4174             : "div{height:35em}\n"
    4175             : + csspp_test::get_close_comment()
    4176             :                 );
    4177             : 
    4178           1 :         CATCH_REQUIRE(c.get_root() == n);
    4179           1 :     }
    4180          15 :     CATCH_END_SECTION()
    4181             : 
    4182             :     // no error left over
    4183          15 :     VERIFY_ERRORS("");
    4184          15 : }
    4185             : 
    4186           6 : CATCH_TEST_CASE("Expression with multiplicative unicode ranges", "[expression] [multiplicative] [unicode-range-value]")
    4187             : {
    4188           6 :     CATCH_START_SECTION("null * null = null")
    4189             :     {
    4190           1 :         std::stringstream ss;
    4191           1 :         ss << "@font-face { unicode-range: null * null; }";
    4192           3 :         csspp::position pos("test.css");
    4193           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4194             : 
    4195           2 :         csspp::parser p(l);
    4196             : 
    4197           1 :         csspp::node::pointer_t n(p.stylesheet());
    4198             : 
    4199             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4200             : 
    4201           1 :         csspp::compiler c;
    4202           1 :         c.set_root(n);
    4203           1 :         c.set_date_time_variables(csspp_test::get_now());
    4204           1 :         c.add_path(csspp_test::get_script_path());
    4205           1 :         c.add_path(csspp_test::get_version_script_path());
    4206             : 
    4207           1 :         c.compile(false);
    4208             : 
    4209           1 :         VERIFY_ERRORS("");
    4210             : 
    4211             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4212             : 
    4213             :         // to verify that the result is still an INTEGER we have to
    4214             :         // test the root node here
    4215           1 :         std::stringstream compiler_out;
    4216           1 :         compiler_out << *n;
    4217           1 :         VERIFY_TREES(compiler_out.str(),
    4218             : 
    4219             : "LIST\n"
    4220             : + csspp_test::get_default_variables() +
    4221             : "  AT_KEYWORD \"font-face\" I:0\n"
    4222             : "    OPEN_CURLYBRACKET B:true\n"
    4223             : "      DECLARATION \"unicode-range\"\n"
    4224             : "        ARG\n"
    4225             : "          NULL_TOKEN\n"
    4226             : + csspp_test::get_close_comment(true)
    4227             : 
    4228             :             );
    4229             : 
    4230             : // Assembler does not support NULL_TOKEN in its output
    4231             : //         std::stringstream assembler_out;
    4232             : //         csspp::assembler a(assembler_out);
    4233             : //         a.output(n, csspp::output_mode_t::COMPRESSED);
    4234             : // 
    4235             : // //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4236             : // 
    4237             : //         CATCH_REQUIRE(assembler_out.str() ==
    4238             : // "div{font:35pt/40pt serif}\n"
    4239             : // + csspp_test::get_close_comment()
    4240             : //                 );
    4241             : 
    4242           1 :         CATCH_REQUIRE(c.get_root() == n);
    4243           1 :     }
    4244           6 :     CATCH_END_SECTION()
    4245             : 
    4246           6 :     CATCH_START_SECTION("unicode * null = null")
    4247             :     {
    4248           1 :         std::stringstream ss;
    4249           1 :         ss << "@font-face { unicode-range: U+7?? * null; }";
    4250           3 :         csspp::position pos("test.css");
    4251           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4252             : 
    4253           2 :         csspp::parser p(l);
    4254             : 
    4255           1 :         csspp::node::pointer_t n(p.stylesheet());
    4256             : 
    4257             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4258             : 
    4259           1 :         csspp::compiler c;
    4260           1 :         c.set_root(n);
    4261           1 :         c.set_date_time_variables(csspp_test::get_now());
    4262           1 :         c.add_path(csspp_test::get_script_path());
    4263           1 :         c.add_path(csspp_test::get_version_script_path());
    4264             : 
    4265           1 :         c.compile(false);
    4266             : 
    4267           1 :         VERIFY_ERRORS("");
    4268             : 
    4269             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4270             : 
    4271             :         // to verify that the result is still an INTEGER we have to
    4272             :         // test the root node here
    4273           1 :         std::stringstream compiler_out;
    4274           1 :         compiler_out << *n;
    4275           1 :         VERIFY_TREES(compiler_out.str(),
    4276             : 
    4277             : "LIST\n"
    4278             : + csspp_test::get_default_variables() +
    4279             : "  AT_KEYWORD \"font-face\" I:0\n"
    4280             : "    OPEN_CURLYBRACKET B:true\n"
    4281             : "      DECLARATION \"unicode-range\"\n"
    4282             : "        ARG\n"
    4283             : "          NULL_TOKEN\n"
    4284             : + csspp_test::get_close_comment(true)
    4285             : 
    4286             :             );
    4287             : 
    4288             : // Assembler does not support NULL_TOKEN in its output
    4289             : //         std::stringstream assembler_out;
    4290             : //         csspp::assembler a(assembler_out);
    4291             : //         a.output(n, csspp::output_mode_t::COMPRESSED);
    4292             : // 
    4293             : // //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4294             : // 
    4295             : //         CATCH_REQUIRE(assembler_out.str() ==
    4296             : // "div{font:35pt/40pt serif}\n"
    4297             : // + csspp_test::get_close_comment()
    4298             : //                 );
    4299             : 
    4300           1 :         CATCH_REQUIRE(c.get_root() == n);
    4301           1 :     }
    4302           6 :     CATCH_END_SECTION()
    4303             : 
    4304           6 :     CATCH_START_SECTION("null * unicode = null")
    4305             :     {
    4306           1 :         std::stringstream ss;
    4307           1 :         ss << "@font-face { unicode-range: null * U+7??; }";
    4308           3 :         csspp::position pos("test.css");
    4309           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4310             : 
    4311           2 :         csspp::parser p(l);
    4312             : 
    4313           1 :         csspp::node::pointer_t n(p.stylesheet());
    4314             : 
    4315             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4316             : 
    4317           1 :         csspp::compiler c;
    4318           1 :         c.set_root(n);
    4319           1 :         c.set_date_time_variables(csspp_test::get_now());
    4320           1 :         c.add_path(csspp_test::get_script_path());
    4321           1 :         c.add_path(csspp_test::get_version_script_path());
    4322             : 
    4323           1 :         c.compile(false);
    4324             : 
    4325           1 :         VERIFY_ERRORS("");
    4326             : 
    4327             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4328             : 
    4329             :         // to verify that the result is still an INTEGER we have to
    4330             :         // test the root node here
    4331           1 :         std::stringstream compiler_out;
    4332           1 :         compiler_out << *n;
    4333           1 :         VERIFY_TREES(compiler_out.str(),
    4334             : 
    4335             : "LIST\n"
    4336             : + csspp_test::get_default_variables() +
    4337             : "  AT_KEYWORD \"font-face\" I:0\n"
    4338             : "    OPEN_CURLYBRACKET B:true\n"
    4339             : "      DECLARATION \"unicode-range\"\n"
    4340             : "        ARG\n"
    4341             : "          NULL_TOKEN\n"
    4342             : + csspp_test::get_close_comment(true)
    4343             : 
    4344             :             );
    4345             : 
    4346             : // Assembler does not support NULL_TOKEN in its output
    4347             : //         std::stringstream assembler_out;
    4348             : //         csspp::assembler a(assembler_out);
    4349             : //         a.output(n, csspp::output_mode_t::COMPRESSED);
    4350             : // 
    4351             : // //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4352             : // 
    4353             : //         CATCH_REQUIRE(assembler_out.str() ==
    4354             : // "div{font:35pt/40pt serif}\n"
    4355             : // + csspp_test::get_close_comment()
    4356             : //                 );
    4357             : 
    4358           1 :         CATCH_REQUIRE(c.get_root() == n);
    4359           1 :     }
    4360           6 :     CATCH_END_SECTION()
    4361             : 
    4362           6 :     CATCH_START_SECTION("unicode * unicode = unicode (smaller range included in other range)")
    4363             :     {
    4364           1 :         std::stringstream ss;
    4365           1 :         ss << "@font-face { unicode-range: U+1??? * U+17??; }";
    4366           3 :         csspp::position pos("test.css");
    4367           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4368             : 
    4369           2 :         csspp::parser p(l);
    4370             : 
    4371           1 :         csspp::node::pointer_t n(p.stylesheet());
    4372             : 
    4373             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4374             : 
    4375           1 :         csspp::compiler c;
    4376           1 :         c.set_root(n);
    4377           1 :         c.set_date_time_variables(csspp_test::get_now());
    4378           1 :         c.add_path(csspp_test::get_script_path());
    4379           1 :         c.add_path(csspp_test::get_version_script_path());
    4380             : 
    4381           1 :         c.compile(false);
    4382             : 
    4383           1 :         VERIFY_ERRORS("");
    4384             : 
    4385             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4386             : 
    4387             :         // to verify that the result is still an INTEGER we have to
    4388             :         // test the root node here
    4389           1 :         std::stringstream compiler_out;
    4390           1 :         compiler_out << *n;
    4391           1 :         VERIFY_TREES(compiler_out.str(),
    4392             : 
    4393             : "LIST\n"
    4394             : + csspp_test::get_default_variables() +
    4395             : "  AT_KEYWORD \"font-face\" I:0\n"
    4396             : "    OPEN_CURLYBRACKET B:true\n"
    4397             : "      DECLARATION \"unicode-range\"\n"
    4398             : "        ARG\n"
    4399             : "          UNICODE_RANGE I:26383984105216\n"
    4400             : + csspp_test::get_close_comment(true)
    4401             : 
    4402             :             );
    4403             : 
    4404           1 :         std::stringstream assembler_out;
    4405           1 :         csspp::assembler a(assembler_out);
    4406           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4407             : 
    4408             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4409             : 
    4410           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4411             : "@font-face {unicode-range:U+17??}\n"
    4412             : + csspp_test::get_close_comment()
    4413             :                 );
    4414             : 
    4415           1 :         CATCH_REQUIRE(c.get_root() == n);
    4416           1 :     }
    4417           6 :     CATCH_END_SECTION()
    4418             : 
    4419           6 :     CATCH_START_SECTION("unicode * unicode = null (no overlap)")
    4420             :     {
    4421           1 :         std::stringstream ss;
    4422           1 :         ss << "@font-face { unicode-range: U+1??? * U+7??; }";
    4423           3 :         csspp::position pos("test.css");
    4424           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4425             : 
    4426           2 :         csspp::parser p(l);
    4427             : 
    4428           1 :         csspp::node::pointer_t n(p.stylesheet());
    4429             : 
    4430             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4431             : 
    4432           1 :         csspp::compiler c;
    4433           1 :         c.set_root(n);
    4434           1 :         c.set_date_time_variables(csspp_test::get_now());
    4435           1 :         c.add_path(csspp_test::get_script_path());
    4436           1 :         c.add_path(csspp_test::get_version_script_path());
    4437             : 
    4438           1 :         c.compile(false);
    4439             : 
    4440           1 :         VERIFY_ERRORS("");
    4441             : 
    4442             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4443             : 
    4444             :         // to verify that the result is still an INTEGER we have to
    4445             :         // test the root node here
    4446           1 :         std::stringstream compiler_out;
    4447           1 :         compiler_out << *n;
    4448           1 :         VERIFY_TREES(compiler_out.str(),
    4449             : 
    4450             : "LIST\n"
    4451             : + csspp_test::get_default_variables() +
    4452             : "  AT_KEYWORD \"font-face\" I:0\n"
    4453             : "    OPEN_CURLYBRACKET B:true\n"
    4454             : "      DECLARATION \"unicode-range\"\n"
    4455             : "        ARG\n"
    4456             : "          NULL_TOKEN\n"
    4457             : + csspp_test::get_close_comment(true)
    4458             : 
    4459             :             );
    4460             : 
    4461             : // Assembler does not support NULL_TOKEN in its output
    4462             : //         std::stringstream assembler_out;
    4463             : //         csspp::assembler a(assembler_out);
    4464             : //         a.output(n, csspp::output_mode_t::COMPRESSED);
    4465             : // 
    4466             : // //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4467             : // 
    4468             : //         CATCH_REQUIRE(assembler_out.str() ==
    4469             : // "div{font:35pt/40pt serif}\n"
    4470             : // + csspp_test::get_close_comment()
    4471             : //                 );
    4472             : 
    4473           1 :         CATCH_REQUIRE(c.get_root() == n);
    4474           1 :     }
    4475           6 :     CATCH_END_SECTION()
    4476             : 
    4477           6 :     CATCH_START_SECTION("unicode * unicode = null (start/end overlap)")
    4478             :     {
    4479           1 :         std::stringstream ss;
    4480           1 :         ss << "@font-face { unicode-range: U+1000-18FF * U+1750-1FFF; }";
    4481           3 :         csspp::position pos("test.css");
    4482           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4483             : 
    4484           2 :         csspp::parser p(l);
    4485             : 
    4486           1 :         csspp::node::pointer_t n(p.stylesheet());
    4487             : 
    4488             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4489             : 
    4490           1 :         csspp::compiler c;
    4491           1 :         c.set_root(n);
    4492           1 :         c.set_date_time_variables(csspp_test::get_now());
    4493           1 :         c.add_path(csspp_test::get_script_path());
    4494           1 :         c.add_path(csspp_test::get_version_script_path());
    4495             : 
    4496           1 :         c.compile(false);
    4497             : 
    4498           1 :         VERIFY_ERRORS("");
    4499             : 
    4500             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4501             : 
    4502             :         // to verify that the result is still an INTEGER we have to
    4503             :         // test the root node here
    4504           1 :         std::stringstream compiler_out;
    4505           1 :         compiler_out << *n;
    4506           1 :         VERIFY_TREES(compiler_out.str(),
    4507             : 
    4508             : "LIST\n"
    4509             : + csspp_test::get_default_variables() +
    4510             : "  AT_KEYWORD \"font-face\" I:0\n"
    4511             : "    OPEN_CURLYBRACKET B:true\n"
    4512             : "      DECLARATION \"unicode-range\"\n"
    4513             : "        ARG\n"
    4514             : "          UNICODE_RANGE I:27483495733072\n"
    4515             : + csspp_test::get_close_comment(true)
    4516             : 
    4517             :             );
    4518             : 
    4519           1 :         std::stringstream assembler_out;
    4520           1 :         csspp::assembler a(assembler_out);
    4521           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4522             : 
    4523             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4524             : 
    4525           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4526             : "@font-face {unicode-range:U+1750-18ff}\n"
    4527             : + csspp_test::get_close_comment()
    4528             :                 );
    4529             : 
    4530           1 :         CATCH_REQUIRE(c.get_root() == n);
    4531           1 :     }
    4532           6 :     CATCH_END_SECTION()
    4533             : 
    4534             :     // no error left over
    4535           6 :     VERIFY_ERRORS("");
    4536           6 : }
    4537             : 
    4538           6 : CATCH_TEST_CASE("Expression with invalid multiplicative unicode ranges", "[expression] [multiplicative] [unicode-range-value] [invalid]")
    4539             : {
    4540           6 :     CATCH_START_SECTION("null / null = null")
    4541             :     {
    4542           1 :         std::stringstream ss;
    4543           1 :         ss << "@font-face { unicode-range: null / null; }";
    4544           3 :         csspp::position pos("test.css");
    4545           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4546             : 
    4547           2 :         csspp::parser p(l);
    4548             : 
    4549           1 :         csspp::node::pointer_t n(p.stylesheet());
    4550             : 
    4551             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4552             : 
    4553           1 :         csspp::compiler c;
    4554           1 :         c.set_root(n);
    4555           1 :         c.set_date_time_variables(csspp_test::get_now());
    4556           1 :         c.add_path(csspp_test::get_script_path());
    4557           1 :         c.add_path(csspp_test::get_version_script_path());
    4558             : 
    4559           1 :         c.compile(false);
    4560             : 
    4561           1 :         VERIFY_ERRORS("test.css(1): error: unicode_range * unicode_range is the only multiplicative operator accepted with unicode ranges, '/' and '%' are not allowed.\n");
    4562             : 
    4563           1 :         CATCH_REQUIRE(c.get_root() == n);
    4564           1 :     }
    4565           6 :     CATCH_END_SECTION()
    4566             : 
    4567           6 :     CATCH_START_SECTION("unicode % null = null")
    4568             :     {
    4569           1 :         std::stringstream ss;
    4570           1 :         ss << "@font-face { unicode-range: U+7?? % null; }";
    4571           3 :         csspp::position pos("test.css");
    4572           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4573             : 
    4574           2 :         csspp::parser p(l);
    4575             : 
    4576           1 :         csspp::node::pointer_t n(p.stylesheet());
    4577             : 
    4578             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4579             : 
    4580           1 :         csspp::compiler c;
    4581           1 :         c.set_root(n);
    4582           1 :         c.set_date_time_variables(csspp_test::get_now());
    4583           1 :         c.add_path(csspp_test::get_script_path());
    4584           1 :         c.add_path(csspp_test::get_version_script_path());
    4585             : 
    4586           1 :         c.compile(false);
    4587             : 
    4588           1 :         VERIFY_ERRORS("test.css(1): error: unicode_range * unicode_range is the only multiplicative operator accepted with unicode ranges, '/' and '%' are not allowed.\n");
    4589             : 
    4590           1 :         CATCH_REQUIRE(c.get_root() == n);
    4591           1 :     }
    4592           6 :     CATCH_END_SECTION()
    4593             : 
    4594           6 :     CATCH_START_SECTION("null / unicode = null")
    4595             :     {
    4596           1 :         std::stringstream ss;
    4597           1 :         ss << "@font-face { unicode-range: null / U+7??; }";
    4598           3 :         csspp::position pos("test.css");
    4599           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4600             : 
    4601           2 :         csspp::parser p(l);
    4602             : 
    4603           1 :         csspp::node::pointer_t n(p.stylesheet());
    4604             : 
    4605             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4606             : 
    4607           1 :         csspp::compiler c;
    4608           1 :         c.set_root(n);
    4609           1 :         c.set_date_time_variables(csspp_test::get_now());
    4610           1 :         c.add_path(csspp_test::get_script_path());
    4611           1 :         c.add_path(csspp_test::get_version_script_path());
    4612             : 
    4613           1 :         c.compile(false);
    4614             : 
    4615           1 :         VERIFY_ERRORS("test.css(1): error: unicode_range * unicode_range is the only multiplicative operator accepted with unicode ranges, '/' and '%' are not allowed.\n");
    4616             : 
    4617           1 :         CATCH_REQUIRE(c.get_root() == n);
    4618           1 :     }
    4619           6 :     CATCH_END_SECTION()
    4620             : 
    4621           6 :     CATCH_START_SECTION("unicode % unicode is an error")
    4622             :     {
    4623           1 :         std::stringstream ss;
    4624           1 :         ss << "@font-face { unicode-range: U+1??? % U+17??; }";
    4625           3 :         csspp::position pos("test.css");
    4626           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4627             : 
    4628           2 :         csspp::parser p(l);
    4629             : 
    4630           1 :         csspp::node::pointer_t n(p.stylesheet());
    4631             : 
    4632             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4633             : 
    4634           1 :         csspp::compiler c;
    4635           1 :         c.set_root(n);
    4636           1 :         c.set_date_time_variables(csspp_test::get_now());
    4637           1 :         c.add_path(csspp_test::get_script_path());
    4638           1 :         c.add_path(csspp_test::get_version_script_path());
    4639             : 
    4640           1 :         c.compile(false);
    4641             : 
    4642           1 :         VERIFY_ERRORS("test.css(1): error: unicode_range * unicode_range is the only multiplicative operator accepted with unicode ranges, '/' and '%' are not allowed.\n");
    4643             : 
    4644           1 :         CATCH_REQUIRE(c.get_root() == n);
    4645           1 :     }
    4646           6 :     CATCH_END_SECTION()
    4647             : 
    4648           6 :     CATCH_START_SECTION("unicode / unicode = null (no overlap)")
    4649             :     {
    4650           1 :         std::stringstream ss;
    4651           1 :         ss << "@font-face { unicode-range: U+1??? / U+7??; }";
    4652           3 :         csspp::position pos("test.css");
    4653           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4654             : 
    4655           2 :         csspp::parser p(l);
    4656             : 
    4657           1 :         csspp::node::pointer_t n(p.stylesheet());
    4658             : 
    4659             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4660             : 
    4661           1 :         csspp::compiler c;
    4662           1 :         c.set_root(n);
    4663           1 :         c.set_date_time_variables(csspp_test::get_now());
    4664           1 :         c.add_path(csspp_test::get_script_path());
    4665           1 :         c.add_path(csspp_test::get_version_script_path());
    4666             : 
    4667           1 :         c.compile(false);
    4668             : 
    4669           1 :         VERIFY_ERRORS("test.css(1): error: unicode_range * unicode_range is the only multiplicative operator accepted with unicode ranges, '/' and '%' are not allowed.\n");
    4670             : 
    4671           1 :         CATCH_REQUIRE(c.get_root() == n);
    4672           1 :     }
    4673           6 :     CATCH_END_SECTION()
    4674             : 
    4675           6 :     CATCH_START_SECTION("unicode % unicode = error really")
    4676             :     {
    4677           1 :         std::stringstream ss;
    4678           1 :         ss << "@font-face { unicode-range: U+1000-18FF % U+1750-1FFF; }";
    4679           3 :         csspp::position pos("test.css");
    4680           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4681             : 
    4682           2 :         csspp::parser p(l);
    4683             : 
    4684           1 :         csspp::node::pointer_t n(p.stylesheet());
    4685             : 
    4686             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4687             : 
    4688           1 :         csspp::compiler c;
    4689           1 :         c.set_root(n);
    4690           1 :         c.set_date_time_variables(csspp_test::get_now());
    4691           1 :         c.add_path(csspp_test::get_script_path());
    4692           1 :         c.add_path(csspp_test::get_version_script_path());
    4693             : 
    4694           1 :         c.compile(false);
    4695             : 
    4696           1 :         VERIFY_ERRORS("test.css(1): error: unicode_range * unicode_range is the only multiplicative operator accepted with unicode ranges, '/' and '%' are not allowed.\n");
    4697             : 
    4698           1 :         CATCH_REQUIRE(c.get_root() == n);
    4699           1 :     }
    4700           6 :     CATCH_END_SECTION()
    4701             : 
    4702             :     // no error left over
    4703           6 :     VERIFY_ERRORS("");
    4704           6 : }
    4705             : 
    4706           3 : CATCH_TEST_CASE("Expression with a font metrics", "[expression] [multiplicative] [font-metrics]")
    4707             : {
    4708           3 :     CATCH_START_SECTION("Not a division, two integers")
    4709             :     {
    4710           1 :         std::stringstream ss;
    4711           1 :         ss << "div { font: 35pt/40pt serif; }";
    4712           3 :         csspp::position pos("test.css");
    4713           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4714             : 
    4715           2 :         csspp::parser p(l);
    4716             : 
    4717           1 :         csspp::node::pointer_t n(p.stylesheet());
    4718             : 
    4719           1 :         csspp::compiler c;
    4720           1 :         c.set_root(n);
    4721           1 :         c.set_date_time_variables(csspp_test::get_now());
    4722           1 :         c.add_path(csspp_test::get_script_path());
    4723           1 :         c.add_path(csspp_test::get_version_script_path());
    4724             : 
    4725           1 :         c.compile(false);
    4726             : 
    4727           1 :         VERIFY_ERRORS("");
    4728             : 
    4729             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4730             : 
    4731             :         // to verify that the result is still an INTEGER we have to
    4732             :         // test the root node here
    4733           1 :         std::stringstream compiler_out;
    4734           1 :         compiler_out << *n;
    4735           1 :         VERIFY_TREES(compiler_out.str(),
    4736             : 
    4737             : "LIST\n"
    4738             : + csspp_test::get_default_variables() +
    4739             : "  COMPONENT_VALUE\n"
    4740             : "    ARG\n"
    4741             : "      IDENTIFIER \"div\"\n"
    4742             : "    OPEN_CURLYBRACKET B:true\n"
    4743             : "      DECLARATION \"font\"\n"
    4744             : "        ARG\n"
    4745             : "          FONT_METRICS FM:35pt/40pt\n"
    4746             : "          WHITESPACE\n"
    4747             : "          IDENTIFIER \"serif\"\n"
    4748             : + csspp_test::get_close_comment(true)
    4749             : 
    4750             :             );
    4751             : 
    4752           1 :         std::stringstream assembler_out;
    4753           1 :         csspp::assembler a(assembler_out);
    4754           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4755             : 
    4756             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4757             : 
    4758           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4759             : "div{font:35pt/40pt serif}\n"
    4760             : + csspp_test::get_close_comment()
    4761             :                 );
    4762             : 
    4763           1 :         CATCH_REQUIRE(c.get_root() == n);
    4764           1 :     }
    4765           3 :     CATCH_END_SECTION()
    4766             : 
    4767           3 :     CATCH_START_SECTION("Not a division, integer and percent")
    4768             :     {
    4769           1 :         std::stringstream ss;
    4770           1 :         ss << "div { font: 35pt/120% sans-serif; }";
    4771           3 :         csspp::position pos("test.css");
    4772           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4773             : 
    4774           2 :         csspp::parser p(l);
    4775             : 
    4776           1 :         csspp::node::pointer_t n(p.stylesheet());
    4777             : 
    4778           1 :         csspp::compiler c;
    4779           1 :         c.set_root(n);
    4780           1 :         c.set_date_time_variables(csspp_test::get_now());
    4781           1 :         c.add_path(csspp_test::get_script_path());
    4782           1 :         c.add_path(csspp_test::get_version_script_path());
    4783             : 
    4784           1 :         c.compile(false);
    4785             : 
    4786           1 :         VERIFY_ERRORS("");
    4787             : 
    4788             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4789             : 
    4790             :         // to verify that the result is still an INTEGER we have to
    4791             :         // test the root node here
    4792           1 :         std::stringstream compiler_out;
    4793           1 :         compiler_out << *n;
    4794           1 :         VERIFY_TREES(compiler_out.str(),
    4795             : 
    4796             : "LIST\n"
    4797             : + csspp_test::get_default_variables() +
    4798             : "  COMPONENT_VALUE\n"
    4799             : "    ARG\n"
    4800             : "      IDENTIFIER \"div\"\n"
    4801             : "    OPEN_CURLYBRACKET B:true\n"
    4802             : "      DECLARATION \"font\"\n"
    4803             : "        ARG\n"
    4804             : "          FONT_METRICS FM:35pt/120%\n"
    4805             : "          WHITESPACE\n"
    4806             : "          IDENTIFIER \"sans-serif\"\n"
    4807             : + csspp_test::get_close_comment(true)
    4808             : 
    4809             :             );
    4810             : 
    4811           1 :         std::stringstream assembler_out;
    4812           1 :         csspp::assembler a(assembler_out);
    4813           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4814             : 
    4815             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4816             : 
    4817           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4818             : "div{font:35pt/120% sans-serif}\n"
    4819             : + csspp_test::get_close_comment()
    4820             :                 );
    4821             : 
    4822           1 :         CATCH_REQUIRE(c.get_root() == n);
    4823           1 :     }
    4824           3 :     CATCH_END_SECTION()
    4825             : 
    4826           3 :     CATCH_START_SECTION("Not a division, spaces and percent twice")
    4827             :     {
    4828           1 :         std::stringstream ss;
    4829           1 :         ss << "div { font: 80% / 120% sans-serif; }";
    4830           3 :         csspp::position pos("test.css");
    4831           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4832             : 
    4833           2 :         csspp::parser p(l);
    4834             : 
    4835           1 :         csspp::node::pointer_t n(p.stylesheet());
    4836             : 
    4837           1 :         csspp::compiler c;
    4838           1 :         c.set_root(n);
    4839           1 :         c.set_date_time_variables(csspp_test::get_now());
    4840           1 :         c.add_path(csspp_test::get_script_path());
    4841           1 :         c.add_path(csspp_test::get_version_script_path());
    4842             : 
    4843           1 :         c.compile(false);
    4844             : 
    4845           1 :         VERIFY_ERRORS("");
    4846             : 
    4847             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4848             : 
    4849             :         // to verify that the result is still an INTEGER we have to
    4850             :         // test the root node here
    4851           1 :         std::stringstream compiler_out;
    4852           1 :         compiler_out << *n;
    4853           1 :         VERIFY_TREES(compiler_out.str(),
    4854             : 
    4855             : "LIST\n"
    4856             : + csspp_test::get_default_variables() +
    4857             : "  COMPONENT_VALUE\n"
    4858             : "    ARG\n"
    4859             : "      IDENTIFIER \"div\"\n"
    4860             : "    OPEN_CURLYBRACKET B:true\n"
    4861             : "      DECLARATION \"font\"\n"
    4862             : "        ARG\n"
    4863             : "          FONT_METRICS FM:80%/120%\n"
    4864             : "          WHITESPACE\n"
    4865             : "          IDENTIFIER \"sans-serif\"\n"
    4866             : + csspp_test::get_close_comment(true)
    4867             : 
    4868             :             );
    4869             : 
    4870           1 :         std::stringstream assembler_out;
    4871           1 :         csspp::assembler a(assembler_out);
    4872           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4873             : 
    4874             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4875             : 
    4876           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4877             : "div{font:80%/120% sans-serif}\n"
    4878             : + csspp_test::get_close_comment()
    4879             :                 );
    4880             : 
    4881           1 :         CATCH_REQUIRE(c.get_root() == n);
    4882           1 :     }
    4883           3 :     CATCH_END_SECTION()
    4884             : 
    4885             :     // no error left over
    4886           3 :     VERIFY_ERRORS("");
    4887           3 : }
    4888             : 
    4889          10 : CATCH_TEST_CASE("Expression with colors", "[expression] [multiplicative] [colors]")
    4890             : {
    4891          10 :     CATCH_START_SECTION("Multiply color by 5")
    4892             :     {
    4893           1 :         std::stringstream ss;
    4894             :         ss << "div {"
    4895             :            << "  color: red * 5;"
    4896             :            << "  border-top-left-color: 5 * teal;"
    4897             :            << "  background-color: black * 5;"
    4898             :            << "  border-bottom-left-color: 5 * azure;"
    4899             :            << "  border-top-right-color: #123456 * 5;"
    4900           1 :            << "}";
    4901           3 :         csspp::position pos("test.css");
    4902           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4903             : 
    4904             : //std::cerr << "parse [" << ss.str() << "]\n";
    4905           2 :         csspp::parser p(l);
    4906             : 
    4907           1 :         csspp::node::pointer_t n(p.stylesheet());
    4908             : 
    4909           1 :         csspp::compiler c;
    4910           1 :         c.set_root(n);
    4911           1 :         c.set_date_time_variables(csspp_test::get_now());
    4912           1 :         c.add_path(csspp_test::get_script_path());
    4913           1 :         c.add_path(csspp_test::get_version_script_path());
    4914             : 
    4915           1 :         c.compile(false);
    4916             : 
    4917           1 :         VERIFY_ERRORS("");
    4918             : 
    4919             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4920             : 
    4921             :         // to verify that the result is still an INTEGER we have to
    4922             :         // test the root node here
    4923           1 :         std::stringstream compiler_out;
    4924           1 :         compiler_out << *n;
    4925           1 :         VERIFY_TREES(compiler_out.str(),
    4926             : 
    4927             : "LIST\n"
    4928             : + csspp_test::get_default_variables() +
    4929             : "  COMPONENT_VALUE\n"
    4930             : "    ARG\n"
    4931             : "      IDENTIFIER \"div\"\n"
    4932             : "    OPEN_CURLYBRACKET B:true\n"
    4933             : "      LIST\n"
    4934             : "        DECLARATION \"color\"\n"
    4935             : "          ARG\n"
    4936             : "            COLOR H:ff0000ff\n"
    4937             : "        DECLARATION \"border-top-left-color\"\n"
    4938             : "          ARG\n"
    4939             : "            COLOR H:ffffff00\n"
    4940             : "        DECLARATION \"background-color\"\n"
    4941             : "          ARG\n"
    4942             : "            COLOR H:ff000000\n"
    4943             : "        DECLARATION \"border-bottom-left-color\"\n"
    4944             : "          ARG\n"
    4945             : "            COLOR H:ffffffff\n"
    4946             : "        DECLARATION \"border-top-right-color\"\n"
    4947             : "          ARG\n"
    4948             : "            COLOR H:ffffff5a\n"
    4949             : + csspp_test::get_close_comment(true)
    4950             : 
    4951             :             );
    4952             : 
    4953           1 :         std::stringstream assembler_out;
    4954           1 :         csspp::assembler a(assembler_out);
    4955           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4956             : 
    4957             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4958             : 
    4959           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4960             : "div{color:red;border-top-left-color:aqua;background-color:#000;border-bottom-left-color:#fff;border-top-right-color:#5affff}\n"
    4961             : + csspp_test::get_close_comment()
    4962             :                 );
    4963             : 
    4964           1 :         CATCH_REQUIRE(c.get_root() == n);
    4965           1 :     }
    4966          10 :     CATCH_END_SECTION()
    4967             : 
    4968          10 :     CATCH_START_SECTION("Divide color by 5")
    4969             :     {
    4970             :         // note: we do not check the swapped version here, that's done in the
    4971             :         //       test checking for invalid operations
    4972           1 :         std::stringstream ss;
    4973             :         ss << "div {"
    4974             :            << "  color: red / 5;"
    4975             :            << "  background-color: black / 5;"
    4976             :            << "  border-top-right-color: #123456 / 5;"
    4977           1 :            << "}";
    4978           3 :         csspp::position pos("test.css");
    4979           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4980             : 
    4981           2 :         csspp::parser p(l);
    4982             : 
    4983           1 :         csspp::node::pointer_t n(p.stylesheet());
    4984             : 
    4985           1 :         csspp::compiler c;
    4986           1 :         c.set_root(n);
    4987           1 :         c.set_date_time_variables(csspp_test::get_now());
    4988           1 :         c.add_path(csspp_test::get_script_path());
    4989           1 :         c.add_path(csspp_test::get_version_script_path());
    4990             : 
    4991           1 :         c.compile(false);
    4992             : 
    4993           1 :         VERIFY_ERRORS("");
    4994             : 
    4995             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4996             : 
    4997             :         // to verify that the result is still an INTEGER we have to
    4998             :         // test the root node here
    4999           1 :         std::stringstream compiler_out;
    5000           1 :         compiler_out << *n;
    5001           1 :         VERIFY_TREES(compiler_out.str(),
    5002             : 
    5003             : "LIST\n"
    5004             : + csspp_test::get_default_variables() +
    5005             : "  COMPONENT_VALUE\n"
    5006             : "    ARG\n"
    5007             : "      IDENTIFIER \"div\"\n"
    5008             : "    OPEN_CURLYBRACKET B:true\n"
    5009             : "      LIST\n"
    5010             : "        DECLARATION \"color\"\n"
    5011             : "          ARG\n"
    5012             : "            COLOR H:33000033\n"
    5013             : "        DECLARATION \"background-color\"\n"
    5014             : "          ARG\n"
    5015             : "            COLOR H:33000000\n"
    5016             : "        DECLARATION \"border-top-right-color\"\n"
    5017             : "          ARG\n"
    5018             : "            COLOR H:33110a04\n"
    5019             : + csspp_test::get_close_comment(true)
    5020             : 
    5021             :             );
    5022             : 
    5023           1 :         std::stringstream assembler_out;
    5024           1 :         csspp::assembler a(assembler_out);
    5025           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5026             : 
    5027             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5028             : 
    5029           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5030             : "div{color:rgba(51,0,0,.2);background-color:rgba(0,0,0,.2);border-top-right-color:rgba(4,10,17,.2)}\n"
    5031             : + csspp_test::get_close_comment()
    5032             :                 );
    5033             : 
    5034           1 :         CATCH_REQUIRE(c.get_root() == n);
    5035           1 :     }
    5036          10 :     CATCH_END_SECTION()
    5037             : 
    5038          10 :     CATCH_START_SECTION("Modulo color by 55")
    5039             :     {
    5040           1 :         std::stringstream ss;
    5041             :         ss << "div {"
    5042             :            << "  color: red % .215686275;"
    5043             :            << "  background-color: black % .21568627555;"
    5044             :            << "  border-top-right-color: #123456 % .21568627555;"
    5045           1 :            << "}";
    5046           3 :         csspp::position pos("test.css");
    5047           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5048             : 
    5049           2 :         csspp::parser p(l);
    5050             : 
    5051           1 :         csspp::node::pointer_t n(p.stylesheet());
    5052             : 
    5053           1 :         csspp::compiler c;
    5054           1 :         c.set_root(n);
    5055           1 :         c.set_date_time_variables(csspp_test::get_now());
    5056           1 :         c.add_path(csspp_test::get_script_path());
    5057           1 :         c.add_path(csspp_test::get_version_script_path());
    5058             : 
    5059           1 :         c.compile(false);
    5060             : 
    5061           1 :         VERIFY_ERRORS("");
    5062             : 
    5063             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5064             : 
    5065             :         // to verify that the result is still an INTEGER we have to
    5066             :         // test the root node here
    5067           1 :         std::stringstream compiler_out;
    5068           1 :         compiler_out << *n;
    5069           1 :         VERIFY_TREES(compiler_out.str(),
    5070             : 
    5071             : "LIST\n"
    5072             : + csspp_test::get_default_variables() +
    5073             : "  COMPONENT_VALUE\n"
    5074             : "    ARG\n"
    5075             : "      IDENTIFIER \"div\"\n"
    5076             : "    OPEN_CURLYBRACKET B:true\n"
    5077             : "      LIST\n"
    5078             : "        DECLARATION \"color\"\n"
    5079             : "          ARG\n"
    5080             : "            COLOR H:23000023\n"
    5081             : "        DECLARATION \"background-color\"\n"
    5082             : "          ARG\n"
    5083             : "            COLOR H:23000000\n"
    5084             : "        DECLARATION \"border-top-right-color\"\n"
    5085             : "          ARG\n"
    5086             : "            COLOR H:231f3412\n"
    5087             : + csspp_test::get_close_comment(true)
    5088             : 
    5089             :             );
    5090             : 
    5091           1 :         std::stringstream assembler_out;
    5092           1 :         csspp::assembler a(assembler_out);
    5093           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5094             : 
    5095             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5096             : 
    5097           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5098             : "div{color:rgba(35,0,0,.14);background-color:rgba(0,0,0,.14);border-top-right-color:rgba(18,52,31,.14)}\n"
    5099             : + csspp_test::get_close_comment()
    5100             :                 );
    5101             : 
    5102           1 :         CATCH_REQUIRE(c.get_root() == n);
    5103           1 :     }
    5104          10 :     CATCH_END_SECTION()
    5105             : 
    5106          10 :     CATCH_START_SECTION("Multiply color by 1.5")
    5107             :     {
    5108           1 :         std::stringstream ss;
    5109           1 :         ss << "div { color: red * 1.5; background-color: black * 1.5; border-color: #123456 * 1.5 }";
    5110           3 :         csspp::position pos("test.css");
    5111           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5112             : 
    5113           2 :         csspp::parser p(l);
    5114             : 
    5115           1 :         csspp::node::pointer_t n(p.stylesheet());
    5116             : 
    5117           1 :         csspp::compiler c;
    5118           1 :         c.set_root(n);
    5119           1 :         c.set_date_time_variables(csspp_test::get_now());
    5120           1 :         c.add_path(csspp_test::get_script_path());
    5121           1 :         c.add_path(csspp_test::get_version_script_path());
    5122             : 
    5123           1 :         c.compile(false);
    5124             : 
    5125           1 :         VERIFY_ERRORS("");
    5126             : 
    5127             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5128             : 
    5129             :         // to verify that the result is still an INTEGER we have to
    5130             :         // test the root node here
    5131           1 :         std::stringstream compiler_out;
    5132           1 :         compiler_out << *n;
    5133           1 :         VERIFY_TREES(compiler_out.str(),
    5134             : 
    5135             : "LIST\n"
    5136             : + csspp_test::get_default_variables() +
    5137             : "  COMPONENT_VALUE\n"
    5138             : "    ARG\n"
    5139             : "      IDENTIFIER \"div\"\n"
    5140             : "    OPEN_CURLYBRACKET B:true\n"
    5141             : "      LIST\n"
    5142             : "        DECLARATION \"color\"\n"
    5143             : "          ARG\n"
    5144             : "            COLOR H:ff0000ff\n"
    5145             : "        DECLARATION \"background-color\"\n"
    5146             : "          ARG\n"
    5147             : "            COLOR H:ff000000\n"
    5148             : "        DECLARATION \"border-color\"\n"
    5149             : "          ARG\n"
    5150             : "            COLOR H:ff814e1b\n"
    5151             : + csspp_test::get_close_comment(true)
    5152             : 
    5153             :             );
    5154             : 
    5155           1 :         std::stringstream assembler_out;
    5156           1 :         csspp::assembler a(assembler_out);
    5157           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5158             : 
    5159             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5160             : 
    5161           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5162             : "div{color:red;background-color:#000;border-color:#1b4e81}\n"
    5163             : + csspp_test::get_close_comment()
    5164             :                 );
    5165             : 
    5166           1 :         CATCH_REQUIRE(c.get_root() == n);
    5167           1 :     }
    5168          10 :     CATCH_END_SECTION()
    5169             : 
    5170          10 :     CATCH_START_SECTION("Multiply color by 1.5")
    5171             :     {
    5172           1 :         std::stringstream ss;
    5173           1 :         ss << "div { color: 1.5 * red; background-color: 1.5 * black; border-color: 1.5 * #123456 }";
    5174           3 :         csspp::position pos("test.css");
    5175           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5176             : 
    5177           2 :         csspp::parser p(l);
    5178             : 
    5179           1 :         csspp::node::pointer_t n(p.stylesheet());
    5180             : 
    5181           1 :         csspp::compiler c;
    5182           1 :         c.set_root(n);
    5183           1 :         c.set_date_time_variables(csspp_test::get_now());
    5184           1 :         c.add_path(csspp_test::get_script_path());
    5185           1 :         c.add_path(csspp_test::get_version_script_path());
    5186             : 
    5187           1 :         c.compile(false);
    5188             : 
    5189           1 :         VERIFY_ERRORS("");
    5190             : 
    5191             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5192             : 
    5193             :         // to verify that the result is still an INTEGER we have to
    5194             :         // test the root node here
    5195           1 :         std::stringstream compiler_out;
    5196           1 :         compiler_out << *n;
    5197           1 :         VERIFY_TREES(compiler_out.str(),
    5198             : 
    5199             : "LIST\n"
    5200             : + csspp_test::get_default_variables() +
    5201             : "  COMPONENT_VALUE\n"
    5202             : "    ARG\n"
    5203             : "      IDENTIFIER \"div\"\n"
    5204             : "    OPEN_CURLYBRACKET B:true\n"
    5205             : "      LIST\n"
    5206             : "        DECLARATION \"color\"\n"
    5207             : "          ARG\n"
    5208             : "            COLOR H:ff0000ff\n"
    5209             : "        DECLARATION \"background-color\"\n"
    5210             : "          ARG\n"
    5211             : "            COLOR H:ff000000\n"
    5212             : "        DECLARATION \"border-color\"\n"
    5213             : "          ARG\n"
    5214             : "            COLOR H:ff814e1b\n"
    5215             : + csspp_test::get_close_comment(true)
    5216             : 
    5217             :             );
    5218             : 
    5219           1 :         std::stringstream assembler_out;
    5220           1 :         csspp::assembler a(assembler_out);
    5221           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5222             : 
    5223             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5224             : 
    5225           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5226             : "div{color:red;background-color:#000;border-color:#1b4e81}\n"
    5227             : + csspp_test::get_close_comment()
    5228             :                 );
    5229             : 
    5230           1 :         CATCH_REQUIRE(c.get_root() == n);
    5231           1 :     }
    5232          10 :     CATCH_END_SECTION()
    5233             : 
    5234          10 :     CATCH_START_SECTION("Divide color by 1.5")
    5235             :     {
    5236           1 :         std::stringstream ss;
    5237           1 :         ss << "div { color: red / 1.5; background-color: black / 1.5; border-color: #123456 / 1.5 }";
    5238           3 :         csspp::position pos("test.css");
    5239           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5240             : 
    5241           2 :         csspp::parser p(l);
    5242             : 
    5243           1 :         csspp::node::pointer_t n(p.stylesheet());
    5244             : 
    5245           1 :         csspp::compiler c;
    5246           1 :         c.set_root(n);
    5247           1 :         c.set_date_time_variables(csspp_test::get_now());
    5248           1 :         c.add_path(csspp_test::get_script_path());
    5249           1 :         c.add_path(csspp_test::get_version_script_path());
    5250             : 
    5251           1 :         c.compile(false);
    5252             : 
    5253           1 :         VERIFY_ERRORS("");
    5254             : 
    5255             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5256             : 
    5257             :         // to verify that the result is still an INTEGER we have to
    5258             :         // test the root node here
    5259           1 :         std::stringstream compiler_out;
    5260           1 :         compiler_out << *n;
    5261           1 :         VERIFY_TREES(compiler_out.str(),
    5262             : 
    5263             : "LIST\n"
    5264             : + csspp_test::get_default_variables() +
    5265             : "  COMPONENT_VALUE\n"
    5266             : "    ARG\n"
    5267             : "      IDENTIFIER \"div\"\n"
    5268             : "    OPEN_CURLYBRACKET B:true\n"
    5269             : "      LIST\n"
    5270             : "        DECLARATION \"color\"\n"
    5271             : "          ARG\n"
    5272             : "            COLOR H:aa0000aa\n"
    5273             : "        DECLARATION \"background-color\"\n"
    5274             : "          ARG\n"
    5275             : "            COLOR H:aa000000\n"
    5276             : "        DECLARATION \"border-color\"\n"
    5277             : "          ARG\n"
    5278             : "            COLOR H:aa39230c\n"
    5279             : + csspp_test::get_close_comment(true)
    5280             : 
    5281             :             );
    5282             : 
    5283           1 :         std::stringstream assembler_out;
    5284           1 :         csspp::assembler a(assembler_out);
    5285           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5286             : 
    5287             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5288             : 
    5289           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5290             : "div{color:rgba(170,0,0,.67);background-color:rgba(0,0,0,.67);border-color:rgba(12,35,57,.67)}\n"
    5291             : + csspp_test::get_close_comment()
    5292             :                 );
    5293             : 
    5294           1 :         CATCH_REQUIRE(c.get_root() == n);
    5295           1 :     }
    5296          10 :     CATCH_END_SECTION()
    5297             : 
    5298          10 :     CATCH_START_SECTION("Modulo color by 0.7")
    5299             :     {
    5300           1 :         std::stringstream ss;
    5301           1 :         ss << "div { color: red % 0.7; background-color: black % 0.7; border-color: #123456 % 0.7 }";
    5302           3 :         csspp::position pos("test.css");
    5303           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5304             : 
    5305           2 :         csspp::parser p(l);
    5306             : 
    5307           1 :         csspp::node::pointer_t n(p.stylesheet());
    5308             : 
    5309           1 :         csspp::compiler c;
    5310           1 :         c.set_root(n);
    5311           1 :         c.set_date_time_variables(csspp_test::get_now());
    5312           1 :         c.add_path(csspp_test::get_script_path());
    5313           1 :         c.add_path(csspp_test::get_version_script_path());
    5314             : 
    5315           1 :         c.compile(false);
    5316             : 
    5317           1 :         VERIFY_ERRORS("");
    5318             : 
    5319             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5320             : 
    5321             :         // to verify that the result is still an INTEGER we have to
    5322             :         // test the root node here
    5323           1 :         std::stringstream compiler_out;
    5324           1 :         compiler_out << *n;
    5325           1 :         VERIFY_TREES(compiler_out.str(),
    5326             : 
    5327             : "LIST\n"
    5328             : + csspp_test::get_default_variables() +
    5329             : "  COMPONENT_VALUE\n"
    5330             : "    ARG\n"
    5331             : "      IDENTIFIER \"div\"\n"
    5332             : "    OPEN_CURLYBRACKET B:true\n"
    5333             : "      LIST\n"
    5334             : "        DECLARATION \"color\"\n"
    5335             : "          ARG\n"
    5336             : "            COLOR H:4d00004d\n"
    5337             : "        DECLARATION \"background-color\"\n"
    5338             : "          ARG\n"
    5339             : "            COLOR H:4d000000\n"
    5340             : "        DECLARATION \"border-color\"\n"
    5341             : "          ARG\n"
    5342             : "            COLOR H:4d563412\n"
    5343             : + csspp_test::get_close_comment(true)
    5344             : 
    5345             :             );
    5346             : 
    5347           1 :         std::stringstream assembler_out;
    5348           1 :         csspp::assembler a(assembler_out);
    5349           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5350             : 
    5351             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5352             : 
    5353           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5354             : "div{color:rgba(77,0,0,.3);background-color:rgba(0,0,0,.3);border-color:rgba(18,52,86,.3)}\n"
    5355             : + csspp_test::get_close_comment()
    5356             :                 );
    5357             : 
    5358           1 :         CATCH_REQUIRE(c.get_root() == n);
    5359           1 :     }
    5360          10 :     CATCH_END_SECTION()
    5361             : 
    5362          10 :     CATCH_START_SECTION("Color * color")
    5363             :     {
    5364           1 :         std::stringstream ss;
    5365           1 :         ss << "div { color: red * blue; background-color: frgba(0.3, 0.7, 0.2, 0.5) * frgba(0.9, 0.85, 1.2, 0.5) }";
    5366           3 :         csspp::position pos("test.css");
    5367           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5368             : 
    5369           2 :         csspp::parser p(l);
    5370             : 
    5371           1 :         csspp::node::pointer_t n(p.stylesheet());
    5372             : 
    5373           1 :         csspp::compiler c;
    5374           1 :         c.set_root(n);
    5375           1 :         c.set_date_time_variables(csspp_test::get_now());
    5376           1 :         c.add_path(csspp_test::get_script_path());
    5377           1 :         c.add_path(csspp_test::get_version_script_path());
    5378             : 
    5379           1 :         c.compile(false);
    5380             : 
    5381           1 :         VERIFY_ERRORS("");
    5382             : 
    5383             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5384             : 
    5385             :         // to verify that the result is still an INTEGER we have to
    5386             :         // test the root node here
    5387           1 :         std::stringstream compiler_out;
    5388           1 :         compiler_out << *n;
    5389           1 :         VERIFY_TREES(compiler_out.str(),
    5390             : 
    5391             : "LIST\n"
    5392             : + csspp_test::get_default_variables() +
    5393             : "  COMPONENT_VALUE\n"
    5394             : "    ARG\n"
    5395             : "      IDENTIFIER \"div\"\n"
    5396             : "    OPEN_CURLYBRACKET B:true\n"
    5397             : "      LIST\n"
    5398             : "        DECLARATION \"color\"\n"
    5399             : "          ARG\n"
    5400             : "            COLOR H:ff000000\n"
    5401             : "        DECLARATION \"background-color\"\n"
    5402             : "          ARG\n"
    5403             : "            COLOR H:403d9845\n"
    5404             : + csspp_test::get_close_comment(true)
    5405             : 
    5406             :             );
    5407             : 
    5408           1 :         std::stringstream assembler_out;
    5409           1 :         csspp::assembler a(assembler_out);
    5410           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5411             : 
    5412             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5413             : 
    5414           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5415             : "div{color:#000;background-color:rgba(69,152,61,.25)}\n"
    5416             : + csspp_test::get_close_comment()
    5417             :                 );
    5418             : 
    5419           1 :         CATCH_REQUIRE(c.get_root() == n);
    5420           1 :     }
    5421          10 :     CATCH_END_SECTION()
    5422             : 
    5423          10 :     CATCH_START_SECTION("Color / color")
    5424             :     {
    5425           1 :         std::stringstream ss;
    5426           1 :         ss << "div { color: red / #0a0a0a; background-color: frgba(0.3, 0.7, 0.2, 0.5) / frgba(0.9, 0.85, 1.2, 0.5) }";
    5427           3 :         csspp::position pos("test.css");
    5428           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5429             : 
    5430           2 :         csspp::parser p(l);
    5431             : 
    5432           1 :         csspp::node::pointer_t n(p.stylesheet());
    5433             : 
    5434           1 :         csspp::compiler c;
    5435           1 :         c.set_root(n);
    5436           1 :         c.set_date_time_variables(csspp_test::get_now());
    5437           1 :         c.add_path(csspp_test::get_script_path());
    5438           1 :         c.add_path(csspp_test::get_version_script_path());
    5439             : 
    5440           1 :         c.compile(false);
    5441             : 
    5442           1 :         VERIFY_ERRORS("");
    5443             : 
    5444             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5445             : 
    5446             :         // to verify that the result is still an INTEGER we have to
    5447             :         // test the root node here
    5448           1 :         std::stringstream compiler_out;
    5449           1 :         compiler_out << *n;
    5450           1 :         VERIFY_TREES(compiler_out.str(),
    5451             : 
    5452             : "LIST\n"
    5453             : + csspp_test::get_default_variables() +
    5454             : "  COMPONENT_VALUE\n"
    5455             : "    ARG\n"
    5456             : "      IDENTIFIER \"div\"\n"
    5457             : "    OPEN_CURLYBRACKET B:true\n"
    5458             : "      LIST\n"
    5459             : "        DECLARATION \"color\"\n"
    5460             : "          ARG\n"
    5461             : "            COLOR H:ff0000ff\n"
    5462             : "        DECLARATION \"background-color\"\n"
    5463             : "          ARG\n"
    5464             : "            COLOR H:ff2ad255\n"
    5465             : + csspp_test::get_close_comment(true)
    5466             : 
    5467             :             );
    5468             : 
    5469           1 :         std::stringstream assembler_out;
    5470           1 :         csspp::assembler a(assembler_out);
    5471           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5472             : 
    5473             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5474             : 
    5475           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5476             : "div{color:red;background-color:#55d22a}\n"
    5477             : + csspp_test::get_close_comment()
    5478             :                 );
    5479             : 
    5480           1 :         CATCH_REQUIRE(c.get_root() == n);
    5481           1 :     }
    5482          10 :     CATCH_END_SECTION()
    5483             : 
    5484          10 :     CATCH_START_SECTION("Color % color")
    5485             :     {
    5486           1 :         std::stringstream ss;
    5487           1 :         ss << "div { color: red % #0a0a0a; background-color: frgba(0.97, 0.85, 1.2, 0.75) % frgba(0.31, 0.7, 0.2, 0.5) }";
    5488           3 :         csspp::position pos("test.css");
    5489           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5490             : 
    5491           2 :         csspp::parser p(l);
    5492             : 
    5493           1 :         csspp::node::pointer_t n(p.stylesheet());
    5494             : 
    5495           1 :         csspp::compiler c;
    5496           1 :         c.set_root(n);
    5497           1 :         c.set_date_time_variables(csspp_test::get_now());
    5498           1 :         c.add_path(csspp_test::get_script_path());
    5499           1 :         c.add_path(csspp_test::get_version_script_path());
    5500             : 
    5501           1 :         c.compile(false);
    5502             : 
    5503           1 :         VERIFY_ERRORS("");
    5504             : 
    5505             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5506             : 
    5507             :         // to verify that the result is still an INTEGER we have to
    5508             :         // test the root node here
    5509           1 :         std::stringstream compiler_out;
    5510           1 :         compiler_out << *n;
    5511           1 :         VERIFY_TREES(compiler_out.str(),
    5512             : 
    5513             : "LIST\n"
    5514             : + csspp_test::get_default_variables() +
    5515             : "  COMPONENT_VALUE\n"
    5516             : "    ARG\n"
    5517             : "      IDENTIFIER \"div\"\n"
    5518             : "    OPEN_CURLYBRACKET B:true\n"
    5519             : "      LIST\n"
    5520             : "        DECLARATION \"color\"\n"
    5521             : "          ARG\n"
    5522             : "            COLOR H:5\n"
    5523             : "        DECLARATION \"background-color\"\n"
    5524             : "          ARG\n"
    5525             : "            COLOR H:4000260a\n"
    5526             : + csspp_test::get_close_comment(true)
    5527             : 
    5528             :             );
    5529             : 
    5530           1 :         std::stringstream assembler_out;
    5531           1 :         csspp::assembler a(assembler_out);
    5532           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5533             : 
    5534             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5535             : 
    5536           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5537             : "div{color:transparent;background-color:rgba(10,38,0,.25)}\n"
    5538             : + csspp_test::get_close_comment()
    5539             :                 );
    5540             : 
    5541           1 :         CATCH_REQUIRE(c.get_root() == n);
    5542           1 :     }
    5543          10 :     CATCH_END_SECTION()
    5544             : 
    5545             :     // no error left over
    5546          10 :     VERIFY_ERRORS("");
    5547          10 : }
    5548             : 
    5549           7 : CATCH_TEST_CASE("Invalid expressions with colors", "[expression] [multiplicative] [colors] [invalid]")
    5550             : {
    5551           7 :     CATCH_START_SECTION("Divide 5 by a color is not valid")
    5552             :     {
    5553           1 :         std::stringstream ss;
    5554           1 :         ss << "div { border-top-left-color: 5 / teal; }";
    5555           3 :         csspp::position pos("test.css");
    5556           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5557             : 
    5558           2 :         csspp::parser p(l);
    5559             : 
    5560           1 :         csspp::node::pointer_t n(p.stylesheet());
    5561             : 
    5562           1 :         csspp::compiler c;
    5563           1 :         c.set_root(n);
    5564           1 :         c.set_date_time_variables(csspp_test::get_now());
    5565           1 :         c.add_path(csspp_test::get_script_path());
    5566           1 :         c.add_path(csspp_test::get_version_script_path());
    5567             : 
    5568           1 :         c.compile(false);
    5569             : 
    5570           1 :         VERIFY_ERRORS("test.css(1): error: 'number / color' and 'number % color' are not available.\n");
    5571             : 
    5572           1 :         CATCH_REQUIRE(c.get_root() == n);
    5573           1 :     }
    5574           7 :     CATCH_END_SECTION()
    5575             : 
    5576           7 :     CATCH_START_SECTION("Modulo 5 by a color is not valid")
    5577             :     {
    5578           1 :         std::stringstream ss;
    5579           1 :         ss << "div { border-top-left-color: 5 % teal; }";
    5580           3 :         csspp::position pos("test.css");
    5581           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5582             : 
    5583           2 :         csspp::parser p(l);
    5584             : 
    5585           1 :         csspp::node::pointer_t n(p.stylesheet());
    5586             : 
    5587           1 :         csspp::compiler c;
    5588           1 :         c.set_root(n);
    5589           1 :         c.set_date_time_variables(csspp_test::get_now());
    5590           1 :         c.add_path(csspp_test::get_script_path());
    5591           1 :         c.add_path(csspp_test::get_version_script_path());
    5592             : 
    5593           1 :         c.compile(false);
    5594             : 
    5595           1 :         VERIFY_ERRORS("test.css(1): error: 'number / color' and 'number % color' are not available.\n");
    5596             : 
    5597           1 :         CATCH_REQUIRE(c.get_root() == n);
    5598           1 :     }
    5599           7 :     CATCH_END_SECTION()
    5600             : 
    5601           7 :     CATCH_START_SECTION("Divide 5.8 by a color is not valid")
    5602             :     {
    5603           1 :         std::stringstream ss;
    5604           1 :         ss << "div { border-top-left-color: 5.8 / teal; }";
    5605           3 :         csspp::position pos("test.css");
    5606           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5607             : 
    5608             : //std::cerr << "parse [" << ss.str() << "]\n";
    5609           2 :         csspp::parser p(l);
    5610             : 
    5611           1 :         csspp::node::pointer_t n(p.stylesheet());
    5612             : 
    5613           1 :         csspp::compiler c;
    5614           1 :         c.set_root(n);
    5615           1 :         c.set_date_time_variables(csspp_test::get_now());
    5616           1 :         c.add_path(csspp_test::get_script_path());
    5617           1 :         c.add_path(csspp_test::get_version_script_path());
    5618             : 
    5619           1 :         c.compile(false);
    5620             : 
    5621           1 :         VERIFY_ERRORS("test.css(1): error: 'number / color' and 'number % color' are not available.\n");
    5622             : 
    5623           1 :         CATCH_REQUIRE(c.get_root() == n);
    5624           1 :     }
    5625           7 :     CATCH_END_SECTION()
    5626             : 
    5627           7 :     CATCH_START_SECTION("Modulo 5.8 by a color is not valid")
    5628             :     {
    5629           1 :         std::stringstream ss;
    5630           1 :         ss << "div { border-top-left-color: 5.8 % teal; }";
    5631           3 :         csspp::position pos("test.css");
    5632           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5633             : 
    5634             : //std::cerr << "parse [" << ss.str() << "]\n";
    5635           2 :         csspp::parser p(l);
    5636             : 
    5637           1 :         csspp::node::pointer_t n(p.stylesheet());
    5638             : 
    5639           1 :         csspp::compiler c;
    5640           1 :         c.set_root(n);
    5641           1 :         c.set_date_time_variables(csspp_test::get_now());
    5642           1 :         c.add_path(csspp_test::get_script_path());
    5643           1 :         c.add_path(csspp_test::get_version_script_path());
    5644             : 
    5645           1 :         c.compile(false);
    5646             : 
    5647           1 :         VERIFY_ERRORS("test.css(1): error: 'number / color' and 'number % color' are not available.\n");
    5648             : 
    5649           1 :         CATCH_REQUIRE(c.get_root() == n);
    5650           1 :     }
    5651           7 :     CATCH_END_SECTION()
    5652             : 
    5653           7 :     CATCH_START_SECTION("Multiply 3px by a color is not valid")
    5654             :     {
    5655           1 :         std::stringstream ss;
    5656           1 :         ss << "div { border-top-left-color: 3px * chocolate; }";
    5657           3 :         csspp::position pos("test.css");
    5658           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5659             : 
    5660             : //std::cerr << "parse [" << ss.str() << "]\n";
    5661           2 :         csspp::parser p(l);
    5662             : 
    5663           1 :         csspp::node::pointer_t n(p.stylesheet());
    5664             : 
    5665           1 :         csspp::compiler c;
    5666           1 :         c.set_root(n);
    5667           1 :         c.set_date_time_variables(csspp_test::get_now());
    5668           1 :         c.add_path(csspp_test::get_script_path());
    5669           1 :         c.add_path(csspp_test::get_version_script_path());
    5670             : 
    5671           1 :         c.compile(false);
    5672             : 
    5673           1 :         VERIFY_ERRORS("test.css(1): error: color factors must be unit less values, 3px is not acceptable.\n");
    5674             : 
    5675           1 :         CATCH_REQUIRE(c.get_root() == n);
    5676           1 :     }
    5677           7 :     CATCH_END_SECTION()
    5678             : 
    5679           7 :     CATCH_START_SECTION("Color division by zero")
    5680             :     {
    5681           1 :         std::stringstream ss;
    5682           1 :         ss << "div { border-top-left-color: teal / blue; }";
    5683           3 :         csspp::position pos("test.css");
    5684           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5685             : 
    5686           2 :         csspp::parser p(l);
    5687             : 
    5688           1 :         csspp::node::pointer_t n(p.stylesheet());
    5689             : 
    5690           1 :         csspp::compiler c;
    5691           1 :         c.set_root(n);
    5692           1 :         c.set_date_time_variables(csspp_test::get_now());
    5693           1 :         c.add_path(csspp_test::get_script_path());
    5694           1 :         c.add_path(csspp_test::get_version_script_path());
    5695             : 
    5696           1 :         c.compile(false);
    5697             : 
    5698           1 :         VERIFY_ERRORS("test.css(1): error: color division does not accept any color component set to zero.\n");
    5699             : 
    5700           1 :         CATCH_REQUIRE(c.get_root() == n);
    5701           1 :     }
    5702           7 :     CATCH_END_SECTION()
    5703             : 
    5704           7 :     CATCH_START_SECTION("Color modulo by zero")
    5705             :     {
    5706           1 :         std::stringstream ss;
    5707           1 :         ss << "div { border-top-left-color: teal % blue; }";
    5708           3 :         csspp::position pos("test.css");
    5709           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5710             : 
    5711           2 :         csspp::parser p(l);
    5712             : 
    5713           1 :         csspp::node::pointer_t n(p.stylesheet());
    5714             : 
    5715           1 :         csspp::compiler c;
    5716           1 :         c.set_root(n);
    5717           1 :         c.set_date_time_variables(csspp_test::get_now());
    5718           1 :         c.add_path(csspp_test::get_script_path());
    5719           1 :         c.add_path(csspp_test::get_version_script_path());
    5720             : 
    5721           1 :         c.compile(false);
    5722             : 
    5723           1 :         VERIFY_ERRORS("test.css(1): error: color modulo does not accept any color component set to zero.\n");
    5724             : 
    5725           1 :         CATCH_REQUIRE(c.get_root() == n);
    5726           1 :     }
    5727           7 :     CATCH_END_SECTION()
    5728             : 
    5729             :     // still no errors?
    5730           7 :     VERIFY_ERRORS("");
    5731           7 : }
    5732             : 
    5733             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14