LCOV - code coverage report
Current view: top level - tests - catch_node.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1668 1669 99.9 %
Date: 2023-11-01 21:56:19 Functions: 12 12 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 node.cpp file.
      22             :  *
      23             :  * This test runs a battery of tests agains the node.cpp
      24             :  * implementation to ensure full coverage.
      25             :  */
      26             : 
      27             : // csspp
      28             : //
      29             : #include    <csspp/exception.h>
      30             : #include    <csspp/lexer.h>
      31             : #include    <csspp/unicode_range.h>
      32             : 
      33             : 
      34             : // self
      35             : //
      36             : #include    "catch_main.h"
      37             : 
      38             : 
      39             : // C++
      40             : //
      41             : #include    <iostream>
      42             : #include    <sstream>
      43             : 
      44             : 
      45             : // C
      46             : //
      47             : #include    <string.h>
      48             : 
      49             : 
      50             : // last include
      51             : //
      52             : #include    <snapdev/poison.h>
      53             : 
      54             : 
      55             : 
      56             : namespace
      57             : {
      58             : 
      59             : 
      60             : } // no name namespace
      61             : 
      62             : 
      63           1 : CATCH_TEST_CASE("Node types", "[node] [type]")
      64             : {
      65             :     // we expect the test suite to be compiled with the exact same version
      66           1 :     csspp::node_type_t w(csspp::node_type_t::UNKNOWN);
      67          69 :     while(w <= csspp::node_type_t::max_type)
      68             :     {
      69         204 :         csspp::position pos("test.css");
      70          68 :         csspp::node::pointer_t n(new csspp::node(w, pos));
      71             : 
      72             :         // verify the type
      73          68 :         CATCH_REQUIRE(n->get_type() == w);
      74             : 
      75          68 :         n->set_flag("important", true);
      76          68 :         CATCH_REQUIRE(n->get_flag("important"));
      77          68 :         n->set_flag("important", false);
      78          68 :         CATCH_REQUIRE_FALSE(n->get_flag("important"));
      79             : 
      80             :         // boolean
      81          68 :         switch(w)
      82             :         {
      83           2 :         case csspp::node_type_t::BOOLEAN:
      84             :         case csspp::node_type_t::OPEN_CURLYBRACKET:
      85             :             {
      86           2 :                 bool b(rand() % 1 == 0);
      87           2 :                 n->set_boolean(b);
      88           2 :                 CATCH_REQUIRE(n->get_boolean() == b);
      89           2 :                 if(w == csspp::node_type_t::OPEN_CURLYBRACKET)
      90             :                 {
      91           1 :                     CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_INVALID);
      92             :                 }
      93             :                 else
      94             :                 {
      95           1 :                     CATCH_REQUIRE(n->to_boolean() == (b ? csspp::boolean_t::BOOLEAN_TRUE : csspp::boolean_t::BOOLEAN_FALSE));
      96             :                 }
      97             :             }
      98           2 :             break;
      99             : 
     100           3 :         case csspp::node_type_t::DECIMAL_NUMBER:
     101             :         case csspp::node_type_t::INTEGER:
     102             :         case csspp::node_type_t::PERCENT:
     103             :             {
     104           3 :                 bool b(rand() % 1 == 0);
     105           3 :                 n->set_boolean(b);
     106           3 :                 CATCH_REQUIRE(n->get_boolean() == b);
     107             :                 // the to_boolean() converts the value not the f_boolean field
     108             :                 // this test MUST happen before the next or we would not know
     109             :                 // whether it  true or false
     110           3 :                 CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_FALSE);
     111             :             }
     112           3 :             break;
     113             : 
     114          63 :         default:
     115          63 :             CATCH_REQUIRE_THROWS_AS(n->set_boolean(true), csspp::csspp_exception_logic);
     116          63 :             CATCH_REQUIRE_THROWS_AS(n->get_boolean(), csspp::csspp_exception_logic);
     117             :             break;
     118             : 
     119             :         }
     120             : 
     121             :         // integer
     122          68 :         switch(w)
     123             :         {
     124           6 :         case csspp::node_type_t::AN_PLUS_B:
     125             :         case csspp::node_type_t::ARG:
     126             :         case csspp::node_type_t::AT_KEYWORD:
     127             :         case csspp::node_type_t::COMMENT:
     128             :         case csspp::node_type_t::INTEGER:
     129             :         case csspp::node_type_t::UNICODE_RANGE:
     130             :             {
     131           6 :                 if(w == csspp::node_type_t::INTEGER)
     132             :                 {
     133           1 :                     CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_FALSE);
     134             :                 }
     135           6 :                 csspp::integer_t i(static_cast<csspp::integer_t>(rand()) + (static_cast<csspp::integer_t>(rand()) << 32));
     136           6 :                 n->set_integer(i);
     137           6 :                 CATCH_REQUIRE(n->get_integer() == i);
     138           6 :                 if(w == csspp::node_type_t::INTEGER)
     139             :                 {
     140           1 :                     CATCH_REQUIRE(n->to_boolean() == (i != 0 ? csspp::boolean_t::BOOLEAN_TRUE : csspp::boolean_t::BOOLEAN_FALSE));
     141             :                 }
     142             :             }
     143           6 :             break;
     144             : 
     145          62 :         default:
     146          62 :             CATCH_REQUIRE_THROWS_AS(n->set_integer(123), csspp::csspp_exception_logic);
     147          62 :             CATCH_REQUIRE_THROWS_AS(n->get_integer(), csspp::csspp_exception_logic);
     148             :             break;
     149             : 
     150             :         }
     151             : 
     152             :         // decimal number
     153          68 :         switch(w)
     154             :         {
     155           2 :         case csspp::node_type_t::DECIMAL_NUMBER:
     156             :         case csspp::node_type_t::PERCENT:
     157           2 :             CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_FALSE);
     158           2 :             n->set_decimal_number(123.456);
     159           2 :             CATCH_REQUIRE(SNAP_CATCH2_NAMESPACE::nearly_equal(n->get_decimal_number(), 123.456, 0.0));
     160           2 :             CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_TRUE);
     161           2 :             break;
     162             : 
     163           1 :         case csspp::node_type_t::FRAME:
     164             :             // no boolean for FRAME (TBD?)
     165           1 :             n->set_decimal_number(123.456);
     166           1 :             CATCH_REQUIRE(SNAP_CATCH2_NAMESPACE::nearly_equal(n->get_decimal_number(), 123.456, 0.0));
     167           1 :             break;
     168             : 
     169          65 :         default:
     170          65 :             CATCH_REQUIRE_THROWS_AS(n->set_decimal_number(3.14159), csspp::csspp_exception_logic);
     171          65 :             CATCH_REQUIRE_THROWS_AS(n->get_decimal_number(), csspp::csspp_exception_logic);
     172             :             break;
     173             : 
     174             :         }
     175             : 
     176             :         // string
     177          68 :         switch(w)
     178             :         {
     179          14 :         case csspp::node_type_t::AT_KEYWORD:
     180             :         case csspp::node_type_t::COMMENT:
     181             :         case csspp::node_type_t::DECIMAL_NUMBER:
     182             :         case csspp::node_type_t::DECLARATION:
     183             :         case csspp::node_type_t::EXCLAMATION:
     184             :         case csspp::node_type_t::FUNCTION:
     185             :         case csspp::node_type_t::HASH:
     186             :         case csspp::node_type_t::IDENTIFIER:
     187             :         case csspp::node_type_t::INTEGER:
     188             :         case csspp::node_type_t::PLACEHOLDER:
     189             :         case csspp::node_type_t::STRING:
     190             :         case csspp::node_type_t::URL:
     191             :         case csspp::node_type_t::VARIABLE:
     192             :         case csspp::node_type_t::VARIABLE_FUNCTION:
     193          14 :             if(w == csspp::node_type_t::STRING)
     194             :             {
     195           1 :                 CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_FALSE);
     196             :             }
     197          14 :             n->set_lowercase_string("test-boolean-string");
     198          14 :             CATCH_REQUIRE(n->get_lowercase_string() == "test-boolean-string");
     199          14 :             CATCH_REQUIRE(n->get_string() == "");
     200          14 :             if(w == csspp::node_type_t::STRING)
     201             :             {
     202             :                 // the lowercase string has no effect on the boolean value
     203           1 :                 CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_FALSE);
     204             :             }
     205          14 :             n->set_string("test-string");
     206          14 :             CATCH_REQUIRE(n->get_string() == "test-string");
     207          14 :             CATCH_REQUIRE(n->get_lowercase_string() == "test-boolean-string");
     208          14 :             if(w == csspp::node_type_t::STRING)
     209             :             {
     210           1 :                 CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_TRUE);
     211             :             }
     212          14 :             n->set_lowercase_string("test-lowercase-string");
     213          14 :             CATCH_REQUIRE(n->get_lowercase_string() == "test-lowercase-string");
     214          14 :             CATCH_REQUIRE(n->get_string() == "test-string");
     215          14 :             if(w == csspp::node_type_t::STRING)
     216             :             {
     217           1 :                 CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_TRUE);
     218             :             }
     219          14 :             break;
     220             : 
     221          54 :         default:
     222         270 :             CATCH_REQUIRE_THROWS_AS(n->set_string("add"), csspp::csspp_exception_logic);
     223          54 :             CATCH_REQUIRE_THROWS_AS(n->get_string(), csspp::csspp_exception_logic);
     224             :             break;
     225             : 
     226             :         }
     227             : 
     228             :         {
     229          68 :             csspp::color c;
     230          68 :             switch(w)
     231             :             {
     232           1 :             case csspp::node_type_t::COLOR:
     233             :                 {
     234             :                     // by default a color is black (transparent) and thus
     235             :                     // represents false
     236           1 :                     CATCH_REQUIRE_FALSE(n->to_boolean());
     237           1 :                     c.set_color(rand() % 255, rand() % 255, rand() % 255, rand() % 255);
     238           1 :                     n->set_color(c);
     239           1 :                     csspp::color d(n->get_color());
     240           1 :                     CATCH_REQUIRE(c.get_color() == d.get_color());
     241           1 :                     if((c.get_color() & 0x00FFFFFF) == 0)
     242             :                     {
     243             :                         // we tested with black... so it is still false
     244           0 :                         CATCH_REQUIRE_FALSE(n->to_boolean());
     245             :                     }
     246             :                     else
     247             :                     {
     248             :                         // otherwise we have a "true color"
     249           1 :                         CATCH_REQUIRE(n->to_boolean());
     250             :                     }
     251             :                 }
     252             :                 break;
     253             : 
     254          67 :             default:
     255          67 :                 CATCH_REQUIRE_THROWS_AS(n->set_color(c), csspp::csspp_exception_logic);
     256          67 :                 CATCH_REQUIRE_THROWS_AS(n->get_color(), csspp::csspp_exception_logic);
     257             :                 break;
     258             : 
     259             :             }
     260             :         }
     261             : 
     262             :         // font metrics
     263          68 :         switch(w)
     264             :         {
     265           1 :         case csspp::node_type_t::FONT_METRICS:
     266           1 :             n->set_font_size(12.5);
     267           1 :             n->set_dim1("px");
     268           1 :             n->set_line_height(24.3);
     269           1 :             n->set_dim2("%");
     270             :             //CATCH_REQUIRE(n->get_string() == "px/%"); -- we do not allow get_string()
     271             :             //CATCH_REQUIRE(n->get_integer() == 12.5 as a double); -- we do not allow get_integer()
     272             :             //CATCH_REQUIRE(n->get_decimal_number() == 24.3); -- we do not allow get_decimal_number()
     273           1 :             CATCH_REQUIRE(SNAP_CATCH2_NAMESPACE::nearly_equal(n->get_font_size(), 12.5, 0.0));
     274           1 :             CATCH_REQUIRE(n->get_dim1() == "px");
     275           1 :             CATCH_REQUIRE(SNAP_CATCH2_NAMESPACE::nearly_equal(n->get_line_height(), 24.3, 0.0));
     276           1 :             CATCH_REQUIRE(n->get_dim2() == "%");
     277             : 
     278             :             // dimensions require a few more tests
     279           1 :             n->set_dim2("deg");  // chane dim2
     280           1 :             CATCH_REQUIRE(n->get_dim1() == "px");
     281           1 :             CATCH_REQUIRE(n->get_dim2() == "deg");
     282           1 :             n->set_dim2("");  // remove dim2
     283           1 :             CATCH_REQUIRE(n->get_dim1() == "px");
     284           1 :             CATCH_REQUIRE(n->get_dim2() == "");
     285           1 :             n->set_dim1("");  // remove dim1
     286           1 :             CATCH_REQUIRE(n->get_dim1() == "");
     287           1 :             CATCH_REQUIRE(n->get_dim2() == "");
     288           1 :             n->set_dim2("em"); // set dim2 without a dim1
     289           1 :             CATCH_REQUIRE(n->get_dim1() == "");
     290           1 :             CATCH_REQUIRE(n->get_dim2() == "em");
     291           1 :             n->set_dim1("px"); // set a dim1 with a dim2
     292           1 :             CATCH_REQUIRE(n->get_dim1() == "px");
     293           1 :             CATCH_REQUIRE(n->get_dim2() == "em");
     294           1 :             n->set_dim1("");  // remove dim1 with a dim2
     295           1 :             CATCH_REQUIRE(n->get_dim1() == "");
     296           1 :             CATCH_REQUIRE(n->get_dim2() == "em");
     297           1 :             n->set_dim2("");  // remove dim2 without a dim1
     298           1 :             CATCH_REQUIRE(n->get_dim1() == "");
     299           1 :             CATCH_REQUIRE(n->get_dim2() == "");
     300           1 :             break;
     301             : 
     302          67 :         default:
     303          67 :             CATCH_REQUIRE_THROWS_AS(n->set_font_size(12.5), csspp::csspp_exception_logic);
     304          67 :             CATCH_REQUIRE_THROWS_AS(n->get_font_size(), csspp::csspp_exception_logic);
     305          67 :             CATCH_REQUIRE_THROWS_AS(n->set_line_height(24.3), csspp::csspp_exception_logic);
     306          67 :             CATCH_REQUIRE_THROWS_AS(n->get_line_height(), csspp::csspp_exception_logic);
     307         335 :             CATCH_REQUIRE_THROWS_AS(n->set_dim1("px"), csspp::csspp_exception_logic);
     308          67 :             CATCH_REQUIRE_THROWS_AS(n->get_dim1(), csspp::csspp_exception_logic);
     309         335 :             CATCH_REQUIRE_THROWS_AS(n->set_dim2("%"), csspp::csspp_exception_logic);
     310          67 :             CATCH_REQUIRE_THROWS_AS(n->get_dim2(), csspp::csspp_exception_logic);
     311             :             break;
     312             : 
     313             :         }
     314             : 
     315             :         // children
     316          68 :         switch(w)
     317             :         {
     318          13 :         case csspp::node_type_t::ARG:
     319             :         case csspp::node_type_t::ARRAY:
     320             :         case csspp::node_type_t::AT_KEYWORD:
     321             :         case csspp::node_type_t::COMPONENT_VALUE:
     322             :         case csspp::node_type_t::DECLARATION:
     323             :         case csspp::node_type_t::FUNCTION:
     324             :         case csspp::node_type_t::LIST:
     325             :         case csspp::node_type_t::MAP:
     326             :         case csspp::node_type_t::OPEN_CURLYBRACKET:
     327             :         case csspp::node_type_t::OPEN_PARENTHESIS:
     328             :         case csspp::node_type_t::OPEN_SQUAREBRACKET:
     329             :         case csspp::node_type_t::VARIABLE_FUNCTION:
     330             :         case csspp::node_type_t::FRAME:
     331             :             {
     332             :                 // try adding one child
     333          13 :                 if(w == csspp::node_type_t::LIST)
     334             :                 {
     335           1 :                     CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_FALSE);
     336             :                 }
     337          13 :                 CATCH_REQUIRE(n->empty());
     338          13 :                 CATCH_REQUIRE(n->size() == 0);
     339          13 :                 CATCH_REQUIRE_THROWS_AS(n->get_child(0), csspp::csspp_exception_overflow);
     340          13 :                 CATCH_REQUIRE_THROWS_AS(n->get_last_child(), csspp::csspp_exception_overflow);
     341          13 :                 CATCH_REQUIRE_THROWS_AS(n->remove_child(0), csspp::csspp_exception_overflow);
     342          39 :                 CATCH_REQUIRE_THROWS_AS(n->remove_child(n), csspp::csspp_exception_logic);
     343             : 
     344          13 :                 csspp::node::pointer_t child1(new csspp::node(csspp::node_type_t::COMMA, n->get_position()));
     345          13 :                 csspp::node::pointer_t child2(new csspp::node(csspp::node_type_t::EXCLAMATION, n->get_position()));
     346          13 :                 csspp::node::pointer_t eof_token(new csspp::node(csspp::node_type_t::EOF_TOKEN, n->get_position()));
     347          13 :                 csspp::node::pointer_t whitespace1(new csspp::node(csspp::node_type_t::WHITESPACE, n->get_position()));
     348          13 :                 csspp::node::pointer_t whitespace2(new csspp::node(csspp::node_type_t::WHITESPACE, n->get_position()));
     349             : 
     350          13 :                 n->add_child(child1);
     351          13 :                 if(w == csspp::node_type_t::LIST)
     352             :                 {
     353           1 :                     CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_TRUE);
     354             :                 }
     355          13 :                 CATCH_REQUIRE(n->size() == 1);
     356          13 :                 CATCH_REQUIRE_FALSE(n->empty());
     357          13 :                 CATCH_REQUIRE(n->get_last_child() == child1);
     358          13 :                 CATCH_REQUIRE(n->get_child(0) == child1);
     359          39 :                 CATCH_REQUIRE_THROWS_AS(n->remove_child(n), csspp::csspp_exception_logic);
     360             : 
     361          13 :                 n->add_child(child2);
     362          13 :                 if(w == csspp::node_type_t::LIST)
     363             :                 {
     364           1 :                     CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_TRUE);
     365             :                 }
     366          13 :                 CATCH_REQUIRE(n->size() == 2);
     367          13 :                 CATCH_REQUIRE_FALSE(n->empty());
     368          13 :                 CATCH_REQUIRE(n->get_last_child() == child2);
     369          13 :                 CATCH_REQUIRE(n->get_child(0) == child1);
     370          13 :                 CATCH_REQUIRE(n->get_child(1) == child2);
     371          39 :                 CATCH_REQUIRE_THROWS_AS(n->remove_child(n), csspp::csspp_exception_logic);
     372             : 
     373          13 :                 if(rand() & 1)
     374             :                 {
     375           5 :                     n->remove_child(0);
     376           5 :                     CATCH_REQUIRE(n->size() == 1);
     377             : 
     378           5 :                     n->remove_child(child2);
     379             :                 }
     380             :                 else
     381             :                 {
     382           8 :                     n->remove_child(child2);
     383           8 :                     CATCH_REQUIRE(n->size() == 1);
     384             : 
     385           8 :                     n->remove_child(0);
     386             :                 }
     387             : 
     388             :                 // fully empty again, all fails like follow
     389          13 :                 if(w == csspp::node_type_t::LIST)
     390             :                 {
     391           1 :                     CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_FALSE);
     392             :                 }
     393          13 :                 CATCH_REQUIRE(n->empty());
     394          13 :                 CATCH_REQUIRE(n->size() == 0);
     395          13 :                 CATCH_REQUIRE_THROWS_AS(n->get_child(0), csspp::csspp_exception_overflow);
     396          13 :                 CATCH_REQUIRE_THROWS_AS(n->get_last_child(), csspp::csspp_exception_overflow);
     397          13 :                 CATCH_REQUIRE_THROWS_AS(n->remove_child(0), csspp::csspp_exception_overflow);
     398          39 :                 CATCH_REQUIRE_THROWS_AS(n->remove_child(n), csspp::csspp_exception_logic);
     399             : 
     400             :                 // test a few more things
     401          13 :                 n->add_child(child1);
     402          13 :                 CATCH_REQUIRE(n->size() == 1);
     403          13 :                 n->insert_child(1, whitespace1);
     404          13 :                 CATCH_REQUIRE(n->size() == 2);
     405          13 :                 n->add_child(whitespace2); // ignore two whitespaces in a row
     406          13 :                 CATCH_REQUIRE(n->size() == 2);
     407          13 :                 n->insert_child(0, child2);
     408          13 :                 CATCH_REQUIRE(n->size() == 3);
     409          13 :                 n->add_child(eof_token);  // never add EOF_TOKEN
     410          13 :                 CATCH_REQUIRE(n->size() == 3);
     411          13 :                 CATCH_REQUIRE(n->get_child(0) == child2);
     412          13 :                 CATCH_REQUIRE(n->get_child(1) == child1);
     413          13 :                 CATCH_REQUIRE(n->get_child(2) == whitespace1);
     414          13 :                 CATCH_REQUIRE(n->child_position(child1) == 1);
     415          13 :                 CATCH_REQUIRE(n->child_position(child2) == 0);
     416          13 :                 CATCH_REQUIRE(n->child_position(whitespace1) == 2);
     417          13 :                 CATCH_REQUIRE(n->child_position(whitespace2) == csspp::node::npos);
     418          13 :                 CATCH_REQUIRE(n->child_position(eof_token) == csspp::node::npos);
     419          13 :                 n->clear();
     420          13 :                 CATCH_REQUIRE(n->size() == 0);
     421          13 :                 CATCH_REQUIRE(n->child_position(child1) == csspp::node::npos);
     422          13 :                 CATCH_REQUIRE(n->child_position(child2) == csspp::node::npos);
     423          13 :                 CATCH_REQUIRE(n->child_position(whitespace1) == csspp::node::npos);
     424          13 :                 CATCH_REQUIRE(n->child_position(whitespace2) == csspp::node::npos);
     425          13 :                 CATCH_REQUIRE(n->child_position(eof_token) == csspp::node::npos);
     426             : 
     427             :                 // test the replace
     428          13 :                 n->add_child(child1);
     429          13 :                 CATCH_REQUIRE(n->size() == 1);
     430          13 :                 CATCH_REQUIRE(n->get_child(0) == child1);
     431          13 :                 n->replace_child(child1, child2);
     432          13 :                 CATCH_REQUIRE(n->size() == 1);
     433          13 :                 CATCH_REQUIRE(n->get_child(0) == child2);
     434             : 
     435          13 :                 csspp::node::pointer_t list(new csspp::node(csspp::node_type_t::LIST, n->get_position()));
     436          13 :                 n->add_child(child1);
     437          13 :                 list->take_over_children_of(n);
     438          13 :                 CATCH_REQUIRE(n->size() == 0);
     439          13 :                 CATCH_REQUIRE(list->size() == 2);
     440          13 :                 CATCH_REQUIRE(list->get_child(0) == child2);
     441          13 :                 CATCH_REQUIRE(list->get_child(1) == child1);
     442          13 :             }
     443             :             break;
     444             : 
     445          55 :         default:
     446          55 :             CATCH_REQUIRE_THROWS_AS(n->empty(), csspp::csspp_exception_logic);
     447          55 :             CATCH_REQUIRE_THROWS_AS(n->size(), csspp::csspp_exception_logic);
     448          55 :             CATCH_REQUIRE_THROWS_AS(n->clear(), csspp::csspp_exception_logic);
     449         165 :             CATCH_REQUIRE_THROWS_AS(n->add_child(n), csspp::csspp_exception_logic);
     450         165 :             CATCH_REQUIRE_THROWS_AS(n->remove_child(n), csspp::csspp_exception_logic);
     451          55 :             CATCH_REQUIRE_THROWS_AS(n->remove_child(0), csspp::csspp_exception_logic);
     452          55 :             CATCH_REQUIRE_THROWS_AS(n->get_child(0), csspp::csspp_exception_logic);
     453          55 :             CATCH_REQUIRE_THROWS_AS(n->get_last_child(), csspp::csspp_exception_logic);
     454         165 :             CATCH_REQUIRE_THROWS_AS(n->take_over_children_of(0), csspp::csspp_exception_logic);
     455             :             break;
     456             : 
     457             :         }
     458             : 
     459             :         // all invalid node types for to_boolean()
     460          68 :         switch(w)
     461             :         {
     462          10 :         case csspp::node_type_t::ARRAY:
     463             :         case csspp::node_type_t::BOOLEAN:
     464             :         case csspp::node_type_t::COLOR:
     465             :         case csspp::node_type_t::DECIMAL_NUMBER:
     466             :         case csspp::node_type_t::INTEGER:
     467             :         case csspp::node_type_t::LIST:
     468             :         case csspp::node_type_t::MAP:
     469             :         case csspp::node_type_t::NULL_TOKEN:
     470             :         case csspp::node_type_t::PERCENT:
     471             :         case csspp::node_type_t::STRING:
     472          10 :             break;
     473             : 
     474          58 :         default:
     475          58 :             CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_INVALID);
     476          58 :             break;
     477             : 
     478             :         }
     479             : 
     480             :         // move to the next type
     481          68 :         w = static_cast<csspp::node_type_t>(static_cast<int>(w) + 1);
     482          68 :     }
     483             : 
     484             :     // no error left over
     485           1 :     VERIFY_ERRORS("");
     486           1 : }
     487             : 
     488           1 : CATCH_TEST_CASE("Invalid tree handling", "[node] [invalid]")
     489             : {
     490             :     // replace with an invalid child
     491             :     {
     492           3 :         csspp::position pos("test.css");
     493           1 :         csspp::node::pointer_t n(new csspp::node(csspp::node_type_t::LIST, pos));
     494             : 
     495           1 :         csspp::node::pointer_t child1(new csspp::node(csspp::node_type_t::INTEGER, pos));
     496           1 :         child1->set_integer(33);
     497           1 :         csspp::node::pointer_t child2(new csspp::node(csspp::node_type_t::STRING, pos));
     498           1 :         child2->set_string("hello!");
     499             : 
     500           1 :         n->add_child(child1);
     501             : 
     502             :         // child2, child1 are inverted
     503           5 :         CATCH_REQUIRE_THROWS_AS(n->replace_child(child2, child1), csspp::csspp_exception_logic);
     504           1 :     }
     505             : 
     506             :     // insert with invalid index
     507             :     {
     508           3 :         csspp::position pos("test.css");
     509           1 :         csspp::node::pointer_t n(new csspp::node(csspp::node_type_t::LIST, pos));
     510             : 
     511           1 :         csspp::node::pointer_t child1(new csspp::node(csspp::node_type_t::INTEGER, pos));
     512           1 :         child1->set_integer(345);
     513           1 :         csspp::node::pointer_t child2(new csspp::node(csspp::node_type_t::STRING, pos));
     514           1 :         child2->set_string("world.");
     515             : 
     516           1 :         n->insert_child(0, child1);
     517             : 
     518             :         // insert index can be 0 or 1, anything else and it is an overflow
     519         101 :         for(int i(-100); i < 0; ++i)
     520             :         {
     521         300 :             CATCH_REQUIRE_THROWS_AS(n->insert_child(i, child2), csspp::csspp_exception_overflow);
     522             :         }
     523         100 :         for(int i(2); i <= 100; ++i)
     524             :         {
     525         297 :             CATCH_REQUIRE_THROWS_AS(n->insert_child(i, child2), csspp::csspp_exception_overflow);
     526             :         }
     527           1 :     }
     528             : 
     529             :     // no error left over
     530           1 :     VERIFY_ERRORS("");
     531           1 : }
     532             : 
     533           1 : CATCH_TEST_CASE("True and false", "[node] [type] [output]")
     534             : {
     535             :     // test boolean values from an identifier
     536             :     {
     537           3 :         csspp::position pos("test.css");
     538           1 :         csspp::node::pointer_t n(new csspp::node(csspp::node_type_t::IDENTIFIER, pos));
     539             : 
     540           1 :         CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_INVALID);
     541             : 
     542           1 :         n->set_string("true");
     543           1 :         CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_TRUE);
     544             : 
     545           1 :         n->set_string("false");
     546           1 :         CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_FALSE);
     547             : 
     548           1 :         n->set_string("null");
     549           1 :         CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_FALSE);
     550             : 
     551           1 :         n->set_string("other");
     552           1 :         CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_INVALID);
     553             : 
     554             :         // fortuitious...
     555           1 :         n->set_string("invalid");
     556           1 :         CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_INVALID);
     557           1 :     }
     558             : 
     559             :     // test boolean values from the NULL token
     560             :     {
     561           3 :         csspp::position pos("test.css");
     562           1 :         csspp::node::pointer_t n(new csspp::node(csspp::node_type_t::NULL_TOKEN, pos));
     563             : 
     564           1 :         CATCH_REQUIRE(n->to_boolean() == csspp::boolean_t::BOOLEAN_FALSE);
     565           1 :     }
     566             : 
     567             :     // no error left over
     568           1 :     VERIFY_ERRORS("");
     569           1 : }
     570             : 
     571           1 : CATCH_TEST_CASE("Node variables", "[node] [variable]")
     572             : {
     573             :     // set/get variables
     574             :     {
     575           3 :         csspp::position pos("test.css");
     576           1 :         csspp::node::pointer_t n(new csspp::node(csspp::node_type_t::LIST, pos));
     577             : 
     578          23 :         csspp::node::pointer_t t[21];
     579          22 :         for(int i(-10); i <= 10; ++i)
     580             :         {
     581          21 :             std::string nb(std::to_string(i));
     582          21 :             t[i + 10].reset(new csspp::node(csspp::node_type_t::IDENTIFIER, pos));
     583          21 :             t[i + 10]->set_string("test" + nb);
     584             : 
     585          21 :             n->set_variable("t" + nb, t[i + 10]);
     586          21 :             CATCH_REQUIRE(n->get_variable("t" + nb) == t[i + 10]);
     587          21 :         }
     588             : 
     589             :         // check contents again
     590          22 :         for(int i(-10); i <= 10; ++i)
     591             :         {
     592          21 :             std::string nb(std::to_string(i));
     593             : 
     594          42 :             csspp::node::pointer_t p(n->get_variable("t" + nb));
     595          21 :             CATCH_REQUIRE(p == t[i + 10]);
     596          21 :             CATCH_REQUIRE(p->get_string() == "test" + nb);
     597          21 :         }
     598             : 
     599           1 :         n->clear_variables();
     600             : 
     601             :         // all are gone now!
     602          22 :         for(int i(-10); i <= 10; ++i)
     603             :         {
     604          21 :             std::string nb(std::to_string(i));
     605             : 
     606          42 :             csspp::node::pointer_t p(n->get_variable("t" + nb));
     607          21 :             CATCH_REQUIRE(!p);
     608          21 :         }
     609          23 :     }
     610             : 
     611             :     // no error left over
     612           1 :     VERIFY_ERRORS("");
     613           1 : }
     614             : 
     615           1 : CATCH_TEST_CASE("Node flags", "[node] [flag]")
     616             : {
     617             :     // read/write flags
     618             :     {
     619           3 :         csspp::position pos("test.css");
     620           1 :         csspp::node::pointer_t n(new csspp::node(csspp::node_type_t::LIST, pos));
     621             : 
     622          22 :         for(int i(-10); i <= 10; ++i)
     623             :         {
     624          42 :             std::string nb("t" + std::to_string(i));
     625             : 
     626          21 :             n->set_flag(nb, true);
     627          21 :             CATCH_REQUIRE(n->get_flag(nb));
     628          21 :             n->set_flag(nb, false);
     629          21 :             CATCH_REQUIRE_FALSE(n->get_flag(nb));
     630          21 :             n->set_flag(nb, true);
     631          21 :             CATCH_REQUIRE(n->get_flag(nb));
     632          21 :         }
     633             : 
     634             :         // check contents again
     635          22 :         for(int i(-10); i <= 10; ++i)
     636             :         {
     637          42 :             std::string nb("t" + std::to_string(i));
     638             : 
     639          21 :             CATCH_REQUIRE(n->get_flag(nb));
     640          21 :         }
     641             : 
     642           1 :         n->clear_flags();
     643             : 
     644             :         // all are gone now!
     645          22 :         for(int i(-10); i <= 10; ++i)
     646             :         {
     647          42 :             std::string nb("t" + std::to_string(i));
     648             : 
     649          21 :             CATCH_REQUIRE_FALSE(n->get_flag(nb));
     650          21 :         }
     651           1 :     }
     652             : 
     653             :     // no error left over
     654           1 :     VERIFY_ERRORS("");
     655           1 : }
     656             : 
     657           1 : CATCH_TEST_CASE("Type names", "[node] [type] [output]")
     658             : {
     659             :     // we expect the test suite to be compiled with the exact same version
     660           1 :     csspp::node_type_t w(csspp::node_type_t::UNKNOWN);
     661          69 :     while(w <= csspp::node_type_t::max_type)
     662             :     {
     663         204 :         csspp::position pos("test.css");
     664          68 :         csspp::node::pointer_t n(new csspp::node(w, pos));
     665             : 
     666          68 :         std::stringstream ss;
     667          68 :         ss << n->get_type();
     668          68 :         std::string const name(ss.str());
     669             : 
     670          68 :         switch(w)
     671             :         {
     672           1 :         case csspp::node_type_t::UNKNOWN:
     673           1 :             CATCH_REQUIRE(name == "UNKNOWN");
     674           1 :             break;
     675             : 
     676           1 :         case csspp::node_type_t::ADD:
     677           1 :             CATCH_REQUIRE(name == "ADD");
     678           1 :             break;
     679             : 
     680           1 :         case csspp::node_type_t::AND:
     681           1 :             CATCH_REQUIRE(name == "AND");
     682           1 :             break;
     683             : 
     684           1 :         case csspp::node_type_t::ASSIGNMENT:
     685           1 :             CATCH_REQUIRE(name == "ASSIGNMENT");
     686           1 :             break;
     687             : 
     688           1 :         case csspp::node_type_t::AT_KEYWORD:
     689           1 :             CATCH_REQUIRE(name == "AT_KEYWORD");
     690           1 :             break;
     691             : 
     692           1 :         case csspp::node_type_t::BOOLEAN:
     693           1 :             CATCH_REQUIRE(name == "BOOLEAN");
     694           1 :             break;
     695             : 
     696           1 :         case csspp::node_type_t::CDC:
     697           1 :             CATCH_REQUIRE(name == "CDC");
     698           1 :             break;
     699             : 
     700           1 :         case csspp::node_type_t::CDO:
     701           1 :             CATCH_REQUIRE(name == "CDO");
     702           1 :             break;
     703             : 
     704           1 :         case csspp::node_type_t::CLOSE_CURLYBRACKET:
     705           1 :             CATCH_REQUIRE(name == "CLOSE_CURLYBRACKET");
     706           1 :             break;
     707             : 
     708           1 :         case csspp::node_type_t::CLOSE_PARENTHESIS:
     709           1 :             CATCH_REQUIRE(name == "CLOSE_PARENTHESIS");
     710           1 :             break;
     711             : 
     712           1 :         case csspp::node_type_t::CLOSE_SQUAREBRACKET:
     713           1 :             CATCH_REQUIRE(name == "CLOSE_SQUAREBRACKET");
     714           1 :             break;
     715             : 
     716           1 :         case csspp::node_type_t::COLON:
     717           1 :             CATCH_REQUIRE(name == "COLON");
     718           1 :             break;
     719             : 
     720           1 :         case csspp::node_type_t::COLOR:
     721           1 :             CATCH_REQUIRE(name == "COLOR");
     722           1 :             break;
     723             : 
     724           1 :         case csspp::node_type_t::COLUMN:
     725           1 :             CATCH_REQUIRE(name == "COLUMN");
     726           1 :             break;
     727             : 
     728           1 :         case csspp::node_type_t::COMMA:
     729           1 :             CATCH_REQUIRE(name == "COMMA");
     730           1 :             break;
     731             : 
     732           1 :         case csspp::node_type_t::COMMENT:
     733           1 :             CATCH_REQUIRE(name == "COMMENT");
     734           1 :             break;
     735             : 
     736           1 :         case csspp::node_type_t::CONDITIONAL:
     737           1 :             CATCH_REQUIRE(name == "CONDITIONAL");
     738           1 :             break;
     739             : 
     740           1 :         case csspp::node_type_t::DASH_MATCH:
     741           1 :             CATCH_REQUIRE(name == "DASH_MATCH");
     742           1 :             break;
     743             : 
     744           1 :         case csspp::node_type_t::DECIMAL_NUMBER:
     745           1 :             CATCH_REQUIRE(name == "DECIMAL_NUMBER");
     746           1 :             break;
     747             : 
     748           1 :         case csspp::node_type_t::DIVIDE:
     749           1 :             CATCH_REQUIRE(name == "DIVIDE");
     750           1 :             break;
     751             : 
     752           1 :         case csspp::node_type_t::DOLLAR:
     753           1 :             CATCH_REQUIRE(name == "DOLLAR");
     754           1 :             break;
     755             : 
     756           1 :         case csspp::node_type_t::EOF_TOKEN:
     757           1 :             CATCH_REQUIRE(name == "EOF_TOKEN");
     758           1 :             break;
     759             : 
     760           1 :         case csspp::node_type_t::EQUAL:
     761           1 :             CATCH_REQUIRE(name == "EQUAL");
     762           1 :             break;
     763             : 
     764           1 :         case csspp::node_type_t::EXCLAMATION:
     765           1 :             CATCH_REQUIRE(name == "EXCLAMATION");
     766           1 :             break;
     767             : 
     768           1 :         case csspp::node_type_t::FONT_METRICS:
     769           1 :             CATCH_REQUIRE(name == "FONT_METRICS");
     770           1 :             break;
     771             : 
     772           1 :         case csspp::node_type_t::FUNCTION:
     773           1 :             CATCH_REQUIRE(name == "FUNCTION");
     774           1 :             break;
     775             : 
     776           1 :         case csspp::node_type_t::GREATER_EQUAL:
     777           1 :             CATCH_REQUIRE(name == "GREATER_EQUAL");
     778           1 :             break;
     779             : 
     780           1 :         case csspp::node_type_t::GREATER_THAN:
     781           1 :             CATCH_REQUIRE(name == "GREATER_THAN");
     782           1 :             break;
     783             : 
     784           1 :         case csspp::node_type_t::HASH:
     785           1 :             CATCH_REQUIRE(name == "HASH");
     786           1 :             break;
     787             : 
     788           1 :         case csspp::node_type_t::IDENTIFIER:
     789           1 :             CATCH_REQUIRE(name == "IDENTIFIER");
     790           1 :             break;
     791             : 
     792           1 :         case csspp::node_type_t::INCLUDE_MATCH:
     793           1 :             CATCH_REQUIRE(name == "INCLUDE_MATCH");
     794           1 :             break;
     795             : 
     796           1 :         case csspp::node_type_t::INTEGER:
     797           1 :             CATCH_REQUIRE(name == "INTEGER");
     798           1 :             break;
     799             : 
     800           1 :         case csspp::node_type_t::LESS_EQUAL:
     801           1 :             CATCH_REQUIRE(name == "LESS_EQUAL");
     802           1 :             break;
     803             : 
     804           1 :         case csspp::node_type_t::LESS_THAN:
     805           1 :             CATCH_REQUIRE(name == "LESS_THAN");
     806           1 :             break;
     807             : 
     808           1 :         case csspp::node_type_t::MODULO:
     809           1 :             CATCH_REQUIRE(name == "MODULO");
     810           1 :             break;
     811             : 
     812           1 :         case csspp::node_type_t::MULTIPLY:
     813           1 :             CATCH_REQUIRE(name == "MULTIPLY");
     814           1 :             break;
     815             : 
     816           1 :         case csspp::node_type_t::NOT_EQUAL:
     817           1 :             CATCH_REQUIRE(name == "NOT_EQUAL");
     818           1 :             break;
     819             : 
     820           1 :         case csspp::node_type_t::NULL_TOKEN:
     821           1 :             CATCH_REQUIRE(name == "NULL_TOKEN");
     822           1 :             break;
     823             : 
     824           1 :         case csspp::node_type_t::OPEN_CURLYBRACKET:
     825           1 :             CATCH_REQUIRE(name == "OPEN_CURLYBRACKET");
     826           1 :             break;
     827             : 
     828           1 :         case csspp::node_type_t::OPEN_PARENTHESIS:
     829           1 :             CATCH_REQUIRE(name == "OPEN_PARENTHESIS");
     830           1 :             break;
     831             : 
     832           1 :         case csspp::node_type_t::OPEN_SQUAREBRACKET:
     833           1 :             CATCH_REQUIRE(name == "OPEN_SQUAREBRACKET");
     834           1 :             break;
     835             : 
     836           1 :         case csspp::node_type_t::PERCENT:
     837           1 :             CATCH_REQUIRE(name == "PERCENT");
     838           1 :             break;
     839             : 
     840           1 :         case csspp::node_type_t::PERIOD:
     841           1 :             CATCH_REQUIRE(name == "PERIOD");
     842           1 :             break;
     843             : 
     844           1 :         case csspp::node_type_t::PLACEHOLDER:
     845           1 :             CATCH_REQUIRE(name == "PLACEHOLDER");
     846           1 :             break;
     847             : 
     848           1 :         case csspp::node_type_t::POWER:
     849           1 :             CATCH_REQUIRE(name == "POWER");
     850           1 :             break;
     851             : 
     852           1 :         case csspp::node_type_t::PRECEDED:
     853           1 :             CATCH_REQUIRE(name == "PRECEDED");
     854           1 :             break;
     855             : 
     856           1 :         case csspp::node_type_t::PREFIX_MATCH:
     857           1 :             CATCH_REQUIRE(name == "PREFIX_MATCH");
     858           1 :             break;
     859             : 
     860           1 :         case csspp::node_type_t::REFERENCE:
     861           1 :             CATCH_REQUIRE(name == "REFERENCE");
     862           1 :             break;
     863             : 
     864           1 :         case csspp::node_type_t::SCOPE:
     865           1 :             CATCH_REQUIRE(name == "SCOPE");
     866           1 :             break;
     867             : 
     868           1 :         case csspp::node_type_t::SEMICOLON:
     869           1 :             CATCH_REQUIRE(name == "SEMICOLON");
     870           1 :             break;
     871             : 
     872           1 :         case csspp::node_type_t::STRING:
     873           1 :             CATCH_REQUIRE(name == "STRING");
     874           1 :             break;
     875             : 
     876           1 :         case csspp::node_type_t::SUBSTRING_MATCH:
     877           1 :             CATCH_REQUIRE(name == "SUBSTRING_MATCH");
     878           1 :             break;
     879             : 
     880           1 :         case csspp::node_type_t::SUBTRACT:
     881           1 :             CATCH_REQUIRE(name == "SUBTRACT");
     882           1 :             break;
     883             : 
     884           1 :         case csspp::node_type_t::SUFFIX_MATCH:
     885           1 :             CATCH_REQUIRE(name == "SUFFIX_MATCH");
     886           1 :             break;
     887             : 
     888           1 :         case csspp::node_type_t::UNICODE_RANGE:
     889           1 :             CATCH_REQUIRE(name == "UNICODE_RANGE");
     890           1 :             break;
     891             : 
     892           1 :         case csspp::node_type_t::URL:
     893           1 :             CATCH_REQUIRE(name == "URL");
     894           1 :             break;
     895             : 
     896           1 :         case csspp::node_type_t::VARIABLE:
     897           1 :             CATCH_REQUIRE(name == "VARIABLE");
     898           1 :             break;
     899             : 
     900           1 :         case csspp::node_type_t::VARIABLE_FUNCTION:
     901           1 :             CATCH_REQUIRE(name == "VARIABLE_FUNCTION");
     902           1 :             break;
     903             : 
     904           1 :         case csspp::node_type_t::WHITESPACE:
     905           1 :             CATCH_REQUIRE(name == "WHITESPACE");
     906           1 :             break;
     907             : 
     908             :         // second part
     909           1 :         case csspp::node_type_t::AN_PLUS_B:
     910           1 :             CATCH_REQUIRE(name == "AN_PLUS_B");
     911           1 :             break;
     912             : 
     913           1 :         case csspp::node_type_t::ARG:
     914           1 :             CATCH_REQUIRE(name == "ARG");
     915           1 :             break;
     916             : 
     917           1 :         case csspp::node_type_t::ARRAY:
     918           1 :             CATCH_REQUIRE(name == "ARRAY");
     919           1 :             break;
     920             : 
     921           1 :         case csspp::node_type_t::COMPONENT_VALUE:
     922           1 :             CATCH_REQUIRE(name == "COMPONENT_VALUE");
     923           1 :             break;
     924             : 
     925           1 :         case csspp::node_type_t::DECLARATION:
     926           1 :             CATCH_REQUIRE(name == "DECLARATION");
     927           1 :             break;
     928             : 
     929           1 :         case csspp::node_type_t::LIST:
     930           1 :             CATCH_REQUIRE(name == "LIST");
     931           1 :             break;
     932             : 
     933           1 :         case csspp::node_type_t::MAP:
     934           1 :             CATCH_REQUIRE(name == "MAP");
     935           1 :             break;
     936             : 
     937           1 :         case csspp::node_type_t::FRAME:
     938           1 :             CATCH_REQUIRE(name == "FRAME");
     939           1 :             break;
     940             : 
     941           1 :         case csspp::node_type_t::max_type:
     942           1 :             CATCH_REQUIRE(name == "max_type");
     943           1 :             break;
     944             : 
     945             :         }
     946             : 
     947             :         // move to the next type
     948          68 :         w = static_cast<csspp::node_type_t>(static_cast<int>(w) + 1);
     949          68 :     }
     950             : 
     951             :     // no error left over
     952           1 :     VERIFY_ERRORS("");
     953           1 : }
     954             : 
     955           1 : CATCH_TEST_CASE("Node output", "[node] [output]")
     956             : {
     957             :     // we expect the test suite to be compiled with the exact same version
     958           1 :     csspp::node_type_t w(csspp::node_type_t::UNKNOWN);
     959          69 :     while(w <= csspp::node_type_t::max_type)
     960             :     {
     961         204 :         csspp::position pos("test.css");
     962          68 :         csspp::node::pointer_t n(new csspp::node(w, pos));
     963             : 
     964          68 :         std::stringstream ss;
     965          68 :         ss << n->get_type();
     966          68 :         std::string const name(ss.str());
     967             : 
     968          68 :         switch(w)
     969             :         {
     970           1 :         case csspp::node_type_t::UNKNOWN:
     971           1 :             CATCH_REQUIRE(name == "UNKNOWN");
     972           1 :             break;
     973             : 
     974           1 :         case csspp::node_type_t::ADD:
     975           1 :             CATCH_REQUIRE(name == "ADD");
     976           1 :             break;
     977             : 
     978           1 :         case csspp::node_type_t::AND:
     979           1 :             CATCH_REQUIRE(name == "AND");
     980           1 :             break;
     981             : 
     982           1 :         case csspp::node_type_t::ASSIGNMENT:
     983           1 :             CATCH_REQUIRE(name == "ASSIGNMENT");
     984           1 :             break;
     985             : 
     986           1 :         case csspp::node_type_t::AT_KEYWORD:
     987           1 :             CATCH_REQUIRE(name == "AT_KEYWORD");
     988           1 :             break;
     989             : 
     990           1 :         case csspp::node_type_t::BOOLEAN:
     991           1 :             CATCH_REQUIRE(name == "BOOLEAN");
     992           1 :             break;
     993             : 
     994           1 :         case csspp::node_type_t::CDC:
     995           1 :             CATCH_REQUIRE(name == "CDC");
     996           1 :             break;
     997             : 
     998           1 :         case csspp::node_type_t::CDO:
     999           1 :             CATCH_REQUIRE(name == "CDO");
    1000           1 :             break;
    1001             : 
    1002           1 :         case csspp::node_type_t::CLOSE_CURLYBRACKET:
    1003           1 :             CATCH_REQUIRE(name == "CLOSE_CURLYBRACKET");
    1004           1 :             break;
    1005             : 
    1006           1 :         case csspp::node_type_t::CLOSE_PARENTHESIS:
    1007           1 :             CATCH_REQUIRE(name == "CLOSE_PARENTHESIS");
    1008           1 :             break;
    1009             : 
    1010           1 :         case csspp::node_type_t::CLOSE_SQUAREBRACKET:
    1011           1 :             CATCH_REQUIRE(name == "CLOSE_SQUAREBRACKET");
    1012           1 :             break;
    1013             : 
    1014           1 :         case csspp::node_type_t::COLON:
    1015           1 :             CATCH_REQUIRE(name == "COLON");
    1016           1 :             break;
    1017             : 
    1018           1 :         case csspp::node_type_t::COLOR:
    1019           1 :             CATCH_REQUIRE(name == "COLOR");
    1020           1 :             break;
    1021             : 
    1022           1 :         case csspp::node_type_t::COLUMN:
    1023           1 :             CATCH_REQUIRE(name == "COLUMN");
    1024           1 :             break;
    1025             : 
    1026           1 :         case csspp::node_type_t::COMMA:
    1027           1 :             CATCH_REQUIRE(name == "COMMA");
    1028           1 :             break;
    1029             : 
    1030           1 :         case csspp::node_type_t::COMMENT:
    1031           1 :             CATCH_REQUIRE(name == "COMMENT");
    1032           1 :             break;
    1033             : 
    1034           1 :         case csspp::node_type_t::CONDITIONAL:
    1035           1 :             CATCH_REQUIRE(name == "CONDITIONAL");
    1036           1 :             break;
    1037             : 
    1038           1 :         case csspp::node_type_t::DASH_MATCH:
    1039           1 :             CATCH_REQUIRE(name == "DASH_MATCH");
    1040           1 :             break;
    1041             : 
    1042           1 :         case csspp::node_type_t::DECIMAL_NUMBER:
    1043           1 :             CATCH_REQUIRE(name == "DECIMAL_NUMBER");
    1044           1 :             break;
    1045             : 
    1046           1 :         case csspp::node_type_t::DIVIDE:
    1047           1 :             CATCH_REQUIRE(name == "DIVIDE");
    1048           1 :             break;
    1049             : 
    1050           1 :         case csspp::node_type_t::DOLLAR:
    1051           1 :             CATCH_REQUIRE(name == "DOLLAR");
    1052           1 :             break;
    1053             : 
    1054           1 :         case csspp::node_type_t::EOF_TOKEN:
    1055           1 :             CATCH_REQUIRE(name == "EOF_TOKEN");
    1056           1 :             break;
    1057             : 
    1058           1 :         case csspp::node_type_t::EQUAL:
    1059           1 :             CATCH_REQUIRE(name == "EQUAL");
    1060           1 :             break;
    1061             : 
    1062           1 :         case csspp::node_type_t::EXCLAMATION:
    1063           1 :             CATCH_REQUIRE(name == "EXCLAMATION");
    1064           1 :             break;
    1065             : 
    1066           1 :         case csspp::node_type_t::FONT_METRICS:
    1067           1 :             CATCH_REQUIRE(name == "FONT_METRICS");
    1068           1 :             break;
    1069             : 
    1070           1 :         case csspp::node_type_t::FUNCTION:
    1071           1 :             CATCH_REQUIRE(name == "FUNCTION");
    1072           1 :             break;
    1073             : 
    1074           1 :         case csspp::node_type_t::GREATER_EQUAL:
    1075           1 :             CATCH_REQUIRE(name == "GREATER_EQUAL");
    1076           1 :             break;
    1077             : 
    1078           1 :         case csspp::node_type_t::GREATER_THAN:
    1079           1 :             CATCH_REQUIRE(name == "GREATER_THAN");
    1080           1 :             break;
    1081             : 
    1082           1 :         case csspp::node_type_t::HASH:
    1083           1 :             CATCH_REQUIRE(name == "HASH");
    1084           1 :             break;
    1085             : 
    1086           1 :         case csspp::node_type_t::IDENTIFIER:
    1087           1 :             CATCH_REQUIRE(name == "IDENTIFIER");
    1088           1 :             break;
    1089             : 
    1090           1 :         case csspp::node_type_t::INCLUDE_MATCH:
    1091           1 :             CATCH_REQUIRE(name == "INCLUDE_MATCH");
    1092           1 :             break;
    1093             : 
    1094           1 :         case csspp::node_type_t::INTEGER:
    1095           1 :             CATCH_REQUIRE(name == "INTEGER");
    1096           1 :             break;
    1097             : 
    1098           1 :         case csspp::node_type_t::LESS_EQUAL:
    1099           1 :             CATCH_REQUIRE(name == "LESS_EQUAL");
    1100           1 :             break;
    1101             : 
    1102           1 :         case csspp::node_type_t::LESS_THAN:
    1103           1 :             CATCH_REQUIRE(name == "LESS_THAN");
    1104           1 :             break;
    1105             : 
    1106           1 :         case csspp::node_type_t::MODULO:
    1107           1 :             CATCH_REQUIRE(name == "MODULO");
    1108           1 :             break;
    1109             : 
    1110           1 :         case csspp::node_type_t::MULTIPLY:
    1111           1 :             CATCH_REQUIRE(name == "MULTIPLY");
    1112           1 :             break;
    1113             : 
    1114           1 :         case csspp::node_type_t::NOT_EQUAL:
    1115           1 :             CATCH_REQUIRE(name == "NOT_EQUAL");
    1116           1 :             break;
    1117             : 
    1118           1 :         case csspp::node_type_t::NULL_TOKEN:
    1119           1 :             CATCH_REQUIRE(name == "NULL_TOKEN");
    1120           1 :             break;
    1121             : 
    1122           1 :         case csspp::node_type_t::OPEN_CURLYBRACKET:
    1123           1 :             CATCH_REQUIRE(name == "OPEN_CURLYBRACKET");
    1124           1 :             break;
    1125             : 
    1126           1 :         case csspp::node_type_t::OPEN_PARENTHESIS:
    1127           1 :             CATCH_REQUIRE(name == "OPEN_PARENTHESIS");
    1128           1 :             break;
    1129             : 
    1130           1 :         case csspp::node_type_t::OPEN_SQUAREBRACKET:
    1131           1 :             CATCH_REQUIRE(name == "OPEN_SQUAREBRACKET");
    1132           1 :             break;
    1133             : 
    1134           1 :         case csspp::node_type_t::PERCENT:
    1135           1 :             CATCH_REQUIRE(name == "PERCENT");
    1136           1 :             break;
    1137             : 
    1138           1 :         case csspp::node_type_t::PERIOD:
    1139           1 :             CATCH_REQUIRE(name == "PERIOD");
    1140           1 :             break;
    1141             : 
    1142           1 :         case csspp::node_type_t::PLACEHOLDER:
    1143           1 :             CATCH_REQUIRE(name == "PLACEHOLDER");
    1144           1 :             break;
    1145             : 
    1146           1 :         case csspp::node_type_t::POWER:
    1147           1 :             CATCH_REQUIRE(name == "POWER");
    1148           1 :             break;
    1149             : 
    1150           1 :         case csspp::node_type_t::PRECEDED:
    1151           1 :             CATCH_REQUIRE(name == "PRECEDED");
    1152           1 :             break;
    1153             : 
    1154           1 :         case csspp::node_type_t::PREFIX_MATCH:
    1155           1 :             CATCH_REQUIRE(name == "PREFIX_MATCH");
    1156           1 :             break;
    1157             : 
    1158           1 :         case csspp::node_type_t::REFERENCE:
    1159           1 :             CATCH_REQUIRE(name == "REFERENCE");
    1160           1 :             break;
    1161             : 
    1162           1 :         case csspp::node_type_t::SCOPE:
    1163           1 :             CATCH_REQUIRE(name == "SCOPE");
    1164           1 :             break;
    1165             : 
    1166           1 :         case csspp::node_type_t::SEMICOLON:
    1167           1 :             CATCH_REQUIRE(name == "SEMICOLON");
    1168           1 :             break;
    1169             : 
    1170           1 :         case csspp::node_type_t::STRING:
    1171           1 :             CATCH_REQUIRE(name == "STRING");
    1172           1 :             break;
    1173             : 
    1174           1 :         case csspp::node_type_t::SUBSTRING_MATCH:
    1175           1 :             CATCH_REQUIRE(name == "SUBSTRING_MATCH");
    1176           1 :             break;
    1177             : 
    1178           1 :         case csspp::node_type_t::SUBTRACT:
    1179           1 :             CATCH_REQUIRE(name == "SUBTRACT");
    1180           1 :             break;
    1181             : 
    1182           1 :         case csspp::node_type_t::SUFFIX_MATCH:
    1183           1 :             CATCH_REQUIRE(name == "SUFFIX_MATCH");
    1184           1 :             break;
    1185             : 
    1186           1 :         case csspp::node_type_t::UNICODE_RANGE:
    1187           1 :             CATCH_REQUIRE(name == "UNICODE_RANGE");
    1188           1 :             break;
    1189             : 
    1190           1 :         case csspp::node_type_t::URL:
    1191           1 :             CATCH_REQUIRE(name == "URL");
    1192           1 :             break;
    1193             : 
    1194           1 :         case csspp::node_type_t::VARIABLE:
    1195           1 :             CATCH_REQUIRE(name == "VARIABLE");
    1196           1 :             break;
    1197             : 
    1198           1 :         case csspp::node_type_t::VARIABLE_FUNCTION:
    1199           1 :             CATCH_REQUIRE(name == "VARIABLE_FUNCTION");
    1200           1 :             break;
    1201             : 
    1202           1 :         case csspp::node_type_t::WHITESPACE:
    1203           1 :             CATCH_REQUIRE(name == "WHITESPACE");
    1204           1 :             break;
    1205             : 
    1206             :         // second part
    1207           1 :         case csspp::node_type_t::AN_PLUS_B:
    1208           1 :             CATCH_REQUIRE(name == "AN_PLUS_B");
    1209           1 :             break;
    1210             : 
    1211           1 :         case csspp::node_type_t::ARG:
    1212           1 :             CATCH_REQUIRE(name == "ARG");
    1213           1 :             break;
    1214             : 
    1215           1 :         case csspp::node_type_t::ARRAY:
    1216           1 :             CATCH_REQUIRE(name == "ARRAY");
    1217           1 :             break;
    1218             : 
    1219           1 :         case csspp::node_type_t::COMPONENT_VALUE:
    1220           1 :             CATCH_REQUIRE(name == "COMPONENT_VALUE");
    1221           1 :             break;
    1222             : 
    1223           1 :         case csspp::node_type_t::DECLARATION:
    1224           1 :             CATCH_REQUIRE(name == "DECLARATION");
    1225           1 :             break;
    1226             : 
    1227           1 :         case csspp::node_type_t::LIST:
    1228           1 :             CATCH_REQUIRE(name == "LIST");
    1229           1 :             break;
    1230             : 
    1231           1 :         case csspp::node_type_t::MAP:
    1232           1 :             CATCH_REQUIRE(name == "MAP");
    1233           1 :             break;
    1234             : 
    1235           1 :         case csspp::node_type_t::FRAME:
    1236           1 :             CATCH_REQUIRE(name == "FRAME");
    1237           1 :             break;
    1238             : 
    1239           1 :         case csspp::node_type_t::max_type:
    1240           1 :             CATCH_REQUIRE(name == "max_type");
    1241           1 :             break;
    1242             : 
    1243             :         }
    1244             : 
    1245             :         // move to the next type
    1246          68 :         w = static_cast<csspp::node_type_t>(static_cast<int>(w) + 1);
    1247          68 :     }
    1248             : 
    1249             :     // no error left over
    1250           1 :     VERIFY_ERRORS("");
    1251           1 : }
    1252             : 
    1253           1 : CATCH_TEST_CASE("Node to string", "[node] [type] [output]")
    1254             : {
    1255             :     // we expect the test suite to be compiled with the exact same version
    1256           5 :     for(int flags(0); flags < 4; ++flags)
    1257             :     {
    1258           4 :         csspp::node_type_t w(csspp::node_type_t::UNKNOWN);
    1259         276 :         while(w <= csspp::node_type_t::max_type)
    1260             :         {
    1261         816 :             csspp::position pos("test.css");
    1262         272 :             csspp::node::pointer_t n(new csspp::node(w, pos));
    1263             : 
    1264         272 :             switch(w)
    1265             :             {
    1266           4 :             case csspp::node_type_t::ADD:
    1267           4 :                 CATCH_REQUIRE(n->to_string(flags) == "+");
    1268           4 :                 break;
    1269             : 
    1270           4 :             case csspp::node_type_t::AND:
    1271           4 :                 CATCH_REQUIRE(n->to_string(flags) == "&&");
    1272           4 :                 break;
    1273             : 
    1274           4 :             case csspp::node_type_t::ASSIGNMENT:
    1275           4 :                 CATCH_REQUIRE(n->to_string(flags) == ":=");
    1276           4 :                 break;
    1277             : 
    1278           4 :             case csspp::node_type_t::AT_KEYWORD:
    1279           4 :                 CATCH_REQUIRE(n->to_string(flags) == "@");
    1280           4 :                 n->set_string("test");
    1281           4 :                 CATCH_REQUIRE(n->to_string(flags) == "@test");
    1282           4 :                 break;
    1283             : 
    1284           4 :             case csspp::node_type_t::BOOLEAN:
    1285           4 :                 CATCH_REQUIRE(n->to_string(flags) == "false");
    1286           4 :                 n->set_boolean(true);
    1287           4 :                 CATCH_REQUIRE(n->to_string(flags) == "true");
    1288           4 :                 break;
    1289             : 
    1290           4 :             case csspp::node_type_t::COLON:
    1291           4 :                 CATCH_REQUIRE(n->to_string(flags) == ":");
    1292           4 :                 break;
    1293             : 
    1294           4 :             case csspp::node_type_t::COLOR:
    1295             :                 {
    1296           4 :                     CATCH_REQUIRE(n->to_string(flags) == "transparent");
    1297           4 :                     csspp::color c;
    1298           4 :                     c.set_color(0x58, 0x32, 0xff, 0xff);
    1299           4 :                     n->set_color(c);
    1300           4 :                     CATCH_REQUIRE(n->to_string(flags) == "#5832ff");
    1301           4 :                     c.set_color(0x58, 0x32, 0xff, 0x7f);
    1302           4 :                     n->set_color(c);
    1303           4 :                     CATCH_REQUIRE(n->to_string(flags) == "rgba(88,50,255,.5)");
    1304             :                 }
    1305             :                 break;
    1306             : 
    1307           4 :             case csspp::node_type_t::COLUMN:
    1308           4 :                 CATCH_REQUIRE(n->to_string(flags) == "||");
    1309           4 :                 break;
    1310             : 
    1311           4 :             case csspp::node_type_t::COMMA:
    1312           4 :                 CATCH_REQUIRE(n->to_string(flags) == ",");
    1313           4 :                 break;
    1314             : 
    1315           4 :             case csspp::node_type_t::COMMENT:
    1316             :                 // once we remove the @preserve, this could happen
    1317           4 :                 CATCH_REQUIRE(n->to_string(flags) == "");
    1318           4 :                 n->set_string("the comment");
    1319           4 :                 CATCH_REQUIRE(n->to_string(flags) == "// the comment\n");
    1320           4 :                 n->set_string("the comment\non two lines");
    1321           4 :                 CATCH_REQUIRE(n->to_string(flags) == "// the comment\n// on two lines\n");
    1322           4 :                 n->set_integer(1);
    1323           4 :                 n->set_string("the C-like comment\non two lines");
    1324           4 :                 CATCH_REQUIRE(n->to_string(flags) == "/* the C-like comment\non two lines */");
    1325           4 :                 break;
    1326             : 
    1327           4 :             case csspp::node_type_t::CONDITIONAL:
    1328           4 :                 CATCH_REQUIRE(n->to_string(flags) == "?");
    1329           4 :                 break;
    1330             : 
    1331           4 :             case csspp::node_type_t::DASH_MATCH:
    1332           4 :                 CATCH_REQUIRE(n->to_string(flags) == "|=");
    1333           4 :                 break;
    1334             : 
    1335           4 :             case csspp::node_type_t::DECIMAL_NUMBER:
    1336           4 :                 CATCH_REQUIRE(n->to_string(flags) == "0");
    1337           4 :                 n->set_string("em");
    1338           4 :                 CATCH_REQUIRE(n->to_string(flags) == "0em");
    1339           4 :                 n->set_decimal_number(1.25);
    1340           4 :                 CATCH_REQUIRE(n->to_string(flags) == "1.25em");
    1341           4 :                 break;
    1342             : 
    1343           4 :             case csspp::node_type_t::DIVIDE:
    1344           4 :                 if((flags & csspp::node::g_to_string_flag_add_spaces) != 0)
    1345             :                 {
    1346           2 :                     CATCH_REQUIRE(n->to_string(flags) == " / ");
    1347             :                 }
    1348             :                 else
    1349             :                 {
    1350           2 :                     CATCH_REQUIRE(n->to_string(flags) == "/");
    1351             :                 }
    1352           4 :                 break;
    1353             : 
    1354           4 :             case csspp::node_type_t::DOLLAR:
    1355           4 :                 CATCH_REQUIRE(n->to_string(flags) == "$");
    1356           4 :                 break;
    1357             : 
    1358           4 :             case csspp::node_type_t::EQUAL:
    1359           4 :                 CATCH_REQUIRE(n->to_string(flags) == "=");
    1360           4 :                 break;
    1361             : 
    1362           4 :             case csspp::node_type_t::EXCLAMATION:
    1363           4 :                 CATCH_REQUIRE(n->to_string(flags) == "!");
    1364           4 :                 break;
    1365             : 
    1366           4 :             case csspp::node_type_t::FONT_METRICS:
    1367           4 :                 CATCH_REQUIRE(n->to_string(flags) ==
    1368             :                           csspp::decimal_number_to_string(n->get_font_size(), false)
    1369             :                         + n->get_dim1()
    1370             :                         + "/"
    1371             :                         + csspp::decimal_number_to_string(n->get_line_height(), false)
    1372             :                         + n->get_dim2());
    1373           4 :                 break;
    1374             : 
    1375           4 :             case csspp::node_type_t::FUNCTION:
    1376             :                 {
    1377             :                     // the defaults are empty...
    1378           4 :                     CATCH_REQUIRE(n->to_string(flags) == "()");
    1379             : 
    1380             :                     // test with an actual function
    1381           4 :                     n->set_string("rgba");
    1382           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1383           4 :                     n->add_child(p);
    1384           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1385           4 :                     n->add_child(p);
    1386           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1387           4 :                     n->add_child(p);
    1388           4 :                     p.reset(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, n->get_position()));
    1389           4 :                     p->set_decimal_number(1.0);
    1390           4 :                     n->add_child(p);
    1391           4 :                     CATCH_REQUIRE(n->to_string(flags) == "rgba(0,0,0,1)");
    1392           4 :                 }
    1393             :                 break;
    1394             : 
    1395           4 :             case csspp::node_type_t::GREATER_EQUAL:
    1396           4 :                 CATCH_REQUIRE(n->to_string(flags) == ">=");
    1397           4 :                 break;
    1398             : 
    1399           4 :             case csspp::node_type_t::GREATER_THAN:
    1400           4 :                 CATCH_REQUIRE(n->to_string(flags) == ">");
    1401           4 :                 break;
    1402             : 
    1403           4 :             case csspp::node_type_t::HASH:
    1404           4 :                 CATCH_REQUIRE(n->to_string(flags) == "#");
    1405           4 :                 n->set_string("random");
    1406           4 :                 CATCH_REQUIRE(n->to_string(flags) == "#random");
    1407           4 :                 break;
    1408             : 
    1409           4 :             case csspp::node_type_t::IDENTIFIER:
    1410           4 :                 CATCH_REQUIRE(n->to_string(flags) == "");
    1411           4 :                 n->set_string("an identifier in CSS can be absolutely anything!");
    1412           4 :                 CATCH_REQUIRE(n->to_string(flags) == "an identifier in CSS can be absolutely anything!");
    1413           4 :                 break;
    1414             : 
    1415           4 :             case csspp::node_type_t::INCLUDE_MATCH:
    1416           4 :                 CATCH_REQUIRE(n->to_string(flags) == "~=");
    1417           4 :                 break;
    1418             : 
    1419           4 :             case csspp::node_type_t::INTEGER:
    1420             :                 {
    1421           4 :                     CATCH_REQUIRE(n->to_string(flags) == "0");
    1422           4 :                     csspp::integer_t i(static_cast<csspp::integer_t>(rand()) + (static_cast<csspp::integer_t>(rand()) << 32));
    1423           4 :                     n->set_integer(i);
    1424           4 :                     CATCH_REQUIRE(n->to_string(flags) == std::to_string(i));
    1425           4 :                     n->set_string("px");
    1426           4 :                     CATCH_REQUIRE(n->to_string(flags) == std::to_string(i) + "px");
    1427             :                 }
    1428           4 :                 break;
    1429             : 
    1430           4 :             case csspp::node_type_t::LESS_EQUAL:
    1431           4 :                 CATCH_REQUIRE(n->to_string(flags) == "<=");
    1432           4 :                 break;
    1433             : 
    1434           4 :             case csspp::node_type_t::LESS_THAN:
    1435           4 :                 CATCH_REQUIRE(n->to_string(flags) == "<");
    1436           4 :                 break;
    1437             : 
    1438           4 :             case csspp::node_type_t::MODULO:
    1439           4 :                 if((flags & csspp::node::g_to_string_flag_add_spaces) != 0)
    1440             :                 {
    1441           2 :                     CATCH_REQUIRE(n->to_string(flags) == " % ");
    1442             :                 }
    1443             :                 else
    1444             :                 {
    1445           2 :                     CATCH_REQUIRE(n->to_string(flags) == "%");
    1446             :                 }
    1447           4 :                 break;
    1448             : 
    1449           4 :             case csspp::node_type_t::MULTIPLY:
    1450           4 :                 CATCH_REQUIRE(n->to_string(flags) == "*");
    1451           4 :                 break;
    1452             : 
    1453           4 :             case csspp::node_type_t::NOT_EQUAL:
    1454           4 :                 CATCH_REQUIRE(n->to_string(flags) == "!=");
    1455           4 :                 break;
    1456             : 
    1457           4 :             case csspp::node_type_t::NULL_TOKEN:
    1458           4 :                 CATCH_REQUIRE(n->to_string(flags) == "");
    1459           4 :                 break;
    1460             : 
    1461           4 :             case csspp::node_type_t::OPEN_CURLYBRACKET:
    1462             :                 {
    1463             :                     // the defaults are empty...
    1464           4 :                     CATCH_REQUIRE(n->to_string(flags) == "{}");
    1465             : 
    1466             :                     // test with an actual expression
    1467           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1468           4 :                     p->set_integer(7);
    1469           4 :                     n->add_child(p);
    1470           4 :                     p.reset(new csspp::node(csspp::node_type_t::MODULO, n->get_position()));
    1471           4 :                     n->add_child(p);
    1472           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1473           4 :                     p->set_integer(52);
    1474           4 :                     n->add_child(p);
    1475           4 :                     if((flags & csspp::node::g_to_string_flag_add_spaces) != 0)
    1476             :                     {
    1477           2 :                         CATCH_REQUIRE(n->to_string(flags) == "{7 % 52}");
    1478             :                     }
    1479             :                     else
    1480             :                     {
    1481           2 :                         CATCH_REQUIRE(n->to_string(flags) == "{7%52}");
    1482             :                     }
    1483           4 :                 }
    1484             :                 break;
    1485             : 
    1486           4 :             case csspp::node_type_t::OPEN_PARENTHESIS:
    1487             :                 {
    1488             :                     // the defaults are empty...
    1489           4 :                     CATCH_REQUIRE(n->to_string(flags) == "()");
    1490             : 
    1491             :                     // test with an actual function
    1492           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1493           4 :                     p->set_integer(17);
    1494           4 :                     n->add_child(p);
    1495           4 :                     p.reset(new csspp::node(csspp::node_type_t::MULTIPLY, n->get_position()));
    1496           4 :                     n->add_child(p);
    1497           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1498           4 :                     p->set_integer(502);
    1499           4 :                     n->add_child(p);
    1500           4 :                     CATCH_REQUIRE(n->to_string(flags) == "(17*502)");
    1501           4 :                 }
    1502             :                 break;
    1503             : 
    1504           4 :             case csspp::node_type_t::OPEN_SQUAREBRACKET:
    1505             :                 {
    1506             :                     // the defaults are empty...
    1507           4 :                     CATCH_REQUIRE(n->to_string(flags) == "[]");
    1508             : 
    1509             :                     // test with an actual function
    1510           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1511           4 :                     p->set_integer(5);
    1512           4 :                     n->add_child(p);
    1513           4 :                     p.reset(new csspp::node(csspp::node_type_t::DIVIDE, n->get_position()));
    1514           4 :                     n->add_child(p);
    1515           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1516           4 :                     p->set_integer(152);
    1517           4 :                     n->add_child(p);
    1518           4 :                     if((flags & csspp::node::g_to_string_flag_add_spaces) != 0)
    1519             :                     {
    1520           2 :                         CATCH_REQUIRE(n->to_string(flags) == "[5 / 152]");
    1521             :                     }
    1522             :                     else
    1523             :                     {
    1524           2 :                         CATCH_REQUIRE(n->to_string(flags) == "[5/152]");
    1525             :                     }
    1526           4 :                 }
    1527             :                 break;
    1528             : 
    1529           4 :             case csspp::node_type_t::PERCENT:
    1530           4 :                 CATCH_REQUIRE(n->to_string(flags) == "0%");
    1531           4 :                 n->set_decimal_number(1.25);
    1532           4 :                 CATCH_REQUIRE(n->to_string(flags) == "125%");
    1533           4 :                 break;
    1534             : 
    1535           4 :             case csspp::node_type_t::PERIOD:
    1536           4 :                 CATCH_REQUIRE(n->to_string(flags) == ".");
    1537           4 :                 break;
    1538             : 
    1539           4 :             case csspp::node_type_t::PLACEHOLDER:
    1540           4 :                 CATCH_REQUIRE(n->to_string(flags) == "%");
    1541           4 :                 n->set_string("the-name-of-the-placeholder");
    1542           4 :                 CATCH_REQUIRE(n->to_string(flags) == "%the-name-of-the-placeholder");
    1543           4 :                 break;
    1544             : 
    1545           4 :             case csspp::node_type_t::POWER:
    1546           4 :                 CATCH_REQUIRE(n->to_string(flags) == "**");
    1547           4 :                 break;
    1548             : 
    1549           4 :             case csspp::node_type_t::PRECEDED:
    1550           4 :                 CATCH_REQUIRE(n->to_string(flags) == "~");
    1551           4 :                 break;
    1552             : 
    1553           4 :             case csspp::node_type_t::PREFIX_MATCH:
    1554           4 :                 CATCH_REQUIRE(n->to_string(flags) == "^=");
    1555           4 :                 break;
    1556             : 
    1557           4 :             case csspp::node_type_t::REFERENCE:
    1558           4 :                 CATCH_REQUIRE(n->to_string(flags) == "&");
    1559           4 :                 break;
    1560             : 
    1561           4 :             case csspp::node_type_t::SCOPE:
    1562           4 :                 CATCH_REQUIRE(n->to_string(flags) == "|");
    1563           4 :                 break;
    1564             : 
    1565           4 :             case csspp::node_type_t::SEMICOLON:
    1566           4 :                 CATCH_REQUIRE(n->to_string(flags) == ";");
    1567           4 :                 break;
    1568             : 
    1569           4 :             case csspp::node_type_t::STRING:
    1570             :                 // with an empty string
    1571           4 :                 if((flags & csspp::node::g_to_string_flag_show_quotes) != 0)
    1572             :                 {
    1573           2 :                     CATCH_REQUIRE(n->to_string(flags) == "\"\"");
    1574             :                 }
    1575             :                 else
    1576             :                 {
    1577           2 :                     CATCH_REQUIRE(n->to_string(flags) == "");
    1578             :                 }
    1579             : 
    1580             :                 // with a ' in the string
    1581           4 :                 n->set_string("whatever string content we'd want really...");
    1582           4 :                 if((flags & csspp::node::g_to_string_flag_show_quotes) != 0)
    1583             :                 {
    1584           2 :                     CATCH_REQUIRE(n->to_string(flags) == "\"whatever string content we'd want really...\"");
    1585             :                 }
    1586             :                 else
    1587             :                 {
    1588           2 :                     CATCH_REQUIRE(n->to_string(flags) == "whatever string content we'd want really...");
    1589             :                 }
    1590             : 
    1591             :                 // with a " in the string
    1592           4 :                 n->set_string("yet if we have one quote like this: \" then the other is used to quote the string");
    1593           4 :                 if((flags & csspp::node::g_to_string_flag_show_quotes) != 0)
    1594             :                 {
    1595           2 :                     CATCH_REQUIRE(n->to_string(flags) == "'yet if we have one quote like this: \" then the other is used to quote the string'");
    1596             :                 }
    1597             :                 else
    1598             :                 {
    1599           2 :                     CATCH_REQUIRE(n->to_string(flags) == "yet if we have one quote like this: \" then the other is used to quote the string");
    1600             :                 }
    1601             : 
    1602             :                 // with both ' and ", more '
    1603           4 :                 n->set_string("counter: ''''' > \"\"\"");
    1604           4 :                 if((flags & csspp::node::g_to_string_flag_show_quotes) != 0)
    1605             :                 {
    1606           2 :                     CATCH_REQUIRE(n->to_string(flags) == "\"counter: ''''' > \\\"\\\"\\\"\"");
    1607             :                 }
    1608             :                 else
    1609             :                 {
    1610           2 :                     CATCH_REQUIRE(n->to_string(flags) == "counter: ''''' > \"\"\"");
    1611             :                 }
    1612             : 
    1613             :                 // with both ' and ", more "
    1614           4 :                 n->set_string("counter: ''' < \"\"\"\"\"");
    1615           4 :                 if((flags & csspp::node::g_to_string_flag_show_quotes) != 0)
    1616             :                 {
    1617           2 :                     CATCH_REQUIRE(n->to_string(flags) == "'counter: \\'\\'\\' < \"\"\"\"\"'");
    1618             :                 }
    1619             :                 else
    1620             :                 {
    1621           2 :                     CATCH_REQUIRE(n->to_string(flags) == "counter: ''' < \"\"\"\"\"");
    1622             :                 }
    1623           4 :                 break;
    1624             : 
    1625           4 :             case csspp::node_type_t::SUBSTRING_MATCH:
    1626           4 :                 CATCH_REQUIRE(n->to_string(flags) == "*=");
    1627           4 :                 break;
    1628             : 
    1629           4 :             case csspp::node_type_t::SUBTRACT:
    1630           4 :                 CATCH_REQUIRE(n->to_string(flags) == "-");
    1631           4 :                 break;
    1632             : 
    1633           4 :             case csspp::node_type_t::SUFFIX_MATCH:
    1634           4 :                 CATCH_REQUIRE(n->to_string(flags) == "$=");
    1635           4 :                 break;
    1636             : 
    1637           4 :             case csspp::node_type_t::UNICODE_RANGE:
    1638           4 :                 CATCH_REQUIRE(n->to_string(flags) == "U+0");
    1639           4 :                 n->set_integer(0x00004FFF00004000);
    1640           4 :                 CATCH_REQUIRE(n->to_string(flags) == "U+4???");
    1641           4 :                 break;
    1642             : 
    1643           4 :             case csspp::node_type_t::URL:
    1644           4 :                 CATCH_REQUIRE(n->to_string(flags) == "url()");
    1645           4 :                 n->set_string("http://this.should.be/a/valid/url");
    1646           4 :                 CATCH_REQUIRE(n->to_string(flags) == "url(http://this.should.be/a/valid/url)");
    1647           4 :                 break;
    1648             : 
    1649           4 :             case csspp::node_type_t::VARIABLE:
    1650           4 :                 CATCH_REQUIRE(n->to_string(flags) == "$");
    1651           4 :                 n->set_string("varname");
    1652           4 :                 CATCH_REQUIRE(n->to_string(flags) == "$varname");
    1653           4 :                 break;
    1654             : 
    1655           4 :             case csspp::node_type_t::VARIABLE_FUNCTION:
    1656             :                 {
    1657             :                     // the defaults are empty...
    1658           4 :                     CATCH_REQUIRE(n->to_string(flags) == "$()");
    1659             : 
    1660             :                     // test with an actual function
    1661           4 :                     n->set_string("my_function");
    1662           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1663           4 :                     n->add_child(p);
    1664           4 :                     p.reset(new csspp::node(csspp::node_type_t::STRING, n->get_position()));
    1665           4 :                     p->set_string("colorful");
    1666           4 :                     n->add_child(p);
    1667           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1668           4 :                     p->set_integer(33);
    1669           4 :                     n->add_child(p);
    1670           4 :                     p.reset(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, n->get_position()));
    1671           4 :                     p->set_decimal_number(1.0);
    1672           4 :                     n->add_child(p);
    1673           4 :                     if((flags & csspp::node::g_to_string_flag_show_quotes) != 0)
    1674             :                     {
    1675           2 :                         CATCH_REQUIRE(n->to_string(flags) == "$my_function(0,\"colorful\",33,1)");
    1676             :                     }
    1677             :                     else
    1678             :                     {
    1679           2 :                         CATCH_REQUIRE(n->to_string(flags) == "$my_function(0,colorful,33,1)");
    1680             :                     }
    1681           4 :                 }
    1682             :                 break;
    1683             : 
    1684           4 :             case csspp::node_type_t::WHITESPACE:
    1685           4 :                 CATCH_REQUIRE(n->to_string(flags) == " ");
    1686           4 :                 break;
    1687             : 
    1688             :             // second part
    1689           4 :             case csspp::node_type_t::AN_PLUS_B:
    1690           4 :                 CATCH_REQUIRE(n->to_string(flags) == "0");
    1691           4 :                 n->set_integer(0x0000000500000003);
    1692           4 :                 CATCH_REQUIRE(n->to_string(flags) == "3n+5");
    1693           4 :                 break;
    1694             : 
    1695           4 :             case csspp::node_type_t::ARG:
    1696             :                 {
    1697             :                     // the defaults are empty...
    1698           4 :                     CATCH_REQUIRE(n->to_string(flags) == "");
    1699           4 :                     CATCH_REQUIRE(n->get_integer() == 0);
    1700             : 
    1701             :                     // test with an actual function
    1702           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1703           4 :                     n->add_child(p);
    1704           4 :                     p.reset(new csspp::node(csspp::node_type_t::ADD, n->get_position()));
    1705           4 :                     n->add_child(p);
    1706           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1707           4 :                     p->set_integer(33);
    1708           4 :                     n->add_child(p);
    1709           4 :                     CATCH_REQUIRE(n->to_string(flags) == "0+33");
    1710           4 :                 }
    1711             :                 break;
    1712             : 
    1713           4 :             case csspp::node_type_t::ARRAY:
    1714             :                 {
    1715             :                     // the defaults are empty...
    1716           4 :                     CATCH_REQUIRE(n->to_string(flags) == "()");
    1717             : 
    1718             :                     // each item is comma separated
    1719           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::IDENTIFIER, n->get_position()));
    1720           4 :                     p->set_string("number");
    1721           4 :                     n->add_child(p);
    1722           4 :                     p.reset(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, n->get_position()));
    1723           4 :                     p->set_decimal_number(3.22);
    1724           4 :                     n->add_child(p);
    1725           4 :                     p.reset(new csspp::node(csspp::node_type_t::POWER, n->get_position()));
    1726           4 :                     n->add_child(p);
    1727           4 :                     p.reset(new csspp::node(csspp::node_type_t::STRING, n->get_position()));
    1728           4 :                     p->set_string("hello world!");
    1729           4 :                     n->add_child(p);
    1730             : 
    1731           4 :                     CATCH_REQUIRE(n->to_string(flags) == "(number, 3.22, **, \"hello world!\")");
    1732           4 :                 }
    1733             :                 break;
    1734             : 
    1735           4 :             case csspp::node_type_t::COMPONENT_VALUE:
    1736             :                 // test with the default (undefined) separator
    1737             :                 {
    1738             :                     // the defaults are empty...
    1739           4 :                     CATCH_REQUIRE(n->to_string(flags) == "");
    1740             : 
    1741             :                     // test with an actual function
    1742           4 :                     csspp::node::pointer_t a(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    1743           4 :                     n->add_child(a);
    1744           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1745           4 :                     a->add_child(p);
    1746             : 
    1747           4 :                     a.reset(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    1748           4 :                     n->add_child(a);
    1749           4 :                     p.reset(new csspp::node(csspp::node_type_t::STRING, n->get_position()));
    1750           4 :                     p->set_string("orange");
    1751           4 :                     a->add_child(p);
    1752             : 
    1753           4 :                     a.reset(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    1754           4 :                     n->add_child(a);
    1755           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1756           4 :                     p->set_integer(33);
    1757           4 :                     a->add_child(p);
    1758             : 
    1759           4 :                     if((flags & csspp::node::g_to_string_flag_show_quotes) != 0)
    1760             :                     {
    1761           2 :                         CATCH_REQUIRE(n->to_string(flags) == "0,\"orange\",33");
    1762             :                     }
    1763             :                     else
    1764             :                     {
    1765           2 :                         CATCH_REQUIRE(n->to_string(flags) == "0,orange,33");
    1766             :                     }
    1767             : 
    1768             :                     // test with an actual function but not argified
    1769           4 :                     n->clear();
    1770           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1771           4 :                     p->set_integer(111);
    1772           4 :                     n->add_child(p);
    1773           4 :                     p.reset(new csspp::node(csspp::node_type_t::COMMA, n->get_position()));
    1774           4 :                     n->add_child(p);
    1775           4 :                     p.reset(new csspp::node(csspp::node_type_t::STRING, n->get_position()));
    1776           4 :                     p->set_string("purple");
    1777           4 :                     n->add_child(p);
    1778           4 :                     p.reset(new csspp::node(csspp::node_type_t::COMMA, n->get_position()));
    1779           4 :                     n->add_child(p);
    1780           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1781           4 :                     p->set_integer(301);
    1782           4 :                     n->add_child(p);
    1783             : 
    1784           4 :                     if((flags & csspp::node::g_to_string_flag_show_quotes) != 0)
    1785             :                     {
    1786           2 :                         CATCH_REQUIRE(n->to_string(flags) == "111,\"purple\",301");
    1787             :                     }
    1788             :                     else
    1789             :                     {
    1790           2 :                         CATCH_REQUIRE(n->to_string(flags) == "111,purple,301");
    1791             :                     }
    1792           4 :                 }
    1793             : 
    1794             :                 // test again with "," as the ARG separator
    1795             :                 {
    1796           4 :                     n->clear();
    1797             : 
    1798             :                     // test with an actual function
    1799           4 :                     csspp::node::pointer_t a(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    1800           4 :                     a->set_integer(static_cast<int>(csspp::node_type_t::COMMA));
    1801           4 :                     n->add_child(a);
    1802           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1803           4 :                     a->add_child(p);
    1804             : 
    1805           4 :                     a.reset(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    1806           4 :                     a->set_integer(static_cast<int>(csspp::node_type_t::COMMA));
    1807           4 :                     n->add_child(a);
    1808           4 :                     p.reset(new csspp::node(csspp::node_type_t::STRING, n->get_position()));
    1809           4 :                     p->set_string("orange");
    1810           4 :                     a->add_child(p);
    1811             : 
    1812           4 :                     a.reset(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    1813           4 :                     a->set_integer(static_cast<int>(csspp::node_type_t::COMMA));
    1814           4 :                     n->add_child(a);
    1815           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1816           4 :                     p->set_integer(33);
    1817           4 :                     a->add_child(p);
    1818             : 
    1819           4 :                     if((flags & csspp::node::g_to_string_flag_show_quotes) != 0)
    1820             :                     {
    1821           2 :                         CATCH_REQUIRE(n->to_string(flags) == "0,\"orange\",33");
    1822             :                     }
    1823             :                     else
    1824             :                     {
    1825           2 :                         CATCH_REQUIRE(n->to_string(flags) == "0,orange,33");
    1826             :                     }
    1827             : 
    1828             :                     // test with an actual function but not argified
    1829           4 :                     n->clear();
    1830           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1831           4 :                     p->set_integer(111);
    1832           4 :                     n->add_child(p);
    1833           4 :                     p.reset(new csspp::node(csspp::node_type_t::COMMA, n->get_position()));
    1834           4 :                     n->add_child(p);
    1835           4 :                     p.reset(new csspp::node(csspp::node_type_t::STRING, n->get_position()));
    1836           4 :                     p->set_string("purple");
    1837           4 :                     n->add_child(p);
    1838           4 :                     p.reset(new csspp::node(csspp::node_type_t::COMMA, n->get_position()));
    1839           4 :                     n->add_child(p);
    1840           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1841           4 :                     p->set_integer(301);
    1842           4 :                     n->add_child(p);
    1843             : 
    1844           4 :                     if((flags & csspp::node::g_to_string_flag_show_quotes) != 0)
    1845             :                     {
    1846           2 :                         CATCH_REQUIRE(n->to_string(flags) == "111,\"purple\",301");
    1847             :                     }
    1848             :                     else
    1849             :                     {
    1850           2 :                         CATCH_REQUIRE(n->to_string(flags) == "111,purple,301");
    1851             :                     }
    1852           4 :                 }
    1853             : 
    1854             :                 // test again with "/" as the ARG separator
    1855             :                 {
    1856           4 :                     n->clear();
    1857             : 
    1858             :                     // test with an actual function
    1859           4 :                     csspp::node::pointer_t a(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    1860           4 :                     a->set_integer(static_cast<int>(csspp::node_type_t::DIVIDE));
    1861           4 :                     n->add_child(a);
    1862           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1863           4 :                     a->add_child(p);
    1864             : 
    1865           4 :                     a.reset(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    1866           4 :                     a->set_integer(static_cast<int>(csspp::node_type_t::DIVIDE));
    1867           4 :                     n->add_child(a);
    1868           4 :                     p.reset(new csspp::node(csspp::node_type_t::STRING, n->get_position()));
    1869           4 :                     p->set_string("orange");
    1870           4 :                     a->add_child(p);
    1871             : 
    1872           4 :                     a.reset(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    1873           4 :                     a->set_integer(static_cast<int>(csspp::node_type_t::DIVIDE));
    1874           4 :                     n->add_child(a);
    1875           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1876           4 :                     p->set_integer(33);
    1877           4 :                     a->add_child(p);
    1878             : 
    1879           4 :                     if((flags & csspp::node::g_to_string_flag_show_quotes) != 0)
    1880             :                     {
    1881           2 :                         CATCH_REQUIRE(n->to_string(flags) == "0/\"orange\"/33");
    1882             :                     }
    1883             :                     else
    1884             :                     {
    1885           2 :                         CATCH_REQUIRE(n->to_string(flags) == "0/orange/33");
    1886             :                     }
    1887             : 
    1888             :                     // test with an actual function but not argified
    1889           4 :                     n->clear();
    1890           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1891           4 :                     p->set_integer(111);
    1892           4 :                     n->add_child(p);
    1893           4 :                     p.reset(new csspp::node(csspp::node_type_t::DIVIDE, n->get_position()));
    1894           4 :                     n->add_child(p);
    1895           4 :                     p.reset(new csspp::node(csspp::node_type_t::STRING, n->get_position()));
    1896           4 :                     p->set_string("purple");
    1897           4 :                     n->add_child(p);
    1898           4 :                     p.reset(new csspp::node(csspp::node_type_t::DIVIDE, n->get_position()));
    1899           4 :                     n->add_child(p);
    1900           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1901           4 :                     p->set_integer(301);
    1902           4 :                     n->add_child(p);
    1903             : 
    1904           4 :                     if((flags & csspp::node::g_to_string_flag_show_quotes) != 0)
    1905             :                     {
    1906           2 :                         if((flags & csspp::node::g_to_string_flag_add_spaces) != 0)
    1907             :                         {
    1908           1 :                             CATCH_REQUIRE(n->to_string(flags) == "111 / \"purple\" / 301");
    1909             :                         }
    1910             :                         else
    1911             :                         {
    1912           1 :                             CATCH_REQUIRE(n->to_string(flags) == "111/\"purple\"/301");
    1913             :                         }
    1914             :                     }
    1915             :                     else
    1916             :                     {
    1917           2 :                         if((flags & csspp::node::g_to_string_flag_add_spaces) != 0)
    1918             :                         {
    1919           1 :                             CATCH_REQUIRE(n->to_string(flags) == "111 / purple / 301");
    1920             :                         }
    1921             :                         else
    1922             :                         {
    1923           1 :                             CATCH_REQUIRE(n->to_string(flags) == "111/purple/301");
    1924             :                         }
    1925             :                     }
    1926           4 :                 }
    1927             :                 break;
    1928             : 
    1929           4 :             case csspp::node_type_t::DECLARATION:
    1930             :                 {
    1931             :                     // the defaults are empty...
    1932           4 :                     CATCH_REQUIRE(n->to_string(flags) == "");
    1933           4 :                     n->set_string("name");
    1934           4 :                     CATCH_REQUIRE(n->to_string(flags) == "name: ");
    1935             : 
    1936             :                     // test with an actual function
    1937           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1938           4 :                     n->add_child(p);
    1939           4 :                     p.reset(new csspp::node(csspp::node_type_t::WHITESPACE, n->get_position()));
    1940           4 :                     n->add_child(p);
    1941           4 :                     p.reset(new csspp::node(csspp::node_type_t::SUBTRACT, n->get_position()));
    1942           4 :                     n->add_child(p);
    1943           4 :                     p.reset(new csspp::node(csspp::node_type_t::WHITESPACE, n->get_position()));
    1944           4 :                     n->add_child(p);
    1945           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1946           4 :                     p->set_integer(33);
    1947           4 :                     n->add_child(p);
    1948           4 :                     CATCH_REQUIRE(n->to_string(flags) == "name: 0 - 33");
    1949           4 :                 }
    1950             : 
    1951             :                 {
    1952           4 :                     n->clear();
    1953             : 
    1954             :                     // 1.45 + 15, 7 - 1.15
    1955           4 :                     csspp::node::pointer_t arg(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    1956           4 :                     n->add_child(arg);
    1957           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, n->get_position()));
    1958           4 :                     p->set_decimal_number(1.45);
    1959           4 :                     arg->add_child(p);
    1960           4 :                     p.reset(new csspp::node(csspp::node_type_t::ADD, n->get_position()));
    1961           4 :                     arg->add_child(p);
    1962           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1963           4 :                     p->set_integer(15);
    1964           4 :                     arg->add_child(p);
    1965             : 
    1966             :                     // there is no comma in the tree once compiled, just another ARG
    1967           4 :                     arg.reset(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    1968           4 :                     n->add_child(arg);
    1969           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    1970           4 :                     p->set_integer(7);
    1971           4 :                     arg->add_child(p);
    1972           4 :                     p.reset(new csspp::node(csspp::node_type_t::SUBTRACT, n->get_position()));
    1973           4 :                     arg->add_child(p);
    1974           4 :                     p.reset(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, n->get_position()));
    1975           4 :                     p->set_decimal_number(1.15);
    1976           4 :                     arg->add_child(p);
    1977             : 
    1978           4 :                     CATCH_REQUIRE(n->to_string(flags) == "name: 1.45+15,7-1.15");
    1979           4 :                 }
    1980             :                 break;
    1981             : 
    1982           4 :             case csspp::node_type_t::LIST:
    1983             :                 {
    1984             :                     // the defaults are empty...
    1985           4 :                     CATCH_REQUIRE(n->to_string(flags) == "");
    1986             : 
    1987             :                     // test with an actual expression
    1988           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, n->get_position()));
    1989           4 :                     p->set_decimal_number(3.22);
    1990           4 :                     n->add_child(p);
    1991           4 :                     p.reset(new csspp::node(csspp::node_type_t::WHITESPACE, n->get_position()));
    1992           4 :                     n->add_child(p);
    1993           4 :                     p.reset(new csspp::node(csspp::node_type_t::POWER, n->get_position()));
    1994           4 :                     n->add_child(p);
    1995           4 :                     p.reset(new csspp::node(csspp::node_type_t::WHITESPACE, n->get_position()));
    1996           4 :                     n->add_child(p);
    1997           4 :                     p.reset(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, n->get_position()));
    1998           4 :                     p->set_decimal_number(5.3);
    1999           4 :                     n->add_child(p);
    2000           4 :                     CATCH_REQUIRE(n->to_string(flags) == "3.22 ** 5.3");
    2001           4 :                 }
    2002             : 
    2003             :                 {
    2004           4 :                     n->clear();
    2005             : 
    2006             :                     // test with a couple of declarations to make sure we get
    2007             :                     // the semi-colon in between
    2008           4 :                     csspp::node::pointer_t declaration(new csspp::node(csspp::node_type_t::DECLARATION, n->get_position()));
    2009           4 :                     n->add_child(declaration);
    2010             : 
    2011             :                     // and a declaration may have multiple arguments
    2012           4 :                     csspp::node::pointer_t arg(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    2013           4 :                     declaration->add_child(arg);
    2014           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, n->get_position()));
    2015           4 :                     p->set_decimal_number(14.53);
    2016           4 :                     arg->add_child(p);
    2017           4 :                     p.reset(new csspp::node(csspp::node_type_t::ADD, n->get_position()));
    2018           4 :                     arg->add_child(p);
    2019           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    2020           4 :                     p->set_integer(150);
    2021           4 :                     arg->add_child(p);
    2022             : 
    2023             :                     // there is no comma in the tree once compiled, just another ARG
    2024           4 :                     arg.reset(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    2025           4 :                     declaration->add_child(arg);
    2026           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    2027           4 :                     p->set_integer(107);
    2028           4 :                     arg->add_child(p);
    2029           4 :                     p.reset(new csspp::node(csspp::node_type_t::SUBTRACT, n->get_position()));
    2030           4 :                     arg->add_child(p);
    2031           4 :                     p.reset(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, n->get_position()));
    2032           4 :                     p->set_decimal_number(115.23);
    2033           4 :                     arg->add_child(p);
    2034             : 
    2035             :                     // second declaration
    2036           4 :                     declaration.reset(new csspp::node(csspp::node_type_t::DECLARATION, n->get_position()));
    2037           4 :                     n->add_child(declaration);
    2038             : 
    2039             :                     // second argument of this declaration
    2040           4 :                     arg.reset(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    2041           4 :                     declaration->add_child(arg);
    2042           4 :                     p.reset(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, n->get_position()));
    2043           4 :                     p->set_decimal_number(1.453);
    2044           4 :                     arg->add_child(p);
    2045           4 :                     p.reset(new csspp::node(csspp::node_type_t::ADD, n->get_position()));
    2046           4 :                     arg->add_child(p);
    2047           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    2048           4 :                     p->set_integer(1);
    2049           4 :                     arg->add_child(p);
    2050             : 
    2051             :                     // there is no comma in the tree once compiled, just another ARG
    2052           4 :                     arg.reset(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    2053           4 :                     declaration->add_child(arg);
    2054           4 :                     p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    2055           4 :                     p->set_integer(19);
    2056           4 :                     arg->add_child(p);
    2057           4 :                     p.reset(new csspp::node(csspp::node_type_t::SUBTRACT, n->get_position()));
    2058           4 :                     arg->add_child(p);
    2059           4 :                     p.reset(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, n->get_position()));
    2060           4 :                     p->set_decimal_number(15.03);
    2061           4 :                     arg->add_child(p);
    2062             : 
    2063           4 :                     CATCH_REQUIRE(n->to_string(flags) == "14.53+150,107-115.23;1.453+1,19-15.03");
    2064           4 :                 }
    2065             :                 break;
    2066             : 
    2067           4 :             case csspp::node_type_t::MAP:
    2068             :                 {
    2069             :                     // the defaults are empty...
    2070           4 :                     CATCH_REQUIRE(n->to_string(flags) == "()");
    2071             : 
    2072             :                     // number: 3.22
    2073           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::IDENTIFIER, n->get_position()));
    2074           4 :                     p->set_string("number");
    2075           4 :                     n->add_child(p);
    2076           4 :                     p.reset(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, n->get_position()));
    2077           4 :                     p->set_decimal_number(3.22);
    2078           4 :                     n->add_child(p);
    2079             : 
    2080             :                     // string: "hello world!"
    2081           4 :                     p.reset(new csspp::node(csspp::node_type_t::IDENTIFIER, n->get_position()));
    2082           4 :                     p->set_string("string");
    2083           4 :                     n->add_child(p);
    2084           4 :                     p.reset(new csspp::node(csspp::node_type_t::STRING, n->get_position()));
    2085           4 :                     p->set_string("hello world!");
    2086           4 :                     n->add_child(p);
    2087             : 
    2088           4 :                     CATCH_REQUIRE(n->to_string(flags) == "(number: 3.22, string: \"hello world!\")");
    2089           4 :                 }
    2090             :                 break;
    2091             : 
    2092           4 :             case csspp::node_type_t::FRAME:
    2093             :                 {
    2094           4 :                     CATCH_REQUIRE(n->to_string(flags) == "from{}");
    2095           4 :                     n->set_decimal_number(0.25);
    2096           4 :                     CATCH_REQUIRE(n->to_string(flags) == "25%{}");
    2097           4 :                     n->set_decimal_number(1.0);
    2098           4 :                     CATCH_REQUIRE(n->to_string(flags) == "to{}");
    2099             : 
    2100             :                     // 68% { right: 322px }
    2101           4 :                     n->set_decimal_number(0.68);
    2102           4 :                     csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::DECLARATION, n->get_position()));
    2103           4 :                     p->set_string("right");
    2104           4 :                     n->add_child(p);
    2105           4 :                     csspp::node::pointer_t q(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    2106           4 :                     p->add_child(q);
    2107           4 :                     csspp::node::pointer_t r(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    2108           4 :                     r->set_string("px");
    2109           4 :                     r->set_integer(322);
    2110           4 :                     q->add_child(r);
    2111             : 
    2112           4 :                     CATCH_REQUIRE(n->to_string(flags) == "68%{right: 322px}");
    2113           4 :                 }
    2114             :                 break;
    2115             : 
    2116             :             // anything else is an error
    2117          32 :             default:
    2118             :                 // other node types generate a throw
    2119          32 :                 CATCH_REQUIRE_THROWS_AS(n->to_string(flags), csspp::csspp_exception_logic);
    2120             :                 break;
    2121             : 
    2122             :             }
    2123             : 
    2124             :             // move to the next type
    2125         272 :             w = static_cast<csspp::node_type_t>(static_cast<int>(w) + 1);
    2126         272 :         }
    2127             :     }
    2128             : 
    2129             :     // no error left over
    2130           1 :     VERIFY_ERRORS("");
    2131           1 : }
    2132             : 
    2133           1 : CATCH_TEST_CASE("Node to string ARG with wrong type", "[node] [output] [invalid]")
    2134             : {
    2135             :     // we expect the test suite to be compiled with the exact same version
    2136           5 :     for(int flags(0); flags < 4; ++flags)
    2137             :     {
    2138           4 :         for(csspp::node_type_t w(csspp::node_type_t::UNKNOWN);
    2139         276 :             w <= csspp::node_type_t::max_type;
    2140         272 :             w = static_cast<csspp::node_type_t>(static_cast<int>(w) + 1))
    2141             :         {
    2142         272 :             switch(w)
    2143             :             {
    2144          12 :             case csspp::node_type_t::UNKNOWN:
    2145             :             case csspp::node_type_t::COMMA:
    2146             :             case csspp::node_type_t::DIVIDE:
    2147          12 :                 continue;
    2148             : 
    2149         260 :             default:
    2150         260 :                 break;
    2151             : 
    2152             :             }
    2153        1040 :             csspp::position pos("test.css");
    2154         520 :             csspp::node::pointer_t n(new csspp::node(csspp::node_type_t::COMPONENT_VALUE, pos));
    2155             : 
    2156             :             // test with an actual function
    2157         520 :             csspp::node::pointer_t a(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    2158         260 :             a->set_integer(static_cast<csspp::integer_t>(w));
    2159         260 :             n->add_child(a);
    2160         520 :             csspp::node::pointer_t p(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    2161         260 :             a->add_child(p);
    2162             : 
    2163         260 :             a.reset(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    2164         260 :             a->set_integer(static_cast<csspp::integer_t>(w));
    2165         260 :             n->add_child(a);
    2166         260 :             p.reset(new csspp::node(csspp::node_type_t::STRING, n->get_position()));
    2167         260 :             p->set_string("orange");
    2168         260 :             a->add_child(p);
    2169             : 
    2170         260 :             a.reset(new csspp::node(csspp::node_type_t::ARG, n->get_position()));
    2171         260 :             a->set_integer(static_cast<csspp::integer_t>(w));
    2172         260 :             n->add_child(a);
    2173         260 :             p.reset(new csspp::node(csspp::node_type_t::INTEGER, n->get_position()));
    2174         260 :             p->set_integer(33);
    2175         260 :             a->add_child(p);
    2176             : 
    2177             :             // w is not valid as an ARG separator so it throws
    2178         260 :             CATCH_REQUIRE_THROWS_AS(n->to_string(flags), csspp::csspp_exception_logic);
    2179             :         }
    2180             :     }
    2181             : 
    2182             :     // no error left over
    2183           1 :     VERIFY_ERRORS("");
    2184           1 : }
    2185             : 
    2186           1 : CATCH_TEST_CASE("Error with node names", "[node] [type] [output]")
    2187             : {
    2188             :     // we expect the test suite to be compiled with the exact same version
    2189           1 :     csspp::node_type_t w(csspp::node_type_t::UNKNOWN);
    2190          69 :     while(w <= csspp::node_type_t::max_type)
    2191             :     {
    2192         204 :         csspp::position pos("test.css");
    2193          68 :         csspp::node::pointer_t n(new csspp::node(w, pos));
    2194             : 
    2195          68 :         csspp::error::instance() << pos
    2196             :                                  << "node name \""
    2197          68 :                                  << n->get_type()
    2198          68 :                                  << "\"."
    2199          68 :                                  << csspp::error_mode_t::ERROR_ERROR;
    2200             : 
    2201         136 :         std::string name("good");
    2202          68 :         switch(w)
    2203             :         {
    2204           1 :         case csspp::node_type_t::UNKNOWN:
    2205           1 :             VERIFY_ERRORS("test.css(1): error: node name \"UNKNOWN\".\n");
    2206           1 :             break;
    2207             : 
    2208           1 :         case csspp::node_type_t::ADD:
    2209           1 :             VERIFY_ERRORS("test.css(1): error: node name \"ADD\".\n");
    2210           1 :             break;
    2211             : 
    2212           1 :         case csspp::node_type_t::AND:
    2213           1 :             VERIFY_ERRORS("test.css(1): error: node name \"AND\".\n");
    2214           1 :             break;
    2215             : 
    2216           1 :         case csspp::node_type_t::ASSIGNMENT:
    2217           1 :             VERIFY_ERRORS("test.css(1): error: node name \"ASSIGNMENT\".\n");
    2218           1 :             break;
    2219             : 
    2220           1 :         case csspp::node_type_t::AT_KEYWORD:
    2221           1 :             VERIFY_ERRORS("test.css(1): error: node name \"AT_KEYWORD\".\n");
    2222           1 :             break;
    2223             : 
    2224           1 :         case csspp::node_type_t::BOOLEAN:
    2225           1 :             VERIFY_ERRORS("test.css(1): error: node name \"BOOLEAN\".\n");
    2226           1 :             break;
    2227             : 
    2228           1 :         case csspp::node_type_t::CDC:
    2229           1 :             VERIFY_ERRORS("test.css(1): error: node name \"CDC\".\n");
    2230           1 :             break;
    2231             : 
    2232           1 :         case csspp::node_type_t::CDO:
    2233           1 :             VERIFY_ERRORS("test.css(1): error: node name \"CDO\".\n");
    2234           1 :             break;
    2235             : 
    2236           1 :         case csspp::node_type_t::CLOSE_CURLYBRACKET:
    2237           1 :             VERIFY_ERRORS("test.css(1): error: node name \"CLOSE_CURLYBRACKET\".\n");
    2238           1 :             break;
    2239             : 
    2240           1 :         case csspp::node_type_t::CLOSE_PARENTHESIS:
    2241           1 :             VERIFY_ERRORS("test.css(1): error: node name \"CLOSE_PARENTHESIS\".\n");
    2242           1 :             break;
    2243             : 
    2244           1 :         case csspp::node_type_t::CLOSE_SQUAREBRACKET:
    2245           1 :             VERIFY_ERRORS("test.css(1): error: node name \"CLOSE_SQUAREBRACKET\".\n");
    2246           1 :             break;
    2247             : 
    2248           1 :         case csspp::node_type_t::COLON:
    2249           1 :             VERIFY_ERRORS("test.css(1): error: node name \"COLON\".\n");
    2250           1 :             break;
    2251             : 
    2252           1 :         case csspp::node_type_t::COLOR:
    2253           1 :             VERIFY_ERRORS("test.css(1): error: node name \"COLOR\".\n");
    2254           1 :             break;
    2255             : 
    2256           1 :         case csspp::node_type_t::COLUMN:
    2257           1 :             VERIFY_ERRORS("test.css(1): error: node name \"COLUMN\".\n");
    2258           1 :             break;
    2259             : 
    2260           1 :         case csspp::node_type_t::COMMA:
    2261           1 :             VERIFY_ERRORS("test.css(1): error: node name \"COMMA\".\n");
    2262           1 :             break;
    2263             : 
    2264           1 :         case csspp::node_type_t::COMMENT:
    2265           1 :             VERIFY_ERRORS("test.css(1): error: node name \"COMMENT\".\n");
    2266           1 :             break;
    2267             : 
    2268           1 :         case csspp::node_type_t::CONDITIONAL:
    2269           1 :             VERIFY_ERRORS("test.css(1): error: node name \"CONDITIONAL\".\n");
    2270           1 :             break;
    2271             : 
    2272           1 :         case csspp::node_type_t::DASH_MATCH:
    2273           1 :             VERIFY_ERRORS("test.css(1): error: node name \"DASH_MATCH\".\n");
    2274           1 :             break;
    2275             : 
    2276           1 :         case csspp::node_type_t::DECIMAL_NUMBER:
    2277           1 :             VERIFY_ERRORS("test.css(1): error: node name \"DECIMAL_NUMBER\".\n");
    2278           1 :             break;
    2279             : 
    2280           1 :         case csspp::node_type_t::DIVIDE:
    2281           1 :             VERIFY_ERRORS("test.css(1): error: node name \"DIVIDE\".\n");
    2282           1 :             break;
    2283             : 
    2284           1 :         case csspp::node_type_t::DOLLAR:
    2285           1 :             VERIFY_ERRORS("test.css(1): error: node name \"DOLLAR\".\n");
    2286           1 :             break;
    2287             : 
    2288           1 :         case csspp::node_type_t::EOF_TOKEN:
    2289           1 :             VERIFY_ERRORS("test.css(1): error: node name \"EOF_TOKEN\".\n");
    2290           1 :             break;
    2291             : 
    2292           1 :         case csspp::node_type_t::EQUAL:
    2293           1 :             VERIFY_ERRORS("test.css(1): error: node name \"EQUAL\".\n");
    2294           1 :             break;
    2295             : 
    2296           1 :         case csspp::node_type_t::EXCLAMATION:
    2297           1 :             VERIFY_ERRORS("test.css(1): error: node name \"EXCLAMATION\".\n");
    2298           1 :             break;
    2299             : 
    2300           1 :         case csspp::node_type_t::FONT_METRICS:
    2301           1 :             VERIFY_ERRORS("test.css(1): error: node name \"FONT_METRICS\".\n");
    2302           1 :             break;
    2303             : 
    2304           1 :         case csspp::node_type_t::FUNCTION:
    2305           1 :             VERIFY_ERRORS("test.css(1): error: node name \"FUNCTION\".\n");
    2306           1 :             break;
    2307             : 
    2308           1 :         case csspp::node_type_t::GREATER_EQUAL:
    2309           1 :             VERIFY_ERRORS("test.css(1): error: node name \"GREATER_EQUAL\".\n");
    2310           1 :             break;
    2311             : 
    2312           1 :         case csspp::node_type_t::GREATER_THAN:
    2313           1 :             VERIFY_ERRORS("test.css(1): error: node name \"GREATER_THAN\".\n");
    2314           1 :             break;
    2315             : 
    2316           1 :         case csspp::node_type_t::HASH:
    2317           1 :             VERIFY_ERRORS("test.css(1): error: node name \"HASH\".\n");
    2318           1 :             break;
    2319             : 
    2320           1 :         case csspp::node_type_t::IDENTIFIER:
    2321           1 :             VERIFY_ERRORS("test.css(1): error: node name \"IDENTIFIER\".\n");
    2322           1 :             break;
    2323             : 
    2324           1 :         case csspp::node_type_t::INCLUDE_MATCH:
    2325           1 :             VERIFY_ERRORS("test.css(1): error: node name \"INCLUDE_MATCH\".\n");
    2326           1 :             break;
    2327             : 
    2328           1 :         case csspp::node_type_t::INTEGER:
    2329           1 :             VERIFY_ERRORS("test.css(1): error: node name \"INTEGER\".\n");
    2330           1 :             break;
    2331             : 
    2332           1 :         case csspp::node_type_t::LESS_EQUAL:
    2333           1 :             VERIFY_ERRORS("test.css(1): error: node name \"LESS_EQUAL\".\n");
    2334           1 :             break;
    2335             : 
    2336           1 :         case csspp::node_type_t::LESS_THAN:
    2337           1 :             VERIFY_ERRORS("test.css(1): error: node name \"LESS_THAN\".\n");
    2338           1 :             break;
    2339             : 
    2340           1 :         case csspp::node_type_t::MODULO:
    2341           1 :             VERIFY_ERRORS("test.css(1): error: node name \"MODULO\".\n");
    2342           1 :             break;
    2343             : 
    2344           1 :         case csspp::node_type_t::MULTIPLY:
    2345           1 :             VERIFY_ERRORS("test.css(1): error: node name \"MULTIPLY\".\n");
    2346           1 :             break;
    2347             : 
    2348           1 :         case csspp::node_type_t::NOT_EQUAL:
    2349           1 :             VERIFY_ERRORS("test.css(1): error: node name \"NOT_EQUAL\".\n");
    2350           1 :             break;
    2351             : 
    2352           1 :         case csspp::node_type_t::NULL_TOKEN:
    2353           1 :             VERIFY_ERRORS("test.css(1): error: node name \"NULL_TOKEN\".\n");
    2354           1 :             break;
    2355             : 
    2356           1 :         case csspp::node_type_t::OPEN_CURLYBRACKET:
    2357           1 :             VERIFY_ERRORS("test.css(1): error: node name \"OPEN_CURLYBRACKET\".\n");
    2358           1 :             break;
    2359             : 
    2360           1 :         case csspp::node_type_t::OPEN_PARENTHESIS:
    2361           1 :             VERIFY_ERRORS("test.css(1): error: node name \"OPEN_PARENTHESIS\".\n");
    2362           1 :             break;
    2363             : 
    2364           1 :         case csspp::node_type_t::OPEN_SQUAREBRACKET:
    2365           1 :             VERIFY_ERRORS("test.css(1): error: node name \"OPEN_SQUAREBRACKET\".\n");
    2366           1 :             break;
    2367             : 
    2368           1 :         case csspp::node_type_t::PERCENT:
    2369           1 :             VERIFY_ERRORS("test.css(1): error: node name \"PERCENT\".\n");
    2370           1 :             break;
    2371             : 
    2372           1 :         case csspp::node_type_t::PERIOD:
    2373           1 :             VERIFY_ERRORS("test.css(1): error: node name \"PERIOD\".\n");
    2374           1 :             break;
    2375             : 
    2376           1 :         case csspp::node_type_t::PLACEHOLDER:
    2377           1 :             VERIFY_ERRORS("test.css(1): error: node name \"PLACEHOLDER\".\n");
    2378           1 :             break;
    2379             : 
    2380           1 :         case csspp::node_type_t::POWER:
    2381           1 :             VERIFY_ERRORS("test.css(1): error: node name \"POWER\".\n");
    2382           1 :             break;
    2383             : 
    2384           1 :         case csspp::node_type_t::PRECEDED:
    2385           1 :             VERIFY_ERRORS("test.css(1): error: node name \"PRECEDED\".\n");
    2386           1 :             break;
    2387             : 
    2388           1 :         case csspp::node_type_t::PREFIX_MATCH:
    2389           1 :             VERIFY_ERRORS("test.css(1): error: node name \"PREFIX_MATCH\".\n");
    2390           1 :             break;
    2391             : 
    2392           1 :         case csspp::node_type_t::REFERENCE:
    2393           1 :             VERIFY_ERRORS("test.css(1): error: node name \"REFERENCE\".\n");
    2394           1 :             break;
    2395             : 
    2396           1 :         case csspp::node_type_t::SCOPE:
    2397           1 :             VERIFY_ERRORS("test.css(1): error: node name \"SCOPE\".\n");
    2398           1 :             break;
    2399             : 
    2400           1 :         case csspp::node_type_t::SEMICOLON:
    2401           1 :             VERIFY_ERRORS("test.css(1): error: node name \"SEMICOLON\".\n");
    2402           1 :             break;
    2403             : 
    2404           1 :         case csspp::node_type_t::STRING:
    2405           1 :             VERIFY_ERRORS("test.css(1): error: node name \"STRING\".\n");
    2406           1 :             break;
    2407             : 
    2408           1 :         case csspp::node_type_t::SUBSTRING_MATCH:
    2409           1 :             VERIFY_ERRORS("test.css(1): error: node name \"SUBSTRING_MATCH\".\n");
    2410           1 :             break;
    2411             : 
    2412           1 :         case csspp::node_type_t::SUBTRACT:
    2413           1 :             VERIFY_ERRORS("test.css(1): error: node name \"SUBTRACT\".\n");
    2414           1 :             break;
    2415             : 
    2416           1 :         case csspp::node_type_t::SUFFIX_MATCH:
    2417           1 :             VERIFY_ERRORS("test.css(1): error: node name \"SUFFIX_MATCH\".\n");
    2418           1 :             break;
    2419             : 
    2420           1 :         case csspp::node_type_t::UNICODE_RANGE:
    2421           1 :             VERIFY_ERRORS("test.css(1): error: node name \"UNICODE_RANGE\".\n");
    2422           1 :             break;
    2423             : 
    2424           1 :         case csspp::node_type_t::URL:
    2425           1 :             VERIFY_ERRORS("test.css(1): error: node name \"URL\".\n");
    2426           1 :             break;
    2427             : 
    2428           1 :         case csspp::node_type_t::VARIABLE:
    2429           1 :             VERIFY_ERRORS("test.css(1): error: node name \"VARIABLE\".\n");
    2430           1 :             break;
    2431             : 
    2432           1 :         case csspp::node_type_t::VARIABLE_FUNCTION:
    2433           1 :             VERIFY_ERRORS("test.css(1): error: node name \"VARIABLE_FUNCTION\".\n");
    2434           1 :             break;
    2435             : 
    2436           1 :         case csspp::node_type_t::WHITESPACE:
    2437           1 :             VERIFY_ERRORS("test.css(1): error: node name \"WHITESPACE\".\n");
    2438           1 :             break;
    2439             : 
    2440             :         // second part
    2441           1 :         case csspp::node_type_t::AN_PLUS_B:
    2442           1 :             VERIFY_ERRORS("test.css(1): error: node name \"AN_PLUS_B\".\n");
    2443           1 :             break;
    2444             : 
    2445           1 :         case csspp::node_type_t::ARG:
    2446           1 :             VERIFY_ERRORS("test.css(1): error: node name \"ARG\".\n");
    2447           1 :             break;
    2448             : 
    2449           1 :         case csspp::node_type_t::ARRAY:
    2450           1 :             VERIFY_ERRORS("test.css(1): error: node name \"ARRAY\".\n");
    2451           1 :             break;
    2452             : 
    2453           1 :         case csspp::node_type_t::COMPONENT_VALUE:
    2454           1 :             VERIFY_ERRORS("test.css(1): error: node name \"COMPONENT_VALUE\".\n");
    2455           1 :             break;
    2456             : 
    2457           1 :         case csspp::node_type_t::DECLARATION:
    2458           1 :             VERIFY_ERRORS("test.css(1): error: node name \"DECLARATION\".\n");
    2459           1 :             break;
    2460             : 
    2461           1 :         case csspp::node_type_t::LIST:
    2462           1 :             VERIFY_ERRORS("test.css(1): error: node name \"LIST\".\n");
    2463           1 :             break;
    2464             : 
    2465           1 :         case csspp::node_type_t::MAP:
    2466           1 :             VERIFY_ERRORS("test.css(1): error: node name \"MAP\".\n");
    2467           1 :             break;
    2468             : 
    2469           1 :         case csspp::node_type_t::FRAME:
    2470           1 :             VERIFY_ERRORS("test.css(1): error: node name \"FRAME\".\n");
    2471           1 :             break;
    2472             : 
    2473           1 :         case csspp::node_type_t::max_type:
    2474           1 :             VERIFY_ERRORS("test.css(1): error: node name \"max_type\".\n");
    2475           1 :             break;
    2476             : 
    2477             :         }
    2478             : 
    2479             :         // move to the next type
    2480          68 :         w = static_cast<csspp::node_type_t>(static_cast<int>(w) + 1);
    2481          68 :     }
    2482             : 
    2483             :     // no error left over
    2484           1 :     VERIFY_ERRORS("");
    2485           1 : }
    2486             : 
    2487           1 : CATCH_TEST_CASE("Print nodes", "[node] [output]")
    2488             : {
    2489             :     // create a tree of nodes, then print it to exercise all the possible
    2490             :     // cases of the display() function
    2491           3 :     csspp::position pos("print.css");
    2492           1 :     csspp::node::pointer_t root(new csspp::node(csspp::node_type_t::LIST, pos));
    2493             : 
    2494           1 :         csspp::node::pointer_t integer(new csspp::node(csspp::node_type_t::INTEGER, pos));
    2495           1 :         integer->set_integer(123);
    2496           1 :         root->add_child(integer);
    2497             : 
    2498           1 :         csspp::node::pointer_t string(new csspp::node(csspp::node_type_t::STRING, pos));
    2499           1 :         string->set_string("bear");
    2500           1 :         root->add_child(string);
    2501             : 
    2502           1 :         csspp::node::pointer_t decimal_number(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, pos));
    2503           1 :         decimal_number->set_decimal_number(100.0);
    2504           1 :         root->add_child(decimal_number);
    2505             : 
    2506           1 :         csspp::node::pointer_t child(new csspp::node(csspp::node_type_t::AT_KEYWORD, pos));
    2507           1 :         child->set_string("@-char");
    2508           1 :         child->set_flag("important", true);
    2509           1 :         csspp::node::pointer_t var(new csspp::node(csspp::node_type_t::IDENTIFIER, pos));
    2510           1 :         var->set_string("colorous");
    2511           1 :         child->set_variable("test", var);
    2512           1 :         root->add_child(child);
    2513             : 
    2514           1 :             csspp::node::pointer_t boolean(new csspp::node(csspp::node_type_t::BOOLEAN, pos));
    2515           1 :             boolean->set_boolean(true);
    2516           1 :             child->add_child(boolean);
    2517             : 
    2518           1 :             csspp::node::pointer_t integer2(new csspp::node(csspp::node_type_t::INTEGER, pos));
    2519           1 :             integer2->set_integer(409);
    2520           1 :             child->add_child(integer2);
    2521             : 
    2522           1 :             csspp::node::pointer_t string2(new csspp::node(csspp::node_type_t::STRING, pos));
    2523           1 :             string2->set_string("rabbit");
    2524           1 :             child->add_child(string2);
    2525             : 
    2526           1 :             csspp::node::pointer_t bracket(new csspp::node(csspp::node_type_t::OPEN_CURLYBRACKET, pos));
    2527           1 :             bracket->set_boolean(true);
    2528           1 :             child->add_child(bracket);
    2529             : 
    2530           1 :                 csspp::node::pointer_t decimal_number2(new csspp::node(csspp::node_type_t::DECIMAL_NUMBER, pos));
    2531           1 :                 decimal_number2->set_decimal_number(208.0);
    2532           1 :                 bracket->add_child(decimal_number2);
    2533             : 
    2534           1 :                 csspp::node::pointer_t an_plus_b(new csspp::node(csspp::node_type_t::AN_PLUS_B, pos));
    2535           1 :                 an_plus_b->set_integer(0x0000000700000003);
    2536           1 :                 bracket->add_child(an_plus_b);
    2537             : 
    2538           1 :                 csspp::node::pointer_t color(new csspp::node(csspp::node_type_t::COLOR, pos));
    2539           1 :                 csspp::color c;
    2540           1 :                 c.set_color(0x11, 0x34, 0x78, 0xFF);
    2541           1 :                 color->set_color(c);
    2542           1 :                 bracket->add_child(color);
    2543             : 
    2544           1 :                 csspp::node::pointer_t font_metrics(new csspp::node(csspp::node_type_t::FONT_METRICS, pos));
    2545           1 :                 font_metrics->set_font_size(3.45);
    2546           1 :                 font_metrics->set_dim1("cm");
    2547           1 :                 font_metrics->set_line_height(1.5);
    2548           1 :                 font_metrics->set_dim2("%");
    2549           1 :                 bracket->add_child(font_metrics);
    2550             : 
    2551           1 :     std::stringstream ss;
    2552           1 :     ss << *root;
    2553             : 
    2554           1 :     VERIFY_TREES(ss.str(),
    2555             : 
    2556             : "LIST\n"
    2557             : "  INTEGER \"\" I:123\n"
    2558             : "  STRING \"bear\"\n"
    2559             : "  DECIMAL_NUMBER \"\" D:100\n"
    2560             : "  AT_KEYWORD \"@-char\" I:0 F:important\n"
    2561             : "      V:test\n"
    2562             : "        IDENTIFIER \"colorous\"\n"
    2563             : "    BOOLEAN B:true\n"
    2564             : "    INTEGER \"\" I:409\n"
    2565             : "    STRING \"rabbit\"\n"
    2566             : "    OPEN_CURLYBRACKET B:true\n"
    2567             : "      DECIMAL_NUMBER \"\" D:208\n"
    2568             : "      AN_PLUS_B S:3n+7\n"
    2569             : "      COLOR H:ff783411\n"
    2570             : "      FONT_METRICS FM:3.45cm/150%\n"
    2571             : 
    2572             :         );
    2573             : 
    2574             :     // also test a clone() and see that the clone is a 1:1 an equivalent
    2575           1 :     csspp::node::pointer_t p(root->clone());
    2576             : 
    2577           1 :     std::stringstream ss2;
    2578           1 :     ss2 << *p;
    2579             : 
    2580           1 :     VERIFY_TREES(ss2.str(),
    2581             : 
    2582             : "LIST\n"
    2583             : "  INTEGER \"\" I:123\n"
    2584             : "  STRING \"bear\"\n"
    2585             : "  DECIMAL_NUMBER \"\" D:100\n"
    2586             : "  AT_KEYWORD \"@-char\" I:0 F:important\n"
    2587             : "      V:test\n"
    2588             : "        IDENTIFIER \"colorous\"\n"
    2589             : "    BOOLEAN B:true\n"
    2590             : "    INTEGER \"\" I:409\n"
    2591             : "    STRING \"rabbit\"\n"
    2592             : "    OPEN_CURLYBRACKET B:true\n"
    2593             : "      DECIMAL_NUMBER \"\" D:208\n"
    2594             : "      AN_PLUS_B S:3n+7\n"
    2595             : "      COLOR H:ff783411\n"
    2596             : "      FONT_METRICS FM:3.45cm/150%\n"
    2597             : 
    2598             :         );
    2599             : 
    2600             :     // no error left over
    2601           1 :     VERIFY_ERRORS("");
    2602           2 : }
    2603             : 
    2604           1 : CATCH_TEST_CASE("Font metrics", "[node] [output]")
    2605             : {
    2606             :     // create a tree of nodes, then print it to exercise all the possible
    2607             :     // cases of the display() function
    2608           3 :     csspp::position pos("font-metrics.css");
    2609           1 :     csspp::node::pointer_t font_metrics(new csspp::node(csspp::node_type_t::FONT_METRICS, pos));
    2610             : 
    2611         101 :     for(int i(0); i < 100; ++i)
    2612             :     {
    2613         100 :         csspp::decimal_number_t const size(static_cast<csspp::decimal_number_t>(rand() % 1000) / 10.0);
    2614         100 :         font_metrics->set_font_size(size);
    2615         100 :         CATCH_REQUIRE((font_metrics->get_font_size() - size) < 0.0001);
    2616             : 
    2617         100 :         csspp::decimal_number_t const height(static_cast<csspp::decimal_number_t>(rand() % 1000) / 10.0);
    2618         100 :         font_metrics->set_line_height(height);
    2619         100 :         CATCH_REQUIRE((font_metrics->get_line_height() - height) < 0.0001);
    2620             : 
    2621             :         // line height has no effect on the font size
    2622         100 :         CATCH_REQUIRE((font_metrics->get_font_size() - size) < 0.0001);
    2623             : 
    2624             :         // to see that font size has no effect on line height...
    2625         100 :         csspp::decimal_number_t const size2(static_cast<csspp::decimal_number_t>(rand() % 1000) / 10.0);
    2626         100 :         font_metrics->set_font_size(size2);
    2627         100 :         CATCH_REQUIRE((font_metrics->get_font_size() - size2) < 0.0001);
    2628             : 
    2629         100 :         CATCH_REQUIRE((font_metrics->get_line_height() - height) < 0.0001);
    2630             :     }
    2631             : 
    2632             :     // no error left over
    2633           1 :     VERIFY_ERRORS("");
    2634           2 : }
    2635             : 
    2636             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14