LCOV - code coverage report
Current view: top level - tests - catch_expr_conditional.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 177 177 100.0 %
Date: 2023-11-01 21:56:19 Functions: 2 2 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: "?:" operator.
      22             :  *
      23             :  * This test runs a battery of tests agains the expression.cpp "?:"
      24             :  * (conditional) operator to ensure full coverage and that all possible
      25             :  * left 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/compiler.h>
      40             : 
      41             : #include    <csspp/assembler.h>
      42             : #include    <csspp/exception.h>
      43             : #include    <csspp/parser.h>
      44             : 
      45             : 
      46             : // self
      47             : //
      48             : #include    "catch_main.h"
      49             : 
      50             : 
      51             : // C++
      52             : //
      53             : #include    <sstream>
      54             : 
      55             : 
      56             : // last include
      57             : //
      58             : #include    <snapdev/poison.h>
      59             : 
      60             : 
      61             : 
      62           3 : CATCH_TEST_CASE("Expression boolean ? a : b", "[expression] [conditional]")
      63             : {
      64           3 :     CATCH_START_SECTION("check 10 = 3 ? 9 : 5")
      65             :     {
      66           1 :         std::stringstream ss;
      67           1 :         ss << "div { z-index: 10 = 3 ? 9 : 5; }";
      68           3 :         csspp::position pos("test.css");
      69           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
      70             : 
      71           2 :         csspp::parser p(l);
      72             : 
      73           1 :         csspp::node::pointer_t n(p.stylesheet());
      74             : 
      75           1 :         csspp::compiler c;
      76           1 :         c.set_root(n);
      77           1 :         c.set_date_time_variables(csspp_test::get_now());
      78           1 :         c.add_path(csspp_test::get_script_path());
      79           1 :         c.add_path(csspp_test::get_version_script_path());
      80             : 
      81           1 :         c.compile(false);
      82             : 
      83             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
      84             : 
      85             :         // to verify that the result is still an INTEGER we have to
      86             :         // test the root node here
      87           1 :         std::stringstream compiler_out;
      88           1 :         compiler_out << *n;
      89           1 :         VERIFY_TREES(compiler_out.str(),
      90             : 
      91             : "LIST\n"
      92             : + csspp_test::get_default_variables() +
      93             : "  COMPONENT_VALUE\n"
      94             : "    ARG\n"
      95             : "      IDENTIFIER \"div\"\n"
      96             : "    OPEN_CURLYBRACKET B:true\n"
      97             : "      DECLARATION \"z-index\"\n"
      98             : "        ARG\n"
      99             : "          INTEGER \"\" I:5\n"
     100             : + csspp_test::get_close_comment(true)
     101             : 
     102             :             );
     103             : 
     104           1 :         std::stringstream assembler_out;
     105           1 :         csspp::assembler a(assembler_out);
     106           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     107             : 
     108             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     109             : 
     110           1 :         CATCH_REQUIRE(assembler_out.str() ==
     111             : 
     112             : "div{z-index:5}\n"
     113             : + csspp_test::get_close_comment()
     114             : 
     115             :                 );
     116             : 
     117           1 :         CATCH_REQUIRE(c.get_root() == n);
     118           1 :     }
     119           3 :     CATCH_END_SECTION()
     120             : 
     121           3 :     CATCH_START_SECTION("check 10 != 3 ? 9 : 5")
     122             :     {
     123           1 :         std::stringstream ss;
     124           1 :         ss << "div { z-index: 10 != 3 ? 9 : 5; }";
     125           3 :         csspp::position pos("test.css");
     126           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     127             : 
     128           2 :         csspp::parser p(l);
     129             : 
     130           1 :         csspp::node::pointer_t n(p.stylesheet());
     131             : 
     132           1 :         csspp::compiler c;
     133           1 :         c.set_root(n);
     134           1 :         c.set_date_time_variables(csspp_test::get_now());
     135           1 :         c.add_path(csspp_test::get_script_path());
     136           1 :         c.add_path(csspp_test::get_version_script_path());
     137             : 
     138           1 :         c.compile(false);
     139             : 
     140             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     141             : 
     142             :         // to verify that the result is still an INTEGER we have to
     143             :         // test the root node here
     144           1 :         std::stringstream compiler_out;
     145           1 :         compiler_out << *n;
     146           1 :         VERIFY_TREES(compiler_out.str(),
     147             : 
     148             : "LIST\n"
     149             : + csspp_test::get_default_variables() +
     150             : "  COMPONENT_VALUE\n"
     151             : "    ARG\n"
     152             : "      IDENTIFIER \"div\"\n"
     153             : "    OPEN_CURLYBRACKET B:true\n"
     154             : "      DECLARATION \"z-index\"\n"
     155             : "        ARG\n"
     156             : "          INTEGER \"\" I:9\n"
     157             : + csspp_test::get_close_comment(true)
     158             : 
     159             :             );
     160             : 
     161           1 :         std::stringstream assembler_out;
     162           1 :         csspp::assembler a(assembler_out);
     163           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     164             : 
     165             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     166             : 
     167           1 :         CATCH_REQUIRE(assembler_out.str() ==
     168             : 
     169             : "div{z-index:9}\n"
     170             : + csspp_test::get_close_comment()
     171             : 
     172             :                 );
     173             : 
     174           1 :         CATCH_REQUIRE(c.get_root() == n);
     175           1 :     }
     176           3 :     CATCH_END_SECTION()
     177             : 
     178           3 :     CATCH_START_SECTION("check 10 != 3 ? \"string\" : 5")
     179             :     {
     180           1 :         std::stringstream ss;
     181           1 :         ss << "div { content: 10 != 3 ? \"string\" : 5; }";
     182           3 :         csspp::position pos("test.css");
     183           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     184             : 
     185           2 :         csspp::parser p(l);
     186             : 
     187           1 :         csspp::node::pointer_t n(p.stylesheet());
     188             : 
     189           1 :         csspp::compiler c;
     190           1 :         c.set_root(n);
     191           1 :         c.set_date_time_variables(csspp_test::get_now());
     192           1 :         c.add_path(csspp_test::get_script_path());
     193           1 :         c.add_path(csspp_test::get_version_script_path());
     194             : 
     195           1 :         c.compile(false);
     196             : 
     197             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     198             : 
     199             :         // to verify that the result is still an INTEGER we have to
     200             :         // test the root node here
     201           1 :         std::stringstream compiler_out;
     202           1 :         compiler_out << *n;
     203           1 :         VERIFY_TREES(compiler_out.str(),
     204             : 
     205             : "LIST\n"
     206             : + csspp_test::get_default_variables() +
     207             : "  COMPONENT_VALUE\n"
     208             : "    ARG\n"
     209             : "      IDENTIFIER \"div\"\n"
     210             : "    OPEN_CURLYBRACKET B:true\n"
     211             : "      DECLARATION \"content\"\n"
     212             : "        ARG\n"
     213             : "          STRING \"string\"\n"
     214             : + csspp_test::get_close_comment(true)
     215             : 
     216             :             );
     217             : 
     218           1 :         std::stringstream assembler_out;
     219           1 :         csspp::assembler a(assembler_out);
     220           1 :         a.output(n, csspp::output_mode_t::COMPRESSED);
     221             : 
     222             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     223             : 
     224           1 :         CATCH_REQUIRE(assembler_out.str() ==
     225             : 
     226             : "div{content:\"string\"}\n"
     227             : + csspp_test::get_close_comment()
     228             : 
     229             :                 );
     230             : 
     231           1 :         CATCH_REQUIRE(c.get_root() == n);
     232           1 :     }
     233           3 :     CATCH_END_SECTION()
     234             : 
     235             :     // no error left over
     236           3 :     VERIFY_ERRORS("");
     237           3 : }
     238             : 
     239           6 : CATCH_TEST_CASE("Expression invalid ? invalid : invalid", "[expression] [conditional] [invalid]")
     240             : {
     241           6 :     CATCH_START_SECTION("just ? is not a valid number")
     242             :     {
     243           1 :         std::stringstream ss;
     244           1 :         ss << "div { border: ?; }";
     245           3 :         csspp::position pos("test.css");
     246           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     247             : 
     248           2 :         csspp::parser p(l);
     249             : 
     250           1 :         csspp::node::pointer_t n(p.stylesheet());
     251             : 
     252           1 :         csspp::compiler c;
     253           1 :         c.set_root(n);
     254           1 :         c.set_date_time_variables(csspp_test::get_now());
     255           1 :         c.add_path(csspp_test::get_script_path());
     256           1 :         c.add_path(csspp_test::get_version_script_path());
     257             : 
     258           1 :         c.compile(false);
     259             : 
     260             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     261             : 
     262           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
     263             : 
     264           1 :         CATCH_REQUIRE(c.get_root() == n);
     265           1 :     }
     266           6 :     CATCH_END_SECTION()
     267             : 
     268           6 :     CATCH_START_SECTION("number ? ? ...  is invalid")
     269             :     {
     270           1 :         std::stringstream ss;
     271           1 :         ss << "div { width: 10px ? ?; }";
     272           3 :         csspp::position pos("test.css");
     273           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     274             : 
     275           2 :         csspp::parser p(l);
     276             : 
     277           1 :         csspp::node::pointer_t n(p.stylesheet());
     278             : 
     279           1 :         csspp::compiler c;
     280           1 :         c.set_root(n);
     281           1 :         c.set_date_time_variables(csspp_test::get_now());
     282           1 :         c.add_path(csspp_test::get_script_path());
     283           1 :         c.add_path(csspp_test::get_version_script_path());
     284             : 
     285           1 :         c.compile(false);
     286             : 
     287             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     288             : 
     289           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
     290             : 
     291           1 :         CATCH_REQUIRE(c.get_root() == n);
     292           1 :     }
     293           6 :     CATCH_END_SECTION()
     294             : 
     295           6 :     CATCH_START_SECTION("true ? 3em : ? is invalid")
     296             :     {
     297           1 :         std::stringstream ss;
     298           1 :         ss << "div { width: true ? 3em : ?; }";
     299           3 :         csspp::position pos("test.css");
     300           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     301             : 
     302           2 :         csspp::parser p(l);
     303             : 
     304           1 :         csspp::node::pointer_t n(p.stylesheet());
     305             : 
     306           1 :         csspp::compiler c;
     307           1 :         c.set_root(n);
     308           1 :         c.set_date_time_variables(csspp_test::get_now());
     309           1 :         c.add_path(csspp_test::get_script_path());
     310           1 :         c.add_path(csspp_test::get_version_script_path());
     311             : 
     312           1 :         c.compile(false);
     313             : 
     314             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     315             : 
     316           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type EOF_TOKEN as a unary expression token.\n");
     317             : 
     318           1 :         CATCH_REQUIRE(c.get_root() == n);
     319           1 :     }
     320           6 :     CATCH_END_SECTION()
     321             : 
     322           6 :     CATCH_START_SECTION("true ? 3em 10em is invalid, missing ':'")
     323             :     {
     324           1 :         std::stringstream ss;
     325           1 :         ss << "div { width: true ? 3em 10em; }";
     326           3 :         csspp::position pos("test.css");
     327           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     328             : 
     329           2 :         csspp::parser p(l);
     330             : 
     331           1 :         csspp::node::pointer_t n(p.stylesheet());
     332             : 
     333           1 :         csspp::compiler c;
     334           1 :         c.set_root(n);
     335           1 :         c.set_date_time_variables(csspp_test::get_now());
     336           1 :         c.add_path(csspp_test::get_script_path());
     337           1 :         c.add_path(csspp_test::get_version_script_path());
     338             : 
     339           1 :         c.compile(false);
     340             : 
     341             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     342             : 
     343           1 :         VERIFY_ERRORS("test.css(1): error: a mandatory ':' was expected after a '?' first expression.\n");
     344             : 
     345           1 :         CATCH_REQUIRE(c.get_root() == n);
     346           1 :     }
     347           6 :     CATCH_END_SECTION()
     348             : 
     349           6 :     CATCH_START_SECTION("unicode-range ? 3em : 10em is invalid, not a boolean")
     350             :     {
     351           1 :         std::stringstream ss;
     352           1 :         ss << "div { width: unicode-range ? 3em : 10em; }";
     353           3 :         csspp::position pos("test.css");
     354           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     355             : 
     356           2 :         csspp::parser p(l);
     357             : 
     358           1 :         csspp::node::pointer_t n(p.stylesheet());
     359             : 
     360           1 :         csspp::compiler c;
     361           1 :         c.set_root(n);
     362           1 :         c.set_date_time_variables(csspp_test::get_now());
     363           1 :         c.add_path(csspp_test::get_script_path());
     364           1 :         c.add_path(csspp_test::get_version_script_path());
     365             : 
     366           1 :         c.compile(false);
     367             : 
     368             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     369             : 
     370           1 :         VERIFY_ERRORS("test.css(1): error: a boolean expression was expected.\n");
     371             : 
     372           1 :         CATCH_REQUIRE(c.get_root() == n);
     373           1 :     }
     374           6 :     CATCH_END_SECTION()
     375             : 
     376           6 :     CATCH_START_SECTION("' false ? 3em : ' is invalid, something's missing")
     377             :     {
     378           1 :         std::stringstream ss;
     379           1 :         ss << "div { width: false ? 3em : ; }";
     380           3 :         csspp::position pos("test.css");
     381           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     382             : 
     383           2 :         csspp::parser p(l);
     384             : 
     385           1 :         csspp::node::pointer_t n(p.stylesheet());
     386             : 
     387           1 :         csspp::compiler c;
     388           1 :         c.set_root(n);
     389           1 :         c.set_date_time_variables(csspp_test::get_now());
     390           1 :         c.add_path(csspp_test::get_script_path());
     391           1 :         c.add_path(csspp_test::get_version_script_path());
     392             : 
     393           1 :         c.compile(false);
     394             : 
     395             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     396             : 
     397           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type EOF_TOKEN as a unary expression token.\n");
     398             : 
     399           1 :         CATCH_REQUIRE(c.get_root() == n);
     400           1 :     }
     401           6 :     CATCH_END_SECTION()
     402             : 
     403             :     // no error left over
     404           6 :     VERIFY_ERRORS("");
     405           6 : }
     406             : 
     407             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14