LCOV - code coverage report
Current view: top level - tests - validator.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 259 271 95.6 %
Date: 2019-09-16 03:06:47 Functions: 11 17 64.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.12