LCOV - code coverage report
Current view: top level - tests - option_info_ref.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 850 860 98.8 %
Date: 2021-09-08 13:54:31 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13