diff options
Diffstat (limited to 'test/test-args.cc')
| -rw-r--r-- | test/test-args.cc | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/test/test-args.cc b/test/test-args.cc new file mode 100644 index 0000000..30057e4 --- /dev/null +++ b/test/test-args.cc @@ -0,0 +1,213 @@ +// -*- mode: c++; c-basic-offset: 2; -*- + +#include "common.hh" +#include "test.hh" + +#include "args.hh" + +#include <algorithm> +#include <memory> +#include <sstream> +#include <stdarg.h> +#include <string> +#include <unordered_map> +#include <vector> + +namespace { + +char const* basic_so[] = { "h", "C", "X", NULL }; +char const* basic_lo[] = { "help", "config", "verbose", "output", NULL }; + +std::unique_ptr<Args> 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<Args>(ret); +} + +bool test_basic(char const* first, ...) { + auto args = setup_basic(); + std::vector<std::string> so; + std::vector<std::string> lo; + std::vector<std::string> a; + std::vector<std::string> 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<char*[]>(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<std::string, char const*> so; + std::unordered_map<std::string, char const*> lo; + std::vector<std::string> a; + std::vector<std::string> 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<char*[]>(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<std::string> 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<char*[]>(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; +} |
