LCOV - code coverage report
Current view: top level - tests - validator.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 261 271 96.3 %
Date: 2019-07-15 03:11:49 Functions: 11 17 64.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.12