summaryrefslogtreecommitdiff
path: root/test/test-args.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/test-args.cc')
-rw-r--r--test/test-args.cc213
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;
+}