From f9ccd0d64bdc6fabe7fde2965db762ddbf1d8e68 Mon Sep 17 00:00:00 2001 From: Pavel Belikov Date: Tue, 25 Jun 2019 22:21:36 +0300 Subject: Fixes #74 : Fix group validation in Subparser/Command --- args.hxx | 29 +++++++++++++++++++---------- test.cxx | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/args.hxx b/args.hxx index 09c1919..da6eb54 100644 --- a/args.hxx +++ b/args.hxx @@ -1633,11 +1633,11 @@ namespace args public: Subparser(std::vector args_, ArgumentParser &parser_, const Command &command_, const HelpParams &helpParams_) - : args(std::move(args_)), parser(&parser_), helpParams(helpParams_), command(command_) + : Group({}, Validators::AllChildGroups), args(std::move(args_)), parser(&parser_), helpParams(helpParams_), command(command_) { } - Subparser(const Command &command_, const HelpParams &helpParams_) : helpParams(helpParams_), command(command_) + Subparser(const Command &command_, const HelpParams &helpParams_) : Group({}, Validators::AllChildGroups), helpParams(helpParams_), command(command_) { } @@ -2128,18 +2128,23 @@ namespace args return; } - for (Base *child: Children()) + auto onValidationError = [&] { - if (child->IsGroup() && !child->Matched()) - { - std::ostringstream problem; - problem << "Group validation failed somewhere!"; + std::ostringstream problem; + problem << "Group validation failed somewhere!"; #ifdef ARGS_NOEXCEPT - error = Error::Validation; - errorMsg = problem.str(); + error = Error::Validation; + errorMsg = problem.str(); #else - throw ValidationError(problem.str()); + throw ValidationError(problem.str()); #endif + }; + + for (Base *child: Children()) + { + if (child->IsGroup() && !child->Matched()) + { + onValidationError(); } child->Validate(shortprefix, longprefix); @@ -2148,6 +2153,10 @@ namespace args if (subparser != nullptr) { subparser->Validate(shortprefix, longprefix); + if (!subparser->Matched()) + { + onValidationError(); + } } if (selectedCommand == nullptr && commandIsRequired && (Group::HasCommand() || subparserHasCommand)) diff --git a/test.cxx b/test.cxx index b46007d..5e84398 100644 --- a/test.cxx +++ b/test.cxx @@ -936,6 +936,25 @@ TEST_CASE("Subparser validation works as expected", "[args]") REQUIRE_THROWS_AS(p.ParseArgs(std::vector{"unknown-command"}), args::ParseError); } +TEST_CASE("Subparser group validation works as expected", "[args]") +{ + int x = 0; + args::ArgumentParser p("parser"); + args::Command a(p, "a", "command a", [&](args::Subparser &s) + { + args::Group required(s, "", args::Group::Validators::All); + args::ValueFlag f(required, "", "", {'f'}); + s.Parse(); + ++x; + }); + + p.RequireCommand(false); + REQUIRE_NOTHROW(p.ParseArgs(std::vector{})); + REQUIRE_NOTHROW(p.ParseArgs(std::vector{"a", "-f", "F"})); + REQUIRE_THROWS_AS(p.ParseArgs(std::vector{"a"}), args::ValidationError); + REQUIRE(x == 1); +} + TEST_CASE("Global options work as expected", "[args]") { args::Group globals; -- cgit v1.2.1