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

Generated by: LCOV version 1.14