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 noSwitchesAfterFirstArg() {
00093 ArgList opts;
00094 opts.push_back("-b");
00095 opts.push_back("cippo");
00096 opts.push_back("foobar");
00097 opts.push_back("--cabal");
00098
00099 Engine1 engine;
00100 engine.no_switches_after_first_arg = true;
00101 ArgList::iterator i = engine.parseList(opts);
00102 assert(i == opts.begin());
00103 assert_eq(opts.size(), 2u);
00104 assert_eq(string(*opts.begin()), string("foobar"));
00105 assert_eq(string(*opts.rbegin()), string("--cabal"));
00106 assert_eq(engine.antani->boolValue(), false);
00107 assert_eq(engine.blinda->stringValue(), "cippo");
00108 }
00109
00110 Test optsOnly() {
00111 ArgList opts;
00112 opts.push_back("-a");
00113 opts.push_back("foobar");
00114
00115 Engine1 engine;
00116 ArgList::iterator i = engine.parseList(opts);
00117 assert(i == opts.begin());
00118 assert_eq(opts.size(), 1u);
00119 assert_eq(string(*opts.begin()), string("foobar"));
00120 assert_eq(engine.antani->boolValue(), true);
00121 assert_eq(engine.blinda->boolValue(), false);
00122 }
00123
00124 Test clusteredShortOpts() {
00125 ArgList opts;
00126 opts.push_back("-ab");
00127 opts.push_back("cippo");
00128
00129 Engine1 engine;
00130 ArgList::iterator i = engine.parseList(opts);
00131 assert(i == opts.end());
00132 assert_eq(opts.size(), 0u);
00133 assert_eq(engine.antani->boolValue(), true);
00134 assert_eq(engine.blinda->stringValue(), "cippo");
00135 }
00136
00137 Test longOptsWithDashes() {
00138 ArgList opts;
00139 opts.push_back("--an-tani");
00140 opts.push_back("foobar");
00141
00142 Engine1 engine;
00143 ArgList::iterator i = engine.parseList(opts);
00144 assert(i == opts.begin());
00145 assert_eq(opts.size(), 1u);
00146 assert_eq(string(*opts.begin()), string("foobar"));
00147 assert_eq(engine.antani->boolValue(), true);
00148 assert_eq(engine.blinda->boolValue(), false);
00149 }
00150
00151
00152 Test longOptsWithArgs() {
00153 ArgList opts;
00154 opts.push_back("--blinda=cippo");
00155 opts.push_back("foobar");
00156 opts.push_back("--antani");
00157
00158 Engine1 engine;
00159 ArgList::iterator i = engine.parseList(opts);
00160 assert(i == opts.begin());
00161 assert_eq(opts.size(), 1u);
00162 assert_eq(string(*opts.begin()), string("foobar"));
00163 assert_eq(engine.antani->boolValue(), true);
00164 assert_eq(engine.blinda->stringValue(), "cippo");
00165 }
00166
00167 Test commandWithArg() {
00168 ArgList opts;
00169 opts.push_back("--yell=foo");
00170 opts.push_back("mess");
00171 opts.push_back("-r");
00172
00173 Engine2 engine;
00174 ArgList::iterator i = engine.parseList(opts);
00175 assert(i == opts.end());
00176 assert_eq(opts.size(), 0u);
00177 assert_eq(engine.foundCommand(), engine.scramble);
00178 assert_eq(engine.scramble_yell->stringValue(), "foo");
00179 assert_eq(engine.scramble_random->boolValue(), true);
00180 assert_eq(engine.fix_yell->stringValue(), string());
00181 assert_eq(engine.fix_quick->boolValue(), false);
00182 assert_eq(engine.help->boolValue(), false);
00183 }
00184
00185
00186 Test commandsWithOverlappingArgs() {
00187 ArgList opts;
00188 opts.push_back("--yell=foo");
00189 opts.push_back("fix");
00190 opts.push_back("--help");
00191 opts.push_back("-Q");
00192
00193 Engine2 engine;
00194 ArgList::iterator i = engine.parseList(opts);
00195 assert(i == opts.end());
00196 assert_eq(opts.size(), 0u);
00197 assert_eq(engine.foundCommand(), engine.fix);
00198 assert_eq(engine.scramble_yell->stringValue(), string());
00199 assert_eq(engine.scramble_random->boolValue(), false);
00200 assert_eq(engine.fix_yell->stringValue(), "foo");
00201 assert_eq(engine.fix_quick->boolValue(), true);
00202 assert_eq(engine.help->boolValue(), true);
00203 }
00204
00205
00206 Test commandsWithoutCommand() {
00207 ArgList opts;
00208 opts.push_back("--help");
00209
00210 Engine2 engine;
00211 ArgList::iterator i = engine.parseList(opts);
00212 assert(i == opts.end());
00213 assert_eq(opts.size(), 0u);
00214 assert_eq(engine.foundCommand(), (Engine*)0);
00215 assert_eq(engine.scramble_yell->stringValue(), string());
00216 assert_eq(engine.scramble_random->boolValue(), false);
00217 assert_eq(engine.fix_yell->stringValue(), string());
00218 assert_eq(engine.fix_quick->boolValue(), false);
00219 assert_eq(engine.help->boolValue(), true);
00220 }
00221
00222
00223 Test creationShortcuts() {
00224 MemoryManager mman;
00225 Public<Engine> engine(&mman, "test", "[options]", "test engine", "this is the long description of a test engine");
00226 OptionGroup* group = engine.addGroup("test option group");
00227 BoolOption* testBool = group->add<BoolOption>("tbool", 0, "testbool", "<val>", "a test bool switch");
00228 IntOption* testInt = group->add<IntOption>("tint", 0, "testint", "<val>", "a test int switch");
00229 StringOption* testString = group->add<StringOption>("tstring", 0, "teststring", "<val>", "a test string switch");
00230 BoolOption* testBool1 = engine.add<BoolOption>("tbool", 0, "testbool1", "<val>", "a test bool switch");
00231 IntOption* testInt1 = engine.add<IntOption>("tint", 0, "testint1", "<val>", "a test int switch");
00232 StringOption* testString1 = engine.add<StringOption>("tstring", 0, "teststring1", "<val>", "a test string switch");
00233
00234 ArgList opts;
00235 opts.push_back("--testbool=true");
00236 opts.push_back("--testint=3");
00237 opts.push_back("--teststring=antani");
00238 opts.push_back("--testbool1=true");
00239 opts.push_back("--testint1=5");
00240 opts.push_back("--teststring1=blinda");
00241
00242 ArgList::iterator i = engine.parseList(opts);
00243 assert(i == opts.end());
00244 assert_eq(opts.size(), 0u);
00245 assert_eq(testBool->boolValue(), true);
00246 assert_eq(testInt->intValue(), 3);
00247 assert_eq(testString->stringValue(), "antani");
00248 assert_eq(testBool1->boolValue(), true);
00249 assert_eq(testInt1->intValue(), 5);
00250 assert_eq(testString1->stringValue(), "blinda");
00251 }
00252
00253 };
00254
00255