LCOV - code coverage report
Current view: top level - tests - catch_expr_logical_and.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 85 85 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 "&&" (logical
      24             :  * and) 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           1 : CATCH_TEST_CASE("Expression value && value", "[expression] [logical-and]")
      62             : {
      63             :     struct value_t
      64             :     {
      65             :         char const *    f_string;
      66             :         bool            f_true;
      67             :     };
      68             : 
      69           1 :     value_t const values[] =
      70             :     {
      71             :         { "10",         true  },
      72             :         { "3",          true  },
      73             :         { "0",          false },
      74             :         { "10.2",       true  },
      75             :         { "3.7",        true  },
      76             :         { "0.0",        false },
      77             :         { "5.1%",       true  },
      78             :         { "1%",         true  },
      79             :         { "0%",         false },
      80             :         { "0.0%",       false },
      81             :         { "true",       true  },
      82             :         { "false",      false },
      83             :         { "null",       false },
      84             :         { "black",      false },
      85             :         { "#7194F0",    true  },
      86             :         { "white",      true  },
      87             :         { "''",         false },
      88             :         { "'black'",    true  },
      89             :         { "'empty'",    true  },
      90             :         { "'false'",    true  }
      91             :     };
      92           1 :     size_t const value_count(sizeof(values) / sizeof(values[0]));
      93             : 
      94          21 :     for(size_t i(0); i < value_count; ++i)
      95             :     {
      96         420 :         for(size_t j(0); j < value_count; ++j)
      97             :         {
      98         400 :             std::stringstream ss;
      99             :             ss << "div { z-index: "
     100         400 :                << values[i].f_string
     101         800 :                << (rand() & 1 ? " && " : " and ")
     102         400 :                << values[j].f_string
     103         400 :                << " ? 9 : 5; }";
     104        1200 :             csspp::position pos("test.css");
     105         400 :             csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     106             : 
     107         800 :             csspp::parser p(l);
     108             : 
     109         400 :             csspp::node::pointer_t n(p.stylesheet());
     110             : 
     111         400 :             csspp::compiler c;
     112         400 :             c.set_root(n);
     113         400 :             c.set_date_time_variables(csspp_test::get_now());
     114         400 :             c.add_path(csspp_test::get_script_path());
     115         400 :             c.add_path(csspp_test::get_version_script_path());
     116             : 
     117         400 :             c.compile(false);
     118             : 
     119             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     120             : 
     121             :             // to verify that the result is still an INTEGER we have to
     122             :             // test the root node here
     123         400 :             std::stringstream compiler_out;
     124         400 :             compiler_out << *n;
     125         400 :             VERIFY_TREES(compiler_out.str(),
     126             : 
     127             : "LIST\n"
     128             : + csspp_test::get_default_variables() +
     129             : "  COMPONENT_VALUE\n"
     130             : "    ARG\n"
     131             : "      IDENTIFIER \"div\"\n"
     132             : "    OPEN_CURLYBRACKET B:true\n"
     133             : "      DECLARATION \"z-index\"\n"
     134             : "        ARG\n"
     135             : "          INTEGER \"\" I:" + (values[i].f_true && values[j].f_true ? "9" : "5") + "\n"
     136             : + csspp_test::get_close_comment(true)
     137             : 
     138             :                 );
     139             : 
     140         400 :             std::stringstream assembler_out;
     141         400 :             csspp::assembler a(assembler_out);
     142         400 :             a.output(n, csspp::output_mode_t::COMPRESSED);
     143             : 
     144             : //std::cerr << "----------------- Result is " << static_cast<csspp::output_mode_t>(i) << "\n[" << out.str() << "]\n";
     145             : 
     146         400 :             CATCH_REQUIRE(assembler_out.str() ==
     147             : 
     148             : std::string("div{z-index:") + (values[i].f_true && values[j].f_true ? "9" : "5") + "}\n"
     149             : + csspp_test::get_close_comment()
     150             : 
     151             :                     );
     152             : 
     153         400 :             CATCH_REQUIRE(c.get_root() == n);
     154         400 :         }
     155             :     }
     156             : 
     157             :     // no error left over
     158           1 :     VERIFY_ERRORS("");
     159           1 : }
     160             : 
     161           3 : CATCH_TEST_CASE("Expression invalid && invalid", "[expression] [logical-and] [invalid]")
     162             : {
     163           3 :     CATCH_START_SECTION("just ? is not a valid boolean")
     164             :     {
     165           1 :         std::stringstream ss;
     166           1 :         ss << "div { border: ?; }";
     167           3 :         csspp::position pos("test.css");
     168           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     169             : 
     170           2 :         csspp::parser p(l);
     171             : 
     172           1 :         csspp::node::pointer_t n(p.stylesheet());
     173             : 
     174           1 :         csspp::compiler c;
     175           1 :         c.set_root(n);
     176           1 :         c.set_date_time_variables(csspp_test::get_now());
     177           1 :         c.add_path(csspp_test::get_script_path());
     178           1 :         c.add_path(csspp_test::get_version_script_path());
     179             : 
     180           1 :         c.compile(false);
     181             : 
     182             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     183             : 
     184           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
     185             : 
     186           1 :         CATCH_REQUIRE(c.get_root() == n);
     187           1 :     }
     188           3 :     CATCH_END_SECTION()
     189             : 
     190           3 :     CATCH_START_SECTION("boolean && ? is invalid")
     191             :     {
     192           1 :         std::stringstream ss;
     193           1 :         ss << "div { width: true && ?; }";
     194           3 :         csspp::position pos("test.css");
     195           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     196             : 
     197           2 :         csspp::parser p(l);
     198             : 
     199           1 :         csspp::node::pointer_t n(p.stylesheet());
     200             : 
     201           1 :         csspp::compiler c;
     202           1 :         c.set_root(n);
     203           1 :         c.set_date_time_variables(csspp_test::get_now());
     204           1 :         c.add_path(csspp_test::get_script_path());
     205           1 :         c.add_path(csspp_test::get_version_script_path());
     206             : 
     207           1 :         c.compile(false);
     208             : 
     209             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     210             : 
     211           1 :         VERIFY_ERRORS("test.css(1): error: unsupported type CONDITIONAL as a unary expression token.\n");
     212             : 
     213           1 :         CATCH_REQUIRE(c.get_root() == n);
     214           1 :     }
     215           3 :     CATCH_END_SECTION()
     216             : 
     217           3 :     CATCH_START_SECTION("boolean && U+A?? is invalid")
     218             :     {
     219           1 :         std::stringstream ss;
     220           1 :         ss << "div { width: false && U+A??; }";
     221           3 :         csspp::position pos("test.css");
     222           1 :         csspp::lexer::pointer_t l(new csspp::lexer(ss, pos));
     223             : 
     224           2 :         csspp::parser p(l);
     225             : 
     226           1 :         csspp::node::pointer_t n(p.stylesheet());
     227             : 
     228           1 :         csspp::compiler c;
     229           1 :         c.set_root(n);
     230           1 :         c.set_date_time_variables(csspp_test::get_now());
     231           1 :         c.add_path(csspp_test::get_script_path());
     232           1 :         c.add_path(csspp_test::get_version_script_path());
     233             : 
     234           1 :         c.compile(false);
     235             : 
     236             : //std::cerr << "Compiler result is: [" << *c.get_root() << "]\n";
     237             : 
     238           1 :         VERIFY_ERRORS("test.css(1): error: a boolean expression was expected.\n");
     239             : 
     240           1 :         CATCH_REQUIRE(c.get_root() == n);
     241           1 :     }
     242           3 :     CATCH_END_SECTION()
     243             : 
     244             :     // no error left over
     245           3 :     VERIFY_ERRORS("");
     246           3 : }
     247             : 
     248             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14