LCOV - code coverage report
Current view: top level - tests - catch_expr_unary.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 183 183 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 for all possible unary expressions.
      22             :  *
      23             :  * This test runs a battery of tests agains the expression.cpp unary
      24             :  * expressions to ensure full coverage and that all possible input types
      25             :  * are checked for the unary 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    <sstream>
      52             : 
      53             : 
      54             : // last include
      55             : //
      56             : #include    <snapdev/poison.h>
      57             : 
      58             : 
      59             : 
      60           3 : CATCH_TEST_CASE("Unary expressions", "[expression] [unary]")
      61             : {
      62           3 :     CATCH_START_SECTION("integer, identifier, hash color, color")
      63             :     {
      64           1 :         std::stringstream ss;
      65             :         ss << "$zzzrv: $_csspp_major > 0;\n"
      66             :            << "$zzzempty: null;\n"
      67             :            << "div {\n"
      68             :            << "  border: 3px solid #f1a932;\n"          // unary hash color
      69             :            << "  z-index: red(complement(#56af9b));\n"  // direct unary color
      70             :            << "  content: \"\\201c\";\n" // open quotation
      71             :            << "  width: 13%;\n"
      72             :            << "  height: 12.5px;\n"
      73             :            << "  color: if($zzzrv, #341109, white);\n"
      74             :            << "  background-x: ( 32px + 44px );\n"
      75             :            << "  background-y: + 44 * 1px;\n"
      76             :            << "  border-top-left-radius: (- 33 + 57) * 2;\n"
      77             :            << "  border-top-right-radius: (- 33.5 + 5.7) * 2;\n"
      78             :            << "  unicode-range: U+410-417;\n"
      79             :            << "  font-size: if(true, 12pt, 12px);\n"
      80             :            << "  font-weight: if(false, bold, thin);\n"
      81             :            << "  margin-left: calc(5% - 5px);\n"
      82             :            << "  margin-right: expression(2.5% + 2px);\n"
      83             :            << "  margin-top: 1.5%;\n"
      84             :            << "  margin-bottom: - 3.2%;\n"
      85           1 :            << "}\n";
      86           3 :         csspp::position pos("test.css");
      87           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
      88             : 
      89           2 :         csspp::parser p(l);
      90             : 
      91           1 :         csspp::node::pointer_t n(p.stylesheet());
      92             : 
      93           1 :         csspp::compiler c;
      94           1 :         c.set_root(n);
      95           1 :         c.set_date_time_variables(csspp_test::get_now());
      96           1 :         c.add_path(csspp_test::get_script_path());
      97           1 :         c.add_path(csspp_test::get_version_script_path());
      98             : 
      99           1 :         c.compile(false);
     100             : 
     101             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     102             : 
     103             :         // to verify that the result is still an INTEGER we have to
     104             :         // test the root node here
     105           1 :         std::stringstream compiler_out;
     106           1 :         compiler_out << *n;
     107           1 :         VERIFY_TREES(compiler_out.str(),
     108             : 
     109             : "LIST\n"
     110             : + csspp_test::get_default_variables() +
     111             : "    V:zzzempty\n"
     112             : "      LIST\n"
     113             : "        VARIABLE \"zzzempty\"\n"
     114             : "        NULL_TOKEN\n"
     115             : "    V:zzzrv\n"
     116             : "      LIST\n"
     117             : "        VARIABLE \"zzzrv\"\n"
     118             : "        LIST\n"
     119             : "          INTEGER \"\" I:1\n"
     120             : "          WHITESPACE\n"
     121             : "          GREATER_THAN\n"
     122             : "          WHITESPACE\n"
     123             : "          INTEGER \"\" I:0\n"
     124             : "  COMPONENT_VALUE\n"
     125             : "    ARG\n"
     126             : "      IDENTIFIER \"div\"\n"
     127             : "    OPEN_CURLYBRACKET B:true\n"
     128             : "      LIST\n"
     129             : "        DECLARATION \"border\"\n"
     130             : "          ARG\n"
     131             : "            INTEGER \"px\" I:3\n"
     132             : "            WHITESPACE\n"
     133             : "            IDENTIFIER \"solid\"\n"
     134             : "            WHITESPACE\n"
     135             : "            COLOR H:ff32a9f1\n"
     136             : "        DECLARATION \"z-index\"\n"
     137             : "          ARG\n"
     138             : "            INTEGER \"\" I:175\n"
     139             : "        DECLARATION \"content\"\n"
     140             : "          ARG\n"
     141             : "            STRING \"\xe2\x80\x9c\"\n"
     142             : "        DECLARATION \"width\"\n"
     143             : "          ARG\n"
     144             : "            PERCENT D:0.13\n"
     145             : "        DECLARATION \"height\"\n"
     146             : "          ARG\n"
     147             : "            DECIMAL_NUMBER \"px\" D:12.5\n"
     148             : "        DECLARATION \"color\"\n"
     149             : "          ARG\n"
     150             : "            COLOR H:ff091134\n"
     151             : "        DECLARATION \"background-x\"\n"
     152             : "          ARG\n"
     153             : "            INTEGER \"px\" I:76\n"
     154             : "        DECLARATION \"background-y\"\n"
     155             : "          ARG\n"
     156             : "            INTEGER \"px\" I:44\n"
     157             : "        DECLARATION \"border-top-left-radius\"\n"
     158             : "          ARG\n"
     159             : "            INTEGER \"\" I:48\n"
     160             : "        DECLARATION \"border-top-right-radius\"\n"
     161             : "          ARG\n"
     162             : "            DECIMAL_NUMBER \"\" D:-55.6\n"
     163             : "        DECLARATION \"unicode-range\"\n"
     164             : "          ARG\n"
     165             : "            UNICODE_RANGE I:4496830759952\n"
     166             : "        DECLARATION \"font-size\"\n"
     167             : "          ARG\n"
     168             : "            INTEGER \"pt\" I:12\n"
     169             : "        DECLARATION \"font-weight\"\n"
     170             : "          ARG\n"
     171             : "            IDENTIFIER \"thin\"\n"
     172             : "        DECLARATION \"margin-left\"\n"
     173             : "          ARG\n"
     174             : "            FUNCTION \"calc\"\n"
     175             : "              ARG\n"
     176             : "                PERCENT D:0.05\n"
     177             : "                WHITESPACE\n"
     178             : "                SUBTRACT\n"
     179             : "                WHITESPACE\n"
     180             : "                INTEGER \"px\" I:5\n"
     181             : "        DECLARATION \"margin-right\"\n"
     182             : "          ARG\n"
     183             : "            FUNCTION \"expression\"\n"
     184             : "              ARG\n"
     185             : "                PERCENT D:0.025\n"
     186             : "                WHITESPACE\n"
     187             : "                ADD\n"
     188             : "                WHITESPACE\n"
     189             : "                INTEGER \"px\" I:2\n"
     190             : "        DECLARATION \"margin-top\"\n"
     191             : "          ARG\n"
     192             : "            PERCENT D:0.015\n"
     193             : "        DECLARATION \"margin-bottom\"\n"
     194             : "          ARG\n"
     195             : "            PERCENT D:-0.032\n"
     196             : + csspp_test::get_close_comment(true)
     197             : 
     198             :             );
     199             : 
     200           1 :         std::stringstream assembler_out;
     201           1 :         csspp::assembler a(assembler_out);
     202           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     203             : 
     204             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     205             : 
     206           1 :         CATCH_REQUIRE(assembler_out.str() ==
     207             : "div{"
     208             :   "border:3px solid #f1a932;"
     209             :   "z-index:175;"
     210             :   "content:\"\xe2\x80\x9c\";"
     211             :   "width:13%;height:12.5px;"
     212             :   "color:#341109;"
     213             :   "background-x:76px;"
     214             :   "background-y:44px;"
     215             :   "border-top-left-radius:48;"
     216             :   "border-top-right-radius:-55.6;"
     217             :   "unicode-range:U+410-417;"
     218             :   "font-size:12pt;"
     219             :   "font-weight:thin;"
     220             :   "margin-left:calc(5% - 5px);"
     221             :   "margin-right:expression(2.5% + 2px);"
     222             :   "margin-top:1.5%;"
     223             :   "margin-bottom:-3.2%"
     224             : "}\n"
     225             : + csspp_test::get_close_comment()
     226             :                 );
     227             : 
     228           1 :         CATCH_REQUIRE(c.get_root() == n);
     229           1 :     }
     230           3 :     CATCH_END_SECTION()
     231             : 
     232           3 :     CATCH_START_SECTION("null token (can't output)")
     233             :     {
     234           1 :         std::stringstream ss;
     235           1 :         ss << "div{width:null}";
     236           3 :         csspp::position pos("test.css");
     237           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     238             : 
     239           2 :         csspp::parser p(l);
     240             : 
     241           1 :         csspp::node::pointer_t n(p.stylesheet());
     242             : 
     243           1 :         csspp::compiler c;
     244           1 :         c.set_root(n);
     245           1 :         c.set_date_time_variables(csspp_test::get_now());
     246           1 :         c.add_path(csspp_test::get_script_path());
     247           1 :         c.add_path(csspp_test::get_version_script_path());
     248             : 
     249           1 :         c.compile(false);
     250             : 
     251             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     252             : 
     253             :         // to verify that the result is still an INTEGER we have to
     254             :         // test the root node here
     255           1 :         std::stringstream compiler_out;
     256           1 :         compiler_out << *n;
     257           1 :         VERIFY_TREES(compiler_out.str(),
     258             : 
     259             : "LIST\n"
     260             : + csspp_test::get_default_variables() +
     261             : "  COMPONENT_VALUE\n"
     262             : "    ARG\n"
     263             : "      IDENTIFIER \"div\"\n"
     264             : "    OPEN_CURLYBRACKET B:true\n"
     265             : "      DECLARATION \"width\"\n"
     266             : "        ARG\n"
     267             : "          NULL_TOKEN\n"
     268             : + csspp_test::get_close_comment(true)
     269             : 
     270             :             );
     271             : 
     272           1 :         CATCH_REQUIRE(c.get_root() == n);
     273           1 :     }
     274           3 :     CATCH_END_SECTION()
     275             : 
     276           3 :     CATCH_START_SECTION("important width")
     277             :     {
     278           1 :         std::stringstream ss;
     279           1 :         ss << "div{width:3px !important}";
     280           3 :         csspp::position pos("test.css");
     281           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     282             : 
     283           2 :         csspp::parser p(l);
     284             : 
     285           1 :         csspp::node::pointer_t n(p.stylesheet());
     286             : 
     287           1 :         csspp::compiler c;
     288           1 :         c.set_root(n);
     289           1 :         c.set_date_time_variables(csspp_test::get_now());
     290           1 :         c.add_path(csspp_test::get_script_path());
     291           1 :         c.add_path(csspp_test::get_version_script_path());
     292             : 
     293           1 :         c.compile(false);
     294             : 
     295             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     296             : 
     297             :         // to verify that the result is still an INTEGER we have to
     298             :         // test the root node here
     299           1 :         std::stringstream compiler_out;
     300           1 :         compiler_out << *n;
     301           1 :         VERIFY_TREES(compiler_out.str(),
     302             : 
     303             : "LIST\n"
     304             : + csspp_test::get_default_variables() +
     305             : "  COMPONENT_VALUE\n"
     306             : "    ARG\n"
     307             : "      IDENTIFIER \"div\"\n"
     308             : "    OPEN_CURLYBRACKET B:true\n"
     309             : "      DECLARATION \"width\" F:important\n"
     310             : "        ARG\n"
     311             : "          INTEGER \"px\" I:3\n"
     312             : + csspp_test::get_close_comment(true)
     313             : 
     314             :             );
     315             : 
     316           1 :         CATCH_REQUIRE(c.get_root() == n);
     317           1 :     }
     318           3 :     CATCH_END_SECTION()
     319             : 
     320             :     // no error left over
     321           3 :     VERIFY_ERRORS("");
     322           3 : }
     323             : 
     324           1 : CATCH_TEST_CASE("Variables in expressions", "[expression] [unary] [variable]")
     325             : {
     326           1 :     CATCH_START_SECTION("set expression variable and reuse")
     327             :     {
     328           1 :         std::stringstream ss;
     329             :         ss << "div {\n"
     330             :            << "  border: (w := 54px, w / 2.7)[-1] solid #f1a932;\n"
     331           1 :            << "}\n";
     332           3 :         csspp::position pos("test.css");
     333           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     334             : 
     335           2 :         csspp::parser p(l);
     336             : 
     337           1 :         csspp::node::pointer_t n(p.stylesheet());
     338             : 
     339           1 :         csspp::compiler c;
     340           1 :         c.set_root(n);
     341           1 :         c.set_date_time_variables(csspp_test::get_now());
     342           1 :         c.add_path(csspp_test::get_script_path());
     343           1 :         c.add_path(csspp_test::get_version_script_path());
     344             : 
     345           1 :         c.compile(false);
     346             : 
     347             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     348             : 
     349             :         // to verify that the result is still an INTEGER we have to
     350             :         // test the root node here
     351           1 :         std::stringstream compiler_out;
     352           1 :         compiler_out << *n;
     353           1 :         VERIFY_TREES(compiler_out.str(),
     354             : 
     355             : "LIST\n"
     356             : + csspp_test::get_default_variables() +
     357             : "  COMPONENT_VALUE\n"
     358             : "    ARG\n"
     359             : "      IDENTIFIER \"div\"\n"
     360             : "    OPEN_CURLYBRACKET B:true\n"
     361             : "      DECLARATION \"border\"\n"
     362             : "        ARG\n"
     363             : "          DECIMAL_NUMBER \"px\" D:20\n"
     364             : "          WHITESPACE\n"
     365             : "          IDENTIFIER \"solid\"\n"
     366             : "          WHITESPACE\n"
     367             : "          COLOR H:ff32a9f1\n"
     368             : + csspp_test::get_close_comment(true)
     369             : 
     370             :             );
     371             : 
     372           1 :         std::stringstream assembler_out;
     373           1 :         csspp::assembler a(assembler_out);
     374           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     375             : 
     376             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     377             : 
     378           1 :         CATCH_REQUIRE(assembler_out.str() ==
     379             : 
     380             : "div{"
     381             :   "border:20px solid #f1a932"
     382             : "}\n"
     383             : + csspp_test::get_close_comment()
     384             : 
     385             :                 );
     386             : 
     387           1 :         CATCH_REQUIRE(c.get_root() == n);
     388           1 :     }
     389           1 :     CATCH_END_SECTION()
     390             : 
     391             :     // no error left over
     392           1 :     VERIFY_ERRORS("");
     393           1 : }
     394             : 
     395           6 : CATCH_TEST_CASE("Invalid unary expressions", "[expression] [unary] [invalid]")
     396             : {
     397           6 :     CATCH_START_SECTION("not a unary token")
     398             :     {
     399           1 :         std::stringstream ss;
     400           1 :         ss << "div { border: ?; }\n";
     401           3 :         csspp::position pos("test.css");
     402           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     403             : 
     404           2 :         csspp::parser p(l);
     405             : 
     406           1 :         csspp::node::pointer_t n(p.stylesheet());
     407             : 
     408           1 :         csspp::compiler c;
     409           1 :         c.set_root(n);
     410           1 :         c.set_date_time_variables(csspp_test::get_now());
     411           1 :         c.add_path(csspp_test::get_script_path());
     412           1 :         c.add_path(csspp_test::get_version_script_path());
     413             : 
     414           1 :         c.compile(false);
     415             : 
     416             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     417             : 
     418           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
     419             : 
     420           1 :         CATCH_REQUIRE(c.get_root() == n);
     421           1 :     }
     422           6 :     CATCH_END_SECTION()
     423             : 
     424           6 :     CATCH_START_SECTION("invalid # color")
     425             :     {
     426           1 :         std::stringstream ss;
     427           1 :         ss << "div { border: #identifier; }\n";
     428           3 :         csspp::position pos("test.css");
     429           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     430             : 
     431           2 :         csspp::parser p(l);
     432             : 
     433           1 :         csspp::node::pointer_t n(p.stylesheet());
     434             : 
     435           1 :         csspp::compiler c;
     436           1 :         c.set_root(n);
     437           1 :         c.set_date_time_variables(csspp_test::get_now());
     438           1 :         c.add_path(csspp_test::get_script_path());
     439           1 :         c.add_path(csspp_test::get_version_script_path());
     440             : 
     441           1 :         c.compile(false);
     442             : 
     443             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     444             : 
     445           1 :         VERIFY_ERRORS("test.css(1): error: the color in #identifier is not valid.\n");
     446             : 
     447           1 :         CATCH_REQUIRE(c.get_root() == n);
     448           1 :     }
     449           6 :     CATCH_END_SECTION()
     450             : 
     451           6 :     CATCH_START_SECTION("not a valid token for minus")
     452             :     {
     453           1 :         std::stringstream ss;
     454           1 :         ss << "div { border: - \"test\"; }\n";
     455           3 :         csspp::position pos("test.css");
     456           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     457             : 
     458           2 :         csspp::parser p(l);
     459             : 
     460           1 :         csspp::node::pointer_t n(p.stylesheet());
     461             : 
     462           1 :         csspp::compiler c;
     463           1 :         c.set_root(n);
     464           1 :         c.set_date_time_variables(csspp_test::get_now());
     465           1 :         c.add_path(csspp_test::get_script_path());
     466           1 :         c.add_path(csspp_test::get_version_script_path());
     467             : 
     468           1 :         c.compile(false);
     469             : 
     470             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     471             : 
     472           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type STRING for operator '-'.\n");
     473             : 
     474           1 :         CATCH_REQUIRE(c.get_root() == n);
     475           1 :     }
     476           6 :     CATCH_END_SECTION()
     477             : 
     478           6 :     CATCH_START_SECTION("improper initialization of an expression object")
     479             :     {
     480           1 :         csspp::node::pointer_t null_node;
     481           4 :         CATCH_REQUIRE_THROWS_AS(new csspp::expression(null_node), csspp::csspp_exception_logic);
     482           1 :     }
     483           6 :     CATCH_END_SECTION()
     484             : 
     485           6 :     CATCH_START_SECTION("important width, wrong order")
     486             :     {
     487           1 :         std::stringstream ss;
     488           1 :         ss << "div { width: !important 3px; }";
     489           3 :         csspp::position pos("test.css");
     490           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     491             : 
     492           2 :         csspp::parser p(l);
     493             : 
     494           1 :         csspp::node::pointer_t n(p.stylesheet());
     495             : 
     496           1 :         csspp::compiler c;
     497           1 :         c.set_root(n);
     498           1 :         c.set_date_time_variables(csspp_test::get_now());
     499           1 :         c.add_path(csspp_test::get_script_path());
     500           1 :         c.add_path(csspp_test::get_version_script_path());
     501             : 
     502           1 :         c.compile(false);
     503             : 
     504             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     505             : 
     506           1 :         VERIFY_ERRORS("test.css(1): warning: A special flag, !important in this case, must only appear at the end of a declaration.\n");
     507             : 
     508           1 :         CATCH_REQUIRE(c.get_root() == n);
     509           1 :     }
     510           6 :     CATCH_END_SECTION()
     511             : 
     512           6 :     CATCH_START_SECTION("minus by itself")
     513             :     {
     514           1 :         std::stringstream ss;
     515           1 :         ss << "div { width: -; }";
     516           3 :         csspp::position pos("test.css");
     517           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     518             : 
     519           2 :         csspp::parser p(l);
     520             : 
     521           1 :         csspp::node::pointer_t n(p.stylesheet());
     522             : 
     523           1 :         csspp::compiler c;
     524           1 :         c.set_root(n);
     525           1 :         c.set_date_time_variables(csspp_test::get_now());
     526           1 :         c.add_path(csspp_test::get_script_path());
     527           1 :         c.add_path(csspp_test::get_version_script_path());
     528             : 
     529           1 :         c.compile(false);
     530             : 
     531             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     532             : 
     533           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type EOF_TOKEN as a unary expression token.\n");
     534             : 
     535           1 :         CATCH_REQUIRE(c.get_root() == n);
     536           1 :     }
     537           6 :     CATCH_END_SECTION()
     538             : 
     539             :     // no error left over
     540           6 :     VERIFY_ERRORS("");
     541           6 : }
     542             : 
     543             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14