diff --git a/include/CLI/App.hpp b/include/CLI/App.hpp index 206473f6..861c901b 100644 --- a/include/CLI/App.hpp +++ b/include/CLI/App.hpp @@ -1146,6 +1146,10 @@ class App { for(const Option_p &opt : options_) { // Required or partially filled if(opt->get_required() || opt->count() != 0) { + // Make sure enough -N arguments parsed (+N is already handled in parsing function) + if(opt->get_expected() < 0 && opt->count() < static_cast(-opt->get_expected())) + throw ArgumentMismatch(opt->single_name() + ": At least " + std::to_string(-opt->get_expected()) + + " required"); // Required but empty if(opt->get_required() && opt->count() == 0) @@ -1408,8 +1412,6 @@ class App { args.pop_back(); collected++; } - if(op->results_.size() < static_cast(-num)) - throw ArgumentMismatch(op->single_name() + ": At least " + std::to_string(-num) + " required"); } else { while(num > 0 && !args.empty()) { diff --git a/tests/AppTest.cpp b/tests/AppTest.cpp index 2ffce3d4..d171c6ed 100644 --- a/tests/AppTest.cpp +++ b/tests/AppTest.cpp @@ -324,10 +324,33 @@ TEST_F(TApp, RequiredOptsDoubleShort) { EXPECT_THROW(run(), CLI::ArgumentMismatch); + app.reset(); + + args = {"-s", "one", "-s", "one", "-s", "one"}; + + EXPECT_THROW(run(), CLI::ArgumentMismatch); +} + +TEST_F(TApp, RequiredOptsDoubleNeg) { + std::vector strs; + app.add_option("-s", strs)->required()->expected(-2); + + args = {"-s", "one"}; + + EXPECT_THROW(run(), CLI::ArgumentMismatch); + + app.reset(); + + args = {"-s", "one", "two", "-s", "three"}; + + EXPECT_NO_THROW(run()); + + EXPECT_EQ(strs, std::vector({"one", "two", "three"})); + app.reset(); args = {"-s", "one", "two"}; - run(); + EXPECT_NO_THROW(run()); EXPECT_EQ(strs, std::vector({"one", "two"})); }