From bb115c04192d6f6028498aee43411c659629daab Mon Sep 17 00:00:00 2001 From: Yoshihiro Hokazono Date: Thu, 16 Sep 2021 06:42:29 +0900 Subject: [PATCH] Add test for variable nargs --- test/test_optional_arguments.cpp | 80 +++++++++++++++++++ test/test_positional_arguments.cpp | 124 +++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+) diff --git a/test/test_optional_arguments.cpp b/test/test_optional_arguments.cpp index d73062a..dd06d62 100644 --- a/test/test_optional_arguments.cpp +++ b/test/test_optional_arguments.cpp @@ -110,6 +110,86 @@ TEST_CASE("Parse optional arguments of many values" * } } +TEST_CASE("Parse 2 optional arguments of many values" * + test_suite("optional_arguments")) { + GIVEN("a program that accepts 2 optional arguments of many values") { + argparse::ArgumentParser program("test"); + program.add_argument("-i").nargs(argparse::NArgsPattern::ANY).scan<'i', int>(); + program.add_argument("-s").nargs(argparse::NArgsPattern::ANY); + + WHEN("provided no argument") { + THEN("the program accepts it and gets empty container") { + REQUIRE_NOTHROW(program.parse_args({"test"})); + auto i = program.get>("-i"); + REQUIRE(i.size() == 0); + + auto s = program.get>("-s"); + REQUIRE(s.size() == 0); + } + } + + WHEN("provided 2 options with many arguments") { + program.parse_args( + {"test", "-i", "-42", "8", "100", "300", "-s", "ok", "this", "works"}); + + THEN("the optional parameter consumes each arguments") { + auto i = program.get>("-i"); + REQUIRE(i.size() == 4); + REQUIRE(i[0] == -42); + REQUIRE(i[1] == 8); + REQUIRE(i[2] == 100); + REQUIRE(i[3] == 300); + + auto s = program.get>("-s"); + REQUIRE(s.size() == 3); + REQUIRE(s[0] == "ok"); + REQUIRE(s[1] == "this"); + REQUIRE(s[2] == "works"); + } + } + } +} + +TEST_CASE("Parse an optional argument of many values" + " and a positional argument of many values" * + test_suite("optional_arguments")) { + GIVEN("a program that accepts an optional argument of many values" + " and a positional argument of many values") { + argparse::ArgumentParser program("test"); + program.add_argument("-s").nargs(argparse::NArgsPattern::ANY); + program.add_argument("input").nargs(argparse::NArgsPattern::ANY); + + WHEN("provided no argument") { + program.parse_args({"test"}); + THEN("the program accepts it and gets empty containers") { + auto s = program.get>("-s"); + REQUIRE(s.size() == 0); + + auto input = program.get>("input"); + REQUIRE(input.size() == 0); + } + } + + WHEN("provided many arguments followed by an option with many arguments") { + program.parse_args( + {"test", "foo", "bar", "-s", "ok", "this", "works"}); + + THEN("the parameters consume each arguments") { + auto s = program.get>("-s"); + REQUIRE(s.size() == 3); + REQUIRE(s[0] == "ok"); + REQUIRE(s[1] == "this"); + REQUIRE(s[2] == "works"); + + auto input = program.get>("input"); + REQUIRE(input.size() == 2); + REQUIRE(input[0] == "foo"); + REQUIRE(input[1] == "bar"); + } + } + } +} + TEST_CASE("Parse arguments of different types" * test_suite("optional_arguments")) { using namespace std::literals; diff --git a/test/test_positional_arguments.cpp b/test/test_positional_arguments.cpp index d0d850f..5c68d6e 100644 --- a/test/test_positional_arguments.cpp +++ b/test/test_positional_arguments.cpp @@ -61,6 +61,130 @@ TEST_CASE("Parse positional arguments with optional arguments in the middle" * REQUIRE_THROWS(program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv", "--num_iterations", "15", "output.mesh" })); } +TEST_CASE("Parse positional nargs=1..2 arguments" * + test_suite("positional_arguments")) { + GIVEN("a program that accepts an optional argument and nargs=1..2 positional arguments") { + argparse::ArgumentParser program("test"); + program.add_argument("-o"); + program.add_argument("input").nargs(1, 2); + + WHEN("provided no argument") { + THEN("the program does not accept it") { + REQUIRE_THROWS(program.parse_args({"test"})); + } + } + + WHEN("provided 1 argument") { + THEN("the program accepts it") { + REQUIRE_NOTHROW(program.parse_args({"test", "a.c"})); + + auto inputs = program.get>("input"); + REQUIRE(inputs.size() == 1); + REQUIRE(inputs[0] == "a.c"); + } + } + + WHEN("provided 2 arguments") { + THEN("the program accepts it") { + REQUIRE_NOTHROW(program.parse_args({"test", "a.c", "b.c"})); + + auto inputs = program.get>("input"); + REQUIRE(inputs.size() == 2); + REQUIRE(inputs[0] == "a.c"); + REQUIRE(inputs[1] == "b.c"); + } + } + + WHEN("provided 3 arguments") { + THEN("the program does not accept it") { + REQUIRE_THROWS(program.parse_args({"test", "a.c", "b.c", "main.c"})); + } + } + + WHEN("provided an optional followed by positional arguments") { + program.parse_args({"test", "-o", "a.out", "a.c", "b.c"}); + + THEN("the optional parameter consumes an argument") { + using namespace std::literals; + REQUIRE(program["-o"] == "a.out"s); + + auto inputs = program.get>("input"); + REQUIRE(inputs.size() == 2); + REQUIRE(inputs[0] == "a.c"); + REQUIRE(inputs[1] == "b.c"); + } + } + + WHEN("provided an optional preceded by positional arguments") { + program.parse_args({"test", "a.c", "b.c", "-o", "a.out"}); + + THEN("the optional parameter consumes an argument") { + using namespace std::literals; + REQUIRE(program["-o"] == "a.out"s); + + auto inputs = program.get>("input"); + REQUIRE(inputs.size() == 2); + REQUIRE(inputs[0] == "a.c"); + REQUIRE(inputs[1] == "b.c"); + } + } + + WHEN("provided an optional in between positional arguments") { + THEN("the program does not accept it") { + REQUIRE_THROWS(program.parse_args({"test", "a.c", "-o", "a.out", "b.c"})); + } + } + } +} + +TEST_CASE("Parse positional nargs=ANY arguments" * + test_suite("positional_arguments")) { + GIVEN("a program that accepts an optional argument and nargs=ANY positional arguments") { + argparse::ArgumentParser program("test"); + program.add_argument("-o"); + program.add_argument("input").nargs(argparse::NArgsPattern::ANY); + + WHEN("provided no argument") { + THEN("the program accepts it and gets empty container") { + REQUIRE_NOTHROW(program.parse_args({"test"})); + + auto inputs = program.get>("input"); + REQUIRE(inputs.size() == 0); + } + } + + WHEN("provided an optional followed by positional arguments") { + program.parse_args({"test", "-o", "a.out", "a.c", "b.c", "main.c"}); + + THEN("the optional parameter consumes an argument") { + using namespace std::literals; + REQUIRE(program["-o"] == "a.out"s); + + auto inputs = program.get>("input"); + REQUIRE(inputs.size() == 3); + REQUIRE(inputs[0] == "a.c"); + REQUIRE(inputs[1] == "b.c"); + REQUIRE(inputs[2] == "main.c"); + } + } + + WHEN("provided an optional preceded by positional arguments") { + program.parse_args({"test", "a.c", "b.c", "main.c", "-o", "a.out"}); + + THEN("the optional parameter consumes an argument") { + using namespace std::literals; + REQUIRE(program["-o"] == "a.out"s); + + auto inputs = program.get>("input"); + REQUIRE(inputs.size() == 3); + REQUIRE(inputs[0] == "a.c"); + REQUIRE(inputs[1] == "b.c"); + REQUIRE(inputs[2] == "main.c"); + } + } + } +} + TEST_CASE("Parse remaining arguments deemed positional" * test_suite("positional_arguments")) { GIVEN("a program that accepts an optional argument and remaining arguments") {