diff --git a/test/unittest/test_argument_parser.cpp b/test/unittest/test_argument_parser.cpp index ad61668c..3d63e5c8 100644 --- a/test/unittest/test_argument_parser.cpp +++ b/test/unittest/test_argument_parser.cpp @@ -29,34 +29,32 @@ TEST_CASE("Optional arguments support long names") CHECK(parsed.get("long_arg")); } -TEST_CASE("ArgumentParser adds help argument automatically...") +TEST_CASE("ArgumentParser adds help argument automatically with short name") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - SUBCASE("...with short name") - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-h"})); - } + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-h"})); +} + +TEST_CASE("ArgumentParser adds help argument automatically with long name") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - SUBCASE("...with long name") - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "--help"})); - } + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "--help"})); } -TEST_CASE("ArgumentParser adds help argument when requested...") +TEST_CASE("ArgumentParser adds help argument when requested with short name") { auto parser = argparse::ArgumentParser().add_help(true).handle(argparse::Handle::none); - SUBCASE("...with short name") - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-h"})); - } + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-h"})); +} + +TEST_CASE("ArgumentParser adds help argument when requested with long name") +{ + auto parser = argparse::ArgumentParser().add_help(true).handle(argparse::Handle::none); - SUBCASE("...with long name") - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "--help"})); - } + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "--help"})); } TEST_CASE("ArgumentParser does not add help argument when requested not to") @@ -66,61 +64,55 @@ TEST_CASE("ArgumentParser does not add help argument when requested not to") CHECK_THROWS(parser.parse_args(2, cstr_arr{"prog", "-h"})); } -TEST_CASE("ArgumentParser does not handle help when requested to...") +TEST_CASE("ArgumentParser does not handle help when requested to handle nothing") { - SUBCASE("...handle nothing") - { - auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-h"}); + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-h"}); - CHECK(parsed.get_value("help") == true); - } + CHECK(parsed.get_value("help") == true); +} - SUBCASE("...handle parsing errors") - { - auto parser = argparse::ArgumentParser().handle(argparse::Handle::errors); +TEST_CASE("ArgumentParser does not handle help when requested to handle parsing errors") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::errors); - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-h"}); + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-h"}); - CHECK(parsed.get_value("help") == true); - } + CHECK(parsed.get_value("help") == true); +} - SUBCASE("...handle version") - { - auto parser = argparse::ArgumentParser().handle(argparse::Handle::version); +TEST_CASE("ArgumentParser does not handle help when requested to handle version") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::version); - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-h"}); + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-h"}); - CHECK(parsed.get_value("help") == true); - } + CHECK(parsed.get_value("help") == true); } -TEST_CASE("ArgumentParser does not handle parsing errors when requested to...") +TEST_CASE("ArgumentParser does not handle parsing errors when requested to handle nothing") { - SUBCASE("...handle nothing") - { - auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - parser.add_argument("pos"); + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos"); - CHECK_THROWS_AS(parser.parse_args(1, cstr_arr{"prog"}), argparse::parsing_error); - } + CHECK_THROWS_AS(parser.parse_args(1, cstr_arr{"prog"}), argparse::parsing_error); +} - SUBCASE("...handle help") - { - auto parser = argparse::ArgumentParser().handle(argparse::Handle::help); - parser.add_argument("pos"); +TEST_CASE("ArgumentParser does not handle parsing errors when requested to handle help") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::help); + parser.add_argument("pos"); - CHECK_THROWS_AS(parser.parse_args(1, cstr_arr{"prog"}), argparse::parsing_error); - } + CHECK_THROWS_AS(parser.parse_args(1, cstr_arr{"prog"}), argparse::parsing_error); +} - SUBCASE("...handle version") - { - auto parser = argparse::ArgumentParser().handle(argparse::Handle::version); - parser.add_argument("pos"); +TEST_CASE("ArgumentParser does not handle parsing errors when requested to handle version") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::version); + parser.add_argument("pos"); - CHECK_THROWS_AS(parser.parse_args(1, cstr_arr{"prog"}), argparse::parsing_error); - } + CHECK_THROWS_AS(parser.parse_args(1, cstr_arr{"prog"}), argparse::parsing_error); } TEST_CASE("ArgumentParser does not handle version when requested to handle nothing") @@ -153,153 +145,158 @@ TEST_CASE("ArgumentParser does not handle version when requested to handle help" CHECK(parsed.get_value("v") == true); } -TEST_CASE("ArgumentParser uses first command-line parameter as its name...") +TEST_CASE("ArgumentParser uses first command-line parameter as its name when executed from current directory using no separators in usage message") { auto parser = argparse::ArgumentParser().add_help(false); - SUBCASE("...when executed from current directory...") - { - SUBCASE("...using no separators...") - { - parser.parse_args(1, cstr_arr{"prog"}); - - SUBCASE("...in usage message") - { - CHECK(parser.format_usage() == "usage: prog"s); - } - - SUBCASE("...in help message") - { - CHECK(parser.format_help() == "usage: prog"s); - } - } - - SUBCASE("...using slash separators...") - { - parser.parse_args(1, cstr_arr{"./prog"}); - - SUBCASE("...in usage message") - { - CHECK(parser.format_usage() == "usage: prog"s); - } - - SUBCASE("...in help message") - { - CHECK(parser.format_help() == "usage: prog"s); - } - } - - SUBCASE("...using backslash separators...") - { - parser.parse_args(1, cstr_arr{".\\prog"}); - - SUBCASE("...in usage message") - { - CHECK(parser.format_usage() == "usage: prog"s); - } - - SUBCASE("...in help message") - { - CHECK(parser.format_help() == "usage: prog"s); - } - } - } - - SUBCASE("...without preceding path when executed from nested directory...") - { - SUBCASE("...using slash separators...") - { - parser.parse_args(1, cstr_arr{"./utils/prog"}); - - SUBCASE("...in usage message") - { - CHECK(parser.format_usage() == "usage: prog"s); - } - - SUBCASE("...in help message") - { - CHECK(parser.format_help() == "usage: prog"s); - } - } - - SUBCASE("...using backslash separators...") - { - parser.parse_args(1, cstr_arr{".\\utils\\prog"}); - - SUBCASE("...in usage message") - { - CHECK(parser.format_usage() == "usage: prog"s); - } - - SUBCASE("...in help message") - { - CHECK(parser.format_help() == "usage: prog"s); - } - } - } - - SUBCASE("...without preceding path when executed from upper directory...") - { - SUBCASE("...using slash separators...") - { - parser.parse_args(1, cstr_arr{"../prog"}); - - SUBCASE("...in usage message") - { - CHECK(parser.format_usage() == "usage: prog"s); - } - - SUBCASE("...in help message") - { - CHECK(parser.format_help() == "usage: prog"s); - } - } - - SUBCASE("...using backslash separators...") - { - parser.parse_args(1, cstr_arr{"..\\prog"}); - - SUBCASE("...in usage message") - { - CHECK(parser.format_usage() == "usage: prog"s); - } - - SUBCASE("...in help message") - { - CHECK(parser.format_help() == "usage: prog"s); - } - } - } -} - -TEST_CASE("ArgumentParser uses prog parameter as its name...") + parser.parse_args(1, cstr_arr{"prog"}); + + CHECK(parser.format_usage() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name when executed from current directory using no separators in help message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{"prog"}); + + CHECK(parser.format_help() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name when executed from current directory using slash separators in usage message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{"./prog"}); + + CHECK(parser.format_usage() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name when executed from current directory using slash separators in help message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{"./prog"}); + + CHECK(parser.format_help() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name when executed from current directory using backslash separators in usage message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{".\\prog"}); + + CHECK(parser.format_usage() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name when executed from current directory using backslash separators in help message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{".\\prog"}); + + CHECK(parser.format_help() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name without preceding path when executed from nested directory using slash separators in usage message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{"./utils/prog"}); + + CHECK(parser.format_usage() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name without preceding path when executed from nested directory using slash separators in help message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{"./utils/prog"}); + + CHECK(parser.format_help() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name without preceding path when executed from nested directory using backslash separators in usage message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{".\\utils\\prog"}); + + CHECK(parser.format_usage() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name without preceding path when executed from nested directory using backslash separators in help message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{".\\utils\\prog"}); + + CHECK(parser.format_help() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name without preceding path when executed from upper directory using slash separators in usage message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{"../prog"}); + + CHECK(parser.format_usage() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name without preceding path when executed from upper directory using slash separators in help message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{"../prog"}); + + CHECK(parser.format_help() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name without preceding path when executed from upper directory using backslash separators in usage message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{"..\\prog"}); + + CHECK(parser.format_usage() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses first command-line parameter as its name without preceding path when executed from upper directory using backslash separators in help message") +{ + auto parser = argparse::ArgumentParser().add_help(false); + + parser.parse_args(1, cstr_arr{"..\\prog"}); + + CHECK(parser.format_help() == "usage: prog"s); +} + +TEST_CASE("ArgumentParser uses prog parameter as its name in usage message") { auto parser = argparse::ArgumentParser().prog("prog").add_help(false); - SUBCASE("...in usage message") - { - CHECK(parser.format_usage() == "usage: prog"s); - } + CHECK(parser.format_usage() == "usage: prog"s); +} - SUBCASE("...in help message") - { - CHECK(parser.format_help() == "usage: prog"s); - } +TEST_CASE("ArgumentParser uses prog parameter as its name in help message") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + + CHECK(parser.format_help() == "usage: prog"s); } -TEST_CASE("ArgumentParser uses usage parameter as its usage...") +TEST_CASE("ArgumentParser uses usage parameter as its usage in usage message") { auto parser = argparse::ArgumentParser().prog("prog").add_help(false).usage("program [options]"); - SUBCASE("...in usage message") - { - CHECK(parser.format_usage() == "usage: program [options]"s); - } + CHECK(parser.format_usage() == "usage: program [options]"s); +} + +TEST_CASE("ArgumentParser uses usage parameter as its usage in help message") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false).usage("program [options]"); - SUBCASE("...in help message") - { - CHECK(parser.format_help() == "usage: program [options]"s); - } + CHECK(parser.format_help() == "usage: program [options]"s); } TEST_CASE("Adding a positional argument with required option set results in error") diff --git a/test/unittest/test_error_message.cpp b/test/unittest/test_error_message.cpp index 0e6ca206..b4388d62 100644 --- a/test/unittest/test_error_message.cpp +++ b/test/unittest/test_error_message.cpp @@ -9,192 +9,179 @@ using namespace std::string_literals; -TEST_CASE("Missing required arguments message lists all optional argument's names...") +TEST_CASE("Missing required arguments message lists all optional argument's names for one argument with one name") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").required(true); - SUBCASE("...for one argument...") - { - SUBCASE("...with one name") - { - parser.add_argument("-o").required(true); - - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o", argparse::parsing_error); +} - SUBCASE("...with two names") - { - parser.add_argument("-o", "--option").required(true); +TEST_CASE("Missing required arguments message lists all optional argument's names for one argument with two names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o", "--option").required(true); - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o/--option", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o/--option", argparse::parsing_error); +} - SUBCASE("...with three names") - { - parser.add_argument("-o", "--option", "--long-option").required(true); +TEST_CASE("Missing required arguments message lists all optional argument's names for one argument with three names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o", "--option", "--long-option").required(true); - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o/--option/--long-option", argparse::parsing_error); - } - } + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o/--option/--long-option", argparse::parsing_error); +} - SUBCASE("...for two arguments...") - { - SUBCASE("...with one name") - { - parser.add_argument("-o").required(true); - parser.add_argument("-r").required(true); +TEST_CASE("Missing required arguments message lists all optional argument's names for two arguments with one name") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").required(true); + parser.add_argument("-r").required(true); - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o -r", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o -r", argparse::parsing_error); +} - SUBCASE("...with two names") - { - parser.add_argument("-o", "--option").required(true); - parser.add_argument("-r", "--required").required(true); +TEST_CASE("Missing required arguments message lists all optional argument's names for two arguments with two names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o", "--option").required(true); + parser.add_argument("-r", "--required").required(true); - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o/--option -r/--required", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o/--option -r/--required", argparse::parsing_error); +} - SUBCASE("...with three names") - { - parser.add_argument("-o", "--option", "--long-option").required(true); - parser.add_argument("-r", "--required", "--really-required").required(true); +TEST_CASE("Missing required arguments message lists all optional argument's names for two arguments with three names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o", "--option", "--long-option").required(true); + parser.add_argument("-r", "--required", "--really-required").required(true); - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o/--option/--long-option -r/--required/--really-required", argparse::parsing_error); - } - } + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o/--option/--long-option -r/--required/--really-required", argparse::parsing_error); } -TEST_CASE("Invalid choice message lists all optional argument's names...") +TEST_CASE("Invalid choice message lists all optional argument's names for argument with one name") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").choices({"a"s, "b"s}); - SUBCASE("...for argument with one name") - { - parser.add_argument("-o").choices({"a"s, "b"s}); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "c"}), "argument -o: invalid choice: \"c\" (choose from \"a\", \"b\")", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "c"}), "argument -o: invalid choice: \"c\" (choose from \"a\", \"b\")", argparse::parsing_error); +} - SUBCASE("...for argument with two names") - { - parser.add_argument("-o", "--option").choices({"a"s, "b"s}); +TEST_CASE("Invalid choice message lists all optional argument's names for argument with two names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o", "--option").choices({"a"s, "b"s}); - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "c"}), "argument -o/--option: invalid choice: \"c\" (choose from \"a\", \"b\")", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "c"}), "argument -o/--option: invalid choice: \"c\" (choose from \"a\", \"b\")", argparse::parsing_error); +} - SUBCASE("...for argument with three names") - { - parser.add_argument("-o", "--option", "--long-option").choices({"a"s, "b"s}); +TEST_CASE("Invalid choice message lists all optional argument's names for argument with three names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o", "--option", "--long-option").choices({"a"s, "b"s}); - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "c"}), "argument -o/--option/--long-option: invalid choice: \"c\" (choose from \"a\", \"b\")", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "c"}), "argument -o/--option/--long-option: invalid choice: \"c\" (choose from \"a\", \"b\")", argparse::parsing_error); } -TEST_CASE("Expected number of arguments message lists all optional argument's names...") +TEST_CASE("Expected number of arguments message lists all optional argument's names for argument with one name") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(1); - SUBCASE("...for argument with one name") - { - parser.add_argument("-o").nargs(1); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o: expected 1 argument", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o: expected 1 argument", argparse::parsing_error); +} - SUBCASE("...for argument with two names") - { - parser.add_argument("-o", "--option").nargs(1); +TEST_CASE("Expected number of arguments message lists all optional argument's names for argument with two names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o", "--option").nargs(1); - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o/--option: expected 1 argument", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o/--option: expected 1 argument", argparse::parsing_error); +} - SUBCASE("...for argument with three names") - { - parser.add_argument("-o", "--option", "--long-option").nargs(1); +TEST_CASE("Expected number of arguments message lists all optional argument's names for argument with three names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o", "--option", "--long-option").nargs(1); - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o/--option/--long-option: expected 1 argument", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o/--option/--long-option: expected 1 argument", argparse::parsing_error); } -TEST_CASE("Expected at least one argument message lists all optional argument's names...") +TEST_CASE("Expected at least one argument message lists all optional argument's names for argument with one name") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::one_or_more); - SUBCASE("...for argument with one name") - { - parser.add_argument("-o").nargs(argparse::one_or_more); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o: expected at least one argument", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o: expected at least one argument", argparse::parsing_error); +} - SUBCASE("...for argument with two names") - { - parser.add_argument("-o", "--option").nargs(argparse::one_or_more); +TEST_CASE("Expected at least one argument message lists all optional argument's names for argument with two names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o", "--option").nargs(argparse::one_or_more); - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o/--option: expected at least one argument", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o/--option: expected at least one argument", argparse::parsing_error); +} - SUBCASE("...for argument with three names") - { - parser.add_argument("-o", "--option", "--long-option").nargs(argparse::one_or_more); +TEST_CASE("Expected at least one argument message lists all optional argument's names for argument with three names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o", "--option", "--long-option").nargs(argparse::one_or_more); - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o/--option/--long-option: expected at least one argument", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o/--option/--long-option: expected at least one argument", argparse::parsing_error); } -TEST_CASE("Expected one argument message lists all optional argument's names...") +TEST_CASE("Expected one argument message lists all optional argument's names for argument with one name") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o"); - SUBCASE("...for argument with one name") - { - parser.add_argument("-o"); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o: expected one argument", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o: expected one argument", argparse::parsing_error); +} - SUBCASE("...for argument with two names") - { - parser.add_argument("-o", "--option"); +TEST_CASE("Expected one argument message lists all optional argument's names for argument with two names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o", "--option"); - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o/--option: expected one argument", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o/--option: expected one argument", argparse::parsing_error); +} - SUBCASE("...for argument with three names") - { - parser.add_argument("-o", "--option", "--long-option"); +TEST_CASE("Expected one argument message lists all optional argument's names for argument with three names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o", "--option", "--long-option"); - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o/--option/--long-option: expected one argument", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o/--option/--long-option: expected one argument", argparse::parsing_error); } -TEST_CASE("Argument not allowed with argument message lists all optional argument's names...") +TEST_CASE("Argument not allowed with argument message lists all optional argument's names for arguments with one name") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); auto group = parser.add_mutually_exclusive_group(); + group.add_argument("-a"); + group.add_argument("-b"); - SUBCASE("...for arguments with one name") - { - group.add_argument("-a"); - group.add_argument("-b"); - - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-a", "a", "-b", "b"}), "argument -b: not allowed with argument -a", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-a", "a", "-b", "b"}), "argument -b: not allowed with argument -a", argparse::parsing_error); +} - SUBCASE("...for arguments with two names") - { - group.add_argument("-a", "--aaa"); - group.add_argument("-b", "--bbb"); +TEST_CASE("Argument not allowed with argument message lists all optional argument's names for arguments with two names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + auto group = parser.add_mutually_exclusive_group(); + group.add_argument("-a", "--aaa"); + group.add_argument("-b", "--bbb"); - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-a", "a", "-b", "b"}), "argument -b/--bbb: not allowed with argument -a/--aaa", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-a", "a", "-b", "b"}), "argument -b/--bbb: not allowed with argument -a/--aaa", argparse::parsing_error); +} - SUBCASE("...for arguments with three names") - { - group.add_argument("-a", "--aaa", "--more-aaa"); - group.add_argument("-b", "--bbb", "--more-bbb"); +TEST_CASE("Argument not allowed with argument message lists all optional argument's names for arguments with three names") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + auto group = parser.add_mutually_exclusive_group(); + group.add_argument("-a", "--aaa", "--more-aaa"); + group.add_argument("-b", "--bbb", "--more-bbb"); - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-a", "a", "-b", "b"}), "argument -b/--bbb/--more-bbb: not allowed with argument -a/--aaa/--more-aaa", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-a", "a", "-b", "b"}), "argument -b/--bbb/--more-bbb: not allowed with argument -a/--aaa/--more-aaa", argparse::parsing_error); } diff --git a/test/unittest/test_help_message.cpp b/test/unittest/test_help_message.cpp index 60c1c81e..012b1489 100644 --- a/test/unittest/test_help_message.cpp +++ b/test/unittest/test_help_message.cpp @@ -12,603 +12,634 @@ using namespace std::string_literals; -TEST_CASE("ArgumentParser provides help message...") +TEST_CASE("ArgumentParser provides help message with usage section") { auto parser = argparse::ArgumentParser().prog("prog").add_help(false); - SUBCASE("...with usage section") - { - CHECK(parser.format_help() == "usage: prog"s); - } - - SUBCASE("...with usage section and description for description and no arguments") - { - auto parser = argparse::ArgumentParser().prog("prog").description("A foo that bars").add_help(false); - - CHECK(parser.format_help() == "usage: prog\n\nA foo that bars"s); - } + CHECK(parser.format_help() == "usage: prog"s); +} - SUBCASE("...with usage section and epilog for epilog and no arguments") - { - auto parser = argparse::ArgumentParser().prog("prog").epilog("And that's how you'd foo a bar").add_help(false); +TEST_CASE("ArgumentParser provides help message with usage section and description for description and no arguments") +{ + auto parser = argparse::ArgumentParser().prog("prog").description("A foo that bars").add_help(false); - CHECK(parser.format_help() == "usage: prog\n\nAnd that's how you'd foo a bar"s); - } + CHECK(parser.format_help() == "usage: prog\n\nA foo that bars"s); +} - SUBCASE("...with usage section and positional arguments section for one positional argument") - { - parser.add_argument("p1"); +TEST_CASE("ArgumentParser provides help message with usage section and epilog for epilog and no arguments") +{ + auto parser = argparse::ArgumentParser().prog("prog").epilog("And that's how you'd foo a bar").add_help(false); - CHECK(parser.format_help() == "usage: prog p1\n\npositional arguments:\n p1"s); - } + CHECK(parser.format_help() == "usage: prog\n\nAnd that's how you'd foo a bar"s); +} - SUBCASE("...with usage section and positional arguments section for two positional arguments") - { - parser.add_argument("p1"); - parser.add_argument("p2"); +TEST_CASE("ArgumentParser provides help message with usage section and positional arguments section for one positional argument") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1"); - CHECK(parser.format_help() == "usage: prog p1 p2\n\npositional arguments:\n p1\n p2"s); - } + CHECK(parser.format_help() == "usage: prog p1\n\npositional arguments:\n p1"s); +} - SUBCASE("...with usage section and positional arguments section for three positional arguments") - { - parser.add_argument("p1"); - parser.add_argument("p2"); - parser.add_argument("p3"); +TEST_CASE("ArgumentParser provides help message with usage section and positional arguments section for two positional arguments") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1"); + parser.add_argument("p2"); - CHECK(parser.format_help() == "usage: prog p1 p2 p3\n\npositional arguments:\n p1\n p2\n p3"s); - } + CHECK(parser.format_help() == "usage: prog p1 p2\n\npositional arguments:\n p1\n p2"s); +} - SUBCASE("...with usage section and optional arguments section for one optional argument") - { - parser.add_argument("-o"); +TEST_CASE("ArgumentParser provides help message with usage section and positional arguments section for three positional arguments") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1"); + parser.add_argument("p2"); + parser.add_argument("p3"); - CHECK(parser.format_help() == "usage: prog [-o O]\n\noptional arguments:\n -o O"s); - } + CHECK(parser.format_help() == "usage: prog p1 p2 p3\n\npositional arguments:\n p1\n p2\n p3"s); +} - SUBCASE("...with usage section and optional arguments section for two optional arguments") - { - parser.add_argument("-o"); - parser.add_argument("--option"); +TEST_CASE("ArgumentParser provides help message with usage section and optional arguments section for one optional argument") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o"); - CHECK(parser.format_help() == "usage: prog [-o O] [--option OPTION]\n\noptional arguments:\n -o O\n --option OPTION"s); - } + CHECK(parser.format_help() == "usage: prog [-o O]\n\noptional arguments:\n -o O"s); +} - SUBCASE("...with usage section and optional arguments section for three optional arguments") - { - parser.add_argument("-o"); - parser.add_argument("--option"); - parser.add_argument("--very-long-name"); +TEST_CASE("ArgumentParser provides help message with usage section and optional arguments section for two optional arguments") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o"); + parser.add_argument("--option"); - CHECK(parser.format_help() == "usage: prog [-o O] [--option OPTION] [--very-long-name VERY_LONG_NAME]\n\noptional arguments:\n -o O\n --option OPTION\n --very-long-name VERY_LONG_NAME"s); - } + CHECK(parser.format_help() == "usage: prog [-o O] [--option OPTION]\n\noptional arguments:\n -o O\n --option OPTION"s); +} - SUBCASE("...with usage section, positional arguments section, and optional arguments section for one positional and one optional argument") - { - parser.add_argument("p1"); - parser.add_argument("-o"); +TEST_CASE("ArgumentParser provides help message with usage section and optional arguments section for three optional arguments") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o"); + parser.add_argument("--option"); + parser.add_argument("--very-long-name"); - CHECK(parser.format_help() == "usage: prog [-o O] p1\n\npositional arguments:\n p1\n\noptional arguments:\n -o O"s); - } + CHECK(parser.format_help() == "usage: prog [-o O] [--option OPTION] [--very-long-name VERY_LONG_NAME]\n\noptional arguments:\n -o O\n --option OPTION\n --very-long-name VERY_LONG_NAME"s); +} - SUBCASE("...with usage section, positional arguments section, and optional arguments section for three positional and three optional arguments") - { - parser.add_argument("p1"); - parser.add_argument("-o"); - parser.add_argument("p2"); - parser.add_argument("-a"); - parser.add_argument("p3"); - parser.add_argument("-z"); +TEST_CASE("ArgumentParser provides help message with usage section, positional arguments section, and optional arguments section for one positional and one optional argument") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1"); + parser.add_argument("-o"); - CHECK(parser.format_help() == "usage: prog [-o O] [-a A] [-z Z] p1 p2 p3\n\npositional arguments:\n p1\n p2\n p3\n\noptional arguments:\n -o O\n -a A\n -z Z"s); - } + CHECK(parser.format_help() == "usage: prog [-o O] p1\n\npositional arguments:\n p1\n\noptional arguments:\n -o O"s); } -TEST_CASE("Help message contains...") +TEST_CASE("ArgumentParser provides help message with usage section, positional arguments section, and optional arguments section for three positional and three optional arguments") { auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1"); + parser.add_argument("-o"); + parser.add_argument("p2"); + parser.add_argument("-a"); + parser.add_argument("p3"); + parser.add_argument("-z"); + + CHECK(parser.format_help() == "usage: prog [-o O] [-a A] [-z Z] p1 p2 p3\n\npositional arguments:\n p1\n p2\n p3\n\noptional arguments:\n -o O\n -a A\n -z Z"s); +} - SUBCASE("...for positional argument...") - { - SUBCASE("...name") - { - parser.add_argument("p1"); +TEST_CASE("Help message contains for positional argument name") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1"); - CHECK(parser.format_help() == "usage: prog p1\n\npositional arguments:\n p1"s); - } + CHECK(parser.format_help() == "usage: prog p1\n\npositional arguments:\n p1"s); +} - SUBCASE("...metavar for argument with metavar set") - { - parser.add_argument("p1").metavar("metap1"); +TEST_CASE("Help message contains for positional argument metavar for argument with metavar set") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").metavar("metap1"); - CHECK(parser.format_help() == "usage: prog metap1\n\npositional arguments:\n metap1"s); - } + CHECK(parser.format_help() == "usage: prog metap1\n\npositional arguments:\n metap1"s); +} - SUBCASE("...name and help for argument with help string") - { - parser.add_argument("p1").help("help1"); +TEST_CASE("Help message contains for positional argument name and help for argument with help string") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").help("help1"); - CHECK(parser.format_help() == "usage: prog p1\n\npositional arguments:\n p1 help1"s); - } + CHECK(parser.format_help() == "usage: prog p1\n\npositional arguments:\n p1 help1"s); +} - SUBCASE("...choices for argument with choices set") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}); +TEST_CASE("Help message contains for positional argument choices for argument with choices set") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}); - CHECK(parser.format_help() == "usage: prog {\"foo\",\"bar\"}\n\npositional arguments:\n {\"foo\",\"bar\"}"s); - } + CHECK(parser.format_help() == "usage: prog {\"foo\",\"bar\"}\n\npositional arguments:\n {\"foo\",\"bar\"}"s); +} - SUBCASE("...name for argument with nargs set as number...") - { - SUBCASE("...1") - { - parser.add_argument("p1").nargs(1); +TEST_CASE("Help message contains for positional argument name for argument with nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").nargs(1); - CHECK(parser.format_help() == "usage: prog p1\n\npositional arguments:\n p1"s); - } + CHECK(parser.format_help() == "usage: prog p1\n\npositional arguments:\n p1"s); +} - SUBCASE("...2") - { - parser.add_argument("p1").nargs(2); +TEST_CASE("Help message contains for positional argument name for argument with nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").nargs(2); - CHECK(parser.format_help() == "usage: prog p1 p1\n\npositional arguments:\n p1"s); - } + CHECK(parser.format_help() == "usage: prog p1 p1\n\npositional arguments:\n p1"s); +} - SUBCASE("...3") - { - parser.add_argument("p1").nargs(3); +TEST_CASE("Help message contains for positional argument name for argument with nargs set as number 3") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").nargs(3); - CHECK(parser.format_help() == "usage: prog p1 p1 p1\n\npositional arguments:\n p1"s); - } - } + CHECK(parser.format_help() == "usage: prog p1 p1 p1\n\npositional arguments:\n p1"s); +} - SUBCASE("...metavar for argument with metavar set and nargs set as number...") - { - SUBCASE("...1") - { - parser.add_argument("p1").metavar("metap1").nargs(1); +TEST_CASE("Help message contains for positional argument metavar for argument with metavar set and nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").metavar("metap1").nargs(1); - CHECK(parser.format_help() == "usage: prog metap1\n\npositional arguments:\n metap1"s); - } + CHECK(parser.format_help() == "usage: prog metap1\n\npositional arguments:\n metap1"s); +} - SUBCASE("...2") - { - parser.add_argument("p1").metavar("metap1").nargs(2); +TEST_CASE("Help message contains for positional argument metavar for argument with metavar set and nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").metavar("metap1").nargs(2); - CHECK(parser.format_help() == "usage: prog metap1 metap1\n\npositional arguments:\n metap1"s); - } + CHECK(parser.format_help() == "usage: prog metap1 metap1\n\npositional arguments:\n metap1"s); +} - SUBCASE("...3") - { - parser.add_argument("p1").metavar("metap1").nargs(3); +TEST_CASE("Help message contains for positional argument metavar for argument with metavar set and nargs set as number 3") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").metavar("metap1").nargs(3); - CHECK(parser.format_help() == "usage: prog metap1 metap1 metap1\n\npositional arguments:\n metap1"s); - } - } + CHECK(parser.format_help() == "usage: prog metap1 metap1 metap1\n\npositional arguments:\n metap1"s); +} - SUBCASE("...choices for argument with choices set and nargs set as number...") - { - SUBCASE("...1") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(1); +TEST_CASE("Help message contains for positional argument choices for argument with choices set and nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(1); - CHECK(parser.format_help() == "usage: prog {\"foo\",\"bar\"}\n\npositional arguments:\n {\"foo\",\"bar\"}"s); - } + CHECK(parser.format_help() == "usage: prog {\"foo\",\"bar\"}\n\npositional arguments:\n {\"foo\",\"bar\"}"s); +} - SUBCASE("...2") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(2); +TEST_CASE("Help message contains for positional argument choices for argument with choices set and nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(2); - CHECK(parser.format_help() == "usage: prog {\"foo\",\"bar\"} {\"foo\",\"bar\"}\n\npositional arguments:\n {\"foo\",\"bar\"}"s); - } + CHECK(parser.format_help() == "usage: prog {\"foo\",\"bar\"} {\"foo\",\"bar\"}\n\npositional arguments:\n {\"foo\",\"bar\"}"s); +} - SUBCASE("...3") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(3); +TEST_CASE("Help message contains for positional argument choices for argument with choices set and nargs set as number 3") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(3); - CHECK(parser.format_help() == "usage: prog {\"foo\",\"bar\"} {\"foo\",\"bar\"} {\"foo\",\"bar\"}\n\npositional arguments:\n {\"foo\",\"bar\"}"s); - } - } + CHECK(parser.format_help() == "usage: prog {\"foo\",\"bar\"} {\"foo\",\"bar\"} {\"foo\",\"bar\"}\n\npositional arguments:\n {\"foo\",\"bar\"}"s); +} - SUBCASE("...name for argument with nargs set as zero_or_one") - { - parser.add_argument("p1").nargs(argparse::zero_or_one); +TEST_CASE("Help message contains for positional argument name for argument with nargs set as zero_or_one") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").nargs(argparse::zero_or_one); - CHECK(parser.format_help() == "usage: prog [p1]\n\npositional arguments:\n p1"s); - } + CHECK(parser.format_help() == "usage: prog [p1]\n\npositional arguments:\n p1"s); +} - SUBCASE("...metavar for argument with metavar set and nargs set as zero_or_one") - { - parser.add_argument("p1").metavar("metap1").nargs(argparse::zero_or_one); +TEST_CASE("Help message contains for positional argument metavar for argument with metavar set and nargs set as zero_or_one") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").metavar("metap1").nargs(argparse::zero_or_one); - CHECK(parser.format_help() == "usage: prog [metap1]\n\npositional arguments:\n metap1"s); - } + CHECK(parser.format_help() == "usage: prog [metap1]\n\npositional arguments:\n metap1"s); +} - SUBCASE("...choices for argument with choices set and nargs set as zero_or_one") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one); +TEST_CASE("Help message contains for positional argument choices for argument with choices set and nargs set as zero_or_one") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one); - CHECK(parser.format_help() == "usage: prog [{\"foo\",\"bar\"}]\n\npositional arguments:\n {\"foo\",\"bar\"}"s); - } + CHECK(parser.format_help() == "usage: prog [{\"foo\",\"bar\"}]\n\npositional arguments:\n {\"foo\",\"bar\"}"s); +} - SUBCASE("...name for argument with nargs set as zero_or_more") - { - parser.add_argument("p1").nargs(argparse::zero_or_more); +TEST_CASE("Help message contains for positional argument name for argument with nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").nargs(argparse::zero_or_more); - CHECK(parser.format_help() == "usage: prog [p1 [p1 ...]]\n\npositional arguments:\n p1"s); - } + CHECK(parser.format_help() == "usage: prog [p1 [p1 ...]]\n\npositional arguments:\n p1"s); +} - SUBCASE("...metavar for argument with metavar set and nargs set as zero_or_more") - { - parser.add_argument("p1").metavar("metap1").nargs(argparse::zero_or_more); +TEST_CASE("Help message contains for positional argument metavar for argument with metavar set and nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").metavar("metap1").nargs(argparse::zero_or_more); - CHECK(parser.format_help() == "usage: prog [metap1 [metap1 ...]]\n\npositional arguments:\n metap1"s); - } + CHECK(parser.format_help() == "usage: prog [metap1 [metap1 ...]]\n\npositional arguments:\n metap1"s); +} - SUBCASE("...choices for argument with choices set and nargs set as zero_or_more") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more); +TEST_CASE("Help message contains for positional argument choices for argument with choices set and nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more); - CHECK(parser.format_help() == "usage: prog [{\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]\n\npositional arguments:\n {\"foo\",\"bar\"}"s); - } + CHECK(parser.format_help() == "usage: prog [{\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]\n\npositional arguments:\n {\"foo\",\"bar\"}"s); +} - SUBCASE("...name for argument with nargs set as one_or_more") - { - parser.add_argument("p1").nargs(argparse::one_or_more); +TEST_CASE("Help message contains for positional argument name for argument with nargs set as one_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").nargs(argparse::one_or_more); - CHECK(parser.format_help() == "usage: prog p1 [p1 ...]\n\npositional arguments:\n p1"s); - } + CHECK(parser.format_help() == "usage: prog p1 [p1 ...]\n\npositional arguments:\n p1"s); +} - SUBCASE("...metavar for argument with metavar set and nargs set as one_or_more") - { - parser.add_argument("p1").metavar("metap1").nargs(argparse::one_or_more); +TEST_CASE("Help message contains for positional argument metavar for argument with metavar set and nargs set as one_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").metavar("metap1").nargs(argparse::one_or_more); - CHECK(parser.format_help() == "usage: prog metap1 [metap1 ...]\n\npositional arguments:\n metap1"s); - } + CHECK(parser.format_help() == "usage: prog metap1 [metap1 ...]\n\npositional arguments:\n metap1"s); +} - SUBCASE("...choices for argument with choices set and nargs set as one_or_more") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more); +TEST_CASE("Help message contains for positional argument choices for argument with choices set and nargs set as one_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more); - CHECK(parser.format_help() == "usage: prog {\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]\n\npositional arguments:\n {\"foo\",\"bar\"}"s); - } - } + CHECK(parser.format_help() == "usage: prog {\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]\n\npositional arguments:\n {\"foo\",\"bar\"}"s); +} - SUBCASE("...for optional argument...") - { - SUBCASE("...name for argument with store true action") - { - parser.add_argument("-o").action(argparse::store_true); +TEST_CASE("Help message contains for optional argument name for argument with store true action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_true); - CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o"s); - } + CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o"s); +} - SUBCASE("...name and long name for argument with store true action") - { - parser.add_argument("-o", "--option").action(argparse::store_true); +TEST_CASE("Help message contains for optional argument name and long name for argument with store true action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o", "--option").action(argparse::store_true); - CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o, --option"s); - } + CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o, --option"s); +} - SUBCASE("...name and help for argument with store true action and help string") - { - parser.add_argument("-o").action(argparse::store_true).help("help1"); +TEST_CASE("Help message contains for optional argument name and help for argument with store true action and help string") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_true).help("help1"); - CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o help1"s); - } + CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o help1"s); +} - SUBCASE("...name for argument with store false action") - { - parser.add_argument("-o").action(argparse::store_false); +TEST_CASE("Help message contains for optional argument name for argument with store false action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_false); - CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o"s); - } + CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o"s); +} - SUBCASE("...name and long name for argument with store false action") - { - parser.add_argument("-o", "--option").action(argparse::store_false); +TEST_CASE("Help message contains for optional argument name and long name for argument with store false action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o", "--option").action(argparse::store_false); - CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o, --option"s); - } + CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o, --option"s); +} - SUBCASE("...name and long name for argument with store false action") - { - parser.add_argument("-o", "--option").action(argparse::store_false); +TEST_CASE("Help message contains for optional argument name and long name for argument with store false action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o", "--option").action(argparse::store_false); - CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o, --option"s); - } + CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o, --option"s); +} - SUBCASE("...name and help for argument with store false action and help string") - { - parser.add_argument("-o").action(argparse::store_false).help("help1"); +TEST_CASE("Help message contains for optional argument name and help for argument with store false action and help string") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_false).help("help1"); - CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o help1"s); - } + CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o help1"s); +} - SUBCASE("...name for argument with store const action") - { - parser.add_argument("-o").action(argparse::store_const); +TEST_CASE("Help message contains for optional argument name for argument with store const action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_const); - CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o"s); - } + CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o"s); +} - SUBCASE("...name and long name for argument with store const action") - { - parser.add_argument("-o", "--option").action(argparse::store_const); +TEST_CASE("Help message contains for optional argument name and long name for argument with store const action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o", "--option").action(argparse::store_const); - CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o, --option"s); - } + CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o, --option"s); +} - SUBCASE("...name and help for argument with store const action and help string") - { - parser.add_argument("-o").action(argparse::store_const).help("help1"); +TEST_CASE("Help message contains for optional argument name and help for argument with store const action and help string") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_const).help("help1"); - CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o help1"s); - } + CHECK(parser.format_help() == "usage: prog [-o]\n\noptional arguments:\n -o help1"s); +} - SUBCASE("...name for argument with help action") - { - parser.add_argument("-h").action(argparse::help); +TEST_CASE("Help message contains for optional argument name for argument with help action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-h").action(argparse::help); - CHECK(parser.format_help() == "usage: prog [-h]\n\noptional arguments:\n -h"s); - } + CHECK(parser.format_help() == "usage: prog [-h]\n\noptional arguments:\n -h"s); +} - SUBCASE("...name and long name for argument with help action") - { - parser.add_argument("-h", "--help").action(argparse::help); +TEST_CASE("Help message contains for optional argument name and long name for argument with help action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-h", "--help").action(argparse::help); - CHECK(parser.format_help() == "usage: prog [-h]\n\noptional arguments:\n -h, --help"s); - } + CHECK(parser.format_help() == "usage: prog [-h]\n\noptional arguments:\n -h, --help"s); +} - SUBCASE("...name and help for argument with help action and help string") - { - parser.add_argument("-h").action(argparse::help).help("help1"); +TEST_CASE("Help message contains for optional argument name and help for argument with help action and help string") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-h").action(argparse::help).help("help1"); - CHECK(parser.format_help() == "usage: prog [-h]\n\noptional arguments:\n -h help1"s); - } + CHECK(parser.format_help() == "usage: prog [-h]\n\noptional arguments:\n -h help1"s); +} - SUBCASE("...name and help for automatically added help argument") - { - auto parser = argparse::ArgumentParser().prog("prog"); +TEST_CASE("Help message contains for optional argument name and help for automatically added help argument") +{ + auto parser = argparse::ArgumentParser().prog("prog"); - CHECK(parser.format_help() == "usage: prog [-h]\n\noptional arguments:\n -h, --help show this help message and exit"s); - } + CHECK(parser.format_help() == "usage: prog [-h]\n\noptional arguments:\n -h, --help show this help message and exit"s); +} - SUBCASE("...name and automatically added help for argument with version action") - { - parser.add_argument("-v").action(argparse::version); +TEST_CASE("Help message contains for optional argument name and automatically added help for argument with version action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-v").action(argparse::version); - CHECK(parser.format_help() == "usage: prog [-v]\n\noptional arguments:\n -v show program's version number and exit"s); - } + CHECK(parser.format_help() == "usage: prog [-v]\n\noptional arguments:\n -v show program's version number and exit"s); +} - SUBCASE("...name, long name, and automatically added help for argument with version action") - { - parser.add_argument("-v", "--version").action(argparse::version); +TEST_CASE("Help message contains for optional argument name, long name, and automatically added help for argument with version action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-v", "--version").action(argparse::version); - CHECK(parser.format_help() == "usage: prog [-v]\n\noptional arguments:\n -v, --version show program's version number and exit"s); - } + CHECK(parser.format_help() == "usage: prog [-v]\n\noptional arguments:\n -v, --version show program's version number and exit"s); +} - SUBCASE("...name and help for argument with version action and help string") - { - parser.add_argument("-v").action(argparse::version).help("version1"); +TEST_CASE("Help message contains for optional argument name and help for argument with version action and help string") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-v").action(argparse::version).help("version1"); - CHECK(parser.format_help() == "usage: prog [-v]\n\noptional arguments:\n -v version1"s); - } + CHECK(parser.format_help() == "usage: prog [-v]\n\noptional arguments:\n -v version1"s); +} - SUBCASE("...name and automatic metavar") - { - parser.add_argument("-o"); +TEST_CASE("Help message contains for optional argument name and automatic metavar") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o"); - CHECK(parser.format_help() == "usage: prog [-o O]\n\noptional arguments:\n -o O"s); - } + CHECK(parser.format_help() == "usage: prog [-o O]\n\noptional arguments:\n -o O"s); +} - SUBCASE("...name and metavar for argument with metavar") - { - parser.add_argument("-o").metavar("METAVARO"); +TEST_CASE("Help message contains for optional argument name and metavar for argument with metavar") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO"); - CHECK(parser.format_help() == "usage: prog [-o METAVARO]\n\noptional arguments:\n -o METAVARO"s); - } + CHECK(parser.format_help() == "usage: prog [-o METAVARO]\n\noptional arguments:\n -o METAVARO"s); +} - SUBCASE("...name, automatic metavar, and help for argument with help string") - { - parser.add_argument("-o").help("help1"); +TEST_CASE("Help message contains for optional argument name, automatic metavar, and help for argument with help string") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").help("help1"); - CHECK(parser.format_help() == "usage: prog [-o O]\n\noptional arguments:\n -o O help1"s); - } + CHECK(parser.format_help() == "usage: prog [-o O]\n\noptional arguments:\n -o O help1"s); +} - SUBCASE("...no brackets for argument with required true") - { - parser.add_argument("-o").required(true); +TEST_CASE("Help message contains for optional argument no brackets for argument with required true") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").required(true); - CHECK(parser.format_help() == "usage: prog -o O\n\noptional arguments:\n -o O"s); - } + CHECK(parser.format_help() == "usage: prog -o O\n\noptional arguments:\n -o O"s); +} - SUBCASE("...brackets for argument with required false") - { - parser.add_argument("-o").required(false); +TEST_CASE("Help message contains for optional argument brackets for argument with required false") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").required(false); - CHECK(parser.format_help() == "usage: prog [-o O]\n\noptional arguments:\n -o O"s); - } + CHECK(parser.format_help() == "usage: prog [-o O]\n\noptional arguments:\n -o O"s); +} - SUBCASE("...name and choices for argument with choices set") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}); +TEST_CASE("Help message contains for optional argument name and choices for argument with choices set") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}); - CHECK(parser.format_help() == "usage: prog [-o {\"foo\",\"bar\"}]\n\noptional arguments:\n -o {\"foo\",\"bar\"}"s); - } + CHECK(parser.format_help() == "usage: prog [-o {\"foo\",\"bar\"}]\n\noptional arguments:\n -o {\"foo\",\"bar\"}"s); +} - SUBCASE("...name and automatic metavar repeated N times for argument with nargs set as number...") - { - SUBCASE("...1") - { - parser.add_argument("-o").nargs(1); +TEST_CASE("Help message contains for optional argument name and automatic metavar repeated N times for argument with nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(1); - CHECK(parser.format_help() == "usage: prog [-o O]\n\noptional arguments:\n -o O"s); - } + CHECK(parser.format_help() == "usage: prog [-o O]\n\noptional arguments:\n -o O"s); +} - SUBCASE("...2") - { - parser.add_argument("-o").nargs(2); +TEST_CASE("Help message contains for optional argument name and automatic metavar repeated N times for argument with nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(2); - CHECK(parser.format_help() == "usage: prog [-o O O]\n\noptional arguments:\n -o O O"s); - } + CHECK(parser.format_help() == "usage: prog [-o O O]\n\noptional arguments:\n -o O O"s); +} - SUBCASE("...3") - { - parser.add_argument("-o").nargs(3); +TEST_CASE("Help message contains for optional argument name and automatic metavar repeated N times for argument with nargs set as number 3") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(3); - CHECK(parser.format_help() == "usage: prog [-o O O O]\n\noptional arguments:\n -o O O O"s); - } - } + CHECK(parser.format_help() == "usage: prog [-o O O O]\n\noptional arguments:\n -o O O O"s); +} - SUBCASE("...name and metavar repeated N times for argument with metavar and nargs set as number...") - { - SUBCASE("...1") - { - parser.add_argument("-o").metavar("METAVARO").nargs(1); +TEST_CASE("Help message contains for optional argument name and metavar repeated N times for argument with metavar and nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").nargs(1); - CHECK(parser.format_help() == "usage: prog [-o METAVARO]\n\noptional arguments:\n -o METAVARO"s); - } + CHECK(parser.format_help() == "usage: prog [-o METAVARO]\n\noptional arguments:\n -o METAVARO"s); +} - SUBCASE("...2") - { - parser.add_argument("-o").metavar("METAVARO").nargs(2); +TEST_CASE("Help message contains for optional argument name and metavar repeated N times for argument with metavar and nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").nargs(2); - CHECK(parser.format_help() == "usage: prog [-o METAVARO METAVARO]\n\noptional arguments:\n -o METAVARO METAVARO"s); - } + CHECK(parser.format_help() == "usage: prog [-o METAVARO METAVARO]\n\noptional arguments:\n -o METAVARO METAVARO"s); +} - SUBCASE("...3") - { - parser.add_argument("-o").metavar("METAVARO").nargs(3); +TEST_CASE("Help message contains for optional argument name and metavar repeated N times for argument with metavar and nargs set as number 3") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").nargs(3); - CHECK(parser.format_help() == "usage: prog [-o METAVARO METAVARO METAVARO]\n\noptional arguments:\n -o METAVARO METAVARO METAVARO"s); - } - } + CHECK(parser.format_help() == "usage: prog [-o METAVARO METAVARO METAVARO]\n\noptional arguments:\n -o METAVARO METAVARO METAVARO"s); +} - SUBCASE("...name and choices repeated N times for argument with choices set and nargs set as number...") - { - SUBCASE("...1") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(1); +TEST_CASE("Help message contains for optional argument name and choices repeated N times for argument with choices set and nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(1); - CHECK(parser.format_help() == "usage: prog [-o {\"foo\",\"bar\"}]\n\noptional arguments:\n -o {\"foo\",\"bar\"}"s); - } + CHECK(parser.format_help() == "usage: prog [-o {\"foo\",\"bar\"}]\n\noptional arguments:\n -o {\"foo\",\"bar\"}"s); +} - SUBCASE("...2") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(2); +TEST_CASE("Help message contains for optional argument name and choices repeated N times for argument with choices set and nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(2); - CHECK(parser.format_help() == "usage: prog [-o {\"foo\",\"bar\"} {\"foo\",\"bar\"}]\n\noptional arguments:\n -o {\"foo\",\"bar\"} {\"foo\",\"bar\"}"s); - } + CHECK(parser.format_help() == "usage: prog [-o {\"foo\",\"bar\"} {\"foo\",\"bar\"}]\n\noptional arguments:\n -o {\"foo\",\"bar\"} {\"foo\",\"bar\"}"s); +} - SUBCASE("...3") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(3); +TEST_CASE("Help message contains for optional argument name and choices repeated N times for argument with choices set and nargs set as number 3") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(3); - CHECK(parser.format_help() == "usage: prog [-o {\"foo\",\"bar\"} {\"foo\",\"bar\"} {\"foo\",\"bar\"}]\n\noptional arguments:\n -o {\"foo\",\"bar\"} {\"foo\",\"bar\"} {\"foo\",\"bar\"}"s); - } - } + CHECK(parser.format_help() == "usage: prog [-o {\"foo\",\"bar\"} {\"foo\",\"bar\"} {\"foo\",\"bar\"}]\n\noptional arguments:\n -o {\"foo\",\"bar\"} {\"foo\",\"bar\"} {\"foo\",\"bar\"}"s); +} - SUBCASE("...name followed by automatic metavar in brackets for argument with nargs set as zero_or_one") - { - parser.add_argument("-o").nargs(argparse::zero_or_one); +TEST_CASE("Help message contains for optional argument name followed by automatic metavar in brackets for argument with nargs set as zero_or_one") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(argparse::zero_or_one); - CHECK(parser.format_help() == "usage: prog [-o [O]]\n\noptional arguments:\n -o [O]"s); - } + CHECK(parser.format_help() == "usage: prog [-o [O]]\n\noptional arguments:\n -o [O]"s); +} - SUBCASE("...name followed by metavar in brackets for argument with metavar set and nargs set as zero_or_one") - { - parser.add_argument("-o").metavar("METAVARO").nargs(argparse::zero_or_one); +TEST_CASE("Help message contains for optional argument name followed by metavar in brackets for argument with metavar set and nargs set as zero_or_one") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").nargs(argparse::zero_or_one); - CHECK(parser.format_help() == "usage: prog [-o [METAVARO]]\n\noptional arguments:\n -o [METAVARO]"s); - } + CHECK(parser.format_help() == "usage: prog [-o [METAVARO]]\n\noptional arguments:\n -o [METAVARO]"s); +} - SUBCASE("...name followed by choices in brackets for argument with choices set and nargs set as zero_or_one") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one); +TEST_CASE("Help message contains for optional argument name followed by choices in brackets for argument with choices set and nargs set as zero_or_one") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one); - CHECK(parser.format_help() == "usage: prog [-o [{\"foo\",\"bar\"}]]\n\noptional arguments:\n -o [{\"foo\",\"bar\"}]"s); - } + CHECK(parser.format_help() == "usage: prog [-o [{\"foo\",\"bar\"}]]\n\noptional arguments:\n -o [{\"foo\",\"bar\"}]"s); +} - SUBCASE("...name followed by automatic metavar in brackets followed by automatic metavar and ellipsis in nested brackets for argument with nargs set as zero_or_more") - { - parser.add_argument("-o").nargs(argparse::zero_or_more); +TEST_CASE("Help message contains for optional argument name followed by automatic metavar in brackets followed by automatic metavar and ellipsis in nested brackets for argument with nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(argparse::zero_or_more); - CHECK(parser.format_help() == "usage: prog [-o [O [O ...]]]\n\noptional arguments:\n -o [O [O ...]]"s); - } + CHECK(parser.format_help() == "usage: prog [-o [O [O ...]]]\n\noptional arguments:\n -o [O [O ...]]"s); +} - SUBCASE("...name followed by metavar in brackets followed by metavar and ellipsis in nested brackets for argument with metavar set and nargs set as zero_or_more") - { - parser.add_argument("-o").metavar("METAVARO").nargs(argparse::zero_or_more); +TEST_CASE("Help message contains for optional argument name followed by metavar in brackets followed by metavar and ellipsis in nested brackets for argument with metavar set and nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").nargs(argparse::zero_or_more); - CHECK(parser.format_help() == "usage: prog [-o [METAVARO [METAVARO ...]]]\n\noptional arguments:\n -o [METAVARO [METAVARO ...]]"s); - } + CHECK(parser.format_help() == "usage: prog [-o [METAVARO [METAVARO ...]]]\n\noptional arguments:\n -o [METAVARO [METAVARO ...]]"s); +} - SUBCASE("...name followed by choices in brackets followed by choices and ellipsis in nested brackets for argument with choices set and nargs set as zero_or_more") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more); +TEST_CASE("Help message contains for optional argument name followed by choices in brackets followed by choices and ellipsis in nested brackets for argument with choices set and nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more); - CHECK(parser.format_help() == "usage: prog [-o [{\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]]\n\noptional arguments:\n -o [{\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]"s); - } + CHECK(parser.format_help() == "usage: prog [-o [{\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]]\n\noptional arguments:\n -o [{\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]"s); +} - SUBCASE("...name followed by automatic metavar followed by automatic metavar and ellipsis in brackets for argument with nargs set as one_or_more") - { - parser.add_argument("-o").nargs(argparse::one_or_more); +TEST_CASE("Help message contains for optional argument name followed by automatic metavar followed by automatic metavar and ellipsis in brackets for argument with nargs set as one_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(argparse::one_or_more); - CHECK(parser.format_help() == "usage: prog [-o O [O ...]]\n\noptional arguments:\n -o O [O ...]"s); - } + CHECK(parser.format_help() == "usage: prog [-o O [O ...]]\n\noptional arguments:\n -o O [O ...]"s); +} - SUBCASE("...name followed by metavar followed by metavar and ellipsis in brackets for argument with metavar set and nargs set as one_or_more") - { - parser.add_argument("-o").metavar("METAVARO").nargs(argparse::one_or_more); +TEST_CASE("Help message contains for optional argument name followed by metavar followed by metavar and ellipsis in brackets for argument with metavar set and nargs set as one_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").nargs(argparse::one_or_more); - CHECK(parser.format_help() == "usage: prog [-o METAVARO [METAVARO ...]]\n\noptional arguments:\n -o METAVARO [METAVARO ...]"s); - } + CHECK(parser.format_help() == "usage: prog [-o METAVARO [METAVARO ...]]\n\noptional arguments:\n -o METAVARO [METAVARO ...]"s); +} - SUBCASE("...name followed by choices followed by choices and ellipsis in brackets for argument with choices set and nargs set as one_or_more") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more); +TEST_CASE("Help message contains for optional argument name followed by choices followed by choices and ellipsis in brackets for argument with choices set and nargs set as one_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more); - CHECK(parser.format_help() == "usage: prog [-o {\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]\n\noptional arguments:\n -o {\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]"s); - } - } + CHECK(parser.format_help() == "usage: prog [-o {\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]\n\noptional arguments:\n -o {\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]"s); } -TEST_CASE("Help string starts on 25th column...") +TEST_CASE("Help string starts on 25th column of the same line for positional arguments with length less than 21 characters") { auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("pos").help("help"); - SUBCASE("...of the same line for...") - { - SUBCASE("...positional arguments with length less than 21 characters") - { - parser.add_argument("pos").help("help"); - - CHECK(parser.format_help() == "usage: prog pos\n\npositional arguments:\n pos help"); - } + CHECK(parser.format_help() == "usage: prog pos\n\npositional arguments:\n pos help"); +} - SUBCASE("...optional arguments with length less than 21 characters") - { - parser.add_argument("-o").help("help"); +TEST_CASE("Help string starts on 25th column of the same line for optional arguments with length less than 21 characters") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").help("help"); - CHECK(parser.format_help() == "usage: prog [-o O]\n\noptional arguments:\n -o O help"); - } - } + CHECK(parser.format_help() == "usage: prog [-o O]\n\noptional arguments:\n -o O help"); +} - SUBCASE("...of the next line for...") - { - SUBCASE("...positional arguments with length of 21 characters or more") - { - parser.add_argument("abcdefghijklmnopqrstu").help("help"); +TEST_CASE("Help string starts on 25th column of the next line for positional arguments with length of 21 characters or more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("abcdefghijklmnopqrstu").help("help"); - CHECK(parser.format_help() == "usage: prog abcdefghijklmnopqrstu\n\npositional arguments:\n abcdefghijklmnopqrstu\n help"); - } + CHECK(parser.format_help() == "usage: prog abcdefghijklmnopqrstu\n\npositional arguments:\n abcdefghijklmnopqrstu\n help"); +} - SUBCASE("...optional arguments with length of 21 characters or more") - { - parser.add_argument("--abcdefghijklmnopq").metavar("A").help("help"); +TEST_CASE("Help string starts on 25th column of the next line for optional arguments with length of 21 characters or more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("--abcdefghijklmnopq").metavar("A").help("help"); - CHECK(parser.format_help() == "usage: prog [--abcdefghijklmnopq A]\n\noptional arguments:\n --abcdefghijklmnopq A\n help"); - } - } + CHECK(parser.format_help() == "usage: prog [--abcdefghijklmnopq A]\n\noptional arguments:\n --abcdefghijklmnopq A\n help"); } diff --git a/test/unittest/test_parsing.cpp b/test/unittest/test_parsing.cpp index 6004d5e1..a6a25883 100644 --- a/test/unittest/test_parsing.cpp +++ b/test/unittest/test_parsing.cpp @@ -30,72 +30,75 @@ TEST_CASE("Parsing a positional argument yields its value") CHECK(parsed.get_value("p1") == "v1"); } -TEST_CASE("Parsing an optional argument...") +TEST_CASE("Parsing an optional argument yields false when it's missing") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); parser.add_argument("-o"); - SUBCASE("...yields false when it's missing") - { - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - CHECK(!parsed.get("o")); - } + CHECK(!parsed.get("o")); +} - SUBCASE("...throws an exception when it's missing argument") - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o: expected one argument", argparse::parsing_error); - } +TEST_CASE("Parsing an optional argument throws an exception when it's missing argument") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o"); - SUBCASE("...yields its value") - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "v1"}); + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o: expected one argument", argparse::parsing_error); +} - CHECK(parsed.get_value("o") == "v1"); - } +TEST_CASE("Parsing an optional argument yields its value") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o"); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "v1"}); + + CHECK(parsed.get_value("o") == "v1"); } -TEST_CASE("Parsing an optional argument with store true action...") +TEST_CASE("Parsing an optional argument with store true action yields false when it's missing") { auto parser = argparse::ArgumentParser(); parser.add_argument("-o").action(argparse::store_true); - SUBCASE("...yields false when it's missing") - { - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - CHECK(parsed.get_value("o") == false); - } + CHECK(parsed.get_value("o") == false); +} - SUBCASE("...yields true when it's present") - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); +TEST_CASE("Parsing an optional argument with store true action yields true when it's present") +{ + auto parser = argparse::ArgumentParser(); + parser.add_argument("-o").action(argparse::store_true); - CHECK(parsed.get_value("o") == true); - } + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); + + CHECK(parsed.get_value("o") == true); } -TEST_CASE("Parsing an optional argument with store false action...") +TEST_CASE("Parsing an optional argument with store false action yields true when it's missing") { auto parser = argparse::ArgumentParser(); parser.add_argument("-o").action(argparse::store_false); - SUBCASE("...yields true when it's missing") - { - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - CHECK(parsed.get_value("o") == true); - } + CHECK(parsed.get_value("o") == true); +} - SUBCASE("...yields false when it's present") - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); +TEST_CASE("Parsing an optional argument with store false action yields false when it's present") +{ + auto parser = argparse::ArgumentParser(); + parser.add_argument("-o").action(argparse::store_false); - CHECK(parsed.get_value("o") == false); - } + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); + + CHECK(parsed.get_value("o") == false); } -TEST_CASE_TEMPLATE("Parsing an optional argument with store const action...", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string, foo::Custom, bar::Custom) +TEST_CASE_TEMPLATE("Parsing an optional argument with store const action yields false when it's missing", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string, foo::Custom, bar::Custom) { auto parser = argparse::ArgumentParser(); @@ -112,50 +115,62 @@ TEST_CASE_TEMPLATE("Parsing an optional argument with store const action...", T, parser.add_argument("-o").action(argparse::store_const).const_(T("bar")); } - SUBCASE("...yields false when it's missing") - { - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - CHECK(!parsed.get("o")); - } + CHECK(!parsed.get("o")); +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with store const action yields const value", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string, foo::Custom, bar::Custom) +{ + auto parser = argparse::ArgumentParser(); - SUBCASE("...yields const value") + if constexpr (std::is_integral_v) { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); + parser.add_argument("-o").action(argparse::store_const).const_(T(65)); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").action(argparse::store_const).const_(T(1.125)); + } + else + { + parser.add_argument("-o").action(argparse::store_const).const_(T("bar")); + } - if constexpr (std::is_integral_v) - { - CHECK(parsed.get_value("o") == T(65)); - } - else if constexpr (std::is_floating_point_v) - { - CHECK(parsed.get_value("o") == T(1.125)); - } - else - { - CHECK(parsed.get_value("o") == T("bar")); - } + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); + + if constexpr (std::is_integral_v) + { + CHECK(parsed.get_value("o") == T(65)); + } + else if constexpr (std::is_floating_point_v) + { + CHECK(parsed.get_value("o") == T(1.125)); + } + else + { + CHECK(parsed.get_value("o") == T("bar")); } } -TEST_CASE("Parsing an optional argument with help action...") +TEST_CASE("Parsing an optional argument with help action yields false when it's missing") { auto parser = argparse::ArgumentParser().add_help(false).handle(argparse::Handle::none); parser.add_argument("-h").action(argparse::help); - SUBCASE("...yields false when it's missing") - { - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - CHECK(parsed.get_value("h") == false); - } + CHECK(parsed.get_value("h") == false); +} - SUBCASE("...yields true when it's present") - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-h"}); +TEST_CASE("Parsing an optional argument with help action yields true when it's present") +{ + auto parser = argparse::ArgumentParser().add_help(false).handle(argparse::Handle::none); + parser.add_argument("-h").action(argparse::help); - CHECK(parsed.get_value("h") == true); - } + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-h"}); + + CHECK(parsed.get_value("h") == true); } TEST_CASE("Parsing an optional argument with version action yields false when it's missing") @@ -178,24 +193,24 @@ TEST_CASE("Parsing an optional argument with version action yields true when it' CHECK(parsed.get_value("v") == true); } -TEST_CASE("Optional argument can be used with either...") +TEST_CASE("Optional argument can be used with either short name") { auto parser = argparse::ArgumentParser(); parser.add_argument("-o", "--option"); - SUBCASE("...short name") - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "val"}); + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "val"}); - CHECK(parsed.get_value("option") == "val"); - } + CHECK(parsed.get_value("option") == "val"); +} - SUBCASE("...long name") - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "--option", "val"}); +TEST_CASE("Optional argument can be used with either long name") +{ + auto parser = argparse::ArgumentParser(); + parser.add_argument("-o", "--option"); - CHECK(parsed.get_value("option") == "val"); - } + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "--option", "val"}); + + CHECK(parsed.get_value("option") == "val"); } TEST_CASE_TEMPLATE("Parsing a positional argument yields its requested type", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, foo::Custom, bar::Custom) @@ -278,7 +293,7 @@ TEST_CASE("Parsing an optional argument with invalid value throws an exception") CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "10gibberish"}), "argument -o: invalid value: '10gibberish'", argparse::parsing_error); } -TEST_CASE_TEMPLATE("Parsing an optional argument with default value...", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string, foo::Custom, bar::Custom) +TEST_CASE_TEMPLATE("Parsing an optional argument with default value yields the default value when it's missing", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string, foo::Custom, bar::Custom) { auto parser = argparse::ArgumentParser(); @@ -295,148 +310,165 @@ TEST_CASE_TEMPLATE("Parsing an optional argument with default value...", T, char parser.add_argument("-o").default_(T("foo")).template type(); } - SUBCASE("...yields the default value when it's missing") + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + + if constexpr (std::is_integral_v) { - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + CHECK(parsed.get_value("o") == T(54)); + } + else if constexpr (std::is_floating_point_v) + { + CHECK(parsed.get_value("o") == T(0.125)); + } + else + { + CHECK(parsed.get_value("o") == T("foo")); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with default value yields value of the argument's type", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string, foo::Custom, bar::Custom) +{ + auto parser = argparse::ArgumentParser(); - if constexpr (std::is_integral_v) - { - CHECK(parsed.get_value("o") == T(54)); - } - else if constexpr (std::is_floating_point_v) - { - CHECK(parsed.get_value("o") == T(0.125)); - } - else - { - CHECK(parsed.get_value("o") == T("foo")); - } + if constexpr (std::is_integral_v) + { + parser.add_argument("-o").default_(T(54)).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").default_(T(0.125)).template type(); + } + else + { + parser.add_argument("-o").default_(T("foo")).template type(); } - SUBCASE("...yields value of the argument's type") + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); - CHECK(parsed.get_value("o") == T(65)); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "65"}); + CHECK(parsed.get_value("o") == T(65)); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "65"}); - CHECK(parsed.get_value("o") == T(65)); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "1.125"}); + CHECK(parsed.get_value("o") == T(65)); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "1.125"}); - CHECK(parsed.get_value("o") == T(1.125)); - } - else - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "bar"}); + CHECK(parsed.get_value("o") == T(1.125)); + } + else + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "bar"}); - CHECK(parsed.get_value("o") == T("bar")); - } + CHECK(parsed.get_value("o") == T("bar")); } } -TEST_CASE("Parsing missing positional argument throws an exception...") +TEST_CASE("Parsing missing positional argument throws an exception for one missing argument") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("p1"); - SUBCASE("...for one missing argument") - { - parser.add_argument("p1"); + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: p1", argparse::parsing_error); +} - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: p1", argparse::parsing_error); - } +TEST_CASE("Parsing missing positional argument throws an exception for two missing arguments") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("p1"); + parser.add_argument("p2"); - SUBCASE("...for two missing arguments") - { - parser.add_argument("p1"); - parser.add_argument("p2"); + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: p1 p2", argparse::parsing_error); +} - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: p1 p2", argparse::parsing_error); - } +TEST_CASE("Parsing missing positional argument throws an exception for three missing arguments") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("p1"); + parser.add_argument("p2"); + parser.add_argument("p3"); - SUBCASE("...for three missing arguments") - { - parser.add_argument("p1"); - parser.add_argument("p2"); - parser.add_argument("p3"); + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: p1 p2 p3", argparse::parsing_error); +} - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: p1 p2 p3", argparse::parsing_error); - } +TEST_CASE("Parsing arguments with help requested disregards parsing errors for missing positional argument") +{ + auto parser = argparse::ArgumentParser().add_help(false).handle(argparse::Handle::none); + parser.add_argument("-h").action(argparse::help); + parser.add_argument("p1"); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-h"})); } -TEST_CASE("Parsing arguments with help requested disregards parsing errors...") +TEST_CASE("Parsing arguments with help requested disregards parsing errors for unrecognised positional argument") { auto parser = argparse::ArgumentParser().add_help(false).handle(argparse::Handle::none); parser.add_argument("-h").action(argparse::help); - SUBCASE("...for missing positional argument") - { - parser.add_argument("p1"); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "p1", "-h"})); +} - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-h"})); - } +TEST_CASE("Parsing arguments with help requested disregards parsing errors for unrecognised optional argument") +{ + auto parser = argparse::ArgumentParser().add_help(false).handle(argparse::Handle::none); + parser.add_argument("-h").action(argparse::help); - SUBCASE("...for unrecognised positional argument") - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "p1", "-h"})); - } + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-a", "-h"})); +} - SUBCASE("...for unrecognised optional argument") - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-a", "-h"})); - } +TEST_CASE("Parsing unrecognised positional argument throws an exception for one unrecognised argument") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("p1"); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "v1", "v2"}), "unrecognised arguments: v2", argparse::parsing_error); } -TEST_CASE("Parsing unrecognised positional argument throws an exception...") +TEST_CASE("Parsing unrecognised positional argument throws an exception for two unrecognised arguments") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); parser.add_argument("p1"); - SUBCASE("...for one unrecognised argument") - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "v1", "v2"}), "unrecognised arguments: v2", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "v1", "v2", "v3"}), "unrecognised arguments: v2 v3", argparse::parsing_error); +} - SUBCASE("...for two unrecognised arguments") - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "v1", "v2", "v3"}), "unrecognised arguments: v2 v3", argparse::parsing_error); - } +TEST_CASE("Parsing unrecognised positional argument throws an exception for three unrecognised arguments") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("p1"); + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "v1", "v2", "v3", "v4"}), "unrecognised arguments: v2 v3 v4", argparse::parsing_error); +} - SUBCASE("...for three unrecognised arguments") - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "v1", "v2", "v3", "v4"}), "unrecognised arguments: v2 v3 v4", argparse::parsing_error); - } +TEST_CASE("Parsing unrecognised optional argument throws an exception for one unrecognised argument") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-a"); + + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-a", "v1", "-b"}), "unrecognised arguments: -b", argparse::parsing_error); } -TEST_CASE("Parsing unrecognised optional argument throws an exception...") +TEST_CASE("Parsing unrecognised optional argument throws an exception for two unrecognised arguments") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); parser.add_argument("-a"); - SUBCASE("...for one unrecognised argument") - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-a", "v1", "-b"}), "unrecognised arguments: -b", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-a", "v1", "-b", "-c"}), "unrecognised arguments: -b -c", argparse::parsing_error); +} - SUBCASE("...for two unrecognised arguments") - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-a", "v1", "-b", "-c"}), "unrecognised arguments: -b -c", argparse::parsing_error); - } +TEST_CASE("Parsing unrecognised optional argument throws an exception for three unrecognised arguments") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-a"); - SUBCASE("...for three unrecognised arguments") - { - CHECK_THROWS_WITH_AS(parser.parse_args(6, cstr_arr{"prog", "-a", "v1", "-b", "-c", "-d"}), "unrecognised arguments: -b -c -d", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(6, cstr_arr{"prog", "-a", "v1", "-b", "-c", "-d"}), "unrecognised arguments: -b -c -d", argparse::parsing_error); } -TEST_CASE("Parsing mixed positional and optional arguments give same result no matter the order...") +TEST_CASE("Parsing mixed positional and optional arguments give same result no matter the order for positional and optional") { auto parser1 = argparse::ArgumentParser(); parser1.add_argument("pos1"); @@ -445,3439 +477,3843 @@ TEST_CASE("Parsing mixed positional and optional arguments give same result no m auto parser2 = argparse::ArgumentParser(); parser2.add_argument("-f"); parser2.add_argument("pos1"); + auto const argv = cstr_arr{"prog", "val1", "-f", "a"}; + auto const parsed1 = parser1.parse_args(4, argv); + auto const parsed2 = parser2.parse_args(4, argv); - SUBCASE("...for positional and optional") - { - auto const argv = cstr_arr{"prog", "val1", "-f", "a"}; - auto const parsed1 = parser1.parse_args(4, argv); - auto const parsed2 = parser2.parse_args(4, argv); + CHECK(parsed1.get_value("pos1") == parsed2.get_value("pos1")); + CHECK(parsed1.get_value("f") == parsed2.get_value("f")); +} - CHECK(parsed1.get_value("pos1") == parsed2.get_value("pos1")); - CHECK(parsed1.get_value("f") == parsed2.get_value("f")); - } +TEST_CASE("Parsing mixed positional and optional arguments give same result no matter the order for optional and positional") +{ + auto parser1 = argparse::ArgumentParser(); + parser1.add_argument("pos1"); + parser1.add_argument("-f"); - SUBCASE("...for optional and positional") - { - auto const argv = cstr_arr{"prog", "-f", "a", "val1"}; - auto const parsed1 = parser1.parse_args(4, argv); - auto const parsed2 = parser2.parse_args(4, argv); + auto parser2 = argparse::ArgumentParser(); + parser2.add_argument("-f"); + parser2.add_argument("pos1"); + auto const argv = cstr_arr{"prog", "-f", "a", "val1"}; + auto const parsed1 = parser1.parse_args(4, argv); + auto const parsed2 = parser2.parse_args(4, argv); - CHECK(parsed1.get_value("pos1") == parsed2.get_value("pos1")); - CHECK(parsed1.get_value("f") == parsed2.get_value("f")); - } + CHECK(parsed1.get_value("pos1") == parsed2.get_value("pos1")); + CHECK(parsed1.get_value("f") == parsed2.get_value("f")); } -TEST_CASE("The resulting attribute name is based on...") +TEST_CASE("The resulting attribute name is based on for positional argument on its name") { auto parser = argparse::ArgumentParser(); + parser.add_argument("foo"); - SUBCASE("...for positional argument...") - { - SUBCASE("...on its name") - { - parser.add_argument("foo"); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "val"}); + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "val"}); - CHECK(parsed.get("foo")); - } + CHECK(parsed.get("foo")); +} - SUBCASE("...on dest parameter") - { - parser.add_argument("foo").dest("bar"); +TEST_CASE("The resulting attribute name is based on for positional argument on dest parameter") +{ + auto parser = argparse::ArgumentParser(); + parser.add_argument("foo").dest("bar"); - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "val"}); + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "val"}); - CHECK(parsed.get("bar")); - } - } + CHECK(parsed.get("bar")); +} - SUBCASE("...for optional argument...") - { - SUBCASE("...on its long name") - { - parser.add_argument("-f", "--foo"); +TEST_CASE("The resulting attribute name is based on for optional argument on its long name") +{ + auto parser = argparse::ArgumentParser(); + parser.add_argument("-f", "--foo"); - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-f", "val"}); + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-f", "val"}); - CHECK(parsed.get("foo")); - } + CHECK(parsed.get("foo")); +} - SUBCASE("...on its short name") - { - parser.add_argument("-f"); +TEST_CASE("The resulting attribute name is based on for optional argument on its short name") +{ + auto parser = argparse::ArgumentParser(); + parser.add_argument("-f"); - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-f", "val"}); + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-f", "val"}); - CHECK(parsed.get("f")); - } + CHECK(parsed.get("f")); +} - SUBCASE("...on dest parameter") - { - parser.add_argument("-f", "--foo").dest("bar"); +TEST_CASE("The resulting attribute name is based on for optional argument on dest parameter") +{ + auto parser = argparse::ArgumentParser(); + parser.add_argument("-f", "--foo").dest("bar"); - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-f", "val"}); + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-f", "val"}); - CHECK(parsed.get("bar")); - } - } + CHECK(parsed.get("bar")); } -TEST_CASE("Parsing a missing optional argument with required...") +TEST_CASE("Parsing a missing optional argument with required true throws an exception") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").required(true); - SUBCASE("...true throws an exception") - { - parser.add_argument("-o").required(true); - - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o", argparse::parsing_error); - } + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: -o", argparse::parsing_error); +} - SUBCASE("...false does not throw") - { - parser.add_argument("-o").required(false); +TEST_CASE("Parsing a missing optional argument with required false does not throw") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").required(false); - CHECK_NOTHROW(parser.parse_args(1, cstr_arr{"prog"})); - } + CHECK_NOTHROW(parser.parse_args(1, cstr_arr{"prog"})); } -TEST_CASE_TEMPLATE("Parsing a positional argument with choices set...", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string, foo::Custom, bar::Custom) +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set accepts one of the values", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string, foo::Custom, bar::Custom) { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - SUBCASE("...accepts one of the values...") + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).template type(); - - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "A"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "C"})); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(23), T(34)}).template type(); - - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "23"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "34"})); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(1.5)}).template type(); - - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.125"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "1.5"})); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).template type(); + parser.add_argument("pos").choices({T('A'), T('C')}).template type(); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "foo"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "bar"})); - } + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "A"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "C"})); } - - SUBCASE("...throws an exception on incorrect value...") + else if constexpr (std::is_integral_v) { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(23), T(34)}).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "3"}), "argument pos: invalid choice: 3 (choose from 23, 34)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(1.5)}).template type(); + parser.add_argument("pos").choices({T(23), T(34)}).template type(); - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 1.5)", argparse::parsing_error); - } - else if constexpr (std::is_same_v) - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).template type(); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "23"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "34"})); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(1.5)}).template type(); - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).template type(); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.125"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "1.5"})); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).template type(); - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "baz"}), "argument pos: invalid choice: (choose from , )", argparse::parsing_error); - } + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "foo"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "bar"})); } } -TEST_CASE_TEMPLATE("Parsing an optional argument with choices set...", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string, foo::Custom, bar::Custom) +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set throws an exception on incorrect value", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string, foo::Custom, bar::Custom) { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - SUBCASE("...accepts one of the values...") + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "A"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "C"})); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(23), T(34)}).template type(); + parser.add_argument("pos").choices({T('A'), T('C')}).template type(); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "23"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "34"})); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(1.5)}).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "1.5"})); - } - else - { - parser.add_argument("-o").choices({T("foo"), T("bar")}).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "bar"})); - } - } - - SUBCASE("...throws an exception on incorrect value...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(23), T(34)}).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "3"}), "argument -o: invalid choice: 3 (choose from 23, 34)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(1.5)}).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 1.5)", argparse::parsing_error); - } - else if constexpr (std::is_same_v) - { - parser.add_argument("-o").choices({T("foo"), T("bar")}).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - else - { - parser.add_argument("-o").choices({T("foo"), T("bar")}).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "baz"}), "argument -o: invalid choice: (choose from , )", argparse::parsing_error); - } - } -} - -TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set...", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) -{ - auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - - SUBCASE("...as a number...") - { - SUBCASE("...consumes the number of arguments...") - { - SUBCASE("...for one argument") - { - parser.add_argument("pos").nargs(1).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "A"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "42"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.5"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "foo"})); - } - } - - SUBCASE("...for two arguments") - { - parser.add_argument("pos").nargs(2).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "A", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "42", "54"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.5", "1.125"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "foo", "bar"})); - } - } - - SUBCASE("...for three arguments") - { - parser.add_argument("pos").nargs(3).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "A", "C", "E"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "42", "54", "65"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.5", "1.125", "2.375"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"})); - } - } - } - - SUBCASE("...yields a list of arguments...") - { - SUBCASE("...for one argument") - { - parser.add_argument("pos").nargs(1).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "B"}); - - CHECK(parsed.get_value>("pos") == std::vector{'B'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "42"}); - - CHECK(parsed.get_value>("pos") == std::vector{42}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.5"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.5}); - } - else - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo"}); - } - } - - SUBCASE("...for two arguments") - { - parser.add_argument("pos").nargs(2).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "B", "D"}); - - CHECK(parsed.get_value>("pos") == std::vector{'B', 'D'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "42", "54"}); - - CHECK(parsed.get_value>("pos") == std::vector{42, 54}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "0.5", "1.125"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.5, 1.125}); - } - else - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "foo", "bar"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo", "bar"}); - } - } - - SUBCASE("...for three arguments") - { - parser.add_argument("pos").nargs(3).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "B", "D", "F"}); - - CHECK(parsed.get_value>("pos") == std::vector{'B', 'D', 'F'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "42", "54", "65"}); - - CHECK(parsed.get_value>("pos") == std::vector{42, 54, 65}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "0.5", "1.125", "2.375"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.5, 1.125, 2.375}); - } - else - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo", "bar", "baz"}); - } - } - } - - SUBCASE("...throws an exception for incorrect arguments number...") - { - SUBCASE("...for one argument and no provided") - { - parser.add_argument("pos").nargs(1).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: pos", argparse::parsing_error); - } - - SUBCASE("...for two arguments and one provided") - { - parser.add_argument("pos").nargs(2).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "A"}), "the following arguments are required: pos", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "42"}), "the following arguments are required: pos", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "0.5"}), "the following arguments are required: pos", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "foo"}), "the following arguments are required: pos", argparse::parsing_error); - } - } - - SUBCASE("...for three arguments and two provided") - { - parser.add_argument("pos").nargs(3).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "A", "B"}), "the following arguments are required: pos", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "42", "54"}), "the following arguments are required: pos", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "0.5", "1.125"}), "the following arguments are required: pos", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "foo", "bar"}), "the following arguments are required: pos", argparse::parsing_error); - } - } - - SUBCASE("...for one argument and two provided") - { - parser.add_argument("pos").nargs(1).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "A", "B"}), "unrecognised arguments: B", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "42", "54"}), "unrecognised arguments: 54", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "0.5", "1.125"}), "unrecognised arguments: 1.125", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "foo", "bar"}), "unrecognised arguments: bar", argparse::parsing_error); - } - } - - SUBCASE("...for one arguments and three provided") - { - parser.add_argument("pos").nargs(1).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "A", "B", "C"}), "unrecognised arguments: B C", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "42", "54", "65"}), "unrecognised arguments: 54 65", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "0.5", "1.125", "2.375"}), "unrecognised arguments: 1.125 2.375", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}), "unrecognised arguments: bar baz", argparse::parsing_error); - } - } - - SUBCASE("...for two arguments and three provided") - { - parser.add_argument("pos").nargs(2).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "A", "B", "C"}), "unrecognised arguments: C", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "42", "54", "65"}), "unrecognised arguments: 65", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "0.5", "1.125", "2.375"}), "unrecognised arguments: 2.375", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}), "unrecognised arguments: baz", argparse::parsing_error); - } - } - } - } - - SUBCASE("...as zero_or_one...") - { - SUBCASE("...consumes single argument and yields it as a single item") - { - parser.add_argument("pos").nargs(argparse::zero_or_one).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); - - CHECK(parsed.get_value("pos") == T('A')); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "42"}); - - CHECK(parsed.get_value("pos") == T(42)); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.5"}); - - CHECK(parsed.get_value("pos") == T(0.5)); - } - else - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); - - CHECK(parsed.get_value("pos") == T("foo")); - } - } - - SUBCASE("...yields default value if no argument is provided") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").nargs(argparse::zero_or_one).default_(T('A')); - - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - - CHECK(parsed.get_value("pos") == T('A')); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").nargs(argparse::zero_or_one).default_(T(10)); - - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - - CHECK(parsed.get_value("pos") == T(10)); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").nargs(argparse::zero_or_one).default_(T(0.0625)); - - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - - CHECK(parsed.get_value("pos") == T(0.0625)); - } - else - { - parser.add_argument("pos").nargs(argparse::zero_or_one).default_("foo"s); - - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - - CHECK(parsed.get_value("pos") == T("foo")); - } - } - } - - SUBCASE("...as zero_or_more...") - { - SUBCASE("...yields an empty list if no arguments provided") - { - parser.add_argument("pos").nargs(argparse::zero_or_more).template type(); - - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - - CHECK(parsed.get_value>("pos") == std::vector()); - } - - SUBCASE("...consumes single argument and yields it as a list") - { - parser.add_argument("pos").nargs(argparse::zero_or_more).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); - - CHECK(parsed.get_value>("pos") == std::vector{'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "42"}); - - CHECK(parsed.get_value>("pos") == std::vector{42}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.5"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.5}); - } - else - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo"}); - } - } - - SUBCASE("...consumes all available arguments and yields them as a list") - { - parser.add_argument("pos").nargs(argparse::zero_or_more).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "A", "G", "J"}); + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(23), T(34)}).template type(); - CHECK(parsed.get_value>("pos") == std::vector{'A', 'G', 'J'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "42", "54", "65"}); + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "3"}), "argument pos: invalid choice: 3 (choose from 23, 34)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(1.5)}).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 1.5)", argparse::parsing_error); + } + else if constexpr (std::is_same_v) + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "baz"}), "argument pos: invalid choice: (choose from , )", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set accepts one of the values", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string, foo::Custom, bar::Custom) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "A"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "C"})); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(23), T(34)}).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "23"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "34"})); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(1.5)}).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "1.5"})); + } + else + { + parser.add_argument("-o").choices({T("foo"), T("bar")}).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set throws an exception on incorrect value", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string, foo::Custom, bar::Custom) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(23), T(34)}).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "3"}), "argument -o: invalid choice: 3 (choose from 23, 34)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(1.5)}).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 1.5)", argparse::parsing_error); + } + else if constexpr (std::is_same_v) + { + parser.add_argument("-o").choices({T("foo"), T("bar")}).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } + else + { + parser.add_argument("-o").choices({T("foo"), T("bar")}).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "baz"}), "argument -o: invalid choice: (choose from , )", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as a number consumes the number of arguments for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(1).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "A"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "42"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.5"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "foo"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as a number consumes the number of arguments for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(2).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "A", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "42", "54"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.5", "1.125"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "foo", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as a number consumes the number of arguments for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(3).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "A", "C", "E"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "42", "54", "65"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.5", "1.125", "2.375"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as a number yields a list of arguments for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(1).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "B"}); + + CHECK(parsed.get_value>("pos") == std::vector{'B'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "42"}); + + CHECK(parsed.get_value>("pos") == std::vector{42}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.5"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.5}); + } + else + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as a number yields a list of arguments for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(2).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "B", "D"}); + + CHECK(parsed.get_value>("pos") == std::vector{'B', 'D'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "42", "54"}); + + CHECK(parsed.get_value>("pos") == std::vector{42, 54}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "0.5", "1.125"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.5, 1.125}); + } + else + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "foo", "bar"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo", "bar"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as a number yields a list of arguments for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(3).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "B", "D", "F"}); + + CHECK(parsed.get_value>("pos") == std::vector{'B', 'D', 'F'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "42", "54", "65"}); + + CHECK(parsed.get_value>("pos") == std::vector{42, 54, 65}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "0.5", "1.125", "2.375"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.5, 1.125, 2.375}); + } + else + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo", "bar", "baz"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as a number throws an exception for incorrect arguments number for one argument and no provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(1).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: pos", argparse::parsing_error); +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as a number throws an exception for incorrect arguments number for two arguments and one provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(2).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "A"}), "the following arguments are required: pos", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "42"}), "the following arguments are required: pos", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "0.5"}), "the following arguments are required: pos", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "foo"}), "the following arguments are required: pos", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as a number throws an exception for incorrect arguments number for three arguments and two provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(3).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "A", "B"}), "the following arguments are required: pos", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "42", "54"}), "the following arguments are required: pos", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "0.5", "1.125"}), "the following arguments are required: pos", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "foo", "bar"}), "the following arguments are required: pos", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as a number throws an exception for incorrect arguments number for one argument and two provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(1).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "A", "B"}), "unrecognised arguments: B", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "42", "54"}), "unrecognised arguments: 54", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "0.5", "1.125"}), "unrecognised arguments: 1.125", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "foo", "bar"}), "unrecognised arguments: bar", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as a number throws an exception for incorrect arguments number for one arguments and three provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(1).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "A", "B", "C"}), "unrecognised arguments: B C", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "42", "54", "65"}), "unrecognised arguments: 54 65", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "0.5", "1.125", "2.375"}), "unrecognised arguments: 1.125 2.375", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}), "unrecognised arguments: bar baz", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as a number throws an exception for incorrect arguments number for two arguments and three provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(2).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "A", "B", "C"}), "unrecognised arguments: C", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "42", "54", "65"}), "unrecognised arguments: 65", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "0.5", "1.125", "2.375"}), "unrecognised arguments: 2.375", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}), "unrecognised arguments: baz", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as zero_or_one consumes single argument and yields it as a single item", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(argparse::zero_or_one).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); + + CHECK(parsed.get_value("pos") == T('A')); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "42"}); + + CHECK(parsed.get_value("pos") == T(42)); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.5"}); + + CHECK(parsed.get_value("pos") == T(0.5)); + } + else + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); + + CHECK(parsed.get_value("pos") == T("foo")); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as zero_or_one yields default value if no argument is provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").nargs(argparse::zero_or_one).default_(T('A')); + + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + + CHECK(parsed.get_value("pos") == T('A')); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").nargs(argparse::zero_or_one).default_(T(10)); + + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + + CHECK(parsed.get_value("pos") == T(10)); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").nargs(argparse::zero_or_one).default_(T(0.0625)); + + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + + CHECK(parsed.get_value("pos") == T(0.0625)); + } + else + { + parser.add_argument("pos").nargs(argparse::zero_or_one).default_("foo"s); + + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + + CHECK(parsed.get_value("pos") == T("foo")); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as zero_or_more yields an empty list if no arguments provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(argparse::zero_or_more).template type(); + + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + + CHECK(parsed.get_value>("pos") == std::vector()); +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as zero_or_more consumes single argument and yields it as a list", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(argparse::zero_or_more).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "42"}); + + CHECK(parsed.get_value>("pos") == std::vector{42}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.5"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.5}); + } + else + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as zero_or_more consumes all available arguments and yields them as a list", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(argparse::zero_or_more).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "A", "G", "J"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A', 'G', 'J'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "42", "54", "65"}); + + CHECK(parsed.get_value>("pos") == std::vector{42, 54, 65}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "0.5", "1.125", "2.375"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.5, 1.125, 2.375}); + } + else + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo", "bar", "baz"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as one_or_more throws an exception if no arguments provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(argparse::one_or_more).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: pos", argparse::parsing_error); +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as one_or_more consumes single argument and yields it as a list", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(argparse::one_or_more).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "42"}); + + CHECK(parsed.get_value>("pos") == std::vector{42}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.5"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.5}); + } + else + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with nargs set as one_or_more consumes all available arguments and yields them as a list", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos").nargs(argparse::one_or_more).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "A", "G", "J"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A', 'G', 'J'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "42", "54", "65"}); + + CHECK(parsed.get_value>("pos") == std::vector{42, 54, 65}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "0.5", "1.125", "2.375"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.5, 1.125, 2.375}); + } + else + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo", "bar", "baz"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as a number consumes the number of arguments for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(1).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "A"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "42"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as a number consumes the number of arguments for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(2).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "42", "54"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.5", "1.125"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as a number consumes the number of arguments for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(3).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "E"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "42", "54", "65"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.5", "1.125", "2.375"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as a number yields a list of arguments for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(1).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); + + CHECK(parsed.get_value>("o") == std::vector{'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "42"}); + + CHECK(parsed.get_value>("o") == std::vector{42}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}); + + CHECK(parsed.get_value>("o") == std::vector{0.5}); + } + else + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as a number yields a list of arguments for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(2).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "A", "C"}); + + CHECK(parsed.get_value>("o") == std::vector{'A', 'C'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "42", "54"}); + + CHECK(parsed.get_value>("o") == std::vector{42, 54}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "0.5", "1.125"}); + + CHECK(parsed.get_value>("o") == std::vector{0.5, 1.125}); + } + else + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "bar"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo", "bar"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as a number yields a list of arguments for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(3).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "E"}); + + CHECK(parsed.get_value>("o") == std::vector{'A', 'C', 'E'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "42", "54", "65"}); + + CHECK(parsed.get_value>("o") == std::vector{42, 54, 65}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "0.5", "1.125", "2.375"}); + + CHECK(parsed.get_value>("o") == std::vector{0.5, 1.125, 2.375}); + } + else + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo", "bar", "baz"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as a number throws an exception for incorrect arguments number for one argument and no provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(1).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o: expected 1 argument", argparse::parsing_error); +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as a number throws an exception for incorrect arguments number for two arguments and one provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(2).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "A"}), "argument -o: expected 2 arguments", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "42"}), "argument -o: expected 2 arguments", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}), "argument -o: expected 2 arguments", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}), "argument -o: expected 2 arguments", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as a number throws an exception for incorrect arguments number for three arguments and two provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(3).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "B"}), "argument -o: expected 3 arguments", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "42", "54"}), "argument -o: expected 3 arguments", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "0.5", "1.125"}), "argument -o: expected 3 arguments", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "bar"}), "argument -o: expected 3 arguments", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as a number throws an exception for incorrect arguments number for one argument and two provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(1).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "B"}), "unrecognised arguments: B", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "42", "54"}), "unrecognised arguments: 54", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "0.5", "1.125"}), "unrecognised arguments: 1.125", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "bar"}), "unrecognised arguments: bar", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as a number throws an exception for incorrect arguments number for one argument and three provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(1).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "B", "C"}), "unrecognised arguments: B C", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "42", "54", "65"}), "unrecognised arguments: 54 65", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "0.5", "1.125", "2.375"}), "unrecognised arguments: 1.125 2.375", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}), "unrecognised arguments: bar baz", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as a number throws an exception for incorrect arguments number for two arguments and three provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(2).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "B", "C"}), "unrecognised arguments: C", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "42", "54", "65"}), "unrecognised arguments: 65", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "0.5", "1.125", "2.375"}), "unrecognised arguments: 2.375", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}), "unrecognised arguments: baz", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as zero_or_one consumes single argument and yields it as a single item", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::zero_or_one).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); + + CHECK(parsed.get_value("o") == T('A')); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "42"}); + + CHECK(parsed.get_value("o") == T(42)); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}); + + CHECK(parsed.get_value("o") == T(0.5)); + } + else + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); + + CHECK(parsed.get_value("o") == T("foo")); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as zero_or_one yields default value if no argument is provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").nargs(argparse::zero_or_one).default_(T('A')); + + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + + CHECK(parsed.get_value("o") == T('A')); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").nargs(argparse::zero_or_one).default_(T(10)); + + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + + CHECK(parsed.get_value("o") == T(10)); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").nargs(argparse::zero_or_one).default_(T(0.0625)); + + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + + CHECK(parsed.get_value("o") == T(0.0625)); + } + else + { + parser.add_argument("-o").nargs(argparse::zero_or_one).default_("foo"s); + + auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); + + CHECK(parsed.get_value("o") == "foo"); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as zero_or_one yields const value if option string is present and no argument is provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").nargs(argparse::zero_or_one).const_(T('A')); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); + + CHECK(parsed.get_value("o") == T('A')); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").nargs(argparse::zero_or_one).const_(T(5)); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); + + CHECK(parsed.get_value("o") == T(5)); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").nargs(argparse::zero_or_one).const_(T(0.875)); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); + + CHECK(parsed.get_value("o") == T(0.875)); + } + else + { + parser.add_argument("-o").nargs(argparse::zero_or_one).const_("foo"s); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); + + CHECK(parsed.get_value("o") == "foo"); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as zero_or_more yields an empty list if no arguments provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::zero_or_more).template type(); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); + + CHECK(parsed.get_value>("o") == std::vector()); +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as zero_or_more consumes single argument and yields it as a list", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::zero_or_more).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); + + CHECK(parsed.get_value>("o") == std::vector{'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "42"}); + + CHECK(parsed.get_value>("o") == std::vector{42}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}); + + CHECK(parsed.get_value>("o") == std::vector{0.5}); + } + else + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as zero_or_more consumes all available arguments and yields them as a list", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::zero_or_more).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "E"}); + + CHECK(parsed.get_value>("o") == std::vector{'A', 'C', 'E'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "42", "54", "65"}); + + CHECK(parsed.get_value>("o") == std::vector{42, 54, 65}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "0.5", "1.125", "2.375"}); + + CHECK(parsed.get_value>("o") == std::vector{0.5, 1.125, 2.375}); + } + else + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo", "bar", "baz"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as one_or_more throws an exception if no arguments provided", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::one_or_more).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o: expected at least one argument", argparse::parsing_error); +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as one_or_more consumes single argument and yields it as a list", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::one_or_more).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); + + CHECK(parsed.get_value>("o") == std::vector{'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "42"}); + + CHECK(parsed.get_value>("o") == std::vector{42}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}); + + CHECK(parsed.get_value>("o") == std::vector{0.5}); + } + else + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set as one_or_more consumes all available arguments and yields them as a list", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::one_or_more).template type(); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "E"}); + + CHECK(parsed.get_value>("o") == std::vector{'A', 'C', 'E'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "42", "54", "65"}); + + CHECK(parsed.get_value>("o") == std::vector{42, 54, 65}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "0.5", "1.125", "2.375"}); + + CHECK(parsed.get_value>("o") == std::vector{0.5, 1.125, 2.375}); + } + else + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo", "bar", "baz"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set consumes the number of arguments for nargs set as a number for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(1).template type(); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "A"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "C"})); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(1).template type(); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "11"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(1).template type(); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.125"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.25"})); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(1).template type(); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "foo"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set consumes the number of arguments for nargs set as a number for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(2).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "A", "A"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "C", "C"})); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(2).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "11", "11"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "22", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(2).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.125", "0.125"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.25", "0.25"})); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(2).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "foo", "foo"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "bar", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set consumes the number of arguments for nargs set as a number for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(3).template type(); + + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "A", "A", "A"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "C", "C", "C"})); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(3).template type(); + + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "11", "11", "11"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "22", "22", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(3).template type(); + + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.125", "0.125", "0.125"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.25", "0.25", "0.25"})); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(3).template type(); + + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "foo", "foo", "foo"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "bar", "bar", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set consumes the number of arguments for nargs set as zero_or_one for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_one).template type(); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "A"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "C"})); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_one).template type(); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "11"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_one).template type(); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.125"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.25"})); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_one).template type(); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "foo"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set consumes the number of arguments for nargs set as zero_or_more for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "A"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "11"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.125"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.25"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "foo"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set consumes the number of arguments for nargs set as zero_or_more for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "A", "A"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "C", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "11", "11"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "22", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.125", "0.125"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.25", "0.25"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "foo", "foo"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "bar", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set consumes the number of arguments for nargs set as zero_or_more for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "A", "A", "A"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "C", "C", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "11", "11", "11"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "22", "22", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.125", "0.125", "0.125"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.25", "0.25", "0.25"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "foo", "foo", "foo"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "bar", "bar", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set consumes the number of arguments for nargs set as one_or_more for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "A"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "11"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.125"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.25"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "foo"})); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set consumes the number of arguments for nargs set as one_or_more for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "A", "A"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "C", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "11", "11"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "22", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.125", "0.125"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.25", "0.25"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "foo", "foo"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "bar", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set consumes the number of arguments for nargs set as one_or_more for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "A", "A", "A"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "C", "C", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "11", "11", "11"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "22", "22", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.125", "0.125", "0.125"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.25", "0.25", "0.25"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "foo", "foo", "foo"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "bar", "bar", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set yields the arguments for nargs set as a number for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(1).template type(); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A'}); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(1).template type(); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "11"}); + + CHECK(parsed.get_value>("pos") == std::vector{11}); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(1).template type(); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.125"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.125}); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(1).template type(); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set yields the arguments for nargs set as a number for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(2).template type(); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "A", "C"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A', 'C'}); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(2).template type(); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "11", "22"}); + + CHECK(parsed.get_value>("pos") == std::vector{11, 22}); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(2).template type(); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "0.125", "0.25"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.125, 0.25}); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(2).template type(); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "foo", "bar"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo", "bar"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set yields the arguments for nargs set as a number for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(3).template type(); + + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "A", "C", "A"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A', 'C', 'A'}); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(3).template type(); + + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "11", "22", "11"}); + + CHECK(parsed.get_value>("pos") == std::vector{11, 22, 11}); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(3).template type(); + + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "0.125", "0.25", "0.125"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.125, 0.25, 0.125}); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(3).template type(); + + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "foo"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo", "bar", "foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set yields the arguments for nargs set as zero_or_one for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_one).template type(); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); + + CHECK(parsed.get_value("pos") == T('A')); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_one).template type(); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "11"}); + + CHECK(parsed.get_value("pos") == T(11)); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_one).template type(); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.125"}); + + CHECK(parsed.get_value("pos") == T(0.125)); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_one).template type(); + + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); + + CHECK(parsed.get_value("pos") == T("foo")); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set yields the arguments for nargs set as zero_or_more for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "11"}); + + CHECK(parsed.get_value>("pos") == std::vector{11}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.125"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.125}); + } + else + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set yields the arguments for nargs set as zero_or_more for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "A", "A"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A', 'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "11", "11"}); + + CHECK(parsed.get_value>("pos") == std::vector{11, 11}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "0.125", "0.125"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.125, 0.125}); + } + else + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "foo", "foo"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo", "foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set yields the arguments for nargs set as zero_or_more for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "A", "A", "A"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A', 'A', 'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "11", "11", "11"}); + + CHECK(parsed.get_value>("pos") == std::vector{11, 11, 11}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "0.125", "0.125", "0.125"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.125, 0.125, 0.125}); + } + else + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "foo", "foo", "foo"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo", "foo", "foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set yields the arguments for nargs set as one_or_more for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "11"}); + + CHECK(parsed.get_value>("pos") == std::vector{11}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.125"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.125}); + } + else + { + auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set yields the arguments for nargs set as one_or_more for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "A", "A"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A', 'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "11", "11"}); + + CHECK(parsed.get_value>("pos") == std::vector{11, 11}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "0.125", "0.125"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.125, 0.125}); + } + else + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "foo", "foo"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo", "foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set yields the arguments for nargs set as one_or_more for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "A", "A", "A"}); + + CHECK(parsed.get_value>("pos") == std::vector{'A', 'A', 'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "11", "11", "11"}); + + CHECK(parsed.get_value>("pos") == std::vector{11, 11, 11}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "0.125", "0.125", "0.125"}); + + CHECK(parsed.get_value>("pos") == std::vector{0.125, 0.125, 0.125}); + } + else + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "foo", "foo", "foo"}); + + CHECK(parsed.get_value>("pos") == std::vector{"foo", "foo", "foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set throws an exception on incorrect value for nargs set as a number for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(1).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(1).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(1).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(1).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set throws an exception on incorrect value for nargs set as a number for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(2).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "A", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(2).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "11", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(2).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "0.125", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(2).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "foo", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set throws an exception on incorrect value for nargs set as a number for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(3).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "A", "C", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(3).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "11", "22", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(3).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "0.125", "0.25", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(3).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set throws an exception on incorrect value for nargs set as zero_or_one for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_one).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_one).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_one).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_one).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set throws an exception on incorrect value for nargs set as zero_or_more for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set throws an exception on incorrect value for nargs set as zero_or_more for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "A", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "11", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "0.125", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "foo", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set throws an exception on incorrect value for nargs set as zero_or_more for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "A", "C", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "11", "22", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "0.125", "0.25", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set throws an exception on incorrect value for nargs set as one_or_more for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set throws an exception on incorrect value for nargs set as one_or_more for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "A", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "11", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "0.125", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "foo", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing a positional argument with choices set throws an exception on incorrect value for nargs set as one_or_more for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "A", "C", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "11", "22", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "0.125", "0.25", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set consumes the number of arguments for nargs set as a number for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(1).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "A"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "C"})); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(1).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "11"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(1).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.25"})); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(1).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set consumes the number of arguments for nargs set as a number for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(2).template type(); + + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "A"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "C", "C"})); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(2).template type(); + + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "11", "11"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "22", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(2).template type(); + + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.125"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.25", "0.25"})); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(2).template type(); + + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "foo"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "bar", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set consumes the number of arguments for nargs set as a number for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(3).template type(); + + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "A", "A"})); + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "C", "C", "C"})); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(3).template type(); + + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "11", "11", "11"})); + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "22", "22", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(3).template type(); + + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.125", "0.125"})); + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.25", "0.25", "0.25"})); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(3).template type(); + + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "foo", "foo"})); + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "bar", "bar", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set consumes the number of arguments for nargs set as zero_or_one for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_one).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "A"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "C"})); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_one).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "11"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_one).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.25"})); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one).template type(); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set consumes the number of arguments for nargs set as zero_or_more for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "A"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "11"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.25"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set consumes the number of arguments for nargs set as zero_or_more for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "A"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "C", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "11", "11"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "22", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.125"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.25", "0.25"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "foo"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "bar", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set consumes the number of arguments for nargs set as zero_or_more for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "A", "A"})); + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "C", "C", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "11", "11", "11"})); + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "22", "22", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.125", "0.125"})); + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.25", "0.25", "0.25"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "foo", "foo"})); + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "bar", "bar", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set consumes the number of arguments for nargs set as one_or_more for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "A"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "11"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.25"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"})); + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set consumes the number of arguments for nargs set as one_or_more for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "A"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "C", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "11", "11"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "22", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.125"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.25", "0.25"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "foo"})); + CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "bar", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set consumes the number of arguments for nargs set as one_or_more for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "A", "A"})); + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "C", "C", "C"})); + } + else if constexpr (std::is_integral_v) + { + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "11", "11", "11"})); + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "22", "22", "22"})); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.125", "0.125"})); + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.25", "0.25", "0.25"})); + } + else + { + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "foo", "foo"})); + CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "bar", "bar", "bar"})); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set yields the arguments for nargs set as a number for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(1).template type(); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); + + CHECK(parsed.get_value>("o") == std::vector{'A'}); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(1).template type(); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "11"}); + + CHECK(parsed.get_value>("o") == std::vector{11}); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(1).template type(); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"}); + + CHECK(parsed.get_value>("o") == std::vector{0.125}); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(1).template type(); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set yields the arguments for nargs set as a number for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(2).template type(); + + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "A", "C"}); + + CHECK(parsed.get_value>("o") == std::vector{'A', 'C'}); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(2).template type(); + + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "11", "22"}); + + CHECK(parsed.get_value>("o") == std::vector{11, 22}); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(2).template type(); + + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.25"}); + + CHECK(parsed.get_value>("o") == std::vector{0.125, 0.25}); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(2).template type(); + + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "bar"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo", "bar"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set yields the arguments for nargs set as a number for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(3).template type(); + + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "A"}); + + CHECK(parsed.get_value>("o") == std::vector{'A', 'C', 'A'}); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(3).template type(); + + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "11", "22", "11"}); + + CHECK(parsed.get_value>("o") == std::vector{11, 22, 11}); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(3).template type(); + + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.25", "0.125"}); + + CHECK(parsed.get_value>("o") == std::vector{0.125, 0.25, 0.125}); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(3).template type(); + + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "foo"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo", "bar", "foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set yields the arguments for nargs set as zero_or_one for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_one).template type(); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); + + CHECK(parsed.get_value("o") == T('A')); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_one).template type(); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "11"}); + + CHECK(parsed.get_value("o") == T(11)); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_one).template type(); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"}); + + CHECK(parsed.get_value("o") == T(0.125)); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one).template type(); + + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); + + CHECK(parsed.get_value("o") == T("foo")); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set yields the arguments for nargs set as zero_or_more for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); + + CHECK(parsed.get_value>("o") == std::vector{'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "11"}); + + CHECK(parsed.get_value>("o") == std::vector{11}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"}); + + CHECK(parsed.get_value>("o") == std::vector{0.125}); + } + else + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set yields the arguments for nargs set as zero_or_more for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "A", "A"}); + + CHECK(parsed.get_value>("o") == std::vector{'A', 'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "11", "11"}); + + CHECK(parsed.get_value>("o") == std::vector{11, 11}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.125"}); + + CHECK(parsed.get_value>("o") == std::vector{0.125, 0.125}); + } + else + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "foo"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo", "foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set yields the arguments for nargs set as zero_or_more for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "A", "A", "A"}); + + CHECK(parsed.get_value>("o") == std::vector{'A', 'A', 'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "11", "11", "11"}); + + CHECK(parsed.get_value>("o") == std::vector{11, 11, 11}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.125", "0.125"}); + + CHECK(parsed.get_value>("o") == std::vector{0.125, 0.125, 0.125}); + } + else + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "foo", "foo"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo", "foo", "foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set yields the arguments for nargs set as one_or_more for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); + + CHECK(parsed.get_value>("o") == std::vector{'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "11"}); + + CHECK(parsed.get_value>("o") == std::vector{11}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"}); + + CHECK(parsed.get_value>("o") == std::vector{0.125}); + } + else + { + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set yields the arguments for nargs set as one_or_more for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "A", "A"}); + + CHECK(parsed.get_value>("o") == std::vector{'A', 'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "11", "11"}); + + CHECK(parsed.get_value>("o") == std::vector{11, 11}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.125"}); + + CHECK(parsed.get_value>("o") == std::vector{0.125, 0.125}); + } + else + { + auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "foo"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo", "foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set yields the arguments for nargs set as one_or_more for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "A", "A", "A"}); + + CHECK(parsed.get_value>("o") == std::vector{'A', 'A', 'A'}); + } + else if constexpr (std::is_integral_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "11", "11", "11"}); + + CHECK(parsed.get_value>("o") == std::vector{11, 11, 11}); + } + else if constexpr (std::is_floating_point_v) + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.125", "0.125"}); + + CHECK(parsed.get_value>("o") == std::vector{0.125, 0.125, 0.125}); + } + else + { + auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "foo", "foo"}); + + CHECK(parsed.get_value>("o") == std::vector{"foo", "foo", "foo"}); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set throws an exception on incorrect value for nargs set as a number for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(1).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(1).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(1).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(1).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set throws an exception on incorrect value for nargs set as a number for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(2).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(2).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "11", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(2).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(2).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set throws an exception on incorrect value for nargs set as a number for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(3).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(3).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "11", "22", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(3).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.25", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(3).template type(); - CHECK(parsed.get_value>("pos") == std::vector{42, 54, 65}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "0.5", "1.125", "2.375"}); + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set throws an exception on incorrect value for nargs set as zero_or_one for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_one).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_one).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_one).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one).template type(); + + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set throws an exception on incorrect value for nargs set as zero_or_more for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more).template type(); + } + + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} + +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set throws an exception on incorrect value for nargs set as zero_or_more for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - CHECK(parsed.get_value>("pos") == std::vector{0.5, 1.125, 2.375}); - } - else - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo", "bar", "baz"}); - } - } - } - - SUBCASE("...as one_or_more...") - { - SUBCASE("...throws an exception if no arguments provided") - { - parser.add_argument("pos").nargs(argparse::one_or_more).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: pos", argparse::parsing_error); - } - - SUBCASE("...consumes single argument and yields it as a list") - { - parser.add_argument("pos").nargs(argparse::one_or_more).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); - - CHECK(parsed.get_value>("pos") == std::vector{'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "42"}); - - CHECK(parsed.get_value>("pos") == std::vector{42}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.5"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.5}); - } - else - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo"}); - } - } - - SUBCASE("...consumes all available arguments and yields them as a list") - { - parser.add_argument("pos").nargs(argparse::one_or_more).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "A", "G", "J"}); - - CHECK(parsed.get_value>("pos") == std::vector{'A', 'G', 'J'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "42", "54", "65"}); - - CHECK(parsed.get_value>("pos") == std::vector{42, 54, 65}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "0.5", "1.125", "2.375"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.5, 1.125, 2.375}); - } - else - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo", "bar", "baz"}); - } - } - } -} - -TEST_CASE_TEMPLATE("Parsing an optional argument with nargs set...", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) -{ - auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - - SUBCASE("...as a number...") - { - SUBCASE("...consumes the number of arguments...") - { - SUBCASE("...for one argument") - { - parser.add_argument("-o").nargs(1).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "A"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "42"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"})); - } - } - - SUBCASE("...for two arguments") - { - parser.add_argument("-o").nargs(2).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "42", "54"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.5", "1.125"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "bar"})); - } - } - - SUBCASE("...for three arguments") - { - parser.add_argument("-o").nargs(3).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "E"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "42", "54", "65"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.5", "1.125", "2.375"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"})); - } - } - } - - SUBCASE("...yields a list of arguments...") - { - SUBCASE("...for one argument") - { - parser.add_argument("-o").nargs(1).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); - - CHECK(parsed.get_value>("o") == std::vector{'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "42"}); - - CHECK(parsed.get_value>("o") == std::vector{42}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}); - - CHECK(parsed.get_value>("o") == std::vector{0.5}); - } - else - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo"}); - } - } - - SUBCASE("...for two arguments") - { - parser.add_argument("-o").nargs(2).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "A", "C"}); - - CHECK(parsed.get_value>("o") == std::vector{'A', 'C'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "42", "54"}); - - CHECK(parsed.get_value>("o") == std::vector{42, 54}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "0.5", "1.125"}); - - CHECK(parsed.get_value>("o") == std::vector{0.5, 1.125}); - } - else - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "bar"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo", "bar"}); - } - } - - SUBCASE("...for three arguments") - { - parser.add_argument("-o").nargs(3).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "E"}); - - CHECK(parsed.get_value>("o") == std::vector{'A', 'C', 'E'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "42", "54", "65"}); - - CHECK(parsed.get_value>("o") == std::vector{42, 54, 65}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "0.5", "1.125", "2.375"}); - - CHECK(parsed.get_value>("o") == std::vector{0.5, 1.125, 2.375}); - } - else - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo", "bar", "baz"}); - } - } - } - - SUBCASE("...throws an exception for incorrect arguments number...") - { - SUBCASE("...for one argument and no provided") - { - parser.add_argument("-o").nargs(1).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o: expected 1 argument", argparse::parsing_error); - } - - SUBCASE("...for two arguments and one provided") - { - parser.add_argument("-o").nargs(2).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "A"}), "argument -o: expected 2 arguments", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "42"}), "argument -o: expected 2 arguments", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}), "argument -o: expected 2 arguments", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}), "argument -o: expected 2 arguments", argparse::parsing_error); - } - } - - SUBCASE("...for three arguments and two provided") - { - parser.add_argument("-o").nargs(3).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "B"}), "argument -o: expected 3 arguments", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "42", "54"}), "argument -o: expected 3 arguments", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "0.5", "1.125"}), "argument -o: expected 3 arguments", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "bar"}), "argument -o: expected 3 arguments", argparse::parsing_error); - } - } - - SUBCASE("...for one argument and two provided") - { - parser.add_argument("-o").nargs(1).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "B"}), "unrecognised arguments: B", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "42", "54"}), "unrecognised arguments: 54", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "0.5", "1.125"}), "unrecognised arguments: 1.125", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "bar"}), "unrecognised arguments: bar", argparse::parsing_error); - } - } - - SUBCASE("...for one argument and three provided") - { - parser.add_argument("-o").nargs(1).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "B", "C"}), "unrecognised arguments: B C", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "42", "54", "65"}), "unrecognised arguments: 54 65", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "0.5", "1.125", "2.375"}), "unrecognised arguments: 1.125 2.375", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}), "unrecognised arguments: bar baz", argparse::parsing_error); - } - } - - SUBCASE("...for two arguments and three provided") - { - parser.add_argument("-o").nargs(2).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "B", "C"}), "unrecognised arguments: C", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "42", "54", "65"}), "unrecognised arguments: 65", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "0.5", "1.125", "2.375"}), "unrecognised arguments: 2.375", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}), "unrecognised arguments: baz", argparse::parsing_error); - } - } - } - } - - SUBCASE("...as zero_or_one...") - { - SUBCASE("...consumes single argument and yields it as a single item") - { - parser.add_argument("-o").nargs(argparse::zero_or_one).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); - - CHECK(parsed.get_value("o") == T('A')); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "42"}); - - CHECK(parsed.get_value("o") == T(42)); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}); - - CHECK(parsed.get_value("o") == T(0.5)); - } - else - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); - - CHECK(parsed.get_value("o") == T("foo")); - } - } - - SUBCASE("...yields default value if no argument is provided") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").nargs(argparse::zero_or_one).default_(T('A')); - - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - - CHECK(parsed.get_value("o") == T('A')); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").nargs(argparse::zero_or_one).default_(T(10)); - - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - - CHECK(parsed.get_value("o") == T(10)); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").nargs(argparse::zero_or_one).default_(T(0.0625)); - - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - - CHECK(parsed.get_value("o") == T(0.0625)); - } - else - { - parser.add_argument("-o").nargs(argparse::zero_or_one).default_("foo"s); - - auto const parsed = parser.parse_args(1, cstr_arr{"prog"}); - - CHECK(parsed.get_value("o") == "foo"); - } - } - - SUBCASE("...yields const value if option string is present and no argument is provided") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").nargs(argparse::zero_or_one).const_(T('A')); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); - - CHECK(parsed.get_value("o") == T('A')); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").nargs(argparse::zero_or_one).const_(T(5)); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); - - CHECK(parsed.get_value("o") == T(5)); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").nargs(argparse::zero_or_one).const_(T(0.875)); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); - - CHECK(parsed.get_value("o") == T(0.875)); - } - else - { - parser.add_argument("-o").nargs(argparse::zero_or_one).const_("foo"s); + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more).template type(); + } - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "11", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} - CHECK(parsed.get_value("o") == "foo"); - } - } - } - - SUBCASE("...as zero_or_more...") - { - SUBCASE("...yields an empty list if no arguments provided") - { - parser.add_argument("-o").nargs(argparse::zero_or_more).template type(); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "-o"}); - - CHECK(parsed.get_value>("o") == std::vector()); - } - - SUBCASE("...consumes single argument and yields it as a list") - { - parser.add_argument("-o").nargs(argparse::zero_or_more).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); - - CHECK(parsed.get_value>("o") == std::vector{'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "42"}); - - CHECK(parsed.get_value>("o") == std::vector{42}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}); - - CHECK(parsed.get_value>("o") == std::vector{0.5}); - } - else - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo"}); - } - } - - SUBCASE("...consumes all available arguments and yields them as a list") - { - parser.add_argument("-o").nargs(argparse::zero_or_more).template type(); +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set throws an exception on incorrect value for nargs set as zero_or_more for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "E"}); + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more).template type(); + } - CHECK(parsed.get_value>("o") == std::vector{'A', 'C', 'E'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "42", "54", "65"}); + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "11", "22", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.25", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} - CHECK(parsed.get_value>("o") == std::vector{42, 54, 65}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "0.5", "1.125", "2.375"}); +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set throws an exception on incorrect value for nargs set as one_or_more for one argument", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - CHECK(parsed.get_value>("o") == std::vector{0.5, 1.125, 2.375}); - } - else - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}); + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more).template type(); + } - CHECK(parsed.get_value>("o") == std::vector{"foo", "bar", "baz"}); - } - } + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); } - - SUBCASE("...as one_or_more...") - { - SUBCASE("...throws an exception if no arguments provided") - { - parser.add_argument("-o").nargs(argparse::one_or_more).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "-o"}), "argument -o: expected at least one argument", argparse::parsing_error); - } - - SUBCASE("...consumes single argument and yields it as a list") - { - parser.add_argument("-o").nargs(argparse::one_or_more).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); - - CHECK(parsed.get_value>("o") == std::vector{'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "42"}); - - CHECK(parsed.get_value>("o") == std::vector{42}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}); - - CHECK(parsed.get_value>("o") == std::vector{0.5}); - } - else - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo"}); - } - } - - SUBCASE("...consumes all available arguments and yields them as a list") - { - parser.add_argument("-o").nargs(argparse::one_or_more).template type(); - - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "E"}); - - CHECK(parsed.get_value>("o") == std::vector{'A', 'C', 'E'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "42", "54", "65"}); - - CHECK(parsed.get_value>("o") == std::vector{42, 54, 65}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "0.5", "1.125", "2.375"}); - - CHECK(parsed.get_value>("o") == std::vector{0.5, 1.125, 2.375}); - } - else - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo", "bar", "baz"}); - } - } - } -} - -TEST_CASE_TEMPLATE("Parsing a positional argument with choices set...", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) -{ - auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - - SUBCASE("...consumes the number of arguments for nargs set...") - { - SUBCASE("...as a number...") - { - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(1).template type(); - - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "A"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "C"})); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(1).template type(); - - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "11"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(1).template type(); - - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.125"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.25"})); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(1).template type(); - - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "foo"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "bar"})); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(2).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "A", "A"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "C", "C"})); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(2).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "11", "11"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "22", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(2).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.125", "0.125"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.25", "0.25"})); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(2).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "foo", "foo"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "bar", "bar"})); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(3).template type(); - - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "A", "A", "A"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "C", "C", "C"})); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(3).template type(); - - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "11", "11", "11"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "22", "22", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(3).template type(); - - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.125", "0.125", "0.125"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.25", "0.25", "0.25"})); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(3).template type(); - - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "foo", "foo", "foo"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "bar", "bar", "bar"})); - } - } - } - - SUBCASE("...as zero_or_one...") - { - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_one).template type(); - - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "A"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "C"})); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_one).template type(); - - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "11"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_one).template type(); - - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.125"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.25"})); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_one).template type(); - - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "foo"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "bar"})); - } - } - } - - SUBCASE("...as zero_or_more...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_more).template type(); - } - - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "A"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "11"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.125"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.25"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "foo"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "bar"})); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "A", "A"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "C", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "11", "11"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "22", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.125", "0.125"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.25", "0.25"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "foo", "foo"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "bar", "bar"})); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "A", "A", "A"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "C", "C", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "11", "11", "11"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "22", "22", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.125", "0.125", "0.125"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.25", "0.25", "0.25"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "foo", "foo", "foo"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "bar", "bar", "bar"})); - } - } - } - - SUBCASE("...as one_or_more...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::one_or_more).template type(); - } - - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "A"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "11"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.125"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "0.25"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "foo"})); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "bar"})); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "A", "A"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "C", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "11", "11"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "22", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.125", "0.125"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "0.25", "0.25"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "foo", "foo"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "bar", "bar"})); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "A", "A", "A"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "C", "C", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "11", "11", "11"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "22", "22", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.125", "0.125", "0.125"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "0.25", "0.25", "0.25"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "foo", "foo", "foo"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "bar", "bar", "bar"})); - } - } - } - } - - SUBCASE("...yields the arguments for nargs set...") - { - SUBCASE("...as a number...") - { - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(1).template type(); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); - - CHECK(parsed.get_value>("pos") == std::vector{'A'}); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(1).template type(); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "11"}); - - CHECK(parsed.get_value>("pos") == std::vector{11}); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(1).template type(); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.125"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.125}); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(1).template type(); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo"}); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(2).template type(); - - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "A", "C"}); - - CHECK(parsed.get_value>("pos") == std::vector{'A', 'C'}); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(2).template type(); - - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "11", "22"}); - - CHECK(parsed.get_value>("pos") == std::vector{11, 22}); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(2).template type(); - - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "0.125", "0.25"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.125, 0.25}); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(2).template type(); - - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "foo", "bar"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo", "bar"}); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(3).template type(); - - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "A", "C", "A"}); - - CHECK(parsed.get_value>("pos") == std::vector{'A', 'C', 'A'}); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(3).template type(); - - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "11", "22", "11"}); - - CHECK(parsed.get_value>("pos") == std::vector{11, 22, 11}); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(3).template type(); - - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "0.125", "0.25", "0.125"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.125, 0.25, 0.125}); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(3).template type(); - - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "foo"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo", "bar", "foo"}); - } - } - } - - SUBCASE("...as zero_or_one...") - { - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_one).template type(); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); - - CHECK(parsed.get_value("pos") == T('A')); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_one).template type(); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "11"}); - - CHECK(parsed.get_value("pos") == T(11)); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_one).template type(); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.125"}); - - CHECK(parsed.get_value("pos") == T(0.125)); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_one).template type(); - - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); - - CHECK(parsed.get_value("pos") == T("foo")); - } - } - } - - SUBCASE("...as zero_or_more...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_more).template type(); - } - - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); - - CHECK(parsed.get_value>("pos") == std::vector{'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "11"}); - - CHECK(parsed.get_value>("pos") == std::vector{11}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.125"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.125}); - } - else - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo"}); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "A", "A"}); - - CHECK(parsed.get_value>("pos") == std::vector{'A', 'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "11", "11"}); - - CHECK(parsed.get_value>("pos") == std::vector{11, 11}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "0.125", "0.125"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.125, 0.125}); - } - else - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "foo", "foo"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo", "foo"}); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "A", "A", "A"}); - - CHECK(parsed.get_value>("pos") == std::vector{'A', 'A', 'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "11", "11", "11"}); - - CHECK(parsed.get_value>("pos") == std::vector{11, 11, 11}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "0.125", "0.125", "0.125"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.125, 0.125, 0.125}); - } - else - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "foo", "foo", "foo"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo", "foo", "foo"}); - } - } - } - - SUBCASE("...as one_or_more...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::one_or_more).template type(); - } - - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "A"}); - - CHECK(parsed.get_value>("pos") == std::vector{'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "11"}); - - CHECK(parsed.get_value>("pos") == std::vector{11}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "0.125"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.125}); - } - else - { - auto const parsed = parser.parse_args(2, cstr_arr{"prog", "foo"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo"}); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "A", "A"}); - - CHECK(parsed.get_value>("pos") == std::vector{'A', 'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "11", "11"}); - - CHECK(parsed.get_value>("pos") == std::vector{11, 11}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "0.125", "0.125"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.125, 0.125}); - } - else - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "foo", "foo"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo", "foo"}); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "A", "A", "A"}); - - CHECK(parsed.get_value>("pos") == std::vector{'A', 'A', 'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "11", "11", "11"}); - - CHECK(parsed.get_value>("pos") == std::vector{11, 11, 11}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "0.125", "0.125", "0.125"}); - - CHECK(parsed.get_value>("pos") == std::vector{0.125, 0.125, 0.125}); - } - else - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "foo", "foo", "foo"}); - - CHECK(parsed.get_value>("pos") == std::vector{"foo", "foo", "foo"}); - } - } - } - } - - SUBCASE("...throws an exception on incorrect value for nargs set...") - { - SUBCASE("...as a number...") - { - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(1).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(1).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(1).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(1).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(2).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "A", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(2).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "11", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(2).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "0.125", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(2).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "foo", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(3).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "A", "C", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(3).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "11", "22", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(3).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "0.125", "0.25", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(3).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - } - - SUBCASE("...as zero_or_one...") - { - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_one).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_one).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_one).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_one).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - } - - SUBCASE("...as zero_or_more...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::zero_or_more).template type(); - } - - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "A", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "11", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "0.125", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "foo", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "A", "C", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "11", "22", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "0.125", "0.25", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - } - - SUBCASE("...as one_or_more...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("pos").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("pos").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("pos").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); - } - else - { - parser.add_argument("pos").choices({T("foo"), T("bar")}).nargs(argparse::one_or_more).template type(); - } - - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(2, cstr_arr{"prog", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "A", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "11", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "0.125", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "foo", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "A", "C", "B"}), "argument pos: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "11", "22", "33"}), "argument pos: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "0.125", "0.25", "0.5"}), "argument pos: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "foo", "bar", "baz"}), "argument pos: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - } - } -} - -TEST_CASE_TEMPLATE("Parsing an optional argument with choices set...", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) -{ - auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - - SUBCASE("...consumes the number of arguments for nargs set...") - { - SUBCASE("...as a number...") - { - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(1).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "A"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "C"})); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(1).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "11"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(1).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.25"})); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(1).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "bar"})); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(2).template type(); - - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "A"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "C", "C"})); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(2).template type(); - - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "11", "11"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "22", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(2).template type(); - - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.125"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.25", "0.25"})); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(2).template type(); - - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "foo"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "bar", "bar"})); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(3).template type(); - - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "A", "A"})); - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "C", "C", "C"})); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(3).template type(); - - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "11", "11", "11"})); - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "22", "22", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(3).template type(); - - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.125", "0.125"})); - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.25", "0.25", "0.25"})); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(3).template type(); - - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "foo", "foo"})); - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "bar", "bar", "bar"})); - } - } - } - - SUBCASE("...as zero_or_one...") - { - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_one).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "A"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "C"})); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_one).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "11"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_one).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.25"})); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one).template type(); - - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "bar"})); - } - } - } - - SUBCASE("...as zero_or_more...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more).template type(); - } - - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "A"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "11"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.25"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "bar"})); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "A"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "C", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "11", "11"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "22", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.125"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.25", "0.25"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "foo"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "bar", "bar"})); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "A", "A"})); - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "C", "C", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "11", "11", "11"})); - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "22", "22", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.125", "0.125"})); - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.25", "0.25", "0.25"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "foo", "foo"})); - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "bar", "bar", "bar"})); - } - } - } - - SUBCASE("...as one_or_more...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more).template type(); - } - - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "A"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "11"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "0.25"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "foo"})); - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-o", "bar"})); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "A"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "C", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "11", "11"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "22", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.125"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "0.25", "0.25"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "foo"})); - CHECK_NOTHROW(parser.parse_args(4, cstr_arr{"prog", "-o", "bar", "bar"})); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "A", "A"})); - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "C", "C", "C"})); - } - else if constexpr (std::is_integral_v) - { - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "11", "11", "11"})); - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "22", "22", "22"})); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.125", "0.125"})); - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "0.25", "0.25", "0.25"})); - } - else - { - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "foo", "foo"})); - CHECK_NOTHROW(parser.parse_args(5, cstr_arr{"prog", "-o", "bar", "bar", "bar"})); - } - } - } - } - - SUBCASE("...yields the arguments for nargs set...") - { - SUBCASE("...as a number...") - { - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(1).template type(); - - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); - - CHECK(parsed.get_value>("o") == std::vector{'A'}); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(1).template type(); - - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "11"}); - - CHECK(parsed.get_value>("o") == std::vector{11}); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(1).template type(); - - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"}); - - CHECK(parsed.get_value>("o") == std::vector{0.125}); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(1).template type(); - - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo"}); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(2).template type(); - - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "A", "C"}); - - CHECK(parsed.get_value>("o") == std::vector{'A', 'C'}); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(2).template type(); - - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "11", "22"}); - - CHECK(parsed.get_value>("o") == std::vector{11, 22}); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(2).template type(); - - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.25"}); - - CHECK(parsed.get_value>("o") == std::vector{0.125, 0.25}); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(2).template type(); - - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "bar"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo", "bar"}); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(3).template type(); - - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "A"}); - - CHECK(parsed.get_value>("o") == std::vector{'A', 'C', 'A'}); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(3).template type(); - - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "11", "22", "11"}); - - CHECK(parsed.get_value>("o") == std::vector{11, 22, 11}); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(3).template type(); - - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.25", "0.125"}); - - CHECK(parsed.get_value>("o") == std::vector{0.125, 0.25, 0.125}); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(3).template type(); - - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "foo"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo", "bar", "foo"}); - } - } - } - - SUBCASE("...as zero_or_one...") - { - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_one).template type(); - - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); - - CHECK(parsed.get_value("o") == T('A')); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_one).template type(); - - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "11"}); - - CHECK(parsed.get_value("o") == T(11)); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_one).template type(); - - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"}); - - CHECK(parsed.get_value("o") == T(0.125)); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one).template type(); - - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); - - CHECK(parsed.get_value("o") == T("foo")); - } - } - } - - SUBCASE("...as zero_or_more...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more).template type(); - } - - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); - - CHECK(parsed.get_value>("o") == std::vector{'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "11"}); - - CHECK(parsed.get_value>("o") == std::vector{11}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"}); - - CHECK(parsed.get_value>("o") == std::vector{0.125}); - } - else - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo"}); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "A", "A"}); - - CHECK(parsed.get_value>("o") == std::vector{'A', 'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "11", "11"}); - - CHECK(parsed.get_value>("o") == std::vector{11, 11}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.125"}); - - CHECK(parsed.get_value>("o") == std::vector{0.125, 0.125}); - } - else - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "foo"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo", "foo"}); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "A", "A", "A"}); - - CHECK(parsed.get_value>("o") == std::vector{'A', 'A', 'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "11", "11", "11"}); - - CHECK(parsed.get_value>("o") == std::vector{11, 11, 11}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.125", "0.125"}); - - CHECK(parsed.get_value>("o") == std::vector{0.125, 0.125, 0.125}); - } - else - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "foo", "foo"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo", "foo", "foo"}); - } - } - } - - SUBCASE("...as one_or_more...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more).template type(); - } - - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "A"}); - - CHECK(parsed.get_value>("o") == std::vector{'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "11"}); - - CHECK(parsed.get_value>("o") == std::vector{11}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "0.125"}); - - CHECK(parsed.get_value>("o") == std::vector{0.125}); - } - else - { - auto const parsed = parser.parse_args(3, cstr_arr{"prog", "-o", "foo"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo"}); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "A", "A"}); - - CHECK(parsed.get_value>("o") == std::vector{'A', 'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "11", "11"}); - - CHECK(parsed.get_value>("o") == std::vector{11, 11}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.125"}); - - CHECK(parsed.get_value>("o") == std::vector{0.125, 0.125}); - } - else - { - auto const parsed = parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "foo"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo", "foo"}); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "A", "A", "A"}); - - CHECK(parsed.get_value>("o") == std::vector{'A', 'A', 'A'}); - } - else if constexpr (std::is_integral_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "11", "11", "11"}); - - CHECK(parsed.get_value>("o") == std::vector{11, 11, 11}); - } - else if constexpr (std::is_floating_point_v) - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.125", "0.125"}); - - CHECK(parsed.get_value>("o") == std::vector{0.125, 0.125, 0.125}); - } - else - { - auto const parsed = parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "foo", "foo"}); - - CHECK(parsed.get_value>("o") == std::vector{"foo", "foo", "foo"}); - } - } - } - } - - SUBCASE("...throws an exception on incorrect value for nargs set...") - { - SUBCASE("...as a number...") - { - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(1).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(1).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(1).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(1).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(2).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(2).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "11", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(2).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(2).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(3).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(3).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "11", "22", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(3).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.25", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(3).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - } - - SUBCASE("...as zero_or_one...") - { - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_one).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_one).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_one).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one).template type(); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - } - - SUBCASE("...as zero_or_more...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::zero_or_more).template type(); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::zero_or_more).template type(); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::zero_or_more).template type(); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more).template type(); - } - - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "11", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "11", "22", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.25", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - } - - SUBCASE("...as one_or_more...") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); - } - else if constexpr (std::is_integral_v) - { - parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); - } - else if constexpr (std::is_floating_point_v) - { - parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); - } - else - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more).template type(); - } - - SUBCASE("...for one argument") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - - SUBCASE("...for two arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "11", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - - SUBCASE("...for three arguments") - { - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); - } - else if constexpr (std::is_integral_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "11", "22", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); - } - else if constexpr (std::is_floating_point_v) - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.25", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); - } - else - { - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); - } - } - } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); } } -TEST_CASE("Parsing missing positional argument with nargs set throws an exception...") +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set throws an exception on incorrect value for nargs set as one_or_more for two arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - SUBCASE("...for one missing argument") + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) { - parser.add_argument("p1").nargs(2); - - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: p1", argparse::parsing_error); + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); } - - SUBCASE("...for two missing arguments") + else if constexpr (std::is_integral_v) { - parser.add_argument("p1").nargs(2); - parser.add_argument("p2").nargs(2); - - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: p1 p2", argparse::parsing_error); + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); } - - SUBCASE("...for three missing arguments") + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else { - parser.add_argument("p1").nargs(2); - parser.add_argument("p2").nargs(2); - parser.add_argument("p3").nargs(2); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more).template type(); + } - CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: p1 p2 p3", argparse::parsing_error); + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "A", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "11", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "0.125", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); } } -TEST_CASE("An optional argument does not consume another optional argument...") +TEST_CASE_TEMPLATE("Parsing an optional argument with choices set throws an exception on incorrect value for nargs set as one_or_more for three arguments", T, char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double, std::string) { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - SUBCASE("...for simple argument") + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) { - parser.add_argument("-o"); - parser.add_argument("-p"); - - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "-p"}), "argument -o: expected one argument", argparse::parsing_error); + parser.add_argument("-o").choices({T('A'), T('C')}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_integral_v) + { + parser.add_argument("-o").choices({T(11), T(22)}).nargs(argparse::one_or_more).template type(); + } + else if constexpr (std::is_floating_point_v) + { + parser.add_argument("-o").choices({T(0.125), T(0.25)}).nargs(argparse::one_or_more).template type(); + } + else + { + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more).template type(); } - SUBCASE("...for argument with nargs set as number...") + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "A", "C", "B"}), "argument -o: invalid choice: B (choose from A, C)", argparse::parsing_error); + } + else if constexpr (std::is_integral_v) + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "11", "22", "33"}), "argument -o: invalid choice: 33 (choose from 11, 22)", argparse::parsing_error); + } + else if constexpr (std::is_floating_point_v) { - SUBCASE("...1") - { - parser.add_argument("-o").nargs(1); - parser.add_argument("-p"); + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "0.125", "0.25", "0.5"}), "argument -o: invalid choice: 0.5 (choose from 0.125, 0.25)", argparse::parsing_error); + } + else + { + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "baz"}), "argument -o: invalid choice: \"baz\" (choose from \"foo\", \"bar\")", argparse::parsing_error); + } +} - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "-p"}), "argument -o: expected 1 argument", argparse::parsing_error); - } +TEST_CASE("Parsing missing positional argument with nargs set throws an exception for one missing argument") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("p1").nargs(2); - SUBCASE("...2") - { - parser.add_argument("-o").nargs(2); - parser.add_argument("-p"); + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: p1", argparse::parsing_error); +} - CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "-p"}), "argument -o: expected 2 arguments", argparse::parsing_error); - } +TEST_CASE("Parsing missing positional argument with nargs set throws an exception for two missing arguments") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("p1").nargs(2); + parser.add_argument("p2").nargs(2); - SUBCASE("...3") - { - parser.add_argument("-o").nargs(3); - parser.add_argument("-p"); + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: p1 p2", argparse::parsing_error); +} - CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "-p"}), "argument -o: expected 3 arguments", argparse::parsing_error); - } - } +TEST_CASE("Parsing missing positional argument with nargs set throws an exception for three missing arguments") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("p1").nargs(2); + parser.add_argument("p2").nargs(2); + parser.add_argument("p3").nargs(2); - SUBCASE("...for argument with nargs set as zero_or_one") - { - parser.add_argument("-o").nargs(argparse::zero_or_one); - parser.add_argument("-p"); + CHECK_THROWS_WITH_AS(parser.parse_args(1, cstr_arr{"prog"}), "the following arguments are required: p1 p2 p3", argparse::parsing_error); +} - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "-p"}), "argument -p: expected one argument", argparse::parsing_error); - } +TEST_CASE("An optional argument does not consume another optional argument for simple argument") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o"); + parser.add_argument("-p"); - SUBCASE("...for argument with nargs set as zero_or_more") - { - parser.add_argument("-o").nargs(argparse::zero_or_more); - parser.add_argument("-p"); + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "-p"}), "argument -o: expected one argument", argparse::parsing_error); +} - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "-p"}), "argument -p: expected one argument", argparse::parsing_error); - } +TEST_CASE("An optional argument does not consume another optional argument for argument with nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(1); + parser.add_argument("-p"); - SUBCASE("...for argument with nargs set as one_or_more") - { - parser.add_argument("-o").nargs(argparse::one_or_more); - parser.add_argument("-p"); + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "-p"}), "argument -o: expected 1 argument", argparse::parsing_error); +} - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "-p"}), "argument -o: expected at least one argument", argparse::parsing_error); - } +TEST_CASE("An optional argument does not consume another optional argument for argument with nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(2); + parser.add_argument("-p"); + + CHECK_THROWS_WITH_AS(parser.parse_args(4, cstr_arr{"prog", "-o", "foo", "-p"}), "argument -o: expected 2 arguments", argparse::parsing_error); } -TEST_CASE("Parsing -- pseudo argument does not throw") +TEST_CASE("An optional argument does not consume another optional argument for argument with nargs set as number 3") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(3); + parser.add_argument("-p"); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "--"})); + CHECK_THROWS_WITH_AS(parser.parse_args(5, cstr_arr{"prog", "-o", "foo", "bar", "-p"}), "argument -o: expected 3 arguments", argparse::parsing_error); } -TEST_CASE("Arguments past the -- pseudo argument are treated as positional...") +TEST_CASE("An optional argument does not consume another optional argument for argument with nargs set as zero_or_one") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::zero_or_one); + parser.add_argument("-p"); - SUBCASE("...for optional arguments") - { - parser.add_argument("-o").action(argparse::store_true); + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "-p"}), "argument -p: expected one argument", argparse::parsing_error); +} - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "--", "-o"}), "unrecognised arguments: -o", argparse::parsing_error); - } +TEST_CASE("An optional argument does not consume another optional argument for argument with nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::zero_or_more); + parser.add_argument("-p"); - SUBCASE("...for positional arguments") - { - parser.add_argument("pos"); + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "-p"}), "argument -p: expected one argument", argparse::parsing_error); +} - auto const parsed =parser.parse_args(3, cstr_arr{"prog", "--", "-o"}); +TEST_CASE("An optional argument does not consume another optional argument for argument with nargs set as one_or_more") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::one_or_more); + parser.add_argument("-p"); - CHECK(parsed.get_value("pos") == "-o"); - } + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "-p"}), "argument -o: expected at least one argument", argparse::parsing_error); } -TEST_CASE("An optional argument does not consume arguments past the -- pseudo argument...") +TEST_CASE("Parsing -- pseudo argument does not throw") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); - SUBCASE("...for simple argument") - { - parser.add_argument("-o"); + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "--"})); +} - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "--"}), "argument -o: expected one argument", argparse::parsing_error); - } +TEST_CASE("Arguments past the -- pseudo argument are treated as positional for optional arguments") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").action(argparse::store_true); - SUBCASE("...for argument with nargs set as number...") - { - SUBCASE("...1") - { - parser.add_argument("-o").nargs(1); + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "--", "-o"}), "unrecognised arguments: -o", argparse::parsing_error); +} - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "--"}), "argument -o: expected 1 argument", argparse::parsing_error); - } +TEST_CASE("Arguments past the -- pseudo argument are treated as positional for positional arguments") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("pos"); - SUBCASE("...2") - { - parser.add_argument("-o").nargs(2); + auto const parsed = parser.parse_args(3, cstr_arr{"prog", "--", "-o"}); - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "--"}), "argument -o: expected 2 arguments", argparse::parsing_error); - } + CHECK(parsed.get_value("pos") == "-o"); +} - SUBCASE("...3") - { - parser.add_argument("-o").nargs(3); +TEST_CASE("An optional argument does not consume arguments past the -- pseudo argument for simple argument") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o"); - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "--"}), "argument -o: expected 3 arguments", argparse::parsing_error); - } - } + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "--"}), "argument -o: expected one argument", argparse::parsing_error); +} - SUBCASE("...for argument with nargs set as zero_or_one") - { - parser.add_argument("-o").nargs(argparse::zero_or_one); +TEST_CASE("An optional argument does not consume arguments past the -- pseudo argument for argument with nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(1); - auto args = parser.parse_args(3, cstr_arr{"prog", "-o", "--"}); + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "--"}), "argument -o: expected 1 argument", argparse::parsing_error); +} - CHECK(!args.get("o")); - } +TEST_CASE("An optional argument does not consume arguments past the -- pseudo argument for argument with nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(2); - SUBCASE("...for argument with nargs set as zero_or_more") - { - parser.add_argument("-o").nargs(argparse::zero_or_more); + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "--"}), "argument -o: expected 2 arguments", argparse::parsing_error); +} - auto args = parser.parse_args(3, cstr_arr{"prog", "-o", "--"}); +TEST_CASE("An optional argument does not consume arguments past the -- pseudo argument for argument with nargs set as number 3") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(3); - CHECK(args.get_value>("o") == std::vector()); - } + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "--"}), "argument -o: expected 3 arguments", argparse::parsing_error); +} - SUBCASE("...for argument with nargs set as one_or_more") - { - parser.add_argument("-o").nargs(argparse::one_or_more); +TEST_CASE("An optional argument does not consume arguments past the -- pseudo argument for argument with nargs set as zero_or_one") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::zero_or_one); - CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "--"}), "argument -o: expected at least one argument", argparse::parsing_error); - } + auto args = parser.parse_args(3, cstr_arr{"prog", "-o", "--"}); - SUBCASE("...for argument with nargs set as zero_or_more and followed by a positional argument") - { - parser.add_argument("-o").nargs(argparse::zero_or_more); - parser.add_argument("pos"); + CHECK(!args.get("o")); +} - auto args = parser.parse_args(4, cstr_arr{"prog", "-o", "--", "val"}); +TEST_CASE("An optional argument does not consume arguments past the -- pseudo argument for argument with nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::zero_or_more); - CHECK(args.get_value>("o") == std::vector()); - CHECK(args.get_value("pos") == "val"); - } + auto args = parser.parse_args(3, cstr_arr{"prog", "-o", "--"}); + + CHECK(args.get_value>("o") == std::vector()); } -TEST_CASE("Parsing joined short options does not throw...") +TEST_CASE("An optional argument does not consume arguments past the -- pseudo argument for argument with nargs set as one_or_more") { auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::one_or_more); - SUBCASE("...for arguments with store true action") - { - parser.add_argument("-a").action(argparse::store_true); - parser.add_argument("-b").action(argparse::store_true); + CHECK_THROWS_WITH_AS(parser.parse_args(3, cstr_arr{"prog", "-o", "--"}), "argument -o: expected at least one argument", argparse::parsing_error); +} - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-ab"})); - } +TEST_CASE("An optional argument does not consume arguments past the -- pseudo argument for argument with nargs set as zero_or_more and followed by a positional argument") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-o").nargs(argparse::zero_or_more); + parser.add_argument("pos"); - SUBCASE("...for arguments with store false action") - { - parser.add_argument("-a").action(argparse::store_false); - parser.add_argument("-b").action(argparse::store_false); + auto args = parser.parse_args(4, cstr_arr{"prog", "-o", "--", "val"}); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-ab"})); - } + CHECK(args.get_value>("o") == std::vector()); + CHECK(args.get_value("pos") == "val"); +} - SUBCASE("...for arguments with store const action") - { - parser.add_argument("-a").action(argparse::store_const).const_(10); - parser.add_argument("-b").action(argparse::store_const).const_(20); +TEST_CASE("Parsing joined short options does not throw for arguments with store true action") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-a").action(argparse::store_true); + parser.add_argument("-b").action(argparse::store_true); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-ab"})); - } + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-ab"})); +} + +TEST_CASE("Parsing joined short options does not throw for arguments with store false action") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-a").action(argparse::store_false); + parser.add_argument("-b").action(argparse::store_false); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-ab"})); +} + +TEST_CASE("Parsing joined short options does not throw for arguments with store const action") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + parser.add_argument("-a").action(argparse::store_const).const_(10); + parser.add_argument("-b").action(argparse::store_const).const_(20); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-ab"})); } TEST_CASE("Parsing joined short options with store true action yields true for each of them") @@ -3934,29 +4370,26 @@ TEST_CASE("Parsing long option with joined argument yields its value") CHECK(args.get_value("long") == "value"); } -TEST_CASE("Parsing long options with same prefix correctly recognises them") +TEST_CASE("Parsing long options with same prefix correctly recognises them plane options") { auto parser = argparse::ArgumentParser(); + parser.add_argument("--same").action(argparse::store_true); + parser.add_argument("--same-prefix").action(argparse::store_true); - SUBCASE("plane options") - { - parser.add_argument("--same").action(argparse::store_true); - parser.add_argument("--same-prefix").action(argparse::store_true); - - auto args = parser.parse_args(2, cstr_arr{"prog", "--same-prefix"}); + auto args = parser.parse_args(2, cstr_arr{"prog", "--same-prefix"}); - CHECK(args.get_value("same") == false); - } + CHECK(args.get_value("same") == false); +} - SUBCASE("options with joined argument") - { - parser.add_argument("--same"); - parser.add_argument("--same-prefix"); +TEST_CASE("Parsing long options with same prefix correctly recognises them options with joined argument") +{ + auto parser = argparse::ArgumentParser(); + parser.add_argument("--same"); + parser.add_argument("--same-prefix"); - auto args = parser.parse_args(2, cstr_arr{"prog", "--same-prefix=value"}); + auto args = parser.parse_args(2, cstr_arr{"prog", "--same-prefix=value"}); - CHECK(!args.get("same")); - } + CHECK(!args.get("same")); } TEST_CASE("Parsing short option with joined argument does not throw") @@ -3977,52 +4410,46 @@ TEST_CASE("Parsing short option with joined argument yields its value") CHECK(args.get_value("o") == "value"); } -TEST_CASE("Parsing joined short options and short option joined with argument does not throw") +TEST_CASE("Parsing joined short options and short option joined with argument does not throw order ao") { auto parser = argparse::ArgumentParser(); + parser.add_argument("-a").action(argparse::store_true); + parser.add_argument("-o"); - SUBCASE("order ao") - { - parser.add_argument("-a").action(argparse::store_true); - parser.add_argument("-o"); - - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-aovalue"})); - } + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-aovalue"})); +} - SUBCASE("order oa") - { - parser.add_argument("-o"); - parser.add_argument("-a").action(argparse::store_true); +TEST_CASE("Parsing joined short options and short option joined with argument does not throw order oa") +{ + auto parser = argparse::ArgumentParser(); + parser.add_argument("-o"); + parser.add_argument("-a").action(argparse::store_true); - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-aovalue"})); - } + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-aovalue"})); } -TEST_CASE("Parsing joined short options and short option joined with argument yields their values") +TEST_CASE("Parsing joined short options and short option joined with argument yields their values order ao") { auto parser = argparse::ArgumentParser(); + parser.add_argument("-a").action(argparse::store_true); + parser.add_argument("-o"); - SUBCASE("order ao") - { - parser.add_argument("-a").action(argparse::store_true); - parser.add_argument("-o"); - - auto args = parser.parse_args(2, cstr_arr{"prog", "-aovalue"}); + auto args = parser.parse_args(2, cstr_arr{"prog", "-aovalue"}); - CHECK(args.get_value("a") == true); - CHECK(args.get_value("o") == "value"); - } + CHECK(args.get_value("a") == true); + CHECK(args.get_value("o") == "value"); +} - SUBCASE("order oa") - { - parser.add_argument("-o"); - parser.add_argument("-a").action(argparse::store_true); +TEST_CASE("Parsing joined short options and short option joined with argument yields their values order oa") +{ + auto parser = argparse::ArgumentParser(); + parser.add_argument("-o"); + parser.add_argument("-a").action(argparse::store_true); - auto args = parser.parse_args(2, cstr_arr{"prog", "-aovalue"}); + auto args = parser.parse_args(2, cstr_arr{"prog", "-aovalue"}); - CHECK(args.get_value("a") == true); - CHECK(args.get_value("o") == "value"); - } + CHECK(args.get_value("a") == true); + CHECK(args.get_value("o") == "value"); } TEST_CASE("Parsing long options does not affect short options") diff --git a/test/unittest/test_parsing_mutually_exclusive_group.cpp b/test/unittest/test_parsing_mutually_exclusive_group.cpp index 799f4e01..d2f4d142 100644 --- a/test/unittest/test_parsing_mutually_exclusive_group.cpp +++ b/test/unittest/test_parsing_mutually_exclusive_group.cpp @@ -22,14 +22,17 @@ TEST_CASE("Parsing mutually exclusive group of arguments with store action does group.add_argument("-a"); group.add_argument("-b"); - SUBCASE("") - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-a", "a"})); - } - SUBCASE("") - { - CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-b", "b"})); - } + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-a", "a"})); +} + +TEST_CASE("Parsing mutually exclusive group of arguments with store action does not throw for a single argument") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + auto group = parser.add_mutually_exclusive_group(); + group.add_argument("-a"); + group.add_argument("-b"); + + CHECK_NOTHROW(parser.parse_args(3, cstr_arr{"prog", "-b", "b"})); } TEST_CASE("Parsing mutually exclusive group of arguments with store action does not throw for arguments in separate groups") @@ -71,14 +74,17 @@ TEST_CASE("Parsing mutually exclusive group of arguments with store true action group.add_argument("-a").action(argparse::store_true); group.add_argument("-b").action(argparse::store_true); - SUBCASE("") - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-a"})); - } - SUBCASE("") - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-b"})); - } + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-a"})); +} + +TEST_CASE("Parsing mutually exclusive group of arguments with store true action does not throw for a single argument") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + auto group = parser.add_mutually_exclusive_group(); + group.add_argument("-a").action(argparse::store_true); + group.add_argument("-b").action(argparse::store_true); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-b"})); } TEST_CASE("Parsing mutually exclusive group of arguments with store true action does not throw for arguments in separate groups") @@ -120,14 +126,17 @@ TEST_CASE("Parsing mutually exclusive group of arguments with store false action group.add_argument("-a").action(argparse::store_false); group.add_argument("-b").action(argparse::store_false); - SUBCASE("") - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-a"})); - } - SUBCASE("") - { - CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-b"})); - } + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-a"})); +} + +TEST_CASE("Parsing mutually exclusive group of arguments with store false action does not throw for a single argument") +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::none); + auto group = parser.add_mutually_exclusive_group(); + group.add_argument("-a").action(argparse::store_false); + group.add_argument("-b").action(argparse::store_false); + + CHECK_NOTHROW(parser.parse_args(2, cstr_arr{"prog", "-b"})); } TEST_CASE("Parsing mutually exclusive group of arguments with store false action does not throw for arguments in separate groups") diff --git a/test/unittest/test_usage_message.cpp b/test/unittest/test_usage_message.cpp index 73f2ed1d..01669815 100644 --- a/test/unittest/test_usage_message.cpp +++ b/test/unittest/test_usage_message.cpp @@ -7,524 +7,557 @@ using namespace std::string_literals; -TEST_CASE("ArgumentParser provides usage message...") +TEST_CASE("ArgumentParser provides usage message with prog name") { auto parser = argparse::ArgumentParser().prog("prog").add_help(false); - SUBCASE("...with prog name") - { - CHECK(parser.format_usage() == "usage: prog"s); - } + CHECK(parser.format_usage() == "usage: prog"s); +} - SUBCASE("...with prog name and list of positional arguments for one positional argument") - { - parser.add_argument("p1"); +TEST_CASE("ArgumentParser provides usage message with prog name and list of positional arguments for one positional argument") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1"); - CHECK(parser.format_usage() == "usage: prog p1"s); - } + CHECK(parser.format_usage() == "usage: prog p1"s); +} - SUBCASE("...with prog name and list of positional arguments for two positional arguments") - { - parser.add_argument("p1"); - parser.add_argument("p2"); +TEST_CASE("ArgumentParser provides usage message with prog name and list of positional arguments for two positional arguments") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1"); + parser.add_argument("p2"); - CHECK(parser.format_usage() == "usage: prog p1 p2"s); - } + CHECK(parser.format_usage() == "usage: prog p1 p2"s); +} - SUBCASE("...with prog name and list of positional arguments for three positional arguments") - { - parser.add_argument("p1"); - parser.add_argument("p2"); - parser.add_argument("p3"); +TEST_CASE("ArgumentParser provides usage message with prog name and list of positional arguments for three positional arguments") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1"); + parser.add_argument("p2"); + parser.add_argument("p3"); - CHECK(parser.format_usage() == "usage: prog p1 p2 p3"s); - } + CHECK(parser.format_usage() == "usage: prog p1 p2 p3"s); +} - SUBCASE("...with prog name and list of optional arguments for one optional argument") - { - parser.add_argument("-o"); +TEST_CASE("ArgumentParser provides usage message with prog name and list of optional arguments for one optional argument") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o"); - CHECK(parser.format_usage() == "usage: prog [-o O]"s); - } + CHECK(parser.format_usage() == "usage: prog [-o O]"s); +} - SUBCASE("...with prog name and list of optional arguments for two optional arguments") - { - parser.add_argument("-o"); - parser.add_argument("--option"); +TEST_CASE("ArgumentParser provides usage message with prog name and list of optional arguments for two optional arguments") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o"); + parser.add_argument("--option"); - CHECK(parser.format_usage() == "usage: prog [-o O] [--option OPTION]"s); - } + CHECK(parser.format_usage() == "usage: prog [-o O] [--option OPTION]"s); +} - SUBCASE("...with prog name and list of optional arguments for three optional arguments") - { - parser.add_argument("-o"); - parser.add_argument("--option"); - parser.add_argument("--very-long-name"); +TEST_CASE("ArgumentParser provides usage message with prog name and list of optional arguments for three optional arguments") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o"); + parser.add_argument("--option"); + parser.add_argument("--very-long-name"); - CHECK(parser.format_usage() == "usage: prog [-o O] [--option OPTION] [--very-long-name VERY_LONG_NAME]"s); - } + CHECK(parser.format_usage() == "usage: prog [-o O] [--option OPTION] [--very-long-name VERY_LONG_NAME]"s); +} - SUBCASE("...for one optional argument with short and long name") - { - parser.add_argument("-f", "--foo"); +TEST_CASE("ArgumentParser provides usage message for one optional argument with short and long name") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-f", "--foo"); - CHECK(parser.format_usage() == "usage: prog [-f FOO]"s); - } + CHECK(parser.format_usage() == "usage: prog [-f FOO]"s); +} - SUBCASE("... for one optional argument with store true action") - { - parser.add_argument("-o").action(argparse::store_true); +TEST_CASE("ArgumentParser provides usage message for one optional argument with store true action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_true); - CHECK(parser.format_usage() == "usage: prog [-o]"s); - } + CHECK(parser.format_usage() == "usage: prog [-o]"s); +} - SUBCASE("...for two optional arguments with store true action") - { - parser.add_argument("-o").action(argparse::store_true); - parser.add_argument("--option").action(argparse::store_true); +TEST_CASE("ArgumentParser provides usage message for two optional arguments with store true action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_true); + parser.add_argument("--option").action(argparse::store_true); + + CHECK(parser.format_usage() == "usage: prog [-o] [--option]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o] [--option]"s); - } +TEST_CASE("ArgumentParser provides usage message for one optional argument with store false action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_false); - SUBCASE("...for one optional argument with store false action") - { - parser.add_argument("-o").action(argparse::store_false); + CHECK(parser.format_usage() == "usage: prog [-o]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o]"s); - } +TEST_CASE("ArgumentParser provides usage message for two optional arguments with store false action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_false); + parser.add_argument("--option").action(argparse::store_false); - SUBCASE("...for two optional arguments with store false action") - { - parser.add_argument("-o").action(argparse::store_false); - parser.add_argument("--option").action(argparse::store_false); + CHECK(parser.format_usage() == "usage: prog [-o] [--option]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o] [--option]"s); - } +TEST_CASE("ArgumentParser provides usage message for one optional argument with store const action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_const); - SUBCASE("...for one optional argument with store const action") - { - parser.add_argument("-o").action(argparse::store_const); + CHECK(parser.format_usage() == "usage: prog [-o]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o]"s); - } +TEST_CASE("ArgumentParser provides usage message for one optional argument with help action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-h").action(argparse::help); - SUBCASE("...for one optional argument with help action") - { - parser.add_argument("-h").action(argparse::help); + CHECK(parser.format_usage() == "usage: prog [-h]"s); +} - CHECK(parser.format_usage() == "usage: prog [-h]"s); - } +TEST_CASE("ArgumentParser provides usage message for one positional and one optional argument") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1"); + parser.add_argument("-o"); - SUBCASE("...for one positional and one optional argument") - { - parser.add_argument("p1"); - parser.add_argument("-o"); + CHECK(parser.format_usage() == "usage: prog [-o O] p1"s); +} - CHECK(parser.format_usage() == "usage: prog [-o O] p1"s); - } +TEST_CASE("ArgumentParser provides usage message for three positional and three optional arguments") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1"); + parser.add_argument("-o"); + parser.add_argument("p2"); + parser.add_argument("-a"); + parser.add_argument("p3"); + parser.add_argument("-z"); + + CHECK(parser.format_usage() == "usage: prog [-o O] [-a A] [-z Z] p1 p2 p3"s); +} - SUBCASE("...for three positional and three optional arguments") - { - parser.add_argument("p1"); - parser.add_argument("-o"); - parser.add_argument("p2"); - parser.add_argument("-a"); - parser.add_argument("p3"); - parser.add_argument("-z"); +TEST_CASE("Usage message contains for positional argument its name") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1"); - CHECK(parser.format_usage() == "usage: prog [-o O] [-a A] [-z Z] p1 p2 p3"s); - } + CHECK(parser.format_usage() == "usage: prog p1"s); } -TEST_CASE("Usage message contains...") +TEST_CASE("Usage message contains for positional argument metavar for argument with metavar set") { auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").metavar("metap1"); - SUBCASE("...for positional argument...") - { - SUBCASE("...its name") - { - parser.add_argument("p1"); + CHECK(parser.format_usage() == "usage: prog metap1"s); +} - CHECK(parser.format_usage() == "usage: prog p1"s); - } +TEST_CASE("Usage message contains for positional argument choices for argument with choices set") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}); - SUBCASE("...metavar for argument with metavar set") - { - parser.add_argument("p1").metavar("metap1"); + CHECK(parser.format_usage() == "usage: prog {\"foo\",\"bar\"}"s); +} - CHECK(parser.format_usage() == "usage: prog metap1"s); - } +TEST_CASE("Usage message contains for positional argument its name repeated N times for argument with nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").nargs(1); - SUBCASE("...choices for argument with choices set") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}); + CHECK(parser.format_usage() == "usage: prog p1"s); +} - CHECK(parser.format_usage() == "usage: prog {\"foo\",\"bar\"}"s); - } +TEST_CASE("Usage message contains for positional argument its name repeated N times for argument with nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").nargs(2); - SUBCASE("...its name repeated N times for argument with nargs set as number...") - { - SUBCASE("...1") - { - parser.add_argument("p1").nargs(1); + CHECK(parser.format_usage() == "usage: prog p1 p1"s); +} - CHECK(parser.format_usage() == "usage: prog p1"s); - } +TEST_CASE("Usage message contains for positional argument its name repeated N times for argument with nargs set as number 3") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").nargs(3); - SUBCASE("...2") - { - parser.add_argument("p1").nargs(2); + CHECK(parser.format_usage() == "usage: prog p1 p1 p1"s); +} - CHECK(parser.format_usage() == "usage: prog p1 p1"s); - } +TEST_CASE("Usage message contains for positional argument choices repeated N times for argument with choices set and nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(1); - SUBCASE("...3") - { - parser.add_argument("p1").nargs(3); + CHECK(parser.format_usage() == "usage: prog {\"foo\",\"bar\"}"s); +} - CHECK(parser.format_usage() == "usage: prog p1 p1 p1"s); - } - } +TEST_CASE("Usage message contains for positional argument choices repeated N times for argument with choices set and nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(2); - SUBCASE("...choices repeated N times for argument with choices set and nargs set as number...") - { - SUBCASE("...1") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(1); + CHECK(parser.format_usage() == "usage: prog {\"foo\",\"bar\"} {\"foo\",\"bar\"}"s); +} - CHECK(parser.format_usage() == "usage: prog {\"foo\",\"bar\"}"s); - } +TEST_CASE("Usage message contains for positional argument choices repeated N times for argument with choices set and nargs set as number 3") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(3); - SUBCASE("...2") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(2); + CHECK(parser.format_usage() == "usage: prog {\"foo\",\"bar\"} {\"foo\",\"bar\"} {\"foo\",\"bar\"}"s); +} - CHECK(parser.format_usage() == "usage: prog {\"foo\",\"bar\"} {\"foo\",\"bar\"}"s); - } +TEST_CASE("Usage message contains for positional argument its name in brackets for argument with nargs set as zero_or_one") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").nargs(argparse::zero_or_one); - SUBCASE("...3") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(3); + CHECK(parser.format_usage() == "usage: prog [p1]"s); +} - CHECK(parser.format_usage() == "usage: prog {\"foo\",\"bar\"} {\"foo\",\"bar\"} {\"foo\",\"bar\"}"s); - } - } +TEST_CASE("Usage message contains for positional argument choices in brackets for argument with choices set and nargs set as zero_or_one") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one); - SUBCASE("...its name in brackets for argument with nargs set as zero_or_one") - { - parser.add_argument("p1").nargs(argparse::zero_or_one); + CHECK(parser.format_usage() == "usage: prog [{\"foo\",\"bar\"}]"s); +} - CHECK(parser.format_usage() == "usage: prog [p1]"s); - } +TEST_CASE("Usage message contains for positional argument its name in brackets followed by its name and ellipsis in brackets for argument with nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").nargs(argparse::zero_or_more); - SUBCASE("...choices in brackets for argument with choices set and nargs set as zero_or_one") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one); + CHECK(parser.format_usage() == "usage: prog [p1 [p1 ...]]"s); +} - CHECK(parser.format_usage() == "usage: prog [{\"foo\",\"bar\"}]"s); - } +TEST_CASE("Usage message contains for positional argument choices in brackets followed by choices and ellipsis in brackets for argument with choices set and nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more); - SUBCASE("...its name in brackets followed by its name and ellipsis in brackets for argument with nargs set as zero_or_more") - { - parser.add_argument("p1").nargs(argparse::zero_or_more); + CHECK(parser.format_usage() == "usage: prog [{\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]"s); +} - CHECK(parser.format_usage() == "usage: prog [p1 [p1 ...]]"s); - } +TEST_CASE("Usage message contains for positional argument its name followed by its name and ellipsis in brackets for argument with nargs set as one_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").nargs(argparse::one_or_more); - SUBCASE("...choices in brackets followed by choices and ellipsis in brackets for argument with choices set and nargs set as zero_or_more") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more); + CHECK(parser.format_usage() == "usage: prog p1 [p1 ...]"s); +} - CHECK(parser.format_usage() == "usage: prog [{\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]"s); - } +TEST_CASE("Usage message contains for positional argument choices followed by choices and ellipsis in brackets for argument with choices set and nargs set as one_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more); - SUBCASE("...its name followed by its name and ellipsis in brackets for argument with nargs set as one_or_more") - { - parser.add_argument("p1").nargs(argparse::one_or_more); + CHECK(parser.format_usage() == "usage: prog {\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]"s); +} - CHECK(parser.format_usage() == "usage: prog p1 [p1 ...]"s); - } +TEST_CASE("Usage message contains for optional argument name for argument with store true action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_true); - SUBCASE("...choices followed by choices and ellipsis in brackets for argument with choices set and nargs set as one_or_more") - { - parser.add_argument("p1").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more); + CHECK(parser.format_usage() == "usage: prog [-o]"s); +} - CHECK(parser.format_usage() == "usage: prog {\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]"s); - } - } +TEST_CASE("Usage message contains for optional argument name for argument with store false action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_false); - SUBCASE("...for optional argument...") - { - SUBCASE("...name for argument with store true action") - { - parser.add_argument("-o").action(argparse::store_true); + CHECK(parser.format_usage() == "usage: prog [-o]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o]"s); - } +TEST_CASE("Usage message contains for optional argument name for argument with store const action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").action(argparse::store_const); - SUBCASE("...name for argument with store false action") - { - parser.add_argument("-o").action(argparse::store_false); + CHECK(parser.format_usage() == "usage: prog [-o]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o]"s); - } +TEST_CASE("Usage message contains for optional argument name for argument with help action") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-h").action(argparse::store_false); - SUBCASE("...name for argument with store const action") - { - parser.add_argument("-o").action(argparse::store_const); + CHECK(parser.format_usage() == "usage: prog [-h]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o]"s); - } +TEST_CASE("Usage message contains for optional argument name and automatic metavar") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o"); - SUBCASE("...name for argument with help action") - { - parser.add_argument("-h").action(argparse::store_false); + CHECK(parser.format_usage() == "usage: prog [-o O]"s); +} - CHECK(parser.format_usage() == "usage: prog [-h]"s); - } +TEST_CASE("Usage message contains for optional argument name and metavar for argument with metavar set") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO"); - SUBCASE("...name and automatic metavar") - { - parser.add_argument("-o"); + CHECK(parser.format_usage() == "usage: prog [-o METAVARO]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o O]"s); - } +TEST_CASE("Usage message contains for optional argument no brackets for argument with required true and automatic metavar") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").required(true); - SUBCASE("...name and metavar for argument with metavar set") - { - parser.add_argument("-o").metavar("METAVARO"); + CHECK(parser.format_usage() == "usage: prog -o O"s); +} - CHECK(parser.format_usage() == "usage: prog [-o METAVARO]"s); - } +TEST_CASE("Usage message contains for optional argument no brackets for argument with required true and metavar") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").required(true); - SUBCASE("...no brackets for argument with required true...") - { - SUBCASE("...and automatic metavar") - { - parser.add_argument("-o").required(true); + CHECK(parser.format_usage() == "usage: prog -o METAVARO"s); +} - CHECK(parser.format_usage() == "usage: prog -o O"s); - } +TEST_CASE("Usage message contains for optional argument no brackets for argument with required true and choices") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).required(true); - SUBCASE("...and metavar") - { - parser.add_argument("-o").metavar("METAVARO").required(true); + CHECK(parser.format_usage() == "usage: prog -o {\"foo\",\"bar\"}"s); +} - CHECK(parser.format_usage() == "usage: prog -o METAVARO"s); - } +TEST_CASE("Usage message contains for optional argument no brackets for argument with required true and nargs") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(1).required(true); - SUBCASE("...and choices") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).required(true); + CHECK(parser.format_usage() == "usage: prog -o O"s); +} - CHECK(parser.format_usage() == "usage: prog -o {\"foo\",\"bar\"}"s); - } +TEST_CASE("Usage message contains for optional argument brackets for argument with required false") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").required(false); - SUBCASE("...and nargs") - { - parser.add_argument("-o").nargs(1).required(true); + CHECK(parser.format_usage() == "usage: prog [-o O]"s); +} - CHECK(parser.format_usage() == "usage: prog -o O"s); - } - } +TEST_CASE("Usage message contains for optional argument name and choices for argument with choices set") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}); - SUBCASE("...brackets for argument with required false") - { - parser.add_argument("-o").required(false); + CHECK(parser.format_usage() == "usage: prog [-o {\"foo\",\"bar\"}]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o O]"s); - } +TEST_CASE("Usage message contains for optional argument its name and automatic metavar repeated N times for argument with nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(1); - SUBCASE("...name and choices for argument with choices set") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}); + CHECK(parser.format_usage() == "usage: prog [-o O]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o {\"foo\",\"bar\"}]"s); - } +TEST_CASE("Usage message contains for optional argument its name and automatic metavar repeated N times for argument with nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(2); - SUBCASE("...its name and automatic metavar repeated N times for argument with nargs set as number...") - { - SUBCASE("...1") - { - parser.add_argument("-o").nargs(1); + CHECK(parser.format_usage() == "usage: prog [-o O O]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o O]"s); - } +TEST_CASE("Usage message contains for optional argument its name and automatic metavar repeated N times for argument with nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(3); - SUBCASE("...2") - { - parser.add_argument("-o").nargs(2); + CHECK(parser.format_usage() == "usage: prog [-o O O O]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o O O]"s); - } +TEST_CASE("Usage message contains for optional argument its name and metavar repeated N times for argument with metavar set and nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").nargs(1); - SUBCASE("...2") - { - parser.add_argument("-o").nargs(3); + CHECK(parser.format_usage() == "usage: prog [-o METAVARO]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o O O O]"s); - } - } +TEST_CASE("Usage message contains for optional argument its name and metavar repeated N times for argument with metavar set and nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").nargs(2); - SUBCASE("...its name and metavar repeated N times for argument with metavar set and nargs set as number...") - { - SUBCASE("...1") - { - parser.add_argument("-o").metavar("METAVARO").nargs(1); + CHECK(parser.format_usage() == "usage: prog [-o METAVARO METAVARO]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o METAVARO]"s); - } +TEST_CASE("Usage message contains for optional argument its name and metavar repeated N times for argument with metavar set and nargs set as number 3") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").nargs(3); - SUBCASE("...2") - { - parser.add_argument("-o").metavar("METAVARO").nargs(2); + CHECK(parser.format_usage() == "usage: prog [-o METAVARO METAVARO METAVARO]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o METAVARO METAVARO]"s); - } +TEST_CASE("Usage message contains for optional argument its name and choices repeated N times for argument with choices set and nargs set as number 1") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(1); - SUBCASE("...3") - { - parser.add_argument("-o").metavar("METAVARO").nargs(3); + CHECK(parser.format_usage() == "usage: prog [-o {\"foo\",\"bar\"}]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o METAVARO METAVARO METAVARO]"s); - } - } +TEST_CASE("Usage message contains for optional argument its name and choices repeated N times for argument with choices set and nargs set as number 2") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(2); - SUBCASE("...its name and choices repeated N times for argument with choices set and nargs set as number...") - { - SUBCASE("...1") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(1); + CHECK(parser.format_usage() == "usage: prog [-o {\"foo\",\"bar\"} {\"foo\",\"bar\"}]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o {\"foo\",\"bar\"}]"s); - } +TEST_CASE("Usage message contains for optional argument its name and choices repeated N times for argument with choices set and nargs set as number 3") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(3); - SUBCASE("...2") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(2); + CHECK(parser.format_usage() == "usage: prog [-o {\"foo\",\"bar\"} {\"foo\",\"bar\"} {\"foo\",\"bar\"}]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o {\"foo\",\"bar\"} {\"foo\",\"bar\"}]"s); - } +TEST_CASE("Usage message contains for optional argument is name and automatic metavar in brackets for argument with nargs set as zero_or_one") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(argparse::zero_or_one); - SUBCASE("...3") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(3); + CHECK(parser.format_usage() == "usage: prog [-o [O]]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o {\"foo\",\"bar\"} {\"foo\",\"bar\"} {\"foo\",\"bar\"}]"s); - } - } +TEST_CASE("Usage message contains for optional argument is name and metavar in brackets for argument with metavar set and nargs set as zero_or_one") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").nargs(argparse::zero_or_one); - SUBCASE("...is name and automatic metavar in brackets for argument with nargs set as zero_or_one") - { - parser.add_argument("-o").nargs(argparse::zero_or_one); + CHECK(parser.format_usage() == "usage: prog [-o [METAVARO]]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o [O]]"s); - } +TEST_CASE("Usage message contains for optional argument is name and choices in brackets for argument with choices set and nargs set as zero_or_one") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one); - SUBCASE("...is name and metavar in brackets for argument with metavar set and nargs set as zero_or_one") - { - parser.add_argument("-o").metavar("METAVARO").nargs(argparse::zero_or_one); + CHECK(parser.format_usage() == "usage: prog [-o [{\"foo\",\"bar\"}]]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o [METAVARO]]"s); - } +TEST_CASE("Usage message contains for optional argument its name followed by automatic metavar in brackets and automatic metavar and ellipsis in nested brackets for arguments with nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(argparse::zero_or_more); - SUBCASE("...is name and choices in brackets for argument with choices set and nargs set as zero_or_one") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_one); + CHECK(parser.format_usage() == "usage: prog [-o [O [O ...]]]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o [{\"foo\",\"bar\"}]]"s); - } +TEST_CASE("Usage message contains for optional argument its name followed by metavar in brackets and metavar and ellipsis in nested brackets for arguments with metavar set and nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").nargs(argparse::zero_or_more); - SUBCASE("...its name followed by automatic metavar in brackets and automatic metavar and ellipsis in nested brackets for arguments with nargs set as zero_or_more") - { - parser.add_argument("-o").nargs(argparse::zero_or_more); + CHECK(parser.format_usage() == "usage: prog [-o [METAVARO [METAVARO ...]]]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o [O [O ...]]]"s); - } +TEST_CASE("Usage message contains for optional argument its name followed by choices in brackets and choices and ellipsis in nested brackets for arguments with choices set and nargs set as zero_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more); - SUBCASE("...its name followed by metavar in brackets and metavar and ellipsis in nested brackets for arguments with metavar set and nargs set as zero_or_more") - { - parser.add_argument("-o").metavar("METAVARO").nargs(argparse::zero_or_more); + CHECK(parser.format_usage() == "usage: prog [-o [{\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o [METAVARO [METAVARO ...]]]"s); - } +TEST_CASE("Usage message contains for optional argument its name followed by automatic metavar and automatic metavar and ellipsis in brackets for arguments with nargs set as one_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").nargs(argparse::one_or_more); - SUBCASE("...its name followed by choices in brackets and choices and ellipsis in nested brackets for arguments with choices set and nargs set as zero_or_more") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::zero_or_more); + CHECK(parser.format_usage() == "usage: prog [-o O [O ...]]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o [{\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]]"s); - } +TEST_CASE("Usage message contains for optional argument its name followed by metavar and metavar and ellipsis in brackets for arguments with metavar set and nargs set as one_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").metavar("METAVARO").nargs(argparse::one_or_more); - SUBCASE("...its name followed by automatic metavar and automatic metavar and ellipsis in brackets for arguments with nargs set as one_or_more") - { - parser.add_argument("-o").nargs(argparse::one_or_more); + CHECK(parser.format_usage() == "usage: prog [-o METAVARO [METAVARO ...]]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o O [O ...]]"s); - } - - SUBCASE("...its name followed by metavar and metavar and ellipsis in brackets for arguments with metavar set and nargs set as one_or_more") - { - parser.add_argument("-o").metavar("METAVARO").nargs(argparse::one_or_more); - - CHECK(parser.format_usage() == "usage: prog [-o METAVARO [METAVARO ...]]"s); - } +TEST_CASE("Usage message contains for optional argument its name followed by choices and choices and ellipsis in brackets for arguments with choices set and nargs set as one_or_more") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more); - SUBCASE("...its name followed by choices and choices and ellipsis in brackets for arguments with choices set and nargs set as one_or_more") - { - parser.add_argument("-o").choices({"foo"s, "bar"s}).nargs(argparse::one_or_more); + CHECK(parser.format_usage() == "usage: prog [-o {\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o {\"foo\",\"bar\"} [{\"foo\",\"bar\"} ...]]"s); - } - } +TEST_CASE("Usage message contains for optional argument in mutually exclusive group its name in brackets") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + auto group = parser.add_mutually_exclusive_group(); + group.add_argument("-o"); - SUBCASE("...for optional argument in mutually exclusive group its name in brackets") - { - auto group = parser.add_mutually_exclusive_group(); - group.add_argument("-o"); - - CHECK(parser.format_usage() == "usage: prog [-o O]"s); - } + CHECK(parser.format_usage() == "usage: prog [-o O]"s); +} - SUBCASE("...for two optional arguments in same mutually exclusive group their names in brackets separated by a pipe") - { - auto group = parser.add_mutually_exclusive_group(); - group.add_argument("-o"); - group.add_argument("-a"); +TEST_CASE("Usage message contains for two optional arguments in same mutually exclusive group their names in brackets separated by a pipe") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + auto group = parser.add_mutually_exclusive_group(); + group.add_argument("-o"); + group.add_argument("-a"); - CHECK(parser.format_usage() == "usage: prog [-o O | -a A]"s); - } + CHECK(parser.format_usage() == "usage: prog [-o O | -a A]"s); +} - SUBCASE("...for three optional arguments in same mutually exclusive group their names in brackets separated by a pipe") - { - auto group = parser.add_mutually_exclusive_group(); - group.add_argument("-o"); - group.add_argument("-a"); - group.add_argument("-z"); +TEST_CASE("Usage message contains for three optional arguments in same mutually exclusive group their names in brackets separated by a pipe") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + auto group = parser.add_mutually_exclusive_group(); + group.add_argument("-o"); + group.add_argument("-a"); + group.add_argument("-z"); - CHECK(parser.format_usage() == "usage: prog [-o O | -a A | -z Z]"s); - } + CHECK(parser.format_usage() == "usage: prog [-o O | -a A | -z Z]"s); +} - SUBCASE("...for two optional arguments in separate mutually exclusive groups their names in brackets") - { - auto group1 = parser.add_mutually_exclusive_group(); - group1.add_argument("-o"); - auto group2 = parser.add_mutually_exclusive_group(); - group2.add_argument("-a"); +TEST_CASE("Usage message contains for two optional arguments in separate mutually exclusive groups their names in brackets") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + auto group1 = parser.add_mutually_exclusive_group(); + group1.add_argument("-o"); + auto group2 = parser.add_mutually_exclusive_group(); + group2.add_argument("-a"); - CHECK(parser.format_usage() == "usage: prog [-o O] [-a A]"s); - } - - SUBCASE("...for four optional arguments in separate mutually exclusive groups their names in brackets separated by a pipe") - { - auto group1 = parser.add_mutually_exclusive_group(); - group1.add_argument("-o"); - group1.add_argument("-p"); - auto group2 = parser.add_mutually_exclusive_group(); - group2.add_argument("-a"); - group2.add_argument("-b"); + CHECK(parser.format_usage() == "usage: prog [-o O] [-a A]"s); +} - CHECK(parser.format_usage() == "usage: prog [-o O | -p P] [-a A | -b B]"s); - } +TEST_CASE("Usage message contains for four optional arguments in separate mutually exclusive groups their names in brackets separated by a pipe") +{ + auto parser = argparse::ArgumentParser().prog("prog").add_help(false); + auto group1 = parser.add_mutually_exclusive_group(); + group1.add_argument("-o"); + group1.add_argument("-p"); + auto group2 = parser.add_mutually_exclusive_group(); + group2.add_argument("-a"); + group2.add_argument("-b"); + + CHECK(parser.format_usage() == "usage: prog [-o O | -p P] [-a A | -b B]"s); }