1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <climits>
17 #include <cstdint>
18 #include <iostream>
19 #include <string>
20 #include <string_view>
21 #include <vector>
22
23 #include "cl_option.h"
24 #include "cl_parser.h"
25 #include "gtest/gtest.h"
26
27 /* ##################### own OptionType for the test #####################
28 * ####################################################################### */
29
30 static bool utCLTypeChecker = false;
31
32 /* You can create own OptionType and Set own Option Parser for him, like this: */
33 class UTCLType {
34 public:
35 UTCLType() = default;
UTCLType(const std::string & data)36 UTCLType(const std::string &data) : data(data) {};
37
38 std::string data;
39 };
operator ==(const UTCLType & opt,const std::string & str)40 bool operator==(const UTCLType &opt, const std::string &str)
41 {
42 bool ret = (opt.data == str) ? true : false;
43 return ret;
44 }
operator ==(const std::string & str,const UTCLType & opt)45 bool operator==(const std::string &str, const UTCLType &opt)
46 {
47 bool ret = (opt.data == str) ? true : false;
48 return ret;
49 }
50
51 template <>
Clear()52 void maplecl::Option<UTCLType>::Clear()
53 {
54 value.data = "";
55 }
56
57 template <>
GetRawValues()58 std::vector<std::string> maplecl::Option<UTCLType>::GetRawValues()
59 {
60 return std::vector<std::string>();
61 }
62
63 template <>
Parse(ssize_t & argsIndex,const std::deque<std::string_view> & args,KeyArg & keyArg)64 maplecl::RetCode maplecl::Option<UTCLType>::Parse(ssize_t &argsIndex, const std::deque<std::string_view> &args,
65 KeyArg &keyArg)
66 {
67 utCLTypeChecker = true;
68 RetCode err = maplecl::RetCode::noError;
69
70 if (args[argsIndex] != "--uttype") {
71 return maplecl::RetCode::parsingErr;
72 }
73
74 ssize_t localArgsIndex = argsIndex + 1;
75 /* Second command line argument does not exist */
76 if (localArgsIndex >= args.size() || args[localArgsIndex].empty()) {
77 return RetCode::valueEmpty;
78 }
79
80 /* In this example, the value of UTCLType must be --UTCLTypeOption */
81 if (args[localArgsIndex] == "--UTCLTypeOption") {
82 argsIndex += 2; /* 2 index: 1 for Option Key, 1 for Value */
83 err = maplecl::RetCode::noError;
84 SetValue(UTCLType("--UTCLTypeOption"));
85 } else {
86 err = maplecl::RetCode::valueEmpty;
87 }
88
89 return err;
90 }
91
92 /* ########################## Test Options ###############################
93 * ####################################################################### */
94
95 namespace testopts {
96
97 maplecl::OptionCategory defaultCategory;
98 maplecl::OptionCategory testCategory1;
99 maplecl::OptionCategory testCategory2;
100
101 maplecl::Option<bool> booloptEnabled({"--boole"}, "");
102 maplecl::Option<bool> booloptDisabled({"--boold"}, "");
103
104 maplecl::Option<std::string> testStr({"--str"}, "");
105
106 maplecl::Option<uint8_t> testUint8({"--uint8"}, "");
107 maplecl::Option<uint16_t> testUint16({"--uint16"}, "");
108
109 maplecl::Option<int32_t> testInt32({"--int32"}, "");
110 maplecl::Option<uint32_t> testUint32({"--uint32"}, "");
111
112 maplecl::Option<int64_t> testInt64({"--int64"}, "");
113 maplecl::Option<uint64_t> testUint64({"--uint64"}, "");
114
115 maplecl::Option<bool> doubleDefinedOpt({"--tst", "-t"}, "");
116
117 maplecl::Option<bool> defaultBool({"--defbool"}, "", maplecl::Init(true));
118 maplecl::Option<std::string> defaultString({"--defstring"}, "", maplecl::Init("Default String"));
119 maplecl::Option<int32_t> defaultDigit({"--defdigit"}, "", maplecl::Init(-42));
120
121 maplecl::Option<bool> enable({"--enable"}, "", maplecl::Init(true), maplecl::DisableWith("--no-enable"));
122 maplecl::Option<bool> enable2({"--enable2"}, "", maplecl::Init(true),
123 maplecl::DisableEvery({"--no-enable2", "--disable"}));
124
125 maplecl::Option<std::string> macro({"-JOIN"}, "", maplecl::joinedValue);
126 maplecl::Option<int32_t> joindig({"--joindig"}, "", maplecl::joinedValue);
127
128 maplecl::Option<std::string> equalStr({"--eqstr"}, "");
129 maplecl::Option<int32_t> equalDig({"--eqdig"}, "");
130
131 maplecl::Option<int32_t> reqVal({"--reqval"}, "", maplecl::requiredValue, maplecl::Init(-42));
132 maplecl::Option<int32_t> optVal({"--optval"}, "", maplecl::optionalValue, maplecl::Init(-42));
133 maplecl::Option<int32_t> woVal({"--woval"}, "", maplecl::disallowedValue, maplecl::Init(-42));
134
135 maplecl::Option<bool> cat1Opt1({"--c1opt1"}, "", {testCategory1});
136 maplecl::Option<bool> cat12Opt({"--c12opt"}, "", {testCategory1, testCategory2});
137
138 maplecl::Option<UTCLType> uttype({"--uttype"}, "");
139
140 maplecl::Option<bool> desc({"--desc"}, "It's test description");
141
142 maplecl::Option<bool> dup({"--dup"}, "");
143
144 maplecl::List<std::string> vecString({"--vecstr"}, "");
145 maplecl::List<uint32_t> vecDig({"--vecdig"}, "");
146 maplecl::List<bool> vecBool({"--vecbool"}, "", maplecl::DisableWith("--no-vecbool"));
147
148 maplecl::List<std::string> vecStringDef({"--vecstrdef"}, "", maplecl::Init("Default"));
149 maplecl::List<uint32_t> vecDigDef({"--vecdigdef"}, "", maplecl::Init(100));
150 maplecl::List<bool> vecBoolDef({"--vecbooldef"}, "", maplecl::DisableWith("--no-vecbooldef"), maplecl::Init(true));
151
152 maplecl::Option<std::string> common({"--common"}, "");
153 } // namespace testopts
154
155 /* ################# "Enable/Disable Boolean Options" Test ###############
156 * ####################################################################### */
157
TEST(clOptions,boolOpt)158 TEST(clOptions, boolOpt)
159 {
160 // create command line
161 const char *argv[] = {"CLTest", // program name
162 "--boole", nullptr};
163 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
164
165 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
166 ASSERT_EQ(err, maplecl::RetCode::noError);
167
168 bool isSet = testopts::booloptEnabled;
169 ASSERT_EQ(isSet, true);
170
171 isSet = testopts::booloptDisabled;
172 ASSERT_EQ(isSet, false);
173 }
174
175 /* ################# "Set and Comapare Options" Test #####################
176 * ####################################################################### */
177
TEST(clOptions,comparableOpt1)178 TEST(clOptions, comparableOpt1)
179 {
180 // create command line
181 const char *argv[] = {"CLTest", // program name
182 "--boole", "--str", "DATA", "--int32", "-42", nullptr};
183 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
184
185 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
186 ASSERT_EQ(err, maplecl::RetCode::noError);
187
188 std::string lStr = "data";
189 int32_t lDig = 42;
190 bool lBool = false;
191
192 bool isSet = (testopts::booloptEnabled == true);
193 ASSERT_EQ(isSet, true);
194 isSet = (testopts::booloptEnabled == lBool);
195 ASSERT_EQ(isSet, false);
196
197 isSet = (testopts::testStr == "DATA");
198 ASSERT_EQ(isSet, true);
199 isSet = ("DATA" == testopts::testStr);
200 ASSERT_EQ(isSet, true);
201 isSet = (testopts::testStr == lStr);
202 ASSERT_EQ(isSet, false);
203
204 isSet = (testopts::testInt32 == -42);
205 ASSERT_EQ(isSet, true);
206 isSet = (-42 == testopts::testInt32);
207 ASSERT_EQ(isSet, true);
208 isSet = (testopts::testInt32 == lDig);
209 ASSERT_EQ(isSet, false);
210 }
211
TEST(clOptions,IncorrectVal)212 TEST(clOptions, IncorrectVal)
213 {
214 // create command line
215 const char *argv[] = {"CLTest", // program name
216 "--str", "--boole", nullptr};
217 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
218
219 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
220 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
221
222 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
223 ASSERT_EQ(badArgs.size(), 1);
224 ASSERT_EQ(badArgs[0].first, "--str");
225 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::valueEmpty);
226
227 bool isSet = (testopts::booloptEnabled == true);
228 ASSERT_EQ(isSet, true);
229 }
230
231 /* ################# "Set Digital Options" Test ##########################
232 * ####################################################################### */
233
TEST(clOptions,digitTestMaxVal)234 TEST(clOptions, digitTestMaxVal)
235 {
236 // create command line
237 const char *argv[] = {"CLTest", // program name
238 "--uint8", "255",
239 "--uint16", "65535",
240 "--int32", "2147483647",
241 "--uint32", "4294967295",
242 "--int64", "9223372036854775807",
243 "--uint64", "18446744073709551615",
244 nullptr};
245 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
246
247 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
248 ASSERT_EQ(err, maplecl::RetCode::noError);
249
250 uint8_t uint8Dig = testopts::testUint8;
251 ASSERT_EQ(uint8Dig, (1 << 8) - 1);
252
253 uint16_t uint16Dig = testopts::testUint16;
254 ASSERT_EQ(uint16Dig, (1 << 16) - 1);
255
256 uint8_t uint8Dig = testopts::testUint8;
257 ASSERT_EQ(uint8Dig, (1 << 8) - 1);
258
259 uint16_t uint16Dig = testopts::testUint16;
260 ASSERT_EQ(uint16Dig, (1 << 16) - 1);
261
262 int32_t int32Dig = testopts::testInt32;
263 ASSERT_EQ(int32Dig, INT_MAX);
264
265 uint32_t uint32Dig = testopts::testUint32;
266 ASSERT_EQ(uint32Dig, UINT_MAX);
267
268 int64_t int64Dig = testopts::testInt64;
269 ASSERT_EQ(int64Dig, LLONG_MAX);
270
271 uint64_t uint64Dig = testopts::testUint64;
272 ASSERT_EQ(uint64Dig, ULLONG_MAX);
273 }
274
TEST(clOptions,digitTestNegativeVal1)275 TEST(clOptions, digitTestNegativeVal1)
276 {
277 // create command line
278 const char *argv[] = {"CLTest", // program name
279 "--uint32", "-10", nullptr};
280 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
281
282 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
283 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
284
285 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
286 ASSERT_EQ(badArgs.size(), 2);
287 ASSERT_EQ(badArgs[0].first, "--uint32");
288 ASSERT_EQ(badArgs[1].first, "-10");
289 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::incorrectValue);
290 ASSERT_EQ(badArgs[1].second, maplecl::RetCode::notRegistered);
291 }
292
TEST(clOptions,digitTestNegativeVal2)293 TEST(clOptions, digitTestNegativeVal2)
294 {
295 // create command line
296 const char *argv[] = {"CLTest", // program name
297 "--uint64", "-10", nullptr};
298 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
299
300 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
301 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
302
303 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
304 ASSERT_EQ(badArgs.size(), 2);
305 ASSERT_EQ(badArgs[0].first, "--uint64");
306 ASSERT_EQ(badArgs[1].first, "-10");
307 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::incorrectValue);
308 ASSERT_EQ(badArgs[1].second, maplecl::RetCode::notRegistered);
309 }
310
TEST(clOptions,digitTestNegativeVal3)311 TEST(clOptions, digitTestNegativeVal3)
312 {
313 // create command line
314 const char *argv[] = {"CLTest", // program name
315 "--int32", "-2147483648", "--int64", "-9223372036854775808", nullptr};
316 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
317
318 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
319 ASSERT_EQ(err, maplecl::RetCode::noError);
320
321 int64_t int64Dig = testopts::testInt64;
322 ASSERT_EQ(int64Dig, LLONG_MIN);
323 }
324
TEST(clOptions,digitIncorrectPrefix)325 TEST(clOptions, digitIncorrectPrefix)
326 {
327 // create command line
328 const char *argv[] = {"CLTest", // program name
329 "--int32", "--10", nullptr};
330 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
331
332 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
333 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
334
335 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
336 ASSERT_EQ(badArgs.size(), 2);
337 ASSERT_EQ(badArgs[0].first, "--int32");
338 ASSERT_EQ(badArgs[1].first, "--10");
339 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::incorrectValue);
340 ASSERT_EQ(badArgs[1].second, maplecl::RetCode::notRegistered);
341 }
342
TEST(clOptions,digitIncorrectVal)343 TEST(clOptions, digitIncorrectVal)
344 {
345 // create command line
346 const char *argv[] = {"CLTest", // program name
347 "--int32", "INCORRECT", nullptr};
348 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
349
350 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
351 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
352
353 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
354 ASSERT_EQ(badArgs.size(), 2);
355 ASSERT_EQ(badArgs[0].first, "--int32");
356 ASSERT_EQ(badArgs[1].first, "INCORRECT");
357 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::incorrectValue);
358 ASSERT_EQ(badArgs[1].second, maplecl::RetCode::notRegistered);
359 }
360
361 /* ################# "Set out of range Value in Option" Test #############
362 * ####################################################################### */
363
TEST(clOptions,digitTestOutOfRange1)364 TEST(clOptions, digitTestOutOfRange1)
365 {
366 // create command line
367 const char *argv[] = {"CLTest", // program name
368 "--int32", "-2147483649", nullptr};
369 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
370
371 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
372 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
373
374 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
375 ASSERT_EQ(badArgs.size(), 2);
376 ASSERT_EQ(badArgs[0].first, "--int32");
377 ASSERT_EQ(badArgs[1].first, "-2147483649");
378 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::outOfRange);
379 ASSERT_EQ(badArgs[1].second, maplecl::RetCode::notRegistered);
380 }
381
TEST(clOptions,digitTestOutOfRange2)382 TEST(clOptions, digitTestOutOfRange2)
383 {
384 // create command line
385 const char *argv[] = {"CLTest", // program name
386 "--uint32", "4294967296", "--uint16", "65536", "--uint8", "256", nullptr};
387 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
388
389 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
390 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
391
392 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
393 ASSERT_EQ(badArgs.size(), 6);
394 ASSERT_EQ(badArgs[0].first, "--uint32");
395 ASSERT_EQ(badArgs[1].first, "4294967296");
396 ASSERT_EQ(badArgs[2].first, "--uint16");
397 ASSERT_EQ(badArgs[3].first, "65536");
398 ASSERT_EQ(badArgs[4].first, "--uint8");
399 ASSERT_EQ(badArgs[5].first, "256");
400 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::outOfRange);
401 ASSERT_EQ(badArgs[1].second, maplecl::RetCode::notRegistered);
402 ASSERT_EQ(badArgs[2].second, maplecl::RetCode::outOfRange);
403 ASSERT_EQ(badArgs[3].second, maplecl::RetCode::notRegistered);
404 ASSERT_EQ(badArgs[4].second, maplecl::RetCode::outOfRange);
405 ASSERT_EQ(badArgs[5].second, maplecl::RetCode::notRegistered);
406 }
407
TEST(clOptions,digitTestOutOfRange3)408 TEST(clOptions, digitTestOutOfRange3)
409 {
410 // create command line
411 const char *argv[] = {"CLTest", // program name
412 "--int64", "-9223372036854775809", nullptr};
413 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
414
415 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
416 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
417
418 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
419 ASSERT_EQ(badArgs.size(), 2);
420 ASSERT_EQ(badArgs[0].first, "--int64");
421 ASSERT_EQ(badArgs[1].first, "-9223372036854775809");
422 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::outOfRange);
423 ASSERT_EQ(badArgs[1].second, maplecl::RetCode::notRegistered);
424 }
425
TEST(clOptions,digitTestOutOfRange4)426 TEST(clOptions, digitTestOutOfRange4)
427 {
428 // create command line
429 const char *argv[] = {"CLTest", // program name
430 "--uint64", "18446744073709551616", nullptr};
431 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
432
433 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
434 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
435
436 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
437 ASSERT_EQ(badArgs.size(), 2);
438 ASSERT_EQ(badArgs[0].first, "--uint64");
439 ASSERT_EQ(badArgs[1].first, "18446744073709551616");
440 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::outOfRange);
441 ASSERT_EQ(badArgs[1].second, maplecl::RetCode::notRegistered);
442 }
443
444 /* ################# Check double option name definition #################
445 * ####################################################################### */
446
TEST(clOptions,doubleDef1)447 TEST(clOptions, doubleDef1)
448 {
449 // create command line
450 const char *argv[] = {"CLTest", // program name
451 "--tst", nullptr};
452 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
453
454 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
455 ASSERT_EQ(err, maplecl::RetCode::noError);
456
457 bool isSet = testopts::doubleDefinedOpt;
458 ASSERT_EQ(isSet, true);
459 }
460
TEST(clOptions,doubleDef2)461 TEST(clOptions, doubleDef2)
462 {
463 // create command line
464 const char *argv[] = {"CLTest", // program name
465 "-t", nullptr};
466 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
467
468 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
469 ASSERT_EQ(err, maplecl::RetCode::noError);
470
471 bool isSet = testopts::doubleDefinedOpt;
472 ASSERT_EQ(isSet, true);
473 }
474
475 /* ################# Check default option initialization #################
476 * ####################################################################### */
477
TEST(clOptions,defaultVal)478 TEST(clOptions, defaultVal)
479 {
480 // create command line
481 const char *argv[] = {"CLTest", // program name
482 nullptr};
483 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
484
485 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
486 ASSERT_EQ(err, maplecl::RetCode::noError);
487
488 /* Default Options are not set in command line but initialized with default value */
489 bool isSet = testopts::defaultBool;
490 ASSERT_EQ(isSet, true);
491
492 std::string defStr = testopts::defaultString;
493 ASSERT_EQ(defStr, "Default String");
494
495 int32_t defaultDigit = testopts::defaultDigit;
496 ASSERT_EQ(defaultDigit, -42);
497 }
498
499 /* ########## Check Option disabling with additional no-opt name #########
500 * ####################################################################### */
501
502 /* check that testopts::enable is enabled by default.
503 * It's needed to be sure that --no-enable disables this option */
TEST(clOptions,disableOpt1)504 TEST(clOptions, disableOpt1)
505 {
506 // create command line
507 const char *argv[] = {"CLTest", // program name
508 nullptr};
509 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
510
511 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
512 ASSERT_EQ(err, maplecl::RetCode::noError);
513
514 bool isSet = testopts::enable;
515 ASSERT_EQ(isSet, true);
516 }
517
TEST(clOptions,disableOpt2)518 TEST(clOptions, disableOpt2)
519 {
520 // create command line
521 const char *argv[] = {"CLTest", // program name
522 "--no-enable", nullptr};
523 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
524
525 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
526 ASSERT_EQ(err, maplecl::RetCode::noError);
527
528 bool isSet = testopts::enable;
529 ASSERT_EQ(isSet, false);
530 }
531
532 /* check that testopts::enable2 is enabled by default.
533 * It's needed to be sure that --no-enable2 and --disable disable this option.
534 * This test check that we can set the vector of disable options with DisableWith("--no-enable2", "--disable")
535 */
TEST(clOptions,disableOpt3)536 TEST(clOptions, disableOpt3)
537 {
538 // create command line
539 const char *argv[] = {"CLTest", // program name
540 nullptr};
541 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
542
543 auto err = cl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
544 ASSERT_EQ(err, cl::RetCode::noError);
545
546 bool isSet = testopts::enable2;
547 ASSERT_EQ(isSet, true);
548 }
549
TEST(clOptions,disableOpt4)550 TEST(clOptions, disableOpt4)
551 {
552 // create command line
553 const char *argv[] = {"CLTest", // program name
554 "--disable", nullptr};
555 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
556
557 auto err = cl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
558 ASSERT_EQ(err, cl::RetCode::noError);
559
560 /* --disable must disable the option */
561 bool isSet = testopts::enable2;
562 ASSERT_EQ(isSet, false);
563
564 /* Reset to reapeat the test with --no-enable2 */
565 cl::CommandLine::GetCommandLine().Clear();
566 isSet = testopts::enable2;
567 ASSERT_EQ(isSet, true);
568
569 const char *argv2[] = {"CLTest", // program name
570 "--no-enable2", nullptr};
571
572 err = cl::CommandLine::GetCommandLine().Parse(argc, (char **)argv2);
573 ASSERT_EQ(err, cl::RetCode::noError);
574
575 /* --no-enable2 must disable the option */
576 isSet = testopts::enable2;
577 ASSERT_EQ(isSet, false);
578 }
579
580 /* ################# Check Joined Options ################################
581 * ####################################################################### */
582
TEST(clOptions,joinedOpt)583 TEST(clOptions, joinedOpt)
584 {
585 // create command line
586 const char *argv[] = {"CLTest", // program name
587 "-JOINMACRO", "--joindig-42", nullptr};
588 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
589
590 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
591 ASSERT_EQ(err, maplecl::RetCode::noError);
592
593 std::string joinOpt = testopts::macro;
594 ASSERT_EQ(joinOpt, "MACRO");
595
596 int32_t joinDig = testopts::joindig;
597 ASSERT_EQ(joinDig, -42);
598 }
599
600 /* ################# Check Options like --opt=value ######################
601 * ####################################################################### */
602
TEST(clOptions,equalOpt)603 TEST(clOptions, equalOpt)
604 {
605 // create command line
606 const char *argv[] = {"CLTest", // program name
607 "--eqstr=EQUALSTRING", "--eqdig=-42", nullptr};
608 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
609
610 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
611 ASSERT_EQ(err, maplecl::RetCode::noError);
612
613 std::string equalStr = testopts::equalStr;
614 ASSERT_EQ(equalStr, "EQUALSTRING");
615
616 int32_t equalDig = testopts::equalDig;
617 ASSERT_EQ(equalDig, -42);
618 }
619
TEST(clOptions,equalOptErr)620 TEST(clOptions, equalOptErr)
621 {
622 // create command line
623 const char *argv[] = {"CLTest", // program name
624 "--eqstr=", "--eqdig=", nullptr};
625 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
626
627 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
628 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
629
630 /* --woval must not contain any key values, so 20 will be handled as second key */
631 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
632 ASSERT_EQ(badArgs.size(), 2);
633 ASSERT_EQ(badArgs[0].first, "--eqstr=");
634 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::valueEmpty);
635
636 ASSERT_EQ(badArgs[1].first, "--eqdig=");
637 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::valueEmpty);
638 }
639
TEST(clOptions,joinedEqualOpt)640 TEST(clOptions, joinedEqualOpt)
641 {
642 // create command line
643 const char *argv[] = {"CLTest", // program name
644 "-JOINTEST=20", nullptr};
645 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
646
647 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
648 ASSERT_EQ(err, maplecl::RetCode::noError);
649
650 std::string joinOpt = testopts::macro;
651 ASSERT_EQ(joinOpt, "TEST=20");
652 }
653
654 /* ################# Check Options with required Value ###################
655 * ####################################################################### */
656
TEST(clOptions,expectedVal1)657 TEST(clOptions, expectedVal1)
658 {
659 // create command line
660 const char *argv[] = {"CLTest", // program name
661 "--reqval", "--boole", nullptr};
662 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
663
664 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
665 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
666
667 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
668 ASSERT_EQ(badArgs.size(), 1);
669 ASSERT_EQ(badArgs[0].first, "--reqval");
670 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::incorrectValue);
671
672 bool isSet = testopts::booloptEnabled;
673 ASSERT_EQ(isSet, true);
674 }
675
TEST(clOptions,expectedVal2)676 TEST(clOptions, expectedVal2)
677 {
678 // create command line
679 const char *argv[] = {"CLTest", // program name
680 "--reqval", "20", nullptr};
681 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
682
683 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
684 ASSERT_EQ(err, maplecl::RetCode::noError);
685
686 int32_t equalDig = testopts::reqVal;
687 ASSERT_EQ(equalDig, 20);
688 }
689
TEST(clOptions,expectedVal3)690 TEST(clOptions, expectedVal3)
691 {
692 // create command line
693 const char *argv[] = {"CLTest", // program name
694 "--optval", nullptr};
695 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
696
697 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
698 ASSERT_EQ(err, maplecl::RetCode::noError);
699
700 int32_t equalDig = testopts::optVal;
701 ASSERT_EQ(equalDig, -42);
702 }
703
TEST(clOptions,expectedVal4)704 TEST(clOptions, expectedVal4)
705 {
706 // create command line
707 const char *argv[] = {"CLTest", // program name
708 "--optval=20", nullptr};
709 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
710
711 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
712 ASSERT_EQ(err, maplecl::RetCode::noError);
713
714 int32_t equalDig = testopts::optVal;
715 ASSERT_EQ(equalDig, 20);
716 }
717
TEST(clOptions,expectedVal5)718 TEST(clOptions, expectedVal5)
719 {
720 // create command line
721 const char *argv[] = {"CLTest", // program name
722 "--optval", "20", nullptr};
723 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
724
725 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
726 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
727 }
728
TEST(clOptions,expectedVal6)729 TEST(clOptions, expectedVal6)
730 {
731 // create command line
732 const char *argv[] = {"CLTest", // program name
733 "--optval", "--boole", nullptr};
734 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
735
736 testopts::booloptEnabled.Clear();
737 testopts::optVal.Clear();
738 ASSERT_EQ(testopts::booloptEnabled.GetValue(), false);
739 ASSERT_EQ(testopts::optVal.IsEnabledByUser(), false);
740
741 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
742 ASSERT_EQ(err, maplecl::RetCode::noError);
743
744 ASSERT_EQ(testopts::booloptEnabled.GetValue(), true);
745 ASSERT_EQ(testopts::optVal.IsEnabledByUser(), true);
746 ASSERT_EQ(testopts::optVal.GetValue(), -42);
747 }
748
TEST(clOptions,expectedVal7)749 TEST(clOptions, expectedVal7)
750 {
751 // create command line
752 const char *argv[] = {"CLTest", // program name
753 "--woval", "20", nullptr};
754 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
755
756 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
757 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
758
759 /* --woval must not contain any key values, so 20 will be handled as second key */
760 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
761 ASSERT_EQ(badArgs.size(), 1);
762 ASSERT_EQ(badArgs[0].first, "20");
763 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::notRegistered);
764 }
765
TEST(clOptions,expectedVal8)766 TEST(clOptions, expectedVal8)
767 {
768 // create command line
769 const char *argv[] = {"CLTest", // program name
770 "--woval=20", nullptr};
771 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
772
773 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
774 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
775
776 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
777 ASSERT_EQ(badArgs.size(), 1);
778 ASSERT_EQ(badArgs[0].first, "--woval=20");
779 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::unnecessaryValue);
780 }
781
TEST(clOptions,expectedVal9)782 TEST(clOptions, expectedVal9)
783 {
784 // create command line
785 const char *argv[] = {"CLTest", // program name
786 "--woval", nullptr};
787 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
788
789 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
790 ASSERT_EQ(err, maplecl::RetCode::noError);
791
792 int32_t equalDig = testopts::woVal;
793 ASSERT_EQ(equalDig, -42);
794 }
795
796 /* ################# Options Category Test ###############################
797 * ####################################################################### */
798
TEST(clOptions,optCategory1)799 TEST(clOptions, optCategory1)
800 {
801 // create command line
802 const char *argv[] = {"CLTest", // program name
803 "--c1opt1", nullptr};
804 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
805
806 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv, testopts::defaultCategory);
807 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
808
809 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
810 ASSERT_EQ(badArgs.size(), 1);
811 ASSERT_EQ(badArgs[0].first, "--c1opt1");
812 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::notRegistered);
813 }
814
TEST(clOptions,optCategory2)815 TEST(clOptions, optCategory2)
816 {
817 // create command line
818 const char *argv[] = {"CLTest", // program name
819 "--c1opt1", "--c12opt", nullptr};
820 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
821
822 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv, testopts::testCategory1);
823 ASSERT_EQ(err, maplecl::RetCode::noError);
824
825 bool isSet = testopts::cat1Opt1;
826 ASSERT_EQ(isSet, true);
827
828 isSet = testopts::cat12Opt;
829 ASSERT_EQ(isSet, true);
830 }
831
TEST(clOptions,optCategory3)832 TEST(clOptions, optCategory3)
833 {
834 // create command line
835 const char *argv[] = {"CLTest", // program name
836 "--c12opt", nullptr};
837 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
838
839 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv, testopts::testCategory2);
840 ASSERT_EQ(err, maplecl::RetCode::noError);
841
842 bool isSet = testopts::cat12Opt;
843 ASSERT_EQ(isSet, true);
844 }
845
846 /* ################# Own OptionType Test #################################
847 * ####################################################################### */
848
TEST(clOptions,ownOptionType1)849 TEST(clOptions, ownOptionType1)
850 {
851 // create command line
852 const char *argv[] = {"CLTest", // program name
853 "--uttype", nullptr};
854 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
855
856 ASSERT_EQ(utCLTypeChecker, false);
857
858 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
859 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
860
861 ASSERT_EQ(utCLTypeChecker, true);
862
863 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
864 ASSERT_EQ(badArgs.size(), 1);
865 ASSERT_EQ(badArgs[0].first, "--uttype");
866 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::valueEmpty);
867 }
868
TEST(clOptions,ownOptionType2)869 TEST(clOptions, ownOptionType2)
870 {
871 // create command line
872 const char *argv[] = {"CLTest", // program name
873 "--uttype", "TEST", nullptr};
874 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
875
876 utCLTypeChecker = false;
877 ASSERT_EQ(utCLTypeChecker, false);
878
879 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
880 ASSERT_EQ(err, maplecl::RetCode::parsingErr);
881
882 ASSERT_EQ(utCLTypeChecker, true);
883
884 auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
885 ASSERT_EQ(badArgs.size(), 2);
886 ASSERT_EQ(badArgs[0].first, "--uttype");
887 ASSERT_EQ(badArgs[0].second, maplecl::RetCode::valueEmpty);
888 ASSERT_EQ(badArgs[1].first, "TEST");
889 ASSERT_EQ(badArgs[1].second, maplecl::RetCode::notRegistered);
890 }
891
TEST(clOptions,ownOptionType3)892 TEST(clOptions, ownOptionType3)
893 {
894 // create command line
895 const char *argv[] = {"CLTest", // program name
896 "--uttype", "--UTCLTypeOption", nullptr};
897 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
898
899 utCLTypeChecker = false;
900 ASSERT_EQ(utCLTypeChecker, false);
901
902 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
903 ASSERT_EQ(err, maplecl::RetCode::noError);
904
905 ASSERT_EQ(utCLTypeChecker, true);
906 UTCLType opt = testopts::uttype;
907
908 std::string tst = "--UTCLTypeOption";
909 bool isSet = (tst == opt);
910
911 ASSERT_EQ(isSet, isSet);
912 ASSERT_EQ(opt, "--UTCLTypeOption");
913 }
914
915 /* ################# Duplicated Option ###################################
916 * ####################################################################### */
917
TEST(clOptions,duplicatedOptions)918 TEST(clOptions, duplicatedOptions)
919 {
920 EXPECT_DEATH(maplecl::Option<bool> dup2({"--dup"}, ""), "");
921 }
922
923 /* ##################### Check Description ###############################
924 * ####################################################################### */
925
TEST(clOptions,description)926 TEST(clOptions, description)
927 {
928 ASSERT_EQ(testopts::desc.GetDescription(), "It's test description");
929 }
930
931 /* ##################### Check maplecl::list ##################################
932 * ####################################################################### */
933
TEST(clOptions,optList1)934 TEST(clOptions, optList1)
935 {
936 // create command line
937 const char *argv[] = {"CLTest", // program name
938 "--vecstr", "data1", "--vecstr", "data2", "--vecstr", "data3", "--vecdig",
939 "10", "--vecdig", "20", "--vecbool", "--no-vecbool", "--vecbool", nullptr};
940 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
941
942 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
943 ASSERT_EQ(err, maplecl::RetCode::noError);
944
945 auto strVals = testopts::vecString.GetValues();
946 ASSERT_EQ(strVals.size(), 3);
947 ASSERT_EQ(strVals[0], "data1");
948 ASSERT_EQ(strVals[1], "data2");
949 ASSERT_EQ(strVals[2], "data3");
950
951 auto digVals = testopts::vecDig.GetValues();
952 ASSERT_EQ(digVals.size(), 2);
953 ASSERT_EQ(digVals[0], 10);
954 ASSERT_EQ(digVals[1], 20);
955
956 auto boolVals = testopts::vecBool.GetValues();
957 ASSERT_EQ(boolVals.size(), 3);
958 ASSERT_EQ(boolVals[0], true);
959 ASSERT_EQ(boolVals[1], false);
960 ASSERT_EQ(boolVals[2], true);
961
962 maplecl::CommandLine::GetCommandLine().Clear(); // to clear previous test data
963
964 ASSERT_EQ(testopts::vecBool.GetValues().size(), 0);
965 ASSERT_EQ(testopts::vecDig.GetValues().size(), 0);
966 ASSERT_EQ(testopts::vecString.GetValues().size(), 0);
967 }
968
TEST(clOptions,optList2)969 TEST(clOptions, optList2)
970 {
971 // create command line
972 const char *argv[] = {"CLTest", // program name
973 "--vecstrdef", "data1", "--vecdigdef", "10", "--vecbooldef", "--no-vecbooldef", nullptr};
974 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
975
976 ASSERT_EQ(testopts::vecBoolDef.GetValues().size(), 1);
977 ASSERT_EQ(testopts::vecDigDef.GetValues().size(), 1);
978 ASSERT_EQ(testopts::vecStringDef.GetValues().size(), 1);
979
980 ASSERT_EQ(testopts::vecDigDef.GetValues()[0], 100);
981 ASSERT_EQ(testopts::vecBoolDef.GetValues()[0], true);
982 ASSERT_EQ(testopts::vecStringDef.GetValues()[0], "Default");
983
984 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
985 ASSERT_EQ(err, maplecl::RetCode::noError);
986
987 ASSERT_EQ(testopts::vecStringDef.GetValues().size(), 2);
988 ASSERT_EQ(testopts::vecDigDef.GetValues().size(), 2);
989 ASSERT_EQ(testopts::vecBoolDef.GetValues().size(), 3);
990
991 ASSERT_EQ(testopts::vecStringDef.GetValues()[1], "data1");
992 ASSERT_EQ(testopts::vecDigDef.GetValues()[1], 10);
993 ASSERT_EQ(testopts::vecBoolDef.GetValues()[1], true);
994 ASSERT_EQ(testopts::vecBoolDef.GetValues()[2], false);
995
996 maplecl::CommandLine::GetCommandLine().Clear(); // to clear previous test data
997 ASSERT_EQ(testopts::vecStringDef.GetValues().size(), 1);
998 ASSERT_EQ(testopts::vecDigDef.GetValues().size(), 1);
999 ASSERT_EQ(testopts::vecBoolDef.GetValues().size(), 1);
1000 }
1001
1002 /* ##################### "GetCommonValue from interface" check ###########
1003 * ####################################################################### */
TEST(clOptions,common)1004 TEST(clOptions, common)
1005 {
1006 // create command line
1007 const char *argv[] = {"CLTest", // program name
1008 "--common", "datacommon", nullptr};
1009 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
1010
1011 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
1012 ASSERT_EQ(err, maplecl::RetCode::noError);
1013
1014 maplecl::OptionInterface *commonOpt = &testopts::common;
1015 std::string val = commonOpt->GetCommonValue();
1016 ASSERT_EQ(val, "datacommon");
1017 }
1018
1019 /* ##################### "CopyIfEnabled" check ###########
1020 * ####################################################################### */
TEST(clOptions,copyifenabled)1021 TEST(clOptions, copyifenabled)
1022 {
1023 // create command line
1024 const char *argv[] = {"CLTest", // program name
1025 "--boole", "--str", "TEST", "--uint8", "10", nullptr};
1026 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
1027
1028 maplecl::CommandLine::GetCommandLine().Clear(); // to clear previous test data
1029 /* Check that options are cleared */
1030 ASSERT_EQ(testopts::booloptEnabled == false, true);
1031 ASSERT_EQ(testopts::booloptEnabled.IsEnabledByUser(), false);
1032 ASSERT_EQ(testopts::booloptDisabled == false, true);
1033 ASSERT_EQ(testopts::booloptDisabled.IsEnabledByUser(), false);
1034 ASSERT_EQ(testopts::testStr == "", true);
1035 ASSERT_EQ(testopts::testStr.IsEnabledByUser(), false);
1036 ASSERT_EQ(testopts::testUint8 == (uint8_t)0, true);
1037 ASSERT_EQ(testopts::testUint8.IsEnabledByUser(), false);
1038
1039 auto err = maplecl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
1040 ASSERT_EQ(err, maplecl::RetCode::noError);
1041
1042 bool boole = false, boold = false;
1043 std::string strTmp = "";
1044 uint8_t u8Tmp = 0;
1045 int tstEnabled = -1, tstDisabled = -1;
1046
1047 maplecl::CopyIfEnabled(boole, testopts::booloptEnabled);
1048 maplecl::CopyIfEnabled(boold, testopts::booloptDisabled);
1049 maplecl::CopyIfEnabled(tstEnabled, 10, testopts::booloptEnabled);
1050 maplecl::CopyIfEnabled(tstDisabled, 10, testopts::booloptDisabled);
1051 maplecl::CopyIfEnabled(strTmp, testopts::testStr);
1052 maplecl::CopyIfEnabled(u8Tmp, testopts::testUint8);
1053
1054 ASSERT_EQ(boole, true);
1055 ASSERT_EQ(boold, false);
1056 ASSERT_EQ(tstEnabled, 10);
1057 ASSERT_EQ(tstDisabled, -1);
1058 ASSERT_EQ(strTmp, "TEST");
1059 ASSERT_EQ(u8Tmp, 10);
1060 }
1061
1062 /* ##################### "Equal in Option" check ###########
1063 * ####################################################################### */
1064
TEST(clOptions,equalInOption)1065 TEST(clOptions, equalInOption)
1066 {
1067 // create command line
1068 const char *argv[] = {"CLTest", // program name
1069 "--common=data", nullptr};
1070 int argc = (sizeof(argv) / sizeof(argv[0])) - 1;
1071
1072 auto err = cl::CommandLine::GetCommandLine().Parse(argc, (char **)argv);
1073 ASSERT_EQ(err, cl::RetCode::noError);
1074
1075 ASSERT_EQ(testopts::common.GetValue() == "data", true);
1076 ASSERT_EQ(testopts::common.GetEqualType() == cl::EqualType::kWithEqual, true);
1077 }
1078