LCOV - code coverage report
Current view: top level - tests - catch_option_info.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 994 994
Test Date: 2026-01-18 09:38:57 Functions: 100.0 % 20 20
Legend: Lines: hit not hit

            Line data    Source code
       1              : // Copyright (c) 2006-2025  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
      26              : //
      27              : #include    <advgetopt/exception.h>
      28              : 
      29              : 
      30              : // C++
      31              : //
      32              : #include    <fstream>
      33              : 
      34              : 
      35              : // last include
      36              : //
      37              : #include    <snapdev/poison.h>
      38              : 
      39              : 
      40              : 
      41              : 
      42              : 
      43            1 : CATCH_TEST_CASE("to_from_short_name", "[option_info][valid][basic][short_name]")
      44              : {
      45            1 :     CATCH_START_SECTION("to_from_short_name: short name to string and back")
      46              :     {
      47              :         // wc == U'\0' is a special case
      48              :         //
      49            1 :         CATCH_REQUIRE(advgetopt::NO_SHORT_NAME == U'\0');
      50            1 :         CATCH_REQUIRE(advgetopt::short_name_to_string(U'\0') == std::string());
      51            1 :         CATCH_REQUIRE(advgetopt::string_to_short_name(std::string()) == U'\0');
      52              : 
      53      1112064 :         for(char32_t wc(1); wc < 0x110000; ++wc)
      54              :         {
      55      1112063 :             if(wc == 0xD800)
      56              :             {
      57            1 :                 wc = 0xE000;
      58              :             }
      59      1112063 :             std::string str(advgetopt::short_name_to_string(wc));
      60      1112063 :             CATCH_REQUIRE(advgetopt::string_to_short_name(str) == wc);
      61              : 
      62              :             // add a second character to prove that string_to_short_name()
      63              :             // only works with one character
      64              :             //
      65      1112063 :             char32_t const second_char(rand() % (0xD800 - 0x20) + 0x20);
      66      1112063 :             str += advgetopt::short_name_to_string(second_char);
      67      1112063 :             CATCH_REQUIRE(advgetopt::string_to_short_name(str) == advgetopt::NO_SHORT_NAME);
      68      1112063 :         }
      69              :     }
      70            1 :     CATCH_END_SECTION()
      71            1 : }
      72              : 
      73              : 
      74            1 : CATCH_TEST_CASE("parsing_string", "[environment][valid]")
      75              : {
      76            1 :     CATCH_START_SECTION("parsing_string: test parsing of empty environment strings")
      77              :     {
      78            1 :         advgetopt::option const options[] =
      79              :         {
      80              :             advgetopt::define_option(
      81              :                   advgetopt::Name("empty")
      82              :                 , advgetopt::ShortName('e')
      83              :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
      84              :                 , advgetopt::Help("the empty option.")
      85              :             ),
      86              :             advgetopt::end_options()
      87              :         };
      88              : 
      89            1 :         advgetopt::options_environment environment_options;
      90            1 :         environment_options.f_project_name = "unittest";
      91            1 :         environment_options.f_options = options;
      92            1 :         environment_options.f_help_header = "Usage: test parse_string()";
      93              : 
      94            1 :         advgetopt::getopt opt(environment_options);
      95              : 
      96            7 :         CATCH_REQUIRE_THROWS_MATCHES(
      97              :                   opt.is_defined("invalid-parameter")
      98              :                 , advgetopt::getopt_initialization
      99              :                 , Catch::Matchers::ExceptionMessage(
     100              :                               "getopt_exception: function called too soon, parser is not done yet (i.e. is_defined(), get_string(), get_long(), get_double() cannot be called until the parser is done)"));
     101              : 
     102            3 :         opt.parse_string("");
     103              : 
     104              :         // a parse without anything means that we're still uninitialized
     105              :         //
     106            7 :         CATCH_REQUIRE_THROWS_MATCHES(
     107              :                   opt.is_defined("invalid-parameter")
     108              :                 , advgetopt::getopt_initialization
     109              :                 , Catch::Matchers::ExceptionMessage(
     110              :                               "getopt_exception: function called too soon, parser is not done yet (i.e. is_defined(), get_string(), get_long(), get_double() cannot be called until the parser is done)"));
     111            1 :     }
     112            1 :     CATCH_END_SECTION()
     113            1 : }
     114              : 
     115              : 
     116              : 
     117              : 
     118              : 
     119            3 : CATCH_TEST_CASE("option_info_basics", "[option_info][valid][basic]")
     120              : {
     121            3 :     CATCH_START_SECTION("option_info_basics: simple option (verify defaults)")
     122              :     {
     123            3 :         advgetopt::option_info verbose("verbose");
     124              : 
     125            1 :         CATCH_REQUIRE(verbose.get_name() == "verbose");
     126            1 :         CATCH_REQUIRE(verbose.get_short_name() == advgetopt::NO_SHORT_NAME);
     127            1 :         CATCH_REQUIRE_FALSE(verbose.is_default_option());
     128            1 :         CATCH_REQUIRE(verbose.get_flags() == 0);
     129              : 
     130            1 :         advgetopt::flag_t flag(1);
     131              :         do
     132              :         {
     133           32 :             CATCH_REQUIRE(verbose.has_flag(flag) == 0);
     134           32 :             flag <<= 1;
     135              :         }
     136           32 :         while(flag != 0);
     137              : 
     138            1 :         CATCH_REQUIRE_FALSE(verbose.has_default());
     139            1 :         CATCH_REQUIRE(verbose.get_default().empty());
     140            1 :         CATCH_REQUIRE(verbose.get_help().empty());
     141              : 
     142            1 :         CATCH_REQUIRE(verbose.get_alias_destination() == nullptr);
     143            1 :         CATCH_REQUIRE(verbose.get_multiple_separators().empty());
     144            1 :         CATCH_REQUIRE_FALSE(verbose.is_defined());
     145            1 :         CATCH_REQUIRE(verbose.size() == 0);
     146            1 :     }
     147            3 :     CATCH_END_SECTION()
     148              : 
     149            3 :     CATCH_START_SECTION("option_info_basics: auto-default")
     150              :     {
     151            3 :         advgetopt::option_info auto_default("--");
     152              : 
     153            1 :         CATCH_REQUIRE(auto_default.has_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION));
     154            1 :         CATCH_REQUIRE(auto_default.is_default_option());
     155              : 
     156            1 :         auto_default.add_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION);
     157              : 
     158            1 :         CATCH_REQUIRE(auto_default.has_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION));
     159            1 :         CATCH_REQUIRE(auto_default.is_default_option());
     160              : 
     161            1 :         auto_default.remove_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION);
     162              : 
     163            1 :         CATCH_REQUIRE_FALSE(auto_default.has_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION)); // unfortunate?
     164            1 :         CATCH_REQUIRE(auto_default.is_default_option());
     165            1 :     }
     166            3 :     CATCH_END_SECTION()
     167              : 
     168            3 :     CATCH_START_SECTION("option_info_basics: explicit default")
     169              :     {
     170            3 :         advgetopt::option_info explicit_default("filenames", 'f');
     171              : 
     172            1 :         CATCH_REQUIRE_FALSE(explicit_default.has_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION));
     173            1 :         CATCH_REQUIRE_FALSE(explicit_default.is_default_option());
     174              : 
     175            1 :         explicit_default.add_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION);
     176              : 
     177            1 :         CATCH_REQUIRE(explicit_default.has_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION));
     178            1 :         CATCH_REQUIRE(explicit_default.is_default_option());
     179              : 
     180            1 :         explicit_default.remove_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION);
     181              : 
     182            1 :         CATCH_REQUIRE_FALSE(explicit_default.has_flag(advgetopt::GETOPT_FLAG_DEFAULT_OPTION));
     183            1 :         CATCH_REQUIRE_FALSE(explicit_default.is_default_option());
     184            1 :     }
     185            3 :     CATCH_END_SECTION()
     186            3 : }
     187              : 
     188              : 
     189              : 
     190            1 : CATCH_TEST_CASE("option_info_flags", "[option_info][valid][flags]")
     191              : {
     192            1 :     CATCH_START_SECTION("option_info_flags: check flags")
     193              :     {
     194            3 :         advgetopt::option_info flags("flags", 'f');
     195              : 
     196            1 :         advgetopt::flag_t flag(1);
     197              :         do
     198              :         {
     199           32 :             CATCH_REQUIRE(flags.get_flags() == 0);
     200              : 
     201           32 :             advgetopt::flag_t clear(1);
     202              :             do
     203              :             {
     204         1024 :                 CATCH_REQUIRE_FALSE(flags.has_flag(clear));
     205         1024 :                 clear <<= 1;
     206              :             }
     207         1024 :             while(clear != 0);
     208              : 
     209           32 :             flags.add_flag(flag);
     210           32 :             CATCH_REQUIRE(flags.has_flag(flag));
     211           32 :             CATCH_REQUIRE(flags.get_flags() == flag);
     212              : 
     213           32 :             advgetopt::flag_t set(1);
     214              :             do
     215              :             {
     216         1024 :                 if(set == flag)
     217              :                 {
     218           32 :                     CATCH_REQUIRE(flags.has_flag(set));
     219              :                 }
     220              :                 else
     221              :                 {
     222          992 :                     CATCH_REQUIRE_FALSE(flags.has_flag(set));
     223              :                 }
     224         1024 :                 set <<= 1;
     225              :             }
     226         1024 :             while(set != 0);
     227              : 
     228           32 :             flags.remove_flag(flag);
     229           32 :             CATCH_REQUIRE(flags.get_flags() == 0);
     230              : 
     231           32 :             clear = 1;
     232              :             do
     233              :             {
     234         1024 :                 CATCH_REQUIRE_FALSE(flags.has_flag(clear));
     235         1024 :                 clear <<= 1;
     236              :             }
     237         1024 :             while(clear != 0);
     238              : 
     239           32 :             flag <<= 1;
     240              :         }
     241           32 :         while(flag != 0);
     242              : 
     243            1 :         flag = 1;
     244              :         do
     245              :         {
     246           32 :             CATCH_REQUIRE(flags.get_flags() == 0);
     247              : 
     248           32 :             advgetopt::flag_t clear(1);
     249              :             do
     250              :             {
     251         1024 :                 CATCH_REQUIRE_FALSE(flags.has_flag(clear));
     252         1024 :                 clear <<= 1;
     253              :             }
     254         1024 :             while(clear != 0);
     255              : 
     256           32 :             flags.set_flags(flag);
     257           32 :             CATCH_REQUIRE(flags.has_flag(flag));
     258           32 :             CATCH_REQUIRE(flags.get_flags() == flag);
     259              : 
     260           32 :             advgetopt::flag_t set(1);
     261              :             do
     262              :             {
     263         1024 :                 if(set == flag)
     264              :                 {
     265           32 :                     CATCH_REQUIRE(flags.has_flag(set));
     266              :                 }
     267              :                 else
     268              :                 {
     269          992 :                     CATCH_REQUIRE_FALSE(flags.has_flag(set));
     270              :                 }
     271         1024 :                 set <<= 1;
     272              :             }
     273         1024 :             while(set != 0);
     274              : 
     275           32 :             flags.set_flags(0);
     276           32 :             CATCH_REQUIRE(flags.get_flags() == 0);
     277              : 
     278           32 :             clear = 1;
     279              :             do
     280              :             {
     281         1024 :                 CATCH_REQUIRE_FALSE(flags.has_flag(clear));
     282         1024 :                 clear <<= 1;
     283              :             }
     284         1024 :             while(clear != 0);
     285              : 
     286           32 :             flag <<= 1;
     287              :         }
     288           32 :         while(flag != 0);
     289            1 :     }
     290            1 :     CATCH_END_SECTION()
     291            1 : }
     292              : 
     293              : 
     294              : 
     295            1 : CATCH_TEST_CASE("option_info_default", "[option_info][valid][default]")
     296              : {
     297            1 :     CATCH_START_SECTION("option_info_default: set/remove default")
     298              :     {
     299            3 :         advgetopt::option_info with_default("with_default", 'w');
     300              : 
     301            1 :         CATCH_REQUIRE_FALSE(with_default.has_default());
     302            1 :         CATCH_REQUIRE_FALSE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
     303            1 :         CATCH_REQUIRE(with_default.get_default().empty());
     304              : 
     305            1 :         with_default.set_default("working");
     306            1 :         CATCH_REQUIRE(with_default.has_default());
     307            1 :         CATCH_REQUIRE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
     308            1 :         CATCH_REQUIRE(with_default.get_default() == "working");
     309              : 
     310            1 :         with_default.remove_default();
     311            1 :         CATCH_REQUIRE_FALSE(with_default.has_default());
     312            1 :         CATCH_REQUIRE_FALSE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
     313            1 :         CATCH_REQUIRE(with_default.get_default().empty());
     314              : 
     315            3 :         std::string const default_value("other");
     316            1 :         with_default.set_default(default_value);
     317            1 :         CATCH_REQUIRE(with_default.has_default());
     318            1 :         CATCH_REQUIRE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
     319            1 :         CATCH_REQUIRE(with_default.get_default() == default_value);
     320              : 
     321            1 :         with_default.remove_default();
     322            1 :         CATCH_REQUIRE_FALSE(with_default.has_default());
     323            1 :         CATCH_REQUIRE_FALSE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
     324            1 :         CATCH_REQUIRE(with_default.get_default().empty());
     325              : 
     326            1 :         std::string const empty_default;
     327            1 :         with_default.set_default(empty_default);
     328            1 :         CATCH_REQUIRE(with_default.has_default());
     329            1 :         CATCH_REQUIRE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
     330            1 :         CATCH_REQUIRE(with_default.get_default().empty());
     331              : 
     332            1 :         with_default.remove_default();
     333            1 :         CATCH_REQUIRE_FALSE(with_default.has_default());
     334            1 :         CATCH_REQUIRE_FALSE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
     335            1 :         CATCH_REQUIRE(with_default.get_default().empty());
     336              : 
     337            1 :         with_default.set_default(nullptr); // no effects
     338            1 :         CATCH_REQUIRE_FALSE(with_default.has_default());
     339            1 :         CATCH_REQUIRE_FALSE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
     340            1 :         CATCH_REQUIRE(with_default.get_default().empty());
     341              : 
     342            3 :         std::string const null_value("null works too");
     343            1 :         with_default.set_default(null_value);
     344            1 :         CATCH_REQUIRE(with_default.has_default());
     345            1 :         CATCH_REQUIRE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
     346            1 :         CATCH_REQUIRE(with_default.get_default() == null_value);
     347              : 
     348            1 :         with_default.set_default(nullptr); // no effects
     349            1 :         CATCH_REQUIRE(with_default.has_default());
     350            1 :         CATCH_REQUIRE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
     351            1 :         CATCH_REQUIRE(with_default.get_default() == null_value);
     352              : 
     353            1 :         with_default.remove_default();
     354            1 :         CATCH_REQUIRE_FALSE(with_default.has_default());
     355            1 :         CATCH_REQUIRE_FALSE(with_default.has_flag(advgetopt::GETOPT_FLAG_HAS_DEFAULT));
     356            1 :         CATCH_REQUIRE(with_default.get_default().empty());
     357            1 :     }
     358            1 :     CATCH_END_SECTION()
     359            1 : }
     360              : 
     361              : 
     362              : 
     363            1 : CATCH_TEST_CASE("option_info_help", "[option_info][valid][help]")
     364              : {
     365            1 :     CATCH_START_SECTION("option_info_help: check help")
     366              :     {
     367            3 :         advgetopt::option_info help("help", 'h');
     368              : 
     369            1 :         CATCH_REQUIRE(help.get_help().empty());
     370              : 
     371            1 :         help.set_help("help me");
     372            1 :         CATCH_REQUIRE(help.get_help() == "help me");
     373              : 
     374            3 :         std::string const msg("help msg");
     375            1 :         help.set_help(msg);
     376            1 :         CATCH_REQUIRE(help.get_help() == msg);
     377              : 
     378            1 :         help.set_help(nullptr);
     379            1 :         CATCH_REQUIRE(help.get_help() == msg);
     380              : 
     381            1 :         help.set_help("");
     382            1 :         CATCH_REQUIRE(help.get_help().empty());
     383            1 :     }
     384            1 :     CATCH_END_SECTION()
     385            1 : }
     386              : 
     387              : 
     388              : 
     389            4 : CATCH_TEST_CASE("option_info_validator", "[option_info][valid][validator]")
     390              : {
     391            4 :     CATCH_START_SECTION("option_info_validator: check validator (one value)")
     392              :     {
     393            3 :         advgetopt::option_info auto_validate("validator", 'C');
     394            1 :         auto_validate.set_flags(advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION);
     395              : 
     396            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     397              : 
     398            3 :         auto_validate.set_value(0, "51");
     399            1 :         CATCH_REQUIRE(auto_validate.size() == 1);
     400            1 :         CATCH_REQUIRE(auto_validate.get_value(0) == "51");
     401            1 :         CATCH_REQUIRE(auto_validate.get_long(0) == 51);
     402            1 :         CATCH_REQUIRE(auto_validate.source() == advgetopt::option_source_t::SOURCE_DIRECT);
     403              : 
     404            1 :         auto_validate.set_validator(nullptr);
     405            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     406              : 
     407            5 :         advgetopt::validator::pointer_t integer_validator(advgetopt::validator::create("integer", {"1","2","5","6","8"}));
     408            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"51\" given to parameter --validator is not considered valid: out of range.");
     409            1 :         auto_validate.set_validator(integer_validator);
     410            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     411            1 :         CATCH_REQUIRE(auto_validate.get_validator() == integer_validator);
     412              : 
     413            3 :         auto_validate.set_value(0, "6", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_DYNAMIC);
     414            1 :         CATCH_REQUIRE(auto_validate.source() == advgetopt::option_source_t::SOURCE_DYNAMIC);
     415              : 
     416            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"3\" given to parameter --validator is not considered valid: out of range.");
     417            3 :         auto_validate.set_value(0, "3", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_CONFIGURATION);
     418            1 :         CATCH_REQUIRE(auto_validate.source() == advgetopt::option_source_t::SOURCE_UNDEFINED);    // it doesn't take... it gets cleared though
     419            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     420              : 
     421            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"11\" given to parameter --validator is not considered valid: out of range.");
     422            3 :         auto_validate.set_value(0, "11", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_ENVIRONMENT_VARIABLE);
     423            1 :         CATCH_REQUIRE(auto_validate.source() == advgetopt::option_source_t::SOURCE_UNDEFINED);    // it doesn't take... it gets cleared though
     424            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     425            1 :     }
     426            4 :     CATCH_END_SECTION()
     427              : 
     428            4 :     CATCH_START_SECTION("option_info_validator: check validator (multiple values)")
     429              :     {
     430            3 :         advgetopt::option_info auto_validate("validator", 'C');
     431              : 
     432            1 :         auto_validate.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
     433              : 
     434            5 :         advgetopt::string_list_t list{","};
     435            1 :         auto_validate.set_multiple_separators(list);
     436              : 
     437            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     438              : 
     439            3 :         auto_validate.set_value(0, "-15", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     440            1 :         CATCH_REQUIRE(auto_validate.size() == 1);
     441            1 :         CATCH_REQUIRE(auto_validate.get_value(0) == "-15");
     442            1 :         CATCH_REQUIRE(auto_validate.get_long(0) == -15);
     443              : 
     444            1 :         auto_validate.set_validator(nullptr);
     445            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     446              : 
     447            5 :         advgetopt::validator::pointer_t integer_validator(advgetopt::validator::create("integer", {"-1","2","5","6","18"}));
     448            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"-15\" given to parameter --validator is not considered valid: out of range.");
     449            1 :         auto_validate.set_validator(integer_validator);
     450            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     451            1 :         CATCH_REQUIRE(auto_validate.get_validator() == integer_validator);
     452              : 
     453            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"3\" given to parameter --validator is not considered valid: out of range.");
     454            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"11\" given to parameter --validator is not considered valid: out of range.");
     455            3 :         CATCH_REQUIRE_FALSE(auto_validate.set_multiple_values("6,3,18,11", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     456            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     457            1 :         CATCH_REQUIRE(auto_validate.size() == 2);
     458            1 :         CATCH_REQUIRE(auto_validate.get_value(0) == "6");
     459            1 :         CATCH_REQUIRE(auto_validate.get_long(0) == 6);
     460            1 :         CATCH_REQUIRE(auto_validate.get_value(1) == "18");
     461            1 :         CATCH_REQUIRE(auto_validate.get_long(1) == 18);
     462              : 
     463            1 :         auto_validate.set_validator(nullptr);
     464            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     465              : 
     466            3 :         CATCH_REQUIRE(auto_validate.set_multiple_values("6,3,18,11", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     467            1 :         CATCH_REQUIRE(auto_validate.size() == 4);
     468            1 :         CATCH_REQUIRE(auto_validate.get_value(0) == "6");
     469            1 :         CATCH_REQUIRE(auto_validate.get_long(0) == 6);
     470            1 :         CATCH_REQUIRE(auto_validate.get_value(1) == "3");
     471            1 :         CATCH_REQUIRE(auto_validate.get_long(1) == 3);
     472            1 :         CATCH_REQUIRE(auto_validate.get_value(2) == "18");
     473            1 :         CATCH_REQUIRE(auto_validate.get_long(2) == 18);
     474            1 :         CATCH_REQUIRE(auto_validate.get_value(3) == "11");
     475            1 :         CATCH_REQUIRE(auto_validate.get_long(3) == 11);
     476            1 :     }
     477            4 :     CATCH_END_SECTION()
     478              : 
     479            4 :     CATCH_START_SECTION("option_info_validator: check integer validator from string (multiple values)")
     480              :     {
     481            3 :         advgetopt::option_info auto_validate("validator", 'C');
     482              : 
     483            1 :         auto_validate.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
     484              : 
     485            5 :         advgetopt::string_list_t list{","};
     486            1 :         auto_validate.set_multiple_separators(list);
     487              : 
     488            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     489              : 
     490            3 :         auto_validate.set_value(0, "35", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     491            1 :         CATCH_REQUIRE(auto_validate.size() == 1);
     492            1 :         CATCH_REQUIRE(auto_validate.get_value(0) == "35");
     493            1 :         CATCH_REQUIRE(auto_validate.get_long(0) == 35);
     494              : 
     495            1 :         auto_validate.set_validator(nullptr);
     496            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     497              : 
     498            1 :         auto_validate.set_validator(std::string());
     499            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     500              : 
     501            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"35\" given to parameter --validator is not considered valid: out of range.");
     502            3 :         auto_validate.set_validator("integer(-1,2,5,6,18,51966)");
     503            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     504            1 :         CATCH_REQUIRE(auto_validate.get_validator() != nullptr);
     505            1 :         CATCH_REQUIRE(auto_validate.get_validator()->name() == "integer");
     506              : 
     507              :         // test with the lowercase introducer
     508              :         //
     509            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"0b11\" given to parameter --validator is not considered valid: out of range.");
     510            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"0o13\" given to parameter --validator is not considered valid: out of range.");
     511            3 :         CATCH_REQUIRE_FALSE(auto_validate.set_multiple_values("0d6,0b11,0x12,0o13,0xcafe", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     512            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     513            1 :         CATCH_REQUIRE(auto_validate.size() == 3);
     514            1 :         CATCH_REQUIRE(auto_validate.get_value(0) == "0d6");
     515            1 :         CATCH_REQUIRE(auto_validate.get_long(0) == 6);
     516            1 :         CATCH_REQUIRE(auto_validate.get_value(1) == "0x12");
     517            1 :         CATCH_REQUIRE(auto_validate.get_long(1) == 18);
     518            1 :         CATCH_REQUIRE(auto_validate.get_value(2) == "0xcafe");
     519            1 :         CATCH_REQUIRE(auto_validate.get_long(2) == 51966);
     520              : 
     521              :         // test with the uppercase introducer
     522              :         //
     523            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"0B11\" given to parameter --validator is not considered valid: out of range.");
     524            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"0O13\" given to parameter --validator is not considered valid: out of range.");
     525            3 :         CATCH_REQUIRE_FALSE(auto_validate.set_multiple_values("0D6,0B11,0X12,0O13,0XCAFE", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     526            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     527            1 :         CATCH_REQUIRE(auto_validate.size() == 3);
     528            1 :         CATCH_REQUIRE(auto_validate.get_value(0) == "0D6");
     529            1 :         CATCH_REQUIRE(auto_validate.get_long(0) == 6);
     530            1 :         CATCH_REQUIRE(auto_validate.get_value(1) == "0X12");
     531            1 :         CATCH_REQUIRE(auto_validate.get_long(1) == 18);
     532            1 :         CATCH_REQUIRE(auto_validate.get_value(2) == "0XCAFE");
     533            1 :         CATCH_REQUIRE(auto_validate.get_long(2) == 51966);
     534              : 
     535            1 :         auto_validate.set_validator(std::string());
     536            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     537              : 
     538              :         // here, however, we cannot use the introducer
     539              :         //
     540            3 :         CATCH_REQUIRE(auto_validate.set_multiple_values("6,3,18,11", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     541            1 :         CATCH_REQUIRE(auto_validate.size() == 4);
     542            1 :         CATCH_REQUIRE(auto_validate.get_value(0) == "6");
     543            1 :         CATCH_REQUIRE(auto_validate.get_long(0) == 6);
     544            1 :         CATCH_REQUIRE(auto_validate.get_value(1) == "3");
     545            1 :         CATCH_REQUIRE(auto_validate.get_long(1) == 3);
     546            1 :         CATCH_REQUIRE(auto_validate.get_value(2) == "18");
     547            1 :         CATCH_REQUIRE(auto_validate.get_long(2) == 18);
     548            1 :         CATCH_REQUIRE(auto_validate.get_value(3) == "11");
     549            1 :         CATCH_REQUIRE(auto_validate.get_long(3) == 11);
     550            1 :     }
     551            4 :     CATCH_END_SECTION()
     552              : 
     553            4 :     CATCH_START_SECTION("option_info_validator: check regex validator from string (multiple values)")
     554              :     {
     555            3 :         advgetopt::option_info auto_validate("validator", 'C');
     556              : 
     557            1 :         auto_validate.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
     558              : 
     559            5 :         advgetopt::string_list_t list{","};
     560            1 :         auto_validate.set_multiple_separators(list);
     561              : 
     562            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     563              : 
     564            3 :         auto_validate.set_value(0, "abc", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     565            1 :         CATCH_REQUIRE(auto_validate.size() == 1);
     566            1 :         CATCH_REQUIRE(auto_validate.get_value(0) == "abc");
     567              : 
     568            1 :         auto_validate.set_validator(nullptr);
     569            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     570              : 
     571            1 :         auto_validate.set_validator(std::string());
     572            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     573              : 
     574            3 :         auto_validate.set_validator("/^[a-z]+$/");
     575            1 :         CATCH_REQUIRE(auto_validate.get_validator() != nullptr);
     576            1 :         CATCH_REQUIRE(auto_validate.get_validator()->name() == "regex");
     577              : 
     578            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"33\" given to parameter --validator is not considered valid: did not match the regex.");
     579            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: input \"45\" given to parameter --validator is not considered valid: did not match the regex.");
     580            3 :         CATCH_REQUIRE_FALSE(auto_validate.set_multiple_values("abc,qqq,33,zac,pop,45", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     581            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     582            1 :         CATCH_REQUIRE(auto_validate.size() == 4);
     583            1 :         CATCH_REQUIRE(auto_validate.get_value(0) == "abc");
     584            1 :         CATCH_REQUIRE(auto_validate.get_value(1) == "qqq");
     585            1 :         CATCH_REQUIRE(auto_validate.get_value(2) == "zac");
     586            1 :         CATCH_REQUIRE(auto_validate.get_value(3) == "pop");
     587              : 
     588            1 :         auto_validate.set_validator(std::string());
     589            1 :         CATCH_REQUIRE(auto_validate.get_validator() == nullptr);
     590              : 
     591            3 :         CATCH_REQUIRE(auto_validate.set_multiple_values("abc,-56,zoc", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     592            1 :         CATCH_REQUIRE(auto_validate.size() == 3);
     593            1 :         CATCH_REQUIRE(auto_validate.get_value(0) == "abc");
     594            1 :         CATCH_REQUIRE(auto_validate.get_value(1) == "-56");
     595            1 :         CATCH_REQUIRE(auto_validate.get_value(2) == "zoc");
     596            1 :     }
     597            4 :     CATCH_END_SECTION()
     598           13 : }
     599              : 
     600              : 
     601              : 
     602              : 
     603            1 : CATCH_TEST_CASE("option_info_alias", "[option_info][valid][alias]")
     604              : {
     605            1 :     CATCH_START_SECTION("option_info_alias: check alias")
     606              :     {
     607            1 :         advgetopt::option_info::pointer_t option(std::make_shared<advgetopt::option_info>("option", 'o'));
     608            3 :         advgetopt::option_info alias("alias", 'a');
     609              : 
     610            1 :         CATCH_REQUIRE(alias.get_alias_destination() == nullptr);
     611              : 
     612            1 :         alias.set_alias_destination(option);
     613              : 
     614            1 :         CATCH_REQUIRE(alias.get_alias_destination() == option);
     615            1 :     }
     616            1 :     CATCH_END_SECTION()
     617            1 : }
     618              : 
     619              : 
     620              : 
     621            1 : CATCH_TEST_CASE("option_info_multiple_separators", "[option_info][valid][separators][multiple]")
     622              : {
     623            1 :     CATCH_START_SECTION("option_info_multiple_separators: check multiple separators")
     624              :     {
     625            3 :         advgetopt::option_info separators("names", 'n');
     626              : 
     627            1 :         separators.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
     628              : 
     629            1 :         CATCH_REQUIRE(separators.get_multiple_separators().empty());
     630              : 
     631            1 :         separators.set_multiple_separators(nullptr);
     632            1 :         CATCH_REQUIRE(separators.get_multiple_separators().empty());
     633              : 
     634            3 :         CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     635            1 :         CATCH_REQUIRE(separators.size() == 1);
     636            1 :         CATCH_REQUIRE(separators.get_value(0) == "n1,n2;n3 n4 ^ n5");
     637              : 
     638            1 :         advgetopt::string_list_t empty_list;
     639            1 :         separators.set_multiple_separators(empty_list);
     640            1 :         CATCH_REQUIRE(separators.get_multiple_separators().empty());
     641              : 
     642            3 :         CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     643            1 :         CATCH_REQUIRE(separators.size() == 1);
     644            1 :         CATCH_REQUIRE(separators.get_value(0) == "n1,n2;n3 n4 ^ n5");
     645              : 
     646            1 :         char const * const empty_separator_list[]{
     647              :             nullptr
     648              :         };
     649            1 :         separators.set_multiple_separators(empty_separator_list);
     650            1 :         CATCH_REQUIRE(separators.get_multiple_separators().empty());
     651              : 
     652            3 :         CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     653            1 :         CATCH_REQUIRE(separators.size() == 1);
     654            1 :         CATCH_REQUIRE(separators.get_value(0) == "n1,n2;n3 n4 ^ n5");
     655              : 
     656            1 :         char const * const separator_list[]{
     657              :             ",",
     658              :             ";",
     659              :             " ",
     660              :             "^",
     661              :             nullptr
     662              :         };
     663            1 :         separators.set_multiple_separators(separator_list);
     664            1 :         CATCH_REQUIRE(separators.get_multiple_separators().size() == 4);
     665              : 
     666            3 :         CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     667            1 :         CATCH_REQUIRE(separators.size() == 5);
     668            1 :         CATCH_REQUIRE(separators.get_value(0) == "n1");
     669            1 :         CATCH_REQUIRE(separators.get_value(1) == "n2");
     670            1 :         CATCH_REQUIRE(separators.get_value(2) == "n3");
     671            1 :         CATCH_REQUIRE(separators.get_value(3) == "n4");
     672            1 :         CATCH_REQUIRE(separators.get_value(4) == "n5");
     673              : 
     674            1 :         separators.set_multiple_separators(empty_separator_list);
     675            1 :         CATCH_REQUIRE(separators.get_multiple_separators().empty());
     676              : 
     677            3 :         CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     678            1 :         CATCH_REQUIRE(separators.size() == 1);
     679            1 :         CATCH_REQUIRE(separators.get_value(0) == "n1,n2;n3 n4 ^ n5");
     680              : 
     681            1 :         advgetopt::string_list_t list{
     682              :             ",",
     683              :             ";",
     684              :             " ",
     685              :             "^",
     686            8 :         };
     687            1 :         separators.set_multiple_separators(list);
     688            1 :         CATCH_REQUIRE(separators.get_multiple_separators().size() == 4);
     689              : 
     690            3 :         CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     691            1 :         CATCH_REQUIRE(separators.size() == 5);
     692            1 :         CATCH_REQUIRE(separators.get_value(0) == "n1");
     693            1 :         CATCH_REQUIRE(separators.get_value(1) == "n2");
     694            1 :         CATCH_REQUIRE(separators.get_value(2) == "n3");
     695            1 :         CATCH_REQUIRE(separators.get_value(3) == "n4");
     696            1 :         CATCH_REQUIRE(separators.get_value(4) == "n5");
     697              : 
     698            1 :         separators.set_multiple_separators(empty_list);
     699            1 :         CATCH_REQUIRE(separators.get_multiple_separators().empty());
     700              : 
     701            3 :         CATCH_REQUIRE(separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE));
     702            1 :         CATCH_REQUIRE(separators.size() == 1);
     703            1 :         CATCH_REQUIRE(separators.get_value(0) == "n1,n2;n3 n4 ^ n5");
     704            1 :     }
     705            1 :     CATCH_END_SECTION()
     706            4 : }
     707              : 
     708              : 
     709              : 
     710            4 : CATCH_TEST_CASE("option_info_add_value", "[option_info][valid][add][multiple]")
     711              : {
     712            4 :     CATCH_START_SECTION("option_info_add_value: add value, verify lock (add/remove flag explicitly)")
     713              :     {
     714            3 :         advgetopt::option_info one_value("names", 'n');
     715              : 
     716            1 :         CATCH_REQUIRE(one_value.size() == 0);
     717              : 
     718            3 :         one_value.add_value("value one", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     719            1 :         CATCH_REQUIRE(one_value.size() == 1);
     720            1 :         CATCH_REQUIRE(one_value.get_value(0) == "value one");
     721              : 
     722            3 :         one_value.add_value("value two", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     723            1 :         CATCH_REQUIRE(one_value.size() == 1);
     724            1 :         CATCH_REQUIRE(one_value.get_value(0) == "value two");
     725              : 
     726            1 :         one_value.add_flag(advgetopt::GETOPT_FLAG_LOCK);
     727              : 
     728            3 :         one_value.add_value("value three", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     729            1 :         CATCH_REQUIRE(one_value.size() == 1);
     730            1 :         CATCH_REQUIRE(one_value.get_value(0) == "value two");
     731              : 
     732            1 :         one_value.remove_flag(advgetopt::GETOPT_FLAG_LOCK);
     733              : 
     734            3 :         one_value.add_value("value four", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     735            1 :         CATCH_REQUIRE(one_value.size() == 1);
     736            1 :         CATCH_REQUIRE(one_value.get_value(0) == "value four");
     737              : 
     738            1 :         one_value.reset();
     739            1 :         CATCH_REQUIRE(one_value.size() == 0);
     740              : 
     741              :         // to verify that the f_integer was reset we kind of very much
     742              :         // have to re-add a value
     743              :         //
     744            3 :         one_value.set_value(0, "value one", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     745            1 :         CATCH_REQUIRE(one_value.size() == 1);
     746            1 :         CATCH_REQUIRE(one_value.get_value(0) == "value one");
     747            1 :     }
     748            4 :     CATCH_END_SECTION()
     749              : 
     750            4 :     CATCH_START_SECTION("option_info_add_value: add value, verify integer")
     751              :     {
     752            3 :         advgetopt::option_info one_value("names", 'n');
     753              : 
     754            1 :         CATCH_REQUIRE(one_value.size() == 0);
     755              : 
     756            3 :         one_value.add_value("123", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     757            1 :         CATCH_REQUIRE(one_value.size() == 1);
     758            1 :         CATCH_REQUIRE(one_value.get_value(0) == "123");
     759            1 :         CATCH_REQUIRE(one_value.get_long(0) == 123);
     760              : 
     761            3 :         one_value.add_value("456", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     762            1 :         CATCH_REQUIRE(one_value.size() == 1);
     763            1 :         CATCH_REQUIRE(one_value.get_value(0) == "456");
     764            1 :         CATCH_REQUIRE(one_value.get_long(0) == 456);
     765              : 
     766            1 :         one_value.add_flag(advgetopt::GETOPT_FLAG_LOCK);
     767              : 
     768            3 :         one_value.add_value("789", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     769            1 :         CATCH_REQUIRE(one_value.size() == 1);
     770            1 :         CATCH_REQUIRE(one_value.get_value(0) == "456");
     771            1 :         CATCH_REQUIRE(one_value.get_long(0) == 456);
     772              : 
     773            1 :         one_value.remove_flag(advgetopt::GETOPT_FLAG_LOCK);
     774              : 
     775            3 :         one_value.add_value("505", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     776            1 :         CATCH_REQUIRE(one_value.size() == 1);
     777            1 :         CATCH_REQUIRE(one_value.get_value(0) == "505");
     778            1 :         CATCH_REQUIRE(one_value.get_long(0) == 505);
     779              : 
     780            1 :         one_value.reset();
     781            1 :         CATCH_REQUIRE(one_value.size() == 0);
     782              : 
     783              :         // to verify that the f_integer was reset we kind of very much
     784              :         // have to re-add a value
     785              :         //
     786            3 :         one_value.set_value(0, "123", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     787            1 :         CATCH_REQUIRE(one_value.size() == 1);
     788            1 :         CATCH_REQUIRE(one_value.get_value(0) == "123");
     789            1 :         CATCH_REQUIRE(one_value.get_long(0) == 123);
     790            1 :     }
     791            4 :     CATCH_END_SECTION()
     792              : 
     793            4 :     CATCH_START_SECTION("option_info_add_value: add value, verify multiple strings")
     794              :     {
     795            3 :         advgetopt::option_info multi_value("names", 'n');
     796              : 
     797            1 :         CATCH_REQUIRE(multi_value.size() == 0);
     798              : 
     799            1 :         multi_value.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
     800              : 
     801            3 :         multi_value.add_value("value one", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     802            1 :         CATCH_REQUIRE(multi_value.size() == 1);
     803            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "value one");
     804              : 
     805            3 :         multi_value.add_value("value two", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     806            1 :         CATCH_REQUIRE(multi_value.size() == 2);
     807            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "value one");
     808            1 :         CATCH_REQUIRE(multi_value.get_value(1) == "value two");
     809              : 
     810            1 :         multi_value.add_flag(advgetopt::GETOPT_FLAG_LOCK);
     811              : 
     812            3 :         multi_value.add_value("value three", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     813            1 :         CATCH_REQUIRE(multi_value.size() == 2);
     814            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "value one");
     815            1 :         CATCH_REQUIRE(multi_value.get_value(1) == "value two");
     816              : 
     817            1 :         multi_value.remove_flag(advgetopt::GETOPT_FLAG_LOCK);
     818              : 
     819            3 :         multi_value.add_value("value four", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     820            1 :         CATCH_REQUIRE(multi_value.size() == 3);
     821            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "value one");
     822            1 :         CATCH_REQUIRE(multi_value.get_value(1) == "value two");
     823            1 :         CATCH_REQUIRE(multi_value.get_value(2) == "value four");
     824              : 
     825            1 :         multi_value.reset();
     826            1 :         CATCH_REQUIRE(multi_value.size() == 0);
     827              : 
     828              :         // to verify that the f_integer was reset we kind of very much
     829              :         // have to re-add a value
     830              :         //
     831            3 :         multi_value.set_value(0, "value one", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     832            1 :         CATCH_REQUIRE(multi_value.size() == 1);
     833            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "value one");
     834            1 :     }
     835            4 :     CATCH_END_SECTION()
     836              : 
     837            4 :     CATCH_START_SECTION("option_info_add_value: add value, verify multiple integers")
     838              :     {
     839            3 :         advgetopt::option_info multi_value("names", 'n');
     840              : 
     841            1 :         CATCH_REQUIRE(multi_value.size() == 0);
     842              : 
     843            1 :         multi_value.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
     844              : 
     845            3 :         multi_value.add_value("123", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     846            1 :         CATCH_REQUIRE(multi_value.size() == 1);
     847            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "123");
     848            1 :         CATCH_REQUIRE(multi_value.get_long(0) == 123);
     849              : 
     850            3 :         multi_value.add_value("456", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     851            1 :         CATCH_REQUIRE(multi_value.size() == 2);
     852            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "123");
     853            1 :         CATCH_REQUIRE(multi_value.get_long(0) == 123);
     854            1 :         CATCH_REQUIRE(multi_value.get_value(1) == "456");
     855            1 :         CATCH_REQUIRE(multi_value.get_long(1) == 456);
     856              : 
     857            1 :         multi_value.add_flag(advgetopt::GETOPT_FLAG_LOCK);
     858              : 
     859            3 :         multi_value.add_value("789", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     860            1 :         CATCH_REQUIRE(multi_value.size() == 2);
     861            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "123");
     862            1 :         CATCH_REQUIRE(multi_value.get_long(0) == 123);
     863            1 :         CATCH_REQUIRE(multi_value.get_value(1) == "456");
     864            1 :         CATCH_REQUIRE(multi_value.get_long(1) == 456);
     865              : 
     866            1 :         multi_value.remove_flag(advgetopt::GETOPT_FLAG_LOCK);
     867              : 
     868            3 :         multi_value.add_value("505", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     869            1 :         CATCH_REQUIRE(multi_value.size() == 3);
     870            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "123");
     871            1 :         CATCH_REQUIRE(multi_value.get_long(0) == 123);
     872            1 :         CATCH_REQUIRE(multi_value.get_value(1) == "456");
     873            1 :         CATCH_REQUIRE(multi_value.get_long(1) == 456);
     874            1 :         CATCH_REQUIRE(multi_value.get_value(2) == "505");
     875            1 :         CATCH_REQUIRE(multi_value.get_long(2) == 505);
     876              : 
     877            1 :         multi_value.reset();
     878            1 :         CATCH_REQUIRE(multi_value.size() == 0);
     879              : 
     880              :         // to verify that the f_integer was reset we kind of very much
     881              :         // have to re-add a value
     882              :         //
     883            3 :         multi_value.set_value(0, "123", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     884            1 :         CATCH_REQUIRE(multi_value.size() == 1);
     885            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "123");
     886            1 :         CATCH_REQUIRE(multi_value.get_long(0) == 123);
     887            1 :     }
     888            4 :     CATCH_END_SECTION()
     889            4 : }
     890              : 
     891              : 
     892              : 
     893            4 : CATCH_TEST_CASE("option_info_set_value", "[option_info][valid][set][multiple]")
     894              : {
     895            4 :     CATCH_START_SECTION("option_info_set_value: set value, verify lock (use lock()/unlock() functions)")
     896              :     {
     897            3 :         advgetopt::option_info one_value("names", 'n');
     898              : 
     899            1 :         CATCH_REQUIRE(one_value.size() == 0);
     900              : 
     901            3 :         one_value.set_value(0, "value one", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     902            1 :         CATCH_REQUIRE(one_value.size() == 1);
     903            1 :         CATCH_REQUIRE(one_value.get_value(0) == "value one");
     904              : 
     905            3 :         one_value.set_value(0, "value two", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     906            1 :         CATCH_REQUIRE(one_value.size() == 1);
     907            1 :         CATCH_REQUIRE(one_value.get_value(0) == "value two");
     908              : 
     909            1 :         one_value.lock();
     910              : 
     911            3 :         one_value.set_value(0, "value three", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     912            1 :         CATCH_REQUIRE(one_value.size() == 1);
     913            1 :         CATCH_REQUIRE(one_value.get_value(0) == "value two");
     914              : 
     915            1 :         one_value.unlock();
     916              : 
     917            3 :         one_value.set_value(0, "value four", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     918            1 :         CATCH_REQUIRE(one_value.size() == 1);
     919            1 :         CATCH_REQUIRE(one_value.get_value(0) == "value four");
     920              : 
     921            1 :         one_value.reset();
     922            1 :         CATCH_REQUIRE(one_value.size() == 0);
     923              : 
     924              :         // to verify that the f_integer was reset we kind of very much
     925              :         // have to re-add a value
     926              :         //
     927            3 :         one_value.set_value(0, "value one", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     928            1 :         CATCH_REQUIRE(one_value.size() == 1);
     929            1 :         CATCH_REQUIRE(one_value.get_value(0) == "value one");
     930            1 :     }
     931            4 :     CATCH_END_SECTION()
     932              : 
     933            4 :     CATCH_START_SECTION("option_info_set_value: set value, verify integer")
     934              :     {
     935            3 :         advgetopt::option_info one_value("names", 'n');
     936              : 
     937            1 :         CATCH_REQUIRE(one_value.size() == 0);
     938              : 
     939            3 :         one_value.set_value(0, "123", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     940            1 :         CATCH_REQUIRE(one_value.size() == 1);
     941            1 :         CATCH_REQUIRE(one_value.get_value(0) == "123");
     942            1 :         CATCH_REQUIRE(one_value.get_long(0) == 123);
     943              : 
     944            3 :         one_value.set_value(0, "456", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     945            1 :         CATCH_REQUIRE(one_value.size() == 1);
     946            1 :         CATCH_REQUIRE(one_value.get_value(0) == "456");
     947            1 :         CATCH_REQUIRE(one_value.get_long(0) == 456);
     948              : 
     949            1 :         one_value.lock();
     950              : 
     951            3 :         one_value.set_value(0, "789", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     952            1 :         CATCH_REQUIRE(one_value.size() == 1);
     953            1 :         CATCH_REQUIRE(one_value.get_value(0) == "456");
     954            1 :         CATCH_REQUIRE(one_value.get_long(0) == 456);
     955              : 
     956            1 :         one_value.unlock();
     957              : 
     958            3 :         one_value.set_value(0, "505", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     959            1 :         CATCH_REQUIRE(one_value.size() == 1);
     960            1 :         CATCH_REQUIRE(one_value.get_value(0) == "505");
     961            1 :         CATCH_REQUIRE(one_value.get_long(0) == 505);
     962              : 
     963            1 :         one_value.reset();
     964            1 :         CATCH_REQUIRE(one_value.size() == 0);
     965              : 
     966              :         // to verify that the f_integer was reset we kind of very much
     967              :         // have to re-add a value
     968              :         //
     969            3 :         one_value.set_value(0, "123", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     970            1 :         CATCH_REQUIRE(one_value.size() == 1);
     971            1 :         CATCH_REQUIRE(one_value.get_value(0) == "123");
     972            1 :         CATCH_REQUIRE(one_value.get_long(0) == 123);
     973            1 :     }
     974            4 :     CATCH_END_SECTION()
     975              : 
     976            4 :     CATCH_START_SECTION("option_info_set_value: set value, verify multiple strings (with MULTIPLE & lock(false))")
     977              :     {
     978            3 :         advgetopt::option_info multi_value("names", 'n');
     979              : 
     980            1 :         multi_value.lock(false);
     981              : 
     982            1 :         CATCH_REQUIRE(multi_value.size() == 0);
     983              : 
     984            1 :         multi_value.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
     985              : 
     986            3 :         multi_value.set_value(0, "value one", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     987            1 :         CATCH_REQUIRE(multi_value.size() == 1);
     988            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "value one");
     989              : 
     990            3 :         multi_value.set_value(1, "value two", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     991            1 :         CATCH_REQUIRE(multi_value.size() == 2);
     992            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "value one");
     993            1 :         CATCH_REQUIRE(multi_value.get_value(1) == "value two");
     994              : 
     995            1 :         multi_value.lock(false);
     996              : 
     997            3 :         multi_value.set_value(2, "value three", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     998            1 :         CATCH_REQUIRE(multi_value.size() == 2);
     999            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "value one");
    1000            1 :         CATCH_REQUIRE(multi_value.get_value(1) == "value two");
    1001              : 
    1002            1 :         multi_value.unlock();
    1003              : 
    1004            3 :         multi_value.set_value(2, "value four", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1005            1 :         CATCH_REQUIRE(multi_value.size() == 3);
    1006            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "value one");
    1007            1 :         CATCH_REQUIRE(multi_value.get_value(1) == "value two");
    1008            1 :         CATCH_REQUIRE(multi_value.get_value(2) == "value four");
    1009              : 
    1010            1 :         multi_value.reset();
    1011            1 :         CATCH_REQUIRE(multi_value.size() == 0);
    1012              : 
    1013              :         // to verify that the f_integer was reset we kind of very much
    1014              :         // have to re-add a value
    1015              :         //
    1016            3 :         multi_value.set_value(0, "value one", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1017            1 :         CATCH_REQUIRE(multi_value.size() == 1);
    1018            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "value one");
    1019            1 :     }
    1020            4 :     CATCH_END_SECTION()
    1021              : 
    1022            4 :     CATCH_START_SECTION("option_info_set_value: set value, verify multiple integers (with MULTIPLE & lock(false))")
    1023              :     {
    1024            3 :         advgetopt::option_info multi_value("names", 'n');
    1025              : 
    1026            1 :         CATCH_REQUIRE(multi_value.size() == 0);
    1027              : 
    1028            1 :         multi_value.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
    1029              : 
    1030            1 :         multi_value.lock(false);
    1031              : 
    1032            3 :         multi_value.set_value(0, "123", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1033            1 :         CATCH_REQUIRE(multi_value.size() == 1);
    1034            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "123");
    1035            1 :         CATCH_REQUIRE(multi_value.get_long(0) == 123);
    1036              : 
    1037            3 :         multi_value.set_value(1, "456", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1038            1 :         CATCH_REQUIRE(multi_value.size() == 2);
    1039            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "123");
    1040            1 :         CATCH_REQUIRE(multi_value.get_long(0) == 123);
    1041            1 :         CATCH_REQUIRE(multi_value.get_value(1) == "456");
    1042            1 :         CATCH_REQUIRE(multi_value.get_long(1) == 456);
    1043              : 
    1044            1 :         multi_value.lock(false);
    1045              : 
    1046            3 :         multi_value.set_value(2, "789", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1047            1 :         CATCH_REQUIRE(multi_value.size() == 2);
    1048            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "123");
    1049            1 :         CATCH_REQUIRE(multi_value.get_long(0) == 123);
    1050            1 :         CATCH_REQUIRE(multi_value.get_value(1) == "456");
    1051            1 :         CATCH_REQUIRE(multi_value.get_long(1) == 456);
    1052              : 
    1053            1 :         multi_value.unlock();
    1054              : 
    1055            3 :         multi_value.set_value(2, "505", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1056            1 :         CATCH_REQUIRE(multi_value.size() == 3);
    1057            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "123");
    1058            1 :         CATCH_REQUIRE(multi_value.get_long(0) == 123);
    1059            1 :         CATCH_REQUIRE(multi_value.get_value(1) == "456");
    1060            1 :         CATCH_REQUIRE(multi_value.get_long(1) == 456);
    1061            1 :         CATCH_REQUIRE(multi_value.get_value(2) == "505");
    1062            1 :         CATCH_REQUIRE(multi_value.get_long(2) == 505);
    1063              : 
    1064            1 :         multi_value.reset();
    1065            1 :         CATCH_REQUIRE(multi_value.size() == 0);
    1066              : 
    1067              :         // to verify that the f_integer was reset we kind of very much
    1068              :         // have to re-add a value
    1069              :         //
    1070            3 :         multi_value.set_value(0, "123", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1071            1 :         CATCH_REQUIRE(multi_value.size() == 1);
    1072            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "123");
    1073            1 :         CATCH_REQUIRE(multi_value.get_long(0) == 123);
    1074            1 :     }
    1075            4 :     CATCH_END_SECTION()
    1076            4 : }
    1077              : 
    1078              : 
    1079              : 
    1080            4 : CATCH_TEST_CASE("option_info_section_functions", "[option_info][valid][add][section]")
    1081              : {
    1082            4 :     CATCH_START_SECTION("option_info_section_functions: value without sections")
    1083              :     {
    1084            3 :         advgetopt::option_info value("no-sections", 'z');
    1085              : 
    1086            1 :         CATCH_REQUIRE(value.get_basename() == "no-sections");
    1087            1 :         CATCH_REQUIRE(value.get_section_name() == std::string());
    1088            1 :         CATCH_REQUIRE(value.get_section_name_list().empty());
    1089            1 :     }
    1090            4 :     CATCH_END_SECTION()
    1091              : 
    1092            4 :     CATCH_START_SECTION("option_info_section_functions: value with one section")
    1093              :     {
    1094            3 :         advgetopt::option_info value("one::section", 'o');
    1095              : 
    1096            1 :         CATCH_REQUIRE(value.get_basename() == "section");
    1097            1 :         CATCH_REQUIRE(value.get_section_name() == "one");
    1098            1 :         advgetopt::string_list_t sections(value.get_section_name_list());
    1099            1 :         CATCH_REQUIRE(sections.size() == 1);
    1100            1 :         CATCH_REQUIRE(sections[0] == "one");
    1101            1 :     }
    1102            4 :     CATCH_END_SECTION()
    1103              : 
    1104            4 :     CATCH_START_SECTION("option_info_section_functions: value with two sections")
    1105              :     {
    1106            3 :         advgetopt::option_info value("one::two::section", 't');
    1107              : 
    1108            1 :         CATCH_REQUIRE(value.get_basename() == "section");
    1109            1 :         CATCH_REQUIRE(value.get_section_name() == "one::two");
    1110            1 :         advgetopt::string_list_t sections(value.get_section_name_list());
    1111            1 :         CATCH_REQUIRE(sections.size() == 2);
    1112            1 :         CATCH_REQUIRE(sections[0] == "one");
    1113            1 :         CATCH_REQUIRE(sections[1] == "two");
    1114            1 :     }
    1115            4 :     CATCH_END_SECTION()
    1116              : 
    1117            4 :     CATCH_START_SECTION("option_info_section_functions: value with three sections")
    1118              :     {
    1119            3 :         advgetopt::option_info value("s1::s2::s3::section", 'f');
    1120              : 
    1121            1 :         CATCH_REQUIRE(value.get_basename() == "section");
    1122            1 :         CATCH_REQUIRE(value.get_section_name() == "s1::s2::s3");
    1123            1 :         advgetopt::string_list_t sections(value.get_section_name_list());
    1124            1 :         CATCH_REQUIRE(sections.size() == 3);
    1125            1 :         CATCH_REQUIRE(sections[0] == "s1");
    1126            1 :         CATCH_REQUIRE(sections[1] == "s2");
    1127            1 :         CATCH_REQUIRE(sections[2] == "s3");
    1128            1 :     }
    1129            4 :     CATCH_END_SECTION()
    1130            4 : }
    1131              : 
    1132              : 
    1133              : 
    1134              : 
    1135            1 : CATCH_TEST_CASE("redefine_option_short_name", "[options][valid][config]")
    1136              : {
    1137            1 :     CATCH_START_SECTION("redefine_option_short_name: test adding '-<delta>' to '--config-dir'")
    1138              :     {
    1139            1 :         advgetopt::option const options[] =
    1140              :         {
    1141              :             advgetopt::define_option(
    1142              :                   advgetopt::Name("group")
    1143              :                 , advgetopt::ShortName('g')
    1144              :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1145              :                 , advgetopt::Help("group name.")
    1146              :             ),
    1147              :             advgetopt::end_options()
    1148              :         };
    1149              : 
    1150            1 :         advgetopt::options_environment environment_options;
    1151            1 :         environment_options.f_project_name = "unittest";
    1152            1 :         environment_options.f_options = options;
    1153            1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
    1154            1 :         environment_options.f_configuration_filename = "snaplog.conf";
    1155            1 :         environment_options.f_help_header = "Usage: test --config-dir";
    1156              : 
    1157            1 :         char const * cargv[] =
    1158              :         {
    1159              :             "/usr/bin/arguments",
    1160              :             "-g",
    1161              :             "m2osw",
    1162              :             "-L",
    1163              :             "-\xE2\xB5\xA0",        // Delta character
    1164              :             "/opt/advgetopt/config",
    1165              :             nullptr
    1166              :         };
    1167            1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
    1168            1 :         char ** argv = const_cast<char **>(cargv);
    1169              : 
    1170            1 :         advgetopt::getopt opt(environment_options);
    1171            1 :         opt.parse_program_name(argv);
    1172              : 
    1173            3 :         CATCH_REQUIRE(opt.get_option("config-dir") != nullptr);
    1174            5 :         CATCH_REQUIRE(opt.get_option("config-dir") == opt.get_option("config_dir"));
    1175            3 :         opt.set_short_name("config-dir", 0x2D60);
    1176              : 
    1177            1 :         opt.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1178              : 
    1179              :         // check that the result is valid
    1180              : 
    1181              :         // an invalid parameter, MUST NOT EXIST
    1182            3 :         CATCH_REQUIRE(opt.get_option("invalid-parameter") == nullptr);
    1183            5 :         CATCH_REQUIRE(opt.get_option("invalid-parameter") == opt.get_option("invalid_parameter"));
    1184            1 :         CATCH_REQUIRE(opt.get_option('Z') == nullptr);
    1185            3 :         CATCH_REQUIRE_FALSE(opt.is_defined("invalid-parameter"));
    1186            3 :         CATCH_REQUIRE(opt.get_default("invalid-parameter").empty());
    1187            3 :         CATCH_REQUIRE(opt.size("invalid-parameter") == 0);
    1188              : 
    1189              :         // the valid parameter
    1190            3 :         CATCH_REQUIRE(opt.get_option("group") != nullptr);
    1191            3 :         CATCH_REQUIRE(opt.get_option('g') == opt.get_option("group"));
    1192            3 :         CATCH_REQUIRE(opt.is_defined("group"));
    1193            3 :         CATCH_REQUIRE(opt.get_string("group") == "m2osw");
    1194            3 :         CATCH_REQUIRE(opt.get_string("group", 0) == "m2osw");
    1195            3 :         CATCH_REQUIRE(opt.get_default("group").empty());
    1196            3 :         CATCH_REQUIRE(opt.size("group") == 1);
    1197              : 
    1198              :         // the license system parameter
    1199            3 :         CATCH_REQUIRE(opt.get_option("license") != nullptr);
    1200            3 :         CATCH_REQUIRE(opt.get_option('L') == opt.get_option("license"));
    1201            3 :         CATCH_REQUIRE(opt.is_defined("license"));
    1202            3 :         CATCH_REQUIRE(opt.get_default("license").empty());
    1203            3 :         CATCH_REQUIRE(opt.size("license") == 1);
    1204              : 
    1205              :         // the config-dir system parameter
    1206            3 :         CATCH_REQUIRE(opt.get_option("config-dir") != nullptr);
    1207            3 :         CATCH_REQUIRE(opt.get_option(static_cast<advgetopt::short_name_t>(0x2D60)) == opt.get_option("config-dir"));
    1208            3 :         CATCH_REQUIRE(opt.is_defined("config-dir"));
    1209            3 :         CATCH_REQUIRE(opt.get_default("config-dir").empty());
    1210            3 :         CATCH_REQUIRE(opt.size("config-dir") == 1);
    1211            3 :         CATCH_REQUIRE(opt.get_string("config-dir") == "/opt/advgetopt/config");
    1212              : 
    1213              :         // other parameters
    1214            1 :         CATCH_REQUIRE(opt.get_program_name() == "arguments");
    1215            1 :         CATCH_REQUIRE(opt.get_program_fullname() == "/usr/bin/arguments");
    1216            1 :     }
    1217            1 :     CATCH_END_SECTION()
    1218            1 : }
    1219              : 
    1220              : 
    1221              : 
    1222              : 
    1223              : 
    1224              : 
    1225              : 
    1226              : 
    1227              : 
    1228           17 : CATCH_TEST_CASE("invalid_option_info", "[option_info][invalid]")
    1229              : {
    1230           17 :     CATCH_START_SECTION("invalid_option_info: no name")
    1231              :     {
    1232            8 :         CATCH_REQUIRE_THROWS_MATCHES(
    1233              :                   advgetopt::option_info("")
    1234              :                 , advgetopt::getopt_logic_error
    1235              :                 , Catch::Matchers::ExceptionMessage(
    1236              :                           "getopt_logic_error: option_info::option_info(): all options must at least have a long name."));
    1237              : 
    1238            8 :         CATCH_REQUIRE_THROWS_MATCHES(
    1239              :                   advgetopt::option_info("", 'v')
    1240              :                 , advgetopt::getopt_logic_error
    1241              :                 , Catch::Matchers::ExceptionMessage(
    1242              :                           "getopt_logic_error: option_info::option_info(): all options must at least have a long name (short name: 'v'.)"));
    1243              : 
    1244            6 :         CATCH_REQUIRE_THROWS_MATCHES(
    1245              :                   advgetopt::option_info(std::string())
    1246              :                 , advgetopt::getopt_logic_error
    1247              :                 , Catch::Matchers::ExceptionMessage(
    1248              :                           "getopt_logic_error: option_info::option_info(): all options must at least have a long name."));
    1249              : 
    1250            6 :         CATCH_REQUIRE_THROWS_MATCHES(
    1251              :                   advgetopt::option_info(std::string(), 'p')
    1252              :                 , advgetopt::getopt_logic_error
    1253              :                 , Catch::Matchers::ExceptionMessage(
    1254              :                           "getopt_logic_error: option_info::option_info(): all options must at least have a long name (short name: 'p'.)"));
    1255              :     }
    1256           17 :     CATCH_END_SECTION()
    1257              : 
    1258           17 :     CATCH_START_SECTION("invalid_option_info: default with short name")
    1259              :     {
    1260            8 :         CATCH_REQUIRE_THROWS_MATCHES(
    1261              :                   advgetopt::option_info("--", 'f')
    1262              :                 , advgetopt::getopt_logic_error
    1263              :                 , Catch::Matchers::ExceptionMessage(
    1264              :                           "getopt_logic_error: option_info::option_info(): the default parameter \"--\" cannot include a short name ('f'.)"));
    1265              :     }
    1266           17 :     CATCH_END_SECTION()
    1267              : 
    1268           17 :     CATCH_START_SECTION("invalid_option_info: long name cannot start with a dash (-)")
    1269              :     {
    1270            8 :         CATCH_REQUIRE_THROWS_MATCHES(
    1271              :                   advgetopt::option_info("--dashes")
    1272              :                 , advgetopt::getopt_logic_error
    1273              :                 , Catch::Matchers::ExceptionMessage(
    1274              :                           "getopt_logic_error: option_info::option_info(): an option cannot start with a dash (-), \"--dashes\" is not valid."));
    1275              :     }
    1276           17 :     CATCH_END_SECTION()
    1277              : 
    1278           17 :     CATCH_START_SECTION("invalid_option_info: short name cannot be a dash (-)")
    1279              :     {
    1280            8 :         CATCH_REQUIRE_THROWS_MATCHES(
    1281              :                   advgetopt::option_info("dash", '-')
    1282              :                 , advgetopt::getopt_logic_error
    1283              :                 , Catch::Matchers::ExceptionMessage(
    1284              :                           "getopt_logic_error: option_info::option_info(): the short name of an option cannot be the dash (-)."));
    1285              :     }
    1286           17 :     CATCH_END_SECTION()
    1287              : 
    1288           17 :     CATCH_START_SECTION("invalid_option_info: set value with undefined source")
    1289              :     {
    1290            3 :         advgetopt::option_info verbose("verbose", 'v');
    1291            9 :         CATCH_REQUIRE_THROWS_MATCHES(
    1292              :                   verbose.set_value(0, "true", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_UNDEFINED)
    1293              :                 , advgetopt::getopt_logic_error
    1294              :                 , Catch::Matchers::ExceptionMessage(
    1295              :                           "getopt_logic_error: option_info::set_value(): called with SOURCE_UNDEFINED (5)."));
    1296            1 :     }
    1297           17 :     CATCH_END_SECTION()
    1298              : 
    1299           17 :     CATCH_START_SECTION("invalid_option_info: set multiple values with undefined source")
    1300              :     {
    1301            3 :         advgetopt::option_info verbose("verbose", 'v');
    1302            9 :         CATCH_REQUIRE_THROWS_MATCHES(
    1303              :                   verbose.set_multiple_values("a,b,c", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_UNDEFINED)
    1304              :                 , advgetopt::getopt_logic_error
    1305              :                 , Catch::Matchers::ExceptionMessage(
    1306              :                           "getopt_logic_error: option_info::set_multiple_values(): called with SOURCE_UNDEFINED (5)."));
    1307            1 :     }
    1308           17 :     CATCH_END_SECTION()
    1309              : 
    1310           17 :     CATCH_START_SECTION("invalid_option_info: get value when undefined")
    1311              :     {
    1312            3 :         advgetopt::option_info verbose("verbose", 'v');
    1313            4 :         CATCH_REQUIRE_THROWS_MATCHES(
    1314              :                   verbose.get_value()
    1315              :                 , advgetopt::getopt_undefined
    1316              :                 , Catch::Matchers::ExceptionMessage(
    1317              :                           "getopt_exception: option_info::get_value(): no value at index 0 (idx >= 0) for --verbose so you can't get this value."));
    1318            1 :     }
    1319           17 :     CATCH_END_SECTION()
    1320              : 
    1321           17 :     CATCH_START_SECTION("invalid_option_info: get long when undefined")
    1322              :     {
    1323            3 :         advgetopt::option_info verbose("verbose", 'v');
    1324            3 :         CATCH_REQUIRE_THROWS_MATCHES(
    1325              :                   verbose.get_long()
    1326              :                 , advgetopt::getopt_undefined
    1327              :                 , Catch::Matchers::ExceptionMessage(
    1328              :                           "getopt_exception: option_info::get_long(): no value at index 0 (idx >= 0) for --verbose so you can't get this value."));
    1329            1 :     }
    1330           17 :     CATCH_END_SECTION()
    1331              : 
    1332           17 :     CATCH_START_SECTION("invalid_option_info: get long when undefined")
    1333              :     {
    1334            3 :         advgetopt::option_info verbose("verbose", 'v');
    1335            3 :         CATCH_REQUIRE_THROWS_MATCHES(
    1336              :                   verbose.get_double()
    1337              :                 , advgetopt::getopt_undefined
    1338              :                 , Catch::Matchers::ExceptionMessage(
    1339              :                           "getopt_exception: option_info::get_double(): no value at index 0 (idx >= 0) for --verbose so you can't get this value."));
    1340            1 :     }
    1341           17 :     CATCH_END_SECTION()
    1342              : 
    1343           17 :     CATCH_START_SECTION("invalid_option_info: check alias of alias")
    1344              :     {
    1345            1 :         advgetopt::option_info::pointer_t option(std::make_shared<advgetopt::option_info>("option", 'o'));
    1346            3 :         advgetopt::option_info alias("alias", 'a');
    1347              : 
    1348            1 :         option->add_flag(advgetopt::GETOPT_FLAG_ALIAS);
    1349              : 
    1350            1 :         CATCH_REQUIRE(alias.get_alias_destination() == nullptr);
    1351              : 
    1352            5 :         CATCH_REQUIRE_THROWS_MATCHES(
    1353              :                   alias.set_alias_destination(option)
    1354              :                 , advgetopt::getopt_invalid
    1355              :                 , Catch::Matchers::ExceptionMessage(
    1356              :                           "getopt_exception: option_info::set_alias(): you can't set an alias as"
    1357              :                           " an alias of another option."));
    1358              : 
    1359            1 :         CATCH_REQUIRE(alias.get_alias_destination() == nullptr);
    1360            1 :     }
    1361           17 :     CATCH_END_SECTION()
    1362              : 
    1363           17 :     CATCH_START_SECTION("invalid_option_info: set value, verify multiple strings (with MULTIPLE)")
    1364              :     {
    1365            3 :         advgetopt::option_info multi_value("names", 'n');
    1366              : 
    1367            1 :         multi_value.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
    1368              : 
    1369            1 :         CATCH_REQUIRE(multi_value.size() == 0);
    1370              : 
    1371            3 :         multi_value.set_value(0, "value one", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1372            1 :         CATCH_REQUIRE(multi_value.size() == 1);
    1373            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "value one");
    1374            1 :         CATCH_REQUIRE(multi_value.source() == advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1375              : 
    1376            9 :         CATCH_REQUIRE_THROWS_MATCHES(
    1377              :                   multi_value.set_value(2, "value two", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE)
    1378              :                 , advgetopt::getopt_logic_error
    1379              :                 , Catch::Matchers::ExceptionMessage(
    1380              :                     "getopt_logic_error: option_info::set_value(): no value at index 2 and it is not the last available index + 1 (idx > 1) so you can't set this value (try add_value() maybe?)."));
    1381              : 
    1382            1 :         CATCH_REQUIRE(multi_value.size() == 1);
    1383            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "value one");
    1384            1 :     }
    1385           17 :     CATCH_END_SECTION()
    1386              : 
    1387           17 :     CATCH_START_SECTION("invalid_option_info: set value, verify multiple integers (with MULTIPLE)")
    1388              :     {
    1389            3 :         advgetopt::option_info multi_value("names", 'n');
    1390              : 
    1391            1 :         multi_value.add_flag(advgetopt::GETOPT_FLAG_MULTIPLE);
    1392              : 
    1393            1 :         CATCH_REQUIRE(multi_value.size() == 0);
    1394              : 
    1395            3 :         multi_value.set_value(0, "123", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1396            1 :         CATCH_REQUIRE(multi_value.size() == 1);
    1397            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "123");
    1398            1 :         CATCH_REQUIRE(multi_value.get_long(0) == 123);
    1399              : 
    1400            9 :         CATCH_REQUIRE_THROWS_MATCHES(
    1401              :                   multi_value.set_value(2, "456", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE)
    1402              :                 , advgetopt::getopt_logic_error
    1403              :                 , Catch::Matchers::ExceptionMessage(
    1404              :                     "getopt_logic_error: option_info::set_value(): no value at index 2 and it is not the last available index + 1 (idx > 1) so you can't set this value (try add_value() maybe?)."));
    1405              : 
    1406            1 :         CATCH_REQUIRE(multi_value.size() == 1);
    1407            1 :         CATCH_REQUIRE(multi_value.get_value(0) == "123");
    1408            1 :         CATCH_REQUIRE(multi_value.get_long(0) == 123);
    1409            1 :     }
    1410           17 :     CATCH_END_SECTION()
    1411              : 
    1412           17 :     CATCH_START_SECTION("invalid_option_info: set value, verify multiple strings (without MULTIPLE)")
    1413              :     {
    1414            3 :         advgetopt::option_info one_value("names", 'n');
    1415              : 
    1416            1 :         CATCH_REQUIRE(one_value.size() == 0);
    1417              : 
    1418            3 :         one_value.set_value(0, "value one", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1419            1 :         CATCH_REQUIRE(one_value.size() == 1);
    1420            1 :         CATCH_REQUIRE(one_value.get_value(0) == "value one");
    1421              : 
    1422            9 :         CATCH_REQUIRE_THROWS_MATCHES(
    1423              :                   one_value.set_value(1, "value two", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE)
    1424              :                 , advgetopt::getopt_logic_error
    1425              :                 , Catch::Matchers::ExceptionMessage(
    1426              :                     "getopt_logic_error: option_info::set_value(): single value option \"--names\" does not accepts index 1 which is not 0."));
    1427              : 
    1428            1 :         CATCH_REQUIRE(one_value.size() == 1);
    1429            1 :         CATCH_REQUIRE(one_value.get_value(0) == "value one");
    1430            1 :     }
    1431           17 :     CATCH_END_SECTION()
    1432              : 
    1433           17 :     CATCH_START_SECTION("invalid_option_info: set value, verify multiple integers (without MULTIPLE)")
    1434              :     {
    1435            3 :         advgetopt::option_info one_value("names", 'n');
    1436              : 
    1437            1 :         CATCH_REQUIRE(one_value.size() == 0);
    1438              : 
    1439            3 :         one_value.set_value(0, "123", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1440            1 :         CATCH_REQUIRE(one_value.size() == 1);
    1441            1 :         CATCH_REQUIRE(one_value.get_value(0) == "123");
    1442            1 :         CATCH_REQUIRE(one_value.get_long(0) == 123);
    1443              : 
    1444            9 :         CATCH_REQUIRE_THROWS_MATCHES(
    1445              :                   one_value.set_value(1, "456", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE)
    1446              :                 , advgetopt::getopt_logic_error
    1447              :                 , Catch::Matchers::ExceptionMessage(
    1448              :                     "getopt_logic_error: option_info::set_value(): single value option \"--names\" does not accepts index 1 which is not 0."));
    1449              : 
    1450            1 :         CATCH_REQUIRE(one_value.size() == 1);
    1451            1 :         CATCH_REQUIRE(one_value.get_value(0) == "123");
    1452            1 :         CATCH_REQUIRE(one_value.get_long(0) == 123);
    1453            1 :     }
    1454           17 :     CATCH_END_SECTION()
    1455              : 
    1456           17 :     CATCH_START_SECTION("invalid_option_info: long number too large")
    1457              :     {
    1458            3 :         advgetopt::option_info size("size", 's');
    1459              : 
    1460            1 :         CATCH_REQUIRE(size.size() == 0);
    1461              : 
    1462              :         // really too large
    1463              :         //
    1464            3 :         size.set_value(0, "100000000000000000000", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1465            1 :         CATCH_REQUIRE(size.size() == 1);
    1466            1 :         CATCH_REQUIRE(size.get_value(0) == "100000000000000000000");
    1467              : 
    1468            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid number (100000000000000000000) in parameter --size at offset 0.");
    1469            1 :         CATCH_REQUIRE(size.get_long(0) == -1);
    1470            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1471              : 
    1472              :         // too large by 1
    1473              :         //
    1474            3 :         size.set_value(0, "9223372036854775808", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1475            1 :         CATCH_REQUIRE(size.size() == 1);
    1476            1 :         CATCH_REQUIRE(size.get_value(0) == "9223372036854775808");
    1477              : 
    1478            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid number (9223372036854775808) in parameter --size at offset 0.");
    1479            1 :         CATCH_REQUIRE(size.get_long(0) == -1);
    1480            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1481              : 
    1482              :         // too small by 1
    1483              :         //
    1484            3 :         size.set_value(0, "-9223372036854775809", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1485            1 :         CATCH_REQUIRE(size.size() == 1);
    1486            1 :         CATCH_REQUIRE(size.get_value(0) == "-9223372036854775809");
    1487              : 
    1488            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid number (-9223372036854775809) in parameter --size at offset 0.");
    1489            1 :         CATCH_REQUIRE(size.get_long(0) == -1);
    1490            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1491              : 
    1492              :         // not a valid number
    1493              :         //
    1494            3 :         size.set_value(0, "97 potatoes", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE);
    1495            1 :         CATCH_REQUIRE(size.size() == 1);
    1496            1 :         CATCH_REQUIRE(size.get_value(0) == "97 potatoes");
    1497              : 
    1498            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid number (97 potatoes) in parameter --size at offset 0.");
    1499            1 :         CATCH_REQUIRE(size.get_long(0) == -1);
    1500            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1501            1 :     }
    1502           17 :     CATCH_END_SECTION()
    1503              : 
    1504           17 :     CATCH_START_SECTION("invalid_option_info: check multiple separators")
    1505              :     {
    1506            3 :         advgetopt::option_info separators("names", 'n');
    1507              : 
    1508            1 :         advgetopt::string_list_t list{
    1509              :             ",",
    1510              :             ";",
    1511              :             " ",
    1512              :             "^"
    1513            8 :         };
    1514            1 :         separators.set_multiple_separators(list);
    1515              : 
    1516            9 :         CATCH_REQUIRE_THROWS_MATCHES(
    1517              :                   separators.set_multiple_values("n1,n2;n3 n4 ^ n5", advgetopt::string_list_t(), advgetopt::option_source_t::SOURCE_COMMAND_LINE)
    1518              :                 , advgetopt::getopt_logic_error
    1519              :                 , Catch::Matchers::ExceptionMessage(
    1520              :                     "getopt_logic_error: option_info::set_multiple_value(): parameter --names expects zero or one parameter."
    1521              :                     " The set_multiple_value() function should not be called with parameters that only accept one value."));
    1522              : 
    1523            1 :         CATCH_REQUIRE(separators.size() == 0);
    1524            1 :     }
    1525           17 :     CATCH_END_SECTION()
    1526              : 
    1527           17 :     CATCH_START_SECTION("invalid_option_info: check invalid parameter (missing ')')")
    1528              :     {
    1529            3 :         advgetopt::option_info auto_validate("validator", 'C');
    1530            3 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: validator(): parameter list must end with ')'. Remaining input: \"...EOS\"");
    1531            3 :         auto_validate.set_validator("regex('^[a-z]+$/'");
    1532            1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1533            1 :     }
    1534           17 :     CATCH_END_SECTION()
    1535           20 : }
    1536              : 
    1537              : 
    1538              : 
    1539              : 
    1540            2 : CATCH_TEST_CASE("check_invalid_config_dir_short_names", "[arguments][invalid][getopt][config]")
    1541              : {
    1542            2 :     CATCH_START_SECTION("check_invalid_config_dir_short_names: trying to set NO_SHORT_NAME as '--config-dir' short name (option_info)")
    1543              :     {
    1544            1 :         advgetopt::option const options[] =
    1545              :         {
    1546              :             advgetopt::define_option(
    1547              :                   advgetopt::Name("print")
    1548              :                 , advgetopt::ShortName(U'p')
    1549              :                 , advgetopt::Flags(advgetopt::command_flags<>())
    1550              :                 , advgetopt::Help("output filename.")
    1551              :             ),
    1552              :             advgetopt::end_options()
    1553              :         };
    1554              : 
    1555            1 :         advgetopt::options_environment environment_options;
    1556            1 :         environment_options.f_project_name = "unittest";
    1557            1 :         environment_options.f_options = options;
    1558            1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
    1559            1 :         environment_options.f_environment_variable_name = "ADVGETOPT_TEST_OPTIONS";
    1560            1 :         environment_options.f_configuration_filename = "snapwatchdog.conf";
    1561            1 :         environment_options.f_help_header = "Usage: test --config-dir";
    1562              : 
    1563            1 :         advgetopt::getopt opt(environment_options);
    1564              : 
    1565            3 :         advgetopt::option_info::pointer_t o(opt.get_option("config-dir"));
    1566            1 :         CATCH_REQUIRE(o != nullptr);
    1567            1 :         CATCH_REQUIRE(o->get_short_name() == advgetopt::NO_SHORT_NAME);
    1568              : 
    1569            3 :         opt.set_short_name("config-dir", advgetopt::NO_SHORT_NAME);
    1570            1 :         CATCH_REQUIRE(o->get_short_name() == advgetopt::NO_SHORT_NAME);
    1571            1 :     }
    1572            2 :     CATCH_END_SECTION()
    1573              : 
    1574            2 :     CATCH_START_SECTION("check_invalid_config_dir_short_names: trying to change short name of '--version' (option_info)")
    1575              :     {
    1576            1 :         advgetopt::option const options[] =
    1577              :         {
    1578              :             advgetopt::define_option(
    1579              :                   advgetopt::Name("print")
    1580              :                 , advgetopt::ShortName('p')
    1581              :                 , advgetopt::Flags(advgetopt::command_flags<>())
    1582              :                 , advgetopt::Help("print all info.")
    1583              :             ),
    1584              :             advgetopt::end_options()
    1585              :         };
    1586              : 
    1587            1 :         advgetopt::options_environment environment_options;
    1588            1 :         environment_options.f_project_name = "unittest";
    1589            1 :         environment_options.f_options = options;
    1590            1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
    1591            1 :         environment_options.f_configuration_filename = "";
    1592            1 :         environment_options.f_help_header = "Usage: test --config-dir";
    1593              : 
    1594            1 :         advgetopt::getopt opt(environment_options);
    1595              : 
    1596            3 :         advgetopt::option_info::pointer_t o(opt.get_option("version"));
    1597            1 :         CATCH_REQUIRE(o != nullptr);
    1598            1 :         CATCH_REQUIRE(o->get_short_name() == U'V');
    1599            1 :         CATCH_REQUIRE(o == opt.get_option(U'V'));
    1600            1 :         CATCH_REQUIRE(opt.get_option(U'v') == nullptr);
    1601              : 
    1602            3 :         opt.set_short_name("version", U'V');   // keep uppercase...
    1603            1 :         CATCH_REQUIRE(o->get_short_name() == U'V');
    1604            1 :         CATCH_REQUIRE(o == opt.get_option(U'V'));
    1605            1 :         CATCH_REQUIRE(opt.get_option(U'v') == nullptr);
    1606              : 
    1607            3 :         opt.set_short_name("version", U'v');   // set to lowercase...
    1608            1 :         CATCH_REQUIRE(o->get_short_name() == U'v');
    1609            1 :         CATCH_REQUIRE(o == opt.get_option(U'v'));
    1610            1 :         CATCH_REQUIRE(opt.get_option(U'V') == nullptr);
    1611              : 
    1612            3 :         opt.set_short_name("version", advgetopt::NO_SHORT_NAME);   // remove completely...
    1613            1 :         CATCH_REQUIRE(o->get_short_name() ==advgetopt::NO_SHORT_NAME);
    1614            1 :         CATCH_REQUIRE(opt.get_option(U'V') == nullptr);
    1615            1 :         CATCH_REQUIRE(opt.get_option(U'v') == nullptr);
    1616            1 :     }
    1617            2 :     CATCH_END_SECTION()
    1618            2 : }
    1619              : 
    1620              : 
    1621              : 
    1622              : 
    1623            1 : CATCH_TEST_CASE("check_option_callbacks", "[arguments][getopt][config][callback]")
    1624              : {
    1625            1 :     CATCH_START_SECTION("check_option_callbacks: check option callbacks")
    1626              :     {
    1627            1 :         advgetopt::option const options[] =
    1628              :         {
    1629              :             advgetopt::define_option(
    1630              :                   advgetopt::Name("print")
    1631              :                 , advgetopt::ShortName(U'p')
    1632              :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
    1633              :                 , advgetopt::Help("output filename.")
    1634              :             ),
    1635              :             advgetopt::end_options()
    1636              :         };
    1637              : 
    1638            1 :         advgetopt::options_environment environment_options;
    1639            1 :         environment_options.f_project_name = "unittest";
    1640            1 :         environment_options.f_options = options;
    1641            1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
    1642            1 :         environment_options.f_configuration_filename = "snapwatchdog.conf";
    1643            1 :         environment_options.f_help_header = "Usage: test --config-dir";
    1644              : 
    1645            1 :         advgetopt::getopt opt(environment_options);
    1646              : 
    1647              :         struct print_expected
    1648              :         {
    1649              :         public:
    1650            8 :             void set_value(std::string const & value)
    1651              :             {
    1652            8 :                 f_value = value;
    1653            8 :             }
    1654              : 
    1655            6 :             std::string const & value() const
    1656              :             {
    1657            6 :                 return f_value;
    1658              :             }
    1659              : 
    1660              :         private:
    1661              :             std::string f_value = std::string();
    1662              :         };
    1663              : 
    1664              :         struct print_callback
    1665              :         {
    1666              :         public:
    1667            2 :             print_callback(print_expected * expected)
    1668            2 :                 : f_expected(expected)
    1669              :             {
    1670            2 :             }
    1671              : 
    1672            6 :             void operator() (advgetopt::option_info const & opt)
    1673              :             {
    1674            6 :                 CATCH_REQUIRE(f_expected->value() == opt.get_value());
    1675            6 :             }
    1676              : 
    1677              :         private:
    1678              :             print_expected *    f_expected = nullptr;
    1679              :         };
    1680              : 
    1681            1 :         print_expected expected1;
    1682            1 :         print_callback cb1(&expected1);
    1683              : 
    1684            3 :         advgetopt::option_info::pointer_t print(opt.get_option("print"));
    1685            1 :         CATCH_REQUIRE(print != nullptr);
    1686            1 :         advgetopt::option_info::callback_id_t const id1(print->add_callback(cb1));
    1687              : 
    1688            3 :         expected1.set_value("color");
    1689            3 :         print->set_value(0, "color");
    1690              : 
    1691              :         // test with a second callback, both are hit
    1692              :         //
    1693            1 :         print_expected expected2;
    1694            1 :         print_callback cb2(&expected2);
    1695            1 :         advgetopt::option_info::callback_id_t const id2(print->add_callback(cb2));
    1696              : 
    1697            3 :         expected1.set_value("black & white");
    1698            3 :         expected2.set_value("black & white");
    1699            3 :         print->set_value(0, "black & white");
    1700              : 
    1701              :         // call the remove without a valid identifier so a change still
    1702              :         // applies
    1703              :         //
    1704            1 :         print->remove_callback(id2 + 10);
    1705              : 
    1706            3 :         expected1.set_value("stipple");
    1707            3 :         expected2.set_value("stipple");
    1708            3 :         print->set_value(0, "stipple");
    1709              : 
    1710              :         // remove the first callback and try again
    1711              :         //
    1712            1 :         print->remove_callback(id1);
    1713              : 
    1714            3 :         expected1.set_value("ignored");     // this was removed
    1715            3 :         expected2.set_value("dithering");
    1716            3 :         print->set_value(0, "dithering");
    1717              : 
    1718              :         // remove the second callback and try again
    1719              :         //
    1720            1 :         print->remove_callback(id2);
    1721              : 
    1722            3 :         expected2.set_value("not called anymore either");
    1723            3 :         print->set_value(0, "cmyk");
    1724            1 :     }
    1725            1 :     CATCH_END_SECTION()
    1726            1 : }
    1727              : 
    1728              : 
    1729              : 
    1730              : // vim: ts=4 sw=4 et
        

Generated by: LCOV version 2.0-1

Snap C++ | List of projects | List of versions