From 92df78585928772bad2ffadee8635428246a79af Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Tue, 18 Nov 2025 15:25:13 +1000 Subject: [PATCH] tests: Add some test coverage for ArgsManager::AddCommand Co-Authored-By: l0rinc --- src/test/argsman_tests.cpp | 76 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/test/argsman_tests.cpp b/src/test/argsman_tests.cpp index c8802d3641c..da0d6840504 100644 --- a/src/test/argsman_tests.cpp +++ b/src/test/argsman_tests.cpp @@ -634,6 +634,82 @@ BOOST_AUTO_TEST_CASE(util_GetArg) BOOST_CHECK_EQUAL(testArgs.GetArg("pritest4", "default"), "b"); } +BOOST_AUTO_TEST_CASE(util_AddCommand) +{ + enum TestFail { SUCCESS, + PARSE_FAIL, + PARSE_ERROR, + NO_COMMAND, + COMMAND_OPTS_BAD_DETAILS, + COMMAND_OPTS }; + + auto testfn = [&](const auto& argv) -> TestFail { + TestArgsManager test_args; + test_args.AddArg("-opt1=", "Opt 1", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::COMMAND_OPTIONS); + test_args.AddArg("-opt2=", "Opt 2", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::COMMAND_OPTIONS); + test_args.AddArg("-opt3=", "Opt 3", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS); + + test_args.AddCommand("cmd1", "No specific options"); + test_args.AddCommand("cmd2", "Opt 1", {"-opt1"}); + test_args.AddCommand("cmd3", "Opt 1 or 2", {"-opt1", "-opt2"}); + + std::string error; + if (!test_args.ParseParameters(argv.size(), argv.data(), error)) return PARSE_FAIL; + if (!error.empty()) return PARSE_ERROR; + const auto command = test_args.GetCommand(); + if (!command) return NO_COMMAND; + std::vector details; + if (!test_args.CheckCommandOptions(command->command, &details)) { + if (details.empty()) return COMMAND_OPTS_BAD_DETAILS; + return COMMAND_OPTS; + } else if (!details.empty()) { + return COMMAND_OPTS_BAD_DETAILS; + } + return SUCCESS; + }; + + BOOST_CHECK_EQUAL(COMMAND_OPTS, testfn(std::array{"x", "-opt1=foo", "cmd1"})); + BOOST_CHECK_EQUAL(SUCCESS, testfn(std::array{"x", "cmd1", "-opt1=foo"})); // things after the command are "args" and left unparsed, not options + + BOOST_CHECK_EQUAL(SUCCESS, testfn(std::array{"x", "-opt1=foo", "cmd2"})); + BOOST_CHECK_EQUAL(SUCCESS, testfn(std::array{"x", "-opt1=foo", "cmd3"})); + BOOST_CHECK_EQUAL(COMMAND_OPTS, testfn(std::array{"x", "-opt2=foo", "cmd1"})); + BOOST_CHECK_EQUAL(COMMAND_OPTS, testfn(std::array{"x", "-opt2=foo", "cmd2"})); + BOOST_CHECK_EQUAL(SUCCESS, testfn(std::array{"x", "-opt2=foo", "cmd3"})); + BOOST_CHECK_EQUAL(SUCCESS, testfn(std::array{"x", "-opt3=foo", "cmd1"})); + BOOST_CHECK_EQUAL(SUCCESS, testfn(std::array{"x", "-opt3=foo", "cmd2"})); + BOOST_CHECK_EQUAL(SUCCESS, testfn(std::array{"x", "-opt3=foo", "cmd3"})); + + BOOST_CHECK_EQUAL(COMMAND_OPTS, testfn(std::array{"x", "-opt1=foo", "-opt3=bar", "-opt2=baz", "cmd1"})); + BOOST_CHECK_EQUAL(COMMAND_OPTS, testfn(std::array{"x", "-opt1=foo", "-opt3=bar", "-opt2=baz", "cmd2"})); + BOOST_CHECK_EQUAL(SUCCESS, testfn(std::array{"x", "-opt1=foo", "-opt3=bar", "-opt2=baz", "cmd3"})); + + BOOST_CHECK_EQUAL(PARSE_FAIL, testfn(std::array{"x", "cmd4"})); + BOOST_CHECK_EQUAL(NO_COMMAND, testfn(std::array{"x", "-opt3=foo"})); + BOOST_CHECK_EQUAL(PARSE_FAIL, testfn(std::array{"x", "-opt4=foo"})); +} + +BOOST_AUTO_TEST_CASE(util_AddCommand_clearargs_replaces_command_options) +{ + const auto add_command{[&](TestArgsManager& test_args, const std::string& option) { + test_args.AddArg(option, "option", ArgsManager::ALLOW_ANY, OptionsCategory::COMMAND_OPTIONS); + test_args.AddCommand("cmd", "cmd", {option}); + }}; + + TestArgsManager test_args; + add_command(test_args, "-opt1"); + test_args.ClearArgs(); + add_command(test_args, "-opt2"); + + const auto help{test_args.GetHelpMessage()}; + BOOST_CHECK(help.find("-opt2") != std::string::npos); + + test_args.ForceSetArg("-opt2", "1"); + std::vector details; + BOOST_CHECK(test_args.CheckCommandOptions("cmd", &details)); + BOOST_CHECK(details.empty()); +} + BOOST_AUTO_TEST_CASE(util_GetChainTypeString) { TestArgsManager test_args;