LCOV - code coverage report
Current view: top level - tests - catch_internal_functions.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2945 2947 99.9 %
Date: 2023-11-01 21:56:19 Functions: 18 18 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             : // https://snapwebsites.org/project/csspp
       4             : // contact@m2osw.com
       5             : //
       6             : // This program is free software; you can redistribute it and/or modify
       7             : // it under the terms of the GNU General Public License as published by
       8             : // the Free Software Foundation; either version 2 of the License, or
       9             : // (at your option) any later version.
      10             : //
      11             : // This program is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : //
      16             : // You should have received a copy of the GNU General Public License along
      17             : // with this program; if not, write to the Free Software Foundation, Inc.,
      18             : // 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      19             : 
      20             : /** \file
      21             :  * \brief Test the internal_functions.cpp file.
      22             :  *
      23             :  * This test runs a battery of tests agains internal_functions.cpp
      24             :  * to ensure full coverage and that all the internal functions are
      25             :  * checked for the equality CSS Preprocessor extensions.
      26             :  *
      27             :  * Note that all the tests use the full chain: lexer, parser, compiler,
      28             :  * and assembler to make sure the results are correct. So these tests
      29             :  * exercise the assembler even more than the assembler tests, except that
      30             :  * it only checks that compressed results are correct instead of all
      31             :  * output modes, since its only goal is covering all the possible
      32             :  * expression cases and not the assembler, compiler, parser, and lexer
      33             :  * classes.
      34             :  */
      35             : 
      36             : // csspp
      37             : //
      38             : #include    <csspp/assembler.h>
      39             : #include    <csspp/compiler.h>
      40             : #include    <csspp/exception.h>
      41             : #include    <csspp/parser.h>
      42             : 
      43             : 
      44             : // self
      45             : //
      46             : #include    "catch_main.h"
      47             : 
      48             : 
      49             : // C++
      50             : //
      51             : #include    <cmath>
      52             : #include    <iomanip>
      53             : #include    <sstream>
      54             : 
      55             : 
      56             : // last include
      57             : //
      58             : #include    <snapdev/poison.h>
      59             : 
      60             : 
      61             : 
      62           1 : CATCH_TEST_CASE("Expression calc()", "[expression] [internal-functions] [calc]")
      63             : {
      64           1 :     CATCH_START_SECTION("calc() -- leave that one alone!")
      65             :     {
      66           1 :         std::stringstream ss;
      67           1 :         ss << "div { width: calc(3px + 5%); }";
      68           3 :         csspp::position pos("test.css");
      69           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
      70             : 
      71           2 :         csspp::parser p(l);
      72             : 
      73           1 :         csspp::node::pointer_t n(p.stylesheet());
      74             : 
      75           1 :         csspp::compiler c;
      76           1 :         c.set_root(n);
      77           1 :         c.set_date_time_variables(csspp_test::get_now());
      78           1 :         c.add_path(csspp_test::get_script_path());
      79           1 :         c.add_path(csspp_test::get_version_script_path());
      80             : 
      81           1 :         c.compile(false);
      82             : 
      83             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
      84             : 
      85           1 :         VERIFY_ERRORS("");
      86             : 
      87           1 :         std::stringstream compiler_out;
      88           1 :         compiler_out << *n;
      89           1 :         VERIFY_TREES(compiler_out.str(),
      90             : 
      91             : "LIST\n"
      92             : + csspp_test::get_default_variables() +
      93             : "  COMPONENT_VALUE\n"
      94             : "    ARG\n"
      95             : "      IDENTIFIER \"div\"\n"
      96             : "    OPEN_CURLYBRACKET B:true\n"
      97             : "      DECLARATION \"width\"\n"
      98             : "        ARG\n"
      99             : "          FUNCTION \"calc\"\n"
     100             : "            ARG\n"
     101             : "              INTEGER \"px\" I:3\n"
     102             : "              WHITESPACE\n"
     103             : "              ADD\n"
     104             : "              WHITESPACE\n"
     105             : "              PERCENT D:0.05\n"
     106             : + csspp_test::get_close_comment(true)
     107             : 
     108             :             );
     109             : 
     110           1 :         std::stringstream assembler_out;
     111           1 :         csspp::assembler a(assembler_out);
     112           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     113             : 
     114             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     115             : 
     116           1 :         CATCH_REQUIRE(assembler_out.str() ==
     117             : 
     118             : "div{width:calc(3px + 5%)}\n"
     119             : + csspp_test::get_close_comment()
     120             : 
     121             :                 );
     122             : 
     123           1 :         CATCH_REQUIRE(c.get_root() == n);
     124           1 :     }
     125           1 :     CATCH_END_SECTION()
     126             : 
     127             :     // no error left over
     128           1 :     VERIFY_ERRORS("");
     129           1 : }
     130             : 
     131           3 : CATCH_TEST_CASE("Expression cos()/sin()/tan()", "[expression] [internal-functions] [cos] [sin] [tan]")
     132             : {
     133           3 :     CATCH_START_SECTION("cos(pi)")
     134             :     {
     135          27 :         for(int angle(-180); angle <= 180; angle += rand() % 25 + 1)
     136             :         {
     137             :             // unspecified (defaults to degrees)
     138             :             {
     139          26 :                 std::stringstream ss;
     140          26 :                 ss << "div { z-index: cos("
     141             :                    << angle
     142          26 :                    << "); }";
     143          78 :                 csspp::position pos("test.css");
     144          26 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     145             : 
     146          52 :                 csspp::parser p(l);
     147             : 
     148          26 :                 csspp::node::pointer_t n(p.stylesheet());
     149             : 
     150          26 :                 csspp::compiler c;
     151          26 :                 c.set_root(n);
     152          26 :                 c.set_date_time_variables(csspp_test::get_now());
     153          26 :                 c.add_path(csspp_test::get_script_path());
     154          26 :                 c.add_path(csspp_test::get_version_script_path());
     155             : 
     156          26 :                 c.compile(false);
     157             : 
     158             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     159             : 
     160             :                 // to verify that the result is still an INTEGER we have to
     161             :                 // test the root node here
     162          26 :                 std::stringstream compiler_out;
     163          26 :                 compiler_out << *n;
     164          26 :                 VERIFY_TREES(compiler_out.str(),
     165             : 
     166             : "LIST\n"
     167             : + csspp_test::get_default_variables() +
     168             : "  COMPONENT_VALUE\n"
     169             : "    ARG\n"
     170             : "      IDENTIFIER \"div\"\n"
     171             : "    OPEN_CURLYBRACKET B:true\n"
     172             : "      DECLARATION \"z-index\"\n"
     173             : "        ARG\n"
     174             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(cos(angle * M_PI / 180.0), false) + "\n"
     175             : + csspp_test::get_close_comment(true)
     176             : 
     177             :                     );
     178             : 
     179          26 :                 std::stringstream assembler_out;
     180          26 :                 csspp::assembler a(assembler_out);
     181          26 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     182             : 
     183             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     184             : 
     185          26 :                 CATCH_REQUIRE(assembler_out.str() ==
     186             : 
     187             : std::string("div{z-index:") + csspp::decimal_number_to_string(cos(angle * M_PI / 180.0), true) + "}\n"
     188             : + csspp_test::get_close_comment()
     189             : 
     190             :                         );
     191             : 
     192          26 :                 CATCH_REQUIRE(c.get_root() == n);
     193          26 :             }
     194             : 
     195             :             // degrees
     196             :             {
     197          26 :                 std::stringstream ss;
     198          26 :                 ss << "div { z-index: cos("
     199             :                    << angle
     200          26 :                    << "deg); }";
     201          78 :                 csspp::position pos("test.css");
     202          26 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     203             : 
     204          52 :                 csspp::parser p(l);
     205             : 
     206          26 :                 csspp::node::pointer_t n(p.stylesheet());
     207             : 
     208          26 :                 csspp::compiler c;
     209          26 :                 c.set_root(n);
     210          26 :                 c.set_date_time_variables(csspp_test::get_now());
     211          26 :                 c.add_path(csspp_test::get_script_path());
     212          26 :                 c.add_path(csspp_test::get_version_script_path());
     213             : 
     214          26 :                 c.compile(false);
     215             : 
     216             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     217             : 
     218             :                 // to verify that the result is still an INTEGER we have to
     219             :                 // test the root node here
     220          26 :                 std::stringstream compiler_out;
     221          26 :                 compiler_out << *n;
     222          26 :                 VERIFY_TREES(compiler_out.str(),
     223             : 
     224             : "LIST\n"
     225             : + csspp_test::get_default_variables() +
     226             : "  COMPONENT_VALUE\n"
     227             : "    ARG\n"
     228             : "      IDENTIFIER \"div\"\n"
     229             : "    OPEN_CURLYBRACKET B:true\n"
     230             : "      DECLARATION \"z-index\"\n"
     231             : "        ARG\n"
     232             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(cos(angle * M_PI / 180.0), false) + "\n"
     233             : + csspp_test::get_close_comment(true)
     234             : 
     235             :                     );
     236             : 
     237          26 :                 std::stringstream assembler_out;
     238          26 :                 csspp::assembler a(assembler_out);
     239          26 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     240             : 
     241             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     242             : 
     243          26 :                 CATCH_REQUIRE(assembler_out.str() ==
     244             : 
     245             : std::string("div{z-index:") + csspp::decimal_number_to_string(cos(angle * M_PI / 180.0), true) + "}\n"
     246             : + csspp_test::get_close_comment()
     247             : 
     248             :                         );
     249             : 
     250          26 :                 CATCH_REQUIRE(c.get_root() == n);
     251          26 :             }
     252             : 
     253             :             // radians
     254             :             {
     255          26 :                 std::stringstream ss;
     256          26 :                 ss << "div { z-index: cos("
     257          26 :                    << angle * M_PI / 180.0
     258          26 :                    << "rad); }";
     259          78 :                 csspp::position pos("test.css");
     260          26 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     261             : 
     262          52 :                 csspp::parser p(l);
     263             : 
     264          26 :                 csspp::node::pointer_t n(p.stylesheet());
     265             : 
     266          26 :                 csspp::compiler c;
     267          26 :                 c.set_root(n);
     268          26 :                 c.set_date_time_variables(csspp_test::get_now());
     269          26 :                 c.add_path(csspp_test::get_script_path());
     270          26 :                 c.add_path(csspp_test::get_version_script_path());
     271             : 
     272          26 :                 c.compile(false);
     273             : 
     274             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     275             : 
     276             :                 // to verify that the result is still an INTEGER we have to
     277             :                 // test the root node here
     278          26 :                 std::stringstream compiler_out;
     279          26 :                 compiler_out << *n;
     280          26 :                 VERIFY_TREES(compiler_out.str(),
     281             : 
     282             : "LIST\n"
     283             : + csspp_test::get_default_variables() +
     284             : "  COMPONENT_VALUE\n"
     285             : "    ARG\n"
     286             : "      IDENTIFIER \"div\"\n"
     287             : "    OPEN_CURLYBRACKET B:true\n"
     288             : "      DECLARATION \"z-index\"\n"
     289             : "        ARG\n"
     290             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(cos(angle * M_PI / 180.0), false) + "\n"
     291             : + csspp_test::get_close_comment(true)
     292             : 
     293             :                     );
     294             : 
     295          26 :                 std::stringstream assembler_out;
     296          26 :                 csspp::assembler a(assembler_out);
     297          26 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     298             : 
     299             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     300             : 
     301          26 :                 CATCH_REQUIRE(assembler_out.str() ==
     302             : 
     303             : std::string("div{z-index:") + csspp::decimal_number_to_string(cos(angle * M_PI / 180.0), true) + "}\n"
     304             : + csspp_test::get_close_comment()
     305             : 
     306             :                         );
     307             : 
     308          26 :                 CATCH_REQUIRE(c.get_root() == n);
     309          26 :             }
     310             : 
     311             :             // gradians
     312             :             {
     313          26 :                 std::stringstream ss;
     314          26 :                 ss << "div { z-index: cos("
     315          26 :                    << angle * 200 / 180.0
     316          26 :                    << "grad); }";
     317          78 :                 csspp::position pos("test.css");
     318          26 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     319             : 
     320          52 :                 csspp::parser p(l);
     321             : 
     322          26 :                 csspp::node::pointer_t n(p.stylesheet());
     323             : 
     324          26 :                 csspp::compiler c;
     325          26 :                 c.set_root(n);
     326          26 :                 c.set_date_time_variables(csspp_test::get_now());
     327          26 :                 c.add_path(csspp_test::get_script_path());
     328          26 :                 c.add_path(csspp_test::get_version_script_path());
     329             : 
     330          26 :                 c.compile(false);
     331             : 
     332             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     333             : 
     334             :                 // to verify that the result is still an INTEGER we have to
     335             :                 // test the root node here
     336          26 :                 std::stringstream compiler_out;
     337          26 :                 compiler_out << *n;
     338          26 :                 VERIFY_TREES(compiler_out.str(),
     339             : 
     340             : "LIST\n"
     341             : + csspp_test::get_default_variables() +
     342             : "  COMPONENT_VALUE\n"
     343             : "    ARG\n"
     344             : "      IDENTIFIER \"div\"\n"
     345             : "    OPEN_CURLYBRACKET B:true\n"
     346             : "      DECLARATION \"z-index\"\n"
     347             : "        ARG\n"
     348             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(cos(angle * M_PI / 180.0), false) + "\n"
     349             : + csspp_test::get_close_comment(true)
     350             : 
     351             :                     );
     352             : 
     353          26 :                 std::stringstream assembler_out;
     354          26 :                 csspp::assembler a(assembler_out);
     355          26 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     356             : 
     357             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     358             : 
     359          26 :                 CATCH_REQUIRE(assembler_out.str() ==
     360             : 
     361             : std::string("div{z-index:") + csspp::decimal_number_to_string(cos(angle * M_PI / 180.0), true) + "}\n"
     362             : + csspp_test::get_close_comment()
     363             : 
     364             :                         );
     365             : 
     366          26 :                 CATCH_REQUIRE(c.get_root() == n);
     367          26 :             }
     368             : 
     369             :             // turns
     370             :             {
     371          26 :                 std::stringstream ss;
     372          26 :                 ss << "div { z-index: cos("
     373          26 :                    << angle / 360.0
     374          26 :                    << "turn); }";
     375          78 :                 csspp::position pos("test.css");
     376          26 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     377             : 
     378          52 :                 csspp::parser p(l);
     379             : 
     380          26 :                 csspp::node::pointer_t n(p.stylesheet());
     381             : 
     382          26 :                 csspp::compiler c;
     383          26 :                 c.set_root(n);
     384          26 :                 c.set_date_time_variables(csspp_test::get_now());
     385          26 :                 c.add_path(csspp_test::get_script_path());
     386          26 :                 c.add_path(csspp_test::get_version_script_path());
     387             : 
     388          26 :                 c.compile(false);
     389             : 
     390             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     391             : 
     392             :                 // to verify that the result is still an INTEGER we have to
     393             :                 // test the root node here
     394          26 :                 std::stringstream compiler_out;
     395          26 :                 compiler_out << *n;
     396          26 :                 VERIFY_TREES(compiler_out.str(),
     397             : 
     398             : "LIST\n"
     399             : + csspp_test::get_default_variables() +
     400             : "  COMPONENT_VALUE\n"
     401             : "    ARG\n"
     402             : "      IDENTIFIER \"div\"\n"
     403             : "    OPEN_CURLYBRACKET B:true\n"
     404             : "      DECLARATION \"z-index\"\n"
     405             : "        ARG\n"
     406             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(cos(angle * M_PI / 180.0), false) + "\n"
     407             : + csspp_test::get_close_comment(true)
     408             : 
     409             :                     );
     410             : 
     411          26 :                 std::stringstream assembler_out;
     412          26 :                 csspp::assembler a(assembler_out);
     413          26 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     414             : 
     415             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     416             : 
     417          26 :                 CATCH_REQUIRE(assembler_out.str() ==
     418             : 
     419             : std::string("div{z-index:") + csspp::decimal_number_to_string(cos(angle * M_PI / 180.0), true) + "}\n"
     420             : + csspp_test::get_close_comment()
     421             : 
     422             :                         );
     423             : 
     424          26 :                 CATCH_REQUIRE(c.get_root() == n);
     425          26 :             }
     426             :         }
     427             :     }
     428           3 :     CATCH_END_SECTION()
     429             : 
     430           3 :     CATCH_START_SECTION("sin(pi)")
     431             :     {
     432          66 :         for(int angle(-180); angle <= 180; angle += rand() % 12)
     433             :         {
     434             :             // unspecified (defaults to degrees)
     435             :             {
     436          65 :                 std::stringstream ss;
     437          65 :                 ss << "div { z-index: sin("
     438             :                    << angle
     439          65 :                    << "); }";
     440         195 :                 csspp::position pos("test.css");
     441          65 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     442             : 
     443         130 :                 csspp::parser p(l);
     444             : 
     445          65 :                 csspp::node::pointer_t n(p.stylesheet());
     446             : 
     447          65 :                 csspp::compiler c;
     448          65 :                 c.set_root(n);
     449          65 :                 c.set_date_time_variables(csspp_test::get_now());
     450          65 :                 c.add_path(csspp_test::get_script_path());
     451          65 :                 c.add_path(csspp_test::get_version_script_path());
     452             : 
     453          65 :                 c.compile(false);
     454             : 
     455             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     456             : 
     457             :                 // to verify that the result is still an INTEGER we have to
     458             :                 // test the root node here
     459          65 :                 std::stringstream compiler_out;
     460          65 :                 compiler_out << *n;
     461          65 :                 VERIFY_TREES(compiler_out.str(),
     462             : 
     463             : "LIST\n"
     464             : + csspp_test::get_default_variables() +
     465             : "  COMPONENT_VALUE\n"
     466             : "    ARG\n"
     467             : "      IDENTIFIER \"div\"\n"
     468             : "    OPEN_CURLYBRACKET B:true\n"
     469             : "      DECLARATION \"z-index\"\n"
     470             : "        ARG\n"
     471             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(sin(angle * M_PI / 180.0), false) + "\n"
     472             : + csspp_test::get_close_comment(true)
     473             : 
     474             :                     );
     475             : 
     476          65 :                 std::stringstream assembler_out;
     477          65 :                 csspp::assembler a(assembler_out);
     478          65 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     479             : 
     480             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     481             : 
     482          65 :                 CATCH_REQUIRE(assembler_out.str() ==
     483             : 
     484             : std::string("div{z-index:") + csspp::decimal_number_to_string(sin(angle * M_PI / 180.0), true) + "}\n"
     485             : + csspp_test::get_close_comment()
     486             : 
     487             :                         );
     488             : 
     489          65 :                 CATCH_REQUIRE(c.get_root() == n);
     490          65 :             }
     491             : 
     492             :             // degrees
     493             :             {
     494          65 :                 std::stringstream ss;
     495          65 :                 ss << "div { z-index: sin("
     496             :                    << angle
     497          65 :                    << "deg); }";
     498         195 :                 csspp::position pos("test.css");
     499          65 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     500             : 
     501         130 :                 csspp::parser p(l);
     502             : 
     503          65 :                 csspp::node::pointer_t n(p.stylesheet());
     504             : 
     505          65 :                 csspp::compiler c;
     506          65 :                 c.set_root(n);
     507          65 :                 c.set_date_time_variables(csspp_test::get_now());
     508          65 :                 c.add_path(csspp_test::get_script_path());
     509          65 :                 c.add_path(csspp_test::get_version_script_path());
     510             : 
     511          65 :                 c.compile(false);
     512             : 
     513             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     514             : 
     515             :                 // to verify that the result is still an INTEGER we have to
     516             :                 // test the root node here
     517          65 :                 std::stringstream compiler_out;
     518          65 :                 compiler_out << *n;
     519          65 :                 VERIFY_TREES(compiler_out.str(),
     520             : 
     521             : "LIST\n"
     522             : + csspp_test::get_default_variables() +
     523             : "  COMPONENT_VALUE\n"
     524             : "    ARG\n"
     525             : "      IDENTIFIER \"div\"\n"
     526             : "    OPEN_CURLYBRACKET B:true\n"
     527             : "      DECLARATION \"z-index\"\n"
     528             : "        ARG\n"
     529             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(sin(angle * M_PI / 180.0), false) + "\n"
     530             : + csspp_test::get_close_comment(true)
     531             : 
     532             :                     );
     533             : 
     534          65 :                 std::stringstream assembler_out;
     535          65 :                 csspp::assembler a(assembler_out);
     536          65 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     537             : 
     538             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     539             : 
     540          65 :                 CATCH_REQUIRE(assembler_out.str() ==
     541             : 
     542             : std::string("div{z-index:") + csspp::decimal_number_to_string(sin(angle * M_PI / 180.0), true) + "}\n"
     543             : + csspp_test::get_close_comment()
     544             : 
     545             :                         );
     546             : 
     547          65 :                 CATCH_REQUIRE(c.get_root() == n);
     548          65 :             }
     549             : 
     550             :             // radians
     551             :             {
     552          65 :                 std::stringstream ss;
     553          65 :                 ss << "div { z-index: sin("
     554          65 :                    << angle * M_PI / 180.0
     555          65 :                    << "rad); }";
     556         195 :                 csspp::position pos("test.css");
     557          65 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     558             : 
     559         130 :                 csspp::parser p(l);
     560             : 
     561          65 :                 csspp::node::pointer_t n(p.stylesheet());
     562             : 
     563          65 :                 csspp::compiler c;
     564          65 :                 c.set_root(n);
     565          65 :                 c.set_date_time_variables(csspp_test::get_now());
     566          65 :                 c.add_path(csspp_test::get_script_path());
     567          65 :                 c.add_path(csspp_test::get_version_script_path());
     568             : 
     569          65 :                 c.compile(false);
     570             : 
     571             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     572             : 
     573             :                 // to verify that the result is still an INTEGER we have to
     574             :                 // test the root node here
     575          65 :                 std::stringstream compiler_out;
     576          65 :                 compiler_out << *n;
     577          65 :                 VERIFY_TREES(compiler_out.str(),
     578             : 
     579             : "LIST\n"
     580             : + csspp_test::get_default_variables() +
     581             : "  COMPONENT_VALUE\n"
     582             : "    ARG\n"
     583             : "      IDENTIFIER \"div\"\n"
     584             : "    OPEN_CURLYBRACKET B:true\n"
     585             : "      DECLARATION \"z-index\"\n"
     586             : "        ARG\n"
     587             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(sin(angle * M_PI / 180.0), false) + "\n"
     588             : + csspp_test::get_close_comment(true)
     589             : 
     590             :                     );
     591             : 
     592          65 :                 std::stringstream assembler_out;
     593          65 :                 csspp::assembler a(assembler_out);
     594          65 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     595             : 
     596             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     597             : 
     598          65 :                 CATCH_REQUIRE(assembler_out.str() ==
     599             : 
     600             : std::string("div{z-index:") + csspp::decimal_number_to_string(sin(angle * M_PI / 180.0), true) + "}\n"
     601             : + csspp_test::get_close_comment()
     602             : 
     603             :                         );
     604             : 
     605          65 :                 CATCH_REQUIRE(c.get_root() == n);
     606          65 :             }
     607             : 
     608             :             // gradians
     609             :             {
     610          65 :                 std::stringstream ss;
     611          65 :                 ss << "div { z-index: sin("
     612          65 :                    << angle * 200 / 180.0
     613          65 :                    << "grad); }";
     614         195 :                 csspp::position pos("test.css");
     615          65 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     616             : 
     617         130 :                 csspp::parser p(l);
     618             : 
     619          65 :                 csspp::node::pointer_t n(p.stylesheet());
     620             : 
     621          65 :                 csspp::compiler c;
     622          65 :                 c.set_root(n);
     623          65 :                 c.set_date_time_variables(csspp_test::get_now());
     624          65 :                 c.add_path(csspp_test::get_script_path());
     625          65 :                 c.add_path(csspp_test::get_version_script_path());
     626             : 
     627          65 :                 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          65 :                 std::stringstream compiler_out;
     634          65 :                 compiler_out << *n;
     635          65 :                 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 \"z-index\"\n"
     644             : "        ARG\n"
     645             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(sin(angle * M_PI / 180.0), false) + "\n"
     646             : + csspp_test::get_close_comment(true)
     647             : 
     648             :                     );
     649             : 
     650          65 :                 std::stringstream assembler_out;
     651          65 :                 csspp::assembler a(assembler_out);
     652          65 :                 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          65 :                 CATCH_REQUIRE(assembler_out.str() ==
     657             : 
     658             : std::string("div{z-index:") + csspp::decimal_number_to_string(sin(angle * M_PI / 180.0), true) + "}\n"
     659             : + csspp_test::get_close_comment()
     660             : 
     661             :                         );
     662             : 
     663          65 :                 CATCH_REQUIRE(c.get_root() == n);
     664          65 :             }
     665             : 
     666             :             // turns
     667             :             {
     668          65 :                 std::stringstream ss;
     669          65 :                 ss << "div { z-index: sin("
     670          65 :                    << angle / 360.0
     671          65 :                    << "turn); }";
     672         195 :                 csspp::position pos("test.css");
     673          65 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     674             : 
     675         130 :                 csspp::parser p(l);
     676             : 
     677          65 :                 csspp::node::pointer_t n(p.stylesheet());
     678             : 
     679          65 :                 csspp::compiler c;
     680          65 :                 c.set_root(n);
     681          65 :                 c.set_date_time_variables(csspp_test::get_now());
     682          65 :                 c.add_path(csspp_test::get_script_path());
     683          65 :                 c.add_path(csspp_test::get_version_script_path());
     684             : 
     685          65 :                 c.compile(false);
     686             : 
     687             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     688             : 
     689             :                 // to verify that the result is still an INTEGER we have to
     690             :                 // test the root node here
     691          65 :                 std::stringstream compiler_out;
     692          65 :                 compiler_out << *n;
     693          65 :                 VERIFY_TREES(compiler_out.str(),
     694             : 
     695             : "LIST\n"
     696             : + csspp_test::get_default_variables() +
     697             : "  COMPONENT_VALUE\n"
     698             : "    ARG\n"
     699             : "      IDENTIFIER \"div\"\n"
     700             : "    OPEN_CURLYBRACKET B:true\n"
     701             : "      DECLARATION \"z-index\"\n"
     702             : "        ARG\n"
     703             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(sin(angle * M_PI / 180.0), false) + "\n"
     704             : + csspp_test::get_close_comment(true)
     705             : 
     706             :                     );
     707             : 
     708          65 :                 std::stringstream assembler_out;
     709          65 :                 csspp::assembler a(assembler_out);
     710          65 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     711             : 
     712             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     713             : 
     714          65 :                 CATCH_REQUIRE(assembler_out.str() ==
     715             : 
     716             : std::string("div{z-index:") + csspp::decimal_number_to_string(sin(angle * M_PI / 180.0), true) + "}\n"
     717             : + csspp_test::get_close_comment()
     718             : 
     719             :                         );
     720             : 
     721          65 :                 CATCH_REQUIRE(c.get_root() == n);
     722          65 :             }
     723             :         }
     724             :     }
     725           3 :     CATCH_END_SECTION()
     726             : 
     727           3 :     CATCH_START_SECTION("tan(pi)")
     728             :     {
     729          68 :         for(int angle(-180); angle <= 180; angle += rand() % 12)
     730             :         {
     731             : 
     732             :             // unspecified (defaults to degrees)
     733             :             {
     734          67 :                 std::stringstream ss;
     735          67 :                 ss << "div { z-index: tan("
     736             :                    << angle
     737          67 :                    << "); }";
     738         201 :                 csspp::position pos("test.css");
     739          67 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     740             : 
     741         134 :                 csspp::parser p(l);
     742             : 
     743          67 :                 csspp::node::pointer_t n(p.stylesheet());
     744             : 
     745          67 :                 csspp::compiler c;
     746          67 :                 c.set_root(n);
     747          67 :                 c.set_date_time_variables(csspp_test::get_now());
     748          67 :                 c.add_path(csspp_test::get_script_path());
     749          67 :                 c.add_path(csspp_test::get_version_script_path());
     750             : 
     751          67 :                 c.compile(false);
     752             : 
     753             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     754             : 
     755             :                 // to verify that the result is still an INTEGER we have to
     756             :                 // test the root node here
     757          67 :                 std::stringstream compiler_out;
     758          67 :                 compiler_out << *n;
     759          67 :                 VERIFY_TREES(compiler_out.str(),
     760             : 
     761             : "LIST\n"
     762             : + csspp_test::get_default_variables() +
     763             : "  COMPONENT_VALUE\n"
     764             : "    ARG\n"
     765             : "      IDENTIFIER \"div\"\n"
     766             : "    OPEN_CURLYBRACKET B:true\n"
     767             : "      DECLARATION \"z-index\"\n"
     768             : "        ARG\n"
     769             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(tan(angle * M_PI / 180.0), false) + "\n"
     770             : + csspp_test::get_close_comment(true)
     771             : 
     772             :                     );
     773             : 
     774          67 :                 std::stringstream assembler_out;
     775          67 :                 csspp::assembler a(assembler_out);
     776          67 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     777             : 
     778             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     779             : 
     780          67 :                 CATCH_REQUIRE(assembler_out.str() ==
     781             : 
     782             : std::string("div{z-index:") + csspp::decimal_number_to_string(tan(angle * M_PI / 180.0), true) + "}\n"
     783             : + csspp_test::get_close_comment()
     784             : 
     785             :                         );
     786             : 
     787          67 :                 CATCH_REQUIRE(c.get_root() == n);
     788          67 :             }
     789             : 
     790             :             // degrees
     791             :             {
     792          67 :                 std::stringstream ss;
     793          67 :                 ss << "div { z-index: tan("
     794             :                    << angle
     795          67 :                    << "deg); }";
     796         201 :                 csspp::position pos("test.css");
     797          67 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     798             : 
     799         134 :                 csspp::parser p(l);
     800             : 
     801          67 :                 csspp::node::pointer_t n(p.stylesheet());
     802             : 
     803          67 :                 csspp::compiler c;
     804          67 :                 c.set_root(n);
     805          67 :                 c.set_date_time_variables(csspp_test::get_now());
     806          67 :                 c.add_path(csspp_test::get_script_path());
     807          67 :                 c.add_path(csspp_test::get_version_script_path());
     808             : 
     809          67 :                 c.compile(false);
     810             : 
     811             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     812             : 
     813             :                 // to verify that the result is still an INTEGER we have to
     814             :                 // test the root node here
     815          67 :                 std::stringstream compiler_out;
     816          67 :                 compiler_out << *n;
     817          67 :                 VERIFY_TREES(compiler_out.str(),
     818             : 
     819             : "LIST\n"
     820             : + csspp_test::get_default_variables() +
     821             : "  COMPONENT_VALUE\n"
     822             : "    ARG\n"
     823             : "      IDENTIFIER \"div\"\n"
     824             : "    OPEN_CURLYBRACKET B:true\n"
     825             : "      DECLARATION \"z-index\"\n"
     826             : "        ARG\n"
     827             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(tan(angle * M_PI / 180.0), false) + "\n"
     828             : + csspp_test::get_close_comment(true)
     829             : 
     830             :                     );
     831             : 
     832          67 :                 std::stringstream assembler_out;
     833          67 :                 csspp::assembler a(assembler_out);
     834          67 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     835             : 
     836             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     837             : 
     838          67 :                 CATCH_REQUIRE(assembler_out.str() ==
     839             : 
     840             : std::string("div{z-index:") + csspp::decimal_number_to_string(tan(angle * M_PI / 180.0), true) + "}\n"
     841             : + csspp_test::get_close_comment()
     842             : 
     843             :                         );
     844             : 
     845          67 :                 CATCH_REQUIRE(c.get_root() == n);
     846          67 :             }
     847             : 
     848             :             // radians
     849             :             {
     850          67 :                 std::stringstream rad;
     851          67 :                 rad << angle * M_PI / 180.0;
     852          67 :                 std::stringstream ss;
     853             :                 ss << "div { z-index: tan("
     854         134 :                    << rad.str()
     855         134 :                    << "rad); }";
     856         201 :                 csspp::position pos("test.css");
     857          67 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     858             : 
     859         134 :                 csspp::parser p(l);
     860             : 
     861          67 :                 csspp::node::pointer_t n(p.stylesheet());
     862             : 
     863          67 :                 csspp::compiler c;
     864          67 :                 c.set_root(n);
     865          67 :                 c.set_date_time_variables(csspp_test::get_now());
     866          67 :                 c.add_path(csspp_test::get_script_path());
     867          67 :                 c.add_path(csspp_test::get_version_script_path());
     868             : 
     869          67 :                 c.compile(false);
     870             : 
     871          67 :                 std::string const r(rad.str());
     872          67 :                 csspp::decimal_number_t rd(atof(r.c_str()));
     873             : 
     874             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     875             : 
     876             :                 // to verify that the result is still an INTEGER we have to
     877             :                 // test the root node here
     878          67 :                 std::stringstream compiler_out;
     879          67 :                 compiler_out << *n;
     880          67 :                 VERIFY_TREES(compiler_out.str(),
     881             : 
     882             : "LIST\n"
     883             : + csspp_test::get_default_variables() +
     884             : "  COMPONENT_VALUE\n"
     885             : "    ARG\n"
     886             : "      IDENTIFIER \"div\"\n"
     887             : "    OPEN_CURLYBRACKET B:true\n"
     888             : "      DECLARATION \"z-index\"\n"
     889             : "        ARG\n"
     890             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(tan(rd), false) + "\n"
     891             : + csspp_test::get_close_comment(true)
     892             : 
     893             :                     );
     894             : 
     895          67 :                 std::stringstream assembler_out;
     896          67 :                 csspp::assembler a(assembler_out);
     897          67 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     898             : 
     899             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     900             : 
     901          67 :                 CATCH_REQUIRE(assembler_out.str() ==
     902             : 
     903             : std::string("div{z-index:") + csspp::decimal_number_to_string(tan(rd), true) + "}\n"
     904             : + csspp_test::get_close_comment()
     905             : 
     906             :                         );
     907             : 
     908          67 :                 CATCH_REQUIRE(c.get_root() == n);
     909          67 :             }
     910             : 
     911             :             // gradians
     912             :             {
     913          67 :                 std::stringstream grad;
     914          67 :                 grad << angle * 200.0 / 180.0;
     915          67 :                 std::stringstream ss;
     916             :                 ss << "div { z-index: tan("
     917         134 :                    << grad.str()
     918         134 :                    << "grad); }";
     919         201 :                 csspp::position pos("test.css");
     920          67 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     921             : 
     922         134 :                 csspp::parser p(l);
     923             : 
     924          67 :                 csspp::node::pointer_t n(p.stylesheet());
     925             : 
     926          67 :                 csspp::compiler c;
     927          67 :                 c.set_root(n);
     928          67 :                 c.set_date_time_variables(csspp_test::get_now());
     929          67 :                 c.add_path(csspp_test::get_script_path());
     930          67 :                 c.add_path(csspp_test::get_version_script_path());
     931             : 
     932          67 :                 c.compile(false);
     933             : 
     934          67 :                 std::string const g(grad.str());
     935          67 :                 csspp::decimal_number_t gd(atof(g.c_str()));
     936             : 
     937             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     938             : 
     939             :                 // to verify that the result is still an INTEGER we have to
     940             :                 // test the root node here
     941          67 :                 std::stringstream compiler_out;
     942          67 :                 compiler_out << *n;
     943          67 :                 VERIFY_TREES(compiler_out.str(),
     944             : 
     945             : "LIST\n"
     946             : + csspp_test::get_default_variables() +
     947             : "  COMPONENT_VALUE\n"
     948             : "    ARG\n"
     949             : "      IDENTIFIER \"div\"\n"
     950             : "    OPEN_CURLYBRACKET B:true\n"
     951             : "      DECLARATION \"z-index\"\n"
     952             : "        ARG\n"
     953             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(tan(gd * M_PI / 200.0), false) + "\n"
     954             : + csspp_test::get_close_comment(true)
     955             : 
     956             :                     );
     957             : 
     958          67 :                 std::stringstream assembler_out;
     959          67 :                 csspp::assembler a(assembler_out);
     960          67 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
     961             : 
     962             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     963             : 
     964          67 :                 CATCH_REQUIRE(assembler_out.str() ==
     965             : 
     966             : std::string("div{z-index:") + csspp::decimal_number_to_string(tan(gd * M_PI / 200.0), true) + "}\n"
     967             : + csspp_test::get_close_comment()
     968             : 
     969             :                         );
     970             : 
     971          67 :                 CATCH_REQUIRE(c.get_root() == n);
     972          67 :             }
     973             : 
     974             :             // turns
     975             :             {
     976          67 :                 std::stringstream turn;
     977          67 :                 turn << angle / 360.0;
     978          67 :                 std::stringstream ss;
     979             :                 ss << "div { z-index: tan("
     980         134 :                    << turn.str()
     981         134 :                    << "turn); }";
     982         201 :                 csspp::position pos("test.css");
     983          67 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     984             : 
     985         134 :                 csspp::parser p(l);
     986             : 
     987          67 :                 csspp::node::pointer_t n(p.stylesheet());
     988             : 
     989          67 :                 csspp::compiler c;
     990          67 :                 c.set_root(n);
     991          67 :                 c.set_date_time_variables(csspp_test::get_now());
     992          67 :                 c.add_path(csspp_test::get_script_path());
     993          67 :                 c.add_path(csspp_test::get_version_script_path());
     994             : 
     995          67 :                 c.compile(false);
     996             : 
     997          67 :                 std::string const t(turn.str());
     998          67 :                 csspp::decimal_number_t tn(atof(t.c_str()));
     999             : 
    1000             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1001             : 
    1002             :                 // to verify that the result is still an INTEGER we have to
    1003             :                 // test the root node here
    1004          67 :                 std::stringstream compiler_out;
    1005          67 :                 compiler_out << *n;
    1006          67 :                 VERIFY_TREES(compiler_out.str(),
    1007             : 
    1008             : "LIST\n"
    1009             : + csspp_test::get_default_variables() +
    1010             : "  COMPONENT_VALUE\n"
    1011             : "    ARG\n"
    1012             : "      IDENTIFIER \"div\"\n"
    1013             : "    OPEN_CURLYBRACKET B:true\n"
    1014             : "      DECLARATION \"z-index\"\n"
    1015             : "        ARG\n"
    1016             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(tan(tn * M_PI * 2.0), false) + "\n"
    1017             : + csspp_test::get_close_comment(true)
    1018             : 
    1019             :                     );
    1020             : 
    1021          67 :                 std::stringstream assembler_out;
    1022          67 :                 csspp::assembler a(assembler_out);
    1023          67 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    1024             : 
    1025             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1026             : 
    1027          67 :                 CATCH_REQUIRE(assembler_out.str() ==
    1028             : 
    1029             : std::string("div{z-index:") + csspp::decimal_number_to_string(tan(tn * M_PI * 2.0), true) + "}\n"
    1030             : + csspp_test::get_close_comment()
    1031             : 
    1032             :                         );
    1033             : 
    1034          67 :                 CATCH_REQUIRE(c.get_root() == n);
    1035          67 :             }
    1036             : 
    1037             :         }
    1038             :     }
    1039           3 :     CATCH_END_SECTION()
    1040             : 
    1041             :     // no error left over
    1042           3 :     VERIFY_ERRORS("");
    1043           3 : }
    1044             : 
    1045           3 : CATCH_TEST_CASE("Expression acos()/asin()/atan()", "[expression] [internal-functions] [acos] [asin] [atan]")
    1046             : {
    1047           3 :     CATCH_START_SECTION("acos(ratio)")
    1048             :     {
    1049          28 :         for(int angle(-180); angle <= 180; angle += rand() % 25 + 1)
    1050             :         {
    1051          27 :             std::stringstream ss;
    1052          27 :             ss << "div { z-index: acos("
    1053          27 :                << cos(angle * M_PI / 180.0)
    1054          27 :                << "rad); }";
    1055          81 :             csspp::position pos("test.css");
    1056          27 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1057             : 
    1058          54 :             csspp::parser p(l);
    1059             : 
    1060          27 :             csspp::node::pointer_t n(p.stylesheet());
    1061             : 
    1062          27 :             csspp::compiler c;
    1063          27 :             c.set_root(n);
    1064          27 :             c.set_date_time_variables(csspp_test::get_now());
    1065          27 :             c.add_path(csspp_test::get_script_path());
    1066          27 :             c.add_path(csspp_test::get_version_script_path());
    1067             : 
    1068          27 :             c.compile(false);
    1069             : 
    1070             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1071             : 
    1072             :             // to verify that the result is still an INTEGER we have to
    1073             :             // test the root node here
    1074          27 :             std::stringstream compiler_out;
    1075          27 :             compiler_out << *n;
    1076          27 :             VERIFY_TREES(compiler_out.str(),
    1077             : 
    1078             : "LIST\n"
    1079             : + csspp_test::get_default_variables() +
    1080             : "  COMPONENT_VALUE\n"
    1081             : "    ARG\n"
    1082             : "      IDENTIFIER \"div\"\n"
    1083             : "    OPEN_CURLYBRACKET B:true\n"
    1084             : "      DECLARATION \"z-index\"\n"
    1085             : "        ARG\n"
    1086             : "          DECIMAL_NUMBER \"rad\" D:" + csspp::decimal_number_to_string(labs(angle) * M_PI / 180.0, false) + "\n"
    1087             : + csspp_test::get_close_comment(true)
    1088             : 
    1089             :                 );
    1090             : 
    1091          27 :             std::stringstream assembler_out;
    1092          27 :             csspp::assembler a(assembler_out);
    1093          27 :             a.output(n, csspp::output_mode_t::COMPRESSED);
    1094             : 
    1095             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1096             : 
    1097          27 :             CATCH_REQUIRE(assembler_out.str() ==
    1098             : 
    1099             : std::string("div{z-index:") + csspp::decimal_number_to_string(labs(angle) * M_PI / 180.0, true) + "rad}\n"
    1100             : + csspp_test::get_close_comment()
    1101             : 
    1102             :                     );
    1103             : 
    1104          27 :             CATCH_REQUIRE(c.get_root() == n);
    1105          27 :         }
    1106             : 
    1107             :         // another test with an integer
    1108             :         {
    1109           1 :             std::stringstream ss;
    1110           1 :             ss << "div { z-index: acos(2); }";
    1111           3 :             csspp::position pos("test.css");
    1112           1 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1113             : 
    1114           2 :             csspp::parser p(l);
    1115             : 
    1116           1 :             csspp::node::pointer_t n(p.stylesheet());
    1117             : 
    1118           1 :             csspp::compiler c;
    1119           1 :             c.set_root(n);
    1120           1 :             c.set_date_time_variables(csspp_test::get_now());
    1121           1 :             c.add_path(csspp_test::get_script_path());
    1122           1 :             c.add_path(csspp_test::get_version_script_path());
    1123             : 
    1124           1 :             c.compile(false);
    1125             : 
    1126             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1127             : 
    1128             :             // to verify that the result is still an INTEGER we have to
    1129             :             // test the root node here
    1130           1 :             std::stringstream compiler_out;
    1131           1 :             compiler_out << *n;
    1132           1 :             VERIFY_TREES(compiler_out.str(),
    1133             : 
    1134             : "LIST\n"
    1135             : + csspp_test::get_default_variables() +
    1136             : "  COMPONENT_VALUE\n"
    1137             : "    ARG\n"
    1138             : "      IDENTIFIER \"div\"\n"
    1139             : "    OPEN_CURLYBRACKET B:true\n"
    1140             : "      DECLARATION \"z-index\"\n"
    1141             : "        ARG\n"
    1142             : "          DECIMAL_NUMBER \"rad\" D:" + csspp::decimal_number_to_string(acos(2.0), false) + "\n"
    1143             : + csspp_test::get_close_comment(true)
    1144             : 
    1145             :                 );
    1146             : 
    1147           1 :             std::stringstream assembler_out;
    1148           1 :             csspp::assembler a(assembler_out);
    1149           1 :             a.output(n, csspp::output_mode_t::COMPRESSED);
    1150             : 
    1151             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1152             : 
    1153           1 :             CATCH_REQUIRE(assembler_out.str() ==
    1154             : 
    1155             : std::string("div{z-index:") + csspp::decimal_number_to_string(acos(2), true) + "rad}\n"
    1156             : + csspp_test::get_close_comment()
    1157             : 
    1158             :                     );
    1159             : 
    1160           1 :             CATCH_REQUIRE(c.get_root() == n);
    1161           1 :         }
    1162             :     }
    1163           3 :     CATCH_END_SECTION()
    1164             : 
    1165           3 :     CATCH_START_SECTION("asin(pi)")
    1166             :     {
    1167          62 :         for(int angle(-180); angle <= 180; angle += rand() % 12)
    1168             :         {
    1169          61 :             std::stringstream ss;
    1170          61 :             ss << "div { z-index: asin("
    1171          61 :                << sin(angle * M_PI / 180.0)
    1172          61 :                << "rad); }";
    1173         183 :             csspp::position pos("test.css");
    1174          61 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1175             : 
    1176         122 :             csspp::parser p(l);
    1177             : 
    1178          61 :             csspp::node::pointer_t n(p.stylesheet());
    1179             : 
    1180          61 :             csspp::compiler c;
    1181          61 :             c.set_root(n);
    1182          61 :             c.set_date_time_variables(csspp_test::get_now());
    1183          61 :             c.add_path(csspp_test::get_script_path());
    1184          61 :             c.add_path(csspp_test::get_version_script_path());
    1185             : 
    1186          61 :             c.compile(false);
    1187             : 
    1188             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1189             : 
    1190             :             // to verify that the result is still an INTEGER we have to
    1191             :             // test the root node here
    1192          61 :             std::stringstream compiler_out;
    1193          61 :             compiler_out << *n;
    1194          61 :             VERIFY_TREES(compiler_out.str(),
    1195             : 
    1196             : "LIST\n"
    1197             : + csspp_test::get_default_variables() +
    1198             : "  COMPONENT_VALUE\n"
    1199             : "    ARG\n"
    1200             : "      IDENTIFIER \"div\"\n"
    1201             : "    OPEN_CURLYBRACKET B:true\n"
    1202             : "      DECLARATION \"z-index\"\n"
    1203             : "        ARG\n"
    1204             : "          DECIMAL_NUMBER \"rad\" D:" + csspp::decimal_number_to_string(asin(sin(angle * M_PI / 180.0)), false) + "\n"
    1205             : + csspp_test::get_close_comment(true)
    1206             : 
    1207             :                 );
    1208             : 
    1209          61 :             std::stringstream assembler_out;
    1210          61 :             csspp::assembler a(assembler_out);
    1211          61 :             a.output(n, csspp::output_mode_t::COMPRESSED);
    1212             : 
    1213             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1214             : 
    1215          61 :             CATCH_REQUIRE(assembler_out.str() ==
    1216             : 
    1217             : std::string("div{z-index:") + csspp::decimal_number_to_string(asin(sin(angle * M_PI / 180.0)), true) + "rad}\n"
    1218             : + csspp_test::get_close_comment()
    1219             : 
    1220             :                     );
    1221             : 
    1222          61 :             CATCH_REQUIRE(c.get_root() == n);
    1223          61 :         }
    1224             : 
    1225             :         // another test with an integer
    1226             :         {
    1227           1 :             std::stringstream ss;
    1228           1 :             ss << "div { z-index: asin(2); }";
    1229           3 :             csspp::position pos("test.css");
    1230           1 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1231             : 
    1232           2 :             csspp::parser p(l);
    1233             : 
    1234           1 :             csspp::node::pointer_t n(p.stylesheet());
    1235             : 
    1236           1 :             csspp::compiler c;
    1237           1 :             c.set_root(n);
    1238           1 :             c.set_date_time_variables(csspp_test::get_now());
    1239           1 :             c.add_path(csspp_test::get_script_path());
    1240           1 :             c.add_path(csspp_test::get_version_script_path());
    1241             : 
    1242           1 :             c.compile(false);
    1243             : 
    1244             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1245             : 
    1246             :             // to verify that the result is still an INTEGER we have to
    1247             :             // test the root node here
    1248           1 :             std::stringstream compiler_out;
    1249           1 :             compiler_out << *n;
    1250           1 :             VERIFY_TREES(compiler_out.str(),
    1251             : 
    1252             : "LIST\n"
    1253             : + csspp_test::get_default_variables() +
    1254             : "  COMPONENT_VALUE\n"
    1255             : "    ARG\n"
    1256             : "      IDENTIFIER \"div\"\n"
    1257             : "    OPEN_CURLYBRACKET B:true\n"
    1258             : "      DECLARATION \"z-index\"\n"
    1259             : "        ARG\n"
    1260             : "          DECIMAL_NUMBER \"rad\" D:" + csspp::decimal_number_to_string(asin(2.0), false) + "\n"
    1261             : + csspp_test::get_close_comment(true)
    1262             : 
    1263             :                 );
    1264             : 
    1265           1 :             std::stringstream assembler_out;
    1266           1 :             csspp::assembler a(assembler_out);
    1267           1 :             a.output(n, csspp::output_mode_t::COMPRESSED);
    1268             : 
    1269             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1270             : 
    1271           1 :             CATCH_REQUIRE(assembler_out.str() ==
    1272             : 
    1273             : std::string("div{z-index:") + csspp::decimal_number_to_string(asin(2), true) + "rad}\n"
    1274             : + csspp_test::get_close_comment()
    1275             : 
    1276             :                     );
    1277             : 
    1278           1 :             CATCH_REQUIRE(c.get_root() == n);
    1279           1 :         }
    1280             :     }
    1281           3 :     CATCH_END_SECTION()
    1282             : 
    1283           3 :     CATCH_START_SECTION("atan(pi)")
    1284             :     {
    1285          69 :         for(int angle(-180); angle <= 180; angle += rand() % 12)
    1286             :         {
    1287          68 :             std::stringstream ss;
    1288          68 :             ss << "div { z-index: atan("
    1289          68 :                << tan(angle * M_PI / 180.0)
    1290          68 :                << "); }";
    1291         204 :             csspp::position pos("test.css");
    1292          68 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1293             : 
    1294         136 :             csspp::parser p(l);
    1295             : 
    1296          68 :             csspp::node::pointer_t n(p.stylesheet());
    1297             : 
    1298          68 :             csspp::compiler c;
    1299          68 :             c.set_root(n);
    1300          68 :             c.set_date_time_variables(csspp_test::get_now());
    1301          68 :             c.add_path(csspp_test::get_script_path());
    1302          68 :             c.add_path(csspp_test::get_version_script_path());
    1303             : 
    1304          68 :             c.compile(false);
    1305             : 
    1306             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1307             : 
    1308             :             // to verify that the result is still an INTEGER we have to
    1309             :             // test the root node here
    1310          68 :             std::stringstream compiler_out;
    1311          68 :             compiler_out << *n;
    1312          68 :             VERIFY_TREES(compiler_out.str(),
    1313             : 
    1314             : "LIST\n"
    1315             : + csspp_test::get_default_variables() +
    1316             : "  COMPONENT_VALUE\n"
    1317             : "    ARG\n"
    1318             : "      IDENTIFIER \"div\"\n"
    1319             : "    OPEN_CURLYBRACKET B:true\n"
    1320             : "      DECLARATION \"z-index\"\n"
    1321             : "        ARG\n"
    1322             : "          DECIMAL_NUMBER \"rad\" D:" + csspp::decimal_number_to_string(atan(tan(angle * M_PI / 180.0)), false) + "\n"
    1323             : + csspp_test::get_close_comment(true)
    1324             : 
    1325             :                 );
    1326             : 
    1327          68 :             std::stringstream assembler_out;
    1328          68 :             csspp::assembler a(assembler_out);
    1329          68 :             a.output(n, csspp::output_mode_t::COMPRESSED);
    1330             : 
    1331             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1332             : 
    1333          68 :             CATCH_REQUIRE(assembler_out.str() ==
    1334             : 
    1335             : std::string("div{z-index:") + csspp::decimal_number_to_string(atan(tan(angle * M_PI / 180.0)), true) + "rad}\n"
    1336             : + csspp_test::get_close_comment()
    1337             : 
    1338             :                     );
    1339             : 
    1340          68 :             CATCH_REQUIRE(c.get_root() == n);
    1341          68 :         }
    1342             : 
    1343             :         // another test with an integer
    1344             :         {
    1345           1 :             std::stringstream ss;
    1346           1 :             ss << "div { z-index: atan(2); }";
    1347           3 :             csspp::position pos("test.css");
    1348           1 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1349             : 
    1350           2 :             csspp::parser p(l);
    1351             : 
    1352           1 :             csspp::node::pointer_t n(p.stylesheet());
    1353             : 
    1354           1 :             csspp::compiler c;
    1355           1 :             c.set_root(n);
    1356           1 :             c.set_date_time_variables(csspp_test::get_now());
    1357           1 :             c.add_path(csspp_test::get_script_path());
    1358           1 :             c.add_path(csspp_test::get_version_script_path());
    1359             : 
    1360           1 :             c.compile(false);
    1361             : 
    1362             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1363             : 
    1364             :             // to verify that the result is still an INTEGER we have to
    1365             :             // test the root node here
    1366           1 :             std::stringstream compiler_out;
    1367           1 :             compiler_out << *n;
    1368           1 :             VERIFY_TREES(compiler_out.str(),
    1369             : 
    1370             : "LIST\n"
    1371             : + csspp_test::get_default_variables() +
    1372             : "  COMPONENT_VALUE\n"
    1373             : "    ARG\n"
    1374             : "      IDENTIFIER \"div\"\n"
    1375             : "    OPEN_CURLYBRACKET B:true\n"
    1376             : "      DECLARATION \"z-index\"\n"
    1377             : "        ARG\n"
    1378             : "          DECIMAL_NUMBER \"rad\" D:" + csspp::decimal_number_to_string(atan(2.0), false) + "\n"
    1379             : + csspp_test::get_close_comment(true)
    1380             : 
    1381             :                 );
    1382             : 
    1383           1 :             std::stringstream assembler_out;
    1384           1 :             csspp::assembler a(assembler_out);
    1385           1 :             a.output(n, csspp::output_mode_t::COMPRESSED);
    1386             : 
    1387             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1388             : 
    1389           1 :             CATCH_REQUIRE(assembler_out.str() ==
    1390             : 
    1391             : std::string("div{z-index:") + csspp::decimal_number_to_string(atan(2), true) + "rad}\n"
    1392             : + csspp_test::get_close_comment()
    1393             : 
    1394             :                     );
    1395             : 
    1396           1 :             CATCH_REQUIRE(c.get_root() == n);
    1397           1 :         }
    1398             :     }
    1399           3 :     CATCH_END_SECTION()
    1400             : 
    1401             :     // no error left over
    1402           3 :     VERIFY_ERRORS("");
    1403           3 : }
    1404             : 
    1405           7 : CATCH_TEST_CASE("Expression abs()/ceil()/floor()/round()/log()/sign()/sqrt()", "[expression] [internal-functions] [abs] [ceil] [floor] [round]")
    1406             : {
    1407           7 :     CATCH_START_SECTION("abs(number)")
    1408             :     {
    1409         159 :         for(int number(-10000); number <= 10000; number += rand() % 250 + 1)
    1410             :         {
    1411             :             // abs(int)
    1412             :             {
    1413         316 :                 std::string const dimension(rand() & 1 ? "cm" : "mm");
    1414         158 :                 std::stringstream ss;
    1415         158 :                 ss << "div { width: abs("
    1416             :                    << number
    1417             :                    << dimension
    1418         158 :                    << "); }";
    1419         474 :                 csspp::position pos("test.css");
    1420         158 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1421             : 
    1422         316 :                 csspp::parser p(l);
    1423             : 
    1424         158 :                 csspp::node::pointer_t n(p.stylesheet());
    1425             : 
    1426         158 :                 csspp::compiler c;
    1427         158 :                 c.set_root(n);
    1428         158 :                 c.set_date_time_variables(csspp_test::get_now());
    1429         158 :                 c.add_path(csspp_test::get_script_path());
    1430         158 :                 c.add_path(csspp_test::get_version_script_path());
    1431             : 
    1432         158 :                 c.compile(false);
    1433             : 
    1434             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1435             : 
    1436             :                 // to verify that the result is still an INTEGER we have to
    1437             :                 // test the root node here
    1438         158 :                 std::stringstream compiler_out;
    1439         158 :                 compiler_out << *n;
    1440         158 :                 VERIFY_TREES(compiler_out.str(),
    1441             : 
    1442             : "LIST\n"
    1443             : + csspp_test::get_default_variables() +
    1444             : "  COMPONENT_VALUE\n"
    1445             : "    ARG\n"
    1446             : "      IDENTIFIER \"div\"\n"
    1447             : "    OPEN_CURLYBRACKET B:true\n"
    1448             : "      DECLARATION \"width\"\n"
    1449             : "        ARG\n"
    1450             : "          INTEGER \"" + dimension + "\" I:" + std::to_string(labs(number)) + "\n"
    1451             : + csspp_test::get_close_comment(true)
    1452             : 
    1453             :                     );
    1454             : 
    1455         158 :                 std::stringstream assembler_out;
    1456         158 :                 csspp::assembler a(assembler_out);
    1457         158 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    1458             : 
    1459             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1460             : 
    1461         158 :                 CATCH_REQUIRE(assembler_out.str() ==
    1462             : 
    1463             : std::string("div{width:") + std::to_string(labs(number)) + dimension + "}\n"
    1464             : + csspp_test::get_close_comment()
    1465             : 
    1466             :                         );
    1467             : 
    1468         158 :                 CATCH_REQUIRE(c.get_root() == n);
    1469         158 :             }
    1470             : 
    1471             :             // abs(float)
    1472             :             {
    1473         316 :                 std::string const dimension(rand() & 1 ? "em" : "px");
    1474         158 :                 std::stringstream ss;
    1475             :                 ss << "div { width: abs("
    1476         158 :                    << std::setprecision(6) << std::fixed
    1477         158 :                    << (static_cast<csspp::decimal_number_t>(number) / 1000.0)
    1478             :                    << dimension
    1479         158 :                    << "); }";
    1480         474 :                 csspp::position pos("test.css");
    1481         158 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1482             : 
    1483         316 :                 csspp::parser p(l);
    1484             : 
    1485         158 :                 csspp::node::pointer_t n(p.stylesheet());
    1486             : 
    1487         158 :                 csspp::compiler c;
    1488         158 :                 c.set_root(n);
    1489         158 :                 c.set_date_time_variables(csspp_test::get_now());
    1490         158 :                 c.add_path(csspp_test::get_script_path());
    1491         158 :                 c.add_path(csspp_test::get_version_script_path());
    1492             : 
    1493         158 :                 c.compile(false);
    1494             : 
    1495             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1496             : 
    1497             :                 // to verify that the result is still an INTEGER we have to
    1498             :                 // test the root node here
    1499         158 :                 std::stringstream compiler_out;
    1500         158 :                 compiler_out << *n;
    1501         158 :                 VERIFY_TREES(compiler_out.str(),
    1502             : 
    1503             : "LIST\n"
    1504             : + csspp_test::get_default_variables() +
    1505             : "  COMPONENT_VALUE\n"
    1506             : "    ARG\n"
    1507             : "      IDENTIFIER \"div\"\n"
    1508             : "    OPEN_CURLYBRACKET B:true\n"
    1509             : "      DECLARATION \"width\"\n"
    1510             : "        ARG\n"
    1511             : "          DECIMAL_NUMBER \"" + dimension + "\" D:" + csspp::decimal_number_to_string(fabs(static_cast<csspp::decimal_number_t>(number) / 1000.0), false) + "\n"
    1512             : + csspp_test::get_close_comment(true)
    1513             : 
    1514             :                     );
    1515             : 
    1516         158 :                 std::stringstream assembler_out;
    1517         158 :                 csspp::assembler a(assembler_out);
    1518         158 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    1519             : 
    1520             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1521             : 
    1522         158 :                 CATCH_REQUIRE(assembler_out.str() ==
    1523             : 
    1524             : std::string("div{width:") + csspp::decimal_number_to_string(fabs(static_cast<csspp::decimal_number_t>(number) / 1000.0), true) + dimension + "}\n"
    1525             : + csspp_test::get_close_comment()
    1526             : 
    1527             :                         );
    1528             : 
    1529         158 :                 CATCH_REQUIRE(c.get_root() == n);
    1530         158 :             }
    1531             :         }
    1532             :     }
    1533           7 :     CATCH_END_SECTION()
    1534             : 
    1535           7 :     CATCH_START_SECTION("ceil(number)")
    1536             :     {
    1537         167 :         for(int number(-10000); number <= 10000; number += rand() % 250 + 1)
    1538             :         {
    1539             :             // ceil(int)
    1540             :             {
    1541         166 :                 std::stringstream ss;
    1542         166 :                 ss << "div { z-index: ceil("
    1543             :                    << number
    1544         166 :                    << "); }";
    1545         498 :                 csspp::position pos("test.css");
    1546         166 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1547             : 
    1548         332 :                 csspp::parser p(l);
    1549             : 
    1550         166 :                 csspp::node::pointer_t n(p.stylesheet());
    1551             : 
    1552         166 :                 csspp::compiler c;
    1553         166 :                 c.set_root(n);
    1554         166 :                 c.set_date_time_variables(csspp_test::get_now());
    1555         166 :                 c.add_path(csspp_test::get_script_path());
    1556         166 :                 c.add_path(csspp_test::get_version_script_path());
    1557             : 
    1558         166 :                 c.compile(false);
    1559             : 
    1560             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1561             : 
    1562             :                 // to verify that the result is still an INTEGER we have to
    1563             :                 // test the root node here
    1564         166 :                 std::stringstream compiler_out;
    1565         166 :                 compiler_out << *n;
    1566         166 :                 VERIFY_TREES(compiler_out.str(),
    1567             : 
    1568             : "LIST\n"
    1569             : + csspp_test::get_default_variables() +
    1570             : "  COMPONENT_VALUE\n"
    1571             : "    ARG\n"
    1572             : "      IDENTIFIER \"div\"\n"
    1573             : "    OPEN_CURLYBRACKET B:true\n"
    1574             : "      DECLARATION \"z-index\"\n"
    1575             : "        ARG\n"
    1576             : "          INTEGER \"\" I:" + std::to_string(number) + "\n"
    1577             : + csspp_test::get_close_comment(true)
    1578             : 
    1579             :                     );
    1580             : 
    1581         166 :                 std::stringstream assembler_out;
    1582         166 :                 csspp::assembler a(assembler_out);
    1583         166 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    1584             : 
    1585             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1586             : 
    1587         166 :                 CATCH_REQUIRE(assembler_out.str() ==
    1588             : 
    1589             : std::string("div{z-index:") + std::to_string(number) + "}\n"
    1590             : + csspp_test::get_close_comment()
    1591             : 
    1592             :                         );
    1593             : 
    1594         166 :                 CATCH_REQUIRE(c.get_root() == n);
    1595         166 :             }
    1596             : 
    1597             :             // ceil(float)
    1598             :             {
    1599         332 :                 std::string const dimension(rand() & 1 ? "deg" : "rad");
    1600         166 :                 std::stringstream ss;
    1601             :                 ss << "div { z-index: ceil("
    1602         166 :                    << std::setprecision(6) << std::fixed
    1603         166 :                    << (static_cast<csspp::decimal_number_t>(number) / 1000.0)
    1604             :                    << dimension
    1605         166 :                    << "); }";
    1606         498 :                 csspp::position pos("test.css");
    1607         166 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1608             : 
    1609         332 :                 csspp::parser p(l);
    1610             : 
    1611         166 :                 csspp::node::pointer_t n(p.stylesheet());
    1612             : 
    1613         166 :                 csspp::compiler c;
    1614         166 :                 c.set_root(n);
    1615         166 :                 c.set_date_time_variables(csspp_test::get_now());
    1616         166 :                 c.add_path(csspp_test::get_script_path());
    1617         166 :                 c.add_path(csspp_test::get_version_script_path());
    1618             : 
    1619         166 :                 c.compile(false);
    1620             : 
    1621             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1622             : 
    1623             :                 // to verify that the result is still an INTEGER we have to
    1624             :                 // test the root node here
    1625         166 :                 std::stringstream compiler_out;
    1626         166 :                 compiler_out << *n;
    1627         166 :                 VERIFY_TREES(compiler_out.str(),
    1628             : 
    1629             : "LIST\n"
    1630             : + csspp_test::get_default_variables() +
    1631             : "  COMPONENT_VALUE\n"
    1632             : "    ARG\n"
    1633             : "      IDENTIFIER \"div\"\n"
    1634             : "    OPEN_CURLYBRACKET B:true\n"
    1635             : "      DECLARATION \"z-index\"\n"
    1636             : "        ARG\n"
    1637             : "          DECIMAL_NUMBER \"" + dimension + "\" D:" + csspp::decimal_number_to_string(ceil(static_cast<csspp::decimal_number_t>(number) / 1000.0), false) + "\n"
    1638             : + csspp_test::get_close_comment(true)
    1639             : 
    1640             :                     );
    1641             : 
    1642         166 :                 std::stringstream assembler_out;
    1643         166 :                 csspp::assembler a(assembler_out);
    1644         166 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    1645             : 
    1646             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1647             : 
    1648         166 :                 CATCH_REQUIRE(assembler_out.str() ==
    1649             : 
    1650             : std::string("div{z-index:") + csspp::decimal_number_to_string(ceil(static_cast<csspp::decimal_number_t>(number) / 1000.0), true) + dimension + "}\n"
    1651             : + csspp_test::get_close_comment()
    1652             : 
    1653             :                         );
    1654             : 
    1655         166 :                 CATCH_REQUIRE(c.get_root() == n);
    1656         166 :             }
    1657             :         }
    1658             :     }
    1659           7 :     CATCH_END_SECTION()
    1660             : 
    1661           7 :     CATCH_START_SECTION("floor(number)")
    1662             :     {
    1663         157 :         for(int number(-10000); number <= 10000; number += rand() % 250 + 1)
    1664             :         {
    1665             :             // floor(int)
    1666             :             {
    1667         156 :                 std::stringstream ss;
    1668         156 :                 ss << "div { z-index: floor("
    1669             :                    << number
    1670         156 :                    << "); }";
    1671         468 :                 csspp::position pos("test.css");
    1672         156 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1673             : 
    1674         312 :                 csspp::parser p(l);
    1675             : 
    1676         156 :                 csspp::node::pointer_t n(p.stylesheet());
    1677             : 
    1678         156 :                 csspp::compiler c;
    1679         156 :                 c.set_root(n);
    1680         156 :                 c.set_date_time_variables(csspp_test::get_now());
    1681         156 :                 c.add_path(csspp_test::get_script_path());
    1682         156 :                 c.add_path(csspp_test::get_version_script_path());
    1683             : 
    1684         156 :                 c.compile(false);
    1685             : 
    1686             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1687             : 
    1688             :                 // to verify that the result is still an INTEGER we have to
    1689             :                 // test the root node here
    1690         156 :                 std::stringstream compiler_out;
    1691         156 :                 compiler_out << *n;
    1692         156 :                 VERIFY_TREES(compiler_out.str(),
    1693             : 
    1694             : "LIST\n"
    1695             : + csspp_test::get_default_variables() +
    1696             : "  COMPONENT_VALUE\n"
    1697             : "    ARG\n"
    1698             : "      IDENTIFIER \"div\"\n"
    1699             : "    OPEN_CURLYBRACKET B:true\n"
    1700             : "      DECLARATION \"z-index\"\n"
    1701             : "        ARG\n"
    1702             : "          INTEGER \"\" I:" + std::to_string(number) + "\n"
    1703             : + csspp_test::get_close_comment(true)
    1704             : 
    1705             :                     );
    1706             : 
    1707         156 :                 std::stringstream assembler_out;
    1708         156 :                 csspp::assembler a(assembler_out);
    1709         156 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    1710             : 
    1711             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1712             : 
    1713         156 :                 CATCH_REQUIRE(assembler_out.str() ==
    1714             : 
    1715             : std::string("div{z-index:") + std::to_string(number) + "}\n"
    1716             : + csspp_test::get_close_comment()
    1717             : 
    1718             :                         );
    1719             : 
    1720         156 :                 CATCH_REQUIRE(c.get_root() == n);
    1721         156 :             }
    1722             : 
    1723             :             // floor(float)
    1724             :             {
    1725         312 :                 std::string const dimension(rand() & 1 ? "em" : "px");
    1726         156 :                 std::stringstream ss;
    1727             :                 ss << "div { width: floor("
    1728         156 :                    << std::setprecision(6) << std::fixed
    1729         156 :                    << (static_cast<csspp::decimal_number_t>(number) / 1000.0)
    1730             :                    << dimension
    1731         156 :                    << "); }";
    1732         468 :                 csspp::position pos("test.css");
    1733         156 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1734             : 
    1735         312 :                 csspp::parser p(l);
    1736             : 
    1737         156 :                 csspp::node::pointer_t n(p.stylesheet());
    1738             : 
    1739         156 :                 csspp::compiler c;
    1740         156 :                 c.set_root(n);
    1741         156 :                 c.set_date_time_variables(csspp_test::get_now());
    1742         156 :                 c.add_path(csspp_test::get_script_path());
    1743         156 :                 c.add_path(csspp_test::get_version_script_path());
    1744             : 
    1745         156 :                 c.compile(false);
    1746             : 
    1747             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1748             : 
    1749             :                 // to verify that the result is still an INTEGER we have to
    1750             :                 // test the root node here
    1751         156 :                 std::stringstream compiler_out;
    1752         156 :                 compiler_out << *n;
    1753         156 :                 VERIFY_TREES(compiler_out.str(),
    1754             : 
    1755             : "LIST\n"
    1756             : + csspp_test::get_default_variables() +
    1757             : "  COMPONENT_VALUE\n"
    1758             : "    ARG\n"
    1759             : "      IDENTIFIER \"div\"\n"
    1760             : "    OPEN_CURLYBRACKET B:true\n"
    1761             : "      DECLARATION \"width\"\n"
    1762             : "        ARG\n"
    1763             : "          DECIMAL_NUMBER \"" + dimension + "\" D:" + csspp::decimal_number_to_string(floor(static_cast<csspp::decimal_number_t>(number) / 1000.0), false) + "\n"
    1764             : + csspp_test::get_close_comment(true)
    1765             : 
    1766             :                     );
    1767             : 
    1768         156 :                 std::stringstream assembler_out;
    1769         156 :                 csspp::assembler a(assembler_out);
    1770         156 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    1771             : 
    1772             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1773             : 
    1774         156 :                 CATCH_REQUIRE(assembler_out.str() ==
    1775             : 
    1776             : std::string("div{width:") + csspp::decimal_number_to_string(floor(static_cast<csspp::decimal_number_t>(number) / 1000.0), true) + dimension + "}\n"
    1777             : + csspp_test::get_close_comment()
    1778             : 
    1779             :                         );
    1780             : 
    1781         156 :                 CATCH_REQUIRE(c.get_root() == n);
    1782         156 :             }
    1783             :         }
    1784             :     }
    1785           7 :     CATCH_END_SECTION()
    1786             : 
    1787           7 :     CATCH_START_SECTION("round(number)")
    1788             :     {
    1789         150 :         for(int number(-10000); number <= 10000; number += rand() % 250 + 1)
    1790             :         {
    1791             :             // round(int)
    1792             :             {
    1793         149 :                 std::stringstream ss;
    1794         149 :                 ss << "div { z-index: round("
    1795             :                    << number
    1796         149 :                    << "); }";
    1797         447 :                 csspp::position pos("test.css");
    1798         149 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1799             : 
    1800         298 :                 csspp::parser p(l);
    1801             : 
    1802         149 :                 csspp::node::pointer_t n(p.stylesheet());
    1803             : 
    1804         149 :                 csspp::compiler c;
    1805         149 :                 c.set_root(n);
    1806         149 :                 c.set_date_time_variables(csspp_test::get_now());
    1807         149 :                 c.add_path(csspp_test::get_script_path());
    1808         149 :                 c.add_path(csspp_test::get_version_script_path());
    1809             : 
    1810         149 :                 c.compile(false);
    1811             : 
    1812             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1813             : 
    1814             :                 // to verify that the result is still an INTEGER we have to
    1815             :                 // test the root node here
    1816         149 :                 std::stringstream compiler_out;
    1817         149 :                 compiler_out << *n;
    1818         149 :                 VERIFY_TREES(compiler_out.str(),
    1819             : 
    1820             : "LIST\n"
    1821             : + csspp_test::get_default_variables() +
    1822             : "  COMPONENT_VALUE\n"
    1823             : "    ARG\n"
    1824             : "      IDENTIFIER \"div\"\n"
    1825             : "    OPEN_CURLYBRACKET B:true\n"
    1826             : "      DECLARATION \"z-index\"\n"
    1827             : "        ARG\n"
    1828             : "          INTEGER \"\" I:" + std::to_string(number) + "\n"
    1829             : + csspp_test::get_close_comment(true)
    1830             : 
    1831             :                     );
    1832             : 
    1833         149 :                 std::stringstream assembler_out;
    1834         149 :                 csspp::assembler a(assembler_out);
    1835         149 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    1836             : 
    1837             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1838             : 
    1839         149 :                 CATCH_REQUIRE(assembler_out.str() ==
    1840             : 
    1841             : std::string("div{z-index:") + std::to_string(number) + "}\n"
    1842             : + csspp_test::get_close_comment()
    1843             : 
    1844             :                         );
    1845             : 
    1846         149 :                 CATCH_REQUIRE(c.get_root() == n);
    1847         149 :             }
    1848             : 
    1849             :             // round(float)
    1850             :             {
    1851         298 :                 std::string const dimension(rand() & 1 ? "px" : "em");
    1852         149 :                 std::stringstream ss;
    1853             :                 ss << "div { width: round("
    1854         149 :                    << std::setprecision(6) << std::fixed
    1855         149 :                    << (static_cast<csspp::decimal_number_t>(number) / 1000.0)
    1856             :                    << dimension
    1857         149 :                    << "); }";
    1858         447 :                 csspp::position pos("test.css");
    1859         149 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1860             : 
    1861         298 :                 csspp::parser p(l);
    1862             : 
    1863         149 :                 csspp::node::pointer_t n(p.stylesheet());
    1864             : 
    1865         149 :                 csspp::compiler c;
    1866         149 :                 c.set_root(n);
    1867         149 :                 c.set_date_time_variables(csspp_test::get_now());
    1868         149 :                 c.add_path(csspp_test::get_script_path());
    1869         149 :                 c.add_path(csspp_test::get_version_script_path());
    1870             : 
    1871         149 :                 c.compile(false);
    1872             : 
    1873             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1874             : 
    1875             :                 // to verify that the result is still an INTEGER we have to
    1876             :                 // test the root node here
    1877         149 :                 std::stringstream compiler_out;
    1878         149 :                 compiler_out << *n;
    1879         149 :                 VERIFY_TREES(compiler_out.str(),
    1880             : 
    1881             : "LIST\n"
    1882             : + csspp_test::get_default_variables() +
    1883             : "  COMPONENT_VALUE\n"
    1884             : "    ARG\n"
    1885             : "      IDENTIFIER \"div\"\n"
    1886             : "    OPEN_CURLYBRACKET B:true\n"
    1887             : "      DECLARATION \"width\"\n"
    1888             : "        ARG\n"
    1889             : "          DECIMAL_NUMBER \"" + dimension + "\" D:" + csspp::decimal_number_to_string(round(static_cast<csspp::decimal_number_t>(number) / 1000.0), false) + "\n"
    1890             : + csspp_test::get_close_comment(true)
    1891             : 
    1892             :                     );
    1893             : 
    1894         149 :                 std::stringstream assembler_out;
    1895         149 :                 csspp::assembler a(assembler_out);
    1896         149 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    1897             : 
    1898             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1899             : 
    1900         149 :                 CATCH_REQUIRE(assembler_out.str() ==
    1901             : 
    1902             : std::string("div{width:") + csspp::decimal_number_to_string(round(static_cast<csspp::decimal_number_t>(number) / 1000.0), true) + dimension + "}\n"
    1903             : + csspp_test::get_close_comment()
    1904             : 
    1905             :                         );
    1906             : 
    1907         149 :                 CATCH_REQUIRE(c.get_root() == n);
    1908         149 :             }
    1909             :         }
    1910             :     }
    1911           7 :     CATCH_END_SECTION()
    1912             : 
    1913           7 :     CATCH_START_SECTION("log(number)")
    1914             :     {
    1915             :         // log(-1) and log(0) are invalid
    1916          89 :         for(int number(1); number <= 10000; number += rand() % 250 + 1)
    1917             :         {
    1918             :             // log(int)
    1919             :             {
    1920          88 :                 std::stringstream ss;
    1921          88 :                 ss << "div { z-index: log("
    1922             :                    << number
    1923          88 :                    << "); }";
    1924         264 :                 csspp::position pos("test.css");
    1925          88 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1926             : 
    1927         176 :                 csspp::parser p(l);
    1928             : 
    1929          88 :                 csspp::node::pointer_t n(p.stylesheet());
    1930             : 
    1931          88 :                 csspp::compiler c;
    1932          88 :                 c.set_root(n);
    1933          88 :                 c.set_date_time_variables(csspp_test::get_now());
    1934          88 :                 c.add_path(csspp_test::get_script_path());
    1935          88 :                 c.add_path(csspp_test::get_version_script_path());
    1936             : 
    1937          88 :                 c.compile(false);
    1938             : 
    1939             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1940             : 
    1941             :                 // to verify that the result is still an INTEGER we have to
    1942             :                 // test the root node here
    1943          88 :                 std::stringstream compiler_out;
    1944          88 :                 compiler_out << *n;
    1945          88 :                 VERIFY_TREES(compiler_out.str(),
    1946             : 
    1947             : "LIST\n"
    1948             : + csspp_test::get_default_variables() +
    1949             : "  COMPONENT_VALUE\n"
    1950             : "    ARG\n"
    1951             : "      IDENTIFIER \"div\"\n"
    1952             : "    OPEN_CURLYBRACKET B:true\n"
    1953             : "      DECLARATION \"z-index\"\n"
    1954             : "        ARG\n"
    1955             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(log(static_cast<csspp::decimal_number_t>(number)), false) + "\n"
    1956             : + csspp_test::get_close_comment(true)
    1957             : 
    1958             :                     );
    1959             : 
    1960          88 :                 std::stringstream assembler_out;
    1961          88 :                 csspp::assembler a(assembler_out);
    1962          88 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    1963             : 
    1964             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    1965             : 
    1966          88 :                 CATCH_REQUIRE(assembler_out.str() ==
    1967             : 
    1968             : std::string("div{z-index:") + csspp::decimal_number_to_string(log(static_cast<csspp::decimal_number_t>(number)), false) + "}\n"
    1969             : + csspp_test::get_close_comment()
    1970             : 
    1971             :                         );
    1972             : 
    1973          88 :                 CATCH_REQUIRE(c.get_root() == n);
    1974          88 :             }
    1975             : 
    1976             :             // log(float)
    1977             :             {
    1978          88 :                 std::stringstream ss;
    1979             :                 ss << "div { z-index: log("
    1980          88 :                    << std::setprecision(6) << std::fixed
    1981          88 :                    << (static_cast<csspp::decimal_number_t>(number) / 1000.0)
    1982          88 :                    << "); }";
    1983         264 :                 csspp::position pos("test.css");
    1984          88 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    1985             : 
    1986         176 :                 csspp::parser p(l);
    1987             : 
    1988          88 :                 csspp::node::pointer_t n(p.stylesheet());
    1989             : 
    1990          88 :                 csspp::compiler c;
    1991          88 :                 c.set_root(n);
    1992          88 :                 c.set_date_time_variables(csspp_test::get_now());
    1993          88 :                 c.add_path(csspp_test::get_script_path());
    1994          88 :                 c.add_path(csspp_test::get_version_script_path());
    1995             : 
    1996          88 :                 c.compile(false);
    1997             : 
    1998             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    1999             : 
    2000             :                 // to verify that the result is still an INTEGER we have to
    2001             :                 // test the root node here
    2002          88 :                 std::stringstream compiler_out;
    2003          88 :                 compiler_out << *n;
    2004          88 :                 VERIFY_TREES(compiler_out.str(),
    2005             : 
    2006             : "LIST\n"
    2007             : + csspp_test::get_default_variables() +
    2008             : "  COMPONENT_VALUE\n"
    2009             : "    ARG\n"
    2010             : "      IDENTIFIER \"div\"\n"
    2011             : "    OPEN_CURLYBRACKET B:true\n"
    2012             : "      DECLARATION \"z-index\"\n"
    2013             : "        ARG\n"
    2014             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(log(static_cast<csspp::decimal_number_t>(number) / 1000.0), false) + "\n"
    2015             : + csspp_test::get_close_comment(true)
    2016             : 
    2017             :                     );
    2018             : 
    2019          88 :                 std::stringstream assembler_out;
    2020          88 :                 csspp::assembler a(assembler_out);
    2021          88 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    2022             : 
    2023             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2024             : 
    2025          88 :                 CATCH_REQUIRE(assembler_out.str() ==
    2026             : 
    2027             : std::string("div{z-index:") + csspp::decimal_number_to_string(log(static_cast<csspp::decimal_number_t>(number) / 1000.0), true) + "}\n"
    2028             : + csspp_test::get_close_comment()
    2029             : 
    2030             :                         );
    2031             : 
    2032          88 :                 CATCH_REQUIRE(c.get_root() == n);
    2033          88 :             }
    2034             :         }
    2035             :     }
    2036           7 :     CATCH_END_SECTION()
    2037             : 
    2038           7 :     CATCH_START_SECTION("sign(number)")
    2039             :     {
    2040         160 :         for(int number(-10000); number <= 10000; number += rand() % 250 + 1)
    2041             :         {
    2042             :             // sign(int)
    2043             :             {
    2044         159 :                 std::stringstream ss;
    2045         159 :                 ss << "div { z-index: sign("
    2046             :                    << number
    2047         159 :                    << "); }";
    2048         477 :                 csspp::position pos("test.css");
    2049         159 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2050             : 
    2051         318 :                 csspp::parser p(l);
    2052             : 
    2053         159 :                 csspp::node::pointer_t n(p.stylesheet());
    2054             : 
    2055         159 :                 csspp::compiler c;
    2056         159 :                 c.set_root(n);
    2057         159 :                 c.set_date_time_variables(csspp_test::get_now());
    2058         159 :                 c.add_path(csspp_test::get_script_path());
    2059         159 :                 c.add_path(csspp_test::get_version_script_path());
    2060             : 
    2061         159 :                 c.compile(false);
    2062             : 
    2063             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2064             : 
    2065             :                 // to verify that the result is still an INTEGER we have to
    2066             :                 // test the root node here
    2067         159 :                 std::stringstream compiler_out;
    2068         159 :                 compiler_out << *n;
    2069         159 :                 VERIFY_TREES(compiler_out.str(),
    2070             : 
    2071             : "LIST\n"
    2072             : + csspp_test::get_default_variables() +
    2073             : "  COMPONENT_VALUE\n"
    2074             : "    ARG\n"
    2075             : "      IDENTIFIER \"div\"\n"
    2076             : "    OPEN_CURLYBRACKET B:true\n"
    2077             : "      DECLARATION \"z-index\"\n"
    2078             : "        ARG\n"
    2079             : "          INTEGER \"\" I:" + std::to_string(number == 0 ? 0 : (number < 0 ? -1 : 1)) + "\n"
    2080             : + csspp_test::get_close_comment(true)
    2081             : 
    2082             :                     );
    2083             : 
    2084         159 :                 std::stringstream assembler_out;
    2085         159 :                 csspp::assembler a(assembler_out);
    2086         159 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    2087             : 
    2088             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2089             : 
    2090         159 :                 CATCH_REQUIRE(assembler_out.str() ==
    2091             : 
    2092             : "div{z-index:" + std::to_string(number == 0 ? 0 : (number < 0 ? -1 : 1)) + "}\n"
    2093             : + csspp_test::get_close_comment()
    2094             : 
    2095             :                         );
    2096             : 
    2097         159 :                 CATCH_REQUIRE(c.get_root() == n);
    2098         159 :             }
    2099             : 
    2100             :             // sign(float)
    2101             :             {
    2102         159 :                 std::stringstream ss;
    2103             :                 ss << "div { z-index: sign("
    2104         159 :                    << std::setprecision(6) << std::fixed
    2105         159 :                    << (static_cast<csspp::decimal_number_t>(number) / 1000.0)
    2106         159 :                    << "); }";
    2107         477 :                 csspp::position pos("test.css");
    2108         159 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2109             : 
    2110         318 :                 csspp::parser p(l);
    2111             : 
    2112         159 :                 csspp::node::pointer_t n(p.stylesheet());
    2113             : 
    2114         159 :                 csspp::compiler c;
    2115         159 :                 c.set_root(n);
    2116         159 :                 c.set_date_time_variables(csspp_test::get_now());
    2117         159 :                 c.add_path(csspp_test::get_script_path());
    2118         159 :                 c.add_path(csspp_test::get_version_script_path());
    2119             : 
    2120         159 :                 c.compile(false);
    2121             : 
    2122             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2123             : 
    2124             :                 // to verify that the result is still an INTEGER we have to
    2125             :                 // test the root node here
    2126         159 :                 std::stringstream compiler_out;
    2127         159 :                 compiler_out << *n;
    2128         159 :                 VERIFY_TREES(compiler_out.str(),
    2129             : 
    2130             : "LIST\n"
    2131             : + csspp_test::get_default_variables() +
    2132             : "  COMPONENT_VALUE\n"
    2133             : "    ARG\n"
    2134             : "      IDENTIFIER \"div\"\n"
    2135             : "    OPEN_CURLYBRACKET B:true\n"
    2136             : "      DECLARATION \"z-index\"\n"
    2137             : "        ARG\n"
    2138             : "          DECIMAL_NUMBER \"\" D:" + (number == 0 ? "0" : (number < 0 ? "-1" : "1")) + "\n"
    2139             : + csspp_test::get_close_comment(true)
    2140             : 
    2141             :                     );
    2142             : 
    2143         159 :                 std::stringstream assembler_out;
    2144         159 :                 csspp::assembler a(assembler_out);
    2145         159 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    2146             : 
    2147             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2148             : 
    2149         159 :                 CATCH_REQUIRE(assembler_out.str() ==
    2150             : 
    2151             : std::string("div{z-index:") + (number == 0 ? "0" : (number < 0 ? "-1" : "1")) + "}\n"
    2152             : + csspp_test::get_close_comment()
    2153             : 
    2154             :                         );
    2155             : 
    2156         159 :                 CATCH_REQUIRE(c.get_root() == n);
    2157         159 :             }
    2158             : 
    2159             :             // sign(percent)
    2160             :             {
    2161         159 :                 std::stringstream ss;
    2162             :                 ss << "div { width: sign("
    2163         159 :                    << std::setprecision(6) << std::fixed
    2164         159 :                    << (static_cast<csspp::decimal_number_t>(number) / 1000.0)
    2165         159 :                    << "%); }";
    2166         477 :                 csspp::position pos("test.css");
    2167         159 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2168             : 
    2169         318 :                 csspp::parser p(l);
    2170             : 
    2171         159 :                 csspp::node::pointer_t n(p.stylesheet());
    2172             : 
    2173         159 :                 csspp::compiler c;
    2174         159 :                 c.set_root(n);
    2175         159 :                 c.set_date_time_variables(csspp_test::get_now());
    2176         159 :                 c.add_path(csspp_test::get_script_path());
    2177         159 :                 c.add_path(csspp_test::get_version_script_path());
    2178             : 
    2179         159 :                 c.compile(false);
    2180             : 
    2181             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2182             : 
    2183             :                 // to verify that the result is still an INTEGER we have to
    2184             :                 // test the root node here
    2185         159 :                 std::stringstream compiler_out;
    2186         159 :                 compiler_out << *n;
    2187         159 :                 VERIFY_TREES(compiler_out.str(),
    2188             : 
    2189             : "LIST\n"
    2190             : + csspp_test::get_default_variables() +
    2191             : "  COMPONENT_VALUE\n"
    2192             : "    ARG\n"
    2193             : "      IDENTIFIER \"div\"\n"
    2194             : "    OPEN_CURLYBRACKET B:true\n"
    2195             : "      DECLARATION \"width\"\n"
    2196             : "        ARG\n"
    2197             : "          PERCENT D:" + (number == 0 ? "0" : (number < 0 ? "-1" : "1")) + "\n"
    2198             : + csspp_test::get_close_comment(true)
    2199             : 
    2200             :                     );
    2201             : 
    2202         159 :                 std::stringstream assembler_out;
    2203         159 :                 csspp::assembler a(assembler_out);
    2204         159 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    2205             : 
    2206             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2207             : 
    2208         159 :                 CATCH_REQUIRE(assembler_out.str() ==
    2209             : 
    2210             : std::string("div{width:") + (number == 0 ? "0" : (number < 0 ? "-100": "100")) + "%}\n"
    2211             : + csspp_test::get_close_comment()
    2212             : 
    2213             :                         );
    2214             : 
    2215         159 :                 CATCH_REQUIRE(c.get_root() == n);
    2216         159 :             }
    2217             :         }
    2218             :     }
    2219           7 :     CATCH_END_SECTION()
    2220             : 
    2221           7 :     CATCH_START_SECTION("sqrt(number)")
    2222             :     {
    2223             :         // sqrt(-number) is not valid, so skip negative numbers
    2224          83 :         for(int number(0); number <= 10000; number += rand() % 250 + 1)
    2225             :         {
    2226             :             // sqrt(int)
    2227             :             {
    2228          82 :                 std::stringstream ss;
    2229          82 :                 ss << "div { z-index: sqrt("
    2230             :                    << number
    2231          82 :                    << "); }";
    2232         246 :                 csspp::position pos("test.css");
    2233          82 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2234             : 
    2235         164 :                 csspp::parser p(l);
    2236             : 
    2237          82 :                 csspp::node::pointer_t n(p.stylesheet());
    2238             : 
    2239          82 :                 csspp::compiler c;
    2240          82 :                 c.set_root(n);
    2241          82 :                 c.set_date_time_variables(csspp_test::get_now());
    2242          82 :                 c.add_path(csspp_test::get_script_path());
    2243          82 :                 c.add_path(csspp_test::get_version_script_path());
    2244             : 
    2245          82 :                 c.compile(false);
    2246             : 
    2247             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2248             : 
    2249             :                 // to verify that the result is still an INTEGER we have to
    2250             :                 // test the root node here
    2251          82 :                 std::stringstream compiler_out;
    2252          82 :                 compiler_out << *n;
    2253          82 :                 VERIFY_TREES(compiler_out.str(),
    2254             : 
    2255             : "LIST\n"
    2256             : + csspp_test::get_default_variables() +
    2257             : "  COMPONENT_VALUE\n"
    2258             : "    ARG\n"
    2259             : "      IDENTIFIER \"div\"\n"
    2260             : "    OPEN_CURLYBRACKET B:true\n"
    2261             : "      DECLARATION \"z-index\"\n"
    2262             : "        ARG\n"
    2263             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(sqrt(static_cast<csspp::decimal_number_t>(number)), false) + "\n"
    2264             : + csspp_test::get_close_comment(true)
    2265             : 
    2266             :                     );
    2267             : 
    2268          82 :                 std::stringstream assembler_out;
    2269          82 :                 csspp::assembler a(assembler_out);
    2270          82 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    2271             : 
    2272             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2273             : 
    2274          82 :                 CATCH_REQUIRE(assembler_out.str() ==
    2275             : 
    2276             : "div{z-index:" + csspp::decimal_number_to_string(sqrt(static_cast<csspp::decimal_number_t>(number)), true) + "}\n"
    2277             : + csspp_test::get_close_comment()
    2278             : 
    2279             :                         );
    2280             : 
    2281          82 :                 CATCH_REQUIRE(c.get_root() == n);
    2282          82 :             }
    2283             : 
    2284             :             // sqrt(float)
    2285             :             {
    2286          82 :                 std::stringstream ss;
    2287             :                 ss << "div { z-index: sqrt("
    2288          82 :                    << std::setprecision(6) << std::fixed
    2289          82 :                    << (static_cast<csspp::decimal_number_t>(number) / 1000.0)
    2290          82 :                    << "); }";
    2291         246 :                 csspp::position pos("test.css");
    2292          82 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2293             : 
    2294         164 :                 csspp::parser p(l);
    2295             : 
    2296          82 :                 csspp::node::pointer_t n(p.stylesheet());
    2297             : 
    2298          82 :                 csspp::compiler c;
    2299          82 :                 c.set_root(n);
    2300          82 :                 c.set_date_time_variables(csspp_test::get_now());
    2301          82 :                 c.add_path(csspp_test::get_script_path());
    2302          82 :                 c.add_path(csspp_test::get_version_script_path());
    2303             : 
    2304          82 :                 c.compile(false);
    2305             : 
    2306             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2307             : 
    2308             :                 // to verify that the result is still an INTEGER we have to
    2309             :                 // test the root node here
    2310          82 :                 std::stringstream compiler_out;
    2311          82 :                 compiler_out << *n;
    2312          82 :                 VERIFY_TREES(compiler_out.str(),
    2313             : 
    2314             : "LIST\n"
    2315             : + csspp_test::get_default_variables() +
    2316             : "  COMPONENT_VALUE\n"
    2317             : "    ARG\n"
    2318             : "      IDENTIFIER \"div\"\n"
    2319             : "    OPEN_CURLYBRACKET B:true\n"
    2320             : "      DECLARATION \"z-index\"\n"
    2321             : "        ARG\n"
    2322             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(sqrt(static_cast<csspp::decimal_number_t>(number) / 1000.0), false) + "\n"
    2323             : + csspp_test::get_close_comment(true)
    2324             : 
    2325             :                     );
    2326             : 
    2327          82 :                 std::stringstream assembler_out;
    2328          82 :                 csspp::assembler a(assembler_out);
    2329          82 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    2330             : 
    2331             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2332             : 
    2333          82 :                 CATCH_REQUIRE(assembler_out.str() ==
    2334             : 
    2335             : std::string("div{z-index:") + csspp::decimal_number_to_string(sqrt(static_cast<csspp::decimal_number_t>(number) / 1000.0), true) + "}\n"
    2336             : + csspp_test::get_close_comment()
    2337             : 
    2338             :                         );
    2339             : 
    2340          82 :                 CATCH_REQUIRE(c.get_root() == n);
    2341          82 :             }
    2342             : 
    2343             :             // sqrt(dimension)
    2344             :             {
    2345          82 :                 std::stringstream ss;
    2346             :                 ss << "div { width: sqrt("
    2347          82 :                    << std::setprecision(6) << std::fixed
    2348          82 :                    << (static_cast<csspp::decimal_number_t>(number) / 1000.0)
    2349          82 :                    << "px\\*px); }";
    2350         246 :                 csspp::position pos("test.css");
    2351          82 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2352             : 
    2353         164 :                 csspp::parser p(l);
    2354             : 
    2355          82 :                 csspp::node::pointer_t n(p.stylesheet());
    2356             : 
    2357          82 :                 csspp::compiler c;
    2358          82 :                 c.set_root(n);
    2359          82 :                 c.set_date_time_variables(csspp_test::get_now());
    2360          82 :                 c.add_path(csspp_test::get_script_path());
    2361          82 :                 c.add_path(csspp_test::get_version_script_path());
    2362             : 
    2363          82 :                 c.compile(false);
    2364             : 
    2365             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2366             : 
    2367             :                 // to verify that the result is still an INTEGER we have to
    2368             :                 // test the root node here
    2369          82 :                 std::stringstream compiler_out;
    2370          82 :                 compiler_out << *n;
    2371          82 :                 VERIFY_TREES(compiler_out.str(),
    2372             : 
    2373             : "LIST\n"
    2374             : + csspp_test::get_default_variables() +
    2375             : "  COMPONENT_VALUE\n"
    2376             : "    ARG\n"
    2377             : "      IDENTIFIER \"div\"\n"
    2378             : "    OPEN_CURLYBRACKET B:true\n"
    2379             : "      DECLARATION \"width\"\n"
    2380             : "        ARG\n"
    2381             : "          DECIMAL_NUMBER \"px\" D:" + csspp::decimal_number_to_string(sqrt(static_cast<csspp::decimal_number_t>(number) / 1000.0), false) + "\n"
    2382             : + csspp_test::get_close_comment(true)
    2383             : 
    2384             :                     );
    2385             : 
    2386          82 :                 std::stringstream assembler_out;
    2387          82 :                 csspp::assembler a(assembler_out);
    2388          82 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    2389             : 
    2390             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2391             : 
    2392          82 :                 CATCH_REQUIRE(assembler_out.str() ==
    2393             : 
    2394             : std::string("div{width:") + csspp::decimal_number_to_string(sqrt(static_cast<csspp::decimal_number_t>(number) / 1000.0), true) + "px}\n"
    2395             : + csspp_test::get_close_comment()
    2396             : 
    2397             :                         );
    2398             : 
    2399          82 :                 CATCH_REQUIRE(c.get_root() == n);
    2400          82 :             }
    2401             : 
    2402             :             // sqrt(dimension) -- dividend and divisor
    2403             :             {
    2404          82 :                 std::stringstream ss;
    2405             :                 ss << "div { width: sqrt("
    2406          82 :                    << std::setprecision(6) << std::fixed
    2407          82 :                    << (static_cast<csspp::decimal_number_t>(number) / 1000.0)
    2408          82 :                    << "px\\*px\\/em\\*em) * 1em; }";
    2409         246 :                 csspp::position pos("test.css");
    2410          82 :                 csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2411             : 
    2412         164 :                 csspp::parser p(l);
    2413             : 
    2414          82 :                 csspp::node::pointer_t n(p.stylesheet());
    2415             : 
    2416          82 :                 csspp::compiler c;
    2417          82 :                 c.set_root(n);
    2418          82 :                 c.set_date_time_variables(csspp_test::get_now());
    2419          82 :                 c.add_path(csspp_test::get_script_path());
    2420          82 :                 c.add_path(csspp_test::get_version_script_path());
    2421             : 
    2422          82 :                 c.compile(false);
    2423             : 
    2424             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2425             : 
    2426             :                 // to verify that the result is still an INTEGER we have to
    2427             :                 // test the root node here
    2428          82 :                 std::stringstream compiler_out;
    2429          82 :                 compiler_out << *n;
    2430          82 :                 VERIFY_TREES(compiler_out.str(),
    2431             : 
    2432             : "LIST\n"
    2433             : + csspp_test::get_default_variables() +
    2434             : "  COMPONENT_VALUE\n"
    2435             : "    ARG\n"
    2436             : "      IDENTIFIER \"div\"\n"
    2437             : "    OPEN_CURLYBRACKET B:true\n"
    2438             : "      DECLARATION \"width\"\n"
    2439             : "        ARG\n"
    2440             : "          DECIMAL_NUMBER \"px\" D:" + csspp::decimal_number_to_string(sqrt(static_cast<csspp::decimal_number_t>(number) / 1000.0), false) + "\n"
    2441             : + csspp_test::get_close_comment(true)
    2442             : 
    2443             :                     );
    2444             : 
    2445          82 :                 std::stringstream assembler_out;
    2446          82 :                 csspp::assembler a(assembler_out);
    2447          82 :                 a.output(n, csspp::output_mode_t::COMPRESSED);
    2448             : 
    2449             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2450             : 
    2451          82 :                 CATCH_REQUIRE(assembler_out.str() ==
    2452             : 
    2453             : std::string("div{width:") + csspp::decimal_number_to_string(sqrt(static_cast<csspp::decimal_number_t>(number) / 1000.0), true) + "px}\n"
    2454             : + csspp_test::get_close_comment()
    2455             : 
    2456             :                         );
    2457             : 
    2458          82 :                 CATCH_REQUIRE(c.get_root() == n);
    2459          82 :             }
    2460             :         }
    2461             :     }
    2462           7 :     CATCH_END_SECTION()
    2463             : 
    2464             :     // no error left over
    2465           7 :     VERIFY_ERRORS("");
    2466           7 : }
    2467             : 
    2468           2 : CATCH_TEST_CASE("Expression red()/green()/blue()/alpha()", "[expression] [internal-functions] [red] [green] [blue] [alpha]")
    2469             : {
    2470           2 :     CATCH_START_SECTION("check color components")
    2471             :     {
    2472           7 :         for(int r(0); r < 256; r += rand() % 100 + 1)
    2473             :         {
    2474          45 :             for(int g(0); g < 256; g += rand() % 100 + 1)
    2475             :             {
    2476         262 :                 for(int b(0); b < 256; b += rand() % 100 + 1)
    2477             :                 {
    2478        1535 :                     for(int alpha(0); alpha < 256; alpha += rand() % 100 + 1)
    2479             :                     {
    2480             :                         {
    2481        1312 :                             std::stringstream ss;
    2482        1312 :                             ss << "div { z-index: red(rgba("
    2483             :                                << r
    2484        1312 :                                << ", "
    2485             :                                << g
    2486        1312 :                                << ", "
    2487             :                                << b
    2488        1312 :                                << ", "
    2489        1312 :                                << alpha / 255.0
    2490             :                                << ")); }\n"
    2491        1312 :                                << "span { z-index: green(rgba("
    2492             :                                << r
    2493        1312 :                                << ", "
    2494             :                                << g
    2495        1312 :                                << ", "
    2496             :                                << b
    2497        1312 :                                << ", "
    2498        1312 :                                << alpha / 255.0
    2499             :                                << ")); }\n"
    2500        1312 :                                << "p { z-index: blue(rgba("
    2501             :                                << r
    2502        1312 :                                << ", "
    2503             :                                << g
    2504        1312 :                                << ", "
    2505             :                                << b
    2506        1312 :                                << ", "
    2507        1312 :                                << alpha / 255.0
    2508             :                                << ")); }\n"
    2509        1312 :                                << "i { z-index: alpha(rgba("
    2510             :                                << r
    2511        1312 :                                << ", "
    2512             :                                << g
    2513        1312 :                                << ", "
    2514             :                                << b
    2515        1312 :                                << ", "
    2516        1312 :                                << alpha / 255.0
    2517             :                                << ")); }\n"
    2518        1312 :                                << "div { z-index: red(rgb("
    2519             :                                << r
    2520        1312 :                                << ", "
    2521             :                                << g
    2522        1312 :                                << ", "
    2523             :                                << b
    2524             :                                << ")); }\n"
    2525        1312 :                                << "span { z-index: green(rgb("
    2526             :                                << r
    2527        1312 :                                << ", "
    2528             :                                << g
    2529        1312 :                                << ", "
    2530             :                                << b
    2531             :                                << ")); }\n"
    2532        1312 :                                << "p { z-index: blue(rgb("
    2533             :                                << r
    2534        1312 :                                << ", "
    2535             :                                << g
    2536        1312 :                                << ", "
    2537             :                                << b
    2538             :                                << ")); }\n"
    2539        1312 :                                << "i { z-index: alpha(rgb("
    2540             :                                << r
    2541        1312 :                                << ", "
    2542             :                                << g
    2543        1312 :                                << ", "
    2544             :                                << b
    2545             :                                << ")); }\n"
    2546        1312 :                                << "div { z-index: red(rgba(rgb("
    2547             :                                << r
    2548        1312 :                                << ", "
    2549             :                                << g
    2550        1312 :                                << ", "
    2551             :                                << b
    2552        1312 :                                << "), "
    2553        1312 :                                << alpha / 255.0
    2554             :                                << ")); }\n"
    2555        1312 :                                << "span { z-index: green(rgba(rgb("
    2556             :                                << r
    2557        1312 :                                << ", "
    2558             :                                << g
    2559        1312 :                                << ", "
    2560             :                                << b
    2561        1312 :                                << "), "
    2562        1312 :                                << alpha / 255.0
    2563             :                                << ")); }\n"
    2564        1312 :                                << "p { z-index: blue(rgba(rgb("
    2565             :                                << r
    2566        1312 :                                << ", "
    2567             :                                << g
    2568        1312 :                                << ", "
    2569             :                                << b
    2570        1312 :                                << "), "
    2571        1312 :                                << alpha / 255.0
    2572             :                                << ")); }\n"
    2573        1312 :                                << "i { z-index: alpha(rgba(rgb("
    2574             :                                << r
    2575        1312 :                                << ", "
    2576             :                                << g
    2577        1312 :                                << ", "
    2578             :                                << b
    2579        1312 :                                << "), "
    2580        1312 :                                << alpha / 255.0
    2581             :                                << ")); }\n"
    2582        1312 :                                << "div { z-index: red(frgba("
    2583        1312 :                                << r / 255.0
    2584        1312 :                                << ", "
    2585        1312 :                                << g / 255.0
    2586        1312 :                                << ", "
    2587        1312 :                                << b / 255.0
    2588        1312 :                                << ", "
    2589        1312 :                                << alpha / 255.0
    2590             :                                << ")); }\n"
    2591        1312 :                                << "span { z-index: green(frgba("
    2592        1312 :                                << r / 255.0
    2593        1312 :                                << ", "
    2594        1312 :                                << g / 255.0
    2595        1312 :                                << ", "
    2596        1312 :                                << b / 255.0
    2597        1312 :                                << ", "
    2598        1312 :                                << alpha / 255.0
    2599             :                                << ")); }\n"
    2600        1312 :                                << "p { z-index: blue(frgba("
    2601        1312 :                                << r / 255.0
    2602        1312 :                                << ", "
    2603        1312 :                                << g / 255.0
    2604        1312 :                                << ", "
    2605        1312 :                                << b / 255.0
    2606        1312 :                                << ", "
    2607        1312 :                                << alpha / 255.0
    2608             :                                << ")); }\n"
    2609        1312 :                                << "i { z-index: alpha(frgba("
    2610        1312 :                                << r / 255.0
    2611        1312 :                                << ", "
    2612        1312 :                                << g / 255.0
    2613        1312 :                                << ", "
    2614        1312 :                                << b / 255.0
    2615        1312 :                                << ", "
    2616        1312 :                                << alpha / 255.0
    2617             :                                << ")); }\n"
    2618        1312 :                                << "div { z-index: red(frgb("
    2619        1312 :                                << r / 255.0
    2620        1312 :                                << ", "
    2621        1312 :                                << g / 255.0
    2622        1312 :                                << ", "
    2623        1312 :                                << b / 255.0
    2624             :                                << ")); }\n"
    2625        1312 :                                << "span { z-index: green(frgb("
    2626        1312 :                                << r / 255.0
    2627        1312 :                                << ", "
    2628        1312 :                                << g / 255.0
    2629        1312 :                                << ", "
    2630        1312 :                                << b / 255.0
    2631             :                                << ")); }\n"
    2632        1312 :                                << "p { z-index: blue(frgb("
    2633        1312 :                                << r / 255.0
    2634        1312 :                                << ", "
    2635        1312 :                                << g / 255.0
    2636        1312 :                                << ", "
    2637        1312 :                                << b / 255.0
    2638             :                                << ")); }\n"
    2639        1312 :                                << "i { z-index: alpha(frgb("
    2640        1312 :                                << r / 255.0
    2641        1312 :                                << ", "
    2642        1312 :                                << g / 255.0
    2643        1312 :                                << ", "
    2644        1312 :                                << b / 255.0
    2645             :                                << ")); }\n"
    2646        1312 :                                << "div { z-index: red(frgba(frgb("
    2647        1312 :                                << r / 255.0
    2648        1312 :                                << ", "
    2649        1312 :                                << g / 255.0
    2650        1312 :                                << ", "
    2651        1312 :                                << b / 255.0
    2652        1312 :                                << "), "
    2653        1312 :                                << alpha / 255.0
    2654             :                                << ")); }\n"
    2655        1312 :                                << "span { z-index: green(frgba(frgb("
    2656        1312 :                                << r / 255.0
    2657        1312 :                                << ", "
    2658        1312 :                                << g / 255.0
    2659        1312 :                                << ", "
    2660        1312 :                                << b / 255.0
    2661        1312 :                                << "), "
    2662        1312 :                                << alpha / 255.0
    2663             :                                << ")); }\n"
    2664        1312 :                                << "p { z-index: blue(frgba(frgb("
    2665        1312 :                                << r / 255.0
    2666        1312 :                                << ", "
    2667        1312 :                                << g / 255.0
    2668        1312 :                                << ", "
    2669        1312 :                                << b / 255.0
    2670        1312 :                                << "), "
    2671        1312 :                                << alpha / 255.0
    2672             :                                << ")); }\n"
    2673        1312 :                                << "i { z-index: alpha(frgba(frgb("
    2674        1312 :                                << r / 255.0
    2675        1312 :                                << ", "
    2676        1312 :                                << g / 255.0
    2677        1312 :                                << ", "
    2678        1312 :                                << b / 255.0
    2679        1312 :                                << "), "
    2680        1312 :                                << alpha / 255.0
    2681        1312 :                                << ")); }\n";
    2682        3936 :                             csspp::position pos("test.css");
    2683        1312 :                             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2684             : 
    2685        2624 :                             csspp::parser p(l);
    2686             : 
    2687        1312 :                             csspp::node::pointer_t n(p.stylesheet());
    2688             : 
    2689        1312 :                             csspp::compiler c;
    2690        1312 :                             c.set_root(n);
    2691        1312 :                             c.set_date_time_variables(csspp_test::get_now());
    2692        1312 :                             c.add_path(csspp_test::get_script_path());
    2693        1312 :                             c.add_path(csspp_test::get_version_script_path());
    2694             : 
    2695        1312 :                             c.compile(false);
    2696             : 
    2697             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2698             : 
    2699             :                             // to verify that the result is still an INTEGER we have to
    2700             :                             // test the root node here
    2701        1312 :                             std::stringstream compiler_out;
    2702        1312 :                             compiler_out << *n;
    2703        1312 :                             VERIFY_TREES(compiler_out.str(),
    2704             : 
    2705             : "LIST\n"
    2706             : + csspp_test::get_default_variables() +
    2707             : // component(rgba())
    2708             : "  COMPONENT_VALUE\n"
    2709             : "    ARG\n"
    2710             : "      IDENTIFIER \"div\"\n"
    2711             : "    OPEN_CURLYBRACKET B:true\n"
    2712             : "      DECLARATION \"z-index\"\n"
    2713             : "        ARG\n"
    2714             : "          INTEGER \"\" I:" + std::to_string(r) + "\n"
    2715             : "  COMPONENT_VALUE\n"
    2716             : "    ARG\n"
    2717             : "      IDENTIFIER \"span\"\n"
    2718             : "    OPEN_CURLYBRACKET B:true\n"
    2719             : "      DECLARATION \"z-index\"\n"
    2720             : "        ARG\n"
    2721             : "          INTEGER \"\" I:" + std::to_string(g) + "\n"
    2722             : "  COMPONENT_VALUE\n"
    2723             : "    ARG\n"
    2724             : "      IDENTIFIER \"p\"\n"
    2725             : "    OPEN_CURLYBRACKET B:true\n"
    2726             : "      DECLARATION \"z-index\"\n"
    2727             : "        ARG\n"
    2728             : "          INTEGER \"\" I:" + std::to_string(b) + "\n"
    2729             : "  COMPONENT_VALUE\n"
    2730             : "    ARG\n"
    2731             : "      IDENTIFIER \"i\"\n"
    2732             : "    OPEN_CURLYBRACKET B:true\n"
    2733             : "      DECLARATION \"z-index\"\n"
    2734             : "        ARG\n"
    2735             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(alpha / 255.0, false) + "\n"
    2736             : // component(rgb())
    2737             : "  COMPONENT_VALUE\n"
    2738             : "    ARG\n"
    2739             : "      IDENTIFIER \"div\"\n"
    2740             : "    OPEN_CURLYBRACKET B:true\n"
    2741             : "      DECLARATION \"z-index\"\n"
    2742             : "        ARG\n"
    2743             : "          INTEGER \"\" I:" + std::to_string(r) + "\n"
    2744             : "  COMPONENT_VALUE\n"
    2745             : "    ARG\n"
    2746             : "      IDENTIFIER \"span\"\n"
    2747             : "    OPEN_CURLYBRACKET B:true\n"
    2748             : "      DECLARATION \"z-index\"\n"
    2749             : "        ARG\n"
    2750             : "          INTEGER \"\" I:" + std::to_string(g) + "\n"
    2751             : "  COMPONENT_VALUE\n"
    2752             : "    ARG\n"
    2753             : "      IDENTIFIER \"p\"\n"
    2754             : "    OPEN_CURLYBRACKET B:true\n"
    2755             : "      DECLARATION \"z-index\"\n"
    2756             : "        ARG\n"
    2757             : "          INTEGER \"\" I:" + std::to_string(b) + "\n"
    2758             : "  COMPONENT_VALUE\n"
    2759             : "    ARG\n"
    2760             : "      IDENTIFIER \"i\"\n"
    2761             : "    OPEN_CURLYBRACKET B:true\n"
    2762             : "      DECLARATION \"z-index\"\n"
    2763             : "        ARG\n"
    2764             : "          DECIMAL_NUMBER \"\" D:1\n"
    2765             : // component(rgba(rgb(), alpha))
    2766             : "  COMPONENT_VALUE\n"
    2767             : "    ARG\n"
    2768             : "      IDENTIFIER \"div\"\n"
    2769             : "    OPEN_CURLYBRACKET B:true\n"
    2770             : "      DECLARATION \"z-index\"\n"
    2771             : "        ARG\n"
    2772             : "          INTEGER \"\" I:" + std::to_string(r) + "\n"
    2773             : "  COMPONENT_VALUE\n"
    2774             : "    ARG\n"
    2775             : "      IDENTIFIER \"span\"\n"
    2776             : "    OPEN_CURLYBRACKET B:true\n"
    2777             : "      DECLARATION \"z-index\"\n"
    2778             : "        ARG\n"
    2779             : "          INTEGER \"\" I:" + std::to_string(g) + "\n"
    2780             : "  COMPONENT_VALUE\n"
    2781             : "    ARG\n"
    2782             : "      IDENTIFIER \"p\"\n"
    2783             : "    OPEN_CURLYBRACKET B:true\n"
    2784             : "      DECLARATION \"z-index\"\n"
    2785             : "        ARG\n"
    2786             : "          INTEGER \"\" I:" + std::to_string(b) + "\n"
    2787             : "  COMPONENT_VALUE\n"
    2788             : "    ARG\n"
    2789             : "      IDENTIFIER \"i\"\n"
    2790             : "    OPEN_CURLYBRACKET B:true\n"
    2791             : "      DECLARATION \"z-index\"\n"
    2792             : "        ARG\n"
    2793             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(alpha / 255.0, false) + "\n"
    2794             : // component(frgba())
    2795             : "  COMPONENT_VALUE\n"
    2796             : "    ARG\n"
    2797             : "      IDENTIFIER \"div\"\n"
    2798             : "    OPEN_CURLYBRACKET B:true\n"
    2799             : "      DECLARATION \"z-index\"\n"
    2800             : "        ARG\n"
    2801             : "          INTEGER \"\" I:" + std::to_string(r) + "\n"
    2802             : "  COMPONENT_VALUE\n"
    2803             : "    ARG\n"
    2804             : "      IDENTIFIER \"span\"\n"
    2805             : "    OPEN_CURLYBRACKET B:true\n"
    2806             : "      DECLARATION \"z-index\"\n"
    2807             : "        ARG\n"
    2808             : "          INTEGER \"\" I:" + std::to_string(g) + "\n"
    2809             : "  COMPONENT_VALUE\n"
    2810             : "    ARG\n"
    2811             : "      IDENTIFIER \"p\"\n"
    2812             : "    OPEN_CURLYBRACKET B:true\n"
    2813             : "      DECLARATION \"z-index\"\n"
    2814             : "        ARG\n"
    2815             : "          INTEGER \"\" I:" + std::to_string(b) + "\n"
    2816             : "  COMPONENT_VALUE\n"
    2817             : "    ARG\n"
    2818             : "      IDENTIFIER \"i\"\n"
    2819             : "    OPEN_CURLYBRACKET B:true\n"
    2820             : "      DECLARATION \"z-index\"\n"
    2821             : "        ARG\n"
    2822             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(alpha / 255.0, false) + "\n"
    2823             : // component(frgb())
    2824             : "  COMPONENT_VALUE\n"
    2825             : "    ARG\n"
    2826             : "      IDENTIFIER \"div\"\n"
    2827             : "    OPEN_CURLYBRACKET B:true\n"
    2828             : "      DECLARATION \"z-index\"\n"
    2829             : "        ARG\n"
    2830             : "          INTEGER \"\" I:" + std::to_string(r) + "\n"
    2831             : "  COMPONENT_VALUE\n"
    2832             : "    ARG\n"
    2833             : "      IDENTIFIER \"span\"\n"
    2834             : "    OPEN_CURLYBRACKET B:true\n"
    2835             : "      DECLARATION \"z-index\"\n"
    2836             : "        ARG\n"
    2837             : "          INTEGER \"\" I:" + std::to_string(g) + "\n"
    2838             : "  COMPONENT_VALUE\n"
    2839             : "    ARG\n"
    2840             : "      IDENTIFIER \"p\"\n"
    2841             : "    OPEN_CURLYBRACKET B:true\n"
    2842             : "      DECLARATION \"z-index\"\n"
    2843             : "        ARG\n"
    2844             : "          INTEGER \"\" I:" + std::to_string(b) + "\n"
    2845             : "  COMPONENT_VALUE\n"
    2846             : "    ARG\n"
    2847             : "      IDENTIFIER \"i\"\n"
    2848             : "    OPEN_CURLYBRACKET B:true\n"
    2849             : "      DECLARATION \"z-index\"\n"
    2850             : "        ARG\n"
    2851             : "          DECIMAL_NUMBER \"\" D:1\n"
    2852             : // component(frgba(frgb(), alpha))
    2853             : "  COMPONENT_VALUE\n"
    2854             : "    ARG\n"
    2855             : "      IDENTIFIER \"div\"\n"
    2856             : "    OPEN_CURLYBRACKET B:true\n"
    2857             : "      DECLARATION \"z-index\"\n"
    2858             : "        ARG\n"
    2859             : "          INTEGER \"\" I:" + std::to_string(r) + "\n"
    2860             : "  COMPONENT_VALUE\n"
    2861             : "    ARG\n"
    2862             : "      IDENTIFIER \"span\"\n"
    2863             : "    OPEN_CURLYBRACKET B:true\n"
    2864             : "      DECLARATION \"z-index\"\n"
    2865             : "        ARG\n"
    2866             : "          INTEGER \"\" I:" + std::to_string(g) + "\n"
    2867             : "  COMPONENT_VALUE\n"
    2868             : "    ARG\n"
    2869             : "      IDENTIFIER \"p\"\n"
    2870             : "    OPEN_CURLYBRACKET B:true\n"
    2871             : "      DECLARATION \"z-index\"\n"
    2872             : "        ARG\n"
    2873             : "          INTEGER \"\" I:" + std::to_string(b) + "\n"
    2874             : "  COMPONENT_VALUE\n"
    2875             : "    ARG\n"
    2876             : "      IDENTIFIER \"i\"\n"
    2877             : "    OPEN_CURLYBRACKET B:true\n"
    2878             : "      DECLARATION \"z-index\"\n"
    2879             : "        ARG\n"
    2880             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(alpha / 255.0, false) + "\n"
    2881             : + csspp_test::get_close_comment(true)
    2882             : 
    2883             :                                 );
    2884             : 
    2885        1312 :                             std::stringstream assembler_out;
    2886        1312 :                             csspp::assembler a(assembler_out);
    2887        1312 :                             a.output(n, csspp::output_mode_t::COMPRESSED);
    2888             : 
    2889             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    2890             : 
    2891        1312 :                             CATCH_REQUIRE(assembler_out.str() ==
    2892             : 
    2893             : // rgba()
    2894             : std::string("div{z-index:") + std::to_string(r) + "}"
    2895             : "span{z-index:" + std::to_string(g) + "}"
    2896             : "p{z-index:" + std::to_string(b) + "}"
    2897             : "i{z-index:" + csspp::decimal_number_to_string(alpha / 255.0, true) + "}"
    2898             : // rbg()
    2899             : "div{z-index:" + std::to_string(r) + "}"
    2900             : "span{z-index:" + std::to_string(g) + "}"
    2901             : "p{z-index:" + std::to_string(b) + "}"
    2902             : "i{z-index:1}"
    2903             : // rgba(rgb(), alpha)
    2904             : "div{z-index:" + std::to_string(r) + "}"
    2905             : "span{z-index:" + std::to_string(g) + "}"
    2906             : "p{z-index:" + std::to_string(b) + "}"
    2907             : "i{z-index:" + csspp::decimal_number_to_string(alpha / 255.0, true) + "}"
    2908             : // frgba()
    2909             : "div{z-index:" + std::to_string(r) + "}"
    2910             : "span{z-index:" + std::to_string(g) + "}"
    2911             : "p{z-index:" + std::to_string(b) + "}"
    2912             : "i{z-index:" + csspp::decimal_number_to_string(alpha / 255.0, true) + "}"
    2913             : // frgb()
    2914             : "div{z-index:" + std::to_string(r) + "}"
    2915             : "span{z-index:" + std::to_string(g) + "}"
    2916             : "p{z-index:" + std::to_string(b) + "}"
    2917             : "i{z-index:1}"
    2918             : // frgba(frgb(), alpha)
    2919             : "div{z-index:" + std::to_string(r) + "}"
    2920             : "span{z-index:" + std::to_string(g) + "}"
    2921             : "p{z-index:" + std::to_string(b) + "}"
    2922             : "i{z-index:" + csspp::decimal_number_to_string(alpha / 255.0, true) + "}"
    2923             : "\n"
    2924             : + csspp_test::get_close_comment()
    2925             : 
    2926             :                                     );
    2927             : 
    2928        1312 :                             CATCH_REQUIRE(c.get_root() == n);
    2929        1312 :                         }
    2930             :                     }
    2931             :                 }
    2932             :             }
    2933             :         }
    2934             :     }
    2935           2 :     CATCH_END_SECTION()
    2936             : 
    2937           2 :     CATCH_START_SECTION("rgb/rgba/frgb/frgba from #color")
    2938             :     {
    2939           1 :         std::stringstream ss;
    2940             :         ss << "div  { z-index: red(  rgba( darkolivegreen, 0.5)); }\n"
    2941             :            << "span { z-index: green(rgba( darkolivegreen, 0.5)); }\n"
    2942             :            << "p    { z-index: blue( rgba( darkolivegreen, 0.5)); }\n"
    2943             :            << "i    { z-index: alpha(rgba( darkolivegreen, 0.5)); }\n"
    2944             :            << "div  { z-index: red(  rgb(  deeppink)); }\n"
    2945             :            << "span { z-index: green(rgb(  deeppink)); }\n"
    2946             :            << "p    { z-index: blue( rgb(  deeppink)); }\n"
    2947             :            << "i    { z-index: alpha(rgb(  deeppink)); }\n"
    2948             :            << "div  { z-index: red(  frgba(ghostwhite, 0.5)); }\n"
    2949             :            << "span { z-index: green(frgba(ghostwhite, 0.5)); }\n"
    2950             :            << "p    { z-index: blue( frgba(ghostwhite, 0.5)); }\n"
    2951             :            << "i    { z-index: alpha(frgba(ghostwhite, 0.5)); }\n"
    2952             :            << "div  { z-index: red(  frgb( hotpink)); }\n"
    2953             :            << "span { z-index: green(frgb( hotpink)); }\n"
    2954             :            << "p    { z-index: blue( frgb( hotpink)); }\n"
    2955           1 :            << "i    { z-index: alpha(frgb( hotpink)); }\n";
    2956           3 :         csspp::position pos("test.css");
    2957           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    2958             : 
    2959           2 :         csspp::parser p(l);
    2960             : 
    2961           1 :         csspp::node::pointer_t n(p.stylesheet());
    2962             : 
    2963           1 :         csspp::compiler c;
    2964           1 :         c.set_root(n);
    2965           1 :         c.set_date_time_variables(csspp_test::get_now());
    2966           1 :         c.add_path(csspp_test::get_script_path());
    2967           1 :         c.add_path(csspp_test::get_version_script_path());
    2968             : 
    2969           1 :         c.compile(false);
    2970             : 
    2971             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    2972             : 
    2973             :         // to verify that the result is still an INTEGER we have to
    2974             :         // test the root node here
    2975           1 :         std::stringstream compiler_out;
    2976           1 :         compiler_out << *n;
    2977           1 :         VERIFY_TREES(compiler_out.str(),
    2978             : 
    2979             : "LIST\n"
    2980             : + csspp_test::get_default_variables() +
    2981             : // component(rgba(darkolivegreen, 0.5))
    2982             : "  COMPONENT_VALUE\n"
    2983             : "    ARG\n"
    2984             : "      IDENTIFIER \"div\"\n"
    2985             : "    OPEN_CURLYBRACKET B:true\n"
    2986             : "      DECLARATION \"z-index\"\n"
    2987             : "        ARG\n"
    2988             : "          INTEGER \"\" I:85\n"
    2989             : "  COMPONENT_VALUE\n"
    2990             : "    ARG\n"
    2991             : "      IDENTIFIER \"span\"\n"
    2992             : "    OPEN_CURLYBRACKET B:true\n"
    2993             : "      DECLARATION \"z-index\"\n"
    2994             : "        ARG\n"
    2995             : "          INTEGER \"\" I:107\n"
    2996             : "  COMPONENT_VALUE\n"
    2997             : "    ARG\n"
    2998             : "      IDENTIFIER \"p\"\n"
    2999             : "    OPEN_CURLYBRACKET B:true\n"
    3000             : "      DECLARATION \"z-index\"\n"
    3001             : "        ARG\n"
    3002             : "          INTEGER \"\" I:47\n"
    3003             : "  COMPONENT_VALUE\n"
    3004             : "    ARG\n"
    3005             : "      IDENTIFIER \"i\"\n"
    3006             : "    OPEN_CURLYBRACKET B:true\n"
    3007             : "      DECLARATION \"z-index\"\n"
    3008             : "        ARG\n"
    3009             : "          DECIMAL_NUMBER \"\" D:0.5\n"
    3010             : // component(rgb(deeppink))
    3011             : "  COMPONENT_VALUE\n"
    3012             : "    ARG\n"
    3013             : "      IDENTIFIER \"div\"\n"
    3014             : "    OPEN_CURLYBRACKET B:true\n"
    3015             : "      DECLARATION \"z-index\"\n"
    3016             : "        ARG\n"
    3017             : "          INTEGER \"\" I:255\n"
    3018             : "  COMPONENT_VALUE\n"
    3019             : "    ARG\n"
    3020             : "      IDENTIFIER \"span\"\n"
    3021             : "    OPEN_CURLYBRACKET B:true\n"
    3022             : "      DECLARATION \"z-index\"\n"
    3023             : "        ARG\n"
    3024             : "          INTEGER \"\" I:20\n"
    3025             : "  COMPONENT_VALUE\n"
    3026             : "    ARG\n"
    3027             : "      IDENTIFIER \"p\"\n"
    3028             : "    OPEN_CURLYBRACKET B:true\n"
    3029             : "      DECLARATION \"z-index\"\n"
    3030             : "        ARG\n"
    3031             : "          INTEGER \"\" I:147\n"
    3032             : "  COMPONENT_VALUE\n"
    3033             : "    ARG\n"
    3034             : "      IDENTIFIER \"i\"\n"
    3035             : "    OPEN_CURLYBRACKET B:true\n"
    3036             : "      DECLARATION \"z-index\"\n"
    3037             : "        ARG\n"
    3038             : "          DECIMAL_NUMBER \"\" D:1\n"
    3039             : // component(frgba(ghostwhite, 0.5))
    3040             : "  COMPONENT_VALUE\n"
    3041             : "    ARG\n"
    3042             : "      IDENTIFIER \"div\"\n"
    3043             : "    OPEN_CURLYBRACKET B:true\n"
    3044             : "      DECLARATION \"z-index\"\n"
    3045             : "        ARG\n"
    3046             : "          INTEGER \"\" I:248\n"
    3047             : "  COMPONENT_VALUE\n"
    3048             : "    ARG\n"
    3049             : "      IDENTIFIER \"span\"\n"
    3050             : "    OPEN_CURLYBRACKET B:true\n"
    3051             : "      DECLARATION \"z-index\"\n"
    3052             : "        ARG\n"
    3053             : "          INTEGER \"\" I:248\n"
    3054             : "  COMPONENT_VALUE\n"
    3055             : "    ARG\n"
    3056             : "      IDENTIFIER \"p\"\n"
    3057             : "    OPEN_CURLYBRACKET B:true\n"
    3058             : "      DECLARATION \"z-index\"\n"
    3059             : "        ARG\n"
    3060             : "          INTEGER \"\" I:255\n"
    3061             : "  COMPONENT_VALUE\n"
    3062             : "    ARG\n"
    3063             : "      IDENTIFIER \"i\"\n"
    3064             : "    OPEN_CURLYBRACKET B:true\n"
    3065             : "      DECLARATION \"z-index\"\n"
    3066             : "        ARG\n"
    3067             : "          DECIMAL_NUMBER \"\" D:0.5\n"
    3068             : // component(frgb(hotpink))
    3069             : "  COMPONENT_VALUE\n"
    3070             : "    ARG\n"
    3071             : "      IDENTIFIER \"div\"\n"
    3072             : "    OPEN_CURLYBRACKET B:true\n"
    3073             : "      DECLARATION \"z-index\"\n"
    3074             : "        ARG\n"
    3075             : "          INTEGER \"\" I:255\n"
    3076             : "  COMPONENT_VALUE\n"
    3077             : "    ARG\n"
    3078             : "      IDENTIFIER \"span\"\n"
    3079             : "    OPEN_CURLYBRACKET B:true\n"
    3080             : "      DECLARATION \"z-index\"\n"
    3081             : "        ARG\n"
    3082             : "          INTEGER \"\" I:105\n"
    3083             : "  COMPONENT_VALUE\n"
    3084             : "    ARG\n"
    3085             : "      IDENTIFIER \"p\"\n"
    3086             : "    OPEN_CURLYBRACKET B:true\n"
    3087             : "      DECLARATION \"z-index\"\n"
    3088             : "        ARG\n"
    3089             : "          INTEGER \"\" I:180\n"
    3090             : "  COMPONENT_VALUE\n"
    3091             : "    ARG\n"
    3092             : "      IDENTIFIER \"i\"\n"
    3093             : "    OPEN_CURLYBRACKET B:true\n"
    3094             : "      DECLARATION \"z-index\"\n"
    3095             : "        ARG\n"
    3096             : "          DECIMAL_NUMBER \"\" D:1\n"
    3097             : + csspp_test::get_close_comment(true)
    3098             : 
    3099             :             );
    3100             : 
    3101           1 :         std::stringstream assembler_out;
    3102           1 :         csspp::assembler a(assembler_out);
    3103           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3104             : 
    3105             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3106             : 
    3107           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3108             : 
    3109             : // rgba(darkolivegreen, 0.5)
    3110             : "div{z-index:85}"
    3111             : "span{z-index:107}"
    3112             : "p{z-index:47}"
    3113             : "i{z-index:.5}"
    3114             : // rbg(deeppink)
    3115             : "div{z-index:255}"
    3116             : "span{z-index:20}"
    3117             : "p{z-index:147}"
    3118             : "i{z-index:1}"
    3119             : // rgba(ghostwhite, 0.5)
    3120             : "div{z-index:248}"
    3121             : "span{z-index:248}"
    3122             : "p{z-index:255}"
    3123             : "i{z-index:.5}"
    3124             : // frgb(hotpink)
    3125             : "div{z-index:255}"
    3126             : "span{z-index:105}"
    3127             : "p{z-index:180}"
    3128             : "i{z-index:1}"
    3129             : "\n"
    3130             : + csspp_test::get_close_comment()
    3131             : 
    3132             :                 );
    3133             : 
    3134           1 :         CATCH_REQUIRE(c.get_root() == n);
    3135           1 :     }
    3136           2 :     CATCH_END_SECTION()
    3137             : 
    3138             :     // no error left over
    3139           2 :     VERIFY_ERRORS("");
    3140           2 : }
    3141             : 
    3142           2 : CATCH_TEST_CASE("Expression hue()/saturation()/lightness()/alpha()", "[expression] [internal-functions] [hue] [saturation] [lightness] [alpha]")
    3143             : {
    3144           2 :     CATCH_START_SECTION("check color components")
    3145             :     {
    3146           7 :         for(int h(46); h < 180; h += rand() % 50 + 1)
    3147             :         {
    3148          49 :             for(int s(rand() % 25 + 1); s < 100; s += rand() % 25 + 1)
    3149             :             {
    3150         349 :                 for(int l(rand() % 25 + 1); l < 100; l += rand() % 25 + 1)
    3151             :                 {
    3152        2022 :                     for(int alpha(rand() % 25); alpha < 256; alpha += rand() % 100 + 1)
    3153             :                     {
    3154        1716 :                         std::stringstream ss;
    3155        1716 :                         ss << "div { z-index: hue(hsla("
    3156             :                            << h
    3157        1716 :                            << "deg, "
    3158             :                            << s
    3159        1716 :                            << "%, "
    3160             :                            << l
    3161        1716 :                            << "%, "
    3162        1716 :                            << alpha / 255.0
    3163             :                            << ")); }\n"
    3164        1716 :                            << "span { z-index: saturation(hsla("
    3165             :                            << h
    3166        1716 :                            << ", "
    3167             :                            << s
    3168        1716 :                            << "%, "
    3169             :                            << l
    3170        1716 :                            << "%, "
    3171        1716 :                            << alpha / 255.0
    3172             :                            << ")); }\n"
    3173        1716 :                            << "p { z-index: lightness(hsla("
    3174             :                            << h
    3175        1716 :                            << ", "
    3176             :                            << s
    3177        1716 :                            << "%, "
    3178             :                            << l
    3179        1716 :                            << "%, "
    3180        1716 :                            << alpha / 255.0
    3181             :                            << ")); }\n"
    3182        1716 :                            << "i { z-index: alpha(hsla("
    3183             :                            << h
    3184        1716 :                            << ", "
    3185             :                            << s
    3186        1716 :                            << "%, "
    3187             :                            << l
    3188        1716 :                            << "%, "
    3189        1716 :                            << alpha / 255.0
    3190             :                            << ")); }\n"
    3191        1716 :                            << "div { z-index: hue(hsl("
    3192             :                            << h
    3193        1716 :                            << "deg, "
    3194             :                            << s
    3195        1716 :                            << "%, "
    3196             :                            << l
    3197             :                            << "%)); }\n"
    3198        1716 :                            << "span { z-index: saturation(hsl("
    3199             :                            << h
    3200        1716 :                            << ", "
    3201             :                            << s
    3202        1716 :                            << "%, "
    3203             :                            << l
    3204             :                            << "%)); }\n"
    3205        1716 :                            << "p { z-index: lightness(hsl("
    3206             :                            << h
    3207        1716 :                            << "deg, "
    3208             :                            << s
    3209        1716 :                            << "%, "
    3210             :                            << l
    3211             :                            << "%)); }\n"
    3212        1716 :                            << "i { z-index: alpha(hsl("
    3213             :                            << h
    3214        1716 :                            << ", "
    3215             :                            << s
    3216        1716 :                            << "%, "
    3217             :                            << l
    3218        1716 :                            << "%)); }\n";
    3219        5148 :                         csspp::position pos("test.css");
    3220        1716 :                         csspp::lexer::pointer_t lex(new csspp::lexer(ss, pos));
    3221             : 
    3222        3432 :                         csspp::parser p(lex);
    3223             : 
    3224        1716 :                         csspp::node::pointer_t n(p.stylesheet());
    3225             : 
    3226        1716 :                         csspp::compiler c;
    3227        1716 :                         c.set_root(n);
    3228        1716 :                         c.set_date_time_variables(csspp_test::get_now());
    3229        1716 :                         c.add_path(csspp_test::get_script_path());
    3230        1716 :                         c.add_path(csspp_test::get_version_script_path());
    3231             : 
    3232        1716 :                         c.compile(false);
    3233             : 
    3234             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3235             : 
    3236             :                         // the h,s,l may come back out slight different
    3237             :                         // so we get the "fixed" value to check in our
    3238             :                         // returned value
    3239        1716 :                         csspp::color col;
    3240        1716 :                         col.set_hsl(fmod(h, 360.0) * M_PI / 180.0, s / 100.0, l / 100.0, alpha);
    3241        1716 :                         csspp::color_component_t h1, s1, l1, alpha1;
    3242        1716 :                         col.get_hsl(h1, s1, l1, alpha1);
    3243             : 
    3244             :                         // to verify that the result is still an INTEGER we have to
    3245             :                         // test the root node here
    3246        1716 :                         std::stringstream compiler_out;
    3247        1716 :                         compiler_out << *n;
    3248        1716 :                         VERIFY_TREES(compiler_out.str(),
    3249             : 
    3250             : "LIST\n"
    3251             : + csspp_test::get_default_variables() +
    3252             : // component(hsla())
    3253             : "  COMPONENT_VALUE\n"
    3254             : "    ARG\n"
    3255             : "      IDENTIFIER \"div\"\n"
    3256             : "    OPEN_CURLYBRACKET B:true\n"
    3257             : "      DECLARATION \"z-index\"\n"
    3258             : "        ARG\n"
    3259             : "          DECIMAL_NUMBER \"deg\" D:" + csspp::decimal_number_to_string(h1 * 180.0 / M_PI, false) + "\n"
    3260             : "  COMPONENT_VALUE\n"
    3261             : "    ARG\n"
    3262             : "      IDENTIFIER \"span\"\n"
    3263             : "    OPEN_CURLYBRACKET B:true\n"
    3264             : "      DECLARATION \"z-index\"\n"
    3265             : "        ARG\n"
    3266             : "          PERCENT D:" + csspp::decimal_number_to_string(s1, false) + "\n"
    3267             : "  COMPONENT_VALUE\n"
    3268             : "    ARG\n"
    3269             : "      IDENTIFIER \"p\"\n"
    3270             : "    OPEN_CURLYBRACKET B:true\n"
    3271             : "      DECLARATION \"z-index\"\n"
    3272             : "        ARG\n"
    3273             : "          PERCENT D:" + csspp::decimal_number_to_string(l1, false) + "\n"
    3274             : "  COMPONENT_VALUE\n"
    3275             : "    ARG\n"
    3276             : "      IDENTIFIER \"i\"\n"
    3277             : "    OPEN_CURLYBRACKET B:true\n"
    3278             : "      DECLARATION \"z-index\"\n"
    3279             : "        ARG\n"
    3280             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(alpha / 255.0, false) + "\n"
    3281             : // component(hsl())
    3282             : "  COMPONENT_VALUE\n"
    3283             : "    ARG\n"
    3284             : "      IDENTIFIER \"div\"\n"
    3285             : "    OPEN_CURLYBRACKET B:true\n"
    3286             : "      DECLARATION \"z-index\"\n"
    3287             : "        ARG\n"
    3288             : "          DECIMAL_NUMBER \"deg\" D:" + csspp::decimal_number_to_string(h1 * 180.0 / M_PI, false) + "\n"
    3289             : "  COMPONENT_VALUE\n"
    3290             : "    ARG\n"
    3291             : "      IDENTIFIER \"span\"\n"
    3292             : "    OPEN_CURLYBRACKET B:true\n"
    3293             : "      DECLARATION \"z-index\"\n"
    3294             : "        ARG\n"
    3295             : "          PERCENT D:" + csspp::decimal_number_to_string(s1, false) + "\n"
    3296             : "  COMPONENT_VALUE\n"
    3297             : "    ARG\n"
    3298             : "      IDENTIFIER \"p\"\n"
    3299             : "    OPEN_CURLYBRACKET B:true\n"
    3300             : "      DECLARATION \"z-index\"\n"
    3301             : "        ARG\n"
    3302             : "          PERCENT D:" + csspp::decimal_number_to_string(l1, false) + "\n"
    3303             : "  COMPONENT_VALUE\n"
    3304             : "    ARG\n"
    3305             : "      IDENTIFIER \"i\"\n"
    3306             : "    OPEN_CURLYBRACKET B:true\n"
    3307             : "      DECLARATION \"z-index\"\n"
    3308             : "        ARG\n"
    3309             : "          DECIMAL_NUMBER \"\" D:1\n"
    3310             : + csspp_test::get_close_comment(true)
    3311             : 
    3312             :                             );
    3313             : 
    3314        1716 :                         std::stringstream assembler_out;
    3315        1716 :                         csspp::assembler a(assembler_out);
    3316        1716 :                         a.output(n, csspp::output_mode_t::COMPRESSED);
    3317             : 
    3318             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3319             : 
    3320        1716 :                         CATCH_REQUIRE(assembler_out.str() ==
    3321             : 
    3322             : // hsla()
    3323             : std::string("div{z-index:") + csspp::decimal_number_to_string(h1 * 180.0 / M_PI, true) + "deg}"
    3324             : "span{z-index:" + std::to_string(s) + "%}"
    3325             : "p{z-index:" + std::to_string(l) + "%}"
    3326             : "i{z-index:" + csspp::decimal_number_to_string(alpha / 255.0, true) + "}"
    3327             : // hsl()
    3328             : "div{z-index:" + csspp::decimal_number_to_string(h1 * 180.0 / M_PI, true) + "deg}"
    3329             : "span{z-index:" + std::to_string(s) + "%}"
    3330             : "p{z-index:" + std::to_string(l) + "%}"
    3331             : "i{z-index:1}"
    3332             : "\n"
    3333             : + csspp_test::get_close_comment()
    3334             : 
    3335             :                                 );
    3336             : 
    3337        1716 :                         CATCH_REQUIRE(c.get_root() == n);
    3338        1716 :                     }
    3339             :                 }
    3340             :             }
    3341             :         }
    3342             :     }
    3343           2 :     CATCH_END_SECTION()
    3344             : 
    3345           2 :     CATCH_START_SECTION("rgb/rgba/frgb/frgba from #color")
    3346             :     {
    3347           1 :         std::stringstream ss;
    3348             :         ss << "div  { z-index: red(  rgba( darkolivegreen, 0.5)); }\n"
    3349             :            << "span { z-index: green(rgba( darkolivegreen, 0.5)); }\n"
    3350             :            << "p    { z-index: blue( rgba( darkolivegreen, 0.5)); }\n"
    3351             :            << "i    { z-index: alpha(rgba( darkolivegreen, 0.5)); }\n"
    3352             :            << "div  { z-index: red(  rgb(  deeppink)); }\n"
    3353             :            << "span { z-index: green(rgb(  deeppink)); }\n"
    3354             :            << "p    { z-index: blue( rgb(  deeppink)); }\n"
    3355             :            << "i    { z-index: alpha(rgb(  deeppink)); }\n"
    3356             :            << "div  { z-index: red(  frgba(ghostwhite, 0.5)); }\n"
    3357             :            << "span { z-index: green(frgba(ghostwhite, 0.5)); }\n"
    3358             :            << "p    { z-index: blue( frgba(ghostwhite, 0.5)); }\n"
    3359             :            << "i    { z-index: alpha(frgba(ghostwhite, 0.5)); }\n"
    3360             :            << "div  { z-index: red(  frgb( hotpink)); }\n"
    3361             :            << "span { z-index: green(frgb( hotpink)); }\n"
    3362             :            << "p    { z-index: blue( frgb( hotpink)); }\n"
    3363           1 :            << "i    { z-index: alpha(frgb( hotpink)); }\n";
    3364           3 :         csspp::position pos("test.css");
    3365           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3366             : 
    3367           2 :         csspp::parser p(l);
    3368             : 
    3369           1 :         csspp::node::pointer_t n(p.stylesheet());
    3370             : 
    3371           1 :         csspp::compiler c;
    3372           1 :         c.set_root(n);
    3373           1 :         c.set_date_time_variables(csspp_test::get_now());
    3374           1 :         c.add_path(csspp_test::get_script_path());
    3375           1 :         c.add_path(csspp_test::get_version_script_path());
    3376             : 
    3377           1 :         c.compile(false);
    3378             : 
    3379             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3380             : 
    3381             :         // to verify that the result is still an INTEGER we have to
    3382             :         // test the root node here
    3383           1 :         std::stringstream compiler_out;
    3384           1 :         compiler_out << *n;
    3385           1 :         VERIFY_TREES(compiler_out.str(),
    3386             : 
    3387             : "LIST\n"
    3388             : + csspp_test::get_default_variables() +
    3389             : // component(rgba(darkolivegreen, 0.5))
    3390             : "  COMPONENT_VALUE\n"
    3391             : "    ARG\n"
    3392             : "      IDENTIFIER \"div\"\n"
    3393             : "    OPEN_CURLYBRACKET B:true\n"
    3394             : "      DECLARATION \"z-index\"\n"
    3395             : "        ARG\n"
    3396             : "          INTEGER \"\" I:85\n"
    3397             : "  COMPONENT_VALUE\n"
    3398             : "    ARG\n"
    3399             : "      IDENTIFIER \"span\"\n"
    3400             : "    OPEN_CURLYBRACKET B:true\n"
    3401             : "      DECLARATION \"z-index\"\n"
    3402             : "        ARG\n"
    3403             : "          INTEGER \"\" I:107\n"
    3404             : "  COMPONENT_VALUE\n"
    3405             : "    ARG\n"
    3406             : "      IDENTIFIER \"p\"\n"
    3407             : "    OPEN_CURLYBRACKET B:true\n"
    3408             : "      DECLARATION \"z-index\"\n"
    3409             : "        ARG\n"
    3410             : "          INTEGER \"\" I:47\n"
    3411             : "  COMPONENT_VALUE\n"
    3412             : "    ARG\n"
    3413             : "      IDENTIFIER \"i\"\n"
    3414             : "    OPEN_CURLYBRACKET B:true\n"
    3415             : "      DECLARATION \"z-index\"\n"
    3416             : "        ARG\n"
    3417             : "          DECIMAL_NUMBER \"\" D:0.5\n"
    3418             : // component(rgb(deeppink))
    3419             : "  COMPONENT_VALUE\n"
    3420             : "    ARG\n"
    3421             : "      IDENTIFIER \"div\"\n"
    3422             : "    OPEN_CURLYBRACKET B:true\n"
    3423             : "      DECLARATION \"z-index\"\n"
    3424             : "        ARG\n"
    3425             : "          INTEGER \"\" I:255\n"
    3426             : "  COMPONENT_VALUE\n"
    3427             : "    ARG\n"
    3428             : "      IDENTIFIER \"span\"\n"
    3429             : "    OPEN_CURLYBRACKET B:true\n"
    3430             : "      DECLARATION \"z-index\"\n"
    3431             : "        ARG\n"
    3432             : "          INTEGER \"\" I:20\n"
    3433             : "  COMPONENT_VALUE\n"
    3434             : "    ARG\n"
    3435             : "      IDENTIFIER \"p\"\n"
    3436             : "    OPEN_CURLYBRACKET B:true\n"
    3437             : "      DECLARATION \"z-index\"\n"
    3438             : "        ARG\n"
    3439             : "          INTEGER \"\" I:147\n"
    3440             : "  COMPONENT_VALUE\n"
    3441             : "    ARG\n"
    3442             : "      IDENTIFIER \"i\"\n"
    3443             : "    OPEN_CURLYBRACKET B:true\n"
    3444             : "      DECLARATION \"z-index\"\n"
    3445             : "        ARG\n"
    3446             : "          DECIMAL_NUMBER \"\" D:1\n"
    3447             : // component(frgba(ghostwhite, 0.5))
    3448             : "  COMPONENT_VALUE\n"
    3449             : "    ARG\n"
    3450             : "      IDENTIFIER \"div\"\n"
    3451             : "    OPEN_CURLYBRACKET B:true\n"
    3452             : "      DECLARATION \"z-index\"\n"
    3453             : "        ARG\n"
    3454             : "          INTEGER \"\" I:248\n"
    3455             : "  COMPONENT_VALUE\n"
    3456             : "    ARG\n"
    3457             : "      IDENTIFIER \"span\"\n"
    3458             : "    OPEN_CURLYBRACKET B:true\n"
    3459             : "      DECLARATION \"z-index\"\n"
    3460             : "        ARG\n"
    3461             : "          INTEGER \"\" I:248\n"
    3462             : "  COMPONENT_VALUE\n"
    3463             : "    ARG\n"
    3464             : "      IDENTIFIER \"p\"\n"
    3465             : "    OPEN_CURLYBRACKET B:true\n"
    3466             : "      DECLARATION \"z-index\"\n"
    3467             : "        ARG\n"
    3468             : "          INTEGER \"\" I:255\n"
    3469             : "  COMPONENT_VALUE\n"
    3470             : "    ARG\n"
    3471             : "      IDENTIFIER \"i\"\n"
    3472             : "    OPEN_CURLYBRACKET B:true\n"
    3473             : "      DECLARATION \"z-index\"\n"
    3474             : "        ARG\n"
    3475             : "          DECIMAL_NUMBER \"\" D:0.5\n"
    3476             : // component(frgb(hotpink))
    3477             : "  COMPONENT_VALUE\n"
    3478             : "    ARG\n"
    3479             : "      IDENTIFIER \"div\"\n"
    3480             : "    OPEN_CURLYBRACKET B:true\n"
    3481             : "      DECLARATION \"z-index\"\n"
    3482             : "        ARG\n"
    3483             : "          INTEGER \"\" I:255\n"
    3484             : "  COMPONENT_VALUE\n"
    3485             : "    ARG\n"
    3486             : "      IDENTIFIER \"span\"\n"
    3487             : "    OPEN_CURLYBRACKET B:true\n"
    3488             : "      DECLARATION \"z-index\"\n"
    3489             : "        ARG\n"
    3490             : "          INTEGER \"\" I:105\n"
    3491             : "  COMPONENT_VALUE\n"
    3492             : "    ARG\n"
    3493             : "      IDENTIFIER \"p\"\n"
    3494             : "    OPEN_CURLYBRACKET B:true\n"
    3495             : "      DECLARATION \"z-index\"\n"
    3496             : "        ARG\n"
    3497             : "          INTEGER \"\" I:180\n"
    3498             : "  COMPONENT_VALUE\n"
    3499             : "    ARG\n"
    3500             : "      IDENTIFIER \"i\"\n"
    3501             : "    OPEN_CURLYBRACKET B:true\n"
    3502             : "      DECLARATION \"z-index\"\n"
    3503             : "        ARG\n"
    3504             : "          DECIMAL_NUMBER \"\" D:1\n"
    3505             : + csspp_test::get_close_comment(true)
    3506             : 
    3507             :             );
    3508             : 
    3509           1 :         std::stringstream assembler_out;
    3510           1 :         csspp::assembler a(assembler_out);
    3511           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    3512             : 
    3513             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3514             : 
    3515           1 :         CATCH_REQUIRE(assembler_out.str() ==
    3516             : 
    3517             : // rgba(darkolivegreen, 0.5)
    3518             : "div{z-index:85}"
    3519             : "span{z-index:107}"
    3520             : "p{z-index:47}"
    3521             : "i{z-index:.5}"
    3522             : // rbg(deeppink)
    3523             : "div{z-index:255}"
    3524             : "span{z-index:20}"
    3525             : "p{z-index:147}"
    3526             : "i{z-index:1}"
    3527             : // rgba(ghostwhite, 0.5)
    3528             : "div{z-index:248}"
    3529             : "span{z-index:248}"
    3530             : "p{z-index:255}"
    3531             : "i{z-index:.5}"
    3532             : // frgb(hotpink)
    3533             : "div{z-index:255}"
    3534             : "span{z-index:105}"
    3535             : "p{z-index:180}"
    3536             : "i{z-index:1}"
    3537             : "\n"
    3538             : + csspp_test::get_close_comment()
    3539             : 
    3540             :                 );
    3541             : 
    3542           1 :         CATCH_REQUIRE(c.get_root() == n);
    3543           1 :     }
    3544           2 :     CATCH_END_SECTION()
    3545             : 
    3546             :     // no error left over
    3547           2 :     VERIFY_ERRORS("");
    3548           2 : }
    3549             : 
    3550           4 : CATCH_TEST_CASE("Expression function_exists()/variable_exists()/global_variable_exists()", "[expression] [internal-functions] [function-exists] [variable-exists] [global-variable-exists]")
    3551             : {
    3552           4 :     CATCH_START_SECTION("check existance of internal functions")
    3553             :     {
    3554             :         // list of internal functions, they all must return true
    3555             :         // those that start with '*' are colors that are viewed
    3556             :         // as functions when followed by '(' but color otherwise
    3557           1 :         char const * internal_functions[] =
    3558             :         {
    3559             :             "abs",
    3560             :             "acos",
    3561             :             "alpha",
    3562             :             "asin",
    3563             :             "atan",
    3564             :             "*blue",
    3565             :             "ceil",
    3566             :             "cos",
    3567             :             "decimal_number",
    3568             :             "floor",
    3569             :             "frgb",
    3570             :             "frgba",
    3571             :             "function_exists",
    3572             :             "global_variable_exists",
    3573             :             "*green",
    3574             :             "hsl",
    3575             :             "hsla",
    3576             :             "hue",
    3577             :             "identifier",
    3578             :             "if",
    3579             :             "integer",
    3580             :             "inspect",
    3581             :             "lightness",
    3582             :             "log",
    3583             :             "max",
    3584             :             "min",
    3585             :             "not",
    3586             :             "percentage",
    3587             :             "random",
    3588             :             "*red",
    3589             :             "rgb",
    3590             :             "rgba",
    3591             :             "round",
    3592             :             "saturation",
    3593             :             "sign",
    3594             :             "sin",
    3595             :             "sqrt",
    3596             :             "string",
    3597             :             "str_length",
    3598             :             "*tan",
    3599             :             "type_of",
    3600             :             "unique_id",
    3601             :             "unit",
    3602             :             "variable_exists"
    3603             :         };
    3604             : 
    3605          45 :         for(size_t idx(0); idx < sizeof(internal_functions) / sizeof(internal_functions[0]); ++idx)
    3606             :         {
    3607          44 :             bool use_string(false);
    3608          44 :             char const *name = internal_functions[idx];
    3609          44 :             if(*name == '*')
    3610             :             {
    3611           4 :                 use_string = true;
    3612           4 :                 ++name;
    3613             :             }
    3614          44 :             std::stringstream ss;
    3615             :             ss << "div { z-index: function_exists("
    3616             :                << (use_string ? "\"" : "")
    3617             :                << name
    3618             :                << (use_string ? "\"" : "")
    3619             :                << ") ? decimal_number(\"3.14\") : 17 }\n"
    3620             :                << "div { z-index: function_exists(\""
    3621             :                << name
    3622             :                << "\") ? decimal_number(\"3.14\") : 17 }\n"
    3623             :                << "div { z-index: function_exists(\"but_not_"
    3624             :                << name
    3625          44 :                << "\") ? decimal_number(\"3.14\") : 17 }\n";
    3626             : //std::cerr << "*** input = [" << ss.str() << "]\n";
    3627         132 :             csspp::position pos("test.css");
    3628          44 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3629             : 
    3630          88 :             csspp::parser p(l);
    3631             : 
    3632          44 :             csspp::node::pointer_t n(p.stylesheet());
    3633             : 
    3634             : //std::cerr << "Parser result is: [" << *n << "]\n";
    3635             : 
    3636          44 :             csspp::compiler c;
    3637          44 :             c.set_root(n);
    3638          44 :             c.set_date_time_variables(csspp_test::get_now());
    3639          44 :             c.add_path(csspp_test::get_script_path());
    3640          44 :             c.add_path(csspp_test::get_version_script_path());
    3641             : 
    3642          44 :             c.compile(false);
    3643             : 
    3644             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3645             : 
    3646             :             // to verify that the result is still an INTEGER we have to
    3647             :             // test the root node here
    3648          44 :             std::stringstream compiler_out;
    3649          44 :             compiler_out << *n;
    3650          44 :             VERIFY_TREES(compiler_out.str(),
    3651             : 
    3652             : "LIST\n"
    3653             : + csspp_test::get_default_variables() +
    3654             : "  COMPONENT_VALUE\n"
    3655             : "    ARG\n"
    3656             : "      IDENTIFIER \"div\"\n"
    3657             : "    OPEN_CURLYBRACKET B:true\n"
    3658             : "      DECLARATION \"z-index\"\n"
    3659             : "        ARG\n"
    3660             : "          DECIMAL_NUMBER \"\" D:3.14\n"
    3661             : "  COMPONENT_VALUE\n"
    3662             : "    ARG\n"
    3663             : "      IDENTIFIER \"div\"\n"
    3664             : "    OPEN_CURLYBRACKET B:true\n"
    3665             : "      DECLARATION \"z-index\"\n"
    3666             : "        ARG\n"
    3667             : "          DECIMAL_NUMBER \"\" D:3.14\n"
    3668             : "  COMPONENT_VALUE\n"
    3669             : "    ARG\n"
    3670             : "      IDENTIFIER \"div\"\n"
    3671             : "    OPEN_CURLYBRACKET B:true\n"
    3672             : "      DECLARATION \"z-index\"\n"
    3673             : "        ARG\n"
    3674             : "          INTEGER \"\" I:17\n"
    3675             : + csspp_test::get_close_comment(true)
    3676             : 
    3677             :                 );
    3678             : 
    3679          44 :             std::stringstream assembler_out;
    3680          44 :             csspp::assembler a(assembler_out);
    3681          44 :             a.output(n, csspp::output_mode_t::COMPRESSED);
    3682             : 
    3683             :     //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3684             : 
    3685          44 :             CATCH_REQUIRE(assembler_out.str() ==
    3686             : 
    3687             : "div{z-index:3.14}div{z-index:3.14}div{z-index:17}\n"
    3688             : + csspp_test::get_close_comment()
    3689             : 
    3690             :                     );
    3691             : 
    3692          44 :             CATCH_REQUIRE(c.get_root() == n);
    3693          44 :         }
    3694             :     }
    3695           4 :     CATCH_END_SECTION()
    3696             : 
    3697             :     // system defined functions are just like user defined functions
    3698             :     // so we don't have to test more (although these are only global
    3699             :     // functions, we could add a test to verify that functions defined
    3700             :     // in a {}-block are ignored from outside that block.)
    3701           4 :     CATCH_START_SECTION("check existance of system functions")
    3702             :     {
    3703             :         // list of system functions, they all must return true
    3704             :         // those that start with '*' are colors that are viewed
    3705             :         // as functions when followed by '(' but color otherwise
    3706           1 :         char const * internal_functions[] =
    3707             :         {
    3708             :             "adjust_hue",
    3709             :             "complement",
    3710             :             "darken",
    3711             :             "deg2rad",
    3712             :             "desaturate",
    3713             :             "fade_in",
    3714             :             "fade_out",
    3715             :             "grayscale",
    3716             :             "invert",
    3717             :             "lighten",
    3718             :             "mix",
    3719             :             "opacify",
    3720             :             "opacity",
    3721             :             "quote",
    3722             :             "remove_unit",
    3723             :             "saturate",
    3724             :             "set_unit",
    3725             :             "transparentize",
    3726             :             "unitless",
    3727             :             "unquote"
    3728             :         };
    3729             : 
    3730          21 :         for(size_t idx(0); idx < sizeof(internal_functions) / sizeof(internal_functions[0]); ++idx)
    3731             :         {
    3732          20 :             bool use_string(false);
    3733          20 :             char const *name = internal_functions[idx];
    3734          20 :             if(*name == '*')
    3735             :             {
    3736           0 :                 use_string = true;
    3737           0 :                 ++name;
    3738             :             }
    3739          20 :             std::stringstream ss;
    3740             :             ss << "div { z-index: function_exists("
    3741             :                << (use_string ? "\"" : "")
    3742             :                << name
    3743             :                << (use_string ? "\"" : "")
    3744             :                << ") ? decimal_number(\"3.14\") : 17 }\n"
    3745             :                << "div { z-index: function_exists(\""
    3746             :                << name
    3747             :                << "\") ? decimal_number(\"3.14\") : 17 }\n"
    3748             :                << "div { z-index: function_exists(\"but_"
    3749             :                << name
    3750          20 :                << "_does_not_exist\") ? decimal_number(\"3.14\") : 17 }\n";
    3751             : //std::cerr << "*** input = [" << ss.str() << "]\n";
    3752          60 :             csspp::position pos("test.css");
    3753          20 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3754             : 
    3755          40 :             csspp::parser p(l);
    3756             : 
    3757          20 :             csspp::node::pointer_t n(p.stylesheet());
    3758             : 
    3759             : //std::cerr << "Parser result is: [" << *n << "]\n";
    3760             : 
    3761          20 :             csspp::compiler c;
    3762          20 :             c.set_root(n);
    3763          20 :             c.set_date_time_variables(csspp_test::get_now());
    3764          20 :             c.add_path(csspp_test::get_script_path());
    3765          20 :             c.add_path(csspp_test::get_version_script_path());
    3766             : 
    3767          20 :             c.compile(false);
    3768             : 
    3769             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3770             : 
    3771             :             // to verify that the result is still an INTEGER we have to
    3772             :             // test the root node here
    3773          20 :             std::stringstream compiler_out;
    3774          20 :             compiler_out << *n;
    3775          20 :             VERIFY_TREES(compiler_out.str(),
    3776             : 
    3777             : "LIST\n"
    3778             : + csspp_test::get_default_variables() +
    3779             : "  COMPONENT_VALUE\n"
    3780             : "    ARG\n"
    3781             : "      IDENTIFIER \"div\"\n"
    3782             : "    OPEN_CURLYBRACKET B:true\n"
    3783             : "      DECLARATION \"z-index\"\n"
    3784             : "        ARG\n"
    3785             : "          DECIMAL_NUMBER \"\" D:3.14\n"
    3786             : "  COMPONENT_VALUE\n"
    3787             : "    ARG\n"
    3788             : "      IDENTIFIER \"div\"\n"
    3789             : "    OPEN_CURLYBRACKET B:true\n"
    3790             : "      DECLARATION \"z-index\"\n"
    3791             : "        ARG\n"
    3792             : "          DECIMAL_NUMBER \"\" D:3.14\n"
    3793             : "  COMPONENT_VALUE\n"
    3794             : "    ARG\n"
    3795             : "      IDENTIFIER \"div\"\n"
    3796             : "    OPEN_CURLYBRACKET B:true\n"
    3797             : "      DECLARATION \"z-index\"\n"
    3798             : "        ARG\n"
    3799             : "          INTEGER \"\" I:17\n"
    3800             : + csspp_test::get_close_comment(true)
    3801             : 
    3802             :                 );
    3803             : 
    3804          20 :             std::stringstream assembler_out;
    3805          20 :             csspp::assembler a(assembler_out);
    3806          20 :             a.output(n, csspp::output_mode_t::COMPRESSED);
    3807             : 
    3808             :     //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3809             : 
    3810          20 :             CATCH_REQUIRE(assembler_out.str() ==
    3811             : 
    3812             : "div{z-index:3.14}div{z-index:3.14}div{z-index:17}\n"
    3813             : + csspp_test::get_close_comment()
    3814             : 
    3815             :                     );
    3816             : 
    3817          20 :             CATCH_REQUIRE(c.get_root() == n);
    3818          20 :         }
    3819             :     }
    3820           4 :     CATCH_END_SECTION()
    3821             : 
    3822           4 :     CATCH_START_SECTION("check that the system defined variables exist")
    3823             :     {
    3824             :         // list of system variables
    3825           1 :         char const * internal_variables[] =
    3826             :         {
    3827             :             // version.scss
    3828             :             "_csspp_version",
    3829             :             "_csspp_major",
    3830             :             "_csspp_minor",
    3831             :             "_csspp_patch",
    3832             : 
    3833             :             // constants.scss
    3834             :             "_csspp_e",
    3835             :             "_csspp_log2e",
    3836             :             "_csspp_log10e",
    3837             :             "_csspp_ln2e",
    3838             :             "_csspp_ln10e",
    3839             :             "_csspp_pi",
    3840             :             "_csspp_pi_rad",
    3841             :             "_csspp_sqrt2",
    3842             : 
    3843             :             // internal (generated by library)
    3844             :             "_csspp_no_logo",
    3845             :             "_csspp_usdate",
    3846             :             "_csspp_month",
    3847             :             "_csspp_day",
    3848             :             "_csspp_year",
    3849             :             "_csspp_time",
    3850             :             "_csspp_hour",
    3851             :             "_csspp_minute",
    3852             :             "_csspp_second",
    3853             :         };
    3854             : 
    3855          22 :         for(size_t idx(0); idx < sizeof(internal_variables) / sizeof(internal_variables[0]); ++idx)
    3856             :         {
    3857          21 :             char const *name = internal_variables[idx];
    3858          21 :             std::stringstream ss;
    3859             :             ss << "div { z-index: global_variable_exists("
    3860             :                << name
    3861             :                << ") ? decimal_number(\"3.14\") : 17 }\n"
    3862             :                << "div { z-index: global_variable_exists(\""
    3863             :                << name
    3864             :                << "\") ? decimal_number(\"3.14\") : 17 }\n"
    3865             :                << "div { z-index: global_variable_exists(\""
    3866             :                << name
    3867             :                << "_not_this_one\") ? decimal_number(\"3.14\") : 17 }\n"
    3868             :                // finally, test with a sub-variable which exists
    3869          21 :                << "div { $sub_var: 123; z-index: global_variable_exists(\"sub_var\") ? decimal_number(\"3.14\") : 17 }\n";
    3870             : //std::cerr << "*** input = [" << ss.str() << "]\n";
    3871          63 :             csspp::position pos("test.css");
    3872          21 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    3873             : 
    3874          42 :             csspp::parser p(l);
    3875             : 
    3876          21 :             csspp::node::pointer_t n(p.stylesheet());
    3877             : 
    3878             : //std::cerr << "Parser result is: [" << *n << "]\n";
    3879             : 
    3880          21 :             csspp::compiler c;
    3881          21 :             c.set_root(n);
    3882          21 :             c.set_date_time_variables(csspp_test::get_now());
    3883          21 :             c.add_path(csspp_test::get_script_path());
    3884          21 :             c.add_path(csspp_test::get_version_script_path());
    3885             : 
    3886          21 :             c.compile(false);
    3887             : 
    3888             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    3889             : 
    3890             :             // to verify that the result is still an INTEGER we have to
    3891             :             // test the root node here
    3892          21 :             std::stringstream compiler_out;
    3893          21 :             compiler_out << *n;
    3894          21 :             VERIFY_TREES(compiler_out.str(),
    3895             : 
    3896             : "LIST\n"
    3897             : + csspp_test::get_default_variables() +
    3898             : "  COMPONENT_VALUE\n"
    3899             : "    ARG\n"
    3900             : "      IDENTIFIER \"div\"\n"
    3901             : "    OPEN_CURLYBRACKET B:true\n"
    3902             : "      DECLARATION \"z-index\"\n"
    3903             : "        ARG\n"
    3904             : "          DECIMAL_NUMBER \"\" D:3.14\n"
    3905             : "  COMPONENT_VALUE\n"
    3906             : "    ARG\n"
    3907             : "      IDENTIFIER \"div\"\n"
    3908             : "    OPEN_CURLYBRACKET B:true\n"
    3909             : "      DECLARATION \"z-index\"\n"
    3910             : "        ARG\n"
    3911             : "          DECIMAL_NUMBER \"\" D:3.14\n"
    3912             : "  COMPONENT_VALUE\n"
    3913             : "    ARG\n"
    3914             : "      IDENTIFIER \"div\"\n"
    3915             : "    OPEN_CURLYBRACKET B:true\n"
    3916             : "      DECLARATION \"z-index\"\n"
    3917             : "        ARG\n"
    3918             : "          INTEGER \"\" I:17\n"
    3919             : "  COMPONENT_VALUE\n"
    3920             : "    ARG\n"
    3921             : "      IDENTIFIER \"div\"\n"
    3922             : "    OPEN_CURLYBRACKET B:true\n"
    3923             : "        V:sub_var\n"
    3924             : "          LIST\n"
    3925             : "            VARIABLE \"sub_var\"\n"
    3926             : "            INTEGER \"\" I:123\n"
    3927             : "      LIST\n"
    3928             : "        DECLARATION \"z-index\"\n"
    3929             : "          ARG\n"
    3930             : "            INTEGER \"\" I:17\n"
    3931             : + csspp_test::get_close_comment(true)
    3932             : 
    3933             :                 );
    3934             : 
    3935          21 :             std::stringstream assembler_out;
    3936          21 :             csspp::assembler a(assembler_out);
    3937          21 :             a.output(n, csspp::output_mode_t::COMPRESSED);
    3938             : 
    3939             :     //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    3940             : 
    3941          21 :             CATCH_REQUIRE(assembler_out.str() ==
    3942             : 
    3943             : "div{z-index:3.14}div{z-index:3.14}div{z-index:17}div{z-index:17}\n"
    3944             : + csspp_test::get_close_comment()
    3945             : 
    3946             :                     );
    3947             : 
    3948          21 :             CATCH_REQUIRE(c.get_root() == n);
    3949          21 :         }
    3950             :     }
    3951           4 :     CATCH_END_SECTION()
    3952             : 
    3953           4 :     CATCH_START_SECTION("check that various variables exist")
    3954             :     {
    3955             :         // list of system variables
    3956           1 :         char const * internal_variables[] =
    3957             :         {
    3958             :             // version.scss
    3959             :             "_csspp_version",
    3960             :             "_csspp_major",
    3961             :             "_csspp_minor",
    3962             :             "_csspp_patch",
    3963             : 
    3964             :             // constants.scss
    3965             :             "_csspp_e",
    3966             :             "_csspp_log2e",
    3967             :             "_csspp_log10e",
    3968             :             "_csspp_ln2e",
    3969             :             "_csspp_ln10e",
    3970             :             "_csspp_pi",
    3971             :             "_csspp_pi_rad",
    3972             :             "_csspp_sqrt2",
    3973             : 
    3974             :             // internal (generated by library)
    3975             :             "_csspp_no_logo",
    3976             :             "_csspp_usdate",
    3977             :             "_csspp_month",
    3978             :             "_csspp_day",
    3979             :             "_csspp_year",
    3980             :             "_csspp_time",
    3981             :             "_csspp_hour",
    3982             :             "_csspp_minute",
    3983             :             "_csspp_second",
    3984             :         };
    3985             : 
    3986          22 :         for(size_t idx(0); idx < sizeof(internal_variables) / sizeof(internal_variables[0]); ++idx)
    3987             :         {
    3988          21 :             char const *name = internal_variables[idx];
    3989          21 :             std::stringstream ss;
    3990             :             ss << "div { z-index: variable_exists("
    3991             :                << name
    3992             :                << ") ? decimal_number(\"3.14\") : 17 }\n"
    3993             :                << "div { z-index: variable_exists(\""
    3994             :                << name
    3995             :                << "\") ? decimal_number(\"3.14\") : 17 }\n"
    3996             :                << "div { z-index: variable_exists(\""
    3997             :                << name
    3998             :                << "_not_this_one\") ? decimal_number(\"3.14\") : 17 }\n"
    3999             :                // finally, test with a sub-variable which exists
    4000             :                << "div { $sub_var: 123; z-index: variable_exists(\"sub_var\") ? decimal_number(\"3.14\") : 17 }\n"
    4001             :                // and then "disappeared"
    4002          21 :                << "div { z-index: variable_exists(\"sub_var\") ? decimal_number(\"3.14\") : 17 }\n";
    4003             : //std::cerr << "*** input = [" << ss.str() << "]\n";
    4004          63 :             csspp::position pos("test.css");
    4005          21 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4006             : 
    4007          42 :             csspp::parser p(l);
    4008             : 
    4009          21 :             csspp::node::pointer_t n(p.stylesheet());
    4010             : 
    4011             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4012             : 
    4013          21 :             csspp::compiler c;
    4014          21 :             c.set_root(n);
    4015          21 :             c.set_date_time_variables(csspp_test::get_now());
    4016          21 :             c.add_path(csspp_test::get_script_path());
    4017          21 :             c.add_path(csspp_test::get_version_script_path());
    4018             : 
    4019          21 :             c.compile(false);
    4020             : 
    4021             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4022             : 
    4023             :             // to verify that the result is still an INTEGER we have to
    4024             :             // test the root node here
    4025          21 :             std::stringstream compiler_out;
    4026          21 :             compiler_out << *n;
    4027          21 :             VERIFY_TREES(compiler_out.str(),
    4028             : 
    4029             : "LIST\n"
    4030             : + csspp_test::get_default_variables() +
    4031             : "  COMPONENT_VALUE\n"
    4032             : "    ARG\n"
    4033             : "      IDENTIFIER \"div\"\n"
    4034             : "    OPEN_CURLYBRACKET B:true\n"
    4035             : "      DECLARATION \"z-index\"\n"
    4036             : "        ARG\n"
    4037             : "          DECIMAL_NUMBER \"\" D:3.14\n"
    4038             : "  COMPONENT_VALUE\n"
    4039             : "    ARG\n"
    4040             : "      IDENTIFIER \"div\"\n"
    4041             : "    OPEN_CURLYBRACKET B:true\n"
    4042             : "      DECLARATION \"z-index\"\n"
    4043             : "        ARG\n"
    4044             : "          DECIMAL_NUMBER \"\" D:3.14\n"
    4045             : "  COMPONENT_VALUE\n"
    4046             : "    ARG\n"
    4047             : "      IDENTIFIER \"div\"\n"
    4048             : "    OPEN_CURLYBRACKET B:true\n"
    4049             : "      DECLARATION \"z-index\"\n"
    4050             : "        ARG\n"
    4051             : "          INTEGER \"\" I:17\n"
    4052             : "  COMPONENT_VALUE\n"
    4053             : "    ARG\n"
    4054             : "      IDENTIFIER \"div\"\n"
    4055             : "    OPEN_CURLYBRACKET B:true\n"
    4056             : "        V:sub_var\n"
    4057             : "          LIST\n"
    4058             : "            VARIABLE \"sub_var\"\n"
    4059             : "            INTEGER \"\" I:123\n"
    4060             : "      LIST\n"
    4061             : "        DECLARATION \"z-index\"\n"
    4062             : "          ARG\n"
    4063             : "            DECIMAL_NUMBER \"\" D:3.14\n"
    4064             : "  COMPONENT_VALUE\n"
    4065             : "    ARG\n"
    4066             : "      IDENTIFIER \"div\"\n"
    4067             : "    OPEN_CURLYBRACKET B:true\n"
    4068             : "      DECLARATION \"z-index\"\n"
    4069             : "        ARG\n"
    4070             : "          INTEGER \"\" I:17\n"
    4071             : + csspp_test::get_close_comment(true)
    4072             : 
    4073             :                 );
    4074             : 
    4075          21 :             std::stringstream assembler_out;
    4076          21 :             csspp::assembler a(assembler_out);
    4077          21 :             a.output(n, csspp::output_mode_t::COMPRESSED);
    4078             : 
    4079             :     //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4080             : 
    4081          21 :             CATCH_REQUIRE(assembler_out.str() ==
    4082             : 
    4083             : "div{z-index:3.14}div{z-index:3.14}div{z-index:17}div{z-index:3.14}div{z-index:17}\n"
    4084             : + csspp_test::get_close_comment()
    4085             : 
    4086             :                     );
    4087             : 
    4088          21 :             CATCH_REQUIRE(c.get_root() == n);
    4089          21 :         }
    4090             :     }
    4091           4 :     CATCH_END_SECTION()
    4092             : 
    4093             :     // no error left over
    4094           4 :     VERIFY_ERRORS("");
    4095           4 : }
    4096             : 
    4097           2 : CATCH_TEST_CASE("Expression unique_id()", "[expression] [internal-functions] [unique-id]")
    4098             : {
    4099           2 :     CATCH_START_SECTION("unique_id() without an identifier")
    4100             :     {
    4101           1 :         std::stringstream ss;
    4102             :         ss << "a { content: string(unique_id()); }"
    4103             :            << "b { content: string(unique_id()); }"
    4104             :            << "c { content: string(unique_id()); }"
    4105             :            << "d { content: string(unique_id()); }"
    4106             :            << "e { content: string(unique_id()); }"
    4107           1 :            << "f { content: string(unique_id()); }";
    4108           3 :         csspp::position pos("test.css");
    4109           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4110             : 
    4111           2 :         csspp::parser p(l);
    4112             : 
    4113           1 :         csspp::node::pointer_t n(p.stylesheet());
    4114             : 
    4115             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4116             : 
    4117             :         // reset counter so we can compare with 1, 2, 3 each time
    4118           1 :         csspp::expression::set_unique_id_counter(0);
    4119           1 :         CATCH_REQUIRE(csspp::expression::get_unique_id_counter() == 0);
    4120             : 
    4121           1 :         csspp::compiler c;
    4122           1 :         c.set_root(n);
    4123           1 :         c.set_date_time_variables(csspp_test::get_now());
    4124           1 :         c.add_path(csspp_test::get_script_path());
    4125           1 :         c.add_path(csspp_test::get_version_script_path());
    4126             : 
    4127           1 :         c.compile(false);
    4128             : 
    4129           1 :         CATCH_REQUIRE(csspp::expression::get_unique_id_counter() == 6);
    4130             : 
    4131             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4132             : 
    4133             :         // to verify that the result is still an INTEGER we have to
    4134             :         // test the root node here
    4135           1 :         std::stringstream compiler_out;
    4136           1 :         compiler_out << *n;
    4137           1 :         VERIFY_TREES(compiler_out.str(),
    4138             : 
    4139             : "LIST\n"
    4140             : + csspp_test::get_default_variables() +
    4141             : "  COMPONENT_VALUE\n"
    4142             : "    ARG\n"
    4143             : "      IDENTIFIER \"a\"\n"
    4144             : "    OPEN_CURLYBRACKET B:true\n"
    4145             : "      DECLARATION \"content\"\n"
    4146             : "        ARG\n"
    4147             : "          STRING \"_csspp_unique1\"\n"
    4148             : "  COMPONENT_VALUE\n"
    4149             : "    ARG\n"
    4150             : "      IDENTIFIER \"b\"\n"
    4151             : "    OPEN_CURLYBRACKET B:true\n"
    4152             : "      DECLARATION \"content\"\n"
    4153             : "        ARG\n"
    4154             : "          STRING \"_csspp_unique2\"\n"
    4155             : "  COMPONENT_VALUE\n"
    4156             : "    ARG\n"
    4157             : "      IDENTIFIER \"c\"\n"
    4158             : "    OPEN_CURLYBRACKET B:true\n"
    4159             : "      DECLARATION \"content\"\n"
    4160             : "        ARG\n"
    4161             : "          STRING \"_csspp_unique3\"\n"
    4162             : "  COMPONENT_VALUE\n"
    4163             : "    ARG\n"
    4164             : "      IDENTIFIER \"d\"\n"
    4165             : "    OPEN_CURLYBRACKET B:true\n"
    4166             : "      DECLARATION \"content\"\n"
    4167             : "        ARG\n"
    4168             : "          STRING \"_csspp_unique4\"\n"
    4169             : "  COMPONENT_VALUE\n"
    4170             : "    ARG\n"
    4171             : "      IDENTIFIER \"e\"\n"
    4172             : "    OPEN_CURLYBRACKET B:true\n"
    4173             : "      DECLARATION \"content\"\n"
    4174             : "        ARG\n"
    4175             : "          STRING \"_csspp_unique5\"\n"
    4176             : "  COMPONENT_VALUE\n"
    4177             : "    ARG\n"
    4178             : "      IDENTIFIER \"f\"\n"
    4179             : "    OPEN_CURLYBRACKET B:true\n"
    4180             : "      DECLARATION \"content\"\n"
    4181             : "        ARG\n"
    4182             : "          STRING \"_csspp_unique6\"\n"
    4183             : + csspp_test::get_close_comment(true)
    4184             : 
    4185             :             );
    4186             : 
    4187           1 :         std::stringstream assembler_out;
    4188           1 :         csspp::assembler a(assembler_out);
    4189           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4190             : 
    4191             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4192             : 
    4193           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4194             : 
    4195             : "a{content:\"_csspp_unique1\"}"
    4196             : "b{content:\"_csspp_unique2\"}"
    4197             : "c{content:\"_csspp_unique3\"}"
    4198             : "d{content:\"_csspp_unique4\"}"
    4199             : "e{content:\"_csspp_unique5\"}"
    4200             : "f{content:\"_csspp_unique6\"}"
    4201             : "\n"
    4202             : + csspp_test::get_close_comment()
    4203             : 
    4204             :                 );
    4205             : 
    4206           1 :         CATCH_REQUIRE(c.get_root() == n);
    4207           1 :     }
    4208           2 :     CATCH_END_SECTION()
    4209             : 
    4210           2 :     CATCH_START_SECTION("unique_id() with out own identifier")
    4211             :     {
    4212           1 :         std::stringstream ss;
    4213             :         ss << "a { content: string(unique_id(my_id)); }\n"
    4214             :            << "b { content: string(unique_id(\"this_id\")); }\n"
    4215             :            << "c { content: string(unique_id('string')); }\n"
    4216             :            << "d { content: string(unique_id(flower)); }\n"
    4217             :            << "e { content: string(unique_id(id)); }\n"
    4218           1 :            << "f { content: string(unique_id(a)); }\n";
    4219           3 :         csspp::position pos("test.css");
    4220           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4221             : 
    4222           2 :         csspp::parser p(l);
    4223             : 
    4224           1 :         csspp::node::pointer_t n(p.stylesheet());
    4225             : 
    4226             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4227             : 
    4228             :         // reset counter so we can compare with 1, 2, 3 each time
    4229           1 :         csspp::expression::set_unique_id_counter(0);
    4230           1 :         CATCH_REQUIRE(csspp::expression::get_unique_id_counter() == 0);
    4231             : 
    4232           1 :         csspp::compiler c;
    4233           1 :         c.set_root(n);
    4234           1 :         c.set_date_time_variables(csspp_test::get_now());
    4235           1 :         c.add_path(csspp_test::get_script_path());
    4236           1 :         c.add_path(csspp_test::get_version_script_path());
    4237             : 
    4238           1 :         c.compile(false);
    4239             : 
    4240           1 :         CATCH_REQUIRE(csspp::expression::get_unique_id_counter() == 6);
    4241             : 
    4242             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4243             : 
    4244             :         // to verify that the result is still an INTEGER we have to
    4245             :         // test the root node here
    4246           1 :         std::stringstream compiler_out;
    4247           1 :         compiler_out << *n;
    4248           1 :         VERIFY_TREES(compiler_out.str(),
    4249             : 
    4250             : "LIST\n"
    4251             : + csspp_test::get_default_variables() +
    4252             : "  COMPONENT_VALUE\n"
    4253             : "    ARG\n"
    4254             : "      IDENTIFIER \"a\"\n"
    4255             : "    OPEN_CURLYBRACKET B:true\n"
    4256             : "      DECLARATION \"content\"\n"
    4257             : "        ARG\n"
    4258             : "          STRING \"my_id1\"\n"
    4259             : "  COMPONENT_VALUE\n"
    4260             : "    ARG\n"
    4261             : "      IDENTIFIER \"b\"\n"
    4262             : "    OPEN_CURLYBRACKET B:true\n"
    4263             : "      DECLARATION \"content\"\n"
    4264             : "        ARG\n"
    4265             : "          STRING \"this_id2\"\n"
    4266             : "  COMPONENT_VALUE\n"
    4267             : "    ARG\n"
    4268             : "      IDENTIFIER \"c\"\n"
    4269             : "    OPEN_CURLYBRACKET B:true\n"
    4270             : "      DECLARATION \"content\"\n"
    4271             : "        ARG\n"
    4272             : "          STRING \"string3\"\n"
    4273             : "  COMPONENT_VALUE\n"
    4274             : "    ARG\n"
    4275             : "      IDENTIFIER \"d\"\n"
    4276             : "    OPEN_CURLYBRACKET B:true\n"
    4277             : "      DECLARATION \"content\"\n"
    4278             : "        ARG\n"
    4279             : "          STRING \"flower4\"\n"
    4280             : "  COMPONENT_VALUE\n"
    4281             : "    ARG\n"
    4282             : "      IDENTIFIER \"e\"\n"
    4283             : "    OPEN_CURLYBRACKET B:true\n"
    4284             : "      DECLARATION \"content\"\n"
    4285             : "        ARG\n"
    4286             : "          STRING \"id5\"\n"
    4287             : "  COMPONENT_VALUE\n"
    4288             : "    ARG\n"
    4289             : "      IDENTIFIER \"f\"\n"
    4290             : "    OPEN_CURLYBRACKET B:true\n"
    4291             : "      DECLARATION \"content\"\n"
    4292             : "        ARG\n"
    4293             : "          STRING \"a6\"\n"
    4294             : + csspp_test::get_close_comment(true)
    4295             : 
    4296             :             );
    4297             : 
    4298           1 :         std::stringstream assembler_out;
    4299           1 :         csspp::assembler a(assembler_out);
    4300           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4301             : 
    4302             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4303             : 
    4304           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4305             : 
    4306             : "a{content:\"my_id1\"}"
    4307             : "b{content:\"this_id2\"}"
    4308             : "c{content:\"string3\"}"
    4309             : "d{content:\"flower4\"}"
    4310             : "e{content:\"id5\"}"
    4311             : "f{content:\"a6\"}"
    4312             : "\n"
    4313             : + csspp_test::get_close_comment()
    4314             : 
    4315             :                 );
    4316             : 
    4317           1 :         CATCH_REQUIRE(c.get_root() == n);
    4318           1 :     }
    4319           2 :     CATCH_END_SECTION()
    4320             : 
    4321             :     // no error left over
    4322           2 :     VERIFY_ERRORS("");
    4323           2 : }
    4324             : 
    4325           1 : CATCH_TEST_CASE("Expression if()", "[expression] [internal-functions] [if]")
    4326             : {
    4327           1 :     CATCH_START_SECTION("check that the inetrnal if() function works as expected")
    4328             :     {
    4329           1 :         std::stringstream ss;
    4330             :         ss << "div { width: if(3.14 = 17, 1.22em, 44px) }\n"
    4331             :            << "div { width: if(3.14 != 17, 1.23em, 45px) }\n"
    4332           1 :            << "div { border: if(3.14 != 17, 0.2em solid black, 0.1em solid white) }\n";
    4333             : //std::cerr << "*** input = [" << ss.str() << "]\n";
    4334           3 :         csspp::position pos("test.css");
    4335           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4336             : 
    4337           2 :         csspp::parser p(l);
    4338             : 
    4339           1 :         csspp::node::pointer_t n(p.stylesheet());
    4340             : 
    4341             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4342             : 
    4343           1 :         csspp::compiler c;
    4344           1 :         c.set_root(n);
    4345           1 :         c.set_date_time_variables(csspp_test::get_now());
    4346           1 :         c.add_path(csspp_test::get_script_path());
    4347           1 :         c.add_path(csspp_test::get_version_script_path());
    4348             : 
    4349           1 :         c.compile(false);
    4350             : 
    4351             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4352             : 
    4353             :         // to verify that the result is still an INTEGER we have to
    4354             :         // test the root node here
    4355           1 :         std::stringstream compiler_out;
    4356           1 :         compiler_out << *n;
    4357           1 :         VERIFY_TREES(compiler_out.str(),
    4358             : 
    4359             : "LIST\n"
    4360             : + csspp_test::get_default_variables() +
    4361             : "  COMPONENT_VALUE\n"
    4362             : "    ARG\n"
    4363             : "      IDENTIFIER \"div\"\n"
    4364             : "    OPEN_CURLYBRACKET B:true\n"
    4365             : "      DECLARATION \"width\"\n"
    4366             : "        ARG\n"
    4367             : "          INTEGER \"px\" I:44\n"
    4368             : "  COMPONENT_VALUE\n"
    4369             : "    ARG\n"
    4370             : "      IDENTIFIER \"div\"\n"
    4371             : "    OPEN_CURLYBRACKET B:true\n"
    4372             : "      DECLARATION \"width\"\n"
    4373             : "        ARG\n"
    4374             : "          DECIMAL_NUMBER \"em\" D:1.23\n"
    4375             : "  COMPONENT_VALUE\n"
    4376             : "    ARG\n"
    4377             : "      IDENTIFIER \"div\"\n"
    4378             : "    OPEN_CURLYBRACKET B:true\n"
    4379             : "      DECLARATION \"border\"\n"
    4380             : "        ARG\n"
    4381             : "          LIST\n"
    4382             : "            DECIMAL_NUMBER \"em\" D:0.2\n"
    4383             : "            WHITESPACE\n"
    4384             : "            IDENTIFIER \"solid\"\n"
    4385             : "            WHITESPACE\n"
    4386             : "            COLOR H:ff000000\n"
    4387             : + csspp_test::get_close_comment(true)
    4388             : 
    4389             :             );
    4390             : 
    4391           1 :         std::stringstream assembler_out;
    4392           1 :         csspp::assembler a(assembler_out);
    4393           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4394             : 
    4395             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4396             : 
    4397           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4398             : 
    4399             : "div{width:44px}div{width:1.23em}div{border:.2em solid #000}\n"
    4400             : + csspp_test::get_close_comment()
    4401             : 
    4402             :                 );
    4403             : 
    4404           1 :         CATCH_REQUIRE(c.get_root() == n);
    4405           1 :     }
    4406           1 :     CATCH_END_SECTION()
    4407             : 
    4408             :     // no error left over
    4409           1 :     VERIFY_ERRORS("");
    4410           1 : }
    4411             : 
    4412           1 : CATCH_TEST_CASE("Expression inspect()", "[expression] [internal-functions] [inspect]")
    4413             : {
    4414           1 :     CATCH_START_SECTION("check that the internal inspect() function works as expected")
    4415             :     {
    4416           1 :         std::stringstream ss;
    4417           1 :         ss << "div { content: inspect(0.2em solid black) }\n";
    4418             : //std::cerr << "*** input = [" << ss.str() << "]\n";
    4419           3 :         csspp::position pos("test.css");
    4420           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4421             : 
    4422           2 :         csspp::parser p(l);
    4423             : 
    4424           1 :         csspp::node::pointer_t n(p.stylesheet());
    4425             : 
    4426             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4427             : 
    4428           1 :         csspp::compiler c;
    4429           1 :         c.set_root(n);
    4430           1 :         c.set_date_time_variables(csspp_test::get_now());
    4431           1 :         c.add_path(csspp_test::get_script_path());
    4432           1 :         c.add_path(csspp_test::get_version_script_path());
    4433             : 
    4434           1 :         c.compile(false);
    4435             : 
    4436             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4437             : 
    4438             :         // to verify that the result is still an INTEGER we have to
    4439             :         // test the root node here
    4440           1 :         std::stringstream compiler_out;
    4441           1 :         compiler_out << *n;
    4442           1 :         VERIFY_TREES(compiler_out.str(),
    4443             : 
    4444             : "LIST\n"
    4445             : + csspp_test::get_default_variables() +
    4446             : "  COMPONENT_VALUE\n"
    4447             : "    ARG\n"
    4448             : "      IDENTIFIER \"div\"\n"
    4449             : "    OPEN_CURLYBRACKET B:true\n"
    4450             : "      DECLARATION \"content\"\n"
    4451             : "        ARG\n"
    4452             : "          STRING \"0.2em solid #000\"\n"
    4453             : + csspp_test::get_close_comment(true)
    4454             : 
    4455             :             );
    4456             : 
    4457           1 :         std::stringstream assembler_out;
    4458           1 :         csspp::assembler a(assembler_out);
    4459           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4460             : 
    4461             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4462             : 
    4463           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4464             : 
    4465             : "div{content:\"0.2em solid #000\"}\n"
    4466             : + csspp_test::get_close_comment()
    4467             : 
    4468             :                 );
    4469             : 
    4470           1 :         CATCH_REQUIRE(c.get_root() == n);
    4471           1 :     }
    4472           1 :     CATCH_END_SECTION()
    4473             : 
    4474             :     // no error left over
    4475           1 :     VERIFY_ERRORS("");
    4476           1 : }
    4477             : 
    4478           1 : CATCH_TEST_CASE("Expression random()", "[expression] [internal-functions] [random]")
    4479             : {
    4480           1 :     CATCH_START_SECTION("check that the internal random() function \"works as expected\"")
    4481             :     {
    4482           1 :         std::stringstream ss;
    4483           1 :         ss << "div { width: random() * 1.0px }\n";
    4484             : //std::cerr << "*** input = [" << ss.str() << "]\n";
    4485           3 :         csspp::position pos("test.css");
    4486           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4487             : 
    4488           2 :         csspp::parser p(l);
    4489             : 
    4490           1 :         csspp::node::pointer_t n(p.stylesheet());
    4491             : 
    4492             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4493             : 
    4494           1 :         csspp::compiler c;
    4495           1 :         c.set_root(n);
    4496           1 :         c.set_date_time_variables(csspp_test::get_now());
    4497           1 :         c.add_path(csspp_test::get_script_path());
    4498           1 :         c.add_path(csspp_test::get_version_script_path());
    4499             : 
    4500           1 :         c.compile(false);
    4501             : 
    4502             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4503             : 
    4504             :         // to check the compiler output we need to know what random
    4505             :         // value was generated; for that purpose, we need to retrieve
    4506             :         // it from the tree
    4507           1 :         csspp::decimal_number_t v(0);
    4508             :         // super ugly if() statement, note that in itself it is no
    4509             :         // different than the test below which compares the compiler
    4510             :         // output tree with what we expect said tree to be
    4511           3 :         if(n->is(csspp::node_type_t::LIST)
    4512           1 :         && n->size() > 0
    4513           3 :         && n->get_child(0)->is(csspp::node_type_t::COMPONENT_VALUE)
    4514           2 :         && n->get_child(0)->size() > 1
    4515           2 :         && n->get_child(0)->get_child(1)->is(csspp::node_type_t::OPEN_CURLYBRACKET)
    4516           2 :         && n->get_child(0)->get_child(1)->size() > 0
    4517           2 :         && n->get_child(0)->get_child(1)->get_child(0)->is(csspp::node_type_t::DECLARATION)
    4518           2 :         && n->get_child(0)->get_child(1)->get_child(0)->size() > 0
    4519           2 :         && n->get_child(0)->get_child(1)->get_child(0)->get_child(0)->is(csspp::node_type_t::ARG)
    4520           2 :         && n->get_child(0)->get_child(1)->get_child(0)->get_child(0)->size() > 0
    4521           3 :         && n->get_child(0)->get_child(1)->get_child(0)->get_child(0)->get_child(0)->is(csspp::node_type_t::DECIMAL_NUMBER))
    4522             :         {
    4523           1 :             v = n->get_child(0)->get_child(1)->get_child(0)->get_child(0)->get_child(0)->get_decimal_number();
    4524             :         }
    4525             : 
    4526             :         // to verify that the result is still an INTEGER we have to
    4527             :         // test the root node here
    4528           1 :         std::stringstream compiler_out;
    4529           1 :         compiler_out << *n;
    4530           1 :         VERIFY_TREES(compiler_out.str(),
    4531             : 
    4532             : "LIST\n"
    4533             : + csspp_test::get_default_variables() +
    4534             : "  COMPONENT_VALUE\n"
    4535             : "    ARG\n"
    4536             : "      IDENTIFIER \"div\"\n"
    4537             : "    OPEN_CURLYBRACKET B:true\n"
    4538             : "      DECLARATION \"width\"\n"
    4539             : "        ARG\n"
    4540             : "          DECIMAL_NUMBER \"px\" D:" + csspp::decimal_number_to_string(v, false) + "\n"
    4541             : + csspp_test::get_close_comment(true)
    4542             : 
    4543             :             );
    4544             : 
    4545           1 :         std::stringstream assembler_out;
    4546           1 :         csspp::assembler a(assembler_out);
    4547           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4548             : 
    4549             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4550             : 
    4551           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4552             : 
    4553             : "div{width:" + csspp::decimal_number_to_string(v, true) + "px}\n"
    4554             : + csspp_test::get_close_comment()
    4555             : 
    4556             :                 );
    4557             : 
    4558           1 :         CATCH_REQUIRE(c.get_root() == n);
    4559           1 :     }
    4560           1 :     CATCH_END_SECTION()
    4561             : 
    4562             :     // no error left over
    4563           1 :     VERIFY_ERRORS("");
    4564           1 : }
    4565             : 
    4566           1 : CATCH_TEST_CASE("Expression min()/max()", "[expression] [internal-functions] [min] [max]")
    4567             : {
    4568           1 :     CATCH_START_SECTION("check the min()/max() functions against a list of random numbers")
    4569             :     {
    4570          11 :         for(int i(0); i < 10; ++i)
    4571             :         {
    4572          10 :             int min(1000);
    4573          10 :             int max(-1000);
    4574          10 :             std::string int_out;
    4575          10 :             std::string px_out;
    4576          10 :             std::string flt_out;
    4577          10 :             std::string em_out;
    4578          10 :             std::string percent_out;
    4579         110 :             for(int j(0); j < 10; ++j)
    4580             :             {
    4581         100 :                 int n(rand() % 2001 - 1000);
    4582         100 :                 if(n < min)
    4583             :                 {
    4584          29 :                     min = n;
    4585             :                 }
    4586         100 :                 if(n > max)
    4587             :                 {
    4588          27 :                     max = n;
    4589             :                 }
    4590         100 :                 if(j != 0)
    4591             :                 {
    4592          90 :                     int_out += ", ";
    4593          90 :                     px_out  += ", ";
    4594          90 :                     flt_out += ", ";
    4595          90 :                     em_out  += ", ";
    4596          90 :                     percent_out += ", ";
    4597             :                 }
    4598         100 :                 int_out += std::to_string(n);
    4599         100 :                 px_out  += std::to_string(n) + "px";
    4600         100 :                 std::stringstream flt;
    4601         100 :                 flt << std::setprecision(6) << std::fixed
    4602         100 :                     << (static_cast<csspp::decimal_number_t>(n) / 100.0);
    4603         100 :                 flt_out += flt.str();
    4604         100 :                 em_out += flt.str() + "em";
    4605         100 :                 percent_out += std::to_string(n) + "%";
    4606         100 :             }
    4607          10 :             std::stringstream ss;
    4608             :             ss << "div { width:  min(" << int_out << ") }\n"
    4609             :                << "sub { height: max(" << int_out << ") }\n"
    4610             :                << "div { width:  min(" << px_out << ") }\n"
    4611             :                << "sub { height: max(" << px_out << ") }\n"
    4612             :                << "div { width:  min(" << flt_out << ") }\n"
    4613             :                << "sub { height: max(" << flt_out << ") }\n"
    4614             :                << "div { width:  min(" << em_out << ") }\n"
    4615             :                << "sub { height: max(" << em_out << ") }\n"
    4616             :                << "div { width:  min(" << percent_out << ") }\n"
    4617          10 :                << "sub { height: max(" << percent_out << ") }\n";
    4618             : //std::cerr << "*** input = [" << ss.str() << "]\n";
    4619          30 :             csspp::position pos("test.css");
    4620          10 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4621             : 
    4622          20 :             csspp::parser p(l);
    4623             : 
    4624          10 :             csspp::node::pointer_t n(p.stylesheet());
    4625             : 
    4626             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4627             : 
    4628          10 :             csspp::compiler c;
    4629          10 :             c.set_root(n);
    4630          10 :             c.set_date_time_variables(csspp_test::get_now());
    4631          10 :             c.add_path(csspp_test::get_script_path());
    4632          10 :             c.add_path(csspp_test::get_version_script_path());
    4633             : 
    4634          10 :             c.compile(false);
    4635             : 
    4636             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4637             : 
    4638             :             // to verify that the result is still an INTEGER we have to
    4639             :             // test the root node here
    4640          10 :             std::stringstream compiler_out;
    4641          10 :             compiler_out << *n;
    4642          10 :             VERIFY_TREES(compiler_out.str(),
    4643             : 
    4644             : "LIST\n"
    4645             : + csspp_test::get_default_variables() +
    4646             : "  COMPONENT_VALUE\n"
    4647             : "    ARG\n"
    4648             : "      IDENTIFIER \"div\"\n"
    4649             : "    OPEN_CURLYBRACKET B:true\n"
    4650             : "      DECLARATION \"width\"\n"
    4651             : "        ARG\n"
    4652             : "          INTEGER \"\" I:" + std::to_string(min) + "\n"
    4653             : "  COMPONENT_VALUE\n"
    4654             : "    ARG\n"
    4655             : "      IDENTIFIER \"sub\"\n"
    4656             : "    OPEN_CURLYBRACKET B:true\n"
    4657             : "      DECLARATION \"height\"\n"
    4658             : "        ARG\n"
    4659             : "          INTEGER \"\" I:" + std::to_string(max) + "\n"
    4660             : "  COMPONENT_VALUE\n"
    4661             : "    ARG\n"
    4662             : "      IDENTIFIER \"div\"\n"
    4663             : "    OPEN_CURLYBRACKET B:true\n"
    4664             : "      DECLARATION \"width\"\n"
    4665             : "        ARG\n"
    4666             : "          INTEGER \"px\" I:" + std::to_string(min) + "\n"
    4667             : "  COMPONENT_VALUE\n"
    4668             : "    ARG\n"
    4669             : "      IDENTIFIER \"sub\"\n"
    4670             : "    OPEN_CURLYBRACKET B:true\n"
    4671             : "      DECLARATION \"height\"\n"
    4672             : "        ARG\n"
    4673             : "          INTEGER \"px\" I:" + std::to_string(max) + "\n"
    4674             : "  COMPONENT_VALUE\n"
    4675             : "    ARG\n"
    4676             : "      IDENTIFIER \"div\"\n"
    4677             : "    OPEN_CURLYBRACKET B:true\n"
    4678             : "      DECLARATION \"width\"\n"
    4679             : "        ARG\n"
    4680             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(min / 100.0, false) + "\n"
    4681             : "  COMPONENT_VALUE\n"
    4682             : "    ARG\n"
    4683             : "      IDENTIFIER \"sub\"\n"
    4684             : "    OPEN_CURLYBRACKET B:true\n"
    4685             : "      DECLARATION \"height\"\n"
    4686             : "        ARG\n"
    4687             : "          DECIMAL_NUMBER \"\" D:" + csspp::decimal_number_to_string(max / 100.0, false) + "\n"
    4688             : "  COMPONENT_VALUE\n"
    4689             : "    ARG\n"
    4690             : "      IDENTIFIER \"div\"\n"
    4691             : "    OPEN_CURLYBRACKET B:true\n"
    4692             : "      DECLARATION \"width\"\n"
    4693             : "        ARG\n"
    4694             : "          DECIMAL_NUMBER \"em\" D:" + csspp::decimal_number_to_string(min / 100.0, false) + "\n"
    4695             : "  COMPONENT_VALUE\n"
    4696             : "    ARG\n"
    4697             : "      IDENTIFIER \"sub\"\n"
    4698             : "    OPEN_CURLYBRACKET B:true\n"
    4699             : "      DECLARATION \"height\"\n"
    4700             : "        ARG\n"
    4701             : "          DECIMAL_NUMBER \"em\" D:" + csspp::decimal_number_to_string(max / 100.0, false) + "\n"
    4702             : "  COMPONENT_VALUE\n"
    4703             : "    ARG\n"
    4704             : "      IDENTIFIER \"div\"\n"
    4705             : "    OPEN_CURLYBRACKET B:true\n"
    4706             : "      DECLARATION \"width\"\n"
    4707             : "        ARG\n"
    4708             : "          PERCENT D:" + csspp::decimal_number_to_string(min / 100.0, false) + "\n"
    4709             : "  COMPONENT_VALUE\n"
    4710             : "    ARG\n"
    4711             : "      IDENTIFIER \"sub\"\n"
    4712             : "    OPEN_CURLYBRACKET B:true\n"
    4713             : "      DECLARATION \"height\"\n"
    4714             : "        ARG\n"
    4715             : "          PERCENT D:" + csspp::decimal_number_to_string(max / 100.0, false) + "\n"
    4716             : + csspp_test::get_close_comment(true)
    4717             : 
    4718             :                 );
    4719             : 
    4720          10 :             std::stringstream assembler_out;
    4721          10 :             csspp::assembler a(assembler_out);
    4722          10 :             a.output(n, csspp::output_mode_t::COMPRESSED);
    4723             : 
    4724             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4725             : 
    4726          10 :             CATCH_REQUIRE(assembler_out.str() ==
    4727             : 
    4728             : "div{width:" + std::to_string(min) + "}"
    4729             : "sub{height:" + std::to_string(max) + "}"
    4730             : "div{width:" + std::to_string(min) + "px}"
    4731             : "sub{height:" + std::to_string(max) + "px}"
    4732             : "div{width:" + csspp::decimal_number_to_string(min / 100.0, true) + "}"
    4733             : "sub{height:" + csspp::decimal_number_to_string(max / 100.0, true) + "}"
    4734             : "div{width:" + csspp::decimal_number_to_string(min / 100.0, true) + "em}"
    4735             : "sub{height:" + csspp::decimal_number_to_string(max / 100.0, true) + "em}"
    4736             : "div{width:" + csspp::decimal_number_to_string(min / 1.0, true) + "%}"
    4737             : "sub{height:" + csspp::decimal_number_to_string(max / 1.0, true) + "%}"
    4738             : "\n"
    4739             : + csspp_test::get_close_comment()
    4740             : 
    4741             :                     );
    4742             : 
    4743          10 :             CATCH_REQUIRE(c.get_root() == n);
    4744          10 :         }
    4745             :     }
    4746           1 :     CATCH_END_SECTION()
    4747             : 
    4748             :     // no error left over
    4749           1 :     VERIFY_ERRORS("");
    4750           1 : }
    4751             : 
    4752           1 : CATCH_TEST_CASE("Expression str_length()", "[expression] [internal-functions] [str-length]")
    4753             : {
    4754           1 :     CATCH_START_SECTION("check the str_length() function")
    4755             :     {
    4756          31 :         for(int i(0); i < 30; ++i)
    4757             :         {
    4758          30 :             std::stringstream ss;
    4759          90 :             csspp::position pos("test.css");
    4760          30 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4761             : 
    4762          30 :             std::string str;
    4763         465 :             for(int j(0); j < i; ++j)
    4764             :             {
    4765             :                 // ensure we check UTF-8 characters (because each such
    4766             :                 // character must be counted as 1 even though multiple
    4767             :                 // bytes are used)
    4768         435 :                 csspp::wide_char_t c(0);
    4769             :                 do
    4770             :                 {
    4771         870 :                     c = ((j & 1) == 0
    4772         435 :                             ? rand() % 26 + 'a'
    4773         210 :                             : rand() % (0x110000 - 0xC0) + 0xC0);
    4774             :                 }
    4775         435 :                 while(c < 'a' || (c >= 0xD800 && c <= 0xDFFF));
    4776         435 :                 char mb[6];
    4777         435 :                 l->wctomb(c, mb, sizeof(mb) / sizeof(mb[0]));
    4778         435 :                 str += mb;
    4779             :             }
    4780          30 :             ss << "p { z-index: str_length(\"" << str << "\") }";
    4781             : //std::cerr << "*** input = [" << ss.str() << "]\n";
    4782             : 
    4783          60 :             csspp::parser p(l);
    4784             : 
    4785          30 :             csspp::node::pointer_t n(p.stylesheet());
    4786             : 
    4787             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4788             : 
    4789          30 :             csspp::compiler c;
    4790          30 :             c.set_root(n);
    4791          30 :             c.set_date_time_variables(csspp_test::get_now());
    4792          30 :             c.add_path(csspp_test::get_script_path());
    4793          30 :             c.add_path(csspp_test::get_version_script_path());
    4794             : 
    4795          30 :             c.compile(false);
    4796             : 
    4797             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4798             : 
    4799             :             // to verify that the result is still an INTEGER we have to
    4800             :             // test the root node here
    4801          30 :             std::stringstream compiler_out;
    4802          30 :             compiler_out << *n;
    4803          30 :             VERIFY_TREES(compiler_out.str(),
    4804             : 
    4805             : "LIST\n"
    4806             : + csspp_test::get_default_variables() +
    4807             : "  COMPONENT_VALUE\n"
    4808             : "    ARG\n"
    4809             : "      IDENTIFIER \"p\"\n"
    4810             : "    OPEN_CURLYBRACKET B:true\n"
    4811             : "      DECLARATION \"z-index\"\n"
    4812             : "        ARG\n"
    4813             : "          INTEGER \"\" I:" + std::to_string(i) + "\n"
    4814             : + csspp_test::get_close_comment(true)
    4815             : 
    4816             :                 );
    4817             : 
    4818          30 :             std::stringstream assembler_out;
    4819          30 :             csspp::assembler a(assembler_out);
    4820          30 :             a.output(n, csspp::output_mode_t::COMPRESSED);
    4821             : 
    4822             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4823             : 
    4824          30 :             CATCH_REQUIRE(assembler_out.str() ==
    4825             : 
    4826             : "p{z-index:" + std::to_string(i) + "}\n"
    4827             : + csspp_test::get_close_comment()
    4828             : 
    4829             :                     );
    4830             : 
    4831          30 :             CATCH_REQUIRE(c.get_root() == n);
    4832          30 :         }
    4833             :     }
    4834           1 :     CATCH_END_SECTION()
    4835             : 
    4836             :     // no error left over
    4837           1 :     VERIFY_ERRORS("");
    4838           1 : }
    4839             : 
    4840           1 : CATCH_TEST_CASE("Expression type_of()", "[expression] [internal-functions] [type-of]")
    4841             : {
    4842           1 :     CATCH_START_SECTION("check the type_of() function")
    4843             :     {
    4844           1 :         std::stringstream ss;
    4845             :         ss << "p { content: type_of(\"string\") }\n"
    4846             :            << "div { content: type_of(12) }\n"
    4847             :            << "span { content: type_of(1.12) }\n"
    4848             :            << "q { content: type_of(15%) }\n"
    4849             :            << "s { content: type_of('string too') }\n"
    4850             :            << "b { content: type_of(true) }\n"
    4851             :            << "i { content: type_of(false) }\n"
    4852             :            << "sub { content: type_of(white) }\n"
    4853             :            << "sup { content: type_of(#ABC) }\n"
    4854             :            << "blockquote { content: type_of(U+9?\x3F) }\n"
    4855             :            << "span { content: type_of(('this', 'is', an, array)) }\n"
    4856             :            << "td { content: type_of((first: 'map', ever : 'tested', with :'csspp')) }\n"
    4857             :            << "th { content: type_of(null) }\n"
    4858           1 :            << "u { content: type_of(test) }\n";
    4859             : //std::cerr << "*** input = [" << ss.str() << "]\n";
    4860           3 :         csspp::position pos("test.css");
    4861           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    4862             : 
    4863             : 
    4864           2 :         csspp::parser p(l);
    4865             : 
    4866           1 :         csspp::node::pointer_t n(p.stylesheet());
    4867             : 
    4868             : //std::cerr << "Parser result is: [" << *n << "]\n";
    4869             : 
    4870           1 :         csspp::compiler c;
    4871           1 :         c.set_root(n);
    4872           1 :         c.set_date_time_variables(csspp_test::get_now());
    4873           1 :         c.add_path(csspp_test::get_script_path());
    4874           1 :         c.add_path(csspp_test::get_version_script_path());
    4875             : 
    4876           1 :         c.compile(false);
    4877             : 
    4878             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    4879             : 
    4880             :         // to verify that the result is still an INTEGER we have to
    4881             :         // test the root node here
    4882           1 :         std::stringstream compiler_out;
    4883           1 :         compiler_out << *n;
    4884           1 :         VERIFY_TREES(compiler_out.str(),
    4885             : 
    4886             : "LIST\n"
    4887             : + csspp_test::get_default_variables() +
    4888             : "  COMPONENT_VALUE\n"
    4889             : "    ARG\n"
    4890             : "      IDENTIFIER \"p\"\n"
    4891             : "    OPEN_CURLYBRACKET B:true\n"
    4892             : "      DECLARATION \"content\"\n"
    4893             : "        ARG\n"
    4894             : "          STRING \"string\"\n"
    4895             : "  COMPONENT_VALUE\n"
    4896             : "    ARG\n"
    4897             : "      IDENTIFIER \"div\"\n"
    4898             : "    OPEN_CURLYBRACKET B:true\n"
    4899             : "      DECLARATION \"content\"\n"
    4900             : "        ARG\n"
    4901             : "          STRING \"integer\"\n"
    4902             : "  COMPONENT_VALUE\n"
    4903             : "    ARG\n"
    4904             : "      IDENTIFIER \"span\"\n"
    4905             : "    OPEN_CURLYBRACKET B:true\n"
    4906             : "      DECLARATION \"content\"\n"
    4907             : "        ARG\n"
    4908             : "          STRING \"number\"\n"
    4909             : "  COMPONENT_VALUE\n"
    4910             : "    ARG\n"
    4911             : "      IDENTIFIER \"q\"\n"
    4912             : "    OPEN_CURLYBRACKET B:true\n"
    4913             : "      DECLARATION \"content\"\n"
    4914             : "        ARG\n"
    4915             : "          STRING \"number\"\n"
    4916             : "  COMPONENT_VALUE\n"
    4917             : "    ARG\n"
    4918             : "      IDENTIFIER \"s\"\n"
    4919             : "    OPEN_CURLYBRACKET B:true\n"
    4920             : "      DECLARATION \"content\"\n"
    4921             : "        ARG\n"
    4922             : "          STRING \"string\"\n"
    4923             : "  COMPONENT_VALUE\n"
    4924             : "    ARG\n"
    4925             : "      IDENTIFIER \"b\"\n"
    4926             : "    OPEN_CURLYBRACKET B:true\n"
    4927             : "      DECLARATION \"content\"\n"
    4928             : "        ARG\n"
    4929             : "          STRING \"bool\"\n"
    4930             : "  COMPONENT_VALUE\n"
    4931             : "    ARG\n"
    4932             : "      IDENTIFIER \"i\"\n"
    4933             : "    OPEN_CURLYBRACKET B:true\n"
    4934             : "      DECLARATION \"content\"\n"
    4935             : "        ARG\n"
    4936             : "          STRING \"bool\"\n"
    4937             : "  COMPONENT_VALUE\n"
    4938             : "    ARG\n"
    4939             : "      IDENTIFIER \"sub\"\n"
    4940             : "    OPEN_CURLYBRACKET B:true\n"
    4941             : "      DECLARATION \"content\"\n"
    4942             : "        ARG\n"
    4943             : "          STRING \"color\"\n"
    4944             : "  COMPONENT_VALUE\n"
    4945             : "    ARG\n"
    4946             : "      IDENTIFIER \"sup\"\n"
    4947             : "    OPEN_CURLYBRACKET B:true\n"
    4948             : "      DECLARATION \"content\"\n"
    4949             : "        ARG\n"
    4950             : "          STRING \"color\"\n"
    4951             : "  COMPONENT_VALUE\n"
    4952             : "    ARG\n"
    4953             : "      IDENTIFIER \"blockquote\"\n"
    4954             : "    OPEN_CURLYBRACKET B:true\n"
    4955             : "      DECLARATION \"content\"\n"
    4956             : "        ARG\n"
    4957             : "          STRING \"unicode-range\"\n"
    4958             : "  COMPONENT_VALUE\n"
    4959             : "    ARG\n"
    4960             : "      IDENTIFIER \"span\"\n"
    4961             : "    OPEN_CURLYBRACKET B:true\n"
    4962             : "      DECLARATION \"content\"\n"
    4963             : "        ARG\n"
    4964             : "          STRING \"list\"\n"
    4965             : "  COMPONENT_VALUE\n"
    4966             : "    ARG\n"
    4967             : "      IDENTIFIER \"td\"\n"
    4968             : "    OPEN_CURLYBRACKET B:true\n"
    4969             : "      DECLARATION \"content\"\n"
    4970             : "        ARG\n"
    4971             : "          STRING \"map\"\n"
    4972             : "  COMPONENT_VALUE\n"
    4973             : "    ARG\n"
    4974             : "      IDENTIFIER \"th\"\n"
    4975             : "    OPEN_CURLYBRACKET B:true\n"
    4976             : "      DECLARATION \"content\"\n"
    4977             : "        ARG\n"
    4978             : "          STRING \"undefined\"\n"
    4979             : "  COMPONENT_VALUE\n"
    4980             : "    ARG\n"
    4981             : "      IDENTIFIER \"u\"\n"
    4982             : "    OPEN_CURLYBRACKET B:true\n"
    4983             : "      DECLARATION \"content\"\n"
    4984             : "        ARG\n"
    4985             : "          STRING \"identifier\"\n"
    4986             : + csspp_test::get_close_comment(true)
    4987             : 
    4988             :             );
    4989             : 
    4990           1 :         std::stringstream assembler_out;
    4991           1 :         csspp::assembler a(assembler_out);
    4992           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    4993             : 
    4994             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    4995             : 
    4996           1 :         CATCH_REQUIRE(assembler_out.str() ==
    4997             : 
    4998             : "p{content:\"string\"}"
    4999             : "div{content:\"integer\"}"
    5000             : "span{content:\"number\"}"
    5001             : "q{content:\"number\"}"
    5002             : "s{content:\"string\"}"
    5003             : "b{content:\"bool\"}"
    5004             : "i{content:\"bool\"}"
    5005             : "sub{content:\"color\"}"
    5006             : "sup{content:\"color\"}"
    5007             : "blockquote{content:\"unicode-range\"}"
    5008             : "span{content:\"list\"}"
    5009             : "td{content:\"map\"}"
    5010             : "th{content:\"undefined\"}"
    5011             : "u{content:\"identifier\"}"
    5012             : "\n"
    5013             : + csspp_test::get_close_comment()
    5014             : 
    5015             :                 );
    5016             : 
    5017           1 :         CATCH_REQUIRE(c.get_root() == n);
    5018           1 :     }
    5019           1 :     CATCH_END_SECTION()
    5020             : 
    5021             :     // no error left over
    5022           1 :     VERIFY_ERRORS("");
    5023           1 : }
    5024             : 
    5025           2 : CATCH_TEST_CASE("Expression unit()", "[expression] [internal-functions] [unit]")
    5026             : {
    5027           2 :     CATCH_START_SECTION("check the unit() function -- standard CSS units")
    5028             :     {
    5029           1 :         std::stringstream ss;
    5030             :         ss << "p { content: unit(12) }\n"
    5031             :            << "div { content: unit(5px) }\n"
    5032             :            << "span { content: unit(1.12%) }\n"
    5033           1 :            << "q { content: unit(15.43em) }\n";
    5034             : //std::cerr << "*** input = [" << ss.str() << "]\n";
    5035           3 :         csspp::position pos("test.css");
    5036           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5037             : 
    5038             : 
    5039           2 :         csspp::parser p(l);
    5040             : 
    5041           1 :         csspp::node::pointer_t n(p.stylesheet());
    5042             : 
    5043             : //std::cerr << "Parser result is: [" << *n << "]\n";
    5044             : 
    5045           1 :         csspp::compiler c;
    5046           1 :         c.set_root(n);
    5047           1 :         c.set_date_time_variables(csspp_test::get_now());
    5048           1 :         c.add_path(csspp_test::get_script_path());
    5049           1 :         c.add_path(csspp_test::get_version_script_path());
    5050             : 
    5051           1 :         c.compile(false);
    5052             : 
    5053             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5054             : 
    5055             :         // to verify that the result is still an INTEGER we have to
    5056             :         // test the root node here
    5057           1 :         std::stringstream compiler_out;
    5058           1 :         compiler_out << *n;
    5059           1 :         VERIFY_TREES(compiler_out.str(),
    5060             : 
    5061             : "LIST\n"
    5062             : + csspp_test::get_default_variables() +
    5063             : "  COMPONENT_VALUE\n"
    5064             : "    ARG\n"
    5065             : "      IDENTIFIER \"p\"\n"
    5066             : "    OPEN_CURLYBRACKET B:true\n"
    5067             : "      DECLARATION \"content\"\n"
    5068             : "        ARG\n"
    5069             : "          STRING \"\"\n"
    5070             : "  COMPONENT_VALUE\n"
    5071             : "    ARG\n"
    5072             : "      IDENTIFIER \"div\"\n"
    5073             : "    OPEN_CURLYBRACKET B:true\n"
    5074             : "      DECLARATION \"content\"\n"
    5075             : "        ARG\n"
    5076             : "          STRING \"px\"\n"
    5077             : "  COMPONENT_VALUE\n"
    5078             : "    ARG\n"
    5079             : "      IDENTIFIER \"span\"\n"
    5080             : "    OPEN_CURLYBRACKET B:true\n"
    5081             : "      DECLARATION \"content\"\n"
    5082             : "        ARG\n"
    5083             : "          STRING \"%\"\n"
    5084             : "  COMPONENT_VALUE\n"
    5085             : "    ARG\n"
    5086             : "      IDENTIFIER \"q\"\n"
    5087             : "    OPEN_CURLYBRACKET B:true\n"
    5088             : "      DECLARATION \"content\"\n"
    5089             : "        ARG\n"
    5090             : "          STRING \"em\"\n"
    5091             : + csspp_test::get_close_comment(true)
    5092             : 
    5093             :             );
    5094             : 
    5095           1 :         std::stringstream assembler_out;
    5096           1 :         csspp::assembler a(assembler_out);
    5097           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5098             : 
    5099             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5100             : 
    5101           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5102             : 
    5103             : "p{content:\"\"}"
    5104             : "div{content:\"px\"}"
    5105             : "span{content:\"%\"}"
    5106             : "q{content:\"em\"}"
    5107             : "\n"
    5108             : + csspp_test::get_close_comment()
    5109             : 
    5110             :                 );
    5111             : 
    5112           1 :         CATCH_REQUIRE(c.get_root() == n);
    5113           1 :     }
    5114           2 :     CATCH_END_SECTION()
    5115             : 
    5116           2 :     CATCH_START_SECTION("check the unit() function -- non-standard CSS units")
    5117             :     {
    5118           1 :         std::stringstream ss;
    5119             :         ss << "p { content: unit(12px ** 2 / 17em) }\n"
    5120             :            << "div { content: unit(5px ** 3) }\n"
    5121           1 :            << "span { content: unit(1.12cm ** 3 / (3em ** 2)) }\n";
    5122             : //std::cerr << "*** input = [" << ss.str() << "]\n";
    5123           3 :         csspp::position pos("test.css");
    5124           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5125             : 
    5126             : 
    5127           2 :         csspp::parser p(l);
    5128             : 
    5129           1 :         csspp::node::pointer_t n(p.stylesheet());
    5130             : 
    5131             : //std::cerr << "Parser result is: [" << *n << "]\n";
    5132             : 
    5133           1 :         csspp::compiler c;
    5134           1 :         c.set_root(n);
    5135           1 :         c.set_date_time_variables(csspp_test::get_now());
    5136           1 :         c.add_path(csspp_test::get_script_path());
    5137           1 :         c.add_path(csspp_test::get_version_script_path());
    5138             : 
    5139           1 :         c.compile(false);
    5140             : 
    5141             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5142             : 
    5143             :         // to verify that the result is still an INTEGER we have to
    5144             :         // test the root node here
    5145           1 :         std::stringstream compiler_out;
    5146           1 :         compiler_out << *n;
    5147           1 :         VERIFY_TREES(compiler_out.str(),
    5148             : 
    5149             : "LIST\n"
    5150             : + csspp_test::get_default_variables() +
    5151             : "  COMPONENT_VALUE\n"
    5152             : "    ARG\n"
    5153             : "      IDENTIFIER \"p\"\n"
    5154             : "    OPEN_CURLYBRACKET B:true\n"
    5155             : "      DECLARATION \"content\"\n"
    5156             : "        ARG\n"
    5157             : "          STRING \"px * px / em\"\n"
    5158             : "  COMPONENT_VALUE\n"
    5159             : "    ARG\n"
    5160             : "      IDENTIFIER \"div\"\n"
    5161             : "    OPEN_CURLYBRACKET B:true\n"
    5162             : "      DECLARATION \"content\"\n"
    5163             : "        ARG\n"
    5164             : "          STRING \"px * px * px\"\n"
    5165             : "  COMPONENT_VALUE\n"
    5166             : "    ARG\n"
    5167             : "      IDENTIFIER \"span\"\n"
    5168             : "    OPEN_CURLYBRACKET B:true\n"
    5169             : "      DECLARATION \"content\"\n"
    5170             : "        ARG\n"
    5171             : "          STRING \"cm * cm * cm / em * em\"\n"
    5172             : + csspp_test::get_close_comment(true)
    5173             : 
    5174             :             );
    5175             : 
    5176           1 :         CATCH_REQUIRE(c.get_root() == n);
    5177           1 :     }
    5178           2 :     CATCH_END_SECTION()
    5179             : 
    5180             :     // no error left over
    5181           2 :     VERIFY_ERRORS("");
    5182           2 : }
    5183             : 
    5184           5 : CATCH_TEST_CASE("Expression decimal_number()/integer()/percentage()/string()/identifier()", "[expression] [internal-functions] [decimal-number] [integer] [percentage] [string] [identifier]")
    5185             : {
    5186           5 :     CATCH_START_SECTION("check conversions to decimal number")
    5187             :     {
    5188           1 :         std::stringstream ss;
    5189             :         ss << "div { z-index: decimal_number(314) }\n"
    5190             :            << "span { z-index: decimal_number(\"3.14\") }\n"
    5191             :            << "p { z-index: decimal_number('3.14px') }\n"
    5192             :            << "i { z-index: decimal_number(\\33\\.14) }\n"
    5193             :            << "q { z-index: decimal_number(3.14%) }\n"
    5194             :            << "s { z-index: decimal_number(\" 123 \") }\n"
    5195             :            << "b { z-index: decimal_number(\"123\") }\n"
    5196             :            << "u { z-index: decimal_number(1.23) }\n"
    5197           1 :            << "blockquote { z-index: decimal_number(\"1.23%\") }\n";
    5198             : //std::cerr << "*** from " << ss.str() << "\n";
    5199           3 :         csspp::position pos("test.css");
    5200           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5201             : 
    5202           2 :         csspp::parser p(l);
    5203             : 
    5204           1 :         csspp::node::pointer_t n(p.stylesheet());
    5205             : 
    5206             : //std::cerr << "Parser result is: [" << *n << "]\n";
    5207             : 
    5208           1 :         csspp::compiler c;
    5209           1 :         c.set_root(n);
    5210           1 :         c.set_date_time_variables(csspp_test::get_now());
    5211           1 :         c.add_path(csspp_test::get_script_path());
    5212           1 :         c.add_path(csspp_test::get_version_script_path());
    5213             : 
    5214           1 :         c.compile(false);
    5215             : 
    5216             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5217             : 
    5218             :         // to verify that the result is still an INTEGER we have to
    5219             :         // test the root node here
    5220           1 :         std::stringstream compiler_out;
    5221           1 :         compiler_out << *n;
    5222           1 :         VERIFY_TREES(compiler_out.str(),
    5223             : 
    5224             : "LIST\n"
    5225             : + csspp_test::get_default_variables() +
    5226             : "  COMPONENT_VALUE\n"
    5227             : "    ARG\n"
    5228             : "      IDENTIFIER \"div\"\n"
    5229             : "    OPEN_CURLYBRACKET B:true\n"
    5230             : "      DECLARATION \"z-index\"\n"
    5231             : "        ARG\n"
    5232             : "          DECIMAL_NUMBER \"\" D:314\n"
    5233             : "  COMPONENT_VALUE\n"
    5234             : "    ARG\n"
    5235             : "      IDENTIFIER \"span\"\n"
    5236             : "    OPEN_CURLYBRACKET B:true\n"
    5237             : "      DECLARATION \"z-index\"\n"
    5238             : "        ARG\n"
    5239             : "          DECIMAL_NUMBER \"\" D:3.14\n"
    5240             : "  COMPONENT_VALUE\n"
    5241             : "    ARG\n"
    5242             : "      IDENTIFIER \"p\"\n"
    5243             : "    OPEN_CURLYBRACKET B:true\n"
    5244             : "      DECLARATION \"z-index\"\n"
    5245             : "        ARG\n"
    5246             : "          DECIMAL_NUMBER \"px\" D:3.14\n"
    5247             : "  COMPONENT_VALUE\n"
    5248             : "    ARG\n"
    5249             : "      IDENTIFIER \"i\"\n"
    5250             : "    OPEN_CURLYBRACKET B:true\n"
    5251             : "      DECLARATION \"z-index\"\n"
    5252             : "        ARG\n"
    5253             : "          DECIMAL_NUMBER \"\" D:3.14\n"
    5254             : "  COMPONENT_VALUE\n"
    5255             : "    ARG\n"
    5256             : "      IDENTIFIER \"q\"\n"
    5257             : "    OPEN_CURLYBRACKET B:true\n"
    5258             : "      DECLARATION \"z-index\"\n"
    5259             : "        ARG\n"
    5260             : "          DECIMAL_NUMBER \"\" D:0.031\n"
    5261             : "  COMPONENT_VALUE\n"
    5262             : "    ARG\n"
    5263             : "      IDENTIFIER \"s\"\n"
    5264             : "    OPEN_CURLYBRACKET B:true\n"
    5265             : "      DECLARATION \"z-index\"\n"
    5266             : "        ARG\n"
    5267             : "          DECIMAL_NUMBER \"\" D:123\n"
    5268             : "  COMPONENT_VALUE\n"
    5269             : "    ARG\n"
    5270             : "      IDENTIFIER \"b\"\n"
    5271             : "    OPEN_CURLYBRACKET B:true\n"
    5272             : "      DECLARATION \"z-index\"\n"
    5273             : "        ARG\n"
    5274             : "          DECIMAL_NUMBER \"\" D:123\n"
    5275             : "  COMPONENT_VALUE\n"
    5276             : "    ARG\n"
    5277             : "      IDENTIFIER \"u\"\n"
    5278             : "    OPEN_CURLYBRACKET B:true\n"
    5279             : "      DECLARATION \"z-index\"\n"
    5280             : "        ARG\n"
    5281             : "          DECIMAL_NUMBER \"\" D:1.23\n"
    5282             : "  COMPONENT_VALUE\n"
    5283             : "    ARG\n"
    5284             : "      IDENTIFIER \"blockquote\"\n"
    5285             : "    OPEN_CURLYBRACKET B:true\n"
    5286             : "      DECLARATION \"z-index\"\n"
    5287             : "        ARG\n"
    5288             : "          DECIMAL_NUMBER \"\" D:0.012\n"
    5289             : + csspp_test::get_close_comment(true)
    5290             : 
    5291             :             );
    5292             : 
    5293           1 :         std::stringstream assembler_out;
    5294           1 :         csspp::assembler a(assembler_out);
    5295           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5296             : 
    5297             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5298             : 
    5299           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5300             : 
    5301             : "div{z-index:314}"
    5302             : "span{z-index:3.14}"
    5303             : "p{z-index:3.14px}"
    5304             : "i{z-index:3.14}"
    5305             : "q{z-index:.031}"
    5306             : "s{z-index:123}"
    5307             : "b{z-index:123}"
    5308             : "u{z-index:1.23}"
    5309             : "blockquote{z-index:.012}"
    5310             : "\n"
    5311             : + csspp_test::get_close_comment()
    5312             : 
    5313             :                 );
    5314             : 
    5315           1 :         CATCH_REQUIRE(c.get_root() == n);
    5316           1 :     }
    5317           5 :     CATCH_END_SECTION()
    5318             : 
    5319           5 :     CATCH_START_SECTION("check conversions to integer")
    5320             :     {
    5321           1 :         std::stringstream ss;
    5322             :         ss << "div { z-index: integer(314) }\n"
    5323             :            << "span { z-index: integer(\"3.14\") }\n"
    5324             :            << "p { z-index: integer('3.14px') }\n"
    5325             :            << "i { z-index: integer(\\33\\.14) }\n"
    5326             :            << "q { z-index: integer(314%) }\n"
    5327             :            << "s { z-index: integer(\" 123 \") }\n"
    5328             :            << "b { z-index: integer(\"123\") }\n"
    5329             :            << "u { z-index: integer(1.23) }\n"
    5330           1 :            << "blockquote { z-index: integer('314%') }\n";
    5331             : //std::cerr << "*** from " << ss.str() << "\n";
    5332           3 :         csspp::position pos("test.css");
    5333           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5334             : 
    5335           2 :         csspp::parser p(l);
    5336             : 
    5337           1 :         csspp::node::pointer_t n(p.stylesheet());
    5338             : 
    5339             : //std::cerr << "Parser result is: [" << *n << "]\n";
    5340             : 
    5341           1 :         csspp::compiler c;
    5342           1 :         c.set_root(n);
    5343           1 :         c.set_date_time_variables(csspp_test::get_now());
    5344           1 :         c.add_path(csspp_test::get_script_path());
    5345           1 :         c.add_path(csspp_test::get_version_script_path());
    5346             : 
    5347           1 :         c.compile(false);
    5348             : 
    5349             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5350             : 
    5351             :         // to verify that the result is still an INTEGER we have to
    5352             :         // test the root node here
    5353           1 :         std::stringstream compiler_out;
    5354           1 :         compiler_out << *n;
    5355           1 :         VERIFY_TREES(compiler_out.str(),
    5356             : 
    5357             : "LIST\n"
    5358             : + csspp_test::get_default_variables() +
    5359             : "  COMPONENT_VALUE\n"
    5360             : "    ARG\n"
    5361             : "      IDENTIFIER \"div\"\n"
    5362             : "    OPEN_CURLYBRACKET B:true\n"
    5363             : "      DECLARATION \"z-index\"\n"
    5364             : "        ARG\n"
    5365             : "          INTEGER \"\" I:314\n"
    5366             : "  COMPONENT_VALUE\n"
    5367             : "    ARG\n"
    5368             : "      IDENTIFIER \"span\"\n"
    5369             : "    OPEN_CURLYBRACKET B:true\n"
    5370             : "      DECLARATION \"z-index\"\n"
    5371             : "        ARG\n"
    5372             : "          INTEGER \"\" I:3\n"
    5373             : "  COMPONENT_VALUE\n"
    5374             : "    ARG\n"
    5375             : "      IDENTIFIER \"p\"\n"
    5376             : "    OPEN_CURLYBRACKET B:true\n"
    5377             : "      DECLARATION \"z-index\"\n"
    5378             : "        ARG\n"
    5379             : "          INTEGER \"px\" I:3\n"
    5380             : "  COMPONENT_VALUE\n"
    5381             : "    ARG\n"
    5382             : "      IDENTIFIER \"i\"\n"
    5383             : "    OPEN_CURLYBRACKET B:true\n"
    5384             : "      DECLARATION \"z-index\"\n"
    5385             : "        ARG\n"
    5386             : "          INTEGER \"\" I:3\n"
    5387             : "  COMPONENT_VALUE\n"
    5388             : "    ARG\n"
    5389             : "      IDENTIFIER \"q\"\n"
    5390             : "    OPEN_CURLYBRACKET B:true\n"
    5391             : "      DECLARATION \"z-index\"\n"
    5392             : "        ARG\n"
    5393             : "          INTEGER \"\" I:3\n"
    5394             : "  COMPONENT_VALUE\n"
    5395             : "    ARG\n"
    5396             : "      IDENTIFIER \"s\"\n"
    5397             : "    OPEN_CURLYBRACKET B:true\n"
    5398             : "      DECLARATION \"z-index\"\n"
    5399             : "        ARG\n"
    5400             : "          INTEGER \"\" I:123\n"
    5401             : "  COMPONENT_VALUE\n"
    5402             : "    ARG\n"
    5403             : "      IDENTIFIER \"b\"\n"
    5404             : "    OPEN_CURLYBRACKET B:true\n"
    5405             : "      DECLARATION \"z-index\"\n"
    5406             : "        ARG\n"
    5407             : "          INTEGER \"\" I:123\n"
    5408             : "  COMPONENT_VALUE\n"
    5409             : "    ARG\n"
    5410             : "      IDENTIFIER \"u\"\n"
    5411             : "    OPEN_CURLYBRACKET B:true\n"
    5412             : "      DECLARATION \"z-index\"\n"
    5413             : "        ARG\n"
    5414             : "          INTEGER \"\" I:1\n"
    5415             : "  COMPONENT_VALUE\n"
    5416             : "    ARG\n"
    5417             : "      IDENTIFIER \"blockquote\"\n"
    5418             : "    OPEN_CURLYBRACKET B:true\n"
    5419             : "      DECLARATION \"z-index\"\n"
    5420             : "        ARG\n"
    5421             : "          INTEGER \"\" I:3\n"
    5422             : + csspp_test::get_close_comment(true)
    5423             : 
    5424             :             );
    5425             : 
    5426           1 :         std::stringstream assembler_out;
    5427           1 :         csspp::assembler a(assembler_out);
    5428           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5429             : 
    5430             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5431             : 
    5432           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5433             : 
    5434             : "div{z-index:314}"
    5435             : "span{z-index:3}"
    5436             : "p{z-index:3px}"
    5437             : "i{z-index:3}"
    5438             : "q{z-index:3}"
    5439             : "s{z-index:123}"
    5440             : "b{z-index:123}"
    5441             : "u{z-index:1}"
    5442             : "blockquote{z-index:3}"
    5443             : "\n"
    5444             : + csspp_test::get_close_comment()
    5445             : 
    5446             :                 );
    5447             : 
    5448           1 :         CATCH_REQUIRE(c.get_root() == n);
    5449           1 :     }
    5450           5 :     CATCH_END_SECTION()
    5451             : 
    5452           5 :     CATCH_START_SECTION("check conversions to percentage")
    5453             :     {
    5454           1 :         std::stringstream ss;
    5455             :         ss << "div { z-index: percentage(314) }\n"
    5456             :            << "span { z-index: percentage(\"3.14\") }\n"
    5457             :            << "p { z-index: percentage('3.14px') }\n"
    5458             :            << "i { z-index: percentage(\\33\\.14) }\n"
    5459             :            << "q { z-index: percentage(3.14%) }\n"
    5460             :            << "s { z-index: percentage(\" 123 \") }\n"
    5461             :            << "b { z-index: percentage(\"123\") }\n"
    5462             :            << "u { z-index: percentage(1.23) }\n"
    5463           1 :            << "blockquote { z-index: percentage(\"1.23%\") }\n";
    5464             : //std::cerr << "*** from " << ss.str() << "\n";
    5465           3 :         csspp::position pos("test.css");
    5466           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5467             : 
    5468           2 :         csspp::parser p(l);
    5469             : 
    5470           1 :         csspp::node::pointer_t n(p.stylesheet());
    5471             : 
    5472             : //std::cerr << "Parser result is: [" << *n << "]\n";
    5473             : 
    5474           1 :         csspp::compiler c;
    5475           1 :         c.set_root(n);
    5476           1 :         c.set_date_time_variables(csspp_test::get_now());
    5477           1 :         c.add_path(csspp_test::get_script_path());
    5478           1 :         c.add_path(csspp_test::get_version_script_path());
    5479             : 
    5480           1 :         c.compile(false);
    5481             : 
    5482             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5483             : 
    5484             :         // to verify that the result is still an INTEGER we have to
    5485             :         // test the root node here
    5486           1 :         std::stringstream compiler_out;
    5487           1 :         compiler_out << *n;
    5488           1 :         VERIFY_TREES(compiler_out.str(),
    5489             : 
    5490             : "LIST\n"
    5491             : + csspp_test::get_default_variables() +
    5492             : "  COMPONENT_VALUE\n"
    5493             : "    ARG\n"
    5494             : "      IDENTIFIER \"div\"\n"
    5495             : "    OPEN_CURLYBRACKET B:true\n"
    5496             : "      DECLARATION \"z-index\"\n"
    5497             : "        ARG\n"
    5498             : "          PERCENT D:314\n"
    5499             : "  COMPONENT_VALUE\n"
    5500             : "    ARG\n"
    5501             : "      IDENTIFIER \"span\"\n"
    5502             : "    OPEN_CURLYBRACKET B:true\n"
    5503             : "      DECLARATION \"z-index\"\n"
    5504             : "        ARG\n"
    5505             : "          PERCENT D:3.14\n"
    5506             : "  COMPONENT_VALUE\n"
    5507             : "    ARG\n"
    5508             : "      IDENTIFIER \"p\"\n"
    5509             : "    OPEN_CURLYBRACKET B:true\n"
    5510             : "      DECLARATION \"z-index\"\n"
    5511             : "        ARG\n"
    5512             : "          PERCENT D:3.14\n"
    5513             : "  COMPONENT_VALUE\n"
    5514             : "    ARG\n"
    5515             : "      IDENTIFIER \"i\"\n"
    5516             : "    OPEN_CURLYBRACKET B:true\n"
    5517             : "      DECLARATION \"z-index\"\n"
    5518             : "        ARG\n"
    5519             : "          PERCENT D:3.14\n"
    5520             : "  COMPONENT_VALUE\n"
    5521             : "    ARG\n"
    5522             : "      IDENTIFIER \"q\"\n"
    5523             : "    OPEN_CURLYBRACKET B:true\n"
    5524             : "      DECLARATION \"z-index\"\n"
    5525             : "        ARG\n"
    5526             : "          PERCENT D:0.031\n"
    5527             : "  COMPONENT_VALUE\n"
    5528             : "    ARG\n"
    5529             : "      IDENTIFIER \"s\"\n"
    5530             : "    OPEN_CURLYBRACKET B:true\n"
    5531             : "      DECLARATION \"z-index\"\n"
    5532             : "        ARG\n"
    5533             : "          PERCENT D:123\n"
    5534             : "  COMPONENT_VALUE\n"
    5535             : "    ARG\n"
    5536             : "      IDENTIFIER \"b\"\n"
    5537             : "    OPEN_CURLYBRACKET B:true\n"
    5538             : "      DECLARATION \"z-index\"\n"
    5539             : "        ARG\n"
    5540             : "          PERCENT D:123\n"
    5541             : "  COMPONENT_VALUE\n"
    5542             : "    ARG\n"
    5543             : "      IDENTIFIER \"u\"\n"
    5544             : "    OPEN_CURLYBRACKET B:true\n"
    5545             : "      DECLARATION \"z-index\"\n"
    5546             : "        ARG\n"
    5547             : "          PERCENT D:1.23\n"
    5548             : "  COMPONENT_VALUE\n"
    5549             : "    ARG\n"
    5550             : "      IDENTIFIER \"blockquote\"\n"
    5551             : "    OPEN_CURLYBRACKET B:true\n"
    5552             : "      DECLARATION \"z-index\"\n"
    5553             : "        ARG\n"
    5554             : "          PERCENT D:0.012\n"
    5555             : + csspp_test::get_close_comment(true)
    5556             : 
    5557             :             );
    5558             : 
    5559           1 :         std::stringstream assembler_out;
    5560           1 :         csspp::assembler a(assembler_out);
    5561           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5562             : 
    5563             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5564             : 
    5565           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5566             : 
    5567             : "div{z-index:31400%}"
    5568             : "span{z-index:314%}"
    5569             : "p{z-index:314%}"
    5570             : "i{z-index:314%}"
    5571             : "q{z-index:3.14%}"
    5572             : "s{z-index:12300%}"
    5573             : "b{z-index:12300%}"
    5574             : "u{z-index:123%}"
    5575             : "blockquote{z-index:1.23%}"
    5576             : "\n"
    5577             : + csspp_test::get_close_comment()
    5578             : 
    5579             :                 );
    5580             : 
    5581           1 :         CATCH_REQUIRE(c.get_root() == n);
    5582           1 :     }
    5583           5 :     CATCH_END_SECTION()
    5584             : 
    5585           5 :     CATCH_START_SECTION("check conversions to string")
    5586             :     {
    5587           1 :         std::stringstream ss;
    5588             :         ss << "div { z-index: string(314) }\n"
    5589             :            << "span { z-index: string(\"3.14\") }\n"
    5590             :            << "p { z-index: string('3.14px') }\n"
    5591             :            << "i { z-index: string(\\33\\.14) }\n"
    5592             :            << "q { z-index: string(3.14%) }\n"
    5593             :            << "s { z-index: string(\" 123 \") }\n"
    5594             :            << "b { z-index: string(\"123\") }\n"
    5595           1 :            << "u { z-index: string(1.23) }\n";
    5596             : //std::cerr << "*** from " << ss.str() << "\n";
    5597           3 :         csspp::position pos("test.css");
    5598           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5599             : 
    5600           2 :         csspp::parser p(l);
    5601             : 
    5602           1 :         csspp::node::pointer_t n(p.stylesheet());
    5603             : 
    5604             : //std::cerr << "Parser result is: [" << *n << "]\n";
    5605             : 
    5606           1 :         csspp::compiler c;
    5607           1 :         c.set_root(n);
    5608           1 :         c.set_date_time_variables(csspp_test::get_now());
    5609           1 :         c.add_path(csspp_test::get_script_path());
    5610           1 :         c.add_path(csspp_test::get_version_script_path());
    5611             : 
    5612           1 :         c.compile(false);
    5613             : 
    5614             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5615             : 
    5616             :         // to verify that the result is still an INTEGER we have to
    5617             :         // test the root node here
    5618           1 :         std::stringstream compiler_out;
    5619           1 :         compiler_out << *n;
    5620           1 :         VERIFY_TREES(compiler_out.str(),
    5621             : 
    5622             : "LIST\n"
    5623             : + csspp_test::get_default_variables() +
    5624             : "  COMPONENT_VALUE\n"
    5625             : "    ARG\n"
    5626             : "      IDENTIFIER \"div\"\n"
    5627             : "    OPEN_CURLYBRACKET B:true\n"
    5628             : "      DECLARATION \"z-index\"\n"
    5629             : "        ARG\n"
    5630             : "          STRING \"314\"\n"
    5631             : "  COMPONENT_VALUE\n"
    5632             : "    ARG\n"
    5633             : "      IDENTIFIER \"span\"\n"
    5634             : "    OPEN_CURLYBRACKET B:true\n"
    5635             : "      DECLARATION \"z-index\"\n"
    5636             : "        ARG\n"
    5637             : "          STRING \"3.14\"\n"
    5638             : "  COMPONENT_VALUE\n"
    5639             : "    ARG\n"
    5640             : "      IDENTIFIER \"p\"\n"
    5641             : "    OPEN_CURLYBRACKET B:true\n"
    5642             : "      DECLARATION \"z-index\"\n"
    5643             : "        ARG\n"
    5644             : "          STRING \"3.14px\"\n"
    5645             : "  COMPONENT_VALUE\n"
    5646             : "    ARG\n"
    5647             : "      IDENTIFIER \"i\"\n"
    5648             : "    OPEN_CURLYBRACKET B:true\n"
    5649             : "      DECLARATION \"z-index\"\n"
    5650             : "        ARG\n"
    5651             : "          STRING \"3.14\"\n"
    5652             : "  COMPONENT_VALUE\n"
    5653             : "    ARG\n"
    5654             : "      IDENTIFIER \"q\"\n"
    5655             : "    OPEN_CURLYBRACKET B:true\n"
    5656             : "      DECLARATION \"z-index\"\n"
    5657             : "        ARG\n"
    5658             : "          STRING \"3.14%\"\n"
    5659             : "  COMPONENT_VALUE\n"
    5660             : "    ARG\n"
    5661             : "      IDENTIFIER \"s\"\n"
    5662             : "    OPEN_CURLYBRACKET B:true\n"
    5663             : "      DECLARATION \"z-index\"\n"
    5664             : "        ARG\n"
    5665             : "          STRING \" 123 \"\n"
    5666             : "  COMPONENT_VALUE\n"
    5667             : "    ARG\n"
    5668             : "      IDENTIFIER \"b\"\n"
    5669             : "    OPEN_CURLYBRACKET B:true\n"
    5670             : "      DECLARATION \"z-index\"\n"
    5671             : "        ARG\n"
    5672             : "          STRING \"123\"\n"
    5673             : "  COMPONENT_VALUE\n"
    5674             : "    ARG\n"
    5675             : "      IDENTIFIER \"u\"\n"
    5676             : "    OPEN_CURLYBRACKET B:true\n"
    5677             : "      DECLARATION \"z-index\"\n"
    5678             : "        ARG\n"
    5679             : "          STRING \"1.23\"\n"
    5680             : + csspp_test::get_close_comment(true)
    5681             : 
    5682             :             );
    5683             : 
    5684           1 :         std::stringstream assembler_out;
    5685           1 :         csspp::assembler a(assembler_out);
    5686           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5687             : 
    5688             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5689             : 
    5690           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5691             : 
    5692             : "div{z-index:\"314\"}"
    5693             : "span{z-index:\"3.14\"}"
    5694             : "p{z-index:\"3.14px\"}"
    5695             : "i{z-index:\"3.14\"}"
    5696             : "q{z-index:\"3.14%\"}"
    5697             : "s{z-index:\" 123 \"}"
    5698             : "b{z-index:\"123\"}"
    5699             : "u{z-index:\"1.23\"}"
    5700             : "\n"
    5701             : + csspp_test::get_close_comment()
    5702             : 
    5703             :                 );
    5704             : 
    5705           1 :         CATCH_REQUIRE(c.get_root() == n);
    5706           1 :     }
    5707           5 :     CATCH_END_SECTION()
    5708             : 
    5709           5 :     CATCH_START_SECTION("check conversions to identifiers")
    5710             :     {
    5711           1 :         std::stringstream ss;
    5712             :         ss << "div { z-index: identifier(test) }\n"
    5713             :            << "span { z-index: identifier(\"test\") }\n"
    5714             :            << "p { z-index: identifier('test') }\n"
    5715             :            << "i { z-index: identifier(123) }\n"
    5716             :            << "q { z-index: identifier(1.23%) }\n"
    5717             :            << "s { z-index: identifier(\" 123 \") }\n"
    5718             :            << "b { z-index: identifier(\"123\") }\n"
    5719           1 :            << "u { z-index: identifier(1.23) }\n";
    5720             : //std::cerr << "*** from " << ss.str() << "\n";
    5721           3 :         csspp::position pos("test.css");
    5722           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5723             : 
    5724           2 :         csspp::parser p(l);
    5725             : 
    5726           1 :         csspp::node::pointer_t n(p.stylesheet());
    5727             : 
    5728             : //std::cerr << "Parser result is: [" << *n << "]\n";
    5729             : 
    5730           1 :         csspp::compiler c;
    5731           1 :         c.set_root(n);
    5732           1 :         c.set_date_time_variables(csspp_test::get_now());
    5733           1 :         c.add_path(csspp_test::get_script_path());
    5734           1 :         c.add_path(csspp_test::get_version_script_path());
    5735             : 
    5736           1 :         c.compile(false);
    5737             : 
    5738             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5739             : 
    5740             :         // to verify that the result is still an INTEGER we have to
    5741             :         // test the root node here
    5742           1 :         std::stringstream compiler_out;
    5743           1 :         compiler_out << *n;
    5744           1 :         VERIFY_TREES(compiler_out.str(),
    5745             : 
    5746             : "LIST\n"
    5747             : + csspp_test::get_default_variables() +
    5748             : "  COMPONENT_VALUE\n"
    5749             : "    ARG\n"
    5750             : "      IDENTIFIER \"div\"\n"
    5751             : "    OPEN_CURLYBRACKET B:true\n"
    5752             : "      DECLARATION \"z-index\"\n"
    5753             : "        ARG\n"
    5754             : "          IDENTIFIER \"test\"\n"
    5755             : "  COMPONENT_VALUE\n"
    5756             : "    ARG\n"
    5757             : "      IDENTIFIER \"span\"\n"
    5758             : "    OPEN_CURLYBRACKET B:true\n"
    5759             : "      DECLARATION \"z-index\"\n"
    5760             : "        ARG\n"
    5761             : "          IDENTIFIER \"test\"\n"
    5762             : "  COMPONENT_VALUE\n"
    5763             : "    ARG\n"
    5764             : "      IDENTIFIER \"p\"\n"
    5765             : "    OPEN_CURLYBRACKET B:true\n"
    5766             : "      DECLARATION \"z-index\"\n"
    5767             : "        ARG\n"
    5768             : "          IDENTIFIER \"test\"\n"
    5769             : "  COMPONENT_VALUE\n"
    5770             : "    ARG\n"
    5771             : "      IDENTIFIER \"i\"\n"
    5772             : "    OPEN_CURLYBRACKET B:true\n"
    5773             : "      DECLARATION \"z-index\"\n"
    5774             : "        ARG\n"
    5775             : "          IDENTIFIER \"123\"\n"
    5776             : "  COMPONENT_VALUE\n"
    5777             : "    ARG\n"
    5778             : "      IDENTIFIER \"q\"\n"
    5779             : "    OPEN_CURLYBRACKET B:true\n"
    5780             : "      DECLARATION \"z-index\"\n"
    5781             : "        ARG\n"
    5782             : "          IDENTIFIER \"1.23%\"\n"
    5783             : "  COMPONENT_VALUE\n"
    5784             : "    ARG\n"
    5785             : "      IDENTIFIER \"s\"\n"
    5786             : "    OPEN_CURLYBRACKET B:true\n"
    5787             : "      DECLARATION \"z-index\"\n"
    5788             : "        ARG\n"
    5789             : "          IDENTIFIER \" 123 \"\n"
    5790             : "  COMPONENT_VALUE\n"
    5791             : "    ARG\n"
    5792             : "      IDENTIFIER \"b\"\n"
    5793             : "    OPEN_CURLYBRACKET B:true\n"
    5794             : "      DECLARATION \"z-index\"\n"
    5795             : "        ARG\n"
    5796             : "          IDENTIFIER \"123\"\n"
    5797             : "  COMPONENT_VALUE\n"
    5798             : "    ARG\n"
    5799             : "      IDENTIFIER \"u\"\n"
    5800             : "    OPEN_CURLYBRACKET B:true\n"
    5801             : "      DECLARATION \"z-index\"\n"
    5802             : "        ARG\n"
    5803             : "          IDENTIFIER \"1.23\"\n"
    5804             : + csspp_test::get_close_comment(true)
    5805             : 
    5806             :             );
    5807             : 
    5808           1 :         std::stringstream assembler_out;
    5809           1 :         csspp::assembler a(assembler_out);
    5810           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
    5811             : 
    5812             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
    5813             : 
    5814           1 :         CATCH_REQUIRE(assembler_out.str() ==
    5815             : 
    5816             : "div{z-index:test}"
    5817             : "span{z-index:test}"
    5818             : "p{z-index:test}"
    5819             : "i{z-index:\\31 23}"
    5820             : "q{z-index:\\31\\.23\\%}"
    5821             : "s{z-index:\\ 123\\ }"
    5822             : "b{z-index:\\31 23}"
    5823             : "u{z-index:\\31\\.23}"
    5824             : "\n"
    5825             : + csspp_test::get_close_comment()
    5826             : 
    5827             :                 );
    5828             : 
    5829           1 :         CATCH_REQUIRE(c.get_root() == n);
    5830           1 :     }
    5831           5 :     CATCH_END_SECTION()
    5832             : 
    5833             :     // no error left over
    5834           5 :     VERIFY_ERRORS("");
    5835           5 : }
    5836             : 
    5837           6 : CATCH_TEST_CASE("Invalid sub-expression decimal_number()/integer()/string()/identifier()", "[expression] [internal-functions] [decimal-number] [integer] [string] [identifier] [invalid]")
    5838             : {
    5839           6 :     CATCH_START_SECTION("check conversions to decimal number with an invalid string")
    5840             :     {
    5841           1 :         std::stringstream ss;
    5842           1 :         ss << "div { z-index: decimal_number(\"invalid\") }\n";
    5843           3 :         csspp::position pos("test.css");
    5844           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5845             : 
    5846           2 :         csspp::parser p(l);
    5847             : 
    5848           1 :         csspp::node::pointer_t n(p.stylesheet());
    5849             : 
    5850             : //std::cerr << "Parser result is: [" << *n << "]\n";
    5851             : 
    5852           1 :         csspp::compiler c;
    5853           1 :         c.set_root(n);
    5854           1 :         c.set_date_time_variables(csspp_test::get_now());
    5855           1 :         c.add_path(csspp_test::get_script_path());
    5856           1 :         c.add_path(csspp_test::get_version_script_path());
    5857             : 
    5858           1 :         c.compile(false);
    5859             : 
    5860             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5861             : 
    5862           1 :         VERIFY_ERRORS("test.css(1): error: decimal_number() expects a string parameter to represent a valid integer, decimal number, or percent value.\n");
    5863             : 
    5864           1 :         CATCH_REQUIRE(c.get_root() == n);
    5865           1 :     }
    5866           6 :     CATCH_END_SECTION()
    5867             : 
    5868           6 :     CATCH_START_SECTION("check decimal number without a parameter")
    5869             :     {
    5870           1 :         std::stringstream ss;
    5871           1 :         ss << "div { z-index: decimal_number() }\n";
    5872           3 :         csspp::position pos("test.css");
    5873           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5874             : 
    5875           2 :         csspp::parser p(l);
    5876             : 
    5877           1 :         csspp::node::pointer_t n(p.stylesheet());
    5878             : 
    5879             : //std::cerr << "Parser result is: [" << *n << "]\n";
    5880             : 
    5881           1 :         csspp::compiler c;
    5882           1 :         c.set_root(n);
    5883           1 :         c.set_date_time_variables(csspp_test::get_now());
    5884           1 :         c.add_path(csspp_test::get_script_path());
    5885           1 :         c.add_path(csspp_test::get_version_script_path());
    5886             : 
    5887           1 :         c.compile(false);
    5888             : 
    5889             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5890             : 
    5891           1 :         VERIFY_ERRORS("test.css(1): error: decimal_number() expects exactly 1 parameter.\n");
    5892             : 
    5893           1 :         CATCH_REQUIRE(c.get_root() == n);
    5894           1 :     }
    5895           6 :     CATCH_END_SECTION()
    5896             : 
    5897           6 :     CATCH_START_SECTION("check conversions to decimal number with a unicode range")
    5898             :     {
    5899           1 :         std::stringstream ss;
    5900           1 :         ss << "div { z-index: decimal_number(U+1-5) }\n";
    5901           3 :         csspp::position pos("test.css");
    5902           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5903             : 
    5904           2 :         csspp::parser p(l);
    5905             : 
    5906           1 :         csspp::node::pointer_t n(p.stylesheet());
    5907             : 
    5908             : //std::cerr << "Parser result is: [" << *n << "]\n";
    5909             : 
    5910           1 :         csspp::compiler c;
    5911           1 :         c.set_root(n);
    5912           1 :         c.set_date_time_variables(csspp_test::get_now());
    5913           1 :         c.add_path(csspp_test::get_script_path());
    5914           1 :         c.add_path(csspp_test::get_version_script_path());
    5915             : 
    5916           1 :         c.compile(false);
    5917             : 
    5918             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5919             : 
    5920           1 :         VERIFY_ERRORS(
    5921             :                 "test.css(1): error: decimal_number() expects one value as parameter.\n"
    5922             :             );
    5923             : 
    5924           1 :         CATCH_REQUIRE(c.get_root() == n);
    5925           1 :     }
    5926           6 :     CATCH_END_SECTION()
    5927             : 
    5928           6 :     CATCH_START_SECTION("check conversions to integer with an invalid string")
    5929             :     {
    5930           1 :         std::stringstream ss;
    5931           1 :         ss << "div { z-index: integer(\"invalid\") }\n";
    5932           3 :         csspp::position pos("test.css");
    5933           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5934             : 
    5935           2 :         csspp::parser p(l);
    5936             : 
    5937           1 :         csspp::node::pointer_t n(p.stylesheet());
    5938             : 
    5939             : //std::cerr << "Parser result is: [" << *n << "]\n";
    5940             : 
    5941           1 :         csspp::compiler c;
    5942           1 :         c.set_root(n);
    5943           1 :         c.set_date_time_variables(csspp_test::get_now());
    5944           1 :         c.add_path(csspp_test::get_script_path());
    5945           1 :         c.add_path(csspp_test::get_version_script_path());
    5946             : 
    5947           1 :         c.compile(false);
    5948             : 
    5949             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5950             : 
    5951           1 :         VERIFY_ERRORS("test.css(1): error: decimal_number() expects a string parameter to represent a valid integer, decimal number, or percent value.\n");
    5952             : 
    5953           1 :         CATCH_REQUIRE(c.get_root() == n);
    5954           1 :     }
    5955           6 :     CATCH_END_SECTION()
    5956             : 
    5957           6 :     CATCH_START_SECTION("check conversions to integer with an invalid expression as parameter")
    5958             :     {
    5959           1 :         std::stringstream ss;
    5960           1 :         ss << "div { z-index: integer(?) }\n";
    5961           3 :         csspp::position pos("test.css");
    5962           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5963             : 
    5964           2 :         csspp::parser p(l);
    5965             : 
    5966           1 :         csspp::node::pointer_t n(p.stylesheet());
    5967             : 
    5968             : //std::cerr << "Parser result is: [" << *n << "]\n";
    5969             : 
    5970           1 :         csspp::compiler c;
    5971           1 :         c.set_root(n);
    5972           1 :         c.set_date_time_variables(csspp_test::get_now());
    5973           1 :         c.add_path(csspp_test::get_script_path());
    5974           1 :         c.add_path(csspp_test::get_version_script_path());
    5975             : 
    5976           1 :         c.compile(false);
    5977             : 
    5978             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    5979             : 
    5980           1 :         VERIFY_ERRORS(
    5981             :                 "test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n"
    5982             :                 "test.css(1): error: integer() expects one value as parameter.\n"
    5983             :             );
    5984             : 
    5985           1 :         CATCH_REQUIRE(c.get_root() == n);
    5986           1 :     }
    5987           6 :     CATCH_END_SECTION()
    5988             : 
    5989           6 :     CATCH_START_SECTION("check conversions to integer with a unicode range")
    5990             :     {
    5991           1 :         std::stringstream ss;
    5992           1 :         ss << "div { z-index: integer(U+1-5) }\n";
    5993           3 :         csspp::position pos("test.css");
    5994           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    5995             : 
    5996           2 :         csspp::parser p(l);
    5997             : 
    5998           1 :         csspp::node::pointer_t n(p.stylesheet());
    5999             : 
    6000             : //std::cerr << "Parser result is: [" << *n << "]\n";
    6001             : 
    6002           1 :         csspp::compiler c;
    6003           1 :         c.set_root(n);
    6004           1 :         c.set_date_time_variables(csspp_test::get_now());
    6005           1 :         c.add_path(csspp_test::get_script_path());
    6006           1 :         c.add_path(csspp_test::get_version_script_path());
    6007             : 
    6008           1 :         c.compile(false);
    6009             : 
    6010             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6011             : 
    6012           1 :         VERIFY_ERRORS(
    6013             :                 "test.css(1): error: integer() expects one value as parameter.\n"
    6014             :             );
    6015             : 
    6016           1 :         CATCH_REQUIRE(c.get_root() == n);
    6017           1 :     }
    6018           6 :     CATCH_END_SECTION()
    6019             : 
    6020             :     // no error left over
    6021           6 :     VERIFY_ERRORS("");
    6022           6 : }
    6023             : 
    6024          63 : CATCH_TEST_CASE("Expression calling functions with invalid parameters", "[expression] [internal-functions] [invalid]")
    6025             : {
    6026          63 :     CATCH_START_SECTION("abs(\"wrong\")")
    6027             :     {
    6028           1 :         std::stringstream ss;
    6029           1 :         ss << "div { width: abs(\"wrong\"); }";
    6030           3 :         csspp::position pos("test.css");
    6031           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6032             : 
    6033           2 :         csspp::parser p(l);
    6034             : 
    6035           1 :         csspp::node::pointer_t n(p.stylesheet());
    6036             : 
    6037           1 :         csspp::compiler c;
    6038           1 :         c.set_root(n);
    6039           1 :         c.set_date_time_variables(csspp_test::get_now());
    6040           1 :         c.add_path(csspp_test::get_script_path());
    6041           1 :         c.add_path(csspp_test::get_version_script_path());
    6042             : 
    6043           1 :         c.compile(false);
    6044             : 
    6045             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6046             : 
    6047           1 :         VERIFY_ERRORS("test.css(1): error: abs() expects a number as parameter.\n");
    6048             : 
    6049           1 :         CATCH_REQUIRE(c.get_root() == n);
    6050           1 :     }
    6051          63 :     CATCH_END_SECTION()
    6052             : 
    6053          63 :     CATCH_START_SECTION("acos(true)")
    6054             :     {
    6055           1 :         std::stringstream ss;
    6056           1 :         ss << "div { width: acos(true); }";
    6057           3 :         csspp::position pos("test.css");
    6058           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6059             : 
    6060           2 :         csspp::parser p(l);
    6061             : 
    6062           1 :         csspp::node::pointer_t n(p.stylesheet());
    6063             : 
    6064           1 :         csspp::compiler c;
    6065           1 :         c.set_root(n);
    6066           1 :         c.set_date_time_variables(csspp_test::get_now());
    6067           1 :         c.add_path(csspp_test::get_script_path());
    6068           1 :         c.add_path(csspp_test::get_version_script_path());
    6069             : 
    6070           1 :         c.compile(false);
    6071             : 
    6072             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6073             : 
    6074           1 :         VERIFY_ERRORS("test.css(1): error: acos() expects a number as parameter.\n");
    6075             : 
    6076           1 :         CATCH_REQUIRE(c.get_root() == n);
    6077           1 :     }
    6078          63 :     CATCH_END_SECTION()
    6079             : 
    6080          63 :     CATCH_START_SECTION("alpha(12)")
    6081             :     {
    6082           1 :         std::stringstream ss;
    6083           1 :         ss << "div { width: alpha(12); }";
    6084           3 :         csspp::position pos("test.css");
    6085           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6086             : 
    6087           2 :         csspp::parser p(l);
    6088             : 
    6089           1 :         csspp::node::pointer_t n(p.stylesheet());
    6090             : 
    6091           1 :         csspp::compiler c;
    6092           1 :         c.set_root(n);
    6093           1 :         c.set_date_time_variables(csspp_test::get_now());
    6094           1 :         c.add_path(csspp_test::get_script_path());
    6095           1 :         c.add_path(csspp_test::get_version_script_path());
    6096             : 
    6097           1 :         c.compile(false);
    6098             : 
    6099             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6100             : 
    6101           1 :         VERIFY_ERRORS("test.css(1): error: alpha() expects a color as parameter.\n");
    6102             : 
    6103           1 :         CATCH_REQUIRE(c.get_root() == n);
    6104           1 :     }
    6105          63 :     CATCH_END_SECTION()
    6106             : 
    6107          63 :     CATCH_START_SECTION("asin(U+4\x3F?)")
    6108             :     {
    6109           1 :         std::stringstream ss;
    6110           1 :         ss << "div { width: asin(U+4\x3F?); }";
    6111           3 :         csspp::position pos("test.css");
    6112           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6113             : 
    6114           2 :         csspp::parser p(l);
    6115             : 
    6116           1 :         csspp::node::pointer_t n(p.stylesheet());
    6117             : 
    6118           1 :         csspp::compiler c;
    6119           1 :         c.set_root(n);
    6120           1 :         c.set_date_time_variables(csspp_test::get_now());
    6121           1 :         c.add_path(csspp_test::get_script_path());
    6122           1 :         c.add_path(csspp_test::get_version_script_path());
    6123             : 
    6124           1 :         c.compile(false);
    6125             : 
    6126             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6127             : 
    6128           1 :         VERIFY_ERRORS("test.css(1): error: asin() expects a number as parameter.\n");
    6129             : 
    6130           1 :         CATCH_REQUIRE(c.get_root() == n);
    6131           1 :     }
    6132          63 :     CATCH_END_SECTION()
    6133             : 
    6134          63 :     CATCH_START_SECTION("atan(U+1-2)")
    6135             :     {
    6136           1 :         std::stringstream ss;
    6137           1 :         ss << "div { width: atan(U+1-2); }";
    6138           3 :         csspp::position pos("test.css");
    6139           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6140             : 
    6141           2 :         csspp::parser p(l);
    6142             : 
    6143           1 :         csspp::node::pointer_t n(p.stylesheet());
    6144             : 
    6145           1 :         csspp::compiler c;
    6146           1 :         c.set_root(n);
    6147           1 :         c.set_date_time_variables(csspp_test::get_now());
    6148           1 :         c.add_path(csspp_test::get_script_path());
    6149           1 :         c.add_path(csspp_test::get_version_script_path());
    6150             : 
    6151           1 :         c.compile(false);
    6152             : 
    6153             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6154             : 
    6155           1 :         VERIFY_ERRORS("test.css(1): error: atan() expects a number as parameter.\n");
    6156             : 
    6157           1 :         CATCH_REQUIRE(c.get_root() == n);
    6158           1 :     }
    6159          63 :     CATCH_END_SECTION()
    6160             : 
    6161          63 :     CATCH_START_SECTION("blue(15)")
    6162             :     {
    6163           1 :         std::stringstream ss;
    6164           1 :         ss << "div { width: blue(15); }";
    6165           3 :         csspp::position pos("test.css");
    6166           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6167             : 
    6168           2 :         csspp::parser p(l);
    6169             : 
    6170           1 :         csspp::node::pointer_t n(p.stylesheet());
    6171             : 
    6172           1 :         csspp::compiler c;
    6173           1 :         c.set_root(n);
    6174           1 :         c.set_date_time_variables(csspp_test::get_now());
    6175           1 :         c.add_path(csspp_test::get_script_path());
    6176           1 :         c.add_path(csspp_test::get_version_script_path());
    6177             : 
    6178           1 :         c.compile(false);
    6179             : 
    6180             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6181             : 
    6182           1 :         VERIFY_ERRORS("test.css(1): error: blue() expects a color as parameter.\n");
    6183             : 
    6184           1 :         CATCH_REQUIRE(c.get_root() == n);
    6185           1 :     }
    6186          63 :     CATCH_END_SECTION()
    6187             : 
    6188          63 :     CATCH_START_SECTION("ceil(false)")
    6189             :     {
    6190           1 :         std::stringstream ss;
    6191           1 :         ss << "div { width: ceil(false); }";
    6192           3 :         csspp::position pos("test.css");
    6193           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6194             : 
    6195           2 :         csspp::parser p(l);
    6196             : 
    6197           1 :         csspp::node::pointer_t n(p.stylesheet());
    6198             : 
    6199           1 :         csspp::compiler c;
    6200           1 :         c.set_root(n);
    6201           1 :         c.set_date_time_variables(csspp_test::get_now());
    6202           1 :         c.add_path(csspp_test::get_script_path());
    6203           1 :         c.add_path(csspp_test::get_version_script_path());
    6204             : 
    6205           1 :         c.compile(false);
    6206             : 
    6207             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6208             : 
    6209           1 :         VERIFY_ERRORS("test.css(1): error: ceil() expects a number as parameter.\n");
    6210             : 
    6211           1 :         CATCH_REQUIRE(c.get_root() == n);
    6212           1 :     }
    6213          63 :     CATCH_END_SECTION()
    6214             : 
    6215          63 :     CATCH_START_SECTION("cos(white)")
    6216             :     {
    6217           1 :         std::stringstream ss;
    6218           1 :         ss << "div { width: cos(white); }";
    6219           3 :         csspp::position pos("test.css");
    6220           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6221             : 
    6222           2 :         csspp::parser p(l);
    6223             : 
    6224           1 :         csspp::node::pointer_t n(p.stylesheet());
    6225             : 
    6226           1 :         csspp::compiler c;
    6227           1 :         c.set_root(n);
    6228           1 :         c.set_date_time_variables(csspp_test::get_now());
    6229           1 :         c.add_path(csspp_test::get_script_path());
    6230           1 :         c.add_path(csspp_test::get_version_script_path());
    6231             : 
    6232           1 :         c.compile(false);
    6233             : 
    6234             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6235             : 
    6236           1 :         VERIFY_ERRORS("test.css(1): error: cos() expects an angle as parameter.\n");
    6237             : 
    6238           1 :         CATCH_REQUIRE(c.get_root() == n);
    6239           1 :     }
    6240          63 :     CATCH_END_SECTION()
    6241             : 
    6242          63 :     CATCH_START_SECTION("floor(false)")
    6243             :     {
    6244           1 :         std::stringstream ss;
    6245           1 :         ss << "div { width: floor(false); }";
    6246           3 :         csspp::position pos("test.css");
    6247           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6248             : 
    6249           2 :         csspp::parser p(l);
    6250             : 
    6251           1 :         csspp::node::pointer_t n(p.stylesheet());
    6252             : 
    6253           1 :         csspp::compiler c;
    6254           1 :         c.set_root(n);
    6255           1 :         c.set_date_time_variables(csspp_test::get_now());
    6256           1 :         c.add_path(csspp_test::get_script_path());
    6257           1 :         c.add_path(csspp_test::get_version_script_path());
    6258             : 
    6259           1 :         c.compile(false);
    6260             : 
    6261             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6262             : 
    6263           1 :         VERIFY_ERRORS("test.css(1): error: floor() expects a number as parameter.\n");
    6264             : 
    6265           1 :         CATCH_REQUIRE(c.get_root() == n);
    6266           1 :     }
    6267          63 :     CATCH_END_SECTION()
    6268             : 
    6269          63 :     CATCH_START_SECTION("frgb(\"200\")")
    6270             :     {
    6271           1 :         std::stringstream ss;
    6272           1 :         ss << "div { width: frgb(\"200\"); }";
    6273           3 :         csspp::position pos("test.css");
    6274           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6275             : 
    6276           2 :         csspp::parser p(l);
    6277             : 
    6278           1 :         csspp::node::pointer_t n(p.stylesheet());
    6279             : 
    6280           1 :         csspp::compiler c;
    6281           1 :         c.set_root(n);
    6282           1 :         c.set_date_time_variables(csspp_test::get_now());
    6283           1 :         c.add_path(csspp_test::get_script_path());
    6284           1 :         c.add_path(csspp_test::get_version_script_path());
    6285             : 
    6286           1 :         c.compile(false);
    6287             : 
    6288             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6289             : 
    6290           1 :         VERIFY_ERRORS("test.css(1): error: frgb() expects exactly one color parameter or three numbers (Red, Green, Blue).\n");
    6291             : 
    6292           1 :         CATCH_REQUIRE(c.get_root() == n);
    6293           1 :     }
    6294          63 :     CATCH_END_SECTION()
    6295             : 
    6296          63 :     CATCH_START_SECTION("frgb(1, 2, 3, 4, 5)")
    6297             :     {
    6298           1 :         std::stringstream ss;
    6299           1 :         ss << "div { width: frgb(1, 2, 3, 4, 5); }";
    6300           3 :         csspp::position pos("test.css");
    6301           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6302             : 
    6303           2 :         csspp::parser p(l);
    6304             : 
    6305           1 :         csspp::node::pointer_t n(p.stylesheet());
    6306             : 
    6307           1 :         csspp::compiler c;
    6308           1 :         c.set_root(n);
    6309           1 :         c.set_date_time_variables(csspp_test::get_now());
    6310           1 :         c.add_path(csspp_test::get_script_path());
    6311           1 :         c.add_path(csspp_test::get_version_script_path());
    6312             : 
    6313           1 :         c.compile(false);
    6314             : 
    6315             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6316             : 
    6317           1 :         VERIFY_ERRORS("test.css(1): error: frgb() expects between 1 and 3 parameters.\n");
    6318             : 
    6319           1 :         CATCH_REQUIRE(c.get_root() == n);
    6320           1 :     }
    6321          63 :     CATCH_END_SECTION()
    6322             : 
    6323          63 :     CATCH_START_SECTION("frgba(\"200\", 1.0)")
    6324             :     {
    6325           1 :         std::stringstream ss;
    6326           1 :         ss << "div { width: frgba(\"200\", 1.0); }";
    6327           3 :         csspp::position pos("test.css");
    6328           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6329             : 
    6330           2 :         csspp::parser p(l);
    6331             : 
    6332           1 :         csspp::node::pointer_t n(p.stylesheet());
    6333             : 
    6334           1 :         csspp::compiler c;
    6335           1 :         c.set_root(n);
    6336           1 :         c.set_date_time_variables(csspp_test::get_now());
    6337           1 :         c.add_path(csspp_test::get_script_path());
    6338           1 :         c.add_path(csspp_test::get_version_script_path());
    6339             : 
    6340           1 :         c.compile(false);
    6341             : 
    6342             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6343             : 
    6344           1 :         VERIFY_ERRORS("test.css(1): error: frgba() expects exactly one color parameter followed by one number (Color, Alpha), or four numbers (Red, Green, Blue, Alpha).\n");
    6345             : 
    6346           1 :         CATCH_REQUIRE(c.get_root() == n);
    6347           1 :     }
    6348          63 :     CATCH_END_SECTION()
    6349             : 
    6350          63 :     CATCH_START_SECTION("function_exists(200)")
    6351             :     {
    6352           1 :         std::stringstream ss;
    6353           1 :         ss << "div { width: function_exists(200); }";
    6354           3 :         csspp::position pos("test.css");
    6355           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6356             : 
    6357           2 :         csspp::parser p(l);
    6358             : 
    6359           1 :         csspp::node::pointer_t n(p.stylesheet());
    6360             : 
    6361           1 :         csspp::compiler c;
    6362           1 :         c.set_root(n);
    6363           1 :         c.set_date_time_variables(csspp_test::get_now());
    6364           1 :         c.add_path(csspp_test::get_script_path());
    6365           1 :         c.add_path(csspp_test::get_version_script_path());
    6366             : 
    6367           1 :         c.compile(false);
    6368             : 
    6369             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6370             : 
    6371           1 :         VERIFY_ERRORS("test.css(1): error: function_exists() expects a string or an identifier as parameter.\n");
    6372             : 
    6373           1 :         CATCH_REQUIRE(c.get_root() == n);
    6374           1 :     }
    6375          63 :     CATCH_END_SECTION()
    6376             : 
    6377          63 :     CATCH_START_SECTION("global_variable_exists(200)")
    6378             :     {
    6379           1 :         std::stringstream ss;
    6380           1 :         ss << "div { width: global_variable_exists(200); }";
    6381           3 :         csspp::position pos("test.css");
    6382           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6383             : 
    6384           2 :         csspp::parser p(l);
    6385             : 
    6386           1 :         csspp::node::pointer_t n(p.stylesheet());
    6387             : 
    6388           1 :         csspp::compiler c;
    6389           1 :         c.set_root(n);
    6390           1 :         c.set_date_time_variables(csspp_test::get_now());
    6391           1 :         c.add_path(csspp_test::get_script_path());
    6392           1 :         c.add_path(csspp_test::get_version_script_path());
    6393             : 
    6394           1 :         c.compile(false);
    6395             : 
    6396             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6397             : 
    6398           1 :         VERIFY_ERRORS("test.css(1): error: global_variable_exists() expects a string or an identifier as parameter.\n");
    6399             : 
    6400           1 :         CATCH_REQUIRE(c.get_root() == n);
    6401           1 :     }
    6402          63 :     CATCH_END_SECTION()
    6403             : 
    6404          63 :     CATCH_START_SECTION("green(1 = 5)")
    6405             :     {
    6406           1 :         std::stringstream ss;
    6407           1 :         ss << "div { width: green(1 = 5); }";
    6408           3 :         csspp::position pos("test.css");
    6409           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6410             : 
    6411           2 :         csspp::parser p(l);
    6412             : 
    6413           1 :         csspp::node::pointer_t n(p.stylesheet());
    6414             : 
    6415           1 :         csspp::compiler c;
    6416           1 :         c.set_root(n);
    6417           1 :         c.set_date_time_variables(csspp_test::get_now());
    6418           1 :         c.add_path(csspp_test::get_script_path());
    6419           1 :         c.add_path(csspp_test::get_version_script_path());
    6420             : 
    6421           1 :         c.compile(false);
    6422             : 
    6423             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6424             : 
    6425           1 :         VERIFY_ERRORS("test.css(1): error: green() expects a color as parameter.\n");
    6426             : 
    6427           1 :         CATCH_REQUIRE(c.get_root() == n);
    6428           1 :     }
    6429          63 :     CATCH_END_SECTION()
    6430             : 
    6431          63 :     CATCH_START_SECTION("hsl(5, '3', 2)")
    6432             :     {
    6433           1 :         std::stringstream ss;
    6434           1 :         ss << "div { width: hsl(5, '3', 2); }";
    6435           3 :         csspp::position pos("test.css");
    6436           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6437             : 
    6438           2 :         csspp::parser p(l);
    6439             : 
    6440           1 :         csspp::node::pointer_t n(p.stylesheet());
    6441             : 
    6442           1 :         csspp::compiler c;
    6443           1 :         c.set_root(n);
    6444           1 :         c.set_date_time_variables(csspp_test::get_now());
    6445           1 :         c.add_path(csspp_test::get_script_path());
    6446           1 :         c.add_path(csspp_test::get_version_script_path());
    6447             : 
    6448           1 :         c.compile(false);
    6449             : 
    6450             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6451             : 
    6452           1 :         VERIFY_ERRORS("test.css(1): error: hsl() expects exactly three numbers: Hue (angle), Saturation (%), and Lightness (%).\n");
    6453             : 
    6454           1 :         CATCH_REQUIRE(c.get_root() == n);
    6455           1 :     }
    6456          63 :     CATCH_END_SECTION()
    6457             : 
    6458          63 :     CATCH_START_SECTION("hsl(3deg, 3%)") // 3rd % is missing
    6459             :     {
    6460           1 :         std::stringstream ss;
    6461           1 :         ss << "div { width: hsl(U+3?\?); }";
    6462           3 :         csspp::position pos("test.css");
    6463           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6464             : 
    6465           2 :         csspp::parser p(l);
    6466             : 
    6467           1 :         csspp::node::pointer_t n(p.stylesheet());
    6468             : 
    6469           1 :         csspp::compiler c;
    6470           1 :         c.set_root(n);
    6471           1 :         c.set_date_time_variables(csspp_test::get_now());
    6472           1 :         c.add_path(csspp_test::get_script_path());
    6473           1 :         c.add_path(csspp_test::get_version_script_path());
    6474             : 
    6475           1 :         c.compile(false);
    6476             : 
    6477             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6478             : 
    6479           1 :         VERIFY_ERRORS("test.css(1): error: hsl() expects exactly 3 parameters.\n");
    6480             : 
    6481           1 :         CATCH_REQUIRE(c.get_root() == n);
    6482           1 :     }
    6483          63 :     CATCH_END_SECTION()
    6484             : 
    6485          63 :     CATCH_START_SECTION("hsla(5, '3', 2, 0.4)")
    6486             :     {
    6487           1 :         std::stringstream ss;
    6488           1 :         ss << "div { width: hsla(5, '3', 2, 0.4); }";
    6489           3 :         csspp::position pos("test.css");
    6490           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6491             : 
    6492           2 :         csspp::parser p(l);
    6493             : 
    6494           1 :         csspp::node::pointer_t n(p.stylesheet());
    6495             : 
    6496           1 :         csspp::compiler c;
    6497           1 :         c.set_root(n);
    6498           1 :         c.set_date_time_variables(csspp_test::get_now());
    6499           1 :         c.add_path(csspp_test::get_script_path());
    6500           1 :         c.add_path(csspp_test::get_version_script_path());
    6501             : 
    6502           1 :         c.compile(false);
    6503             : 
    6504             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6505             : 
    6506           1 :         VERIFY_ERRORS("test.css(1): error: hsla() expects exactly four numbers: Hue (angle), Saturation (%), Lightness (%), and Alpha (0.0 to 1.0).\n");
    6507             : 
    6508           1 :         CATCH_REQUIRE(c.get_root() == n);
    6509           1 :     }
    6510          63 :     CATCH_END_SECTION()
    6511             : 
    6512          63 :     CATCH_START_SECTION("hue('string')")
    6513             :     {
    6514           1 :         std::stringstream ss;
    6515           1 :         ss << "div { width: hue('string'); }";
    6516           3 :         csspp::position pos("test.css");
    6517           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6518             : 
    6519           2 :         csspp::parser p(l);
    6520             : 
    6521           1 :         csspp::node::pointer_t n(p.stylesheet());
    6522             : 
    6523           1 :         csspp::compiler c;
    6524           1 :         c.set_root(n);
    6525           1 :         c.set_date_time_variables(csspp_test::get_now());
    6526           1 :         c.add_path(csspp_test::get_script_path());
    6527           1 :         c.add_path(csspp_test::get_version_script_path());
    6528             : 
    6529           1 :         c.compile(false);
    6530             : 
    6531             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6532             : 
    6533           1 :         VERIFY_ERRORS("test.css(1): error: hue() expects a color as parameter.\n");
    6534             : 
    6535           1 :         CATCH_REQUIRE(c.get_root() == n);
    6536           1 :     }
    6537          63 :     CATCH_END_SECTION()
    6538             : 
    6539          63 :     CATCH_START_SECTION("identifier(U+333)")
    6540             :     {
    6541           1 :         std::stringstream ss;
    6542           1 :         ss << "div { width: identifier(U+333); }";
    6543           3 :         csspp::position pos("test.css");
    6544           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6545             : 
    6546           2 :         csspp::parser p(l);
    6547             : 
    6548           1 :         csspp::node::pointer_t n(p.stylesheet());
    6549             : 
    6550           1 :         csspp::compiler c;
    6551           1 :         c.set_root(n);
    6552           1 :         c.set_date_time_variables(csspp_test::get_now());
    6553           1 :         c.add_path(csspp_test::get_script_path());
    6554           1 :         c.add_path(csspp_test::get_version_script_path());
    6555             : 
    6556           1 :         c.compile(false);
    6557             : 
    6558             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6559             : 
    6560           1 :         VERIFY_ERRORS("test.css(1): error: identifier() expects one value as parameter.\n");
    6561             : 
    6562           1 :         CATCH_REQUIRE(c.get_root() == n);
    6563           1 :     }
    6564          63 :     CATCH_END_SECTION()
    6565             : 
    6566          63 :     CATCH_START_SECTION("if(true false)")
    6567             :     {
    6568           1 :         std::stringstream ss;
    6569           1 :         ss << "div { width: if(true false, result if true, result if false); }";
    6570           3 :         csspp::position pos("test.css");
    6571           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6572             : 
    6573           2 :         csspp::parser p(l);
    6574             : 
    6575           1 :         csspp::node::pointer_t n(p.stylesheet());
    6576             : 
    6577           1 :         csspp::compiler c;
    6578           1 :         c.set_root(n);
    6579           1 :         c.set_date_time_variables(csspp_test::get_now());
    6580           1 :         c.add_path(csspp_test::get_script_path());
    6581           1 :         c.add_path(csspp_test::get_version_script_path());
    6582             : 
    6583           1 :         c.compile(false);
    6584             : 
    6585             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6586             : 
    6587           1 :         VERIFY_ERRORS("test.css(1): error: if() expects a boolean as its first argument.\n");
    6588             : 
    6589           1 :         CATCH_REQUIRE(c.get_root() == n);
    6590           1 :     }
    6591          63 :     CATCH_END_SECTION()
    6592             : 
    6593          63 :     CATCH_START_SECTION("lightness(3px solid #439812)")
    6594             :     {
    6595           1 :         std::stringstream ss;
    6596           1 :         ss << "div { width: lightness(3px solid #439812); }";
    6597           3 :         csspp::position pos("test.css");
    6598           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6599             : 
    6600           2 :         csspp::parser p(l);
    6601             : 
    6602           1 :         csspp::node::pointer_t n(p.stylesheet());
    6603             : 
    6604           1 :         csspp::compiler c;
    6605           1 :         c.set_root(n);
    6606           1 :         c.set_date_time_variables(csspp_test::get_now());
    6607           1 :         c.add_path(csspp_test::get_script_path());
    6608           1 :         c.add_path(csspp_test::get_version_script_path());
    6609             : 
    6610           1 :         c.compile(false);
    6611             : 
    6612             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6613             : 
    6614           1 :         VERIFY_ERRORS("test.css(1): error: lightness() expects a color as parameter.\n");
    6615             : 
    6616           1 :         CATCH_REQUIRE(c.get_root() == n);
    6617           1 :     }
    6618          63 :     CATCH_END_SECTION()
    6619             : 
    6620          63 :     CATCH_START_SECTION("log(5.3px)")
    6621             :     {
    6622           1 :         std::stringstream ss;
    6623           1 :         ss << "div { width: log(5.3px); }";
    6624           3 :         csspp::position pos("test.css");
    6625           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6626             : 
    6627           2 :         csspp::parser p(l);
    6628             : 
    6629           1 :         csspp::node::pointer_t n(p.stylesheet());
    6630             : 
    6631           1 :         csspp::compiler c;
    6632           1 :         c.set_root(n);
    6633           1 :         c.set_date_time_variables(csspp_test::get_now());
    6634           1 :         c.add_path(csspp_test::get_script_path());
    6635           1 :         c.add_path(csspp_test::get_version_script_path());
    6636             : 
    6637           1 :         c.compile(false);
    6638             : 
    6639             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6640             : 
    6641           1 :         VERIFY_ERRORS("test.css(1): error: log() expects a unit less number as parameter.\n");
    6642             : 
    6643           1 :         CATCH_REQUIRE(c.get_root() == n);
    6644           1 :     }
    6645          63 :     CATCH_END_SECTION()
    6646             : 
    6647          63 :     CATCH_START_SECTION("log(0.0)")
    6648             :     {
    6649           1 :         std::stringstream ss;
    6650           1 :         ss << "div { width: log(0.0); }";
    6651           3 :         csspp::position pos("test.css");
    6652           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6653             : 
    6654           2 :         csspp::parser p(l);
    6655             : 
    6656           1 :         csspp::node::pointer_t n(p.stylesheet());
    6657             : 
    6658           1 :         csspp::compiler c;
    6659           1 :         c.set_root(n);
    6660           1 :         c.set_date_time_variables(csspp_test::get_now());
    6661           1 :         c.add_path(csspp_test::get_script_path());
    6662           1 :         c.add_path(csspp_test::get_version_script_path());
    6663             : 
    6664           1 :         c.compile(false);
    6665             : 
    6666             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6667             : 
    6668           1 :         VERIFY_ERRORS("test.css(1): error: log() expects a positive number as parameter.\n");
    6669             : 
    6670           1 :         CATCH_REQUIRE(c.get_root() == n);
    6671           1 :     }
    6672          63 :     CATCH_END_SECTION()
    6673             : 
    6674          63 :     CATCH_START_SECTION("log(-7)")
    6675             :     {
    6676           1 :         std::stringstream ss;
    6677           1 :         ss << "div { width: log(-7); }";
    6678           3 :         csspp::position pos("test.css");
    6679           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6680             : 
    6681           2 :         csspp::parser p(l);
    6682             : 
    6683           1 :         csspp::node::pointer_t n(p.stylesheet());
    6684             : 
    6685           1 :         csspp::compiler c;
    6686           1 :         c.set_root(n);
    6687           1 :         c.set_date_time_variables(csspp_test::get_now());
    6688           1 :         c.add_path(csspp_test::get_script_path());
    6689           1 :         c.add_path(csspp_test::get_version_script_path());
    6690             : 
    6691           1 :         c.compile(false);
    6692             : 
    6693             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6694             : 
    6695           1 :         VERIFY_ERRORS("test.css(1): error: log() expects a positive number as parameter.\n");
    6696             : 
    6697           1 :         CATCH_REQUIRE(c.get_root() == n);
    6698           1 :     }
    6699          63 :     CATCH_END_SECTION()
    6700             : 
    6701          63 :     CATCH_START_SECTION("log(\"not accepted\")")
    6702             :     {
    6703           1 :         std::stringstream ss;
    6704           1 :         ss << "div { width: log(\"not accepted\"); }";
    6705           3 :         csspp::position pos("test.css");
    6706           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6707             : 
    6708           2 :         csspp::parser p(l);
    6709             : 
    6710           1 :         csspp::node::pointer_t n(p.stylesheet());
    6711             : 
    6712           1 :         csspp::compiler c;
    6713           1 :         c.set_root(n);
    6714           1 :         c.set_date_time_variables(csspp_test::get_now());
    6715           1 :         c.add_path(csspp_test::get_script_path());
    6716           1 :         c.add_path(csspp_test::get_version_script_path());
    6717             : 
    6718           1 :         c.compile(false);
    6719             : 
    6720             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6721             : 
    6722           1 :         VERIFY_ERRORS("test.css(1): error: log() expects a number as parameter.\n");
    6723             : 
    6724           1 :         CATCH_REQUIRE(c.get_root() == n);
    6725           1 :     }
    6726          63 :     CATCH_END_SECTION()
    6727             : 
    6728          63 :     CATCH_START_SECTION("max(3px, 5em)")
    6729             :     {
    6730           1 :         std::stringstream ss;
    6731           1 :         ss << "div { width: max(3px, 5em); }";
    6732           3 :         csspp::position pos("test.css");
    6733           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6734             : 
    6735           2 :         csspp::parser p(l);
    6736             : 
    6737           1 :         csspp::node::pointer_t n(p.stylesheet());
    6738             : 
    6739           1 :         csspp::compiler c;
    6740           1 :         c.set_root(n);
    6741           1 :         c.set_date_time_variables(csspp_test::get_now());
    6742           1 :         c.add_path(csspp_test::get_script_path());
    6743           1 :         c.add_path(csspp_test::get_version_script_path());
    6744             : 
    6745           1 :         c.compile(false);
    6746             : 
    6747             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6748             : 
    6749           1 :         VERIFY_ERRORS("test.css(1): error: max() expects all numbers to have the same dimension.\n");
    6750             : 
    6751           1 :         CATCH_REQUIRE(c.get_root() == n);
    6752           1 :     }
    6753          63 :     CATCH_END_SECTION()
    6754             : 
    6755          63 :     CATCH_START_SECTION("max(3px 5px, 1px 3px)")
    6756             :     {
    6757           1 :         std::stringstream ss;
    6758           1 :         ss << "div { width: max(3px, 5em); }";
    6759           3 :         csspp::position pos("test.css");
    6760           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6761             : 
    6762           2 :         csspp::parser p(l);
    6763             : 
    6764           1 :         csspp::node::pointer_t n(p.stylesheet());
    6765             : 
    6766           1 :         csspp::compiler c;
    6767           1 :         c.set_root(n);
    6768           1 :         c.set_date_time_variables(csspp_test::get_now());
    6769           1 :         c.add_path(csspp_test::get_script_path());
    6770           1 :         c.add_path(csspp_test::get_version_script_path());
    6771             : 
    6772           1 :         c.compile(false);
    6773             : 
    6774             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6775             : 
    6776           1 :         VERIFY_ERRORS("test.css(1): error: max() expects all numbers to have the same dimension.\n");
    6777             : 
    6778           1 :         CATCH_REQUIRE(c.get_root() == n);
    6779           1 :     }
    6780          63 :     CATCH_END_SECTION()
    6781             : 
    6782          63 :     CATCH_START_SECTION("max('strings', 'are', 'illegal', 'here')")
    6783             :     {
    6784           1 :         std::stringstream ss;
    6785           1 :         ss << "div { width: max('strings', 'are', 'illegal', 'here'); }";
    6786           3 :         csspp::position pos("test.css");
    6787           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6788             : 
    6789           2 :         csspp::parser p(l);
    6790             : 
    6791           1 :         csspp::node::pointer_t n(p.stylesheet());
    6792             : 
    6793           1 :         csspp::compiler c;
    6794           1 :         c.set_root(n);
    6795           1 :         c.set_date_time_variables(csspp_test::get_now());
    6796           1 :         c.add_path(csspp_test::get_script_path());
    6797           1 :         c.add_path(csspp_test::get_version_script_path());
    6798             : 
    6799           1 :         c.compile(false);
    6800             : 
    6801             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6802             : 
    6803           1 :         VERIFY_ERRORS(
    6804             :                 "test.css(1): error: max() expects any number of numbers.\n"
    6805             :                 "test.css(1): error: max() expects any number of numbers.\n"
    6806             :                 "test.css(1): error: max() expects any number of numbers.\n"
    6807             :                 "test.css(1): error: max() expects any number of numbers.\n"
    6808             :             );
    6809             : 
    6810           1 :         CATCH_REQUIRE(c.get_root() == n);
    6811           1 :     }
    6812          63 :     CATCH_END_SECTION()
    6813             : 
    6814          63 :     CATCH_START_SECTION("min(3px, 5em)")
    6815             :     {
    6816           1 :         std::stringstream ss;
    6817           1 :         ss << "div { width: min(3px, 5em); }";
    6818           3 :         csspp::position pos("test.css");
    6819           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6820             : 
    6821           2 :         csspp::parser p(l);
    6822             : 
    6823           1 :         csspp::node::pointer_t n(p.stylesheet());
    6824             : 
    6825           1 :         csspp::compiler c;
    6826           1 :         c.set_root(n);
    6827           1 :         c.set_date_time_variables(csspp_test::get_now());
    6828           1 :         c.add_path(csspp_test::get_script_path());
    6829           1 :         c.add_path(csspp_test::get_version_script_path());
    6830             : 
    6831           1 :         c.compile(false);
    6832             : 
    6833             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6834             : 
    6835           1 :         VERIFY_ERRORS("test.css(1): error: min() expects all numbers to have the same dimension.\n");
    6836             : 
    6837           1 :         CATCH_REQUIRE(c.get_root() == n);
    6838           1 :     }
    6839          63 :     CATCH_END_SECTION()
    6840             : 
    6841          63 :     CATCH_START_SECTION("min(3px 5px, 1px 3px)")
    6842             :     {
    6843           1 :         std::stringstream ss;
    6844           1 :         ss << "div { width: min(3px, 5em); }";
    6845           3 :         csspp::position pos("test.css");
    6846           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6847             : 
    6848           2 :         csspp::parser p(l);
    6849             : 
    6850           1 :         csspp::node::pointer_t n(p.stylesheet());
    6851             : 
    6852           1 :         csspp::compiler c;
    6853           1 :         c.set_root(n);
    6854           1 :         c.set_date_time_variables(csspp_test::get_now());
    6855           1 :         c.add_path(csspp_test::get_script_path());
    6856           1 :         c.add_path(csspp_test::get_version_script_path());
    6857             : 
    6858           1 :         c.compile(false);
    6859             : 
    6860             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6861             : 
    6862           1 :         VERIFY_ERRORS("test.css(1): error: min() expects all numbers to have the same dimension.\n");
    6863             : 
    6864           1 :         CATCH_REQUIRE(c.get_root() == n);
    6865           1 :     }
    6866          63 :     CATCH_END_SECTION()
    6867             : 
    6868          63 :     CATCH_START_SECTION("min('strings', 'are', 'illegal', 'here')")
    6869             :     {
    6870           1 :         std::stringstream ss;
    6871           1 :         ss << "div { width: min('strings', 'are', 'illegal', 'here'); }";
    6872           3 :         csspp::position pos("test.css");
    6873           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6874             : 
    6875           2 :         csspp::parser p(l);
    6876             : 
    6877           1 :         csspp::node::pointer_t n(p.stylesheet());
    6878             : 
    6879           1 :         csspp::compiler c;
    6880           1 :         c.set_root(n);
    6881           1 :         c.set_date_time_variables(csspp_test::get_now());
    6882           1 :         c.add_path(csspp_test::get_script_path());
    6883           1 :         c.add_path(csspp_test::get_version_script_path());
    6884             : 
    6885           1 :         c.compile(false);
    6886             : 
    6887             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6888             : 
    6889           1 :         VERIFY_ERRORS(
    6890             :                 "test.css(1): error: min() expects any number of numbers.\n"
    6891             :                 "test.css(1): error: min() expects any number of numbers.\n"
    6892             :                 "test.css(1): error: min() expects any number of numbers.\n"
    6893             :                 "test.css(1): error: min() expects any number of numbers.\n"
    6894             :             );
    6895             : 
    6896           1 :         CATCH_REQUIRE(c.get_root() == n);
    6897           1 :     }
    6898          63 :     CATCH_END_SECTION()
    6899             : 
    6900          63 :     CATCH_START_SECTION("not(U+78-7F)")
    6901             :     {
    6902           1 :         std::stringstream ss;
    6903           1 :         ss << "div { width: not(U+78-7F); }";
    6904           3 :         csspp::position pos("test.css");
    6905           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6906             : 
    6907           2 :         csspp::parser p(l);
    6908             : 
    6909           1 :         csspp::node::pointer_t n(p.stylesheet());
    6910             : 
    6911           1 :         csspp::compiler c;
    6912           1 :         c.set_root(n);
    6913           1 :         c.set_date_time_variables(csspp_test::get_now());
    6914           1 :         c.add_path(csspp_test::get_script_path());
    6915           1 :         c.add_path(csspp_test::get_version_script_path());
    6916             : 
    6917           1 :         c.compile(false);
    6918             : 
    6919             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6920             : 
    6921           1 :         VERIFY_ERRORS("test.css(1): error: a boolean expression was expected.\n");
    6922             : 
    6923           1 :         CATCH_REQUIRE(c.get_root() == n);
    6924           1 :     }
    6925          63 :     CATCH_END_SECTION()
    6926             : 
    6927          63 :     CATCH_START_SECTION("not(true false)")
    6928             :     {
    6929           1 :         std::stringstream ss;
    6930           1 :         ss << "div { width: not(true false); }";
    6931           3 :         csspp::position pos("test.css");
    6932           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6933             : 
    6934           2 :         csspp::parser p(l);
    6935             : 
    6936           1 :         csspp::node::pointer_t n(p.stylesheet());
    6937             : 
    6938           1 :         csspp::compiler c;
    6939           1 :         c.set_root(n);
    6940           1 :         c.set_date_time_variables(csspp_test::get_now());
    6941           1 :         c.add_path(csspp_test::get_script_path());
    6942           1 :         c.add_path(csspp_test::get_version_script_path());
    6943             : 
    6944           1 :         c.compile(false);
    6945             : 
    6946             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6947             : 
    6948           1 :         VERIFY_ERRORS("test.css(1): error: not() expects a boolean as its first argument.\n");
    6949             : 
    6950           1 :         CATCH_REQUIRE(c.get_root() == n);
    6951           1 :     }
    6952          63 :     CATCH_END_SECTION()
    6953             : 
    6954          63 :     CATCH_START_SECTION("percentage(U+333)")
    6955             :     {
    6956           1 :         std::stringstream ss;
    6957           1 :         ss << "div { width: percentage(U+333); }";
    6958           3 :         csspp::position pos("test.css");
    6959           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6960             : 
    6961           2 :         csspp::parser p(l);
    6962             : 
    6963           1 :         csspp::node::pointer_t n(p.stylesheet());
    6964             : 
    6965           1 :         csspp::compiler c;
    6966           1 :         c.set_root(n);
    6967           1 :         c.set_date_time_variables(csspp_test::get_now());
    6968           1 :         c.add_path(csspp_test::get_script_path());
    6969           1 :         c.add_path(csspp_test::get_version_script_path());
    6970             : 
    6971           1 :         c.compile(false);
    6972             : 
    6973             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    6974             : 
    6975           1 :         VERIFY_ERRORS("test.css(1): error: percentage() expects one value as parameter.\n");
    6976             : 
    6977           1 :         CATCH_REQUIRE(c.get_root() == n);
    6978           1 :     }
    6979          63 :     CATCH_END_SECTION()
    6980             : 
    6981          63 :     CATCH_START_SECTION("percentage(\"not a number\")")
    6982             :     {
    6983           1 :         std::stringstream ss;
    6984           1 :         ss << "div { width: percentage(\"not a number\"); }";
    6985           3 :         csspp::position pos("test.css");
    6986           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    6987             : 
    6988           2 :         csspp::parser p(l);
    6989             : 
    6990           1 :         csspp::node::pointer_t n(p.stylesheet());
    6991             : 
    6992           1 :         csspp::compiler c;
    6993           1 :         c.set_root(n);
    6994           1 :         c.set_date_time_variables(csspp_test::get_now());
    6995           1 :         c.add_path(csspp_test::get_script_path());
    6996           1 :         c.add_path(csspp_test::get_version_script_path());
    6997             : 
    6998           1 :         c.compile(false);
    6999             : 
    7000             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7001             : 
    7002           1 :         VERIFY_ERRORS("test.css(1): error: percentage() expects a string parameter to represent a valid integer, decimal number, or percent value.\n");
    7003             : 
    7004           1 :         CATCH_REQUIRE(c.get_root() == n);
    7005           1 :     }
    7006          63 :     CATCH_END_SECTION()
    7007             : 
    7008          63 :     CATCH_START_SECTION("red(15)")
    7009             :     {
    7010           1 :         std::stringstream ss;
    7011           1 :         ss << "div { width: red(15); }";
    7012           3 :         csspp::position pos("test.css");
    7013           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7014             : 
    7015           2 :         csspp::parser p(l);
    7016             : 
    7017           1 :         csspp::node::pointer_t n(p.stylesheet());
    7018             : 
    7019           1 :         csspp::compiler c;
    7020           1 :         c.set_root(n);
    7021           1 :         c.set_date_time_variables(csspp_test::get_now());
    7022           1 :         c.add_path(csspp_test::get_script_path());
    7023           1 :         c.add_path(csspp_test::get_version_script_path());
    7024             : 
    7025           1 :         c.compile(false);
    7026             : 
    7027             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7028             : 
    7029           1 :         VERIFY_ERRORS("test.css(1): error: red() expects a color as parameter.\n");
    7030             : 
    7031           1 :         CATCH_REQUIRE(c.get_root() == n);
    7032           1 :     }
    7033          63 :     CATCH_END_SECTION()
    7034             : 
    7035          63 :     CATCH_START_SECTION("rgb(\"200\")")
    7036             :     {
    7037           1 :         std::stringstream ss;
    7038           1 :         ss << "div { width: rgb(\"200\"); }";
    7039           3 :         csspp::position pos("test.css");
    7040           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7041             : 
    7042           2 :         csspp::parser p(l);
    7043             : 
    7044           1 :         csspp::node::pointer_t n(p.stylesheet());
    7045             : 
    7046           1 :         csspp::compiler c;
    7047           1 :         c.set_root(n);
    7048           1 :         c.set_date_time_variables(csspp_test::get_now());
    7049           1 :         c.add_path(csspp_test::get_script_path());
    7050           1 :         c.add_path(csspp_test::get_version_script_path());
    7051             : 
    7052           1 :         c.compile(false);
    7053             : 
    7054             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7055             : 
    7056           1 :         VERIFY_ERRORS("test.css(1): error: rgb() expects exactly one color parameter (Color) or three numbers (Red, Green, Blue).\n");
    7057             : 
    7058           1 :         CATCH_REQUIRE(c.get_root() == n);
    7059           1 :     }
    7060          63 :     CATCH_END_SECTION()
    7061             : 
    7062          63 :     CATCH_START_SECTION("rgb(red green blue)")
    7063             :     {
    7064           1 :         std::stringstream ss;
    7065           1 :         ss << "div { width: rgb(red green blue); }";
    7066           3 :         csspp::position pos("test.css");
    7067           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7068             : 
    7069           2 :         csspp::parser p(l);
    7070             : 
    7071           1 :         csspp::node::pointer_t n(p.stylesheet());
    7072             : 
    7073           1 :         csspp::compiler c;
    7074           1 :         c.set_root(n);
    7075           1 :         c.set_date_time_variables(csspp_test::get_now());
    7076           1 :         c.add_path(csspp_test::get_script_path());
    7077           1 :         c.add_path(csspp_test::get_version_script_path());
    7078             : 
    7079           1 :         c.compile(false);
    7080             : 
    7081             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7082             : 
    7083           1 :         VERIFY_ERRORS("test.css(1): error: rgb() expects exactly one color parameter (Color) or three numbers (Red, Green, Blue).\n");
    7084             : 
    7085           1 :         CATCH_REQUIRE(c.get_root() == n);
    7086           1 :     }
    7087          63 :     CATCH_END_SECTION()
    7088             : 
    7089          63 :     CATCH_START_SECTION("rgba(\"200\", 1.0)")
    7090             :     {
    7091           1 :         std::stringstream ss;
    7092           1 :         ss << "div { width: rgba(\"200\", 1.0); }";
    7093           3 :         csspp::position pos("test.css");
    7094           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7095             : 
    7096           2 :         csspp::parser p(l);
    7097             : 
    7098           1 :         csspp::node::pointer_t n(p.stylesheet());
    7099             : 
    7100           1 :         csspp::compiler c;
    7101           1 :         c.set_root(n);
    7102           1 :         c.set_date_time_variables(csspp_test::get_now());
    7103           1 :         c.add_path(csspp_test::get_script_path());
    7104           1 :         c.add_path(csspp_test::get_version_script_path());
    7105             : 
    7106           1 :         c.compile(false);
    7107             : 
    7108             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7109             : 
    7110           1 :         VERIFY_ERRORS("test.css(1): error: rgba() expects exactly one color parameter followed by alpha (Color, Alpha) or four numbers (Red, Green, Blue, Alpha).\n");
    7111             : 
    7112           1 :         CATCH_REQUIRE(c.get_root() == n);
    7113           1 :     }
    7114          63 :     CATCH_END_SECTION()
    7115             : 
    7116          63 :     CATCH_START_SECTION("round(false)")
    7117             :     {
    7118           1 :         std::stringstream ss;
    7119           1 :         ss << "div { width: round(false); }";
    7120           3 :         csspp::position pos("test.css");
    7121           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7122             : 
    7123           2 :         csspp::parser p(l);
    7124             : 
    7125           1 :         csspp::node::pointer_t n(p.stylesheet());
    7126             : 
    7127           1 :         csspp::compiler c;
    7128           1 :         c.set_root(n);
    7129           1 :         c.set_date_time_variables(csspp_test::get_now());
    7130           1 :         c.add_path(csspp_test::get_script_path());
    7131           1 :         c.add_path(csspp_test::get_version_script_path());
    7132             : 
    7133           1 :         c.compile(false);
    7134             : 
    7135             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7136             : 
    7137           1 :         VERIFY_ERRORS("test.css(1): error: round() expects a number as parameter.\n");
    7138             : 
    7139           1 :         CATCH_REQUIRE(c.get_root() == n);
    7140           1 :     }
    7141          63 :     CATCH_END_SECTION()
    7142             : 
    7143          63 :     CATCH_START_SECTION("saturation(U+3?\?)")
    7144             :     {
    7145           1 :         std::stringstream ss;
    7146           1 :         ss << "div { width: saturation(U+3?\?); }";
    7147           3 :         csspp::position pos("test.css");
    7148           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7149             : 
    7150           2 :         csspp::parser p(l);
    7151             : 
    7152           1 :         csspp::node::pointer_t n(p.stylesheet());
    7153             : 
    7154           1 :         csspp::compiler c;
    7155           1 :         c.set_root(n);
    7156           1 :         c.set_date_time_variables(csspp_test::get_now());
    7157           1 :         c.add_path(csspp_test::get_script_path());
    7158           1 :         c.add_path(csspp_test::get_version_script_path());
    7159             : 
    7160           1 :         c.compile(false);
    7161             : 
    7162             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7163             : 
    7164           1 :         VERIFY_ERRORS("test.css(1): error: saturation() expects a color as parameter.\n");
    7165             : 
    7166           1 :         CATCH_REQUIRE(c.get_root() == n);
    7167           1 :     }
    7168          63 :     CATCH_END_SECTION()
    7169             : 
    7170          63 :     CATCH_START_SECTION("sign('number')")
    7171             :     {
    7172           1 :         std::stringstream ss;
    7173           1 :         ss << "div { width: sign('number'); }";
    7174           3 :         csspp::position pos("test.css");
    7175           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7176             : 
    7177           2 :         csspp::parser p(l);
    7178             : 
    7179           1 :         csspp::node::pointer_t n(p.stylesheet());
    7180             : 
    7181           1 :         csspp::compiler c;
    7182           1 :         c.set_root(n);
    7183           1 :         c.set_date_time_variables(csspp_test::get_now());
    7184           1 :         c.add_path(csspp_test::get_script_path());
    7185           1 :         c.add_path(csspp_test::get_version_script_path());
    7186             : 
    7187           1 :         c.compile(false);
    7188             : 
    7189             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7190             : 
    7191           1 :         VERIFY_ERRORS("test.css(1): error: sign() expects a number as parameter.\n");
    7192             : 
    7193           1 :         CATCH_REQUIRE(c.get_root() == n);
    7194           1 :     }
    7195          63 :     CATCH_END_SECTION()
    7196             : 
    7197          63 :     CATCH_START_SECTION("sin('number')")
    7198             :     {
    7199           1 :         std::stringstream ss;
    7200           1 :         ss << "div { width: sin('number'); }";
    7201           3 :         csspp::position pos("test.css");
    7202           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7203             : 
    7204           2 :         csspp::parser p(l);
    7205             : 
    7206           1 :         csspp::node::pointer_t n(p.stylesheet());
    7207             : 
    7208           1 :         csspp::compiler c;
    7209           1 :         c.set_root(n);
    7210           1 :         c.set_date_time_variables(csspp_test::get_now());
    7211           1 :         c.add_path(csspp_test::get_script_path());
    7212           1 :         c.add_path(csspp_test::get_version_script_path());
    7213             : 
    7214           1 :         c.compile(false);
    7215             : 
    7216             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7217             : 
    7218           1 :         VERIFY_ERRORS("test.css(1): error: sin() expects an angle as parameter.\n");
    7219             : 
    7220           1 :         CATCH_REQUIRE(c.get_root() == n);
    7221           1 :     }
    7222          63 :     CATCH_END_SECTION()
    7223             : 
    7224          63 :     CATCH_START_SECTION("sqrt(-4.0)")
    7225             :     {
    7226           1 :         std::stringstream ss;
    7227           1 :         ss << "div { width: sqrt(-4.0); }";
    7228           3 :         csspp::position pos("test.css");
    7229           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7230             : 
    7231           2 :         csspp::parser p(l);
    7232             : 
    7233           1 :         csspp::node::pointer_t n(p.stylesheet());
    7234             : 
    7235           1 :         csspp::compiler c;
    7236           1 :         c.set_root(n);
    7237           1 :         c.set_date_time_variables(csspp_test::get_now());
    7238           1 :         c.add_path(csspp_test::get_script_path());
    7239           1 :         c.add_path(csspp_test::get_version_script_path());
    7240             : 
    7241           1 :         c.compile(false);
    7242             : 
    7243             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7244             : 
    7245           1 :         VERIFY_ERRORS("test.css(1): error: sqrt() expects zero or a positive number.\n");
    7246             : 
    7247           1 :         CATCH_REQUIRE(c.get_root() == n);
    7248           1 :     }
    7249          63 :     CATCH_END_SECTION()
    7250             : 
    7251          63 :     CATCH_START_SECTION("sqrt(4.0px)")
    7252             :     {
    7253           1 :         std::stringstream ss;
    7254           1 :         ss << "div { width: sqrt(4.0px); }";
    7255           3 :         csspp::position pos("test.css");
    7256           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7257             : 
    7258           2 :         csspp::parser p(l);
    7259             : 
    7260           1 :         csspp::node::pointer_t n(p.stylesheet());
    7261             : 
    7262           1 :         csspp::compiler c;
    7263           1 :         c.set_root(n);
    7264           1 :         c.set_date_time_variables(csspp_test::get_now());
    7265           1 :         c.add_path(csspp_test::get_script_path());
    7266           1 :         c.add_path(csspp_test::get_version_script_path());
    7267             : 
    7268           1 :         c.compile(false);
    7269             : 
    7270             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7271             : 
    7272           1 :         VERIFY_ERRORS("test.css(1): error: sqrt() expects dimensions to be squarely defined (i.e. 'px * px').\n");
    7273             : 
    7274           1 :         CATCH_REQUIRE(c.get_root() == n);
    7275           1 :     }
    7276          63 :     CATCH_END_SECTION()
    7277             : 
    7278          63 :     CATCH_START_SECTION("sqrt(4.0px*px/em*cm)")
    7279             :     {
    7280           1 :         std::stringstream ss;
    7281           1 :         ss << "div { width: sqrt(4.0px\\*px\\/em\\*cm); }";
    7282           3 :         csspp::position pos("test.css");
    7283           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7284             : 
    7285           2 :         csspp::parser p(l);
    7286             : 
    7287           1 :         csspp::node::pointer_t n(p.stylesheet());
    7288             : 
    7289           1 :         csspp::compiler c;
    7290           1 :         c.set_root(n);
    7291           1 :         c.set_date_time_variables(csspp_test::get_now());
    7292           1 :         c.add_path(csspp_test::get_script_path());
    7293           1 :         c.add_path(csspp_test::get_version_script_path());
    7294             : 
    7295           1 :         c.compile(false);
    7296             : 
    7297             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7298             : 
    7299           1 :         VERIFY_ERRORS("test.css(1): error: sqrt() expects dimensions to be squarely defined (i.e. 'px * px').\n");
    7300             : 
    7301           1 :         CATCH_REQUIRE(c.get_root() == n);
    7302           1 :     }
    7303          63 :     CATCH_END_SECTION()
    7304             : 
    7305          63 :     CATCH_START_SECTION("sqrt(4.0px*cm/em*em)")
    7306             :     {
    7307           1 :         std::stringstream ss;
    7308           1 :         ss << "div { width: sqrt(4.0px\\*cm\\/em\\*em); }";
    7309           3 :         csspp::position pos("test.css");
    7310           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7311             : 
    7312           2 :         csspp::parser p(l);
    7313             : 
    7314           1 :         csspp::node::pointer_t n(p.stylesheet());
    7315             : 
    7316           1 :         csspp::compiler c;
    7317           1 :         c.set_root(n);
    7318           1 :         c.set_date_time_variables(csspp_test::get_now());
    7319           1 :         c.add_path(csspp_test::get_script_path());
    7320           1 :         c.add_path(csspp_test::get_version_script_path());
    7321             : 
    7322           1 :         c.compile(false);
    7323             : 
    7324             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7325             : 
    7326           1 :         VERIFY_ERRORS("test.css(1): error: sqrt() expects dimensions to be squarely defined (i.e. 'px * px').\n");
    7327             : 
    7328           1 :         CATCH_REQUIRE(c.get_root() == n);
    7329           1 :     }
    7330          63 :     CATCH_END_SECTION()
    7331             : 
    7332          63 :     CATCH_START_SECTION("sqrt(35%)")
    7333             :     {
    7334           1 :         std::stringstream ss;
    7335           1 :         ss << "div { width: sqrt(35%); }";
    7336           3 :         csspp::position pos("test.css");
    7337           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7338             : 
    7339           2 :         csspp::parser p(l);
    7340             : 
    7341           1 :         csspp::node::pointer_t n(p.stylesheet());
    7342             : 
    7343           1 :         csspp::compiler c;
    7344           1 :         c.set_root(n);
    7345           1 :         c.set_date_time_variables(csspp_test::get_now());
    7346           1 :         c.add_path(csspp_test::get_script_path());
    7347           1 :         c.add_path(csspp_test::get_version_script_path());
    7348             : 
    7349           1 :         c.compile(false);
    7350             : 
    7351             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7352             : 
    7353           1 :         VERIFY_ERRORS("test.css(1): error: sqrt() expects a number as parameter.\n");
    7354             : 
    7355           1 :         CATCH_REQUIRE(c.get_root() == n);
    7356           1 :     }
    7357          63 :     CATCH_END_SECTION()
    7358             : 
    7359          63 :     CATCH_START_SECTION("sqrt('number')")
    7360             :     {
    7361           1 :         std::stringstream ss;
    7362           1 :         ss << "div { width: sqrt('number'); }";
    7363           3 :         csspp::position pos("test.css");
    7364           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7365             : 
    7366           2 :         csspp::parser p(l);
    7367             : 
    7368           1 :         csspp::node::pointer_t n(p.stylesheet());
    7369             : 
    7370           1 :         csspp::compiler c;
    7371           1 :         c.set_root(n);
    7372           1 :         c.set_date_time_variables(csspp_test::get_now());
    7373           1 :         c.add_path(csspp_test::get_script_path());
    7374           1 :         c.add_path(csspp_test::get_version_script_path());
    7375             : 
    7376           1 :         c.compile(false);
    7377             : 
    7378             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7379             : 
    7380           1 :         VERIFY_ERRORS("test.css(1): error: sqrt() expects a number as parameter.\n");
    7381             : 
    7382           1 :         CATCH_REQUIRE(c.get_root() == n);
    7383           1 :     }
    7384          63 :     CATCH_END_SECTION()
    7385             : 
    7386          63 :     CATCH_START_SECTION("sqrt(12px dashed chocolate)")
    7387             :     {
    7388           1 :         std::stringstream ss;
    7389           1 :         ss << "div { width: sqrt(12px dashed chocolate); }";
    7390           3 :         csspp::position pos("test.css");
    7391           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7392             : 
    7393           2 :         csspp::parser p(l);
    7394             : 
    7395           1 :         csspp::node::pointer_t n(p.stylesheet());
    7396             : 
    7397           1 :         csspp::compiler c;
    7398           1 :         c.set_root(n);
    7399           1 :         c.set_date_time_variables(csspp_test::get_now());
    7400           1 :         c.add_path(csspp_test::get_script_path());
    7401           1 :         c.add_path(csspp_test::get_version_script_path());
    7402             : 
    7403           1 :         c.compile(false);
    7404             : 
    7405             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7406             : 
    7407           1 :         VERIFY_ERRORS("test.css(1): error: sqrt() expects a number as parameter.\n");
    7408             : 
    7409           1 :         CATCH_REQUIRE(c.get_root() == n);
    7410           1 :     }
    7411          63 :     CATCH_END_SECTION()
    7412             : 
    7413          63 :     CATCH_START_SECTION("string(U+110-11f)")
    7414             :     {
    7415           1 :         std::stringstream ss;
    7416           1 :         ss << "div { width: string(U+110-11f); }";
    7417           3 :         csspp::position pos("test.css");
    7418           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7419             : 
    7420           2 :         csspp::parser p(l);
    7421             : 
    7422           1 :         csspp::node::pointer_t n(p.stylesheet());
    7423             : 
    7424           1 :         csspp::compiler c;
    7425           1 :         c.set_root(n);
    7426           1 :         c.set_date_time_variables(csspp_test::get_now());
    7427           1 :         c.add_path(csspp_test::get_script_path());
    7428           1 :         c.add_path(csspp_test::get_version_script_path());
    7429             : 
    7430           1 :         c.compile(false);
    7431             : 
    7432             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7433             : 
    7434           1 :         VERIFY_ERRORS("test.css(1): error: string() expects one value as parameter.\n");
    7435             : 
    7436           1 :         CATCH_REQUIRE(c.get_root() == n);
    7437           1 :     }
    7438          63 :     CATCH_END_SECTION()
    7439             : 
    7440          63 :     CATCH_START_SECTION("str_length(110)")
    7441             :     {
    7442           1 :         std::stringstream ss;
    7443           1 :         ss << "div { width: str_length(110); }";
    7444           3 :         csspp::position pos("test.css");
    7445           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7446             : 
    7447           2 :         csspp::parser p(l);
    7448             : 
    7449           1 :         csspp::node::pointer_t n(p.stylesheet());
    7450             : 
    7451           1 :         csspp::compiler c;
    7452           1 :         c.set_root(n);
    7453           1 :         c.set_date_time_variables(csspp_test::get_now());
    7454           1 :         c.add_path(csspp_test::get_script_path());
    7455           1 :         c.add_path(csspp_test::get_version_script_path());
    7456             : 
    7457           1 :         c.compile(false);
    7458             : 
    7459             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7460             : 
    7461           1 :         VERIFY_ERRORS("test.css(1): error: str_length() expects one string as parameter.\n");
    7462             : 
    7463           1 :         CATCH_REQUIRE(c.get_root() == n);
    7464           1 :     }
    7465          63 :     CATCH_END_SECTION()
    7466             : 
    7467          63 :     CATCH_START_SECTION("str_length(10px solid blue)")
    7468             :     {
    7469           1 :         std::stringstream ss;
    7470           1 :         ss << "div { width: str_length(10px solid blue); }";
    7471           3 :         csspp::position pos("test.css");
    7472           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7473             : 
    7474           2 :         csspp::parser p(l);
    7475             : 
    7476           1 :         csspp::node::pointer_t n(p.stylesheet());
    7477             : 
    7478           1 :         csspp::compiler c;
    7479           1 :         c.set_root(n);
    7480           1 :         c.set_date_time_variables(csspp_test::get_now());
    7481           1 :         c.add_path(csspp_test::get_script_path());
    7482           1 :         c.add_path(csspp_test::get_version_script_path());
    7483             : 
    7484           1 :         c.compile(false);
    7485             : 
    7486             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7487             : 
    7488           1 :         VERIFY_ERRORS("test.css(1): error: str_length() expects one string as parameter.\n");
    7489             : 
    7490           1 :         CATCH_REQUIRE(c.get_root() == n);
    7491           1 :     }
    7492          63 :     CATCH_END_SECTION()
    7493             : 
    7494          63 :     CATCH_START_SECTION("tan(true)")
    7495             :     {
    7496           1 :         std::stringstream ss;
    7497           1 :         ss << "div { width: tan(true); }";
    7498           3 :         csspp::position pos("test.css");
    7499           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7500             : 
    7501           2 :         csspp::parser p(l);
    7502             : 
    7503           1 :         csspp::node::pointer_t n(p.stylesheet());
    7504             : 
    7505           1 :         csspp::compiler c;
    7506           1 :         c.set_root(n);
    7507           1 :         c.set_date_time_variables(csspp_test::get_now());
    7508           1 :         c.add_path(csspp_test::get_script_path());
    7509           1 :         c.add_path(csspp_test::get_version_script_path());
    7510             : 
    7511           1 :         c.compile(false);
    7512             : 
    7513             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7514             : 
    7515           1 :         VERIFY_ERRORS("test.css(1): error: tan() expects an angle as parameter.\n");
    7516             : 
    7517           1 :         CATCH_REQUIRE(c.get_root() == n);
    7518           1 :     }
    7519          63 :     CATCH_END_SECTION()
    7520             : 
    7521          63 :     CATCH_START_SECTION("tan(30px)")
    7522             :     {
    7523           1 :         std::stringstream ss;
    7524           1 :         ss << "div { width: tan(30px); }";
    7525           3 :         csspp::position pos("test.css");
    7526           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7527             : 
    7528           2 :         csspp::parser p(l);
    7529             : 
    7530           1 :         csspp::node::pointer_t n(p.stylesheet());
    7531             : 
    7532           1 :         csspp::compiler c;
    7533           1 :         c.set_root(n);
    7534           1 :         c.set_date_time_variables(csspp_test::get_now());
    7535           1 :         c.add_path(csspp_test::get_script_path());
    7536           1 :         c.add_path(csspp_test::get_version_script_path());
    7537             : 
    7538           1 :         c.compile(false);
    7539             : 
    7540             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7541             : 
    7542           1 :         VERIFY_ERRORS("test.css(1): error: trigonometry functions expect an angle (deg, grad, rad, turn) as a parameter.\n");
    7543             : 
    7544           1 :         CATCH_REQUIRE(c.get_root() == n);
    7545           1 :     }
    7546          63 :     CATCH_END_SECTION()
    7547             : 
    7548          63 :     CATCH_START_SECTION("type_of(30pear 3carrot 15apple)")
    7549             :     {
    7550           1 :         std::stringstream ss;
    7551           1 :         ss << "div { width: type_of(30pear 3carrot 15apple); }";
    7552           3 :         csspp::position pos("test.css");
    7553           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7554             : 
    7555           2 :         csspp::parser p(l);
    7556             : 
    7557           1 :         csspp::node::pointer_t n(p.stylesheet());
    7558             : 
    7559           1 :         csspp::compiler c;
    7560           1 :         c.set_root(n);
    7561           1 :         c.set_date_time_variables(csspp_test::get_now());
    7562           1 :         c.add_path(csspp_test::get_script_path());
    7563           1 :         c.add_path(csspp_test::get_version_script_path());
    7564             : 
    7565           1 :         c.compile(false);
    7566             : 
    7567             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7568             : 
    7569           1 :         VERIFY_ERRORS("test.css(1): error: type_of() expects one value as a parameter.\n");
    7570             : 
    7571           1 :         CATCH_REQUIRE(c.get_root() == n);
    7572           1 :     }
    7573          63 :     CATCH_END_SECTION()
    7574             : 
    7575          63 :     CATCH_START_SECTION("unique_id() with an integer")
    7576             :     {
    7577           1 :         std::stringstream ss;
    7578           1 :         ss << "a { z-index: unique_id(33); }\n";
    7579           3 :         csspp::position pos("test.css");
    7580           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7581             : 
    7582           2 :         csspp::parser p(l);
    7583             : 
    7584           1 :         csspp::node::pointer_t n(p.stylesheet());
    7585             : 
    7586             : //std::cerr << "Parser result is: [" << *n << "]\n";
    7587             : 
    7588           1 :         csspp::compiler c;
    7589           1 :         c.set_root(n);
    7590           1 :         c.set_date_time_variables(csspp_test::get_now());
    7591           1 :         c.add_path(csspp_test::get_script_path());
    7592           1 :         c.add_path(csspp_test::get_version_script_path());
    7593             : 
    7594           1 :         c.compile(false);
    7595             : 
    7596             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7597             : 
    7598           1 :         VERIFY_ERRORS("test.css(1): error: unique_id() expects a string or an identifier as its optional parameter.\n");
    7599             : 
    7600           1 :         CATCH_REQUIRE(c.get_root() == n);
    7601           1 :     }
    7602          63 :     CATCH_END_SECTION()
    7603             : 
    7604          63 :     CATCH_START_SECTION("unique_id() with a unicode range")
    7605             :     {
    7606           1 :         std::stringstream ss;
    7607           1 :         ss << "a { z-index: unique_id(U+33-44); }\n";
    7608           3 :         csspp::position pos("test.css");
    7609           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7610             : 
    7611           2 :         csspp::parser p(l);
    7612             : 
    7613           1 :         csspp::node::pointer_t n(p.stylesheet());
    7614             : 
    7615             : //std::cerr << "Parser result is: [" << *n << "]\n";
    7616             : 
    7617           1 :         csspp::compiler c;
    7618           1 :         c.set_root(n);
    7619           1 :         c.set_date_time_variables(csspp_test::get_now());
    7620           1 :         c.add_path(csspp_test::get_script_path());
    7621           1 :         c.add_path(csspp_test::get_version_script_path());
    7622             : 
    7623           1 :         c.compile(false);
    7624             : 
    7625             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7626             : 
    7627           1 :         VERIFY_ERRORS("test.css(1): error: unique_id() expects a string or an identifier as its optional parameter.\n");
    7628             : 
    7629           1 :         CATCH_REQUIRE(c.get_root() == n);
    7630           1 :     }
    7631          63 :     CATCH_END_SECTION()
    7632             : 
    7633          63 :     CATCH_START_SECTION("unit('string')")
    7634             :     {
    7635           1 :         std::stringstream ss;
    7636           1 :         ss << "div { width: unit('string'); }";
    7637           3 :         csspp::position pos("test.css");
    7638           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7639             : 
    7640           2 :         csspp::parser p(l);
    7641             : 
    7642           1 :         csspp::node::pointer_t n(p.stylesheet());
    7643             : 
    7644           1 :         csspp::compiler c;
    7645           1 :         c.set_root(n);
    7646           1 :         c.set_date_time_variables(csspp_test::get_now());
    7647           1 :         c.add_path(csspp_test::get_script_path());
    7648           1 :         c.add_path(csspp_test::get_version_script_path());
    7649             : 
    7650           1 :         c.compile(false);
    7651             : 
    7652             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7653             : 
    7654           1 :         VERIFY_ERRORS("test.css(1): error: unit() expects a number as parameter.\n");
    7655             : 
    7656           1 :         CATCH_REQUIRE(c.get_root() == n);
    7657           1 :     }
    7658          63 :     CATCH_END_SECTION()
    7659             : 
    7660          63 :     CATCH_START_SECTION("unit(5px dashed tan)")
    7661             :     {
    7662           1 :         std::stringstream ss;
    7663           1 :         ss << "div { width: unit(5px dashed tan); }";
    7664           3 :         csspp::position pos("test.css");
    7665           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7666             : 
    7667           2 :         csspp::parser p(l);
    7668             : 
    7669           1 :         csspp::node::pointer_t n(p.stylesheet());
    7670             : 
    7671           1 :         csspp::compiler c;
    7672           1 :         c.set_root(n);
    7673           1 :         c.set_date_time_variables(csspp_test::get_now());
    7674           1 :         c.add_path(csspp_test::get_script_path());
    7675           1 :         c.add_path(csspp_test::get_version_script_path());
    7676             : 
    7677           1 :         c.compile(false);
    7678             : 
    7679             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7680             : 
    7681           1 :         VERIFY_ERRORS("test.css(1): error: unit() expects a number as parameter.\n");
    7682             : 
    7683           1 :         CATCH_REQUIRE(c.get_root() == n);
    7684           1 :     }
    7685          63 :     CATCH_END_SECTION()
    7686             : 
    7687          63 :     CATCH_START_SECTION("variable_exists(200)")
    7688             :     {
    7689           1 :         std::stringstream ss;
    7690           1 :         ss << "div { width: variable_exists(200); }";
    7691           3 :         csspp::position pos("test.css");
    7692           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7693             : 
    7694           2 :         csspp::parser p(l);
    7695             : 
    7696           1 :         csspp::node::pointer_t n(p.stylesheet());
    7697             : 
    7698           1 :         csspp::compiler c;
    7699           1 :         c.set_root(n);
    7700           1 :         c.set_date_time_variables(csspp_test::get_now());
    7701           1 :         c.add_path(csspp_test::get_script_path());
    7702           1 :         c.add_path(csspp_test::get_version_script_path());
    7703             : 
    7704           1 :         c.compile(false);
    7705             : 
    7706             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7707             : 
    7708           1 :         VERIFY_ERRORS("test.css(1): error: variable_exists() expects a string or an identifier as parameter.\n");
    7709             : 
    7710           1 :         CATCH_REQUIRE(c.get_root() == n);
    7711           1 :     }
    7712          63 :     CATCH_END_SECTION()
    7713             : 
    7714          63 :     CATCH_START_SECTION("variable_exists(3px solid white)")
    7715             :     {
    7716           1 :         std::stringstream ss;
    7717           1 :         ss << "div { width: variable_exists(3px solid white); }";
    7718           3 :         csspp::position pos("test.css");
    7719           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
    7720             : 
    7721           2 :         csspp::parser p(l);
    7722             : 
    7723           1 :         csspp::node::pointer_t n(p.stylesheet());
    7724             : 
    7725           1 :         csspp::compiler c;
    7726           1 :         c.set_root(n);
    7727           1 :         c.set_date_time_variables(csspp_test::get_now());
    7728           1 :         c.add_path(csspp_test::get_script_path());
    7729           1 :         c.add_path(csspp_test::get_version_script_path());
    7730             : 
    7731           1 :         c.compile(false);
    7732             : 
    7733             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
    7734             : 
    7735           1 :         VERIFY_ERRORS("test.css(1): error: variable_exists() expects a string or an identifier as parameter.\n");
    7736             : 
    7737           1 :         CATCH_REQUIRE(c.get_root() == n);
    7738           1 :     }
    7739          63 :     CATCH_END_SECTION()
    7740             : 
    7741             :     // no error left over
    7742          63 :     VERIFY_ERRORS("");
    7743          63 : }
    7744             : 
    7745             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14