From d2b331f02aae5249dae7448ccbc6a21180e0aea2 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Mon, 30 Dec 2024 12:34:47 -0800 Subject: [PATCH] Fix Issue #1090, (#1108) max, min on positional was not respected, specifically max positionals only filled up to min, and skipped over optional options. Fixes #1090 --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- include/CLI/impl/App_inl.hpp | 2 +- tests/AppTest.cpp | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/include/CLI/impl/App_inl.hpp b/include/CLI/impl/App_inl.hpp index c17fa808..ceeca898 100644 --- a/include/CLI/impl/App_inl.hpp +++ b/include/CLI/impl/App_inl.hpp @@ -1731,7 +1731,7 @@ CLI11_INLINE bool App::_parse_positional(std::vector &args, bool ha for(const Option_p &opt : options_) { // Eat options, one by one, until done if(opt->get_positional() && - (static_cast(opt->count()) < opt->get_items_expected_min() || opt->get_allow_extra_args())) { + (static_cast(opt->count()) < opt->get_items_expected_max() || opt->get_allow_extra_args())) { if(validate_positionals_) { std::string pos = positional; pos = opt->_validate(pos, 0); diff --git a/tests/AppTest.cpp b/tests/AppTest.cpp index 6dc87828..877460b4 100644 --- a/tests/AppTest.cpp +++ b/tests/AppTest.cpp @@ -1236,6 +1236,56 @@ TEST_CASE_METHOD(TApp, "RequiredOptsDoubleNeg", "[app]") { CHECK(std::vector({"one", "two"}) == strs); } +TEST_CASE_METHOD(TApp, "ExpectedRangeParam", "[app]") { + + app.add_option("-s")->required()->expected(2, 4); + + args = {"-s", "one"}; + + CHECK_THROWS_AS(run(), CLI::ArgumentMismatch); + + args = {"-s", "one", "two"}; + + CHECK_NOTHROW(run()); + + args = {"-s", "one", "two", "three"}; + + CHECK_NOTHROW(run()); + + args = {"-s", "one", "two", "three", "four"}; + + CHECK_NOTHROW(run()); + + args = {"-s", "one", "two", "three", "four", "five"}; + + CHECK_THROWS_AS(run(), CLI::ExtrasError); +} + +TEST_CASE_METHOD(TApp, "ExpectedRangePositional", "[app]") { + + app.add_option("arg")->required()->expected(2, 4); + + args = {"one"}; + + CHECK_THROWS_AS(run(), CLI::ArgumentMismatch); + + args = {"one", "two"}; + + CHECK_NOTHROW(run()); + + args = {"one", "two", "three"}; + + CHECK_NOTHROW(run()); + + args = {"one", "two", "three", "four"}; + + CHECK_NOTHROW(run()); + + args = {"one", "two", "three", "four", "five"}; + + CHECK_THROWS_AS(run(), CLI::ExtrasError); +} + // This makes sure unlimited option priority is // correct for space vs. no space #90 TEST_CASE_METHOD(TApp, "PositionalNoSpace", "[app]") {