LCOV - code coverage report
Current view: top level - tests - catch_part.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 356 360 98.9 %
Date: 2023-01-24 22:36:19 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2023  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/versiontheca
       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             : // tested file
      20             : //
      21             : #include    "versiontheca/part.h"
      22             : 
      23             : 
      24             : // self
      25             : //
      26             : #include    "catch_main.h"
      27             : 
      28             : 
      29             : 
      30             : // versiontheca
      31             : //
      32             : #include    "versiontheca/exception.h"
      33             : #include    "versiontheca/versiontheca.h"
      34             : 
      35             : 
      36             : // C++
      37             : //
      38             : #include    <cstring>
      39             : #include    <iomanip>
      40             : #include    <stdexcept>
      41             : 
      42             : 
      43             : 
      44             : 
      45             : namespace
      46             : {
      47             : 
      48             : 
      49         100 : bool is_number(std::string value)
      50             : {
      51         100 :     for(auto const c : value)
      52             :     {
      53         100 :         if(c < '0' || c > '9')
      54             :         {
      55         100 :             return false;
      56             :         }
      57             :     }
      58             : 
      59           0 :     return !value.empty();
      60             : }
      61             : 
      62             : 
      63             : 
      64             : }
      65             : // no name namespace
      66             : 
      67             : 
      68           8 : CATCH_TEST_CASE("part_integer", "[part][integer][valid]")
      69             : {
      70          12 :     CATCH_START_SECTION("part_integer: verify default part")
      71             :     {
      72           2 :         versiontheca::part p;
      73             : 
      74           1 :         CATCH_REQUIRE(p.get_separator() == U'\0');
      75           1 :         CATCH_REQUIRE(p.get_width() == 0);
      76           1 :         CATCH_REQUIRE(p.get_type() == '\0');
      77           1 :         CATCH_REQUIRE(p.is_integer());
      78             :         //CATCH_REQUIRE(p.get_string()); -- would throw
      79           1 :         CATCH_REQUIRE(p.get_integer() == 0);
      80           1 :         CATCH_REQUIRE(p.to_string() == "0");
      81           1 :         CATCH_REQUIRE(p.get_last_error().empty());
      82           1 :         CATCH_REQUIRE(p.is_zero());
      83             : 
      84           1 :         CATCH_REQUIRE(p.next());
      85           1 :         CATCH_REQUIRE(p.get_integer() == 1);
      86             :     }
      87             :     CATCH_END_SECTION()
      88             : 
      89          12 :     CATCH_START_SECTION("part_integer: set_value(\"\") sets the value to integer 0")
      90             :     {
      91           2 :         versiontheca::part p;
      92             : 
      93           1 :         p.set_value(std::string());
      94             : 
      95           1 :         CATCH_REQUIRE(p.get_separator() == U'\0');
      96           1 :         CATCH_REQUIRE(p.get_width() == 0);
      97           1 :         CATCH_REQUIRE(p.get_type() == '\0');
      98           1 :         CATCH_REQUIRE(p.is_integer());
      99             :         //CATCH_REQUIRE(p.get_string()); -- would throw
     100           1 :         CATCH_REQUIRE(p.get_integer() == 0);
     101           1 :         CATCH_REQUIRE(p.to_string() == "0");
     102           1 :         CATCH_REQUIRE(p.get_last_error().empty());
     103           1 :         CATCH_REQUIRE(p.is_zero());
     104             :     }
     105             :     CATCH_END_SECTION()
     106             : 
     107          12 :     CATCH_START_SECTION("part_integer: random integers, using set_integer()")
     108             :     {
     109         101 :         for(int i(0); i < 100; ++i)
     110             :         {
     111         200 :             versiontheca::part p;
     112             : 
     113         100 :             versiontheca::part_integer_t value;
     114         100 :             SNAP_CATCH2_NAMESPACE::random(value);
     115         100 :             p.set_integer(value);
     116             : 
     117         100 :             CATCH_REQUIRE(p.get_separator() == U'\0');
     118         100 :             CATCH_REQUIRE(p.get_width() == 0);
     119         100 :             CATCH_REQUIRE(p.get_type() == '\0');
     120         100 :             CATCH_REQUIRE(p.is_integer());
     121             :             //CATCH_REQUIRE(p.get_string() == value); -- would throw
     122         100 :             CATCH_REQUIRE(p.get_integer() == value);
     123         200 :             std::stringstream ss;
     124         100 :             ss << value;
     125         100 :             CATCH_REQUIRE(p.to_string() == ss.str());
     126         100 :             CATCH_REQUIRE(p.get_last_error().empty());
     127         100 :             if(value == 0)
     128             :             {
     129           0 :                 CATCH_REQUIRE(p.is_zero());
     130             :             }
     131             :             else
     132             :             {
     133         100 :                 CATCH_REQUIRE_FALSE(p.is_zero());
     134             :             }
     135             :         }
     136             :     }
     137             :     CATCH_END_SECTION()
     138             : 
     139          12 :     CATCH_START_SECTION("part_integer: random integers from string, using set_value()")
     140             :     {
     141         101 :         for(int i(0); i < 100; ++i)
     142             :         {
     143         200 :             versiontheca::part p;
     144             : 
     145         100 :             versiontheca::part_integer_t value;
     146         100 :             SNAP_CATCH2_NAMESPACE::random(value);
     147         200 :             std::stringstream ss;
     148         100 :             ss << value;
     149         100 :             p.set_value(ss.str());
     150             : 
     151         100 :             CATCH_REQUIRE(p.get_separator() == U'\0');
     152         100 :             CATCH_REQUIRE(p.get_width() == 0);
     153         100 :             CATCH_REQUIRE(p.get_type() == '\0');
     154         100 :             CATCH_REQUIRE(p.is_integer());
     155             :             //CATCH_REQUIRE(p.get_string() == value); -- would throw
     156         100 :             CATCH_REQUIRE(p.get_integer() == value);
     157         100 :             CATCH_REQUIRE(p.to_string() == ss.str());
     158         100 :             CATCH_REQUIRE(p.get_last_error().empty());
     159         100 :             if(value == 0)
     160             :             {
     161           0 :                 CATCH_REQUIRE(p.is_zero());
     162             :             }
     163             :             else
     164             :             {
     165         100 :                 CATCH_REQUIRE_FALSE(p.is_zero());
     166             :             }
     167             :         }
     168             :     }
     169             :     CATCH_END_SECTION()
     170             : 
     171          12 :     CATCH_START_SECTION("part_integer: check minimum integer")
     172             :     {
     173           2 :         versiontheca::part p;
     174           1 :         p.set_integer(0);
     175           1 :         CATCH_REQUIRE(p.is_integer());
     176           1 :         CATCH_REQUIRE(p.get_integer() == 0U);
     177             : 
     178           1 :         CATCH_REQUIRE_FALSE(p.previous());
     179           1 :         CATCH_REQUIRE(p.get_integer() == 0U);
     180             :     }
     181             :     CATCH_END_SECTION()
     182             : 
     183          12 :     CATCH_START_SECTION("part_integer: check maximum integer")
     184             :     {
     185           2 :         versiontheca::part p;
     186           1 :         p.set_to_max_integer();
     187           1 :         CATCH_REQUIRE(p.is_integer());
     188           1 :         CATCH_REQUIRE(p.get_integer() == std::numeric_limits<versiontheca::part_integer_t>::max());
     189             : 
     190           1 :         CATCH_REQUIRE_FALSE(p.next());
     191           1 :         CATCH_REQUIRE(p.get_integer() == std::numeric_limits<versiontheca::part_integer_t>::max());
     192             :     }
     193             :     CATCH_END_SECTION()
     194           6 : }
     195             : 
     196             : 
     197          10 : CATCH_TEST_CASE("part_string", "[part][integer][valid]")
     198             : {
     199          16 :     CATCH_START_SECTION("part_string: strings of digits, using set_string()")
     200             :     {
     201         101 :         for(int i(0); i < 100; ++i)
     202             :         {
     203         200 :             versiontheca::part p;
     204             : 
     205         100 :             versiontheca::part_integer_t number;
     206         100 :             SNAP_CATCH2_NAMESPACE::random(number);
     207         200 :             std::stringstream ss;
     208         100 :             ss << number;
     209         100 :             p.set_string(ss.str());
     210             : 
     211         100 :             CATCH_REQUIRE(p.get_separator() == U'\0');
     212         100 :             CATCH_REQUIRE(p.get_width() == 0);
     213         100 :             CATCH_REQUIRE(p.get_type() == '\0');
     214         100 :             CATCH_REQUIRE_FALSE(p.is_integer());
     215         100 :             CATCH_REQUIRE(p.get_string() == ss.str());
     216             :             //CATCH_REQUIRE(p.get_integer() == value); -- would throw
     217         100 :             CATCH_REQUIRE(p.to_string() == ss.str());
     218         100 :             CATCH_REQUIRE(p.get_last_error().empty());
     219         100 :             CATCH_REQUIRE_FALSE(p.is_zero());
     220             :         }
     221             :     }
     222             :     CATCH_END_SECTION()
     223             : 
     224          16 :     CATCH_START_SECTION("part_string: random strings, using set_string()")
     225             :     {
     226         101 :         for(int i(0); i < 100; ++i)
     227             :         {
     228         200 :             versiontheca::part p;
     229             : 
     230         200 :             std::string value;
     231         100 :             value = SNAP_CATCH2_NAMESPACE::random_string(1, 25, SNAP_CATCH2_NAMESPACE::character_t::CHARACTER_UNICODE);
     232         100 :             p.set_string(value);
     233             : 
     234         100 :             CATCH_REQUIRE(p.get_separator() == U'\0');
     235         100 :             CATCH_REQUIRE(p.get_width() == 0);
     236         100 :             CATCH_REQUIRE(p.get_type() == '\0');
     237         100 :             CATCH_REQUIRE_FALSE(p.is_integer());
     238         100 :             CATCH_REQUIRE(p.get_string() == value);
     239             :             //CATCH_REQUIRE(p.get_integer() == value); -- would throw
     240         100 :             CATCH_REQUIRE(p.to_string() == value);
     241         100 :             CATCH_REQUIRE(p.get_last_error().empty());
     242         100 :             CATCH_REQUIRE_FALSE(p.is_zero());
     243             :         }
     244             :     }
     245             :     CATCH_END_SECTION()
     246             : 
     247          16 :     CATCH_START_SECTION("part_string: random strings, using set_value()")
     248             :     {
     249         101 :         for(int i(0); i < 100; ++i)
     250             :         {
     251         200 :             versiontheca::part p;
     252             : 
     253         200 :             std::string value;
     254           0 :             do
     255             :             {
     256         100 :                 value = SNAP_CATCH2_NAMESPACE::random_string(1, 25, SNAP_CATCH2_NAMESPACE::character_t::CHARACTER_UNICODE);
     257             :             }
     258         100 :             while(is_number(value));
     259         100 :             p.set_value(value);
     260             : 
     261         100 :             CATCH_REQUIRE(p.get_separator() == U'\0');
     262         100 :             CATCH_REQUIRE(p.get_width() == 0);
     263         100 :             CATCH_REQUIRE(p.get_type() == '\0');
     264         100 :             CATCH_REQUIRE_FALSE(p.is_integer());
     265         100 :             CATCH_REQUIRE(p.get_string() == value);
     266             :             //CATCH_REQUIRE(p.get_integer() == value); -- would throw
     267         100 :             CATCH_REQUIRE(p.to_string() == value);
     268         100 :             CATCH_REQUIRE(p.get_last_error().empty());
     269         100 :             CATCH_REQUIRE_FALSE(p.is_zero());
     270             :         }
     271             :     }
     272             :     CATCH_END_SECTION()
     273             : 
     274          16 :     CATCH_START_SECTION("part_string: check maximum string")
     275             :     {
     276          11 :         for(int sz(1); sz <= 10; ++sz)
     277             :         {
     278          20 :             versiontheca::part p;
     279          10 :             p.set_to_max_string(sz);
     280          10 :             CATCH_REQUIRE_FALSE(p.is_integer());
     281          20 :             std::string expected;
     282          10 :             expected.reserve(sz);
     283          65 :             for(int i(0); i < sz; ++i)
     284             :             {
     285          55 :                 expected += 'z';
     286             :             }
     287          10 :             CATCH_REQUIRE(p.get_string() == expected);
     288             :         }
     289             :     }
     290             :     CATCH_END_SECTION()
     291             : 
     292          16 :     CATCH_START_SECTION("part_string: next on two letters up to max.")
     293             :     {
     294           1 :         char buf[3] = { 'A', 'A', '\0' };
     295           2 :         versiontheca::part p;
     296           1 :         p.set_value(buf);
     297           1 :         CATCH_REQUIRE_FALSE(p.is_integer());
     298           1 :         CATCH_REQUIRE(p.get_string() == buf);
     299          52 :         for(int j(0); j < 51; ++j)
     300             :         {
     301        1326 :             for(int i(0); i < 25; ++i) // AA to AZ
     302             :             {
     303        1275 :                 CATCH_REQUIRE(p.next());
     304        1275 :                 ++buf[1];
     305        1275 :                 CATCH_REQUIRE(p.get_string() == buf);
     306             :             }
     307          51 :             CATCH_REQUIRE(p.next()); // Z + 1 = 'a'
     308          51 :             buf[1] = 'a';
     309          51 :             CATCH_REQUIRE(p.get_string() == buf);
     310        1326 :             for(int i(0); i < 25; ++i)
     311             :             {
     312        1275 :                 CATCH_REQUIRE(p.next());
     313        1275 :                 ++buf[1];
     314        1275 :                 CATCH_REQUIRE(p.get_string() == buf);
     315             :             }
     316          51 :             CATCH_REQUIRE(p.next()); // z + 1 = 'A' + carry
     317          51 :             if(buf[0] == 'Z')
     318             :             {
     319           1 :                 buf[0] = 'a';
     320             :             }
     321             :             else
     322             :             {
     323          50 :                 ++buf[0];
     324             :             }
     325          51 :             buf[1] = 'A';
     326          51 :             CATCH_REQUIRE(p.get_string() == buf);
     327             :         }
     328             : 
     329             :         // one more time on the lower character
     330             :         //
     331          26 :         for(int i(0); i < 25; ++i) // AA to AZ
     332             :         {
     333          25 :             CATCH_REQUIRE(p.next());
     334          25 :             ++buf[1];
     335          25 :             CATCH_REQUIRE(p.get_string() == buf);
     336             :         }
     337           1 :         CATCH_REQUIRE(p.next()); // Z + 1 = 'a'
     338           1 :         buf[1] = 'a';
     339           1 :         CATCH_REQUIRE(p.get_string() == buf);
     340          26 :         for(int i(0); i < 25; ++i)
     341             :         {
     342          25 :             CATCH_REQUIRE(p.next());
     343          25 :             ++buf[1];
     344          25 :             CATCH_REQUIRE(p.get_string() == buf);
     345             :         }
     346           1 :         CATCH_REQUIRE_FALSE(p.next());
     347           1 :         CATCH_REQUIRE(p.get_string() == buf);
     348             :     }
     349             :     CATCH_END_SECTION()
     350             : 
     351          16 :     CATCH_START_SECTION("part_string: next on two letters separated by + up to max.")
     352             :     {
     353           1 :         char buf[4] = { 'A', '+', 'A', '\0' };
     354           2 :         versiontheca::part p;
     355           1 :         p.set_value(buf);
     356           1 :         CATCH_REQUIRE_FALSE(p.is_integer());
     357           1 :         CATCH_REQUIRE(p.get_string() == buf);
     358          52 :         for(int j(0); j < 51; ++j)
     359             :         {
     360        1326 :             for(int i(0); i < 25; ++i)
     361             :             {
     362        1275 :                 CATCH_REQUIRE(p.next());
     363        1275 :                 ++buf[2];
     364        1275 :                 CATCH_REQUIRE(p.get_string() == buf);
     365             :             }
     366          51 :             CATCH_REQUIRE(p.next()); // Z + 1 = 'a'
     367          51 :             buf[2] = 'a';
     368          51 :             CATCH_REQUIRE(p.get_string() == buf);
     369        1326 :             for(int i(0); i < 25; ++i)
     370             :             {
     371        1275 :                 CATCH_REQUIRE(p.next());
     372        1275 :                 ++buf[2];
     373        1275 :                 CATCH_REQUIRE(p.get_string() == buf);
     374             :             }
     375          51 :             CATCH_REQUIRE(p.next()); // z + 1 = 'A' + carry
     376          51 :             if(buf[0] == 'Z')
     377             :             {
     378           1 :                 buf[0] = 'a';
     379             :             }
     380             :             else
     381             :             {
     382          50 :                 ++buf[0];
     383             :             }
     384          51 :             buf[2] = 'A';
     385          51 :             CATCH_REQUIRE(p.get_string() == buf);
     386             :         }
     387             : 
     388             :         // one more time on the lower character
     389             :         //
     390          26 :         for(int i(0); i < 25; ++i) // AA to AZ
     391             :         {
     392          25 :             CATCH_REQUIRE(p.next());
     393          25 :             ++buf[2];
     394          25 :             CATCH_REQUIRE(p.get_string() == buf);
     395             :         }
     396           1 :         CATCH_REQUIRE(p.next()); // Z + 1 = 'a'
     397           1 :         buf[2] = 'a';
     398           1 :         CATCH_REQUIRE(p.get_string() == buf);
     399          26 :         for(int i(0); i < 25; ++i)
     400             :         {
     401          25 :             CATCH_REQUIRE(p.next());
     402          25 :             ++buf[2];
     403          25 :             CATCH_REQUIRE(p.get_string() == buf);
     404             :         }
     405           1 :         CATCH_REQUIRE_FALSE(p.next());
     406           1 :         CATCH_REQUIRE(p.get_string() == buf);
     407             :     }
     408             :     CATCH_END_SECTION()
     409             : 
     410          16 :     CATCH_START_SECTION("part_string: previous on two letters up to min.")
     411             :     {
     412           1 :         char buf[3] = { 'z', 'z', '\0' };
     413           2 :         versiontheca::part p;
     414           1 :         p.set_value(buf);
     415           1 :         CATCH_REQUIRE_FALSE(p.is_integer());
     416           1 :         CATCH_REQUIRE(p.get_string() == buf);
     417          52 :         for(int j(0); j < 51; ++j)
     418             :         {
     419        1326 :             for(int i(0); i < 25; ++i)
     420             :             {
     421        1275 :                 CATCH_REQUIRE(p.previous());
     422        1275 :                 --buf[1];
     423        1275 :                 CATCH_REQUIRE(p.get_string() == buf);
     424             :             }
     425          51 :             CATCH_REQUIRE(p.previous()); // a - 1 = 'Z'
     426          51 :             buf[1] = 'Z';
     427          51 :             CATCH_REQUIRE(p.get_string() == buf);
     428        1326 :             for(int i(0); i < 25; ++i)
     429             :             {
     430        1275 :                 CATCH_REQUIRE(p.previous());
     431        1275 :                 --buf[1];
     432        1275 :                 CATCH_REQUIRE(p.get_string() == buf);
     433             :             }
     434          51 :             CATCH_REQUIRE(p.previous()); // a - 1 = 'Z' + carry
     435          51 :             if(buf[0] == 'a')
     436             :             {
     437           1 :                 buf[0] = 'Z';
     438             :             }
     439             :             else
     440             :             {
     441          50 :                 --buf[0];
     442             :             }
     443          51 :             buf[1] = 'z';
     444          51 :             CATCH_REQUIRE(p.get_string() == buf);
     445             :         }
     446             : 
     447             :         // one more time on the lower character
     448             :         //
     449          26 :         for(int i(0); i < 25; ++i) // AA to AZ
     450             :         {
     451          25 :             CATCH_REQUIRE(p.previous());
     452          25 :             --buf[1];
     453          25 :             CATCH_REQUIRE(p.get_string() == buf);
     454             :         }
     455           1 :         CATCH_REQUIRE(p.previous()); // a + 1 = 'Z'
     456           1 :         buf[1] = 'Z';
     457           1 :         CATCH_REQUIRE(p.get_string() == buf);
     458          26 :         for(int i(0); i < 25; ++i)
     459             :         {
     460          25 :             CATCH_REQUIRE(p.previous());
     461          25 :             --buf[1];
     462          25 :             CATCH_REQUIRE(p.get_string() == buf);
     463             :         }
     464           1 :         CATCH_REQUIRE_FALSE(p.previous());
     465           1 :         CATCH_REQUIRE(p.get_string() == buf);
     466             :     }
     467             :     CATCH_END_SECTION()
     468             : 
     469          16 :     CATCH_START_SECTION("part_string: previous on two letters separated by + up to min.")
     470             :     {
     471           1 :         char buf[4] = { 'z', '+', 'z', '\0' };
     472           2 :         versiontheca::part p;
     473           1 :         p.set_value(buf);
     474           1 :         CATCH_REQUIRE_FALSE(p.is_integer());
     475           1 :         CATCH_REQUIRE(p.get_string() == buf);
     476          52 :         for(int j(0); j < 51; ++j)
     477             :         {
     478        1326 :             for(int i(0); i < 25; ++i)
     479             :             {
     480        1275 :                 CATCH_REQUIRE(p.previous());
     481        1275 :                 --buf[2];
     482        1275 :                 CATCH_REQUIRE(p.get_string() == buf);
     483             :             }
     484          51 :             CATCH_REQUIRE(p.previous()); // a - 1 = 'Z'
     485          51 :             buf[2] = 'Z';
     486          51 :             CATCH_REQUIRE(p.get_string() == buf);
     487        1326 :             for(int i(0); i < 25; ++i)
     488             :             {
     489        1275 :                 CATCH_REQUIRE(p.previous());
     490        1275 :                 --buf[2];
     491        1275 :                 CATCH_REQUIRE(p.get_string() == buf);
     492             :             }
     493          51 :             CATCH_REQUIRE(p.previous()); // a - 1 = 'Z' + carry
     494          51 :             if(buf[0] == 'a')
     495             :             {
     496           1 :                 buf[0] = 'Z';
     497             :             }
     498             :             else
     499             :             {
     500          50 :                 --buf[0];
     501             :             }
     502          51 :             buf[2] = 'z';
     503          51 :             CATCH_REQUIRE(p.get_string() == buf);
     504             :         }
     505             : 
     506             :         // one more time on the lower character
     507             :         //
     508          26 :         for(int i(0); i < 25; ++i) // AA to AZ
     509             :         {
     510          25 :             CATCH_REQUIRE(p.previous());
     511          25 :             --buf[2];
     512          25 :             CATCH_REQUIRE(p.get_string() == buf);
     513             :         }
     514           1 :         CATCH_REQUIRE(p.previous()); // a - 1 = 'Z'
     515           1 :         buf[2] = 'Z';
     516           1 :         CATCH_REQUIRE(p.get_string() == buf);
     517          26 :         for(int i(0); i < 25; ++i)
     518             :         {
     519          25 :             CATCH_REQUIRE(p.previous());
     520          25 :             --buf[2];
     521          25 :             CATCH_REQUIRE(p.get_string() == buf);
     522             :         }
     523           1 :         CATCH_REQUIRE_FALSE(p.previous());
     524           1 :         CATCH_REQUIRE(p.get_string() == buf);
     525             :     }
     526             :     CATCH_END_SECTION()
     527           8 : }
     528             : 
     529             : 
     530           5 : CATCH_TEST_CASE("part_compare", "[part][compare][valid]")
     531             : {
     532           6 :     CATCH_START_SECTION("part_compare: integers")
     533             :     {
     534           2 :         versiontheca::part a;
     535           2 :         versiontheca::part b;
     536             : 
     537           1 :         CATCH_REQUIRE(a.compare(b) == 0);
     538           1 :         a.set_integer(10);
     539           1 :         CATCH_REQUIRE(a.compare(b) == 1);
     540           1 :         b.set_integer(253);
     541           1 :         CATCH_REQUIRE(a.compare(b) == -1);
     542             :     }
     543             :     CATCH_END_SECTION()
     544             : 
     545           6 :     CATCH_START_SECTION("part_compare: strings")
     546             :     {
     547           2 :         versiontheca::part a;
     548           2 :         versiontheca::part b;
     549             : 
     550           1 :         a.set_string("abc");
     551           1 :         b.set_string("xyz");
     552             : 
     553           1 :         CATCH_REQUIRE(a.compare(b) == -1);
     554           1 :         CATCH_REQUIRE(a.compare(a) == 0);
     555           1 :         CATCH_REQUIRE(b.compare(b) == 0);
     556           1 :         a.set_string("xyz~more");
     557           1 :         CATCH_REQUIRE(a.compare(b) == 1);
     558           1 :         b.set_string("xyz~more");
     559           1 :         CATCH_REQUIRE(a.compare(b) == 0);
     560             :     }
     561             :     CATCH_END_SECTION()
     562             : 
     563           6 :     CATCH_START_SECTION("part_compare: mix")
     564             :     {
     565           2 :         versiontheca::part a;
     566           2 :         versiontheca::part b;
     567             : 
     568           1 :         a.set_string("10");
     569           1 :         b.set_integer(2);
     570             : 
     571           1 :         CATCH_REQUIRE(a.compare(b) == -1); // 10 > 2 but as string "10" < "2"
     572           1 :         CATCH_REQUIRE(b.compare(a) == 1);
     573             :     }
     574             :     CATCH_END_SECTION()
     575           3 : }
     576             : 
     577             : 
     578           5 : CATCH_TEST_CASE("part_meta", "[part][valid]")
     579             : {
     580           6 :     CATCH_START_SECTION("part_meta: separators")
     581             :     {
     582     1114081 :         for(char32_t sep(U' '); sep < 0x110000; ++sep)
     583             :         {
     584     1116161 :             if((sep >= 0x7F && sep <= 0x9F)
     585     1114047 :             || (sep >= 0xD800 && sep <= 0xDFFF))
     586             :             {
     587        2081 :                 continue;
     588             :             }
     589     2223998 :             versiontheca::part p;
     590     1111999 :             p.set_separator(sep);
     591     1111999 :             CATCH_REQUIRE(p.get_separator() == sep);
     592             : 
     593             :             // we can always reset back to U'\0'
     594             :             //
     595     1111999 :             p.set_separator(U'\0');
     596     1111999 :             CATCH_REQUIRE(p.get_separator() == U'\0');
     597             :         }
     598             :     }
     599             :     CATCH_END_SECTION()
     600             : 
     601           6 :     CATCH_START_SECTION("part_meta: width")
     602             :     {
     603         257 :         for(int width(0); width < 256; ++width)
     604             :         {
     605         512 :             versiontheca::part p;
     606         256 :             CATCH_REQUIRE(p.get_width() == 0);
     607         256 :             p.set_width(width);
     608         256 :             CATCH_REQUIRE(p.get_width() == width);
     609             :         }
     610             :     }
     611             :     CATCH_END_SECTION()
     612             : 
     613           6 :     CATCH_START_SECTION("part_meta: type")
     614             :     {
     615         257 :         for(int type(0); type < 256; ++type)
     616             :         {
     617         512 :             versiontheca::part p;
     618         256 :             CATCH_REQUIRE(p.get_type() == '\0');
     619         256 :             p.set_type(type);
     620         256 :             CATCH_REQUIRE(p.get_type() == static_cast<char>(type));
     621             :         }
     622             :     }
     623             :     CATCH_END_SECTION()
     624           3 : }
     625             : 
     626             : 
     627           7 : CATCH_TEST_CASE("part_invalid", "[part][invalid]")
     628             : {
     629          10 :     CATCH_START_SECTION("part_invalid: bad separators (controls)")
     630             :     {
     631          32 :         for(char32_t sep(U'\x01'); sep < U' '; ++sep)
     632             :         {
     633          62 :             versiontheca::part p;
     634          31 :             CATCH_REQUIRE_THROWS_MATCHES(
     635             :                   p.set_separator(sep)
     636             :                 , versiontheca::invalid_parameter
     637             :                 , Catch::Matchers::ExceptionMessage(
     638             :                           "versiontheca_exception: separator cannot be a control other than U'\\0' or a surrogate."));
     639             :         }
     640             :     }
     641             :     CATCH_END_SECTION()
     642             : 
     643          10 :     CATCH_START_SECTION("part_invalid: bad separators (graphical controls)")
     644             :     {
     645          34 :         for(char32_t sep(U'\x7F'); sep < U'\xA0'; ++sep)
     646             :         {
     647          66 :             versiontheca::part p;
     648          33 :             CATCH_REQUIRE_THROWS_MATCHES(
     649             :                   p.set_separator(sep)
     650             :                 , versiontheca::invalid_parameter
     651             :                 , Catch::Matchers::ExceptionMessage(
     652             :                           "versiontheca_exception: separator cannot be a control other than U'\\0' or a surrogate."));
     653             :         }
     654             :     }
     655             :     CATCH_END_SECTION()
     656             : 
     657          10 :     CATCH_START_SECTION("part_invalid: bad separators (surrogates)")
     658             :     {
     659        2048 :         for(char32_t sep(0XD800); sep < 0xDFFF; ++sep)
     660             :         {
     661        4094 :             versiontheca::part p;
     662        2047 :             CATCH_REQUIRE_THROWS_MATCHES(
     663             :                   p.set_separator(sep)
     664             :                 , versiontheca::invalid_parameter
     665             :                 , Catch::Matchers::ExceptionMessage(
     666             :                           "versiontheca_exception: separator cannot be a control other than U'\\0' or a surrogate."));
     667             :         }
     668             :     }
     669             :     CATCH_END_SECTION()
     670             : 
     671          10 :     CATCH_START_SECTION("part_invalid: get_string() when integer")
     672             :     {
     673           2 :         versiontheca::part p;
     674           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     675             :               p.get_string()
     676             :             , versiontheca::wrong_type
     677             :             , Catch::Matchers::ExceptionMessage(
     678             :                       "versiontheca_exception: this part is not a string."));
     679             :     }
     680             :     CATCH_END_SECTION()
     681             : 
     682          10 :     CATCH_START_SECTION("part_invalid: get_integer() when string")
     683             :     {
     684           2 :         versiontheca::part p;
     685           1 :         p.set_string("now this is a string");
     686           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     687             :               p.get_integer()
     688             :             , versiontheca::wrong_type
     689             :             , Catch::Matchers::ExceptionMessage(
     690             :                       "versiontheca_exception: this part is not an integer."));
     691             :     }
     692             :     CATCH_END_SECTION()
     693          11 : }
     694             : 
     695             : 
     696             : 
     697             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13