LCOV - code coverage report
Current view: top level - tests - catch_options_sources.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 314 314 100.0 %
Date: 2022-07-15 09:02:52 Functions: 4 4 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             : // boost
      31             : //
      32             : #include    <boost/algorithm/string/replace.hpp>
      33             : 
      34             : 
      35             : // snapdev
      36             : //
      37             : #include    <snapdev/safe_setenv.h>
      38             : 
      39             : 
      40             : // C++
      41             : //
      42             : #include    <fstream>
      43             : 
      44             : 
      45             : // last include
      46             : //
      47             : #include    <snapdev/poison.h>
      48             : 
      49             : 
      50             : 
      51             : 
      52             : 
      53           3 : CATCH_TEST_CASE("options_sources", "[options][sources][valid]")
      54             : {
      55           2 :     CATCH_START_SECTION("System options only")
      56             :     {
      57           1 :         advgetopt::option const options[] =
      58             :         {
      59             :             advgetopt::define_option(
      60             :                   advgetopt::Name("verbose")
      61             :                 , advgetopt::ShortName('v')
      62             :                 , advgetopt::Flags(advgetopt::command_flags<
      63             :                               advgetopt::GETOPT_FLAG_REQUIRED
      64             :                             | advgetopt::GETOPT_FLAG_DYNAMIC_CONFIGURATION>())
      65             :                 , advgetopt::Help("make it all verbose.")
      66             :             ),
      67             :             advgetopt::end_options()
      68             :         };
      69             : 
      70           1 :         advgetopt::options_environment environment_options;
      71           1 :         environment_options.f_project_name = "unittest";
      72           1 :         environment_options.f_group_name = "sources";
      73           1 :         environment_options.f_options = options;
      74           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
      75           1 :         environment_options.f_help_header = "Usage: test valid options from system options only";
      76             : 
      77           1 :         char const * cargv[] =
      78             :         {
      79             :             "tests/options-parser",
      80             :             "--license",
      81             :             "--show-option-sources",
      82             :             "--version",
      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           2 :         advgetopt::option_info::pointer_t verbose(opt.get_option("verbose"));
      91           1 :         CATCH_REQUIRE(verbose != nullptr);
      92           1 :         verbose->set_value(0, "true");
      93             : 
      94           2 :         advgetopt::option_info::pointer_t copyright(opt.get_option("copyright"));
      95           1 :         CATCH_REQUIRE(copyright != nullptr);
      96           1 :         copyright->set_value(0, "1", advgetopt::option_source_t::SOURCE_DYNAMIC);
      97           1 :         copyright->reset();
      98             : 
      99           2 :         advgetopt::option_info::pointer_t version(opt.get_option("version"));
     100           1 :         CATCH_REQUIRE(version != nullptr);
     101             : 
     102           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: option \"--version\" can't be directly updated.");
     103           1 :         version->set_value(0, "true");
     104           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
     105             : 
     106             :         // check that we got source info as expected
     107             : 
     108           2 :         advgetopt::option_info::pointer_t license(opt.get_option("license"));
     109           1 :         CATCH_REQUIRE(license != nullptr);
     110           2 :         advgetopt::string_list_t license_sources(license->trace_sources());
     111           1 :         CATCH_REQUIRE(license_sources.size() == 1);
     112           1 :         CATCH_REQUIRE(license_sources[0] == "license= [command-line]");
     113             : 
     114           2 :         advgetopt::option_info::pointer_t show(opt.get_option("show-option-sources"));
     115           1 :         CATCH_REQUIRE(show != nullptr);
     116           2 :         advgetopt::string_list_t show_option_sources(show->trace_sources());
     117           1 :         CATCH_REQUIRE(show_option_sources.size() == 1);
     118           1 :         CATCH_REQUIRE(show_option_sources[0] == "show-option-sources= [command-line]");
     119             : 
     120           2 :         advgetopt::string_list_t verbose_sources(verbose->trace_sources());
     121           1 :         CATCH_REQUIRE(verbose_sources.size() == 1);
     122           1 :         CATCH_REQUIRE(verbose_sources[0] == "verbose=true [direct]");
     123             : 
     124           2 :         advgetopt::option_info::pointer_t help(opt.get_option("help"));
     125           1 :         CATCH_REQUIRE(help != nullptr);
     126           2 :         advgetopt::string_list_t help_sources(help->trace_sources());
     127           1 :         CATCH_REQUIRE(help_sources.size() == 0);
     128             : 
     129           2 :         advgetopt::string_list_t copyright_sources(copyright->trace_sources());
     130           1 :         CATCH_REQUIRE(copyright_sources.size() == 2);
     131           1 :         CATCH_REQUIRE(copyright_sources[0] == "copyright=1 [dynamic]");
     132           1 :         CATCH_REQUIRE(copyright_sources[1] == "copyright [*undefined-source*]");
     133             : 
     134             :         // process system options now
     135           2 :         std::stringstream ss;
     136           1 :         advgetopt::flag_t const result(opt.process_system_options(ss));
     137           1 :         CATCH_REQUIRE(result == (advgetopt::SYSTEM_OPTION_SHOW_OPTION_SOURCES
     138             :                                | advgetopt::SYSTEM_OPTION_VERSION
     139             :                                | advgetopt::SYSTEM_OPTION_LICENSE));
     140           1 :         CATCH_REQUIRE_LONG_STRING(ss.str(),
     141             : "warning: no version found.\n"
     142             : "warning: no license found.\n"
     143             : "Option Sources:\n"
     144             : "  1. option \"build-date\" (undefined)\n"
     145             : "\n"
     146             : "  2. option \"compiler-version\" (undefined)\n"
     147             : "\n"
     148             : "  3. option \"configuration-filenames\" (undefined)\n"
     149             : "\n"
     150             : "  4. option \"copyright\"\n"
     151             : "     copyright=1 [dynamic]\n"
     152             : "     copyright [*undefined-source*]\n"
     153             : "\n"
     154             : "  5. option \"environment-variable-name\" (undefined)\n"
     155             : "\n"
     156             : "  6. option \"has-sanitizer\" (undefined)\n"
     157             : "\n"
     158             : "  7. option \"help\" (undefined)\n"
     159             : "\n"
     160             : "  8. option \"license\"\n"
     161             : "     license= [command-line]\n"
     162             : "\n"
     163             : "  9. option \"path-to-option-definitions\" (undefined)\n"
     164             : "\n"
     165             : "  10. option \"print-option\" (undefined)\n"
     166             : "\n"
     167             : "  11. option \"show-option-sources\"\n"
     168             : "     show-option-sources= [command-line]\n"
     169             : "\n"
     170             : "  12. option \"verbose\"\n"
     171             : "     verbose=true [direct]\n"
     172             : "\n"
     173             : "  13. option \"version\"\n"
     174             : "     version= [command-line]\n"
     175             : "\n"
     176             : );
     177             :     }
     178             :     CATCH_END_SECTION()
     179           1 : }
     180             : 
     181             : 
     182           4 : CATCH_TEST_CASE("options_sources_environment_variable_and_config_file", "[options][sources][valid][config][environment_variable]")
     183             : {
     184           4 :     CATCH_START_SECTION("load options from a config file, environment variable, and command line with --config-dir on the command line")
     185             :     {
     186           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("sources", "src");
     187             : 
     188             :         {
     189           2 :             std::ofstream config_file;
     190           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     191           1 :             CATCH_REQUIRE(config_file.good());
     192           1 :             config_file <<
     193             :                 "# Auto-generated\n"
     194             :                 "unique     = perfect  \n"
     195             :                 "definition = long value here\n"
     196             :                 "sources    = just fine \t\n"
     197             :                 "multiple   = value\r\n"
     198             :                 "good       = variable \n"
     199             :                 "organized  = set\n"
     200             :                 "more       = data\t \n"
     201             :             ;
     202             :         }
     203             : 
     204           1 :         advgetopt::option const options[] =
     205             :         {
     206             :             advgetopt::define_option(
     207             :                   advgetopt::Name("unique")
     208             :                 , advgetopt::ShortName('u')
     209             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     210             :                 , advgetopt::Help("unique option.")
     211             :                 , advgetopt::DefaultValue("long")
     212             :             ),
     213             :             advgetopt::define_option(
     214             :                   advgetopt::Name("color")
     215             :                 , advgetopt::ShortName('c')
     216             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     217             :                                                       , advgetopt::GETOPT_FLAG_MULTIPLE
     218             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP2>())
     219             :                 , advgetopt::Help("specify a color.")
     220             :             ),
     221             :             advgetopt::define_option(
     222             :                   advgetopt::Name("definition")
     223             :                 , advgetopt::ShortName('d')
     224             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     225             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP1>())
     226             :                 , advgetopt::Help("complete definition.")
     227             :             ),
     228             :             advgetopt::define_option(
     229             :                   advgetopt::Name("sources")
     230             :                 , advgetopt::ShortName('s')
     231             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     232             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP2>())
     233             :                 , advgetopt::Help("where it all came from.")
     234             :             ),
     235             :             advgetopt::define_option(
     236             :                   advgetopt::Name("multiple")
     237             :                 , advgetopt::ShortName('m')
     238             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     239             :                                                       , advgetopt::GETOPT_FLAG_MULTIPLE
     240             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP1>())
     241             :                 , advgetopt::Help("whether we have one or more.")
     242             :             ),
     243             :             advgetopt::define_option(
     244             :                   advgetopt::Name("zap")
     245             :                 , advgetopt::ShortName('z')
     246             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_SHOW_GROUP2>())
     247             :                 , advgetopt::Help("zap all of it.")
     248             :             ),
     249             :             advgetopt::define_option(
     250             :                   advgetopt::Name("good")
     251             :                 , advgetopt::ShortName('g')
     252             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     253             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP1>())
     254             :                 , advgetopt::Help("current status.")
     255             :             ),
     256             :             advgetopt::define_option(
     257             :                   advgetopt::Name("organized")
     258             :                 , advgetopt::ShortName('o')
     259             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     260             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP2>())
     261             :                 , advgetopt::Help("how the whole thing was organized.")
     262             :             ),
     263             :             advgetopt::define_option(
     264             :                   advgetopt::Name("more")
     265             :                 , advgetopt::ShortName('+')
     266             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     267             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP1>())
     268             :                 , advgetopt::Help("anything more you can think of.")
     269             :             ),
     270             :             advgetopt::define_option(
     271             :                   advgetopt::Name("verbose")
     272             :                 , advgetopt::ShortName('v')
     273             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_SHOW_GROUP1>())
     274             :                 , advgetopt::Help("anything more you can think of.")
     275             :             ),
     276             :             advgetopt::end_options()
     277             :         };
     278             : 
     279           1 :         snapdev::safe_setenv env(
     280             :                   "ADVGETOPT_TEST_OPTIONS"
     281           2 :                 , "--verbose --more=instructions --color black orange purple --sources=all");
     282             : 
     283           1 :         advgetopt::options_environment environment_options;
     284           1 :         environment_options.f_project_name = "unittest";
     285           1 :         environment_options.f_group_name = "sources";
     286           1 :         environment_options.f_options = options;
     287           1 :         environment_options.f_environment_variable_name = "ADVGETOPT_TEST_OPTIONS";
     288           1 :         environment_options.f_configuration_filename = "src.config";
     289           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     290           1 :         environment_options.f_help_header = "Usage: test source from command line, environment variable, and configuration file";
     291           1 :         environment_options.f_version = "1.2.3";
     292             : 
     293           2 :         std::string const config_dir("--config-dir=" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config");
     294           1 :         char const * cargv[] =
     295             :         {
     296             :             "tests/options-parser",
     297             :             "--version",
     298             :             "--show-option-sources",
     299             :             "--more=magical",
     300             :             "--organized",
     301             :             "logically",
     302             :             "--zap",
     303           1 :             config_dir.c_str(),
     304             :             nullptr
     305           1 :         };
     306           1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
     307           1 :         char ** argv = const_cast<char **>(cargv);
     308             : 
     309           2 :         advgetopt::getopt opt(environment_options, argc, argv);
     310             : 
     311             :         // verify command line options
     312             : 
     313           2 :         advgetopt::option_info::pointer_t version(opt.get_option("version"));
     314           1 :         CATCH_REQUIRE(version != nullptr);
     315           1 :         CATCH_REQUIRE(opt.is_defined("version"));
     316           2 :         advgetopt::string_list_t version_sources(version->trace_sources());
     317           1 :         CATCH_REQUIRE(version_sources.size() == 1);
     318           1 :         CATCH_REQUIRE(version_sources[0] == "version= [command-line]");
     319             : 
     320           2 :         advgetopt::option_info::pointer_t show(opt.get_option("show-option-sources"));
     321           1 :         CATCH_REQUIRE(show != nullptr);
     322           1 :         CATCH_REQUIRE(opt.is_defined("show-option-sources"));
     323           2 :         advgetopt::string_list_t show_option_sources(show->trace_sources());
     324           1 :         CATCH_REQUIRE(show_option_sources.size() == 1);
     325           1 :         CATCH_REQUIRE(show_option_sources[0] == "show-option-sources= [command-line]");
     326             : 
     327           2 :         advgetopt::option_info::pointer_t more(opt.get_option("more"));
     328           1 :         CATCH_REQUIRE(more != nullptr);
     329           1 :         CATCH_REQUIRE(opt.is_defined("more"));
     330           2 :         advgetopt::string_list_t more_sources(more->trace_sources());
     331           1 :         CATCH_REQUIRE(more_sources.size() == 3);
     332           2 :         std::string expected_config("more=data [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]");
     333           1 :         CATCH_REQUIRE(more_sources[0] == expected_config);
     334           1 :         CATCH_REQUIRE(more_sources[1] == "more=instructions [environment-variable]");
     335           1 :         CATCH_REQUIRE(more_sources[2] == "more=magical [command-line]");
     336             : 
     337           2 :         advgetopt::option_info::pointer_t organized(opt.get_option("organized"));
     338           1 :         CATCH_REQUIRE(organized != nullptr);
     339           1 :         CATCH_REQUIRE(opt.is_defined("organized"));
     340           2 :         advgetopt::string_list_t organized_sources(organized->trace_sources());
     341           1 :         CATCH_REQUIRE(organized_sources.size() == 2);
     342           1 :         expected_config = "organized=set [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]";
     343           1 :         CATCH_REQUIRE(organized_sources[0] == expected_config);
     344           1 :         CATCH_REQUIRE(organized_sources[1] == "organized=logically [command-line]");
     345             : 
     346           2 :         advgetopt::option_info::pointer_t zap(opt.get_option("zap"));
     347           1 :         CATCH_REQUIRE(zap != nullptr);
     348           1 :         CATCH_REQUIRE(opt.is_defined("zap"));
     349           2 :         advgetopt::string_list_t zap_sources(zap->trace_sources());
     350           1 :         CATCH_REQUIRE(zap_sources.size() == 1);
     351           1 :         CATCH_REQUIRE(zap_sources[0] == "zap= [command-line]");
     352             : 
     353           2 :         advgetopt::option_info::pointer_t config_dir_opt(opt.get_option("config-dir"));
     354           1 :         CATCH_REQUIRE(config_dir_opt != nullptr);
     355           1 :         CATCH_REQUIRE(opt.is_defined("config_dir"));
     356           2 :         advgetopt::string_list_t config_dir_sources(config_dir_opt->trace_sources());
     357           1 :         CATCH_REQUIRE(config_dir_sources.size() == 1);
     358           1 :         expected_config = "config-dir[0]=" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config [command-line]";
     359           1 :         CATCH_REQUIRE(config_dir_sources[0] == expected_config);
     360             : 
     361             :         // verify environment variable options which are not also on the command line
     362             : 
     363           2 :         advgetopt::option_info::pointer_t verbose(opt.get_option("verbose"));
     364           1 :         CATCH_REQUIRE(verbose != nullptr);
     365           1 :         CATCH_REQUIRE(opt.is_defined("verbose"));
     366           2 :         advgetopt::string_list_t verbose_sources(verbose->trace_sources());
     367           1 :         CATCH_REQUIRE(verbose_sources.size() == 1);
     368           1 :         CATCH_REQUIRE(verbose_sources[0] == "verbose= [environment-variable]");
     369             : 
     370           2 :         advgetopt::option_info::pointer_t color(opt.get_option("color"));
     371           1 :         CATCH_REQUIRE(color != nullptr);
     372           1 :         CATCH_REQUIRE(opt.is_defined("color"));
     373           2 :         advgetopt::string_list_t color_sources(color->trace_sources());
     374           1 :         CATCH_REQUIRE(color_sources.size() == 3);
     375           1 :         CATCH_REQUIRE(color_sources[0] == "color[0]=black [environment-variable]");
     376           1 :         CATCH_REQUIRE(color_sources[1] == "color[1]=orange [environment-variable]");
     377           1 :         CATCH_REQUIRE(color_sources[2] == "color[2]=purple [environment-variable]");
     378             : 
     379           2 :         advgetopt::option_info::pointer_t sources(opt.get_option("sources"));
     380           1 :         CATCH_REQUIRE(sources != nullptr);
     381           1 :         CATCH_REQUIRE(opt.is_defined("sources"));
     382           2 :         advgetopt::string_list_t sources_sources(sources->trace_sources());
     383           1 :         CATCH_REQUIRE(sources_sources.size() == 2);
     384           1 :         expected_config = "sources=just fine [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]";
     385           1 :         CATCH_REQUIRE(sources_sources[0] == expected_config);
     386           1 :         CATCH_REQUIRE(sources_sources[1] == "sources=all [environment-variable]");
     387             : 
     388             :         // verify configuration file parameters that appear no where else
     389             : 
     390           2 :         advgetopt::option_info::pointer_t unique(opt.get_option("unique"));
     391           1 :         CATCH_REQUIRE(unique != nullptr);
     392           1 :         CATCH_REQUIRE(opt.is_defined("unique"));
     393           2 :         advgetopt::string_list_t unique_sources(unique->trace_sources());
     394           1 :         CATCH_REQUIRE(unique_sources.size() == 1);
     395           1 :         expected_config = "unique=perfect [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]";
     396           1 :         CATCH_REQUIRE(unique_sources[0] == expected_config);
     397             : 
     398           2 :         advgetopt::option_info::pointer_t definition(opt.get_option("definition"));
     399           1 :         CATCH_REQUIRE(definition != nullptr);
     400           1 :         CATCH_REQUIRE(opt.is_defined("definition"));
     401           2 :         advgetopt::string_list_t definition_sources(definition->trace_sources());
     402           1 :         CATCH_REQUIRE(definition_sources.size() == 1);
     403           1 :         expected_config = "definition=long value here [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]";
     404           1 :         CATCH_REQUIRE(definition_sources[0] == expected_config);
     405             : 
     406           2 :         advgetopt::option_info::pointer_t multiple(opt.get_option("multiple"));
     407           1 :         CATCH_REQUIRE(multiple != nullptr);
     408           1 :         CATCH_REQUIRE(opt.is_defined("multiple"));
     409           2 :         advgetopt::string_list_t multiple_sources(multiple->trace_sources());
     410           1 :         CATCH_REQUIRE(multiple_sources.size() == 1);
     411           1 :         expected_config = "multiple[0]=value [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]";
     412           1 :         CATCH_REQUIRE(multiple_sources[0] == expected_config);
     413             : 
     414           2 :         advgetopt::option_info::pointer_t good(opt.get_option("good"));
     415           1 :         CATCH_REQUIRE(good != nullptr);
     416           1 :         CATCH_REQUIRE(opt.is_defined("good"));
     417           2 :         advgetopt::string_list_t good_sources(good->trace_sources());
     418           1 :         CATCH_REQUIRE(good_sources.size() == 1);
     419           1 :         expected_config = "good=variable [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]";
     420           1 :         CATCH_REQUIRE(good_sources[0] == expected_config);
     421             : 
     422             :         // process system options now
     423           2 :         std::stringstream ss;
     424           1 :         advgetopt::flag_t const result(opt.process_system_options(ss));
     425           1 :         CATCH_REQUIRE(result == (advgetopt::SYSTEM_OPTION_SHOW_OPTION_SOURCES
     426             :                                | advgetopt::SYSTEM_OPTION_VERSION
     427             :                                | advgetopt::SYSTEM_OPTION_CONFIG_DIR));
     428           1 :         CATCH_REQUIRE_LONG_STRING(ss.str(),
     429             : "1.2.3\n"
     430             : "Option Sources:\n"
     431             : "  1. option \"build-date\" (undefined)\n"
     432             : "\n"
     433             : "  2. option \"color\"\n"
     434             : "     color[0]=black [environment-variable]\n"
     435             : "     color[1]=orange [environment-variable]\n"
     436             : "     color[2]=purple [environment-variable]\n"
     437             : "\n"
     438             : "  3. option \"compiler-version\" (undefined)\n"
     439             : "\n"
     440             : "  4. option \"config-dir\"\n"
     441             : "     config-dir[0]=" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config [command-line]\n"
     442             : "\n"
     443             : "  5. option \"configuration-filenames\" (undefined)\n"
     444             : "\n"
     445             : "  6. option \"copyright\" (undefined)\n"
     446             : "\n"
     447             : "  7. option \"definition\"\n"
     448             : "     definition=long value here [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]\n"
     449             : "\n"
     450             : "  8. option \"environment-variable-name\" (undefined)\n"
     451             : "\n"
     452             : "  9. option \"good\"\n"
     453             : "     good=variable [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]\n"
     454             : "\n"
     455             : "  10. option \"has-sanitizer\" (undefined)\n"
     456             : "\n"
     457             : "  11. option \"help\" (undefined)\n"
     458             : "\n"
     459             : "  12. option \"license\" (undefined)\n"
     460             : "\n"
     461             : "  13. option \"long-help\" (undefined)\n"
     462             : "\n"
     463             : "  14. option \"more\"\n"
     464             : "     more=data [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]\n"
     465             : "     more=instructions [environment-variable]\n"
     466             : "     more=magical [command-line]\n"
     467             : "\n"
     468             : "  15. option \"multiple\"\n"
     469             : "     multiple[0]=value [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]\n"
     470             : "\n"
     471             : "  16. option \"organized\"\n"
     472             : "     organized=set [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]\n"
     473             : "     organized=logically [command-line]\n"
     474             : "\n"
     475             : "  17. option \"path-to-option-definitions\" (undefined)\n"
     476             : "\n"
     477             : "  18. option \"print-option\" (undefined)\n"
     478             : "\n"
     479             : "  19. option \"show-option-sources\"\n"
     480             : "     show-option-sources= [command-line]\n"
     481             : "\n"
     482             : "  20. option \"sources\"\n"
     483             : "     sources=just fine [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]\n"
     484             : "     sources=all [environment-variable]\n"
     485             : "\n"
     486             : "  21. option \"unique\"\n"
     487             : "     unique=perfect [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/src.config\"]\n"
     488             : "\n"
     489             : "  22. option \"verbose\"\n"
     490             : "     verbose= [environment-variable]\n"
     491             : "\n"
     492             : "  23. option \"version\"\n"
     493             : "     version= [command-line]\n"
     494             : "\n"
     495             : "  24. option \"zap\"\n"
     496             : "     zap= [command-line]\n"
     497             : "\n"
     498             : );
     499             :     }
     500             :     CATCH_END_SECTION()
     501             : 
     502           4 :     CATCH_START_SECTION("load options from a config file, environment variable, and command line with --config-dir in the environment variable")
     503             :     {
     504           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("sources", "hidden");
     505             : 
     506             :         {
     507           2 :             std::ofstream config_file;
     508           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     509           1 :             CATCH_REQUIRE(config_file.good());
     510           1 :             config_file <<
     511             :                 "# Auto-generated\n"
     512             :                 "unique     = perfect  \n"
     513             :                 "definition = long value here\n"
     514             :                 "sources    = just fine \t\n"
     515             :                 "multiple   = the origin of life\r\n"
     516             :                 "good       = variable \n"
     517             :                 "organized  = set\n"
     518             :                 "more       = data\t \n"
     519             :             ;
     520             :         }
     521             : 
     522           1 :         std::string const sub_config_file(boost::replace_all_copy(
     523             :                   SNAP_CATCH2_NAMESPACE::g_config_project_filename
     524             :                 , "50"
     525           2 :                 , "65"));
     526             :         {
     527           2 :             std::ofstream config_file;
     528           1 :             config_file.open(sub_config_file, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     529           1 :             CATCH_REQUIRE(config_file.good());
     530           1 :             config_file <<
     531             :                 "definition=\"this is a better definition\"\n"
     532             :                 "#sources=overwrite\n"
     533             :                 "multiple=should we not see this one instead?\n"
     534             :                 "good=enhanced\n"
     535             :                 "# Auto-generated\n"
     536             :             ;
     537             :         }
     538             : 
     539           1 :         advgetopt::option const options[] =
     540             :         {
     541             :             advgetopt::define_option(
     542             :                   advgetopt::Name("unique")
     543             :                 , advgetopt::ShortName('u')
     544             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     545             :                 , advgetopt::Help("unique option.")
     546             :                 , advgetopt::DefaultValue("long")
     547             :             ),
     548             :             advgetopt::define_option(
     549             :                   advgetopt::Name("color")
     550             :                 , advgetopt::ShortName('c')
     551             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     552             :                                                       , advgetopt::GETOPT_FLAG_MULTIPLE
     553             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP2>())
     554             :                 , advgetopt::Help("specify a color.")
     555             :             ),
     556             :             advgetopt::define_option(
     557             :                   advgetopt::Name("definition")
     558             :                 , advgetopt::ShortName('d')
     559             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     560             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP1>())
     561             :                 , advgetopt::Help("complete definition.")
     562             :             ),
     563             :             advgetopt::define_option(
     564             :                   advgetopt::Name("sources")
     565             :                 , advgetopt::ShortName('s')
     566             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     567             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP2>())
     568             :                 , advgetopt::Help("where it all came from.")
     569             :             ),
     570             :             advgetopt::define_option(
     571             :                   advgetopt::Name("multiple")
     572             :                 , advgetopt::ShortName('m')
     573             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     574             :                                                       , advgetopt::GETOPT_FLAG_MULTIPLE
     575             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP1>())
     576             :                 , advgetopt::Help("whether we have one or more.")
     577             :             ),
     578             :             advgetopt::define_option(
     579             :                   advgetopt::Name("zap")
     580             :                 , advgetopt::ShortName('z')
     581             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_SHOW_GROUP2>())
     582             :                 , advgetopt::Help("zap all of it.")
     583             :             ),
     584             :             advgetopt::define_option(
     585             :                   advgetopt::Name("good")
     586             :                 , advgetopt::ShortName('g')
     587             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     588             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP1>())
     589             :                 , advgetopt::Help("current status.")
     590             :             ),
     591             :             advgetopt::define_option(
     592             :                   advgetopt::Name("organized")
     593             :                 , advgetopt::ShortName('o')
     594             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     595             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP2>())
     596             :                 , advgetopt::Help("how the whole thing was organized.")
     597             :             ),
     598             :             advgetopt::define_option(
     599             :                   advgetopt::Name("more")
     600             :                 , advgetopt::ShortName('+')
     601             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED
     602             :                                                       , advgetopt::GETOPT_FLAG_SHOW_GROUP1>())
     603             :                 , advgetopt::Help("anything more you can think of.")
     604             :             ),
     605             :             advgetopt::define_option(
     606             :                   advgetopt::Name("verbose")
     607             :                 , advgetopt::ShortName('v')
     608             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_SHOW_GROUP1>())
     609             :                 , advgetopt::Help("anything more you can think of.")
     610             :             ),
     611             :             advgetopt::end_options()
     612             :         };
     613             : 
     614           2 :         std::string const config_dir("--config-dir=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config\"");
     615           1 :         snapdev::safe_setenv env(
     616             :                   "ADVGETOPT_TEST_OPTIONS"
     617             :                 , "--verbose --more=instructions "
     618           2 :                 + config_dir
     619           3 :                 + " --color black orange purple --sources=all --multiple here too");
     620             : 
     621           1 :         advgetopt::options_environment environment_options;
     622           1 :         environment_options.f_project_name = "unittest";
     623           1 :         environment_options.f_group_name = "sources";
     624           1 :         environment_options.f_options = options;
     625           1 :         environment_options.f_environment_variable_name = "ADVGETOPT_TEST_OPTIONS";
     626           1 :         environment_options.f_configuration_filename = "hidden.config";
     627           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     628           1 :         environment_options.f_help_header = "Usage: test source from command line, environment variable, and configuration file";
     629           1 :         environment_options.f_license = "GPL 2 or GPL 3";
     630             : 
     631           1 :         char const * cargv[] =
     632             :         {
     633             :             "tests/options-parser",
     634             :             "--license",
     635             :             "--show-option-sources",
     636             :             "--more=magical",
     637             :             "--multiple=first",
     638             :             "--organized",
     639             :             "logically",
     640             :             "--zap",
     641             :             "--multiple=last",
     642             :             "--copyright",
     643             :             nullptr
     644             :         };
     645           1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
     646           1 :         char ** argv = const_cast<char **>(cargv);
     647             : 
     648           2 :         advgetopt::getopt opt(environment_options, argc, argv);
     649             : 
     650             :         // verify command line options
     651             : 
     652           2 :         advgetopt::option_info::pointer_t license(opt.get_option("license"));
     653           1 :         CATCH_REQUIRE(license != nullptr);
     654           1 :         CATCH_REQUIRE(opt.is_defined("license"));
     655           2 :         advgetopt::string_list_t license_sources(license->trace_sources());
     656           1 :         CATCH_REQUIRE(license_sources.size() == 1);
     657           1 :         CATCH_REQUIRE(license_sources[0] == "license= [command-line]");
     658             : 
     659           2 :         advgetopt::option_info::pointer_t show(opt.get_option("show-option-sources"));
     660           1 :         CATCH_REQUIRE(show != nullptr);
     661           1 :         CATCH_REQUIRE(opt.is_defined("show-option-sources"));
     662           2 :         advgetopt::string_list_t show_option_sources(show->trace_sources());
     663           1 :         CATCH_REQUIRE(show_option_sources.size() == 1);
     664           1 :         CATCH_REQUIRE(show_option_sources[0] == "show-option-sources= [command-line]");
     665             : 
     666           2 :         advgetopt::option_info::pointer_t more(opt.get_option("more"));
     667           1 :         CATCH_REQUIRE(more != nullptr);
     668           1 :         CATCH_REQUIRE(opt.is_defined("more"));
     669           2 :         advgetopt::string_list_t more_sources(more->trace_sources());
     670           1 :         CATCH_REQUIRE(more_sources.size() == 3);
     671           2 :         std::string expected_config("more=data [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]");
     672           1 :         CATCH_REQUIRE(more_sources[0] == expected_config);
     673           1 :         CATCH_REQUIRE(more_sources[1] == "more=instructions [environment-variable]");
     674           1 :         CATCH_REQUIRE(more_sources[2] == "more=magical [command-line]");
     675             : 
     676           2 :         advgetopt::option_info::pointer_t organized(opt.get_option("organized"));
     677           1 :         CATCH_REQUIRE(organized != nullptr);
     678           1 :         CATCH_REQUIRE(opt.is_defined("organized"));
     679           2 :         advgetopt::string_list_t organized_sources(organized->trace_sources());
     680           1 :         CATCH_REQUIRE(organized_sources.size() == 2);
     681           1 :         expected_config = "organized=set [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]";
     682           1 :         CATCH_REQUIRE(organized_sources[0] == expected_config);
     683           1 :         CATCH_REQUIRE(organized_sources[1] == "organized=logically [command-line]");
     684             : 
     685           2 :         advgetopt::option_info::pointer_t multiple(opt.get_option("multiple"));
     686           1 :         CATCH_REQUIRE(multiple != nullptr);
     687           1 :         CATCH_REQUIRE(opt.is_defined("multiple"));
     688           2 :         advgetopt::string_list_t multiple_sources(multiple->trace_sources());
     689           1 :         CATCH_REQUIRE(multiple_sources.size() == 6);
     690           1 :         expected_config = "multiple[0]=the origin of life [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]";
     691           1 :         CATCH_REQUIRE(multiple_sources[0] == expected_config);
     692           1 :         expected_config = "multiple[0]=should we not see this one instead? [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/sources.d/65-hidden.config\"]";       // TODO: this should not be [0]?
     693           1 :         CATCH_REQUIRE(multiple_sources[1] == expected_config);
     694           1 :         expected_config = "multiple[1]=here [environment-variable]";       // TODO: this should not be [1]?
     695           1 :         CATCH_REQUIRE(multiple_sources[2] == expected_config);
     696           1 :         expected_config = "multiple[2]=too [environment-variable]";       // TODO: this should not be [2]?
     697           1 :         CATCH_REQUIRE(multiple_sources[3] == expected_config);
     698           1 :         expected_config = "multiple[0]=first [command-line]";       // TODO: this should not be [0]?
     699           1 :         CATCH_REQUIRE(multiple_sources[4] == expected_config);
     700           1 :         expected_config = "multiple[0]=last [command-line]";        // TODO: this should not be [0]?
     701           1 :         CATCH_REQUIRE(multiple_sources[5] == expected_config);
     702             : 
     703           2 :         advgetopt::option_info::pointer_t zap(opt.get_option("zap"));
     704           1 :         CATCH_REQUIRE(zap != nullptr);
     705           1 :         CATCH_REQUIRE(opt.is_defined("zap"));
     706           2 :         advgetopt::string_list_t zap_sources(zap->trace_sources());
     707           1 :         CATCH_REQUIRE(zap_sources.size() == 1);
     708           1 :         CATCH_REQUIRE(zap_sources[0] == "zap= [command-line]");
     709             : 
     710             :         // verify environment variable options which are not also on the command line
     711             : 
     712           2 :         advgetopt::option_info::pointer_t verbose(opt.get_option("verbose"));
     713           1 :         CATCH_REQUIRE(verbose != nullptr);
     714           1 :         CATCH_REQUIRE(opt.is_defined("verbose"));
     715           2 :         advgetopt::string_list_t verbose_sources(verbose->trace_sources());
     716           1 :         CATCH_REQUIRE(verbose_sources.size() == 1);
     717           1 :         CATCH_REQUIRE(verbose_sources[0] == "verbose= [environment-variable]");
     718             : 
     719           2 :         advgetopt::option_info::pointer_t color(opt.get_option("color"));
     720           1 :         CATCH_REQUIRE(color != nullptr);
     721           1 :         CATCH_REQUIRE(opt.is_defined("color"));
     722           2 :         advgetopt::string_list_t color_sources(color->trace_sources());
     723           1 :         CATCH_REQUIRE(color_sources.size() == 3);
     724           1 :         CATCH_REQUIRE(color_sources[0] == "color[0]=black [environment-variable]");
     725           1 :         CATCH_REQUIRE(color_sources[1] == "color[1]=orange [environment-variable]");
     726           1 :         CATCH_REQUIRE(color_sources[2] == "color[2]=purple [environment-variable]");
     727             : 
     728           2 :         advgetopt::option_info::pointer_t sources(opt.get_option("sources"));
     729           1 :         CATCH_REQUIRE(sources != nullptr);
     730           1 :         CATCH_REQUIRE(opt.is_defined("sources"));
     731           2 :         advgetopt::string_list_t sources_sources(sources->trace_sources());
     732           1 :         CATCH_REQUIRE(sources_sources.size() == 2);
     733           1 :         expected_config = "sources=just fine [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]";
     734           1 :         CATCH_REQUIRE(sources_sources[0] == expected_config);
     735           1 :         CATCH_REQUIRE(sources_sources[1] == "sources=all [environment-variable]");
     736             : 
     737           2 :         advgetopt::option_info::pointer_t config_dir_opt(opt.get_option("config-dir"));
     738           1 :         CATCH_REQUIRE(config_dir_opt != nullptr);
     739           1 :         CATCH_REQUIRE(opt.is_defined("config_dir"));
     740           2 :         advgetopt::string_list_t config_dir_sources(config_dir_opt->trace_sources());
     741           1 :         CATCH_REQUIRE(config_dir_sources.size() == 1);
     742           1 :         expected_config = "config-dir[0]=" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config [environment-variable]";
     743           1 :         CATCH_REQUIRE(config_dir_sources[0] == expected_config);
     744             : 
     745             :         // verify configuration file parameters that appear no where else
     746             : 
     747           2 :         advgetopt::option_info::pointer_t unique(opt.get_option("unique"));
     748           1 :         CATCH_REQUIRE(unique != nullptr);
     749           1 :         CATCH_REQUIRE(opt.is_defined("unique"));
     750           2 :         advgetopt::string_list_t unique_sources(unique->trace_sources());
     751           1 :         CATCH_REQUIRE(unique_sources.size() == 1);
     752           1 :         expected_config = "unique=perfect [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]";
     753           1 :         CATCH_REQUIRE(unique_sources[0] == expected_config);
     754             : 
     755           2 :         advgetopt::option_info::pointer_t definition(opt.get_option("definition"));
     756           1 :         CATCH_REQUIRE(definition != nullptr);
     757           1 :         CATCH_REQUIRE(opt.is_defined("definition"));
     758           2 :         advgetopt::string_list_t definition_sources(definition->trace_sources());
     759           1 :         CATCH_REQUIRE(definition_sources.size() == 2);
     760           1 :         expected_config = "definition=long value here [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]";
     761           1 :         CATCH_REQUIRE(definition_sources[0] == expected_config);
     762           1 :         expected_config = "definition=this is a better definition [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/sources.d/65-hidden.config\"]";
     763           1 :         CATCH_REQUIRE(definition_sources[1] == expected_config);
     764             : 
     765           2 :         advgetopt::option_info::pointer_t good(opt.get_option("good"));
     766           1 :         CATCH_REQUIRE(good != nullptr);
     767           1 :         CATCH_REQUIRE(opt.is_defined("good"));
     768           2 :         advgetopt::string_list_t good_sources(good->trace_sources());
     769           1 :         CATCH_REQUIRE(good_sources.size() == 2);
     770           1 :         expected_config = "good=variable [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]";
     771           1 :         CATCH_REQUIRE(good_sources[0] == expected_config);
     772           1 :         expected_config = "good=enhanced [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/sources.d/65-hidden.config\"]";
     773           1 :         CATCH_REQUIRE(good_sources[1] == expected_config);
     774             : 
     775             :         // process system options now
     776           2 :         std::stringstream ss;
     777           1 :         advgetopt::flag_t const result(opt.process_system_options(ss));
     778           1 :         CATCH_REQUIRE(result == (advgetopt::SYSTEM_OPTION_SHOW_OPTION_SOURCES
     779             :                                | advgetopt::SYSTEM_OPTION_LICENSE
     780             :                                | advgetopt::SYSTEM_OPTION_COPYRIGHT
     781             :                                | advgetopt::SYSTEM_OPTION_CONFIG_DIR));
     782           1 :         CATCH_REQUIRE_LONG_STRING(ss.str(),
     783             : "warning: no copyright notice found.\n"
     784             : "GPL 2 or GPL 3\n"
     785             : "Option Sources:\n"
     786             : "  1. option \"build-date\" (undefined)\n"
     787             : "\n"
     788             : "  2. option \"color\"\n"
     789             : "     color[0]=black [environment-variable]\n"
     790             : "     color[1]=orange [environment-variable]\n"
     791             : "     color[2]=purple [environment-variable]\n"
     792             : "\n"
     793             : "  3. option \"compiler-version\" (undefined)\n"
     794             : "\n"
     795             : "  4. option \"config-dir\"\n"
     796             : "     config-dir[0]=" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config [environment-variable]\n"
     797             : "\n"
     798             : "  5. option \"configuration-filenames\" (undefined)\n"
     799             : "\n"
     800             : "  6. option \"copyright\"\n"
     801             : "     copyright= [command-line]\n"
     802             : "\n"
     803             : "  7. option \"definition\"\n"
     804             : "     definition=long value here [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]\n"
     805             : "     definition=this is a better definition [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/sources.d/65-hidden.config\"]\n"
     806             : "\n"
     807             : "  8. option \"environment-variable-name\" (undefined)\n"
     808             : "\n"
     809             : "  9. option \"good\"\n"
     810             : "     good=variable [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]\n"
     811             : "     good=enhanced [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/sources.d/65-hidden.config\"]\n"
     812             : "\n"
     813             : "  10. option \"has-sanitizer\" (undefined)\n"
     814             : "\n"
     815             : "  11. option \"help\" (undefined)\n"
     816             : "\n"
     817             : "  12. option \"license\"\n"
     818             : "     license= [command-line]\n"
     819             : "\n"
     820             : "  13. option \"long-help\" (undefined)\n"
     821             : "\n"
     822             : "  14. option \"more\"\n"
     823             : "     more=data [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]\n"
     824             : "     more=instructions [environment-variable]\n"
     825             : "     more=magical [command-line]\n"
     826             : "\n"
     827             : "  15. option \"multiple\"\n"
     828             : "     multiple[0]=the origin of life [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]\n"
     829             : "     multiple[0]=should we not see this one instead? [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/sources.d/65-hidden.config\"]\n"
     830             : "     multiple[1]=here [environment-variable]\n"
     831             : "     multiple[2]=too [environment-variable]\n"
     832             : "     multiple[0]=first [command-line]\n"
     833             : "     multiple[0]=last [command-line]\n"
     834             : "\n"
     835             : "  16. option \"organized\"\n"
     836             : "     organized=set [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]\n"
     837             : "     organized=logically [command-line]\n"
     838             : "\n"
     839             : "  17. option \"path-to-option-definitions\" (undefined)\n"
     840             : "\n"
     841             : "  18. option \"print-option\" (undefined)\n"
     842             : "\n"
     843             : "  19. option \"show-option-sources\"\n"
     844             : "     show-option-sources= [command-line]\n"
     845             : "\n"
     846             : "  20. option \"sources\"\n"
     847             : "     sources=just fine [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]\n"
     848             : "     sources=all [environment-variable]\n"
     849             : "\n"
     850             : "  21. option \"unique\"\n"
     851             : "     unique=perfect [configuration=\"" + SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config/hidden.config\"]\n"
     852             : "\n"
     853             : "  22. option \"verbose\"\n"
     854             : "     verbose= [environment-variable]\n"
     855             : "\n"
     856             : "  23. option \"version\" (undefined)\n"
     857             : "\n"
     858             : "  24. option \"zap\"\n"
     859             : "     zap= [command-line]\n"
     860             : "\n"
     861             : );
     862             :     }
     863             :     CATCH_END_SECTION()
     864           8 : }
     865             : 
     866             : 
     867             : 
     868             : 
     869             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13