// // argument_test.cpp // program_args-test // // Created by Sam Jaffe on 2/7/21. // #include "program_args/arguments.h" #include "xcode_gtest_helper.h" using testing::ElementsAre; using testing::Eq; using testing::IsEmpty; template static T parse(char const * const (&argv)[N]) { return T(N, argv); } struct ArgumentTest : program::Arguments { using Arguments::Arguments; std::string arg0 = argument(0, "arg0"); }; TEST(ArgumentTest, ThrowsIfMissingArg) { EXPECT_THROW(parse({""}), program::IllegalPositionError); } TEST(ArgumentTest, ProcessesArgument) { auto const options = parse({"", "value"}); EXPECT_THAT(options.arg0, Eq("value")); } TEST(ArgumentTest, HasNoIssueWithOverflowArg) { auto const options = parse({"", "value", "extra"}); EXPECT_THAT(options.arg0, Eq("value")); EXPECT_THAT(options.args(), ElementsAre("extra")); } struct OptionalArgumentTest : program::Arguments { using Arguments::Arguments; std::string arg0 = argument(0, "arg0"); std::string arg1 = argument(1, "arg1") = "second"; }; TEST(OptionalArgumentTest, DoesNotRequireOptionalArg) { EXPECT_NO_THROW(parse({"", "value"})); } TEST(OptionalArgumentTest, DefaultsOutValueAsExpected) { auto const options = parse({"", "value"}); EXPECT_THAT(options.arg1, Eq("second")); } TEST(OptionalArgumentTest, DoesNotOverflowSecondArg) { auto const options = parse({"", "value", "extra"}); EXPECT_THAT(options.arg0, Eq("value")); EXPECT_THAT(options.arg1, Eq("extra")); EXPECT_THAT(options.args(), ElementsAre()); } struct DuplicateArgumentTest : program::Arguments { using Arguments::Arguments; std::string arg0 = argument(0, "arg0"); std::string arg1 = argument(0, "arg1"); }; TEST(DuplicateArgumentTest, ThrowsOnConstruction) { EXPECT_THROW(DuplicateArgumentTest(), program::IllegalPositionError); } struct SkippedArgumentTest : program::Arguments { using Arguments::Arguments; std::string arg0 = argument(1, "arg0"); }; TEST(SkippedArgumentTest, ThrowsOnParsing) { EXPECT_NO_THROW(SkippedArgumentTest()); EXPECT_THROW(parse({"", "", ""}), program::IllegalPositionError); } struct OOOArgumentTest : program::Arguments { using Arguments::Arguments; std::string arg0 = argument(0, "arg0") = ""; std::string arg1 = argument(1, "arg1"); }; TEST(OOOArgumentTest, ThrowsOnConstruction) { EXPECT_THROW(OOOArgumentTest(), program::ArgumentStructureError); } struct RestArgsTest : program::Arguments { using Arguments::Arguments; std::string arg0 = argument(0, "arg0") = ""; std::vector args = rest(); }; TEST(RestArgsTest, SetsOptionalArgFirst) { auto const options = parse({"", "A"}); EXPECT_THAT(options.arg0, "A"); EXPECT_THAT(options.args, IsEmpty()); } TEST(RestArgsTest, ForwardsOverflowIntoRest) { auto const options = parse({"", "A", "B", "C"}); EXPECT_THAT(options.arg0, "A"); EXPECT_THAT(options.args, ElementsAre("B", "C")); } struct RestDefaultArgsTest : program::Arguments { using Arguments::Arguments; std::string arg0 = argument(0, "arg0") = ""; std::vector args = rest() = "REST"; }; TEST(RestDefaultArgsTest, SetsRest) { auto const options = parse({""}); EXPECT_THAT(options.args, ElementsAre("REST")); } TEST(RestDefaultArgsTest, OverridesRest) { auto const options = parse({"", "A", "B"}); EXPECT_THAT(options.args, ElementsAre("B")); }