/* -*- C++ -*- (c) 2007 Petr Rockai (c) 2007 Enrico Zini */ #include #include #include using namespace wibble::commandline; using namespace std; // Happy trick to get access to protected methods we need to use for the tests template class Public : public T { public: Public(MemoryManager* mman = 0, const std::string& name = std::string(), const std::string& usage = std::string(), const std::string& description = std::string(), const std::string& longDescription = std::string()) : T(mman, name, usage, description, longDescription) {} ArgList::iterator parseList(ArgList& list) { return T::parseList(list); } ArgList::iterator parse(ArgList& list, ArgList::iterator begin) { return T::parse(list, begin); } }; class Engine1 : public Public { MemoryManager mman; public: Engine1() : Public(&mman) { antani = add("antani", 'a', "antani"); blinda = add("blinda", 'b', "blinda"); antani->addAlias("an-tani"); } BoolOption* antani; StringOption* blinda; }; class Engine2 : public Public { MemoryManager mman; public: Engine2() : Public(&mman) { help = add("help", 'h', "help", "get help"); scramble = addEngine("scramble"); scramble_random = scramble->add("random", 'r', "random"); scramble_yell = scramble->add("yell", 0, "yell"); scramble->aliases.push_back("mess"); fix = addEngine("fix"); fix_quick = fix->add("quick", 'Q', "quick"); fix_yell = fix->add("yell", 0, "yell"); } BoolOption* help; Engine* scramble; BoolOption* scramble_random; StringOption* scramble_yell; Engine* fix; BoolOption* fix_quick; StringOption* fix_yell; }; struct TestCommandlineEngine { Test optsAndArgs() { ArgList opts; opts.push_back("ciaps"); opts.push_back("-b"); opts.push_back("cippo"); opts.push_back("foobar"); Engine1 engine; ArgList::iterator i = engine.parseList(opts); assert(i == opts.begin()); assert_eq(opts.size(), 2u); assert_eq(string(*opts.begin()), string("ciaps")); assert_eq(string(*opts.rbegin()), string("foobar")); assert_eq(engine.antani->boolValue(), false); assert_eq(engine.blinda->stringValue(), "cippo"); } Test noSwitchesAfterFirstArg() { ArgList opts; opts.push_back("-b"); opts.push_back("cippo"); opts.push_back("foobar"); opts.push_back("--cabal"); Engine1 engine; engine.no_switches_after_first_arg = true; ArgList::iterator i = engine.parseList(opts); assert(i == opts.begin()); assert_eq(opts.size(), 2u); assert_eq(string(*opts.begin()), string("foobar")); assert_eq(string(*opts.rbegin()), string("--cabal")); assert_eq(engine.antani->boolValue(), false); assert_eq(engine.blinda->stringValue(), "cippo"); } Test optsOnly() { ArgList opts; opts.push_back("-a"); opts.push_back("foobar"); Engine1 engine; ArgList::iterator i = engine.parseList(opts); assert(i == opts.begin()); assert_eq(opts.size(), 1u); assert_eq(string(*opts.begin()), string("foobar")); assert_eq(engine.antani->boolValue(), true); assert_eq(engine.blinda->boolValue(), false); } Test clusteredShortOpts() { ArgList opts; opts.push_back("-ab"); opts.push_back("cippo"); Engine1 engine; ArgList::iterator i = engine.parseList(opts); assert(i == opts.end()); assert_eq(opts.size(), 0u); assert_eq(engine.antani->boolValue(), true); assert_eq(engine.blinda->stringValue(), "cippo"); } Test longOptsWithDashes() { ArgList opts; opts.push_back("--an-tani"); opts.push_back("foobar"); Engine1 engine; ArgList::iterator i = engine.parseList(opts); assert(i == opts.begin()); assert_eq(opts.size(), 1u); assert_eq(string(*opts.begin()), string("foobar")); assert_eq(engine.antani->boolValue(), true); assert_eq(engine.blinda->boolValue(), false); } // Test long options with arguments Test longOptsWithArgs() { ArgList opts; opts.push_back("--blinda=cippo"); opts.push_back("foobar"); opts.push_back("--antani"); Engine1 engine; ArgList::iterator i = engine.parseList(opts); assert(i == opts.begin()); assert_eq(opts.size(), 1u); assert_eq(string(*opts.begin()), string("foobar")); assert_eq(engine.antani->boolValue(), true); assert_eq(engine.blinda->stringValue(), "cippo"); } Test commandWithArg() { ArgList opts; opts.push_back("--yell=foo"); opts.push_back("mess"); opts.push_back("-r"); Engine2 engine; ArgList::iterator i = engine.parseList(opts); assert(i == opts.end()); assert_eq(opts.size(), 0u); assert_eq(engine.foundCommand(), engine.scramble); assert_eq(engine.scramble_yell->stringValue(), "foo"); assert_eq(engine.scramble_random->boolValue(), true); assert_eq(engine.fix_yell->stringValue(), string()); assert_eq(engine.fix_quick->boolValue(), false); assert_eq(engine.help->boolValue(), false); } // Test the other command, with overlapping arguments Test commandsWithOverlappingArgs() { ArgList opts; opts.push_back("--yell=foo"); opts.push_back("fix"); opts.push_back("--help"); opts.push_back("-Q"); Engine2 engine; ArgList::iterator i = engine.parseList(opts); assert(i == opts.end()); assert_eq(opts.size(), 0u); assert_eq(engine.foundCommand(), engine.fix); assert_eq(engine.scramble_yell->stringValue(), string()); assert_eq(engine.scramble_random->boolValue(), false); assert_eq(engine.fix_yell->stringValue(), "foo"); assert_eq(engine.fix_quick->boolValue(), true); assert_eq(engine.help->boolValue(), true); } // Test invocation without command Test commandsWithoutCommand() { ArgList opts; opts.push_back("--help"); Engine2 engine; ArgList::iterator i = engine.parseList(opts); assert(i == opts.end()); assert_eq(opts.size(), 0u); assert_eq(engine.foundCommand(), static_cast(0)); assert_eq(engine.scramble_yell->stringValue(), string()); assert_eq(engine.scramble_random->boolValue(), false); assert_eq(engine.fix_yell->stringValue(), string()); assert_eq(engine.fix_quick->boolValue(), false); assert_eq(engine.help->boolValue(), true); } // Test creation shortcuts Test creationShortcuts() { MemoryManager mman; Public engine(&mman, "test", "[options]", "test engine", "this is the long description of a test engine"); OptionGroup* group = engine.addGroup("test option group"); BoolOption* testBool = group->add("tbool", 0, "testbool", "", "a test bool switch"); IntOption* testInt = group->add("tint", 0, "testint", "", "a test int switch"); StringOption* testString = group->add("tstring", 0, "teststring", "", "a test string switch"); BoolOption* testBool1 = engine.add("tbool", 0, "testbool1", "", "a test bool switch"); IntOption* testInt1 = engine.add("tint", 0, "testint1", "", "a test int switch"); StringOption* testString1 = engine.add("tstring", 0, "teststring1", "", "a test string switch"); ArgList opts; opts.push_back("--testbool=true"); opts.push_back("--testint=3"); opts.push_back("--teststring=antani"); opts.push_back("--testbool1=true"); opts.push_back("--testint1=5"); opts.push_back("--teststring1=blinda"); ArgList::iterator i = engine.parseList(opts); assert(i == opts.end()); assert_eq(opts.size(), 0u); assert_eq(testBool->boolValue(), true); assert_eq(testInt->intValue(), 3); assert_eq(testString->stringValue(), "antani"); assert_eq(testBool1->boolValue(), true); assert_eq(testInt1->intValue(), 5); assert_eq(testString1->stringValue(), "blinda"); } }; // vim:set ts=4 sw=4: