mirror of
https://git.lynn.is/Gwen/argparser.git
synced 2024-04-29 10:23:45 +02:00
566 lines
20 KiB
C++
566 lines
20 KiB
C++
#include "argparser/argparser.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
// TODO: test whitespace in tuples and arrays
|
|
// TODO: test empty values for everything
|
|
// TODO: test option->has(result), flag->has(result) and arg->has(result)
|
|
// TODO: test enum types and commas
|
|
// TODO: fuzz testing (blocked on clang 16 being available on arch)
|
|
|
|
class Parser : public ::testing::Test {
|
|
|
|
protected:
|
|
argparser::parser p{};
|
|
argparser::type_handle_impl<uint32_t> uintType;
|
|
|
|
Parser() = default;
|
|
|
|
~Parser() override = default;
|
|
|
|
void SetUp() override {
|
|
uintType = p.basic_type<uint32_t>("uint");
|
|
}
|
|
|
|
void TearDown() override {
|
|
}
|
|
};
|
|
|
|
TEST_F(Parser, SingleOption) {
|
|
auto fooOption = p.option("--foo", uintType);
|
|
auto parsed = p.parse({"--foo", "123"});
|
|
auto foo = fooOption->get(parsed);
|
|
EXPECT_EQ(foo, 123);
|
|
}
|
|
|
|
TEST_F(Parser, OptionWithEqualsSign) {
|
|
auto fooOption = p.option("--foo", uintType);
|
|
auto parsed = p.parse({"--foo=123"});
|
|
auto foo = fooOption->get(parsed);
|
|
EXPECT_EQ(foo, 123);
|
|
}
|
|
|
|
TEST_F(Parser, MultipleOptions) {
|
|
auto fooOption = p.option("--foo", uintType);
|
|
auto barOption = p.option("--bar", uintType);
|
|
auto parsed = p.parse({"--foo", "234", "--bar", "345"});
|
|
auto foo = fooOption->get(parsed);
|
|
auto bar = barOption->get(parsed);
|
|
EXPECT_EQ(foo, 234);
|
|
EXPECT_EQ(bar, 345);
|
|
}
|
|
|
|
TEST_F(Parser, MultipleOptionsDifferentOrder) {
|
|
auto fooOption = p.option("--foo", uintType);
|
|
auto barOption = p.option("--bar", uintType);
|
|
auto parsed = p.parse({"--bar", "345", "--foo", "234"});
|
|
auto foo = fooOption->get(parsed);
|
|
auto bar = barOption->get(parsed);
|
|
EXPECT_EQ(foo, 234);
|
|
EXPECT_EQ(bar, 345);
|
|
}
|
|
|
|
TEST_F(Parser, OptionsAreNotRequiredByDefault) {
|
|
auto fooOption = p.option("--foo", uintType);
|
|
auto barOption = p.option("--bar", uintType);
|
|
auto parsed = p.parse({"--foo", "234"});
|
|
auto foo = fooOption->get(parsed);
|
|
auto has_bar = barOption->has(parsed);
|
|
EXPECT_EQ(foo, 234);
|
|
EXPECT_EQ(has_bar, false);
|
|
}
|
|
|
|
TEST_F(Parser, RequiredOption) {
|
|
auto _1 = p.option("--foo", uintType);
|
|
[[maybe_unused]] auto _2 = p.option("--bar", uintType)->required();
|
|
EXPECT_THROW(auto _3 = p.parse({"--foo", "234"});, argparser::errors::missing_option_error);
|
|
}
|
|
|
|
TEST_F(Parser, MissingValue) {
|
|
auto _1 = p.option("--foo", uintType);
|
|
EXPECT_THROW(auto _2 = p.parse({"--foo"});, argparser::errors::missing_option_value_error);
|
|
}
|
|
|
|
TEST_F(Parser, MissingValueWithNextOption) {
|
|
auto _1 = p.option("--foo", uintType);
|
|
auto _2 = p.option("--bar", uintType);
|
|
EXPECT_THROW(auto _3 = p.parse({"--foo", "--bar", "123"});, argparser::errors::missing_option_value_error);
|
|
}
|
|
|
|
TEST_F(Parser, InvalidValue) {
|
|
auto _1 = p.option("--foo", uintType);
|
|
EXPECT_THROW(auto _2 = p.parse({"--foo", "-12"});, argparser::errors::type_parsing_error);
|
|
}
|
|
|
|
TEST_F(Parser, InvalidEmptyValue) {
|
|
auto _1 = p.option("--foo", uintType);
|
|
EXPECT_THROW(auto _2 = p.parse({"--foo", ""});, argparser::errors::type_parsing_error);
|
|
}
|
|
|
|
TEST_F(Parser, OptionPassedMultipleTimesReturnsLastValue) {
|
|
auto fooOption = p.option("--foo", uintType);
|
|
auto parsed = p.parse({"--foo", "23", "--foo", "45"});
|
|
EXPECT_EQ(fooOption->get(parsed), 45);
|
|
}
|
|
|
|
TEST_F(Parser, OptionNameMustStartWithTwoDashes) {
|
|
EXPECT_THROW(auto _1 = p.option("foo", uintType);, argparser::errors::invalid_option_name_error);
|
|
}
|
|
|
|
TEST_F(Parser, DefaultValue) {
|
|
auto fooOption = p.option("--foo", uintType)->default_value(123);
|
|
auto parsed = p.parse({});
|
|
EXPECT_EQ(fooOption->get(parsed), 123);
|
|
EXPECT_EQ(fooOption->has(parsed), false);
|
|
}
|
|
|
|
TEST_F(Parser, RepeatableOption) {
|
|
auto fooOption = p.repeatable_option("--foo", uintType);
|
|
auto parsed = p.parse({"--foo", "123", "--foo", "234"});
|
|
auto foo = fooOption->get(parsed);
|
|
EXPECT_EQ(foo.size(), 2);
|
|
EXPECT_EQ(foo[0], 123);
|
|
EXPECT_EQ(foo[1], 234);
|
|
}
|
|
|
|
TEST_F(Parser, RepeatableOptionDefaultValue) {
|
|
auto fooOption = p.repeatable_option("--foo", uintType)->default_value({1, 2, 3});
|
|
auto parsed = p.parse({});
|
|
auto foo = fooOption->get(parsed);
|
|
EXPECT_EQ(foo.size(), 3);
|
|
EXPECT_EQ(foo[0], 1);
|
|
EXPECT_EQ(foo[1], 2);
|
|
EXPECT_EQ(foo[2], 3);
|
|
}
|
|
|
|
TEST_F(Parser, RepeatableOptionLimits) {
|
|
auto fooFlag = p.repeatable_option("--foo", uintType)->min(2)->max(4);
|
|
auto parsed = p.parse({"--foo", "1", "--foo", "2"});
|
|
auto val = fooFlag->get(parsed);
|
|
EXPECT_EQ(val.size(), 2);
|
|
EXPECT_EQ(val[0], 1);
|
|
EXPECT_EQ(val[1], 2);
|
|
parsed = p.parse({"--foo", "1", "--foo", "2", "--foo", "3"});
|
|
val = fooFlag->get(parsed);
|
|
EXPECT_EQ(val.size(), 3);
|
|
EXPECT_EQ(val[0], 1);
|
|
EXPECT_EQ(val[1], 2);
|
|
EXPECT_EQ(val[2], 3);
|
|
parsed = p.parse({"--foo", "1", "--foo", "2", "--foo", "3", "--foo", "4"});
|
|
val = fooFlag->get(parsed);
|
|
EXPECT_EQ(val.size(), 4);
|
|
EXPECT_EQ(val[0], 1);
|
|
EXPECT_EQ(val[1], 2);
|
|
EXPECT_EQ(val[2], 3);
|
|
EXPECT_EQ(val[3], 4);
|
|
EXPECT_THROW(auto _1 = p.parse({});, argparser::errors::wrong_option_count_error);
|
|
EXPECT_THROW(auto _2 = p.parse({"--foo", "1"});, argparser::errors::wrong_option_count_error);
|
|
EXPECT_THROW(auto _3 = p.parse({"--foo", "1", "--foo", "2", "--foo", "3", "--foo", "4", "--foo", "5"});, argparser::errors::wrong_option_count_error);
|
|
EXPECT_THROW(auto _4 = p.parse({"--foo", "1", "--foo", "2", "--foo", "3", "--foo", "4", "--foo", "5", "--foo", "6"});, argparser::errors::wrong_option_count_error);
|
|
}
|
|
|
|
TEST_F(Parser, Flag) {
|
|
auto fooFlag = p.flag("--foo");
|
|
auto parsed = p.parse({"--foo"});
|
|
EXPECT_EQ(fooFlag->get(parsed), true);
|
|
parsed = p.parse({});
|
|
EXPECT_EQ(fooFlag->get(parsed), false);
|
|
}
|
|
|
|
TEST_F(Parser, FlagInverted) {
|
|
auto fooFlag = p.flag("--foo")->invert();
|
|
auto parsed = p.parse({"--foo"});
|
|
EXPECT_EQ(fooFlag->get(parsed), false);
|
|
parsed = p.parse({});
|
|
EXPECT_EQ(fooFlag->get(parsed), true);
|
|
}
|
|
|
|
TEST_F(Parser, RepeatableFLag) {
|
|
auto fooFlag = p.repeatable_flag("--foo");
|
|
auto parsed = p.parse({});
|
|
EXPECT_EQ(fooFlag->get(parsed), 0);
|
|
parsed = p.parse({"--foo"});
|
|
EXPECT_EQ(fooFlag->get(parsed), 1);
|
|
parsed = p.parse({"--foo", "--foo", "--foo", "--foo", "--foo"});
|
|
EXPECT_EQ(fooFlag->get(parsed), 5);
|
|
}
|
|
|
|
TEST_F(Parser, RepeatableFlagLimits) {
|
|
auto fooFlag = p.repeatable_flag("--foo")->min(2)->max(4);
|
|
auto parsed = p.parse({"--foo", "--foo"});
|
|
EXPECT_EQ(fooFlag->get(parsed), 2);
|
|
parsed = p.parse({"--foo", "--foo", "--foo"});
|
|
EXPECT_EQ(fooFlag->get(parsed), 3);
|
|
parsed = p.parse({"--foo", "--foo", "--foo", "--foo"});
|
|
EXPECT_EQ(fooFlag->get(parsed), 4);
|
|
EXPECT_THROW(auto _1 = p.parse({});, argparser::errors::wrong_option_count_error);
|
|
EXPECT_THROW(auto _2 = p.parse({"--foo"});, argparser::errors::wrong_option_count_error);
|
|
EXPECT_THROW(auto _3 = p.parse({"--foo", "--foo", "--foo", "--foo", "--foo"});, argparser::errors::wrong_option_count_error);
|
|
EXPECT_THROW(auto _4 = p.parse({"--foo", "--foo", "--foo", "--foo", "--foo", "--foo"});, argparser::errors::wrong_option_count_error);
|
|
}
|
|
|
|
TEST_F(Parser, OptionAndFlagNamesMustBeUnique) {
|
|
EXPECT_THROW({
|
|
auto _1 = p.option("--optopt", uintType);
|
|
auto _2 = p.option("--optopt", uintType);
|
|
},
|
|
argparser::errors::duplicate_option_name);
|
|
EXPECT_THROW({
|
|
auto _1 = p.flag("--flagflag");
|
|
auto _2 = p.flag("--flagflag");
|
|
},
|
|
argparser::errors::duplicate_option_name);
|
|
EXPECT_THROW({
|
|
auto _1 = p.option("--optflag", uintType);
|
|
auto _2 = p.flag("--optflag");
|
|
},
|
|
argparser::errors::duplicate_option_name);
|
|
EXPECT_THROW({
|
|
auto _1 = p.option("--optrepflag", uintType);
|
|
auto _2 = p.repeatable_flag("--optrepflag");
|
|
},
|
|
argparser::errors::duplicate_option_name);
|
|
EXPECT_THROW({
|
|
auto _1 = p.flag("--flagopt");
|
|
auto _2 = p.option("--flagopt", uintType);
|
|
},
|
|
argparser::errors::duplicate_option_name);
|
|
}
|
|
|
|
TEST_F(Parser, OptionWithOnlyShortName) {
|
|
auto fooOpt = p.option("-f", uintType);
|
|
argparser::parse_result pr;
|
|
uint32_t fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f", "123"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, 123);
|
|
}
|
|
|
|
TEST_F(Parser, RepeatableOptionWithOnlyShortName) {
|
|
auto fooOpt = p.repeatable_option("-f", uintType);
|
|
argparser::parse_result pr;
|
|
std::vector<uint32_t> fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f", "123"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, (decltype(fooVal){123}));
|
|
}
|
|
|
|
TEST_F(Parser, FlagWithOnlyShortName) {
|
|
auto fooFlag = p.flag("-f");
|
|
argparser::parse_result pr;
|
|
bool fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, true);
|
|
}
|
|
|
|
TEST_F(Parser, RepeatableFlagWithOnlyShortName) {
|
|
auto fooFlag = p.flag("-f");
|
|
argparser::parse_result pr;
|
|
unsigned int fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, 1);
|
|
}
|
|
|
|
TEST_F(Parser, OptionWithLongAndShortName) {
|
|
auto fooOpt = p.option("--foo", "-f", uintType);
|
|
argparser::parse_result pr;
|
|
uint32_t fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f", "123"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, 123);
|
|
EXPECT_NO_THROW(pr = p.parse({"--foo", "123"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, 123);
|
|
}
|
|
|
|
TEST_F(Parser, OptionWithShortAndLongName) {
|
|
auto fooOpt = p.option("-f", "--foo", uintType);
|
|
argparser::parse_result pr;
|
|
uint32_t fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f", "123"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, 123);
|
|
EXPECT_NO_THROW(pr = p.parse({"--foo", "123"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, 123);
|
|
}
|
|
|
|
TEST_F(Parser, RepeatableOptionWithLongAndShortName) {
|
|
auto fooOpt = p.repeatable_option("--foo", "-f", uintType);
|
|
argparser::parse_result pr;
|
|
std::vector<uint32_t> fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f", "123"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, (decltype(fooVal){123}));
|
|
EXPECT_NO_THROW(pr = p.parse({"--foo", "123"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, (decltype(fooVal){123}));
|
|
EXPECT_NO_THROW(pr = p.parse({"--foo", "123", "-f", "234"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, (decltype(fooVal){123, 234}));
|
|
EXPECT_NO_THROW(pr = p.parse({"-f", "123", "--foo", "234"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, (decltype(fooVal){123, 234}));
|
|
}
|
|
|
|
TEST_F(Parser, RepeatableOptionWithShortAndLongName) {
|
|
auto fooOpt = p.repeatable_option("-f", "--foo", uintType);
|
|
argparser::parse_result pr;
|
|
std::vector<uint32_t> fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f", "123"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, (decltype(fooVal){123}));
|
|
EXPECT_NO_THROW(pr = p.parse({"--foo", "123"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, (decltype(fooVal){123}));
|
|
EXPECT_NO_THROW(pr = p.parse({"--foo", "123", "-f", "234"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, (decltype(fooVal){123, 234}));
|
|
EXPECT_NO_THROW(pr = p.parse({"-f", "123", "--foo", "234"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, (decltype(fooVal){123, 234}));
|
|
}
|
|
|
|
TEST_F(Parser, FlagWithLongAndSHortName) {
|
|
auto fooFlag = p.flag("--foo", "-f");
|
|
argparser::parse_result pr;
|
|
bool fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, true);
|
|
EXPECT_NO_THROW(pr = p.parse({"--foo"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, true);
|
|
}
|
|
|
|
TEST_F(Parser, FlagWithShortAndLongName) {
|
|
auto fooFlag = p.flag("-f", "--foo");
|
|
argparser::parse_result pr;
|
|
bool fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, true);
|
|
EXPECT_NO_THROW(pr = p.parse({"--foo"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, true);
|
|
}
|
|
|
|
TEST_F(Parser, RepeatableFlagWithLongAndShortName) {
|
|
auto fooFlag = p.repeatable_flag("--foo", "-f");
|
|
argparser::parse_result pr;
|
|
unsigned int fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, 1);
|
|
EXPECT_NO_THROW(pr = p.parse({"--foo"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, 1);
|
|
EXPECT_NO_THROW(pr = p.parse({"-f", "--foo"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, 2);
|
|
EXPECT_NO_THROW(pr = p.parse({"--foo", "-f"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, 2);
|
|
}
|
|
|
|
TEST_F(Parser, RepeatableFlagWithShortAndLongName) {
|
|
auto fooFlag = p.repeatable_flag("-f", "--foo");
|
|
argparser::parse_result pr;
|
|
unsigned int fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, 1);
|
|
EXPECT_NO_THROW(pr = p.parse({"--foo"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, 1);
|
|
EXPECT_NO_THROW(pr = p.parse({"-f", "--foo"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, 2);
|
|
EXPECT_NO_THROW(pr = p.parse({"--foo", "-f"}));
|
|
EXPECT_NO_THROW(fooVal = fooFlag->get(pr));
|
|
EXPECT_EQ(fooVal, 2);
|
|
}
|
|
|
|
|
|
TEST_F(Parser, ShortOptionCombinedWithValue) {
|
|
auto fooOpt = p.option("-f", uintType);
|
|
argparser::parse_result pr;
|
|
uint32_t fooVal;
|
|
EXPECT_NO_THROW(pr = p.parse({"-f123"}));
|
|
EXPECT_NO_THROW(fooVal = fooOpt->get(pr));
|
|
EXPECT_EQ(fooVal, 123);
|
|
}
|
|
|
|
TEST_F(Parser, MultipleShortFlags) {
|
|
auto flagA = p.flag("-a");
|
|
auto flagB = p.flag("-b");
|
|
auto flagC = p.flag("-c");
|
|
argparser::parse_result pr;
|
|
EXPECT_NO_THROW(pr = p.parse({"-cab"}));
|
|
EXPECT_EQ(flagA->get(pr), true);
|
|
EXPECT_EQ(flagB->get(pr), true);
|
|
EXPECT_EQ(flagC->get(pr), true);
|
|
}
|
|
|
|
TEST_F(Parser, MultipleShortFlagsCombinedWithShortOptionWithValue) {
|
|
auto flagA = p.flag("-a");
|
|
auto flagB = p.flag("-b");
|
|
auto flagC = p.flag("-c");
|
|
auto fooOpt = p.option("-f", uintType);
|
|
argparser::parse_result pr;
|
|
EXPECT_NO_THROW(pr = p.parse({"-cabf123"}));
|
|
EXPECT_EQ(flagA->get(pr), true);
|
|
EXPECT_EQ(flagB->get(pr), true);
|
|
EXPECT_EQ(flagC->get(pr), true);
|
|
EXPECT_EQ(fooOpt->get(pr), 123);
|
|
}
|
|
|
|
|
|
TEST_F(Parser, SingleArgument) {
|
|
auto fooArg = p.arg("foo", uintType);
|
|
auto parsed = p.parse({"123"});
|
|
EXPECT_EQ(fooArg->get(parsed), 123);
|
|
}
|
|
|
|
TEST_F(Parser, MissingArgumentThrows) {
|
|
auto fooArg = p.arg("foo", uintType);
|
|
EXPECT_THROW(auto _ = p.parse({});, argparser::errors::missing_argument_error);
|
|
}
|
|
|
|
TEST_F(Parser, MultipleArguments) {
|
|
auto fooArg = p.arg("foo", uintType);
|
|
auto barArg = p.arg("bar", uintType);
|
|
auto parsed = p.parse({"123", "234"});
|
|
EXPECT_EQ(fooArg->get(parsed), 123);
|
|
EXPECT_EQ(barArg->get(parsed), 234);
|
|
}
|
|
|
|
TEST_F(Parser, MixedArgumentsAndOptionsAndFlags) {
|
|
auto fooArg = p.arg("foo", uintType);
|
|
auto barArg = p.arg("bar", uintType);
|
|
auto asdfOpt = p.option("--asdf", uintType);
|
|
auto qwertyFlag = p.flag("--qwerty");
|
|
auto parsed = p.parse({"123", "--asdf", "1", "234", "--qwerty"});
|
|
EXPECT_EQ(fooArg->get(parsed), 123);
|
|
EXPECT_EQ(barArg->get(parsed), 234);
|
|
EXPECT_EQ(asdfOpt->get(parsed), 1);
|
|
EXPECT_EQ(qwertyFlag->get(parsed), true);
|
|
|
|
parsed = p.parse({"--asdf", "123", "234", "345"});
|
|
EXPECT_EQ(fooArg->get(parsed), 234);
|
|
EXPECT_EQ(barArg->get(parsed), 345);
|
|
EXPECT_EQ(asdfOpt->get(parsed), 123);
|
|
EXPECT_EQ(qwertyFlag->get(parsed), false);
|
|
}
|
|
|
|
TEST_F(Parser, OptionalArgument) {
|
|
auto fooArg = p.optional_arg("foo", uintType);
|
|
auto parsed = p.parse({"123"});
|
|
EXPECT_EQ(fooArg->get(parsed).has_value(), true);
|
|
EXPECT_EQ(fooArg->get(parsed).value(), 123);
|
|
EXPECT_EQ(fooArg->has(parsed), true);
|
|
parsed = p.parse({});
|
|
EXPECT_EQ(fooArg->get(parsed).has_value(), false);
|
|
EXPECT_EQ(fooArg->has(parsed), false);
|
|
}
|
|
|
|
TEST_F(Parser, OptionalArgumentDefaultValue) {
|
|
auto fooArg = p.optional_arg("foo", uintType)->default_value(99);
|
|
auto parsed = p.parse({"123"});
|
|
EXPECT_EQ(fooArg->get(parsed), 123);
|
|
EXPECT_EQ(fooArg->has(parsed), true);
|
|
parsed = p.parse({});
|
|
EXPECT_EQ(fooArg->get(parsed), 99);
|
|
EXPECT_EQ(fooArg->has(parsed), false);
|
|
}
|
|
|
|
TEST_F(Parser, RepeatedArgument) {
|
|
auto fooArg = p.repeatable_arg("foo", uintType);
|
|
auto parsed = p.parse({"123", "234", "345", "456"});
|
|
auto val = fooArg->get(parsed);
|
|
EXPECT_EQ(val.size(), 4);
|
|
EXPECT_EQ(val[0], 123);
|
|
EXPECT_EQ(val[1], 234);
|
|
EXPECT_EQ(val[2], 345);
|
|
EXPECT_EQ(val[3], 456);
|
|
}
|
|
|
|
TEST_F(Parser, RepeatedArgumentLimits) {
|
|
auto fooArg = p.repeatable_arg("foo", uintType)->min(2)->max(4);
|
|
argparser::parse_result parsed;
|
|
EXPECT_NO_THROW(parsed = p.parse({"1", "2"}););
|
|
EXPECT_EQ(fooArg->get(parsed), (std::vector<uint32_t>{1, 2}));
|
|
EXPECT_NO_THROW(parsed = p.parse({"1", "2", "3"}););
|
|
EXPECT_EQ(fooArg->get(parsed), (std::vector<uint32_t>{1, 2, 3}));
|
|
EXPECT_NO_THROW(parsed = p.parse({"1", "2", "3", "4"}););
|
|
EXPECT_EQ(fooArg->get(parsed), (std::vector<uint32_t>{1, 2, 3, 4}));
|
|
EXPECT_THROW(parsed = p.parse({}), argparser::errors::missing_argument_error);
|
|
EXPECT_THROW(parsed = p.parse({"1"}), argparser::errors::missing_argument_error);
|
|
EXPECT_THROW(parsed = p.parse({"1", "2", "3", "4", "5"}), argparser::errors::too_many_arguments_error);
|
|
EXPECT_THROW(parsed = p.parse({"1", "2", "3", "4", "5", "6"}), argparser::errors::too_many_arguments_error);
|
|
EXPECT_THROW(parsed = p.parse({"1", "2", "3", "4", "5", "6", "7"}), argparser::errors::too_many_arguments_error);
|
|
}
|
|
|
|
TEST_F(Parser, MixedArguments) {
|
|
auto boolType = p.enum_type<bool>("bool", {{"true", true}, {"false", false}});
|
|
auto tupleType = p.tuple_type("tuple", uintType, uintType);
|
|
|
|
auto argA = p.repeatable_arg("a", uintType);
|
|
auto argB = p.optional_arg("b", boolType);
|
|
auto argC = p.arg("c", tupleType);
|
|
auto argD = p.repeatable_arg("d", uintType);
|
|
auto parsed = p.parse({"1", "2", "3", "true", "1,2", "4", "5"});
|
|
auto valA = argA->get(parsed);
|
|
auto valB = argB->get(parsed);
|
|
auto valC = argC->get(parsed);
|
|
auto valD = argD->get(parsed);
|
|
EXPECT_EQ(valA.size(), 3);
|
|
EXPECT_EQ(valA[0], 1);
|
|
EXPECT_EQ(valA[1], 2);
|
|
EXPECT_EQ(valA[2], 3);
|
|
EXPECT_TRUE(valB.has_value());
|
|
EXPECT_EQ(valB.value(), true);
|
|
EXPECT_EQ(valC, (std::make_tuple<uint32_t, uint32_t>(1, 2)));
|
|
EXPECT_EQ(valD, (decltype(valD){4, 5}));
|
|
}
|
|
|
|
TEST_F(Parser, ArgumentWrongType) {
|
|
auto boolType = p.enum_type<bool>("bool", {{"true", true}, {"false", false}});
|
|
auto fooArg = p.arg("foo", boolType);
|
|
EXPECT_THROW(auto _ = p.parse({"123", "true"});, argparser::errors::type_parsing_error);
|
|
}
|
|
|
|
TEST_F(Parser, RemainingArguments) {
|
|
auto fooArg = p.arg("foo", uintType);
|
|
p.enable_remaining_args();
|
|
argparser::parse_result pr;
|
|
EXPECT_NO_THROW(pr = p.parse({"123", "234", "456"}));
|
|
EXPECT_EQ(fooArg->get(pr), 123);
|
|
EXPECT_EQ(pr.remaining(), (std::vector<std::string>{"234", "456"}));
|
|
}
|
|
|
|
TEST_F(Parser, OptionsAndFlagsAsRemainingArguments) {
|
|
auto fooOpt = p.option("--foo", uintType);
|
|
auto barFlag = p.flag("--bar");
|
|
p.enable_remaining_args();
|
|
argparser::parse_result pr;
|
|
EXPECT_NO_THROW(pr = p.parse({"123", "--foo", "456", "--bar"}));
|
|
EXPECT_EQ(pr.remaining(), (std::vector<std::string>{"123", "--foo", "456", "--bar"}));
|
|
EXPECT_FALSE(fooOpt->has(pr));
|
|
EXPECT_FALSE(barFlag->has(pr));
|
|
}
|
|
|
|
TEST_F(Parser, RemainingArgumentsWithDoubleDash) {
|
|
auto fooOpt = p.option("--foo", uintType);
|
|
auto barFlag = p.flag("--bar");
|
|
auto arg = p.arg("arg", uintType);
|
|
p.enable_remaining_args();
|
|
argparser::parse_result pr;
|
|
EXPECT_NO_THROW(pr = p.parse({"123", "--", "--foo", "456", "--bar"}));
|
|
EXPECT_EQ(pr.remaining(), (std::vector<std::string>{"--foo", "456", "--bar"}));
|
|
EXPECT_FALSE(fooOpt->has(pr));
|
|
EXPECT_FALSE(barFlag->has(pr));
|
|
EXPECT_EQ(arg->get(pr), 123);
|
|
}
|