1//
2// OptionProcessorTest.cpp
3//
4// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "OptionProcessorTest.h"
12#include "Poco/CppUnit/TestCaller.h"
13#include "Poco/CppUnit/TestSuite.h"
14#include "Poco/Util/Option.h"
15#include "Poco/Util/OptionSet.h"
16#include "Poco/Util/OptionProcessor.h"
17#include "Poco/Util/OptionException.h"
18
19
20using Poco::Util::Option;
21using Poco::Util::OptionSet;
22using Poco::Util::OptionProcessor;
23
24
25OptionProcessorTest::OptionProcessorTest(const std::string& name): CppUnit::TestCase(name)
26{
27}
28
29
30OptionProcessorTest::~OptionProcessorTest()
31{
32}
33
34
35void OptionProcessorTest::testUnix()
36{
37 OptionSet set;
38 set.addOption(
39 Option("include-dir", "I", "specify a search path for locating header files")
40 .required(false)
41 .repeatable(true)
42 .argument("path"));
43
44 set.addOption(
45 Option("library-dir", "L", "specify a search path for locating library files")
46 .required(false)
47 .repeatable(true)
48 .argument("path"));
49
50 set.addOption(
51 Option("output", "o", "specify the output file", true)
52 .argument("file", true));
53
54 set.addOption(
55 Option("verbose", "v")
56 .description("enable verbose mode")
57 .required(false)
58 .repeatable(false));
59
60 set.addOption(
61 Option("optimize", "O")
62 .description("enable optimization")
63 .required(false)
64 .repeatable(false)
65 .argument("level", false)
66 .group("mode"));
67
68 set.addOption(
69 Option("debug", "g")
70 .description("generate debug information")
71 .required(false)
72 .repeatable(false)
73 .group("mode"));
74
75 set.addOption(
76 Option("info", "i")
77 .description("print information")
78 .required(false)
79 .repeatable(false));
80
81 OptionProcessor p1(set);
82 std::string name;
83 std::string value;
84
85 assertTrue (p1.process("-I/usr/include", name, value));
86 assertTrue (name == "include-dir");
87 assertTrue (value == "/usr/include");
88
89 assertTrue (p1.process("--include:/usr/local/include", name, value));
90 assertTrue (name == "include-dir");
91 assertTrue (value == "/usr/local/include");
92
93 assertTrue (p1.process("-I", name, value));
94 assertTrue (name.empty());
95 assertTrue (value.empty());
96 assertTrue (p1.process("/usr/include", name, value));
97 assertTrue (name == "include-dir");
98 assertTrue (value == "/usr/include");
99
100 assertTrue (p1.process("-I", name, value));
101 assertTrue (name.empty());
102 assertTrue (value.empty());
103 assertTrue (p1.process("-L", name, value));
104 assertTrue (name == "include-dir");
105 assertTrue (value == "-L");
106
107 assertTrue (p1.process("--lib=/usr/local/lib", name, value));
108 assertTrue (name == "library-dir");
109 assertTrue (value == "/usr/local/lib");
110
111 assertTrue (p1.process("-ofile", name, value));
112 assertTrue (name == "output");
113 assertTrue (value == "file");
114
115 assertTrue (!p1.process("src/file.cpp", name, value));
116 assertTrue (!p1.process("/src/file.cpp", name, value));
117
118 try
119 {
120 p1.process("--output:file", name, value);
121 fail("duplicate - must throw");
122 }
123 catch (Poco::Util::DuplicateOptionException&)
124 {
125 }
126
127 assertTrue (p1.process("-g", name, value));
128 assertTrue (name == "debug");
129 assertTrue (value == "");
130
131 try
132 {
133 p1.process("--optimize", name, value);
134 fail("incompatible - must throw");
135 }
136 catch (Poco::Util::IncompatibleOptionsException&)
137 {
138 }
139
140 try
141 {
142 p1.process("-x", name, value);
143 fail("unknown option - must throw");
144 }
145 catch (Poco::Util::UnknownOptionException&)
146 {
147 }
148
149 try
150 {
151 p1.process("--in", name, value);
152 fail("ambiguous option - must throw");
153 }
154 catch (Poco::Util::AmbiguousOptionException&)
155 {
156 }
157}
158
159
160void OptionProcessorTest::testDefault()
161{
162 OptionSet set;
163 set.addOption(
164 Option("include-dir", "I", "specify a search path for locating header files")
165 .required(false)
166 .repeatable(true)
167 .argument("path"));
168
169 set.addOption(
170 Option("library-dir", "L", "specify a search path for locating library files")
171 .required(false)
172 .repeatable(true)
173 .argument("path"));
174
175 set.addOption(
176 Option("output", "o", "specify the output file", true)
177 .argument("file", true));
178
179 set.addOption(
180 Option("verbose", "v")
181 .description("enable verbose mode")
182 .required(false)
183 .repeatable(false));
184
185 set.addOption(
186 Option("optimize", "O")
187 .description("enable optimization")
188 .required(false)
189 .repeatable(false)
190 .argument("level", false)
191 .group("mode"));
192
193 set.addOption(
194 Option("debug", "g")
195 .description("generate debug information")
196 .required(false)
197 .repeatable(false)
198 .group("mode"));
199
200 set.addOption(
201 Option("info", "i")
202 .description("print information")
203 .required(false)
204 .repeatable(false));
205
206 OptionProcessor p1(set);
207 p1.setUnixStyle(false);
208 std::string name;
209 std::string value;
210
211 assertTrue (p1.process("/Inc:/usr/include", name, value));
212 assertTrue (name == "include-dir");
213 assertTrue (value == "/usr/include");
214
215 assertTrue (p1.process("/include:/usr/local/include", name, value));
216 assertTrue (name == "include-dir");
217 assertTrue (value == "/usr/local/include");
218
219 assertTrue (p1.process("/Inc", name, value));
220 assertTrue (name.empty());
221 assertTrue (value.empty());
222 assertTrue (p1.process("/usr/include", name, value));
223 assertTrue (name == "include-dir");
224 assertTrue (value == "/usr/include");
225
226 assertTrue (p1.process("/lib=/usr/local/lib", name, value));
227 assertTrue (name == "library-dir");
228 assertTrue (value == "/usr/local/lib");
229
230 assertTrue (p1.process("/out:file", name, value));
231 assertTrue (name == "output");
232 assertTrue (value == "file");
233
234 assertTrue (!p1.process("src/file.cpp", name, value));
235 assertTrue (!p1.process("\\src\\file.cpp", name, value));
236
237 try
238 {
239 p1.process("/output:file", name, value);
240 fail("duplicate - must throw");
241 }
242 catch (Poco::Util::DuplicateOptionException&)
243 {
244 }
245
246 assertTrue (p1.process("/debug", name, value));
247 assertTrue (name == "debug");
248 assertTrue (value == "");
249
250 try
251 {
252 p1.process("/OPT", name, value);
253 fail("incompatible - must throw");
254 }
255 catch (Poco::Util::IncompatibleOptionsException&)
256 {
257 }
258
259 try
260 {
261 p1.process("/x", name, value);
262 fail("unknown option - must throw");
263 }
264 catch (Poco::Util::UnknownOptionException&)
265 {
266 }
267
268 try
269 {
270 p1.process("/in", name, value);
271 fail("ambiguous option - must throw");
272 }
273 catch (Poco::Util::AmbiguousOptionException&)
274 {
275 }
276}
277
278
279void OptionProcessorTest::testRequired()
280{
281 OptionSet set;
282 set.addOption(
283 Option("option", "o")
284 .required(true)
285 .repeatable(true));
286
287 OptionProcessor p1(set);
288 std::string name;
289 std::string value;
290
291 try
292 {
293 p1.checkRequired();
294 fail("no options specified - must throw");
295 }
296 catch (Poco::Util::MissingOptionException&)
297 {
298 }
299
300 assertTrue (p1.process("-o", name, value));
301 p1.checkRequired();
302}
303
304
305void OptionProcessorTest::testArgs()
306{
307 OptionSet set;
308 set.addOption(
309 Option("include-dir", "I", "specify a search path for locating header files")
310 .required(false)
311 .repeatable(true)
312 .argument("path"));
313
314 set.addOption(
315 Option("optimize", "O")
316 .description("enable optimization")
317 .required(false)
318 .repeatable(true)
319 .argument("level", false));
320
321 OptionProcessor p1(set);
322 std::string name;
323 std::string value;
324
325 assertTrue (p1.process("-I/usr/include", name, value));
326 assertTrue (name == "include-dir");
327 assertTrue (value == "/usr/include");
328
329 assertTrue (p1.process("--include:/usr/local/include", name, value));
330 assertTrue (name == "include-dir");
331 assertTrue (value == "/usr/local/include");
332
333 assertTrue (p1.process("-I", name, value));
334 assertTrue (name.empty());
335 assertTrue (value.empty());
336 assertTrue (p1.process("/usr/include", name, value));
337 assertTrue (name == "include-dir");
338 assertTrue (value == "/usr/include");
339
340 assertTrue (p1.process("-I", name, value));
341 assertTrue (name.empty());
342 assertTrue (value.empty());
343 assertTrue (p1.process("-L", name, value));
344 assertTrue (name == "include-dir");
345 assertTrue (value == "-L");
346
347 assertTrue (p1.process("-O", name, value));
348 assertTrue (name == "optimize");
349 assertTrue (value.empty());
350
351 assertTrue (p1.process("-O2", name, value));
352 assertTrue (name == "optimize");
353 assertTrue (value == "2");
354}
355
356
357void OptionProcessorTest::setUp()
358{
359}
360
361
362void OptionProcessorTest::tearDown()
363{
364}
365
366
367CppUnit::Test* OptionProcessorTest::suite()
368{
369 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("OptionProcessorTest");
370
371 CppUnit_addTest(pSuite, OptionProcessorTest, testUnix);
372 CppUnit_addTest(pSuite, OptionProcessorTest, testDefault);
373 CppUnit_addTest(pSuite, OptionProcessorTest, testRequired);
374 CppUnit_addTest(pSuite, OptionProcessorTest, testArgs);
375
376 return pSuite;
377}
378