| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- //
- // options_test.cpp
- // program_args-test
- //
- // Created by Sam Jaffe on 2/7/21.
- //
- #include "program_args/arguments.h"
- #include <filesystem>
- #include "xcode_gtest_helper.h"
- using testing::ElementsAre;
- using testing::Eq;
- using testing::IsEmpty;
- template <typename T, size_t N> static T parse(char const * const (&argv)[N]) {
- return T(N, argv);
- }
- struct LongOptionTest : program::Arguments<LongOptionTest> {
- using program::Arguments<LongOptionTest>::Arguments;
- std::string endpoint = option("endpoint");
- int port = option("port");
- };
- TEST(LongOptionTest, ArgumentsAreDefaultedNaturally) {
- auto const options = parse<LongOptionTest>({""});
- EXPECT_THAT(options.endpoint, Eq(""));
- EXPECT_THAT(options.port, Eq(0));
- }
- TEST(LongOptionTest, CanProvideStringArgument) {
- auto const options = parse<LongOptionTest>({"", "--endpoint", "/null"});
- EXPECT_THAT(options.endpoint, Eq("/null"));
- }
- TEST(LongOptionTest, CanProvideNumericArgument) {
- auto const options = parse<LongOptionTest>({"", "--port", "443"});
- EXPECT_THAT(options.port, Eq(443));
- }
- TEST(LongOptionTest, WillThrowOnInvalidNumericArgument) {
- EXPECT_THROW(parse<LongOptionTest>({"", "--port", "one"}),
- program::ProgramArgumentsError);
- }
- TEST(LongOptionTest, WillThrowOnRepeatedArgument) {
- EXPECT_THROW(parse<LongOptionTest>({"", "--port", "8080", "--port", "443"}),
- program::ArgumentStructureError);
- }
- TEST(LongOptionTest, WillThrowOnUnknownArgument) {
- EXPECT_THROW(parse<LongOptionTest>({"", "--path", "/null"}),
- program::NotAnArgumentError);
- }
- TEST(LongOptionTest, DoesNotImplicitlyShortenArgs) {
- EXPECT_THROW(parse<LongOptionTest>({"", "-p", "443"}),
- program::NotAnArgumentError);
- }
- struct LongOptionWithDefaultTest
- : program::Arguments<LongOptionWithDefaultTest> {
- using program::Arguments<LongOptionWithDefaultTest>::Arguments;
- std::string endpoint = option("endpoint") = "/default";
- int port = option("port") = 8080;
- };
- TEST(LongOptionWithDefaultTest, ArgumentsAreDefaultedNaturally) {
- auto const options = parse<LongOptionWithDefaultTest>({""});
- EXPECT_THAT(options.endpoint, Eq("/default"));
- EXPECT_THAT(options.port, Eq(8080));
- }
- TEST(LongOptionWithDefaultTest, CanProvideStringArgument) {
- auto const options =
- parse<LongOptionWithDefaultTest>({"", "--endpoint", "/null"});
- EXPECT_THAT(options.endpoint, Eq("/null"));
- }
- TEST(LongOptionWithDefaultTest, CanProvideNumericArgument) {
- auto const options = parse<LongOptionWithDefaultTest>({"", "--port", "443"});
- EXPECT_THAT(options.port, Eq(443));
- }
- struct LongOptionWithAbbrevTest : program::Arguments<LongOptionWithAbbrevTest> {
- using program::Arguments<LongOptionWithAbbrevTest>::Arguments;
- std::string endpoint = option("endpoint", 'e');
- int port = option("port", 'p');
- };
- TEST(LongOptionWithAbbrevTest, CanProvideStringArgument) {
- auto const options =
- parse<LongOptionWithAbbrevTest>({"", "--endpoint", "/null"});
- EXPECT_THAT(options.endpoint, Eq("/null"));
- }
- TEST(LongOptionWithAbbrevTest, CanProvideAbbrevStringArgument) {
- auto const options = parse<LongOptionWithAbbrevTest>({"", "-e", "/null"});
- EXPECT_THAT(options.endpoint, Eq("/null"));
- }
- TEST(LongOptionWithAbbrevTest, CanProvideNumericArgument) {
- auto const options = parse<LongOptionWithAbbrevTest>({"", "--port", "443"});
- EXPECT_THAT(options.port, Eq(443));
- }
- TEST(LongOptionWithAbbrevTest, CanProvideAbbrevNumericArgument) {
- auto const options = parse<LongOptionWithAbbrevTest>({"", "-p", "443"});
- EXPECT_THAT(options.port, Eq(443));
- }
- TEST(LongOptionWithAbbrevTest, ShortAndLongArgsGoToSamePool) {
- EXPECT_THROW(
- parse<LongOptionWithAbbrevTest>({"", "--port", "8080", "-p", "443"}),
- program::ArgumentStructureError);
- }
- TEST(LongOptionWithAbbrevTest, CanPutAbbrevArgAndValueInSameToken) {
- EXPECT_NO_THROW(parse<LongOptionWithAbbrevTest>({"", "-p443"}));
- auto const options = parse<LongOptionWithAbbrevTest>({"", "-p443"});
- EXPECT_THAT(options.port, Eq(443));
- }
- struct LongOptionRepeatTest : program::Arguments<LongOptionRepeatTest> {
- using program::Arguments<LongOptionRepeatTest>::Arguments;
- std::vector<int> port = option("port");
- };
- TEST(LongOptionRepeatTest, DefaultIsEmpty) {
- auto const options = parse<LongOptionRepeatTest>({""});
- EXPECT_THAT(options.port, IsEmpty());
- }
- TEST(LongOptionRepeatTest, CanProvideArgument) {
- auto const options = parse<LongOptionRepeatTest>({"", "--port", "443"});
- EXPECT_THAT(options.port, ElementsAre(443));
- }
- TEST(LongOptionRepeatTest, RepeatingArgumentsAppends) {
- auto const options =
- parse<LongOptionRepeatTest>({"", "--port", "443", "--port", "8080"});
- EXPECT_THAT(options.port, ElementsAre(443, 8080));
- }
- struct LongOptionRepeatWithDefaultTest
- : program::Arguments<LongOptionRepeatWithDefaultTest> {
- using program::Arguments<LongOptionRepeatWithDefaultTest>::Arguments;
- std::vector<int> port = option("port") = std::vector{8080};
- };
- TEST(LongOptionRepeatWithDefaultTest, DefaultIsProvided) {
- auto const options = parse<LongOptionRepeatWithDefaultTest>({""});
- EXPECT_THAT(options.port, ElementsAre(8080));
- }
- TEST(LongOptionRepeatWithDefaultTest, ArgumentOverwritesDefault) {
- auto const options =
- parse<LongOptionRepeatWithDefaultTest>({"", "--port", "443"});
- EXPECT_THAT(options.port, ElementsAre(443));
- }
- namespace fs = std::filesystem;
- struct DeferOptionTest : program::Arguments<DeferOptionTest> {
- using Arguments::Arguments;
- fs::path path = option("path") = ".";
- fs::path log = option("log") = PROGRAM_DEFER(path / "test.log");
- };
- TEST(DeferOptionTest, DefaultResolves) {
- auto const options = parse<DeferOptionTest>({""});
- EXPECT_THAT(options.log.string(), "./test.log");
- }
- TEST(DeferOptionTest, CapturesUpdateToDependent) {
- auto const options = parse<DeferOptionTest>({"", "--path", "/var/log"});
- EXPECT_THAT(options.log.string(), "/var/log/test.log");
- }
- TEST(DeferOptionTest, SettingActualArgWillOverwrite) {
- auto const options = parse<DeferOptionTest>({"", "--path", "/var/log", "--log", "test.log"});
- EXPECT_THAT(options.log.string(), "test.log");
- }
- struct ShortOptionTest : program::Arguments<ShortOptionTest> {
- using Arguments::Arguments;
- int arg = option('n');
- };
- TEST(ShortOptionTest, DoesNotAllowDoubleDash) {
- EXPECT_THROW(parse<ShortOptionTest>({"", "--n", "5"}), program::NotAnArgumentError);
- }
- TEST(ShortOptionTest, CanConstructWithOnlyAbbrev) {
- auto const options = parse<ShortOptionTest>({"", "-n", "5"});
- EXPECT_THAT(options.arg, 5);
- }
|