LCOV - code coverage report
Current view: top level - tests - catch_node.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 257 257 100.0 %
Date: 2022-11-20 20:56:31 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2019-2022  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/basic-xml
       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 3 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
      17             : // along with this program.  If not, see <https://www.gnu.org/licenses/>.
      18             : 
      19             : // self
      20             : //
      21             : #include    "catch_main.h"
      22             : 
      23             : 
      24             : // basic-xml
      25             : //
      26             : #include    <basic-xml/exception.h>
      27             : #include    <basic-xml/node.h>
      28             : #include    <basic-xml/type.h>
      29             : 
      30             : 
      31             : 
      32           4 : CATCH_TEST_CASE("node", "[node][valid]")
      33             : {
      34           4 :     CATCH_START_SECTION("basic node")
      35             :     {
      36           2 :         basic_xml::node n("root");
      37           1 :         CATCH_REQUIRE(n.tag_name() == "root");
      38             : 
      39           1 :         CATCH_REQUIRE(n.text() == "");
      40           1 :         n.append_text("some text");
      41           1 :         CATCH_REQUIRE(n.text() == "some text");
      42           1 :         n.append_text(" more text");
      43           1 :         CATCH_REQUIRE(n.text() == "some text more text");
      44           1 :         n.set_text(" this new text   ");
      45           1 :         CATCH_REQUIRE(n.text() == "this new text");
      46           1 :         CATCH_REQUIRE(n.text(false) == " this new text   ");
      47           1 :         n.set_text(" this new text   \r\n");
      48           1 :         CATCH_REQUIRE(n.text() == "this new text");
      49           1 :         CATCH_REQUIRE(n.text(false) == " this new text   \r\n");
      50             : 
      51           1 :         CATCH_REQUIRE(n.all_attributes().empty());
      52           1 :         CATCH_REQUIRE(n.attribute("unknown").empty());
      53           1 :         n.set_attribute("test", "me");
      54           1 :         CATCH_REQUIRE(n.attribute("test") == "me");
      55           1 :         CATCH_REQUIRE(n.attribute("unknown").empty());
      56           1 :         CATCH_REQUIRE(n.all_attributes().size() == 1);
      57             : 
      58           1 :         CATCH_REQUIRE(n.parent() == nullptr);
      59           1 :         CATCH_REQUIRE(n.first_child() == nullptr);
      60           1 :         CATCH_REQUIRE(n.last_child() == nullptr);
      61           1 :         CATCH_REQUIRE(n.next() == nullptr);
      62           1 :         CATCH_REQUIRE(n.previous() == nullptr);
      63             :     }
      64             :     CATCH_END_SECTION()
      65             : 
      66           4 :     CATCH_START_SECTION("node tree")
      67             :     {
      68           2 :         basic_xml::node::pointer_t root(std::make_shared<basic_xml::node>("root"));
      69           1 :         CATCH_REQUIRE(root->tag_name() == "root");
      70             : 
      71             :         // level 1
      72             :         //
      73           2 :         basic_xml::node::pointer_t l1c1(std::make_shared<basic_xml::node>("l1c1"));
      74           1 :         CATCH_REQUIRE(l1c1->tag_name() == "l1c1");
      75             : 
      76           2 :         basic_xml::node::pointer_t l1c2(std::make_shared<basic_xml::node>("l1c2"));
      77           1 :         CATCH_REQUIRE(l1c2->tag_name() == "l1c2");
      78             : 
      79           2 :         basic_xml::node::pointer_t l1c3(std::make_shared<basic_xml::node>("l1c3"));
      80           1 :         CATCH_REQUIRE(l1c3->tag_name() == "l1c3");
      81             : 
      82             :         // append l1c1
      83             :         //
      84           1 :         root->append_child(l1c1);
      85           1 :         CATCH_REQUIRE(l1c1->parent() == root);
      86           1 :         CATCH_REQUIRE(l1c1->first_child() == nullptr);
      87           1 :         CATCH_REQUIRE(l1c1->last_child() == nullptr);
      88           1 :         CATCH_REQUIRE(l1c1->next() == nullptr);
      89           1 :         CATCH_REQUIRE(l1c1->previous() == nullptr);
      90             : 
      91           1 :         CATCH_REQUIRE(root->parent() == nullptr);
      92           1 :         CATCH_REQUIRE(root->first_child() == l1c1);
      93           1 :         CATCH_REQUIRE(root->last_child() == l1c1);
      94           1 :         CATCH_REQUIRE(root->next() == nullptr);
      95           1 :         CATCH_REQUIRE(root->previous() == nullptr);
      96             : 
      97             :         // append l1c2
      98             :         //
      99           1 :         root->append_child(l1c2);
     100           1 :         CATCH_REQUIRE(l1c2->parent() == root);
     101           1 :         CATCH_REQUIRE(l1c2->first_child() == nullptr);
     102           1 :         CATCH_REQUIRE(l1c2->last_child() == nullptr);
     103           1 :         CATCH_REQUIRE(l1c2->next() == nullptr);
     104           1 :         CATCH_REQUIRE(l1c2->previous() == l1c1);
     105             : 
     106           1 :         CATCH_REQUIRE(l1c1->next() == l1c2);
     107           1 :         CATCH_REQUIRE(l1c1->previous() == nullptr);
     108             : 
     109           1 :         CATCH_REQUIRE(root->parent() == nullptr);
     110           1 :         CATCH_REQUIRE(root->first_child() == l1c1);
     111           1 :         CATCH_REQUIRE(root->last_child() == l1c2);
     112           1 :         CATCH_REQUIRE(root->next() == nullptr);
     113           1 :         CATCH_REQUIRE(root->previous() == nullptr);
     114             : 
     115             :         // append l1c3
     116             :         //
     117           1 :         root->append_child(l1c3);
     118           1 :         CATCH_REQUIRE(l1c3->parent() == root);
     119           1 :         CATCH_REQUIRE(l1c3->first_child() == nullptr);
     120           1 :         CATCH_REQUIRE(l1c3->last_child() == nullptr);
     121           1 :         CATCH_REQUIRE(l1c3->next() == nullptr);
     122           1 :         CATCH_REQUIRE(l1c3->previous() == l1c2);
     123             : 
     124           1 :         CATCH_REQUIRE(l1c1->next() == l1c2);
     125           1 :         CATCH_REQUIRE(l1c1->previous() == nullptr);
     126             : 
     127           1 :         CATCH_REQUIRE(l1c2->next() == l1c3);
     128           1 :         CATCH_REQUIRE(l1c2->previous() == l1c1);
     129             : 
     130           1 :         CATCH_REQUIRE(root->parent() == nullptr);
     131           1 :         CATCH_REQUIRE(root->first_child() == l1c1);
     132           1 :         CATCH_REQUIRE(root->last_child() == l1c3);
     133           1 :         CATCH_REQUIRE(root->next() == nullptr);
     134           1 :         CATCH_REQUIRE(root->previous() == nullptr);
     135             : 
     136             :         // level 2
     137             :         //
     138           2 :         basic_xml::node::pointer_t l2c1(std::make_shared<basic_xml::node>("l2c1"));
     139           1 :         CATCH_REQUIRE(l2c1->tag_name() == "l2c1");
     140             : 
     141           2 :         basic_xml::node::pointer_t l2c2(std::make_shared<basic_xml::node>("l2c2"));
     142           1 :         CATCH_REQUIRE(l2c2->tag_name() == "l2c2");
     143             : 
     144           2 :         basic_xml::node::pointer_t l2c3(std::make_shared<basic_xml::node>("l2c3"));
     145           1 :         CATCH_REQUIRE(l2c3->tag_name() == "l2c3");
     146             : 
     147             :         // append l2c1
     148             :         //
     149           1 :         l1c2->append_child(l2c1);
     150           1 :         CATCH_REQUIRE(l2c1->parent() == l1c2);
     151           1 :         CATCH_REQUIRE(l2c1->parent()->parent() == root);
     152           1 :         CATCH_REQUIRE(l2c1->first_child() == nullptr);
     153           1 :         CATCH_REQUIRE(l2c1->last_child() == nullptr);
     154           1 :         CATCH_REQUIRE(l2c1->next() == nullptr);
     155           1 :         CATCH_REQUIRE(l2c1->previous() == nullptr);
     156             : 
     157           1 :         CATCH_REQUIRE(root->parent() == nullptr);
     158           1 :         CATCH_REQUIRE(root->first_child() == l1c1);
     159           1 :         CATCH_REQUIRE(root->last_child() == l1c3);
     160           1 :         CATCH_REQUIRE(root->next() == nullptr);
     161           1 :         CATCH_REQUIRE(root->previous() == nullptr);
     162             : 
     163             :         // append l2c2
     164             :         //
     165           1 :         l1c2->append_child(l2c2);
     166           1 :         CATCH_REQUIRE(l2c2->parent() == l1c2);
     167           1 :         CATCH_REQUIRE(l2c2->parent()->parent() == root);
     168           1 :         CATCH_REQUIRE(l2c2->first_child() == nullptr);
     169           1 :         CATCH_REQUIRE(l2c2->last_child() == nullptr);
     170           1 :         CATCH_REQUIRE(l2c2->next() == nullptr);
     171           1 :         CATCH_REQUIRE(l2c2->previous() == l2c1);
     172             : 
     173           1 :         CATCH_REQUIRE(l2c1->next() == l2c2);
     174           1 :         CATCH_REQUIRE(l2c1->previous() == nullptr);
     175             : 
     176           1 :         CATCH_REQUIRE(root->parent() == nullptr);
     177           1 :         CATCH_REQUIRE(root->first_child() == l1c1);
     178           1 :         CATCH_REQUIRE(root->last_child() == l1c3);
     179           1 :         CATCH_REQUIRE(root->next() == nullptr);
     180           1 :         CATCH_REQUIRE(root->previous() == nullptr);
     181             : 
     182             :         // append l2c3
     183             :         //
     184           1 :         l1c2->append_child(l2c3);
     185           1 :         CATCH_REQUIRE(l2c3->parent() == l1c2);
     186           1 :         CATCH_REQUIRE(l2c3->parent()->parent() == root);
     187           1 :         CATCH_REQUIRE(l2c3->first_child() == nullptr);
     188           1 :         CATCH_REQUIRE(l2c3->last_child() == nullptr);
     189           1 :         CATCH_REQUIRE(l2c3->next() == nullptr);
     190           1 :         CATCH_REQUIRE(l2c3->previous() == l2c2);
     191             : 
     192           1 :         CATCH_REQUIRE(l2c1->next() == l2c2);
     193           1 :         CATCH_REQUIRE(l2c1->previous() == nullptr);
     194             : 
     195           1 :         CATCH_REQUIRE(l2c2->next() == l2c3);
     196           1 :         CATCH_REQUIRE(l2c2->previous() == l2c1);
     197             : 
     198           1 :         CATCH_REQUIRE(root->parent() == nullptr);
     199           1 :         CATCH_REQUIRE(root->first_child() == l1c1);
     200           1 :         CATCH_REQUIRE(root->last_child() == l1c3);
     201           1 :         CATCH_REQUIRE(root->next() == nullptr);
     202           1 :         CATCH_REQUIRE(root->previous() == nullptr);
     203             :     }
     204             :     CATCH_END_SECTION()
     205           2 : }
     206             : 
     207             : 
     208             : 
     209           5 : CATCH_TEST_CASE("node_output", "[node][valid]")
     210             : {
     211           6 :     CATCH_START_SECTION("convert string with entities")
     212             :     {
     213           1 :         CATCH_REQUIRE(basic_xml::convert_to_entity("nothing to convert", "<>&") == "nothing to convert");
     214             : 
     215           1 :         CATCH_REQUIRE(basic_xml::convert_to_entity("try < and > and & and \" and ' all should change", "<>&\"'") == "try &lt; and &gt; and &amp; and &quot; and &apos; all should change");
     216             : 
     217           1 :         CATCH_REQUIRE(basic_xml::convert_to_entity("try < and > and & but keep \" and '", "<>&") == "try &lt; and &gt; and &amp; but keep \" and '");
     218             :     }
     219             :     CATCH_END_SECTION()
     220             : 
     221           6 :     CATCH_START_SECTION("node output")
     222             :     {
     223           2 :         basic_xml::node n("root");
     224           1 :         CATCH_REQUIRE(n.tag_name() == "root");
     225             : 
     226           1 :         n.append_text("with text");
     227           1 :         n.set_attribute("simple-attribute", "with some value");
     228             : 
     229           2 :         std::stringstream ss;
     230           1 :         ss << n;
     231           1 :         CATCH_REQUIRE(ss.str() == "<root simple-attribute=\"with some value\">with text</root>");
     232             :     }
     233             :     CATCH_END_SECTION()
     234             : 
     235           6 :     CATCH_START_SECTION("node tree output")
     236             :     {
     237           2 :         basic_xml::node::pointer_t root(std::make_shared<basic_xml::node>("root"));
     238           1 :         root->set_attribute("even-root", "can have an \"attribute\"");
     239           2 :         basic_xml::node::pointer_t l1c1(std::make_shared<basic_xml::node>("l1c1"));
     240           2 :         basic_xml::node::pointer_t l1c2(std::make_shared<basic_xml::node>("l1c2"));
     241           1 :         l1c2->append_text("wierd text + sub-tags");
     242           2 :         basic_xml::node::pointer_t l1c3(std::make_shared<basic_xml::node>("l1c3"));
     243           1 :         l1c3->append_text("<\"it's not empty & it works\">");
     244           1 :         root->append_child(l1c1);
     245           1 :         root->append_child(l1c2);
     246           1 :         root->append_child(l1c3);
     247           2 :         basic_xml::node::pointer_t l2c1(std::make_shared<basic_xml::node>("l2c1"));
     248           1 :         l2c1->set_attribute("color", "l'escargot");
     249           1 :         l2c1->append_text("sub-node has data");
     250           2 :         basic_xml::node::pointer_t l2c2(std::make_shared<basic_xml::node>("l2c2"));
     251           2 :         basic_xml::node::pointer_t l2c3(std::make_shared<basic_xml::node>("l2c3"));
     252           1 :         l2c3->set_attribute("i33", "\"it's both this time\"");
     253           1 :         l2c3->append_text("last-node has data too");
     254           1 :         l1c2->append_child(l2c1);
     255           1 :         l1c2->append_child(l2c2);
     256           1 :         l1c2->append_child(l2c3);
     257             : 
     258           2 :         std::stringstream ss;
     259           1 :         ss << *root;
     260           1 :         CATCH_REQUIRE(ss.str() == "<root even-root='can have an \"attribute\"'>"
     261             :                     "<l1c1/><l1c2><l2c1 color=\"l'escargot\">sub-node has data</l2c1>"
     262             :                     "<l2c2/><l2c3 i33=\"&quot;it's both this time&quot;\">"
     263             :                     "last-node has data too</l2c3>wierd text + sub-tags</l1c2>"
     264             :                     "<l1c3>&lt;\"it's not empty &amp; it works\"&gt;</l1c3></root>");
     265             :     }
     266             :     CATCH_END_SECTION()
     267           3 : }
     268             : 
     269             : 
     270             : 
     271           6 : CATCH_TEST_CASE("node_errors", "[node][invalid]")
     272             : {
     273           8 :     CATCH_START_SECTION("bad tag name: empty")
     274             :     {
     275           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     276             :                   basic_xml::node(std::string())
     277             :                 , basic_xml::invalid_token
     278             :                 , Catch::Matchers::ExceptionMessage(
     279             :                           "xml_error: \"\" is not a valid token for a tag name."));
     280             :     }
     281             :     CATCH_END_SECTION()
     282             : 
     283           8 :     CATCH_START_SECTION("bad tag name: invalid character in name")
     284             :     {
     285          11 :         for(int count(0); count < 10; ++count)
     286             :         {
     287          20 :             std::string tag_name;
     288          10 :             int max(rand() % 10 + 10);
     289         160 :             for(int len(0); len < max; ++len)
     290             :             {
     291         150 :                 switch(rand() % (tag_name.empty() ? 3 : 5))
     292             :                 {
     293          40 :                 case 0:
     294          40 :                     tag_name += static_cast<char>(rand() % 26 + 'a');
     295          40 :                     break;
     296             : 
     297          29 :                 case 1:
     298          29 :                     tag_name += static_cast<char>(rand() % 26 + 'A');
     299          29 :                     break;
     300             : 
     301          28 :                 case 2:
     302          28 :                     tag_name += '_';
     303          28 :                     break;
     304             : 
     305          27 :                 case 3:
     306          27 :                     tag_name += static_cast<char>(rand() % 10 + '0');
     307          27 :                     break;
     308             : 
     309          26 :                 case 4:
     310          26 :                     tag_name += '-';
     311          26 :                     break;
     312             : 
     313             :                 }
     314             :             }
     315             : 
     316             :             // invalid if it does not start with an alpha character
     317             :             //
     318          10 :             char start(rand() % 255 + 1);
     319          16 :             while(basic_xml::is_alpha(start))
     320             :             {
     321           3 :                 start = rand() % 255 + 1;
     322             :             }
     323          10 :             CATCH_REQUIRE_THROWS_MATCHES(
     324             :                       basic_xml::node(start + tag_name)
     325             :                     , basic_xml::invalid_token
     326             :                     , Catch::Matchers::ExceptionMessage(
     327             :                               "xml_error: \""
     328             :                             + (start + tag_name)
     329             :                             + "\" is not a valid token for a tag name."));
     330             : 
     331             :             // invalid if it ends with '-'
     332             :             //
     333          10 :             CATCH_REQUIRE_THROWS_MATCHES(
     334             :                       basic_xml::node(tag_name + '-')
     335             :                     , basic_xml::invalid_token
     336             :                     , Catch::Matchers::ExceptionMessage(
     337             :                               "xml_error: \""
     338             :                             + tag_name
     339             :                             + "-\" is not a valid token for a tag name."));
     340             : 
     341             :             // invalid if invalid char anywhere within
     342             :             //
     343         170 :             for(size_t pos(0); pos <= tag_name.length(); ++pos)
     344             :             {
     345         160 :                 char mid(rand() % 255 + 1);
     346         266 :                 while(basic_xml::is_alpha(mid) || basic_xml::is_digit(mid))
     347             :                 {
     348          53 :                     mid = rand() % 255 + 1;
     349             :                 }
     350         160 :                 std::string bad_name(
     351         320 :                           tag_name.substr(0, pos)
     352         480 :                         + mid
     353         640 :                         + tag_name.substr(pos));
     354         160 :                 CATCH_REQUIRE_THROWS_MATCHES(
     355             :                           basic_xml::node(bad_name)
     356             :                         , basic_xml::invalid_token
     357             :                         , Catch::Matchers::ExceptionMessage(
     358             :                                   "xml_error: \""
     359             :                                 + bad_name
     360             :                                 + "\" is not a valid token for a tag name."));
     361             :             }
     362             :         }
     363             :     }
     364             :     CATCH_END_SECTION()
     365             : 
     366           8 :     CATCH_START_SECTION("bad attribute name: invalid character in name")
     367             :     {
     368           2 :         basic_xml::node n("tag");
     369             : 
     370          11 :         for(int count(0); count < 10; ++count)
     371             :         {
     372          20 :             std::string attribute_name;
     373          10 :             int max(rand() % 10 + 10);
     374         146 :             for(int len(0); len < max; ++len)
     375             :             {
     376         136 :                 switch(rand() % (attribute_name.empty() ? 3 : 5))
     377             :                 {
     378          25 :                 case 0:
     379          25 :                     attribute_name += static_cast<char>(rand() % 26 + 'a');
     380          25 :                     break;
     381             : 
     382          37 :                 case 1:
     383          37 :                     attribute_name += static_cast<char>(rand() % 26 + 'A');
     384          37 :                     break;
     385             : 
     386          25 :                 case 2:
     387          25 :                     attribute_name += '_';
     388          25 :                     break;
     389             : 
     390          27 :                 case 3:
     391          27 :                     attribute_name += static_cast<char>(rand() % 10 + '0');
     392          27 :                     break;
     393             : 
     394          22 :                 case 4:
     395          22 :                     attribute_name += '-';
     396          22 :                     break;
     397             : 
     398             :                 }
     399             :             }
     400             : 
     401             :             // invalid if it does not start with an alpha character
     402             :             //
     403          10 :             char start(rand() % 255 + 1);
     404          14 :             while(basic_xml::is_alpha(start))
     405             :             {
     406           2 :                 start = rand() % 255 + 1;
     407             :             }
     408          10 :             CATCH_REQUIRE_THROWS_MATCHES(
     409             :                       n.set_attribute(start + attribute_name, "value")
     410             :                     , basic_xml::invalid_token
     411             :                     , Catch::Matchers::ExceptionMessage(
     412             :                               "xml_error: \""
     413             :                             + (start + attribute_name)
     414             :                             + "\" is not a valid token for an attribute name."));
     415             : 
     416             :             // invalid if it ends with '-'
     417             :             //
     418          10 :             CATCH_REQUIRE_THROWS_MATCHES(
     419             :                       n.set_attribute(attribute_name + '-', "value")
     420             :                     , basic_xml::invalid_token
     421             :                     , Catch::Matchers::ExceptionMessage(
     422             :                               "xml_error: \""
     423             :                             + attribute_name
     424             :                             + "-\" is not a valid token for an attribute name."));
     425             : 
     426             :             // invalid if invalid char anywhere within
     427             :             //
     428         156 :             for(size_t pos(0); pos <= attribute_name.length(); ++pos)
     429             :             {
     430         146 :                 char mid(rand() % 255 + 1);
     431         248 :                 while(basic_xml::is_alpha(mid) || basic_xml::is_digit(mid))
     432             :                 {
     433          51 :                     mid = rand() % 255 + 1;
     434             :                 }
     435         146 :                 std::string bad_name(
     436         292 :                           attribute_name.substr(0, pos)
     437         438 :                         + mid
     438         584 :                         + attribute_name.substr(pos));
     439         146 :                 CATCH_REQUIRE_THROWS_MATCHES(
     440             :                           n.set_attribute(bad_name, "value")
     441             :                         , basic_xml::invalid_token
     442             :                         , Catch::Matchers::ExceptionMessage(
     443             :                                   "xml_error: \""
     444             :                                 + bad_name
     445             :                                 + "\" is not a valid token for an attribute name."));
     446             :             }
     447             :         }
     448             :     }
     449             :     CATCH_END_SECTION()
     450             : 
     451           8 :     CATCH_START_SECTION("re-append a child fails")
     452             :     {
     453           2 :         basic_xml::node::pointer_t root(std::make_shared<basic_xml::node>("top"));
     454             : 
     455           2 :         basic_xml::node::pointer_t l1c1(std::make_shared<basic_xml::node>("l1c1"));
     456           2 :         basic_xml::node::pointer_t l1c2(std::make_shared<basic_xml::node>("l1c2"));
     457           2 :         basic_xml::node::pointer_t l1c3(std::make_shared<basic_xml::node>("l1c3"));
     458             : 
     459           1 :         root->append_child(l1c1);
     460           1 :         root->append_child(l1c2);
     461           1 :         root->append_child(l1c3);
     462             : 
     463           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     464             :                   l1c1->append_child(l1c2)
     465             :                 , basic_xml::node_already_in_tree
     466             :                 , Catch::Matchers::ExceptionMessage(
     467             :                           "xml_error: Somehow you are trying to add a child node of a node that was already added to a tree of nodes."));
     468             : 
     469           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     470             :                   l1c2->append_child(l1c1)
     471             :                 , basic_xml::node_already_in_tree
     472             :                 , Catch::Matchers::ExceptionMessage(
     473             :                           "xml_error: Somehow you are trying to add a child node of a node that was already added to a tree of nodes."));
     474             : 
     475           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     476             :                   l1c1->append_child(l1c3)
     477             :                 , basic_xml::node_already_in_tree
     478             :                 , Catch::Matchers::ExceptionMessage(
     479             :                           "xml_error: Somehow you are trying to add a child node of a node that was already added to a tree of nodes."));
     480             : 
     481           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     482             :                   l1c1->append_child(root)
     483             :                 , basic_xml::node_is_root
     484             :                 , Catch::Matchers::ExceptionMessage(
     485             :                           "xml_error: Trying to append the root node within the sub-tree."));
     486             : 
     487           2 :         basic_xml::node::pointer_t l2c1(std::make_shared<basic_xml::node>("l2c1"));
     488           2 :         basic_xml::node::pointer_t l2c2(std::make_shared<basic_xml::node>("l2c2"));
     489           2 :         basic_xml::node::pointer_t l2c3(std::make_shared<basic_xml::node>("l2c3"));
     490             : 
     491           1 :         l1c3->append_child(l2c1);
     492           1 :         l1c3->append_child(l2c2);
     493           1 :         l1c3->append_child(l2c3);
     494             : 
     495           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     496             :                   l2c1->append_child(root)
     497             :                 , basic_xml::node_is_root
     498             :                 , Catch::Matchers::ExceptionMessage(
     499             :                           "xml_error: Trying to append the root node within the sub-tree."));
     500             : 
     501           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     502             :                   l2c2->append_child(root)
     503             :                 , basic_xml::node_is_root
     504             :                 , Catch::Matchers::ExceptionMessage(
     505             :                           "xml_error: Trying to append the root node within the sub-tree."));
     506             : 
     507           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     508             :                   l2c3->append_child(root)
     509             :                 , basic_xml::node_is_root
     510             :                 , Catch::Matchers::ExceptionMessage(
     511             :                           "xml_error: Trying to append the root node within the sub-tree."));
     512             :     }
     513             :     CATCH_END_SECTION()
     514          10 : }
     515             : 
     516             : 
     517             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13