// -*- mode: c++; c-basic-offset: 2; -*- #include "common.hh" #include "test.hh" #include "args.hh" #include #include #include #include #include #include #include namespace { char const* basic_so[] = { "h", "C", "X", NULL }; char const* basic_lo[] = { "help", "config", "verbose", "output", NULL }; std::unique_ptr setup_basic() { auto ret = Args::create(); ret->add('h', "help", "help"); ret->add('C', "config", "FILE", "config FILE"); ret->add("verbose", "be verbose"); ret->add('X', "", "TEST", "test"); ret->add("output", "OUT", "output"); return std::unique_ptr(ret); } bool test_basic(char const* first, ...) { auto args = setup_basic(); std::vector so; std::vector lo; std::vector a; std::vector argv; va_list tmp; char const* arg; va_start(tmp, first); if (first) { so.push_back(first); while (true) { arg = va_arg(tmp, char const*); if (!arg) break; so.push_back(arg); } } while (true) { arg = va_arg(tmp, char const*); if (!arg) break; lo.push_back(arg); } while (true) { arg = va_arg(tmp, char const*); if (!arg) break; a.push_back(arg); } argv.push_back("program"); while (true) { arg = va_arg(tmp, char const*); if (!arg) break; argv.push_back(arg); } va_end(tmp); auto tmp_argv = std::unique_ptr(new char*[argv.size()]); for (size_t i = 0; i < argv.size(); ++i) { tmp_argv[i] = &argv[i][0]; } ASSERT_EQ(true, args->run(argv.size(), tmp_argv.get(), std::cerr)); ASSERT_EQ(true, args->good()); for (auto i = basic_so; *i; ++i) { ASSERT_EQ(std::count(so.begin(), so.end(), *i) > 0, args->is_set(**i)); } for (auto i = basic_lo; *i; ++i) { ASSERT_EQ(std::count(lo.begin(), lo.end(), *i) > 0, args->is_set(*i)); } ASSERT_EQ(a.size(), args->arguments().size()); for (size_t i = 0; i < a.size(); ++i) { ASSERT_EQ(a[i], args->arguments()[i]); } return true; } bool test_basic_arg(char const* first, ...) { auto args = setup_basic(); std::unordered_map so; std::unordered_map lo; std::vector a; std::vector argv; va_list tmp; char const* arg; va_start(tmp, first); if (first) { so.insert(std::make_pair(first, va_arg(tmp, char const*))); while (true) { arg = va_arg(tmp, char const*); if (!arg) break; so.insert(std::make_pair(arg, va_arg(tmp, char const*))); } } while (true) { arg = va_arg(tmp, char const*); if (!arg) break; lo.insert(std::make_pair(arg, va_arg(tmp, char const*))); } while (true) { arg = va_arg(tmp, char const*); if (!arg) break; a.push_back(arg); } argv.push_back("/program"); while (true) { arg = va_arg(tmp, char const*); if (!arg) break; argv.push_back(arg); } va_end(tmp); auto tmp_argv = std::unique_ptr(new char*[argv.size()]); for (size_t i = 0; i < argv.size(); ++i) { tmp_argv[i] = &argv[i][0]; } ASSERT_EQ(true, args->run(argv.size(), tmp_argv.get(), std::cerr)); ASSERT_EQ(true, args->good()); for (auto i = basic_so; *i; ++i) { ASSERT_EQ(so.count(*i) > 0, args->is_set(**i)); } for (auto& i : so) { auto tmp = args->arg(i.first[0], nullptr); ASSERT_STREQ(i.second, tmp); } for (auto i = basic_lo; *i; ++i) { ASSERT_EQ(lo.count(*i) > 0, args->is_set(*i)); } for (auto& i : lo) { auto tmp = args->arg(i.first, nullptr); ASSERT_STREQ(i.second, tmp); } ASSERT_EQ(a.size(), args->arguments().size()); for (size_t i = 0; i < a.size(); ++i) { ASSERT_EQ(a[i], args->arguments()[i]); } return true; } bool test_basic_fail(char const* first, ...) { auto args = setup_basic(); std::vector argv; va_list tmp; char const* arg; va_start(tmp, first); argv.push_back("/usr/bin/program"); if (first) { argv.push_back(first); while (true) { arg = va_arg(tmp, char const*); if (!arg) break; argv.push_back(arg); } } va_end(tmp); auto tmp_argv = std::unique_ptr(new char*[argv.size()]); for (size_t i = 0; i < argv.size(); ++i) { tmp_argv[i] = &argv[i][0]; } std::stringstream out; ASSERT_EQ(false, args->run(argv.size(), tmp_argv.get(), out)); ASSERT_EQ(false, args->good()); return true; } } // namespace int main(void) { BEFORE; RUN(test_basic(NULL, NULL, NULL, NULL)); // no arguments RUN(test_basic("h", NULL, "help", NULL, NULL, "--help", NULL)); RUN(test_basic("h", NULL, "help", NULL, NULL, "-h", NULL)); RUN(test_basic("h", NULL, "help", NULL, "arg", NULL, "--help", "arg", NULL)); RUN(test_basic("h", NULL, "help", NULL, "arg", NULL, "arg", "--help", NULL)); RUN(test_basic("h", NULL, "help", "verbose", NULL, NULL, "--verbose", "--help", NULL)); RUN(test_basic("h", NULL, "help", "verbose", NULL, NULL, "--verbose", "-h", NULL)); RUN(test_basic(NULL, NULL, "arg", "--help", NULL, "--", "arg", "--help", NULL)); RUN(test_basic(NULL, NULL, "arg", "--help", NULL, "arg", "--", "--help", NULL)); RUN(test_basic_arg("C", "configfile", NULL, "config", "configfile", NULL, NULL, "-C", "configfile", NULL)); RUN(test_basic_arg("C", "configfile", NULL, "config", "configfile", NULL, NULL, "--config", "configfile", NULL)); RUN(test_basic_arg("C", "configfile", NULL, "config", "configfile", NULL, NULL, "--config=configfile", NULL)); RUN(test_basic_arg("C", "configfile", "h", NULL, NULL, "config", "configfile", "help", NULL, NULL, NULL, "-Ch", "configfile", NULL)); RUN(test_basic_arg("C", "configfile", "X", "test", NULL, "config", "configfile", NULL, NULL, "-CX", "configfile", "test", NULL)); RUN(test_basic_arg("X", "-C", NULL, NULL, NULL, "-X", "-C", NULL)); RUN(test_basic_fail("-C", NULL)); RUN(test_basic_fail("--config", NULL)); RUN(test_basic_fail("-X", NULL)); RUN(test_basic_fail("-Y", NULL)); RUN(test_basic_fail("-XC", NULL)); RUN(test_basic_fail("--output", NULL)); RUN(test_basic_fail("--outp", NULL)); RUN(test_basic_fail("--help=", NULL)); AFTER; }