LCOV - code coverage report
Current view: top level - tests - catch_option_info_ref.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 952 962 99.0 %
Date: 2022-07-15 09:02:52 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2006-2022  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             : // advgetopt
      21             : //
      22             : #include    <advgetopt/exception.h>
      23             : 
      24             : 
      25             : // self
      26             : //
      27             : #include    "catch_main.h"
      28             : 
      29             : 
      30             : // libutf8
      31             : //
      32             : #include    <libutf8/libutf8.h>
      33             : 
      34             : 
      35             : // C++
      36             : //
      37             : #include    <fstream>
      38             : 
      39             : 
      40             : // last include
      41             : //
      42             : #include    <snapdev/poison.h>
      43             : 
      44             : 
      45             : 
      46             : 
      47             : 
      48          29 : CATCH_TEST_CASE("option_info_ref", "[option_info][valid][reference]")
      49             : {
      50          54 :     CATCH_START_SECTION("Option info reference")
      51             :     {
      52           1 :         advgetopt::option const options[] =
      53             :         {
      54             :             advgetopt::define_option(
      55             :                   advgetopt::Name("reference")
      56             :                 , advgetopt::ShortName('r')
      57             :                 , advgetopt::Flags(advgetopt::command_flags<
      58             :                               advgetopt::GETOPT_FLAG_REQUIRED
      59             :                             | advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
      60             :                 , advgetopt::Help("test reference.")
      61             :             ),
      62             :             advgetopt::define_option(
      63             :                   advgetopt::Name("verbose")
      64             :                 , advgetopt::ShortName('v')
      65             :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
      66             :                 , advgetopt::Help("make it all verbose.")
      67             :             ),
      68             :             advgetopt::end_options()
      69             :         };
      70             : 
      71           1 :         advgetopt::options_environment environment_options;
      72           1 :         environment_options.f_project_name = "unittest";
      73           1 :         environment_options.f_options = options;
      74           1 :         environment_options.f_help_header = "Usage: verify references";
      75             : 
      76           1 :         char const * cargv[] =
      77             :         {
      78             :             "/usr/bin/arguments",
      79             :             "--reference",
      80             :             "1001",
      81             :             "--verbose",
      82             :             "loud",
      83             :             nullptr
      84             :         };
      85           1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
      86           1 :         char ** argv = const_cast<char **>(cargv);
      87             : 
      88           2 :         advgetopt::getopt opt(environment_options, argc, argv);
      89             : 
      90             :         // check that the result is valid
      91             : 
      92             :         // verify both parameters the "normal" way
      93           1 :         CATCH_REQUIRE(opt.get_option("reference") != nullptr);
      94           1 :         CATCH_REQUIRE(opt.size("reference") == 1);
      95           1 :         CATCH_REQUIRE(opt.get_string("reference") == "1001");
      96             : 
      97           1 :         CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
      98           1 :         CATCH_REQUIRE(opt.size("verbose") == 1);
      99           1 :         CATCH_REQUIRE(opt.get_string("verbose") == "loud");
     100             : 
     101             :         // check the read-only verbose which does not create a reference
     102           1 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "1001");
     103           1 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "loud");
     104             : 
     105           2 :         std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
     106           1 :         CATCH_REQUIRE(reference_value == "1001");
     107           2 :         std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
     108           1 :         CATCH_REQUIRE(verbose_value == "loud");
     109             : 
     110             :         // get a reference
     111           2 :         advgetopt::option_info_ref reference_ref(opt["reference"]);
     112           2 :         advgetopt::option_info_ref verbose_ref(opt["verbose"]);
     113             : 
     114           1 :         CATCH_REQUIRE_FALSE(reference_ref.empty());
     115           1 :         CATCH_REQUIRE_FALSE(verbose_ref.empty());
     116             : 
     117           1 :         CATCH_REQUIRE(reference_ref.length() == 4);
     118           1 :         CATCH_REQUIRE(reference_ref.size() == 4);
     119           1 :         CATCH_REQUIRE(verbose_ref.length() == 4);
     120           1 :         CATCH_REQUIRE(verbose_ref.size() == 4);
     121             : 
     122           1 :         CATCH_REQUIRE(reference_ref == reference_ref);
     123           1 :         CATCH_REQUIRE_FALSE(reference_ref != reference_ref);
     124           1 :         CATCH_REQUIRE_FALSE(reference_ref < reference_ref);
     125           1 :         CATCH_REQUIRE(reference_ref <= reference_ref);
     126           1 :         CATCH_REQUIRE_FALSE(reference_ref > reference_ref);
     127           1 :         CATCH_REQUIRE(reference_ref >= reference_ref);
     128             : 
     129           1 :         CATCH_REQUIRE_FALSE(reference_ref == verbose_ref);
     130           1 :         CATCH_REQUIRE(reference_ref != verbose_ref);
     131           1 :         CATCH_REQUIRE(reference_ref < verbose_ref);
     132           1 :         CATCH_REQUIRE(reference_ref <= verbose_ref);
     133           1 :         CATCH_REQUIRE_FALSE(reference_ref > verbose_ref);
     134           1 :         CATCH_REQUIRE_FALSE(reference_ref >= verbose_ref);
     135             : 
     136           1 :         reference_ref += "3";
     137           1 :         CATCH_REQUIRE(reference_ref == "10013");
     138           1 :         CATCH_REQUIRE("10013" == reference_ref);
     139           1 :         CATCH_REQUIRE(reference_ref != "17013");
     140           1 :         CATCH_REQUIRE("10413" != reference_ref);
     141           1 :         CATCH_REQUIRE(reference_ref < "20");
     142           1 :         CATCH_REQUIRE("1001" < reference_ref);
     143           1 :         CATCH_REQUIRE(reference_ref <= "10013");
     144           1 :         CATCH_REQUIRE("10013" <= reference_ref);
     145           1 :         CATCH_REQUIRE(reference_ref > "%");
     146           1 :         CATCH_REQUIRE("10014" > reference_ref);
     147           1 :         CATCH_REQUIRE(reference_ref >= "!");
     148           1 :         CATCH_REQUIRE("10013" >= reference_ref);
     149             : 
     150           2 :         std::string const new_value("zero");
     151           1 :         reference_ref = new_value;
     152           1 :         CATCH_REQUIRE(reference_ref == reference_ref);
     153           1 :         CATCH_REQUIRE(reference_ref == new_value);
     154           1 :         CATCH_REQUIRE(new_value == reference_ref);
     155           1 :         CATCH_REQUIRE_FALSE(reference_ref != new_value);
     156           1 :         CATCH_REQUIRE_FALSE(new_value != reference_ref);
     157           1 :         CATCH_REQUIRE_FALSE(reference_ref < new_value);
     158           1 :         CATCH_REQUIRE_FALSE(new_value < reference_ref);
     159           1 :         CATCH_REQUIRE(reference_ref <= new_value);
     160           1 :         CATCH_REQUIRE(new_value <= reference_ref);
     161           1 :         CATCH_REQUIRE_FALSE(reference_ref > new_value);
     162           1 :         CATCH_REQUIRE_FALSE(new_value > reference_ref);
     163           1 :         CATCH_REQUIRE(reference_ref >= new_value);
     164           1 :         CATCH_REQUIRE(new_value >= reference_ref);
     165             : 
     166           1 :         reference_ref += verbose_ref;
     167           1 :         CATCH_REQUIRE(reference_ref == reference_ref);
     168           1 :         CATCH_REQUIRE(reference_ref == "zeroloud");
     169           1 :         CATCH_REQUIRE("zeroloud" == reference_ref);
     170           1 :         CATCH_REQUIRE_FALSE(reference_ref != "zeroloud");
     171           1 :         CATCH_REQUIRE_FALSE("zeroloud" != reference_ref);
     172           1 :         CATCH_REQUIRE_FALSE(reference_ref < "zeroloud");
     173           1 :         CATCH_REQUIRE_FALSE("zeroloud" < reference_ref);
     174           1 :         CATCH_REQUIRE(reference_ref <= "zeroloud");
     175           1 :         CATCH_REQUIRE("zeroloud" <= reference_ref);
     176           1 :         CATCH_REQUIRE_FALSE(reference_ref > "zeroloud");
     177           1 :         CATCH_REQUIRE_FALSE("zeroloud" > reference_ref);
     178           1 :         CATCH_REQUIRE(reference_ref >= "zeroloud");
     179           1 :         CATCH_REQUIRE("zeroloud" >= reference_ref);
     180             : 
     181           1 :         reference_ref += '?';
     182           1 :         CATCH_REQUIRE(reference_ref == reference_ref);
     183           1 :         CATCH_REQUIRE(reference_ref == "zeroloud?");
     184           1 :         CATCH_REQUIRE("zeroloud?" == reference_ref);
     185           1 :         CATCH_REQUIRE_FALSE(reference_ref != "zeroloud?");
     186           1 :         CATCH_REQUIRE_FALSE("zeroloud?" != reference_ref);
     187           1 :         CATCH_REQUIRE_FALSE(reference_ref < "zeroloud?");
     188           1 :         CATCH_REQUIRE_FALSE("zeroloud?" < reference_ref);
     189           1 :         CATCH_REQUIRE(reference_ref <= "zeroloud?");
     190           1 :         CATCH_REQUIRE("zeroloud?" <= reference_ref);
     191           1 :         CATCH_REQUIRE_FALSE(reference_ref > "zeroloud?");
     192           1 :         CATCH_REQUIRE_FALSE("zeroloud?" > reference_ref);
     193           1 :         CATCH_REQUIRE(reference_ref >= "zeroloud?");
     194           1 :         CATCH_REQUIRE("zeroloud?" >= reference_ref);
     195             : 
     196           1 :         CATCH_REQUIRE_FALSE(reference_ref + "more" == reference_ref);
     197           1 :         CATCH_REQUIRE(reference_ref + "more" == "zeroloud?more");
     198           1 :         CATCH_REQUIRE("zeroloud?more" == reference_ref + "more");
     199           1 :         CATCH_REQUIRE(reference_ref + std::string("extra") == "zeroloud?extra");
     200           1 :         CATCH_REQUIRE("zeroloud?extra" == reference_ref + std::string("extra"));
     201           1 :         CATCH_REQUIRE(reference_ref + verbose_ref == "zeroloud?loud");
     202           1 :         CATCH_REQUIRE("zeroloud?loud" == reference_ref + verbose_ref);
     203             : 
     204           1 :         CATCH_REQUIRE_FALSE(reference_ref + '+' == reference_ref);
     205           1 :         CATCH_REQUIRE(reference_ref + '+' == "zeroloud?+");
     206           1 :         CATCH_REQUIRE("zeroloud?+" == reference_ref + '+');
     207           1 :         CATCH_REQUIRE('+' + reference_ref == "+zeroloud?");
     208           1 :         CATCH_REQUIRE("+zeroloud?" == '+' + reference_ref);
     209             : 
     210           1 :         CATCH_REQUIRE(reference_ref + '\0' == reference_ref);
     211           1 :         CATCH_REQUIRE(reference_ref + '\0' == "zeroloud?");
     212           1 :         CATCH_REQUIRE("zeroloud?" == reference_ref + '\0');
     213           1 :         CATCH_REQUIRE('\0' + reference_ref == "zeroloud?");
     214           1 :         CATCH_REQUIRE("zeroloud?" == '\0' + reference_ref);
     215             : 
     216           1 :         char32_t c(rand() % 0xFFFFF + ' ');
     217           1 :         if(c >= 0xD800 && c < 0xE000)
     218             :         {
     219           0 :             c += 0x800;
     220             :         }
     221             : 
     222           1 :         CATCH_REQUIRE_FALSE(reference_ref + c == reference_ref);
     223           1 :         CATCH_REQUIRE(reference_ref + c == "zeroloud?" + libutf8::to_u8string(c));
     224           1 :         CATCH_REQUIRE("zeroloud?" + libutf8::to_u8string(c) == reference_ref + c);
     225           1 :         CATCH_REQUIRE(c + reference_ref == libutf8::to_u8string(c) + "zeroloud?");
     226           1 :         CATCH_REQUIRE(libutf8::to_u8string(c) + "zeroloud?" == c + reference_ref);
     227             : 
     228           1 :         c = U'\0';
     229             : 
     230           1 :         CATCH_REQUIRE(reference_ref + c == reference_ref);
     231           1 :         CATCH_REQUIRE(reference_ref + c == "zeroloud?");
     232           1 :         CATCH_REQUIRE("zeroloud?" == reference_ref + c);
     233           1 :         CATCH_REQUIRE(c + reference_ref == "zeroloud?");
     234           1 :         CATCH_REQUIRE("zeroloud?" == c + reference_ref);
     235             : 
     236           1 :         reference_ref = "reset";
     237           1 :         CATCH_REQUIRE('"' + reference_ref + '"' == "\"reset\"");
     238           1 :         CATCH_REQUIRE('\0' + reference_ref + '\0' == std::string("reset") + '\0');  // we do not control the second + here...
     239           1 :         CATCH_REQUIRE(c + reference_ref + c == "reset");
     240             : 
     241           1 :         reference_ref = verbose_ref;
     242           1 :         CATCH_REQUIRE('(' + reference_ref + ')' == "(loud)");
     243           1 :         CATCH_REQUIRE('\0' + reference_ref + '\0' == std::string("loud") + '\0');  // we do not control the second + here...
     244           1 :         CATCH_REQUIRE(c + reference_ref + c == "loud");
     245             : 
     246           2 :         std::string const secret("secret");
     247           1 :         reference_ref += ' ';
     248           1 :         reference_ref += secret;
     249           1 :         CATCH_REQUIRE('>' + reference_ref + '<' == ">loud secret<");
     250           1 :         char32_t const left(0x1D233);
     251           1 :         char32_t const right(0x1D234);
     252           1 :         CATCH_REQUIRE((left + (reference_ref + right)) == "\xF0\x9D\x88\xB3loud secret\xF0\x9D\x88\xB4");
     253           1 :         CATCH_REQUIRE(((left + reference_ref) + right) == "\xF0\x9D\x88\xB3loud secret\xF0\x9D\x88\xB4");
     254           1 :         CATCH_REQUIRE(c == U'\0');
     255           1 :         CATCH_REQUIRE((c + (reference_ref + c)) == "loud secret");
     256           1 :         CATCH_REQUIRE(((c + reference_ref) + c) == "loud secret");
     257           1 :         CATCH_REQUIRE(reference_ref + new_value == "loud secretzero");
     258           1 :         CATCH_REQUIRE(new_value + reference_ref == "zeroloud secret");
     259           1 :         CATCH_REQUIRE(reference_ref + " more" == "loud secret more");
     260           1 :         CATCH_REQUIRE("less " + reference_ref == "less loud secret");
     261             : 
     262           1 :         reference_ref = '#';
     263           1 :         CATCH_REQUIRE(reference_ref == "#");
     264           1 :         reference_ref += '\0';
     265           1 :         CATCH_REQUIRE(reference_ref == "#");
     266           1 :         reference_ref += c;
     267           1 :         CATCH_REQUIRE(reference_ref == "#");
     268             : 
     269           1 :         reference_ref = '\0';
     270           1 :         CATCH_REQUIRE(reference_ref == "");
     271             : 
     272           1 :         reference_ref = '?';
     273           1 :         CATCH_REQUIRE(reference_ref == "?");
     274           1 :         reference_ref += '\0';
     275           1 :         CATCH_REQUIRE(reference_ref == "?");
     276           1 :         reference_ref += c;
     277           1 :         CATCH_REQUIRE(reference_ref == "?");
     278             : 
     279           1 :         reference_ref = c;
     280           1 :         CATCH_REQUIRE(reference_ref == "");
     281             :     }
     282             :     CATCH_END_SECTION()
     283             : 
     284          54 :     CATCH_START_SECTION("Non-existant reference")
     285             :     {
     286           1 :         advgetopt::option const options[] =
     287             :         {
     288             :             advgetopt::define_option(
     289             :                   advgetopt::Name("reference")
     290             :                 , advgetopt::ShortName('r')
     291             :                 , advgetopt::Flags(advgetopt::command_flags<
     292             :                               advgetopt::GETOPT_FLAG_REQUIRED
     293             :                             | advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
     294             :                 , advgetopt::Help("test reference.")
     295             :             ),
     296             :             advgetopt::define_option(
     297             :                   advgetopt::Name("verbose")
     298             :                 , advgetopt::ShortName('v')
     299             :                 , advgetopt::Flags(advgetopt::command_flags<
     300             :                               advgetopt::GETOPT_FLAG_REQUIRED
     301             :                             | advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
     302             :                 , advgetopt::Help("make it all verbose.")
     303             :             ),
     304             :             advgetopt::end_options()
     305             :         };
     306             : 
     307           1 :         advgetopt::options_environment environment_options;
     308           1 :         environment_options.f_project_name = "unittest";
     309           1 :         environment_options.f_options = options;
     310           1 :         environment_options.f_help_header = "Usage: verify references";
     311             : 
     312           1 :         char const * cargv[] =
     313             :         {
     314             :             "/usr/bin/arguments",
     315             :             "--reference",
     316             :             "1001",
     317             :             "--verbose",
     318             :             "loud",
     319             :             nullptr
     320             :         };
     321           1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
     322           1 :         char ** argv = const_cast<char **>(cargv);
     323             : 
     324           2 :         advgetopt::getopt opt(environment_options, argc, argv);
     325             : 
     326             :         // check that the result is valid
     327             : 
     328             :         // verify both parameters the "normal" way
     329           1 :         CATCH_REQUIRE(opt.get_option("reference") != nullptr);
     330           1 :         CATCH_REQUIRE(opt.size("reference") == 1);
     331           1 :         CATCH_REQUIRE(opt.get_string("reference") == "1001");
     332             : 
     333           1 :         CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
     334           1 :         CATCH_REQUIRE(opt.size("verbose") == 1);
     335           1 :         CATCH_REQUIRE(opt.get_string("verbose") == "loud");
     336             : 
     337           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     338             : 
     339             :         // check the read-only verbose which does not create a reference
     340           1 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "1001");
     341           1 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "loud");
     342             : 
     343           2 :         std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
     344           1 :         CATCH_REQUIRE(reference_value == "1001");
     345           2 :         std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
     346           1 :         CATCH_REQUIRE(verbose_value == "loud");
     347             : 
     348             :         // get references
     349           2 :         advgetopt::option_info_ref unknown_ref(opt["unknown"]);
     350           2 :         advgetopt::option_info_ref reference_ref(opt["reference"]);
     351           2 :         advgetopt::option_info_ref verbose_ref(opt["verbose"]);
     352             : 
     353           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     354             : 
     355           1 :         char const * null_string(nullptr);
     356             : 
     357           1 :         CATCH_REQUIRE(unknown_ref.empty());
     358           1 :         CATCH_REQUIRE(unknown_ref.length() == 0);
     359           1 :         CATCH_REQUIRE(unknown_ref.size() == 0);
     360           1 :         CATCH_REQUIRE(unknown_ref.get_long() == 0);
     361             : #pragma GCC diagnostic push
     362             : #pragma GCC diagnostic ignored "-Wfloat-equal"
     363             :         {
     364           1 :             bool const a1(unknown_ref.get_double() == 0.0);
     365           1 :             CATCH_REQUIRE(a1);
     366             :         }
     367             : #pragma GCC diagnostic pop
     368           1 :         CATCH_REQUIRE(static_cast<std::string>(unknown_ref) == "");
     369           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     370             : 
     371           1 :         CATCH_REQUIRE_FALSE(static_cast<bool>(unknown_ref));
     372           1 :         CATCH_REQUIRE(!unknown_ref);
     373           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     374             : 
     375           1 :         CATCH_REQUIRE(unknown_ref == nullptr);
     376           1 :         CATCH_REQUIRE(unknown_ref == "");
     377           1 :         CATCH_REQUIRE(unknown_ref == std::string());
     378           1 :         CATCH_REQUIRE_FALSE(unknown_ref == std::string("test"));
     379           1 :         CATCH_REQUIRE(nullptr == unknown_ref);
     380           1 :         CATCH_REQUIRE("" == unknown_ref);
     381           1 :         CATCH_REQUIRE(std::string() == unknown_ref);
     382           1 :         CATCH_REQUIRE_FALSE(std::string("test") == unknown_ref);
     383           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     384             : 
     385           1 :         CATCH_REQUIRE_FALSE(unknown_ref != nullptr);
     386           1 :         CATCH_REQUIRE_FALSE(unknown_ref != "");
     387           1 :         CATCH_REQUIRE_FALSE(unknown_ref != std::string());
     388           1 :         CATCH_REQUIRE(unknown_ref != std::string("test"));
     389           1 :         CATCH_REQUIRE_FALSE(nullptr != unknown_ref);
     390           1 :         CATCH_REQUIRE_FALSE("" != unknown_ref);
     391           1 :         CATCH_REQUIRE_FALSE(std::string() != unknown_ref);
     392           1 :         CATCH_REQUIRE(std::string("test") != unknown_ref);
     393           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     394             : 
     395           1 :         CATCH_REQUIRE_FALSE(unknown_ref < nullptr);
     396           1 :         CATCH_REQUIRE_FALSE(unknown_ref < "");
     397           1 :         CATCH_REQUIRE_FALSE(unknown_ref < std::string());
     398           1 :         CATCH_REQUIRE(unknown_ref < std::string("test"));
     399           1 :         CATCH_REQUIRE_FALSE(nullptr < unknown_ref);
     400           1 :         CATCH_REQUIRE_FALSE("" < unknown_ref);
     401           1 :         CATCH_REQUIRE_FALSE(std::string() < unknown_ref);
     402           1 :         CATCH_REQUIRE_FALSE(std::string("test") < unknown_ref);
     403           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     404             : 
     405           1 :         CATCH_REQUIRE(unknown_ref <= nullptr);
     406           1 :         CATCH_REQUIRE(unknown_ref <= "");
     407           1 :         CATCH_REQUIRE(unknown_ref <= std::string());
     408           1 :         CATCH_REQUIRE(unknown_ref <= std::string("test"));
     409           1 :         CATCH_REQUIRE(nullptr <= unknown_ref);
     410           1 :         CATCH_REQUIRE("" <= unknown_ref);
     411           1 :         CATCH_REQUIRE(std::string() <= unknown_ref);
     412           1 :         CATCH_REQUIRE_FALSE(std::string("test") <= unknown_ref);
     413           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     414             : 
     415           1 :         CATCH_REQUIRE_FALSE(unknown_ref > nullptr);
     416           1 :         CATCH_REQUIRE_FALSE(unknown_ref > "");
     417           1 :         CATCH_REQUIRE_FALSE(unknown_ref > std::string());
     418           1 :         CATCH_REQUIRE_FALSE(unknown_ref > std::string("test"));
     419           1 :         CATCH_REQUIRE_FALSE(nullptr > unknown_ref);
     420           1 :         CATCH_REQUIRE_FALSE("" > unknown_ref);
     421           1 :         CATCH_REQUIRE_FALSE(std::string() > unknown_ref);
     422           1 :         CATCH_REQUIRE(std::string("test") > unknown_ref);
     423           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     424             : 
     425           1 :         CATCH_REQUIRE(unknown_ref >= nullptr);
     426           1 :         CATCH_REQUIRE(unknown_ref >= "");
     427           1 :         CATCH_REQUIRE(unknown_ref >= std::string());
     428           1 :         CATCH_REQUIRE_FALSE(unknown_ref >= std::string("test"));
     429           1 :         CATCH_REQUIRE(nullptr >= unknown_ref);
     430           1 :         CATCH_REQUIRE("" >= unknown_ref);
     431           1 :         CATCH_REQUIRE(std::string() >= unknown_ref);
     432           1 :         CATCH_REQUIRE(std::string("test") >= unknown_ref);
     433           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     434             : 
     435           1 :         CATCH_REQUIRE(unknown_ref + '\0' == "");
     436           1 :         CATCH_REQUIRE(unknown_ref + '<' == "<");
     437           1 :         CATCH_REQUIRE(unknown_ref + static_cast<char32_t>(U'\0') == "");
     438           1 :         CATCH_REQUIRE(unknown_ref + static_cast<char32_t>(U'\x2020') == "\xE2\x80\xA0");
     439           1 :         CATCH_REQUIRE(unknown_ref + null_string == "");
     440           1 :         CATCH_REQUIRE(unknown_ref + "abc\xE4\x81\x81" == "abc\xE4\x81\x81");
     441           1 :         CATCH_REQUIRE(unknown_ref + std::string("xyz\xE4\x9E\x99") == "xyz\xE4\x9E\x99");
     442           1 :         CATCH_REQUIRE(unknown_ref + reference_ref == "1001");
     443           1 :         CATCH_REQUIRE(unknown_ref + verbose_ref == "loud");
     444           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     445             : 
     446           1 :         CATCH_REQUIRE('\0' + unknown_ref == "");
     447           1 :         CATCH_REQUIRE('<' + unknown_ref == "<");
     448           1 :         CATCH_REQUIRE(static_cast<char32_t>(U'\0') + unknown_ref == "");
     449           1 :         CATCH_REQUIRE(static_cast<char32_t>(U'\x2020') + unknown_ref == "\xE2\x80\xA0");
     450           1 :         CATCH_REQUIRE(null_string + unknown_ref == "");
     451           1 :         CATCH_REQUIRE("abc\xE4\x81\x81" + unknown_ref == "abc\xE4\x81\x81");
     452           1 :         CATCH_REQUIRE(std::string("xyz\xE4\x9E\x99") + unknown_ref == "xyz\xE4\x9E\x99");
     453           1 :         CATCH_REQUIRE(reference_ref + unknown_ref == "1001");
     454           1 :         CATCH_REQUIRE(verbose_ref + unknown_ref == "loud");
     455           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     456             : 
     457           1 :         unknown_ref = static_cast<char32_t>(U'\x4819'); // == '\xE4\xA0\x99'
     458           1 :         CATCH_REQUIRE(opt.is_defined("unknown"));
     459             : 
     460           1 :         CATCH_REQUIRE_FALSE(unknown_ref.empty());
     461           1 :         CATCH_REQUIRE(unknown_ref.length() == 3);       // 3 UTF-8 bytes
     462           1 :         CATCH_REQUIRE(unknown_ref.size() == 3);
     463             : 
     464           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid number (\xE4\xA0\x99) in parameter --unknown at offset 0.");
     465           1 :         CATCH_REQUIRE(unknown_ref.get_long() == -1);
     466           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     467             : 
     468             : #pragma GCC diagnostic push
     469             : #pragma GCC diagnostic ignored "-Wfloat-equal"
     470             :         {
     471           1 :             SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid number (\xE4\xA0\x99) in parameter --unknown at offset 0.");
     472           1 :             bool const a2(unknown_ref.get_double() == -1.0);
     473           1 :             CATCH_REQUIRE(a2);
     474           1 :             SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     475             :         }
     476             : #pragma GCC diagnostic pop
     477             : 
     478           1 :         CATCH_REQUIRE(static_cast<std::string>(unknown_ref) == "\xE4\xA0\x99");
     479           1 :         CATCH_REQUIRE(opt.is_defined("unknown"));
     480             : 
     481           1 :         CATCH_REQUIRE(static_cast<bool>(unknown_ref));
     482           1 :         CATCH_REQUIRE_FALSE(!unknown_ref);
     483           1 :         CATCH_REQUIRE(opt.is_defined("unknown"));
     484             : 
     485           1 :         CATCH_REQUIRE_FALSE(unknown_ref == nullptr);
     486           1 :         CATCH_REQUIRE_FALSE(unknown_ref == "");
     487           1 :         CATCH_REQUIRE(unknown_ref == "\xE4\xA0\x99");
     488           1 :         CATCH_REQUIRE_FALSE(unknown_ref == std::string());
     489           1 :         CATCH_REQUIRE_FALSE(unknown_ref == std::string("test"));
     490           1 :         CATCH_REQUIRE(unknown_ref == std::string("\xE4\xA0\x99"));
     491           1 :         CATCH_REQUIRE_FALSE(nullptr == unknown_ref);
     492           1 :         CATCH_REQUIRE_FALSE("" == unknown_ref);
     493           1 :         CATCH_REQUIRE("\xE4\xA0\x99" == unknown_ref);
     494           1 :         CATCH_REQUIRE_FALSE(std::string() == unknown_ref);
     495           1 :         CATCH_REQUIRE_FALSE(std::string("test") == unknown_ref);
     496           1 :         CATCH_REQUIRE(std::string("\xE4\xA0\x99") == unknown_ref);
     497           1 :         CATCH_REQUIRE(opt.is_defined("unknown"));
     498             : 
     499           1 :         CATCH_REQUIRE(unknown_ref != nullptr);
     500           1 :         CATCH_REQUIRE(unknown_ref != "");
     501           1 :         CATCH_REQUIRE_FALSE(unknown_ref != "\xE4\xA0\x99");
     502           1 :         CATCH_REQUIRE(unknown_ref != std::string());
     503           1 :         CATCH_REQUIRE(unknown_ref != std::string("test"));
     504           1 :         CATCH_REQUIRE_FALSE(unknown_ref != std::string("\xE4\xA0\x99"));
     505           1 :         CATCH_REQUIRE(nullptr != unknown_ref);
     506           1 :         CATCH_REQUIRE("" != unknown_ref);
     507           1 :         CATCH_REQUIRE_FALSE("\xE4\xA0\x99" != unknown_ref);
     508           1 :         CATCH_REQUIRE(std::string() != unknown_ref);
     509           1 :         CATCH_REQUIRE(std::string("test") != unknown_ref);
     510           1 :         CATCH_REQUIRE_FALSE(std::string("\xE4\xA0\x99") != unknown_ref);
     511           1 :         CATCH_REQUIRE(opt.is_defined("unknown"));
     512             : 
     513           1 :         CATCH_REQUIRE_FALSE(unknown_ref < nullptr);
     514           1 :         CATCH_REQUIRE_FALSE(unknown_ref < "");
     515           1 :         CATCH_REQUIRE_FALSE(unknown_ref < "\xE4\xA0\x99");
     516           1 :         CATCH_REQUIRE_FALSE(unknown_ref < std::string());
     517           1 :         CATCH_REQUIRE_FALSE(unknown_ref < std::string("test"));
     518           1 :         CATCH_REQUIRE_FALSE(unknown_ref < std::string("\xE4\xA0\x99"));
     519           1 :         CATCH_REQUIRE(nullptr < unknown_ref);
     520           1 :         CATCH_REQUIRE("" < unknown_ref);
     521           1 :         CATCH_REQUIRE_FALSE("\xE4\xA0\x99" < unknown_ref);
     522           1 :         CATCH_REQUIRE(std::string() < unknown_ref);
     523           1 :         CATCH_REQUIRE(std::string("test") < unknown_ref);
     524           1 :         CATCH_REQUIRE_FALSE(std::string("\xE4\xA0\x99") < unknown_ref);
     525           1 :         CATCH_REQUIRE(opt.is_defined("unknown"));
     526             : 
     527           1 :         CATCH_REQUIRE_FALSE(unknown_ref <= nullptr);
     528           1 :         CATCH_REQUIRE_FALSE(unknown_ref <= "");
     529           1 :         CATCH_REQUIRE(unknown_ref <= "\xE4\xA0\x99");
     530           1 :         CATCH_REQUIRE_FALSE(unknown_ref <= std::string());
     531           1 :         CATCH_REQUIRE_FALSE(unknown_ref <= std::string("test"));
     532           1 :         CATCH_REQUIRE(unknown_ref <= std::string("\xE4\xA0\x99"));
     533           1 :         CATCH_REQUIRE(nullptr <= unknown_ref);
     534           1 :         CATCH_REQUIRE("" <= unknown_ref);
     535           1 :         CATCH_REQUIRE("\xE4\xA0\x99" <= unknown_ref);
     536           1 :         CATCH_REQUIRE(std::string() <= unknown_ref);
     537           1 :         CATCH_REQUIRE(std::string("test") <= unknown_ref);
     538           1 :         CATCH_REQUIRE(std::string("\xE4\xA0\x99") <= unknown_ref);
     539           1 :         CATCH_REQUIRE(opt.is_defined("unknown"));
     540             : 
     541           1 :         CATCH_REQUIRE(unknown_ref > nullptr);
     542           1 :         CATCH_REQUIRE(unknown_ref > "");
     543           1 :         CATCH_REQUIRE_FALSE(unknown_ref > "\xE4\xA0\x99");
     544           1 :         CATCH_REQUIRE(unknown_ref > std::string());
     545           1 :         CATCH_REQUIRE(unknown_ref > std::string("test"));
     546           1 :         CATCH_REQUIRE_FALSE(unknown_ref > std::string("\xE4\xA0\x99"));
     547           1 :         CATCH_REQUIRE_FALSE(nullptr > unknown_ref);
     548           1 :         CATCH_REQUIRE_FALSE("" > unknown_ref);
     549           1 :         CATCH_REQUIRE_FALSE("\xE4\xA0\x99" > unknown_ref);
     550           1 :         CATCH_REQUIRE_FALSE(std::string() > unknown_ref);
     551           1 :         CATCH_REQUIRE_FALSE(std::string("test") > unknown_ref);
     552           1 :         CATCH_REQUIRE_FALSE(std::string("\xE4\xA0\x99") > unknown_ref);
     553           1 :         CATCH_REQUIRE(opt.is_defined("unknown"));
     554             : 
     555           1 :         CATCH_REQUIRE(unknown_ref >= nullptr);
     556           1 :         CATCH_REQUIRE(unknown_ref >= "");
     557           1 :         CATCH_REQUIRE(unknown_ref >= "\xE4\xA0\x99");
     558           1 :         CATCH_REQUIRE(unknown_ref >= std::string());
     559           1 :         CATCH_REQUIRE(unknown_ref >= std::string("test"));
     560           1 :         CATCH_REQUIRE(unknown_ref >= std::string("\xE4\xA0\x99"));
     561           1 :         CATCH_REQUIRE_FALSE(nullptr >= unknown_ref);
     562           1 :         CATCH_REQUIRE_FALSE("" >= unknown_ref);
     563           1 :         CATCH_REQUIRE_FALSE(std::string() >= unknown_ref);
     564           1 :         CATCH_REQUIRE_FALSE(std::string("test") >= unknown_ref);
     565           1 :         CATCH_REQUIRE(opt.is_defined("unknown"));
     566             : 
     567           1 :         CATCH_REQUIRE(unknown_ref + '\0' == "\xE4\xA0\x99");
     568           1 :         CATCH_REQUIRE(unknown_ref + '<' == "\xE4\xA0\x99<");
     569           1 :         CATCH_REQUIRE(unknown_ref + static_cast<char32_t>(U'\0') == "\xE4\xA0\x99");
     570           1 :         CATCH_REQUIRE(unknown_ref + static_cast<char32_t>(U'\x2020') == "\xE4\xA0\x99\xE2\x80\xA0");
     571           1 :         CATCH_REQUIRE(unknown_ref + null_string == "\xE4\xA0\x99");
     572           1 :         CATCH_REQUIRE(unknown_ref + "abc\xE4\x81\x81" == "\xE4\xA0\x99\x61\x62\x63\xE4\x81\x81");
     573           1 :         CATCH_REQUIRE(unknown_ref + std::string("xyz\xE4\x9E\x99") == "\xE4\xA0\x99xyz\xE4\x9E\x99");
     574           1 :         CATCH_REQUIRE(unknown_ref + reference_ref == "\xE4\xA0\x99\x31\x30\x30\x31");
     575           1 :         CATCH_REQUIRE(unknown_ref + verbose_ref == "\xE4\xA0\x99loud");
     576           1 :         CATCH_REQUIRE(opt.is_defined("unknown"));
     577             : 
     578           1 :         CATCH_REQUIRE('\0' + unknown_ref == "\xE4\xA0\x99");
     579           1 :         CATCH_REQUIRE('<' + unknown_ref == "<\xE4\xA0\x99");
     580           1 :         CATCH_REQUIRE(static_cast<char32_t>(U'\0') + unknown_ref == "\xE4\xA0\x99");
     581           1 :         CATCH_REQUIRE(static_cast<char32_t>(U'\x2020') + unknown_ref == "\xE2\x80\xA0\xE4\xA0\x99");
     582           1 :         CATCH_REQUIRE(null_string + unknown_ref == "\xE4\xA0\x99");
     583           1 :         CATCH_REQUIRE("abc\xE4\x81\x81" + unknown_ref == "abc\xE4\x81\x81\xE4\xA0\x99");
     584           1 :         CATCH_REQUIRE(std::string("xyz\xE4\x9E\x99") + unknown_ref == "xyz\xE4\x9E\x99\xE4\xA0\x99");
     585           1 :         CATCH_REQUIRE(reference_ref + unknown_ref == "1001\xE4\xA0\x99");
     586           1 :         CATCH_REQUIRE(verbose_ref + unknown_ref == "loud\xE4\xA0\x99");
     587           1 :         CATCH_REQUIRE(opt.is_defined("unknown"));
     588             :     }
     589             :     CATCH_END_SECTION()
     590             : 
     591          54 :     CATCH_START_SECTION("Set non-existant reference + many CATCH_WHEN()")
     592             :     {
     593          25 :         advgetopt::option const options[] =
     594             :         {
     595             :             advgetopt::define_option(
     596             :                   advgetopt::Name("reference")
     597             :                 , advgetopt::ShortName('r')
     598             :                 , advgetopt::Flags(advgetopt::command_flags<
     599             :                               advgetopt::GETOPT_FLAG_REQUIRED
     600             :                             | advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
     601             :                 , advgetopt::Help("test reference.")
     602             :                 , advgetopt::DefaultValue("978")
     603             :             ),
     604             :             advgetopt::define_option(
     605             :                   advgetopt::Name("verbose")
     606             :                 , advgetopt::ShortName('v')
     607             :                 , advgetopt::Flags(advgetopt::command_flags<
     608             :                               advgetopt::GETOPT_FLAG_REQUIRED
     609             :                             | advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
     610             :                 , advgetopt::Help("make it all verbose.")
     611             :             ),
     612             :             advgetopt::end_options()
     613             :         };
     614             : 
     615          25 :         advgetopt::options_environment environment_options;
     616          25 :         environment_options.f_project_name = "unittest";
     617          25 :         environment_options.f_options = options;
     618          25 :         environment_options.f_help_header = "Usage: verify references";
     619             : 
     620          25 :         char const * cargv[] =
     621             :         {
     622             :             "/usr/bin/arguments",
     623             :             "--reference",
     624             :             "3100",
     625             :             "--verbose",
     626             :             "silence",
     627             :             nullptr
     628             :         };
     629          25 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
     630          25 :         char ** argv = const_cast<char **>(cargv);
     631             : 
     632          50 :         advgetopt::getopt opt(environment_options, argc, argv);
     633             : 
     634             :         // check that the result is valid
     635             : 
     636             :         // verify both parameters the "normal" way
     637          25 :         CATCH_REQUIRE(opt.get_option("reference") != nullptr);
     638          25 :         CATCH_REQUIRE(opt.size("reference") == 1);
     639          25 :         CATCH_REQUIRE(opt.get_string("reference") == "3100");
     640          25 :         CATCH_REQUIRE(opt.get_long("reference") == 3100);
     641             : #pragma GCC diagnostic push
     642             : #pragma GCC diagnostic ignored "-Wfloat-equal"
     643             :         {
     644          25 :             bool const a3(opt.get_double("reference") == 3100.0);
     645          25 :             CATCH_REQUIRE(a3);
     646             :         }
     647             : #pragma GCC diagnostic pop
     648             : 
     649          25 :         CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
     650          25 :         CATCH_REQUIRE(opt.size("verbose") == 1);
     651          25 :         CATCH_REQUIRE(opt.get_string("verbose") == "silence");
     652             : 
     653          25 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     654             : 
     655             :         // check the read-only verbose which does not create a reference
     656          25 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "3100");
     657          25 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "silence");
     658             : 
     659          50 :         std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
     660          25 :         CATCH_REQUIRE(reference_value == "3100");
     661          50 :         std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
     662          25 :         CATCH_REQUIRE(verbose_value == "silence");
     663             : 
     664             :         // get references
     665          50 :         advgetopt::option_info_ref unknown_ref(opt["unknown"]);
     666          50 :         advgetopt::option_info_ref undefined_ref(opt["undefined"]);     // never set, used as rhs to test setting/adding with an undefined ref.
     667          50 :         advgetopt::option_info_ref reference_ref(opt["reference"]);
     668          50 :         advgetopt::option_info_ref verbose_ref(opt["verbose"]);
     669             : 
     670          25 :         CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     671          25 :         CATCH_REQUIRE(opt.is_defined("reference"));
     672          25 :         CATCH_REQUIRE(opt.is_defined("verbose"));
     673          25 :         CATCH_REQUIRE(reference_ref.get_long() == 3100);
     674             : #pragma GCC diagnostic push
     675             : #pragma GCC diagnostic ignored "-Wfloat-equal"
     676             :         {
     677          25 :             bool const a4(reference_ref.get_double() == 3100.0);
     678          25 :             CATCH_REQUIRE(a4);
     679             :         }
     680             : #pragma GCC diagnostic pop
     681             : 
     682          50 :         CATCH_WHEN("with = & zero char")
     683             :         {
     684           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     685             : 
     686           1 :             char const c('\0');
     687           1 :             unknown_ref = c;
     688             : 
     689           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     690             : 
     691           2 :             std::string s;
     692           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     693             : 
     694           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     695           1 :             CATCH_REQUIRE(unknown_value == s);
     696             : 
     697           1 :             CATCH_REQUIRE(unknown_ref == s);
     698             : 
     699           1 :             unknown_ref += c;
     700             : 
     701           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     702             : 
     703           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     704             : 
     705           2 :             std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     706           1 :             CATCH_REQUIRE(unknown_value2 == s);
     707             : 
     708           1 :             CATCH_REQUIRE(unknown_ref == s);
     709             :         }
     710             : 
     711          50 :         CATCH_WHEN("with = & valid char")
     712             :         {
     713           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     714             : 
     715           1 :             char const c(rand() % 26 + 'a');
     716           1 :             unknown_ref = c;
     717             : 
     718           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     719             : 
     720           2 :             std::string s;
     721           1 :             s += c;
     722           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     723             : 
     724           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     725           1 :             CATCH_REQUIRE(unknown_value == s);
     726             : 
     727           1 :             CATCH_REQUIRE(unknown_ref == s);
     728             : 
     729           1 :             char const d(rand() % 26 + 'a');
     730           1 :             unknown_ref += d;
     731             : 
     732           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     733             : 
     734           1 :             s += d;
     735           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     736             : 
     737           2 :             std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     738           1 :             CATCH_REQUIRE(unknown_value2 == s);
     739             : 
     740           1 :             CATCH_REQUIRE(unknown_ref == s);
     741             :         }
     742             : 
     743          50 :         CATCH_WHEN("with = & zero char32_t")
     744             :         {
     745           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     746             : 
     747           1 :             char32_t const c(U'\0');
     748           1 :             unknown_ref = c;
     749             : 
     750           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     751             : 
     752           2 :             std::string s;
     753           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     754             : 
     755           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     756           1 :             CATCH_REQUIRE(unknown_value == s);
     757             : 
     758           1 :             CATCH_REQUIRE(unknown_ref == s);
     759             : 
     760           1 :             unknown_ref += c;
     761             : 
     762           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     763             : 
     764           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     765             : 
     766           2 :             std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     767           1 :             CATCH_REQUIRE(unknown_value2 == s);
     768             : 
     769           1 :             CATCH_REQUIRE(unknown_ref == s);
     770             :         }
     771             : 
     772          50 :         CATCH_WHEN("with = & valid char32_t")
     773             :         {
     774           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     775             : 
     776           1 :             char32_t c((rand() & 0xFFFFF) + ' ');
     777           1 :             if(c >= 0xD800 && c < 0xE000)
     778             :             {
     779           0 :                 c += 0x0800;
     780             :             }
     781           1 :             unknown_ref = c;
     782             : 
     783           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     784             : 
     785           2 :             std::string s;
     786           1 :             s += libutf8::to_u8string(c);
     787           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     788             : 
     789           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     790           1 :             CATCH_REQUIRE(unknown_value == s);
     791             : 
     792           1 :             CATCH_REQUIRE(unknown_ref == s);
     793             : 
     794           1 :             char32_t d((rand() & 0xFFFFF) + ' ');
     795           1 :             if(d >= 0xD800 && d < 0xE000)
     796             :             {
     797           0 :                 d += 0x0800;
     798             :             }
     799           1 :             unknown_ref += d;
     800             : 
     801           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     802             : 
     803           1 :             s += libutf8::to_u8string(d);
     804           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     805             : 
     806           2 :             std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     807           1 :             CATCH_REQUIRE(unknown_value2 == s);
     808             : 
     809           1 :             CATCH_REQUIRE(unknown_ref == s);
     810             :         }
     811             : 
     812          50 :         CATCH_WHEN("with = & nullptr of 'char const *'")
     813             :         {
     814           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     815             : 
     816           1 :             char const * str(nullptr);
     817           1 :             unknown_ref = str;
     818             : 
     819           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     820             : 
     821           2 :             std::string s;
     822           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     823             : 
     824           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     825           1 :             CATCH_REQUIRE(unknown_value == s);
     826             : 
     827           1 :             CATCH_REQUIRE(unknown_ref == s);
     828             : 
     829           1 :             unknown_ref += str;
     830             : 
     831           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     832             : 
     833           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     834             : 
     835           2 :             std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     836           1 :             CATCH_REQUIRE(unknown_value2 == s);
     837             : 
     838           1 :             CATCH_REQUIRE(unknown_ref == s);
     839             :         }
     840             : 
     841          50 :         CATCH_WHEN("with = & empty 'char const *' string")
     842             :         {
     843           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     844             : 
     845           1 :             char const * str("");
     846           1 :             unknown_ref = str;
     847             : 
     848           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     849             : 
     850           2 :             std::string s;
     851           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     852             : 
     853           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     854           1 :             CATCH_REQUIRE(unknown_value == s);
     855             : 
     856           1 :             CATCH_REQUIRE(unknown_ref == s);
     857             : 
     858           1 :             unknown_ref += str;
     859             : 
     860           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     861             : 
     862           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     863             : 
     864           2 :             std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     865           1 :             CATCH_REQUIRE(unknown_value2 == s);
     866             : 
     867           1 :             CATCH_REQUIRE(unknown_ref == s);
     868             :         }
     869             : 
     870          50 :         CATCH_WHEN("with = & valid `char const *`")
     871             :         {
     872           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     873             : 
     874           2 :             std::string str;
     875           1 :             size_t max(rand() % 10 + 1);
     876           5 :             for(size_t idx(0); idx < max; ++idx)
     877             :             {
     878           4 :                 char32_t c((rand() & 0xFFFFF) + ' ');
     879           4 :                 if(c >= 0xD800 && c < 0xE000)
     880             :                 {
     881           0 :                     c += 0x0800;
     882             :                 }
     883           4 :                 str += libutf8::to_u8string(c);
     884             :             }
     885           1 :             unknown_ref = str.c_str();
     886             : 
     887           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     888             : 
     889           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == str);
     890             : 
     891           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     892           1 :             CATCH_REQUIRE(unknown_value == str);
     893             : 
     894           1 :             CATCH_REQUIRE(unknown_ref == str);
     895             : 
     896           2 :             std::string add;
     897           1 :             max = rand() % 10 + 1;
     898          11 :             for(size_t idx(0); idx < max; ++idx)
     899             :             {
     900          10 :                 char32_t c((rand() & 0xFFFFF) + ' ');
     901          10 :                 if(c >= 0xD800 && c < 0xE000)
     902             :                 {
     903           0 :                     c += 0x0800;
     904             :                 }
     905          10 :                 add += libutf8::to_u8string(c);
     906             :             }
     907           1 :             unknown_ref += add.c_str();
     908             : 
     909           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     910             : 
     911           1 :             str += add;
     912           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == str);
     913             : 
     914           2 :             std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     915           1 :             CATCH_REQUIRE(unknown_value2 == str);
     916             : 
     917           1 :             CATCH_REQUIRE(unknown_ref == str);
     918             :         }
     919             : 
     920          50 :         CATCH_WHEN("with = & empty std::string")
     921             :         {
     922           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     923             : 
     924           2 :             std::string str;
     925           1 :             unknown_ref = str;
     926             : 
     927           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     928             : 
     929           2 :             std::string s;
     930           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     931             : 
     932           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     933           1 :             CATCH_REQUIRE(unknown_value == s);
     934             : 
     935           1 :             CATCH_REQUIRE(unknown_ref == s);
     936             : 
     937           1 :             unknown_ref += str;
     938             : 
     939           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     940             : 
     941           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
     942             : 
     943           2 :             std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     944           1 :             CATCH_REQUIRE(unknown_value2 == s);
     945             : 
     946           1 :             CATCH_REQUIRE(unknown_ref == s);
     947             :         }
     948             : 
     949          50 :         CATCH_WHEN("with = & valid std::string")
     950             :         {
     951           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
     952             : 
     953           2 :             std::string str;
     954           1 :             size_t max(rand() % 10 + 1);
     955           4 :             for(size_t idx(0); idx < max; ++idx)
     956             :             {
     957           3 :                 char32_t c((rand() & 0xFFFFF) + ' ');
     958           3 :                 if(c >= 0xD800 && c < 0xE000)
     959             :                 {
     960           0 :                     c += 0x0800;
     961             :                 }
     962           3 :                 str += libutf8::to_u8string(c);
     963             :             }
     964           1 :             unknown_ref = str;
     965             : 
     966           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     967             : 
     968           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == str);
     969             : 
     970           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     971           1 :             CATCH_REQUIRE(unknown_value == str);
     972             : 
     973           1 :             CATCH_REQUIRE(unknown_ref == str);
     974             : 
     975           2 :             std::string add;
     976           1 :             max = rand() % 10 + 1;
     977           4 :             for(size_t idx(0); idx < max; ++idx)
     978             :             {
     979           3 :                 char32_t c((rand() & 0xFFFFF) + ' ');
     980           3 :                 if(c >= 0xD800 && c < 0xE000)
     981             :                 {
     982           0 :                     c += 0x0800;
     983             :                 }
     984           3 :                 add += libutf8::to_u8string(c);
     985             :             }
     986           1 :             unknown_ref += add;
     987             : 
     988           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
     989             : 
     990           1 :             str += add;
     991           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == str);
     992             : 
     993           2 :             std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
     994           1 :             CATCH_REQUIRE(unknown_value2 == str);
     995             : 
     996           1 :             CATCH_REQUIRE(unknown_ref == str);
     997             :         }
     998             : 
     999          50 :         CATCH_WHEN("with = & unknown reference")
    1000             :         {
    1001           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1002             : 
    1003           1 :             unknown_ref = undefined_ref;
    1004             : 
    1005           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1006             : 
    1007           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == "");
    1008             : 
    1009           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1010           1 :             CATCH_REQUIRE(unknown_value == std::string());
    1011             : 
    1012           1 :             CATCH_REQUIRE(unknown_ref == std::string());
    1013             :         }
    1014             : 
    1015          50 :         CATCH_WHEN("with = & self reference")
    1016             :         {
    1017           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1018             : 
    1019           1 :             unknown_ref = unknown_ref;
    1020             : 
    1021           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1022             : 
    1023           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == "");
    1024             : 
    1025           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1026           1 :             CATCH_REQUIRE(unknown_value == std::string());
    1027             : 
    1028           1 :             CATCH_REQUIRE(unknown_ref == std::string());
    1029             : 
    1030           1 :             CATCH_REQUIRE(unknown_ref == unknown_ref);
    1031             :         }
    1032             : 
    1033          50 :         CATCH_WHEN("with = & known reference")
    1034             :         {
    1035           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1036             : 
    1037           1 :             unknown_ref = verbose_ref;
    1038             : 
    1039           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1040             : 
    1041           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == verbose_value);
    1042             : 
    1043           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1044           1 :             CATCH_REQUIRE(unknown_value == verbose_value);
    1045             : 
    1046           1 :             CATCH_REQUIRE(unknown_ref == verbose_value);
    1047             : 
    1048           1 :             unknown_ref += reference_ref;
    1049             : 
    1050           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1051             : 
    1052           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == verbose_value + reference_value);
    1053             : 
    1054           2 :             std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1055           1 :             CATCH_REQUIRE(unknown_value2 == verbose_value + reference_value);
    1056             : 
    1057           1 :             CATCH_REQUIRE(unknown_ref == verbose_value + reference_value);
    1058             :         }
    1059             : 
    1060          50 :         CATCH_WHEN("with += & zero char")
    1061             :         {
    1062           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1063             : 
    1064           1 :             char const c('\0');
    1065           1 :             unknown_ref += c;
    1066             : 
    1067           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1068             : 
    1069           2 :             std::string s;
    1070           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
    1071             : 
    1072           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1073           1 :             CATCH_REQUIRE(unknown_value == s);
    1074             : 
    1075           1 :             CATCH_REQUIRE(unknown_ref == s);
    1076             :         }
    1077             : 
    1078          50 :         CATCH_WHEN("with += & valid char")
    1079             :         {
    1080           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1081             : 
    1082           1 :             char const c(rand() % 26 + 'a');
    1083           1 :             unknown_ref += c;
    1084             : 
    1085           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1086             : 
    1087           2 :             std::string s;
    1088           1 :             s += c;
    1089           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
    1090             : 
    1091           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1092           1 :             CATCH_REQUIRE(unknown_value == s);
    1093             : 
    1094           1 :             CATCH_REQUIRE(unknown_ref == s);
    1095             :         }
    1096             : 
    1097          50 :         CATCH_WHEN("with += & zero char32_t")
    1098             :         {
    1099           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1100             : 
    1101           1 :             char32_t const c(U'\0');
    1102           1 :             unknown_ref += c;
    1103             : 
    1104           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1105             : 
    1106           2 :             std::string s;
    1107           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
    1108             : 
    1109           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1110           1 :             CATCH_REQUIRE(unknown_value == s);
    1111             : 
    1112           1 :             CATCH_REQUIRE(unknown_ref == s);
    1113             :         }
    1114             : 
    1115          50 :         CATCH_WHEN("with += & valid char32_t")
    1116             :         {
    1117           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1118             : 
    1119           1 :             char32_t c((rand() & 0xFFFFF) + ' ');
    1120           1 :             if(c >= 0xD800 && c < 0xE000)
    1121             :             {
    1122           0 :                 c += 0x0800;
    1123             :             }
    1124             : 
    1125           1 :             unknown_ref += c;
    1126             : 
    1127           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1128             : 
    1129           2 :             std::string s;
    1130           1 :             s += libutf8::to_u8string(c);
    1131           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
    1132             : 
    1133           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1134           1 :             CATCH_REQUIRE(unknown_value == s);
    1135             : 
    1136           1 :             CATCH_REQUIRE(unknown_ref == s);
    1137             :         }
    1138             : 
    1139          50 :         CATCH_WHEN("with += & nullptr of 'char const *'")
    1140             :         {
    1141           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1142             : 
    1143           1 :             char const * str(nullptr);
    1144             : 
    1145           1 :             unknown_ref += str;
    1146             : 
    1147           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1148             : 
    1149           2 :             std::string s;
    1150           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
    1151             : 
    1152           2 :             std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1153           1 :             CATCH_REQUIRE(unknown_value2 == s);
    1154             : 
    1155           1 :             CATCH_REQUIRE(unknown_ref == s);
    1156             :         }
    1157             : 
    1158          50 :         CATCH_WHEN("with += & empty 'char const *' string")
    1159             :         {
    1160           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1161             : 
    1162           1 :             char const * str("");
    1163             : 
    1164           1 :             unknown_ref += str;
    1165             : 
    1166           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1167             : 
    1168           2 :             std::string s;
    1169           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
    1170             : 
    1171           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1172           1 :             CATCH_REQUIRE(unknown_value == s);
    1173             : 
    1174           1 :             CATCH_REQUIRE(unknown_ref == s);
    1175             :         }
    1176             : 
    1177          50 :         CATCH_WHEN("with += & valid `char const *`")
    1178             :         {
    1179           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1180             : 
    1181           2 :             std::string str;
    1182           1 :             size_t max(rand() % 10 + 1);
    1183          11 :             for(size_t idx(0); idx < max; ++idx)
    1184             :             {
    1185          10 :                 char32_t c((rand() & 0xFFFFF) + ' ');
    1186          10 :                 if(c >= 0xD800 && c < 0xE000)
    1187             :                 {
    1188           0 :                     c += 0x0800;
    1189             :                 }
    1190          10 :                 str += libutf8::to_u8string(c);
    1191             :             }
    1192             : 
    1193           1 :             unknown_ref += str.c_str();
    1194             : 
    1195           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1196             : 
    1197           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == str);
    1198             : 
    1199           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1200           1 :             CATCH_REQUIRE(unknown_value == str);
    1201             : 
    1202           1 :             CATCH_REQUIRE(unknown_ref == str);
    1203             :         }
    1204             : 
    1205          50 :         CATCH_WHEN("with += & empty std::string")
    1206             :         {
    1207           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1208             : 
    1209           2 :             std::string str;
    1210           1 :             unknown_ref += str;
    1211             : 
    1212           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1213             : 
    1214           2 :             std::string s;
    1215           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == s);
    1216             : 
    1217           2 :             std::string const unknown_value2(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1218           1 :             CATCH_REQUIRE(unknown_value2 == s);
    1219             : 
    1220           1 :             CATCH_REQUIRE(unknown_ref == s);
    1221             :         }
    1222             : 
    1223          50 :         CATCH_WHEN("with += & valid std::string")
    1224             :         {
    1225           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1226             : 
    1227           2 :             std::string str;
    1228           1 :             size_t max(rand() % 10 + 1);
    1229           3 :             for(size_t idx(0); idx < max; ++idx)
    1230             :             {
    1231           2 :                 char32_t c((rand() & 0xFFFFF) + ' ');
    1232           2 :                 if(c >= 0xD800 && c < 0xE000)
    1233             :                 {
    1234           0 :                     c += 0x0800;
    1235             :                 }
    1236           2 :                 str += libutf8::to_u8string(c);
    1237             :             }
    1238           1 :             unknown_ref += str;
    1239             : 
    1240           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1241             : 
    1242           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == str);
    1243             : 
    1244           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1245           1 :             CATCH_REQUIRE(unknown_value == str);
    1246             : 
    1247           1 :             CATCH_REQUIRE(unknown_ref == str);
    1248             :         }
    1249             : 
    1250          50 :         CATCH_WHEN("with += & unknown reference")
    1251             :         {
    1252           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1253             : 
    1254           1 :             unknown_ref += undefined_ref;
    1255             : 
    1256           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1257             : 
    1258           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == "");
    1259             : 
    1260           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1261           1 :             CATCH_REQUIRE(unknown_value == std::string());
    1262             : 
    1263           1 :             CATCH_REQUIRE(unknown_ref == std::string());
    1264             :         }
    1265             : 
    1266          50 :         CATCH_WHEN("with += & self reference")
    1267             :         {
    1268           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1269             : 
    1270           1 :             unknown_ref += unknown_ref;
    1271             : 
    1272           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1273             : 
    1274           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == "");
    1275             : 
    1276           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1277           1 :             CATCH_REQUIRE(unknown_value == std::string());
    1278             : 
    1279           1 :             CATCH_REQUIRE(unknown_ref == std::string());
    1280             : 
    1281           1 :             CATCH_REQUIRE(unknown_ref == unknown_ref);
    1282             :         }
    1283             : 
    1284          50 :         CATCH_WHEN("with += & known reference")
    1285             :         {
    1286           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1287             : 
    1288           1 :             unknown_ref += reference_ref;
    1289             : 
    1290           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1291             : 
    1292           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == reference_value);
    1293             : 
    1294           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1295           1 :             CATCH_REQUIRE(unknown_value == reference_value);
    1296             : 
    1297           1 :             CATCH_REQUIRE(unknown_ref == reference_value);
    1298             :         }
    1299             : 
    1300          50 :         CATCH_WHEN("with += & self reference")
    1301             :         {
    1302           1 :             CATCH_REQUIRE_FALSE(opt.is_defined("unknown"));
    1303             : 
    1304           1 :             unknown_ref += unknown_ref;
    1305             : 
    1306           1 :             CATCH_REQUIRE(opt.is_defined("unknown"));
    1307             : 
    1308           1 :             CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["unknown"] == "");
    1309             : 
    1310           2 :             std::string const unknown_value(const_cast<advgetopt::getopt const &>(opt)["unknown"]);
    1311           1 :             CATCH_REQUIRE(unknown_value == "");
    1312             : 
    1313           1 :             CATCH_REQUIRE(unknown_ref == "");
    1314             :         }
    1315             :     }
    1316             :     CATCH_END_SECTION()
    1317          27 : }
    1318             : 
    1319             : 
    1320             : 
    1321           4 : CATCH_TEST_CASE("option_info_ref_with_valid_default", "[option_info][valid][reference][long][default]")
    1322             : {
    1323           4 :     CATCH_START_SECTION("No reference on command line, valid default for get_long()")
    1324             :     {
    1325           1 :         advgetopt::option const options[] =
    1326             :         {
    1327             :             advgetopt::define_option(
    1328             :                   advgetopt::Name("reference")
    1329             :                 , advgetopt::ShortName('r')
    1330             :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1331             :                 , advgetopt::Help("test reference.")
    1332             :                 , advgetopt::DefaultValue("459")
    1333             :             ),
    1334             :             advgetopt::define_option(
    1335             :                   advgetopt::Name("verbose")
    1336             :                 , advgetopt::ShortName('v')
    1337             :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1338             :                 , advgetopt::Help("make it all verbose.")
    1339             :             ),
    1340             :             advgetopt::end_options()
    1341             :         };
    1342             : 
    1343           1 :         advgetopt::options_environment environment_options;
    1344           1 :         environment_options.f_project_name = "unittest";
    1345           1 :         environment_options.f_options = options;
    1346           1 :         environment_options.f_help_header = "Usage: verify references";
    1347             : 
    1348           1 :         char const * cargv[] =
    1349             :         {
    1350             :             "/usr/bin/arguments",
    1351             :             "--verbose",
    1352             :             "loud",
    1353             :             nullptr
    1354             :         };
    1355           1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
    1356           1 :         char ** argv = const_cast<char **>(cargv);
    1357             : 
    1358           2 :         advgetopt::getopt opt(environment_options, argc, argv);
    1359             : 
    1360             :         // check that the result is valid
    1361             : 
    1362             :         // verify both parameters the "normal" way
    1363           1 :         CATCH_REQUIRE(opt.get_option("reference") != nullptr);
    1364           1 :         CATCH_REQUIRE(opt.size("reference") == 0);
    1365           1 :         CATCH_REQUIRE(opt.get_string("reference") == "459");
    1366             : 
    1367           1 :         CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
    1368           1 :         CATCH_REQUIRE(opt.size("verbose") == 1);
    1369           1 :         CATCH_REQUIRE(opt.get_string("verbose") == "loud");
    1370             : 
    1371             :         // check the read-only verbose which does not create a reference
    1372           1 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "459");
    1373           1 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "loud");
    1374             : 
    1375           2 :         std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
    1376           1 :         CATCH_REQUIRE(reference_value == "459");
    1377           2 :         std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
    1378           1 :         CATCH_REQUIRE(verbose_value == "loud");
    1379             : 
    1380             :         // get a reference
    1381           2 :         advgetopt::option_info_ref reference_ref(opt["reference"]);
    1382           2 :         advgetopt::option_info_ref verbose_ref(opt["verbose"]);
    1383             : 
    1384           1 :         CATCH_REQUIRE(reference_ref.empty());
    1385           1 :         CATCH_REQUIRE_FALSE(verbose_ref.empty());
    1386             : 
    1387           1 :         CATCH_REQUIRE(reference_ref.length() == 3);
    1388           1 :         CATCH_REQUIRE(reference_ref.size() == 3);
    1389           1 :         CATCH_REQUIRE(verbose_ref.length() == 4);
    1390           1 :         CATCH_REQUIRE(verbose_ref.size() == 4);
    1391             : 
    1392           1 :         CATCH_REQUIRE(reference_ref.get_long() == 459);
    1393             : 
    1394           1 :         CATCH_REQUIRE(reference_ref == reference_ref);
    1395           1 :         CATCH_REQUIRE_FALSE(reference_ref != reference_ref);
    1396           1 :         CATCH_REQUIRE_FALSE(reference_ref < reference_ref);
    1397           1 :         CATCH_REQUIRE(reference_ref <= reference_ref);
    1398           1 :         CATCH_REQUIRE_FALSE(reference_ref > reference_ref);
    1399           1 :         CATCH_REQUIRE(reference_ref >= reference_ref);
    1400             : 
    1401           1 :         CATCH_REQUIRE_FALSE(reference_ref == verbose_ref);
    1402           1 :         CATCH_REQUIRE(reference_ref != verbose_ref);
    1403           1 :         CATCH_REQUIRE(reference_ref < verbose_ref);
    1404           1 :         CATCH_REQUIRE(reference_ref <= verbose_ref);
    1405           1 :         CATCH_REQUIRE_FALSE(reference_ref > verbose_ref);
    1406           1 :         CATCH_REQUIRE_FALSE(reference_ref >= verbose_ref);
    1407             :     }
    1408             :     CATCH_END_SECTION()
    1409             : 
    1410           4 :     CATCH_START_SECTION("No reference on command line, valid default for get_double()")
    1411             :     {
    1412           1 :         advgetopt::option const options[] =
    1413             :         {
    1414             :             advgetopt::define_option(
    1415             :                   advgetopt::Name("reference")
    1416             :                 , advgetopt::ShortName('r')
    1417             :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1418             :                 , advgetopt::Help("test reference.")
    1419             :                 , advgetopt::DefaultValue("45.9")
    1420             :             ),
    1421             :             advgetopt::define_option(
    1422             :                   advgetopt::Name("verbose")
    1423             :                 , advgetopt::ShortName('v')
    1424             :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1425             :                 , advgetopt::Help("make it all verbose.")
    1426             :             ),
    1427             :             advgetopt::end_options()
    1428             :         };
    1429             : 
    1430           1 :         advgetopt::options_environment environment_options;
    1431           1 :         environment_options.f_project_name = "unittest";
    1432           1 :         environment_options.f_options = options;
    1433           1 :         environment_options.f_help_header = "Usage: verify references";
    1434             : 
    1435           1 :         char const * cargv[] =
    1436             :         {
    1437             :             "/usr/bin/arguments",
    1438             :             "--verbose",
    1439             :             "loud",
    1440             :             nullptr
    1441             :         };
    1442           1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
    1443           1 :         char ** argv = const_cast<char **>(cargv);
    1444             : 
    1445           2 :         advgetopt::getopt opt(environment_options, argc, argv);
    1446             : 
    1447             :         // check that the result is valid
    1448             : 
    1449             :         // verify both parameters the "normal" way
    1450           1 :         CATCH_REQUIRE(opt.get_option("reference") != nullptr);
    1451           1 :         CATCH_REQUIRE(opt.size("reference") == 0);
    1452           1 :         CATCH_REQUIRE(opt.get_string("reference") == "45.9");
    1453             : 
    1454           1 :         CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
    1455           1 :         CATCH_REQUIRE(opt.size("verbose") == 1);
    1456           1 :         CATCH_REQUIRE(opt.get_string("verbose") == "loud");
    1457             : 
    1458             :         // check the read-only verbose which does not create a reference
    1459           1 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "45.9");
    1460           1 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "loud");
    1461             : 
    1462           2 :         std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
    1463           1 :         CATCH_REQUIRE(reference_value == "45.9");
    1464           2 :         std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
    1465           1 :         CATCH_REQUIRE(verbose_value == "loud");
    1466             : 
    1467             :         // get a reference
    1468           2 :         advgetopt::option_info_ref reference_ref(opt["reference"]);
    1469           2 :         advgetopt::option_info_ref verbose_ref(opt["verbose"]);
    1470             : 
    1471           1 :         CATCH_REQUIRE(reference_ref.empty());
    1472           1 :         CATCH_REQUIRE_FALSE(verbose_ref.empty());
    1473             : 
    1474           1 :         CATCH_REQUIRE(reference_ref.length() == 4);
    1475           1 :         CATCH_REQUIRE(reference_ref.size() == 4);
    1476           1 :         CATCH_REQUIRE(verbose_ref.length() == 4);
    1477           1 :         CATCH_REQUIRE(verbose_ref.size() == 4);
    1478             : 
    1479             : #pragma GCC diagnostic push
    1480             : #pragma GCC diagnostic ignored "-Wfloat-equal"
    1481             :         {
    1482           1 :             bool const a1(reference_ref.get_double() == 45.9);
    1483           1 :             CATCH_REQUIRE(a1);
    1484             :         }
    1485             : #pragma GCC diagnostic pop
    1486             : 
    1487           1 :         CATCH_REQUIRE(reference_ref == reference_ref);
    1488           1 :         CATCH_REQUIRE_FALSE(reference_ref != reference_ref);
    1489           1 :         CATCH_REQUIRE_FALSE(reference_ref < reference_ref);
    1490           1 :         CATCH_REQUIRE(reference_ref <= reference_ref);
    1491           1 :         CATCH_REQUIRE_FALSE(reference_ref > reference_ref);
    1492           1 :         CATCH_REQUIRE(reference_ref >= reference_ref);
    1493             : 
    1494           1 :         CATCH_REQUIRE_FALSE(reference_ref == verbose_ref);
    1495           1 :         CATCH_REQUIRE(reference_ref != verbose_ref);
    1496           1 :         CATCH_REQUIRE(reference_ref < verbose_ref);
    1497           1 :         CATCH_REQUIRE(reference_ref <= verbose_ref);
    1498           1 :         CATCH_REQUIRE_FALSE(reference_ref > verbose_ref);
    1499           1 :         CATCH_REQUIRE_FALSE(reference_ref >= verbose_ref);
    1500             :     }
    1501             :     CATCH_END_SECTION()
    1502           2 : }
    1503             : 
    1504             : 
    1505             : 
    1506           4 : CATCH_TEST_CASE("option_info_ref_with_invalid_default", "[option_info][invalid][reference][long][default]")
    1507             : {
    1508           4 :     CATCH_START_SECTION("No reference on command line, not valid for get_long()")
    1509             :     {
    1510           1 :         advgetopt::option const options[] =
    1511             :         {
    1512             :             advgetopt::define_option(
    1513             :                   advgetopt::Name("reference")
    1514             :                 , advgetopt::ShortName('r')
    1515             :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1516             :                 , advgetopt::Help("test reference.")
    1517             :                 , advgetopt::DefaultValue("undefined")
    1518             :             ),
    1519             :             advgetopt::define_option(
    1520             :                   advgetopt::Name("verbose")
    1521             :                 , advgetopt::ShortName('v')
    1522             :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1523             :                 , advgetopt::Help("make it all verbose.")
    1524             :             ),
    1525             :             advgetopt::end_options()
    1526             :         };
    1527             : 
    1528           1 :         advgetopt::options_environment environment_options;
    1529           1 :         environment_options.f_project_name = "unittest";
    1530           1 :         environment_options.f_options = options;
    1531           1 :         environment_options.f_help_header = "Usage: verify references";
    1532             : 
    1533           1 :         char const * cargv[] =
    1534             :         {
    1535             :             "/usr/bin/arguments",
    1536             :             "--verbose",
    1537             :             "loud",
    1538             :             nullptr
    1539             :         };
    1540           1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
    1541           1 :         char ** argv = const_cast<char **>(cargv);
    1542             : 
    1543           2 :         advgetopt::getopt opt(environment_options, argc, argv);
    1544             : 
    1545             :         // check that the result is valid
    1546             : 
    1547             :         // verify both parameters the "normal" way
    1548           1 :         CATCH_REQUIRE(opt.get_option("reference") != nullptr);
    1549           1 :         CATCH_REQUIRE(opt.size("reference") == 0);
    1550           1 :         CATCH_REQUIRE(opt.get_string("reference") == "undefined");
    1551             : 
    1552           1 :         CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
    1553           1 :         CATCH_REQUIRE(opt.size("verbose") == 1);
    1554           1 :         CATCH_REQUIRE(opt.get_string("verbose") == "loud");
    1555             : 
    1556             :         // check the read-only verbose which does not create a reference
    1557           1 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "undefined");
    1558           1 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "loud");
    1559             : 
    1560           2 :         std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
    1561           1 :         CATCH_REQUIRE(reference_value == "undefined");
    1562           2 :         std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
    1563           1 :         CATCH_REQUIRE(verbose_value == "loud");
    1564             : 
    1565             :         // get a reference
    1566           2 :         advgetopt::option_info_ref reference_ref(opt["reference"]);
    1567           2 :         advgetopt::option_info_ref verbose_ref(opt["verbose"]);
    1568             : 
    1569           1 :         CATCH_REQUIRE(reference_ref.empty());
    1570           1 :         CATCH_REQUIRE_FALSE(verbose_ref.empty());
    1571             : 
    1572           1 :         CATCH_REQUIRE(reference_ref.length() == 9);
    1573           1 :         CATCH_REQUIRE(reference_ref.size() == 9);
    1574           1 :         CATCH_REQUIRE(verbose_ref.length() == 4);
    1575           1 :         CATCH_REQUIRE(verbose_ref.size() == 4);
    1576             : 
    1577           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid default value for a number (undefined) in parameter --reference at offset 0.");
    1578           1 :         CATCH_REQUIRE(reference_ref.get_long() == -1);
    1579           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1580             : 
    1581           1 :         CATCH_REQUIRE(reference_ref == reference_ref);
    1582           1 :         CATCH_REQUIRE_FALSE(reference_ref != reference_ref);
    1583           1 :         CATCH_REQUIRE_FALSE(reference_ref < reference_ref);
    1584           1 :         CATCH_REQUIRE(reference_ref <= reference_ref);
    1585           1 :         CATCH_REQUIRE_FALSE(reference_ref > reference_ref);
    1586           1 :         CATCH_REQUIRE(reference_ref >= reference_ref);
    1587             : 
    1588           1 :         CATCH_REQUIRE_FALSE(reference_ref == verbose_ref);
    1589           1 :         CATCH_REQUIRE(reference_ref != verbose_ref);
    1590           1 :         CATCH_REQUIRE_FALSE(reference_ref < verbose_ref);
    1591           1 :         CATCH_REQUIRE_FALSE(reference_ref <= verbose_ref);
    1592           1 :         CATCH_REQUIRE(reference_ref > verbose_ref);
    1593           1 :         CATCH_REQUIRE(reference_ref >= verbose_ref);
    1594             :     }
    1595             :     CATCH_END_SECTION()
    1596             : 
    1597           4 :     CATCH_START_SECTION("No reference on command line, not valid for get_double()")
    1598             :     {
    1599           1 :         advgetopt::option const options[] =
    1600             :         {
    1601             :             advgetopt::define_option(
    1602             :                   advgetopt::Name("reference")
    1603             :                 , advgetopt::ShortName('r')
    1604             :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1605             :                 , advgetopt::Help("test reference.")
    1606             :                 , advgetopt::DefaultValue("undefined")
    1607             :             ),
    1608             :             advgetopt::define_option(
    1609             :                   advgetopt::Name("verbose")
    1610             :                 , advgetopt::ShortName('v')
    1611             :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1612             :                 , advgetopt::Help("make it all verbose.")
    1613             :             ),
    1614             :             advgetopt::end_options()
    1615             :         };
    1616             : 
    1617           1 :         advgetopt::options_environment environment_options;
    1618           1 :         environment_options.f_project_name = "unittest";
    1619           1 :         environment_options.f_options = options;
    1620           1 :         environment_options.f_help_header = "Usage: verify references";
    1621             : 
    1622           1 :         char const * cargv[] =
    1623             :         {
    1624             :             "/usr/bin/arguments",
    1625             :             "--verbose",
    1626             :             "loud",
    1627             :             nullptr
    1628             :         };
    1629           1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
    1630           1 :         char ** argv = const_cast<char **>(cargv);
    1631             : 
    1632           2 :         advgetopt::getopt opt(environment_options, argc, argv);
    1633             : 
    1634             :         // check that the result is valid
    1635             : 
    1636             :         // verify both parameters the "normal" way
    1637           1 :         CATCH_REQUIRE(opt.get_option("reference") != nullptr);
    1638           1 :         CATCH_REQUIRE(opt.size("reference") == 0);
    1639           1 :         CATCH_REQUIRE(opt.get_string("reference") == "undefined");
    1640             : 
    1641           1 :         CATCH_REQUIRE(opt.get_option("verbose") != nullptr);
    1642           1 :         CATCH_REQUIRE(opt.size("verbose") == 1);
    1643           1 :         CATCH_REQUIRE(opt.get_string("verbose") == "loud");
    1644             : 
    1645             :         // check the read-only verbose which does not create a reference
    1646           1 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["reference"] == "undefined");
    1647           1 :         CATCH_REQUIRE(const_cast<advgetopt::getopt const &>(opt)["verbose"] == "loud");
    1648             : 
    1649           2 :         std::string const reference_value(const_cast<advgetopt::getopt const &>(opt)["reference"]);
    1650           1 :         CATCH_REQUIRE(reference_value == "undefined");
    1651           2 :         std::string const verbose_value(const_cast<advgetopt::getopt const &>(opt)["verbose"]);
    1652           1 :         CATCH_REQUIRE(verbose_value == "loud");
    1653             : 
    1654             :         // get a reference
    1655           2 :         advgetopt::option_info_ref reference_ref(opt["reference"]);
    1656           2 :         advgetopt::option_info_ref verbose_ref(opt["verbose"]);
    1657             : 
    1658           1 :         CATCH_REQUIRE(reference_ref.empty());
    1659           1 :         CATCH_REQUIRE_FALSE(verbose_ref.empty());
    1660             : 
    1661           1 :         CATCH_REQUIRE(reference_ref.length() == 9);
    1662           1 :         CATCH_REQUIRE(reference_ref.size() == 9);
    1663           1 :         CATCH_REQUIRE(verbose_ref.length() == 4);
    1664           1 :         CATCH_REQUIRE(verbose_ref.size() == 4);
    1665             : 
    1666             : #pragma GCC diagnostic push
    1667             : #pragma GCC diagnostic ignored "-Wfloat-equal"
    1668             :         {
    1669           1 :             SNAP_CATCH2_NAMESPACE::push_expected_log("error: invalid default value as a double number (undefined) in parameter --reference at offset 0.");
    1670           1 :             bool const a1(reference_ref.get_double() == -1);
    1671           1 :             CATCH_REQUIRE(a1);
    1672           1 :             SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1673             :         }
    1674             : #pragma GCC diagnostic pop
    1675             : 
    1676           1 :         CATCH_REQUIRE(reference_ref == reference_ref);
    1677           1 :         CATCH_REQUIRE_FALSE(reference_ref != reference_ref);
    1678           1 :         CATCH_REQUIRE_FALSE(reference_ref < reference_ref);
    1679           1 :         CATCH_REQUIRE(reference_ref <= reference_ref);
    1680           1 :         CATCH_REQUIRE_FALSE(reference_ref > reference_ref);
    1681           1 :         CATCH_REQUIRE(reference_ref >= reference_ref);
    1682             : 
    1683           1 :         CATCH_REQUIRE_FALSE(reference_ref == verbose_ref);
    1684           1 :         CATCH_REQUIRE(reference_ref != verbose_ref);
    1685           1 :         CATCH_REQUIRE_FALSE(reference_ref < verbose_ref);
    1686           1 :         CATCH_REQUIRE_FALSE(reference_ref <= verbose_ref);
    1687           1 :         CATCH_REQUIRE(reference_ref > verbose_ref);
    1688           1 :         CATCH_REQUIRE(reference_ref >= verbose_ref);
    1689             :     }
    1690             :     CATCH_END_SECTION()
    1691           8 : }
    1692             : 
    1693             : 
    1694             : 
    1695             : 
    1696             : 
    1697             : 
    1698             : 
    1699             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13