LCOV - code coverage report
Current view: top level - tests - catch_validator.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 257 268 95.9 %
Date: 2021-09-08 17:05:25 Functions: 11 17 64.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2006-2021  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/advgetopt
       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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
      19             : 
      20             : // self
      21             : //
      22             : #include    "catch_main.h"
      23             : 
      24             : 
      25             : // advgetopt lib
      26             : //
      27             : #include    <advgetopt/exception.h>
      28             : 
      29             : 
      30             : // snapdev lib
      31             : //
      32             : #include    <snapdev/safe_setenv.h>
      33             : 
      34             : 
      35             : // C++ lib
      36             : //
      37             : #include <fstream>
      38             : 
      39             : 
      40             : // last include
      41             : //
      42             : #include    <snapdev/poison.h>
      43             : 
      44             : 
      45             : 
      46             : 
      47             : 
      48             : namespace
      49             : {
      50             : 
      51       41240 : std::int64_t large_rnd()
      52             : {
      53       41240 :     return (static_cast<std::int64_t>(rand()) <<  0)
      54       41240 :          ^ (static_cast<std::int64_t>(rand()) << 16)
      55       41240 :          ^ (static_cast<std::int64_t>(rand()) << 32)
      56       41240 :          ^ (static_cast<std::int64_t>(rand()) << 48);
      57             : }
      58             : 
      59             : }
      60             : 
      61             : 
      62             : 
      63           4 : CATCH_TEST_CASE("unknown_validator", "[validator][valid][validation]")
      64             : {
      65           4 :     CATCH_START_SECTION("Undefined validator")
      66             :         // this is a valid case, it does not throw, it just returns a nullptr
      67             :         //
      68           1 :         CATCH_REQUIRE(advgetopt::validator::create("unknown", advgetopt::string_list_t()) == nullptr);
      69             :     CATCH_END_SECTION()
      70             : 
      71           4 :     CATCH_START_SECTION("Empty string")
      72           1 :         CATCH_REQUIRE(advgetopt::validator::create(std::string()) == nullptr);
      73             :     CATCH_END_SECTION()
      74           2 : }
      75             : 
      76             : 
      77             : 
      78           5 : CATCH_TEST_CASE("integer_validator", "[validator][valid][validation]")
      79             : {
      80           6 :     CATCH_START_SECTION("Verify the integer validator")
      81           2 :         advgetopt::validator::pointer_t integer_validator(advgetopt::validator::create("integer", advgetopt::string_list_t()));
      82             : 
      83           1 :         CATCH_REQUIRE(integer_validator != nullptr);
      84           1 :         CATCH_REQUIRE(integer_validator->name() == "integer");
      85             : 
      86           1 :         CATCH_REQUIRE_FALSE(integer_validator->validate(""));
      87           1 :         CATCH_REQUIRE_FALSE(integer_validator->validate("+"));
      88           1 :         CATCH_REQUIRE_FALSE(integer_validator->validate("-"));
      89             : 
      90        1001 :         for(int idx(0); idx < 1000; ++idx)
      91             :         {
      92        1000 :             std::int64_t value(large_rnd());
      93        2000 :             std::string const v(std::to_string(value));
      94             : 
      95        1000 :             CATCH_REQUIRE(integer_validator->validate(v));
      96             : 
      97        1000 :             if(value >= 0)
      98             :             {
      99         481 :                 CATCH_REQUIRE(integer_validator->validate('+' + v));
     100             :             }
     101             : 
     102        2000 :             std::string const space_before(' ' + v);
     103        1000 :             CATCH_REQUIRE_FALSE(integer_validator->validate(space_before));
     104             : 
     105        2000 :             std::string const space_after(v + ' ');
     106        1000 :             CATCH_REQUIRE_FALSE(integer_validator->validate(space_after));
     107             : 
     108        2000 :             std::string const before(static_cast<char>(rand() % 26 + 'a') + v);
     109        1000 :             CATCH_REQUIRE_FALSE(integer_validator->validate(before));
     110             : 
     111        2000 :             std::string const after(v + static_cast<char>(rand() % 26 + 'a'));
     112        1000 :             CATCH_REQUIRE_FALSE(integer_validator->validate(after));
     113             :         }
     114             : 
     115             :         // max number
     116           1 :         CATCH_REQUIRE(integer_validator->validate("9223372036854775807"));
     117           1 :         CATCH_REQUIRE(integer_validator->validate("+9223372036854775807"));
     118             : 
     119             :         // overflow
     120           1 :         CATCH_REQUIRE_FALSE(integer_validator->validate("9223372036854775808"));
     121           1 :         CATCH_REQUIRE_FALSE(integer_validator->validate("+9223372036854775808"));
     122             : 
     123             :         // min number
     124           1 :         CATCH_REQUIRE(integer_validator->validate("-9223372036854775808"));
     125             : 
     126             :         // underflow
     127           1 :         CATCH_REQUIRE_FALSE(integer_validator->validate("-9223372036854775809"));
     128             : 
     129             :         // too many digits
     130           1 :         CATCH_REQUIRE_FALSE(integer_validator->validate("92233720368547758091"));
     131           1 :         CATCH_REQUIRE_FALSE(integer_validator->validate("+92233720368547758092"));
     132           1 :         CATCH_REQUIRE_FALSE(integer_validator->validate("-92233720368547758093"));
     133             :     CATCH_END_SECTION()
     134             : 
     135           6 :     CATCH_START_SECTION("Verify the integer ranges")
     136           1 :         bool had_standalone(false);
     137          21 :         for(int count(0); count < 20 || !had_standalone; ++count)
     138             :         {
     139          20 :             std::int64_t min(large_rnd());
     140          20 :             std::int64_t max(large_rnd());
     141          20 :             if(min > max)
     142             :             {
     143          10 :                 std::swap(min, max);
     144             :             }
     145             : 
     146          40 :             std::string const & smin(std::to_string(min));
     147          40 :             std::string const & smax(std::to_string(max));
     148             : 
     149          40 :             std::string range("...");
     150          80 :             for(int three(0); three < 3; ++three)
     151             :             {
     152          60 :                 if(rand() % 5 == 0)
     153             :                 {
     154          12 :                     range = ' ' + range;
     155             :                 }
     156          60 :                 if(rand() % 5 == 0)
     157             :                 {
     158          10 :                     range = range + ' ';
     159             :                 }
     160             :             }
     161          20 :             range = smin + range + smax;
     162          80 :             for(int three(0); three < 3; ++three)
     163             :             {
     164          60 :                 if(rand() % 5 == 0)
     165             :                 {
     166          11 :                     range = ' ' + range;
     167             :                 }
     168          60 :                 if(rand() % 5 == 0)
     169             :                 {
     170          13 :                     range = range + ' ';
     171             :                 }
     172             :             }
     173             : 
     174          20 :             std::int64_t standalone(0);
     175          20 :             bool standalone_included(rand() % 4 == 0);
     176          20 :             if(standalone_included)
     177             :             {
     178           6 :                 if(min == std::numeric_limits<std::int64_t>::min()
     179           3 :                 && max == std::numeric_limits<std::int64_t>::max())
     180             :                 {
     181           0 :                     standalone_included = false;
     182             :                 }
     183             :                 else
     184             :                 {
     185           3 :                     had_standalone = true;
     186           2 :                     do
     187             :                     {
     188           5 :                         standalone = large_rnd();
     189             :                     }
     190           5 :                     while(standalone >= min && standalone <= max);
     191             : 
     192           6 :                     std::string sep(",");
     193           3 :                     if(rand() % 3 == 0)
     194             :                     {
     195           1 :                         sep = ' ' + sep;
     196             :                     }
     197           3 :                     if(rand() % 3 == 0)
     198             :                     {
     199           0 :                         sep = sep + ' ';
     200             :                     }
     201           3 :                     if(rand() % 2 == 0)
     202             :                     {
     203           0 :                         range = std::to_string(standalone) + "," + range;
     204             :                     }
     205             :                     else
     206             :                     {
     207           3 :                         range = range + "," + std::to_string(standalone);
     208             :                     }
     209             :                 }
     210             :             }
     211          40 :             advgetopt::string_list_t range_list;
     212          40 :             advgetopt::split_string(range
     213             :                        , range_list
     214          20 :                        , {","});
     215          40 :             advgetopt::validator::pointer_t integer_validator(advgetopt::validator::create("integer", range_list));
     216             : 
     217          20 :             CATCH_REQUIRE(integer_validator != nullptr);
     218          20 :             CATCH_REQUIRE(integer_validator->name() == "integer");
     219             : 
     220       20020 :             for(int idx(0); idx < 1000; ++idx)
     221             :             {
     222       20000 :                 std::int64_t value(large_rnd());
     223             : 
     224             :                 // force valid values otherwise we're likely to only have
     225             :                 // invalid ones
     226             :                 //
     227       20000 :                 if(idx % 10 == 0)
     228             :                 {
     229        2000 :                     value %= max - min + 1;
     230        2000 :                     value += min;
     231             :                 }
     232       18000 :                 else if(idx % 50 == 1 && standalone_included)
     233             :                 {
     234          60 :                     value = standalone;
     235             :                 }
     236             : 
     237       40000 :                 std::string const v(std::to_string(value));
     238             : 
     239       20000 :                 if((standalone_included && value == standalone)
     240       19940 :                 || (value >= min && value <= max))
     241             :                 {
     242        7487 :                     CATCH_REQUIRE(integer_validator->validate(v));
     243             :                 }
     244             :                 else
     245             :                 {
     246       12513 :                     CATCH_REQUIRE_FALSE(integer_validator->validate(v));
     247             :                 }
     248             : 
     249       20000 :                 if(value >= 0)
     250             :                 {
     251        9927 :                     if((standalone_included && value == standalone)
     252        9927 :                     || (value >= min && value <= max))
     253             :                     {
     254        4067 :                         CATCH_REQUIRE(integer_validator->validate('+' + v));
     255             :                     }
     256             :                     else
     257             :                     {
     258        5860 :                         CATCH_REQUIRE_FALSE(integer_validator->validate('+' + v));
     259             :                     }
     260             :                 }
     261             : 
     262       40000 :                 std::string const space_before(' ' + v);
     263       20000 :                 CATCH_REQUIRE_FALSE(integer_validator->validate(space_before));
     264             : 
     265       40000 :                 std::string const space_after(v + ' ');
     266       20000 :                 CATCH_REQUIRE_FALSE(integer_validator->validate(space_after));
     267             : 
     268       40000 :                 std::string const before(static_cast<char>(rand() % 26 + 'a') + v);
     269       20000 :                 CATCH_REQUIRE_FALSE(integer_validator->validate(before));
     270             : 
     271       40000 :                 std::string const after(v + static_cast<char>(rand() % 26 + 'a'));
     272       20000 :                 CATCH_REQUIRE_FALSE(integer_validator->validate(after));
     273             :             }
     274             :         }
     275             :     CATCH_END_SECTION()
     276             : 
     277           6 :     CATCH_START_SECTION("Verify the integer standalone list")
     278          21 :         for(int count(0); count < 20; ++count)
     279             :         {
     280          20 :             int valid(rand() % 10 + 5);
     281          40 :             std::vector<std::int64_t> numbers;
     282          20 :             numbers.reserve(valid);
     283          40 :             std::string standalone_values;
     284         215 :             for(int idx(0); idx < valid; ++idx)
     285             :             {
     286         195 :                 std::int64_t const value(large_rnd());
     287         195 :                 numbers.push_back(value);
     288         390 :                 std::string const & svalue(std::to_string(value));
     289         195 :                 if(rand() % 5 == 0)
     290             :                 {
     291          40 :                     standalone_values += ' ';
     292             :                 }
     293         195 :                 if(idx != 0)
     294             :                 {
     295         175 :                     standalone_values += ',';
     296             :                 }
     297         195 :                 if(rand() % 5 == 0)
     298             :                 {
     299          47 :                     standalone_values += ' ';
     300             :                 }
     301         195 :                 standalone_values += svalue;
     302             :             }
     303          20 :             if(rand() % 5 == 0)
     304             :             {
     305           3 :                 standalone_values += ' ';
     306             :             }
     307          40 :             advgetopt::string_list_t range_list;
     308          40 :             advgetopt::split_string(standalone_values
     309             :                        , range_list
     310          20 :                        , {","});
     311             : 
     312          40 :             advgetopt::validator::pointer_t integer_validator(advgetopt::validator::create("integer", range_list));
     313             : 
     314          20 :             CATCH_REQUIRE(integer_validator != nullptr);
     315          20 :             CATCH_REQUIRE(integer_validator->name() == "integer");
     316             : 
     317         215 :             for(size_t idx(0); idx < numbers.size(); ++idx)
     318             :             {
     319         390 :                 std::string const svalue(std::to_string(numbers[idx]));
     320             : 
     321         195 :                 CATCH_REQUIRE(integer_validator->validate(svalue));
     322             :             }
     323             : 
     324       20020 :             for(int idx(0); idx < 1000; ++idx)
     325             :             {
     326       20000 :                 std::int64_t value;
     327             : 
     328             :                 for(;;)
     329             :                 {
     330       20000 :                     value = large_rnd();
     331       20000 :                     if(std::find(numbers.begin(), numbers.end(), value) == numbers.end())
     332             :                     {
     333       20000 :                         break;
     334             :                     }
     335             :                 }
     336             : 
     337       20000 :                 CATCH_REQUIRE_FALSE(integer_validator->validate(std::to_string(value)));
     338             :             }
     339             :         }
     340             :     CATCH_END_SECTION()
     341           3 : }
     342             : 
     343             : 
     344             : 
     345             : 
     346           6 : CATCH_TEST_CASE("regex_validator", "[validator][valid][validation]")
     347             : {
     348           8 :     CATCH_START_SECTION("Verify the regex validator")
     349           2 :         advgetopt::validator::pointer_t regex_validator(advgetopt::validator::create("regex", {".*@.*\\..*"}));
     350             : 
     351           1 :         CATCH_REQUIRE(regex_validator != nullptr);
     352           1 :         CATCH_REQUIRE(regex_validator->name() == "regex");
     353             : 
     354           1 :         CATCH_REQUIRE(regex_validator->validate("@m2osw."));
     355           1 :         CATCH_REQUIRE(regex_validator->validate("contact@m2osw.com"));
     356           1 :         CATCH_REQUIRE(regex_validator->validate("Contact@m2osw.com"));
     357           1 :         CATCH_REQUIRE(regex_validator->validate("Contact@M2OSW.com"));
     358             : 
     359           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("contact@m2osw:com"));
     360           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("contact!m2osw.com"));
     361             :     CATCH_END_SECTION()
     362             : 
     363           8 :     CATCH_START_SECTION("Verify the regex string (case sensitive)")
     364           2 :         advgetopt::validator::pointer_t regex_validator(advgetopt::validator::create("regex", {"/contact@.*\\..*/"}));
     365             : 
     366           1 :         CATCH_REQUIRE(regex_validator != nullptr);
     367           1 :         CATCH_REQUIRE(regex_validator->name() == "regex");
     368             : 
     369           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("@m2osw."));
     370           1 :         CATCH_REQUIRE(regex_validator->validate("contact@m2osw.com"));
     371           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("Contact@m2osw.com"));
     372           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("Contact@M2OSW.com"));
     373             : 
     374           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("contact@m2osw:com"));
     375           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("contact!m2osw.com"));
     376             :     CATCH_END_SECTION()
     377             : 
     378           8 :     CATCH_START_SECTION("Verify the regex string (case insensitive)")
     379           2 :         advgetopt::validator::pointer_t regex_validator(advgetopt::validator::create("regex", {"/contact@.*\\..*/i"}));
     380             : 
     381           1 :         CATCH_REQUIRE(regex_validator != nullptr);
     382           1 :         CATCH_REQUIRE(regex_validator->name() == "regex");
     383             : 
     384           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("@m2osw."));
     385           1 :         CATCH_REQUIRE(regex_validator->validate("contact@m2osw.com"));
     386           1 :         CATCH_REQUIRE(regex_validator->validate("Contact@m2osw.com"));
     387           1 :         CATCH_REQUIRE(regex_validator->validate("Contact@M2OSW.com"));
     388             : 
     389           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("contact@m2osw:com"));
     390           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("contact!m2osw.com"));
     391             :     CATCH_END_SECTION()
     392             : 
     393           8 :     CATCH_START_SECTION("Verify direct regex string (case insensitive)")
     394           2 :         advgetopt::validator::pointer_t regex_validator(advgetopt::validator::create("/contact@.*\\..*/i"));
     395             : 
     396           1 :         CATCH_REQUIRE(regex_validator != nullptr);
     397           1 :         CATCH_REQUIRE(regex_validator->name() == "regex");
     398             : 
     399           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("@m2osw."));
     400           1 :         CATCH_REQUIRE(regex_validator->validate("contact@m2osw.com"));
     401           1 :         CATCH_REQUIRE(regex_validator->validate("Contact@m2osw.com"));
     402           1 :         CATCH_REQUIRE(regex_validator->validate("Contact@M2OSW.com"));
     403             : 
     404           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("contact@m2osw:com"));
     405           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("contact!m2osw.com"));
     406             :     CATCH_END_SECTION()
     407           4 : }
     408             : 
     409             : 
     410             : 
     411             : 
     412             : 
     413             : 
     414             : 
     415             : 
     416           8 : CATCH_TEST_CASE("invalid_validator", "[validator][invalid][validation]")
     417             : {
     418          12 :     CATCH_START_SECTION("Register duplicated factories")
     419           0 :         class duplicate_integer
     420             :             : public advgetopt::validator
     421             :         {
     422             :         public:
     423           0 :             virtual std::string const name() const
     424             :             {
     425           0 :                 return "integer";
     426             :             }
     427             : 
     428           0 :             virtual bool validate(std::string const & value) const override
     429             :             {
     430           0 :                 return value == "123";
     431             :             }
     432             :         };
     433           3 :         class duplicate_factory
     434             :             : public advgetopt::validator_factory
     435             :         {
     436             :         public:
     437           2 :             virtual std::string get_name() const
     438             :             {
     439           2 :                 return "integer";
     440             :             }
     441             : 
     442           0 :             virtual std::shared_ptr<advgetopt::validator> create(advgetopt::string_list_t const & data) const override
     443             :             {
     444           0 :                 snap::NOT_USED(data); // ignore `data`
     445           0 :                 return std::make_shared<duplicate_integer>();
     446             :             }
     447             :         };
     448           2 :         std::unique_ptr<advgetopt::validator_factory> factory(new duplicate_factory());
     449           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     450             :                   advgetopt::validator::register_validator(*factory.get())
     451             :                 , advgetopt::getopt_logic_error
     452             :                 , Catch::Matchers::ExceptionMessage(
     453             :                           "getopt_logic_error: you have two or more validator factories named \"integer\"."));
     454             :     CATCH_END_SECTION()
     455             : 
     456             : 
     457          12 :     CATCH_START_SECTION("Verify invalid ranges")
     458           1 :         advgetopt::string_list_t range{
     459             :             "abc",
     460             :             "abc...6",
     461             :             "3...def",
     462           2 :             "10...1"};
     463             : 
     464           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: abc is not a valid value for your ranges; it must only be digits, optionally preceeded by a sign (+ or -) and not overflow an int64_t value.");
     465           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: abc is not a valid value for your ranges; it must only be digits, optionally preceeded by a sign (+ or -) and not overflow an int64_t value.");
     466           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: def is not a valid value for your ranges; it must only be digits, optionally preceeded by a sign (+ or -) and not overflow an int64_t value.");
     467           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: 10 has to be smaller or equal to 1; you have an invalid range.");
     468             : 
     469           2 :         advgetopt::validator::pointer_t integer_validator(advgetopt::validator::create("integer", range));
     470           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     471             :     CATCH_END_SECTION()
     472             : 
     473          12 :     CATCH_START_SECTION("Verify invalid regex flags")
     474           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag f in regular expression \"/contact@.*\\..*/f\".");
     475             : 
     476           2 :         advgetopt::validator::pointer_t regex_validator(advgetopt::validator::create("regex", {"/contact@.*\\..*/f"}));
     477           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     478             : 
     479           1 :         CATCH_REQUIRE(regex_validator != nullptr);
     480           1 :         CATCH_REQUIRE(regex_validator->name() == "regex");
     481             : 
     482           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("@m2osw."));
     483           1 :         CATCH_REQUIRE(regex_validator->validate("contact@m2osw.com"));
     484           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("Contact@m2osw.com"));
     485           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("Contact@M2OSW.com"));
     486             : 
     487           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("contact@m2osw:com"));
     488           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("contact!m2osw.com"));
     489             :     CATCH_END_SECTION()
     490             : 
     491          12 :     CATCH_START_SECTION("Verify invalid regex flags")
     492           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag * in regular expression \"/contact@.*\\..*\".");
     493           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag . in regular expression \"/contact@.*\\..*\".");
     494           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag . in regular expression \"/contact@.*\\..*\".");
     495           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag \\ in regular expression \"/contact@.*\\..*\".");
     496           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag * in regular expression \"/contact@.*\\..*\".");
     497           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag . in regular expression \"/contact@.*\\..*\".");
     498           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag @ in regular expression \"/contact@.*\\..*\".");
     499           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag t in regular expression \"/contact@.*\\..*\".");
     500           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag c in regular expression \"/contact@.*\\..*\".");
     501           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag a in regular expression \"/contact@.*\\..*\".");
     502           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag t in regular expression \"/contact@.*\\..*\".");
     503           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag n in regular expression \"/contact@.*\\..*\".");
     504           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag o in regular expression \"/contact@.*\\..*\".");
     505           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: unsupported regex flag c in regular expression \"/contact@.*\\..*\".");
     506           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid regex definition, ending / is missing in \"/contact@.*\\..*\".");
     507             : 
     508           2 :         advgetopt::validator::pointer_t regex_validator(advgetopt::validator::create("regex", {"/contact@.*\\..*"}));
     509           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     510             : 
     511           1 :         CATCH_REQUIRE(regex_validator != nullptr);
     512           1 :         CATCH_REQUIRE(regex_validator->name() == "regex");
     513             : 
     514           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("@m2osw."));
     515           1 :         CATCH_REQUIRE(regex_validator->validate("contact@m2osw.com"));
     516           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("Contact@m2osw.com"));
     517           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("Contact@M2OSW.com"));
     518             : 
     519           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("contact@m2osw:com"));
     520           1 :         CATCH_REQUIRE_FALSE(regex_validator->validate("contact!m2osw.com"));
     521             :     CATCH_END_SECTION()
     522             : 
     523          12 :     CATCH_START_SECTION("Verify regex refuses more than one parameter")
     524           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log(
     525             :                           "error: validator_regex() only supports one parameter;"
     526             :                           " 2 were supplied;"
     527             :                           " single or double quotation may be required?");
     528           1 :         advgetopt::validator::create("regex", {"[a-z]+", "[0-9]+"});
     529           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     530             : 
     531           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log(
     532             :                           "error: validator_regex() only supports one parameter;"
     533             :                           " 2 were supplied;"
     534             :                           " single or double quotation may be required?");
     535           1 :         advgetopt::validator::create("regex([a-z]+, [0-9]+)");
     536           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     537             : 
     538           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log(
     539             :                           "error: validator_regex() only supports one parameter;"
     540             :                           " 3 were supplied;"
     541             :                           " single or double quotation may be required?");
     542           1 :         advgetopt::validator::create("regex", {"[a-z]+", "[0-9]+", "[#!@]"});
     543           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     544             : 
     545           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log(
     546             :                           "error: validator_regex() only supports one parameter;"
     547             :                           " 3 were supplied;"
     548             :                           " single or double quotation may be required?");
     549           1 :         advgetopt::validator::create("regex(\"[a-z]+\", \"[0-9]+\", \"[#!@]\")");
     550           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     551             :     CATCH_END_SECTION()
     552             : 
     553          12 :     CATCH_START_SECTION("Verify missing ')' in string based create")
     554           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     555             :                   advgetopt::validator::create("integer(1...7")
     556             :                 , advgetopt::getopt_logic_error
     557             :                 , Catch::Matchers::ExceptionMessage(
     558             :                           "getopt_logic_error: invalid validator parameter definition: \"integer(1...7\", the ')' is missing."));
     559             : 
     560           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     561             :                   advgetopt::validator::create("regex([a-z]+")
     562             :                 , advgetopt::getopt_logic_error
     563             :                 , Catch::Matchers::ExceptionMessage(
     564             :                           "getopt_logic_error: invalid validator parameter definition: \"regex([a-z]+\", the ')' is missing."));
     565             :     CATCH_END_SECTION()
     566          12 : }
     567             : 
     568             : 
     569             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13