Commit 815553211b644b2a64b5dc671c602233c49c065f
Committed by
GitHub
1 parent
728ac3a8
fix and test some reported issues (#661)
Showing
4 changed files
with
45 additions
and
4 deletions
include/CLI/App.hpp
| ... | ... | @@ -2825,10 +2825,13 @@ class App { |
| 2825 | 2825 | parse_order_.push_back(op.get()); |
| 2826 | 2826 | } |
| 2827 | 2827 | } |
| 2828 | - | |
| 2829 | - // if we only partially completed a type then add an empty string for later processing | |
| 2830 | - if(min_num > 0 && op->get_type_size_max() != min_num && (collected % op->get_type_size_max()) != 0) { | |
| 2831 | - op->add_result(std::string{}); | |
| 2828 | + // if we only partially completed a type then add an empty string if allowed for later processing | |
| 2829 | + if(min_num > 0 && (collected % op->get_type_size_max()) != 0) { | |
| 2830 | + if(op->get_type_size_max() != op->get_type_size_min()) { | |
| 2831 | + op->add_result(std::string{}); | |
| 2832 | + } else { | |
| 2833 | + throw ArgumentMismatch::PartialType(op->get_name(), op->get_type_size_min(), op->get_type_name()); | |
| 2834 | + } | |
| 2832 | 2835 | } |
| 2833 | 2836 | if(op->get_trigger_on_parse()) { |
| 2834 | 2837 | op->run_callback(); | ... | ... |
include/CLI/Error.hpp
| ... | ... | @@ -277,6 +277,10 @@ class ArgumentMismatch : public ParseError { |
| 277 | 277 | static ArgumentMismatch FlagOverride(std::string name) { |
| 278 | 278 | return ArgumentMismatch(name + " was given a disallowed flag override"); |
| 279 | 279 | } |
| 280 | + static ArgumentMismatch PartialType(std::string name, int num, std::string type) { | |
| 281 | + return ArgumentMismatch(name + ": " + type + " only partially specified: " + std::to_string(num) + | |
| 282 | + " required for each element"); | |
| 283 | + } | |
| 280 | 284 | }; |
| 281 | 285 | |
| 282 | 286 | /// Thrown when a requires option is missing | ... | ... |
tests/ConfigFileTest.cpp
| ... | ... | @@ -2103,6 +2103,19 @@ TEST_CASE_METHOD(TApp, "TomlOutputVector", "[config]") { |
| 2103 | 2103 | CHECK(str == "vector=[1, 2, 3]\n"); |
| 2104 | 2104 | } |
| 2105 | 2105 | |
| 2106 | +TEST_CASE_METHOD(TApp, "TomlOutputTuple", "[config]") { | |
| 2107 | + | |
| 2108 | + std::tuple<double, double, double, double> t; | |
| 2109 | + app.add_option("--tuple", t); | |
| 2110 | + app.config_formatter(std::make_shared<CLI::ConfigTOML>()); | |
| 2111 | + args = {"--tuple", "1", "2", "3", "4"}; | |
| 2112 | + | |
| 2113 | + run(); | |
| 2114 | + | |
| 2115 | + std::string str = app.config_to_str(); | |
| 2116 | + CHECK(str == "tuple=[1, 2, 3, 4]\n"); | |
| 2117 | +} | |
| 2118 | + | |
| 2106 | 2119 | TEST_CASE_METHOD(TApp, "ConfigOutputVectorCustom", "[config]") { |
| 2107 | 2120 | |
| 2108 | 2121 | std::vector<int> v; | ... | ... |
tests/OptionTypeTest.cpp
| ... | ... | @@ -554,6 +554,27 @@ TEST_CASE_METHOD(TApp, "vectorPairFail", "[optiontype]") { |
| 554 | 554 | CHECK_THROWS_AS(run(), CLI::ConversionError); |
| 555 | 555 | } |
| 556 | 556 | |
| 557 | +TEST_CASE_METHOD(TApp, "vectorPairFail2", "[optiontype]") { | |
| 558 | + | |
| 559 | + std::vector<std::pair<int, int>> custom_opt; | |
| 560 | + | |
| 561 | + auto opt = app.add_option("--pairs", custom_opt); | |
| 562 | + | |
| 563 | + args = {"--pairs", "1", "2", "3", "4"}; | |
| 564 | + | |
| 565 | + run(); | |
| 566 | + CHECK(custom_opt.size() == 2U); | |
| 567 | + | |
| 568 | + args = {"--pairs", "1", "2", "3"}; | |
| 569 | + | |
| 570 | + CHECK_THROWS_AS(run(), CLI::ArgumentMismatch); | |
| 571 | + // now change the type size to explicitly allow 1 or 2 | |
| 572 | + opt->type_size(1, 2); | |
| 573 | + | |
| 574 | + run(); | |
| 575 | + CHECK(custom_opt.size() == 2U); | |
| 576 | +} | |
| 577 | + | |
| 557 | 578 | TEST_CASE_METHOD(TApp, "vectorPairTypeRange", "[optiontype]") { |
| 558 | 579 | |
| 559 | 580 | std::vector<std::pair<int, std::string>> custom_opt; | ... | ... |