1 #include "OptionParser.h"
2 
3 #include <cstring>
4 #include <sstream>
5 
6 #include <cppunit/extensions/HelperMacros.h>
7 
8 #include "OptionHandlerImpl.h"
9 #include "Exception.h"
10 #include "util.h"
11 #include "Option.h"
12 #include "array_fun.h"
13 #include "prefs.h"
14 #include "help_tags.h"
15 
16 namespace aria2 {
17 
18 class OptionParserTest : public CppUnit::TestFixture {
19 
20   CPPUNIT_TEST_SUITE(OptionParserTest);
21   CPPUNIT_TEST(testFindAll);
22   CPPUNIT_TEST(testFindByNameSubstring);
23   CPPUNIT_TEST(testFindByTag);
24   CPPUNIT_TEST(testFind);
25   CPPUNIT_TEST(testFindByShortName);
26   CPPUNIT_TEST(testFindById);
27   CPPUNIT_TEST(testParseDefaultValues);
28   CPPUNIT_TEST(testParseArg);
29   CPPUNIT_TEST(testParse);
30   CPPUNIT_TEST(testParseKeyVals);
31   CPPUNIT_TEST_SUITE_END();
32 
33 private:
34   std::shared_ptr<OptionParser> oparser_;
35 
36 public:
setUp()37   void setUp()
38   {
39     oparser_.reset(new OptionParser());
40 
41     OptionHandler* timeout(
42         new DefaultOptionHandler(PREF_TIMEOUT, NO_DESCRIPTION, "ALPHA", "",
43                                  OptionHandler::REQ_ARG, 'A'));
44     timeout->addTag(TAG_BASIC);
45     timeout->setEraseAfterParse(true);
46     oparser_->addOptionHandler(timeout);
47 
48     OptionHandler* dir(new DefaultOptionHandler(PREF_DIR));
49     dir->addTag(TAG_BASIC);
50     dir->addTag(TAG_HTTP);
51     dir->addTag(TAG_FILE);
52     oparser_->addOptionHandler(dir);
53 
54     DefaultOptionHandler* daemon(
55         new DefaultOptionHandler(PREF_DAEMON, NO_DESCRIPTION, "CHARLIE", "",
56                                  OptionHandler::REQ_ARG, 'C'));
57     daemon->hide();
58     daemon->addTag(TAG_FILE);
59     oparser_->addOptionHandler(daemon);
60 
61     OptionHandler* out(new UnitNumberOptionHandler(PREF_OUT, NO_DESCRIPTION,
62                                                    "1M", -1, -1, 'D'));
63     out->addTag(TAG_FILE);
64     oparser_->addOptionHandler(out);
65   }
66 
tearDown()67   void tearDown() {}
68 
69   void testFindAll();
70   void testFindByNameSubstring();
71   void testFindByTag();
72   void testFind();
73   void testFindByShortName();
74   void testFindById();
75   void testParseDefaultValues();
76   void testParseArg();
77   void testParse();
78   void testParseKeyVals();
79 };
80 
81 CPPUNIT_TEST_SUITE_REGISTRATION(OptionParserTest);
82 
testFindAll()83 void OptionParserTest::testFindAll()
84 {
85   std::vector<const OptionHandler*> res = oparser_->findAll();
86   CPPUNIT_ASSERT_EQUAL((size_t)3, res.size());
87   CPPUNIT_ASSERT_EQUAL(std::string("timeout"), std::string(res[0]->getName()));
88   CPPUNIT_ASSERT_EQUAL(std::string("dir"), std::string(res[1]->getName()));
89   CPPUNIT_ASSERT_EQUAL(std::string("out"), std::string(res[2]->getName()));
90 }
91 
testFindByNameSubstring()92 void OptionParserTest::testFindByNameSubstring()
93 {
94   std::vector<const OptionHandler*> res = oparser_->findByNameSubstring("i");
95   CPPUNIT_ASSERT_EQUAL((size_t)2, res.size());
96   CPPUNIT_ASSERT_EQUAL(std::string("timeout"), std::string(res[0]->getName()));
97   CPPUNIT_ASSERT_EQUAL(std::string("dir"), std::string(res[1]->getName()));
98 }
99 
testFindByTag()100 void OptionParserTest::testFindByTag()
101 {
102   std::vector<const OptionHandler*> res = oparser_->findByTag(TAG_FILE);
103   CPPUNIT_ASSERT_EQUAL((size_t)2, res.size());
104   CPPUNIT_ASSERT_EQUAL(std::string("dir"), std::string(res[0]->getName()));
105   CPPUNIT_ASSERT_EQUAL(std::string("out"), std::string(res[1]->getName()));
106 }
107 
testFind()108 void OptionParserTest::testFind()
109 {
110   const OptionHandler* dir = oparser_->find(PREF_DIR);
111   CPPUNIT_ASSERT(dir);
112   CPPUNIT_ASSERT_EQUAL(std::string("dir"), std::string(dir->getName()));
113 
114   const OptionHandler* daemon = oparser_->find(PREF_DAEMON);
115   CPPUNIT_ASSERT(!daemon);
116 
117   const OptionHandler* log = oparser_->find(PREF_LOG);
118   CPPUNIT_ASSERT(!log);
119 }
120 
testFindByShortName()121 void OptionParserTest::testFindByShortName()
122 {
123   const OptionHandler* timeout = oparser_->findByShortName('A');
124   CPPUNIT_ASSERT(timeout);
125   CPPUNIT_ASSERT_EQUAL(std::string("timeout"), std::string(timeout->getName()));
126 
127   CPPUNIT_ASSERT(!oparser_->findByShortName('C'));
128 }
129 
testFindById()130 void OptionParserTest::testFindById()
131 {
132   const OptionHandler* timeout = oparser_->findById(PREF_TIMEOUT->i);
133   CPPUNIT_ASSERT(timeout);
134   CPPUNIT_ASSERT_EQUAL(std::string("timeout"), std::string(timeout->getName()));
135 
136   CPPUNIT_ASSERT(!oparser_->findById(9999));
137 }
138 
testParseDefaultValues()139 void OptionParserTest::testParseDefaultValues()
140 {
141   Option option;
142   oparser_->parseDefaultValues(option);
143   CPPUNIT_ASSERT_EQUAL(std::string("ALPHA"), option.get(PREF_TIMEOUT));
144   CPPUNIT_ASSERT_EQUAL(std::string("1048576"), option.get(PREF_OUT));
145   CPPUNIT_ASSERT_EQUAL(std::string("CHARLIE"), option.get(PREF_DAEMON));
146   CPPUNIT_ASSERT(!option.defined(PREF_DIR));
147 }
148 
testParseArg()149 void OptionParserTest::testParseArg()
150 {
151   Option option;
152   char prog[7];
153   strncpy(prog, "aria2c", sizeof(prog));
154 
155   char optionTimeout[3];
156   strncpy(optionTimeout, "-A", sizeof(optionTimeout));
157   char argTimeout[6];
158   strncpy(argTimeout, "ALPHA", sizeof(argTimeout));
159   char optionDir[8];
160   strncpy(optionDir, "--dir", sizeof(optionDir));
161   char argDir[6];
162   strncpy(argDir, "BRAVO", sizeof(argDir));
163 
164   char nonopt1[8];
165   strncpy(nonopt1, "nonopt1", sizeof(nonopt1));
166   char nonopt2[8];
167   strncpy(nonopt2, "nonopt2", sizeof(nonopt2));
168 
169   char* argv[] = {prog,   optionTimeout, argTimeout, optionDir,
170                   argDir, nonopt1,       nonopt2};
171   int argc = arraySize(argv);
172 
173   std::stringstream s;
174   std::vector<std::string> nonopts;
175 
176   oparser_->parseArg(s, nonopts, argc, argv);
177 
178   CPPUNIT_ASSERT_EQUAL(std::string("timeout=ALPHA\n"
179                                    "dir=BRAVO\n"),
180                        s.str());
181 
182   CPPUNIT_ASSERT_EQUAL((size_t)2, nonopts.size());
183   CPPUNIT_ASSERT_EQUAL(std::string("nonopt1"), nonopts[0]);
184   CPPUNIT_ASSERT_EQUAL(std::string("nonopt2"), nonopts[1]);
185 
186   CPPUNIT_ASSERT_EQUAL(std::string("*****"), std::string(argTimeout));
187 }
188 
testParse()189 void OptionParserTest::testParse()
190 {
191   Option option;
192   std::istringstream in("timeout=Hello\n"
193                         "UNKNOWN=x\n"
194                         "\n"
195                         "dir=World");
196   oparser_->parse(option, in);
197   CPPUNIT_ASSERT_EQUAL(std::string("Hello"), option.get(PREF_TIMEOUT));
198   CPPUNIT_ASSERT_EQUAL(std::string("World"), option.get(PREF_DIR));
199 }
200 
testParseKeyVals()201 void OptionParserTest::testParseKeyVals()
202 {
203   Option option;
204   KeyVals kv;
205   kv.push_back(std::make_pair("timeout", "Hello"));
206   kv.push_back(std::make_pair("UNKNOWN", "x"));
207   kv.push_back(std::make_pair("dir", "World"));
208   oparser_->parse(option, kv);
209   CPPUNIT_ASSERT_EQUAL(std::string("Hello"), option.get(PREF_TIMEOUT));
210   CPPUNIT_ASSERT_EQUAL(std::string("World"), option.get(PREF_DIR));
211 }
212 
213 } // namespace aria2
214