00001
00002
00003 #include <wibble/commandline/engine.h>
00004
00005 #include <wibble/test.h>
00006 #include <string>
00007
00008 using namespace wibble::commandline;
00009 using namespace std;
00010
00011
00012 template<typename T>
00013 class Public : public T
00014 {
00015 public:
00016 Public(MemoryManager* mman = 0, const std::string& name = std::string(),
00017 const std::string& usage = std::string(),
00018 const std::string& description = std::string(),
00019 const std::string& longDescription = std::string())
00020 : T(mman, name, usage, description, longDescription) {}
00021
00022 ArgList::iterator parseList(ArgList& list) { return T::parseList(list); }
00023 ArgList::iterator parse(ArgList& list, ArgList::iterator begin)
00024 {
00025 return T::parse(list, begin);
00026 }
00027 };
00028
00029 class Engine1 : public Public<Engine>
00030 {
00031 MemoryManager mman;
00032
00033 public:
00034 Engine1() : Public<Engine>(&mman)
00035 {
00036 antani = add<BoolOption>("antani", 'a', "antani");
00037 blinda = add<StringOption>("blinda", 'b', "blinda");
00038
00039 antani->addAlias("an-tani");
00040 }
00041
00042 BoolOption* antani;
00043 StringOption* blinda;
00044 };
00045
00046 class Engine2 : public Public<Engine>
00047 {
00048 MemoryManager mman;
00049
00050 public:
00051 Engine2() : Public<Engine>(&mman)
00052 {
00053 help = add<BoolOption>("help", 'h', "help", "get help");
00054
00055 scramble = addEngine("scramble");
00056 scramble_random = scramble->add<BoolOption>("random", 'r', "random");
00057 scramble_yell = scramble->add<StringOption>("yell", 0, "yell");
00058 scramble->aliases.push_back("mess");
00059
00060 fix = addEngine("fix");
00061 fix_quick = fix->add<BoolOption>("quick", 'Q', "quick");
00062 fix_yell = fix->add<StringOption>("yell", 0, "yell");
00063 }
00064
00065 BoolOption* help;
00066 Engine* scramble;
00067 BoolOption* scramble_random;
00068 StringOption* scramble_yell;
00069 Engine* fix;
00070 BoolOption* fix_quick;
00071 StringOption* fix_yell;
00072 };
00073
00074 struct TestCommandlineEngine {
00075 Test optsAndArgs() {
00076 ArgList opts;
00077 opts.push_back("ciaps");
00078 opts.push_back("-b");
00079 opts.push_back("cippo");
00080 opts.push_back("foobar");
00081
00082 Engine1 engine;
00083 ArgList::iterator i = engine.parseList(opts);
00084 assert(i == opts.begin());
00085 assert_eq(opts.size(), 2u);
00086 assert_eq(string(*opts.begin()), string("ciaps"));
00087 assert_eq(string(*opts.rbegin()), string("foobar"));
00088 assert_eq(engine.antani->boolValue(), false);
00089 assert_eq(engine.blinda->stringValue(), "cippo");
00090 }
00091
00092 Test optsOnly() {
00093 ArgList opts;
00094 opts.push_back("-a");
00095 opts.push_back("foobar");
00096
00097 Engine1 engine;
00098 ArgList::iterator i = engine.parseList(opts);
00099 assert(i == opts.begin());
00100 assert_eq(opts.size(), 1u);
00101 assert_eq(string(*opts.begin()), string("foobar"));
00102 assert_eq(engine.antani->boolValue(), true);
00103 assert_eq(engine.blinda->boolValue(), false);
00104 }
00105
00106 Test clusteredShortOpts() {
00107 ArgList opts;
00108 opts.push_back("-ab");
00109 opts.push_back("cippo");
00110
00111 Engine1 engine;
00112 ArgList::iterator i = engine.parseList(opts);
00113 assert(i == opts.end());
00114 assert_eq(opts.size(), 0u);
00115 assert_eq(engine.antani->boolValue(), true);
00116 assert_eq(engine.blinda->stringValue(), "cippo");
00117 }
00118
00119 Test longOptsWithDashes() {
00120 ArgList opts;
00121 opts.push_back("--an-tani");
00122 opts.push_back("foobar");
00123
00124 Engine1 engine;
00125 ArgList::iterator i = engine.parseList(opts);
00126 assert(i == opts.begin());
00127 assert_eq(opts.size(), 1u);
00128 assert_eq(string(*opts.begin()), string("foobar"));
00129 assert_eq(engine.antani->boolValue(), true);
00130 assert_eq(engine.blinda->boolValue(), false);
00131 }
00132
00133
00134 Test longOptsWithArgs() {
00135 ArgList opts;
00136 opts.push_back("--blinda=cippo");
00137 opts.push_back("foobar");
00138 opts.push_back("--antani");
00139
00140 Engine1 engine;
00141 ArgList::iterator i = engine.parseList(opts);
00142 assert(i == opts.begin());
00143 assert_eq(opts.size(), 1u);
00144 assert_eq(string(*opts.begin()), string("foobar"));
00145 assert_eq(engine.antani->boolValue(), true);
00146 assert_eq(engine.blinda->stringValue(), "cippo");
00147 }
00148
00149 Test commandWithArg() {
00150 ArgList opts;
00151 opts.push_back("--yell=foo");
00152 opts.push_back("mess");
00153 opts.push_back("-r");
00154
00155 Engine2 engine;
00156 ArgList::iterator i = engine.parseList(opts);
00157 assert(i == opts.end());
00158 assert_eq(opts.size(), 0u);
00159 assert_eq(engine.foundCommand(), engine.scramble);
00160 assert_eq(engine.scramble_yell->stringValue(), "foo");
00161 assert_eq(engine.scramble_random->boolValue(), true);
00162 assert_eq(engine.fix_yell->stringValue(), string());
00163 assert_eq(engine.fix_quick->boolValue(), false);
00164 assert_eq(engine.help->boolValue(), false);
00165 }
00166
00167
00168 Test commandsWithOverlappingArgs() {
00169 ArgList opts;
00170 opts.push_back("--yell=foo");
00171 opts.push_back("fix");
00172 opts.push_back("--help");
00173 opts.push_back("-Q");
00174
00175 Engine2 engine;
00176 ArgList::iterator i = engine.parseList(opts);
00177 assert(i == opts.end());
00178 assert_eq(opts.size(), 0u);
00179 assert_eq(engine.foundCommand(), engine.fix);
00180 assert_eq(engine.scramble_yell->stringValue(), string());
00181 assert_eq(engine.scramble_random->boolValue(), false);
00182 assert_eq(engine.fix_yell->stringValue(), "foo");
00183 assert_eq(engine.fix_quick->boolValue(), true);
00184 assert_eq(engine.help->boolValue(), true);
00185 }
00186
00187
00188 Test commandsWithoutCommand() {
00189 ArgList opts;
00190 opts.push_back("--help");
00191
00192 Engine2 engine;
00193 ArgList::iterator i = engine.parseList(opts);
00194 assert(i == opts.end());
00195 assert_eq(opts.size(), 0u);
00196 assert_eq(engine.foundCommand(), (Engine*)0);
00197 assert_eq(engine.scramble_yell->stringValue(), string());
00198 assert_eq(engine.scramble_random->boolValue(), false);
00199 assert_eq(engine.fix_yell->stringValue(), string());
00200 assert_eq(engine.fix_quick->boolValue(), false);
00201 assert_eq(engine.help->boolValue(), true);
00202 }
00203
00204
00205 Test creationShortcuts() {
00206 MemoryManager mman;
00207 Public<Engine> engine(&mman, "test", "[options]", "test engine", "this is the long description of a test engine");
00208 OptionGroup* group = engine.addGroup("test option group");
00209 BoolOption* testBool = group->add<BoolOption>("tbool", 0, "testbool", "<val>", "a test bool switch");
00210 IntOption* testInt = group->add<IntOption>("tint", 0, "testint", "<val>", "a test int switch");
00211 StringOption* testString = group->add<StringOption>("tstring", 0, "teststring", "<val>", "a test string switch");
00212 BoolOption* testBool1 = engine.add<BoolOption>("tbool", 0, "testbool1", "<val>", "a test bool switch");
00213 IntOption* testInt1 = engine.add<IntOption>("tint", 0, "testint1", "<val>", "a test int switch");
00214 StringOption* testString1 = engine.add<StringOption>("tstring", 0, "teststring1", "<val>", "a test string switch");
00215
00216 ArgList opts;
00217 opts.push_back("--testbool=true");
00218 opts.push_back("--testint=3");
00219 opts.push_back("--teststring=antani");
00220 opts.push_back("--testbool1=true");
00221 opts.push_back("--testint1=5");
00222 opts.push_back("--teststring1=blinda");
00223
00224 ArgList::iterator i = engine.parseList(opts);
00225 assert(i == opts.end());
00226 assert_eq(opts.size(), 0u);
00227 assert_eq(testBool->boolValue(), true);
00228 assert_eq(testInt->intValue(), 3);
00229 assert_eq(testString->stringValue(), "antani");
00230 assert_eq(testBool1->boolValue(), true);
00231 assert_eq(testInt1->intValue(), 5);
00232 assert_eq(testString1->stringValue(), "blinda");
00233 }
00234
00235 };
00236
00237