Commit dcbcb4721dda5dab0a56d9faaaee50e6a30f7758

Authored by Philip Top
Committed by GitHub
1 parent 1a26afab

fix: negated flag config files (#775)

* add some coverage tests, and fix the issue with negated flags and config files

* style: pre-commit.ci fixes

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
include/CLI/impl/Config_inl.hpp
... ... @@ -344,6 +344,9 @@ ConfigBase::to_config(const App *app, bool default_also, bool write_description,
344 344 }
345 345  
346 346 if(!value.empty()) {
  347 + if(!opt->get_fnames().empty()) {
  348 + value = opt->get_flag_value(name, value);
  349 + }
347 350 if(write_description && opt->has_description()) {
348 351 out << '\n';
349 352 out << commentLead << detail::fix_newlines(commentLead, opt->get_description()) << '\n';
... ...
tests/ConfigFileTest.cpp
... ... @@ -2497,6 +2497,29 @@ TEST_CASE_METHOD(TApp, &quot;ConfigWriteReadWrite&quot;, &quot;[config]&quot;) {
2497 2497 CHECK(config2 == config1);
2498 2498 }
2499 2499  
  2500 +TEST_CASE_METHOD(TApp, "ConfigWriteReadNegated", "[config]") {
  2501 +
  2502 + TempFile tmpini{"TestIniTmp.ini"};
  2503 + bool flag{true};
  2504 + app.add_flag("!--no-flag", flag);
  2505 + args = {"--no-flag"};
  2506 + run();
  2507 +
  2508 + // Save config, with default values too
  2509 + std::string config1 = app.config_to_str(false, false);
  2510 + {
  2511 + std::ofstream out{tmpini};
  2512 + out << config1 << std::endl;
  2513 + }
  2514 + CHECK_FALSE(flag);
  2515 + args.clear();
  2516 + flag = true;
  2517 + app.set_config("--config", tmpini, "Read an ini file", true);
  2518 + run();
  2519 +
  2520 + CHECK_FALSE(flag);
  2521 +}
  2522 +
2500 2523 /////// INI output tests
2501 2524  
2502 2525 TEST_CASE_METHOD(TApp, "IniOutputSimple", "[config]") {
... ...
tests/CreationTest.cpp
... ... @@ -549,6 +549,25 @@ TEST_CASE_METHOD(TApp, &quot;GetOptionList&quot;, &quot;[creation]&quot;) {
549 549 }
550 550 }
551 551  
  552 +TEST_CASE_METHOD(TApp, "GetOptionListFilter", "[creation]") {
  553 + int two{0};
  554 + auto *flag = app.add_flag("--one");
  555 + app.add_option("--two", two);
  556 +
  557 + const CLI::App &const_app = app; // const alias to force use of const-methods
  558 + std::vector<const CLI::Option *> opt_listc =
  559 + const_app.get_options([](const CLI::Option *opt) { return opt->get_name() == "--one"; });
  560 +
  561 + REQUIRE(static_cast<std::size_t>(1) == opt_listc.size());
  562 + CHECK(flag == opt_listc.at(0));
  563 +
  564 + std::vector<CLI::Option *> opt_list =
  565 + app.get_options([](const CLI::Option *opt) { return opt->get_name() == "--one"; });
  566 +
  567 + REQUIRE(static_cast<std::size_t>(1) == opt_list.size());
  568 + CHECK(flag == opt_list.at(0));
  569 +}
  570 +
552 571 TEST_CASE("ValidatorTests: TestValidatorCreation", "[creation]") {
553 572 std::function<std::string(std::string &)> op1 = [](std::string &val) {
554 573 return (val.size() >= 5) ? std::string{} : val;
... ...
tests/SubcommandTest.cpp
... ... @@ -916,6 +916,10 @@ TEST_CASE_METHOD(TApp, &quot;SubcomInheritCaseCheck&quot;, &quot;[subcom]&quot;) {
916 916 CHECK(app.get_subcommands({}).size() == 2u);
917 917 CHECK(app.get_subcommands([](const CLI::App *s) { return s->get_name() == "sub1"; }).size() == 1u);
918 918  
  919 + // check the const version of get_subcommands
  920 + const auto &app_const = app;
  921 + CHECK(app_const.get_subcommands([](const CLI::App *s) { return s->get_name() == "sub1"; }).size() == 1u);
  922 +
919 923 args = {"SuB1"};
920 924 run();
921 925 CHECK(app.get_subcommands().at(0) == sub1);
... ... @@ -1192,6 +1196,18 @@ TEST_CASE_METHOD(ManySubcommands, &quot;manyIndexQueryPtr&quot;, &quot;[subcom]&quot;) {
1192 1196 CHECK_THROWS_AS(app.get_subcommand_ptr(4), CLI::OptionNotFound);
1193 1197 }
1194 1198  
  1199 +TEST_CASE_METHOD(ManySubcommands, "manyIndexQueryPtrByName", "[subcom]") {
  1200 + auto s1 = app.get_subcommand_ptr("sub1");
  1201 + auto s2 = app.get_subcommand_ptr("sub2");
  1202 + auto s3 = app.get_subcommand_ptr("sub3");
  1203 + auto s4 = app.get_subcommand_ptr("sub4");
  1204 + CHECK(sub1 == s1.get());
  1205 + CHECK(sub2 == s2.get());
  1206 + CHECK(sub3 == s3.get());
  1207 + CHECK(sub4 == s4.get());
  1208 + CHECK_THROWS_AS(app.get_subcommand_ptr("sub5"), CLI::OptionNotFound);
  1209 +}
  1210 +
1195 1211 TEST_CASE_METHOD(ManySubcommands, "Required1Fuzzy", "[subcom]") {
1196 1212  
1197 1213 app.require_subcommand(0, 1);
... ...