1/*
2 * Copyright (c) 2021-2022 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 "utils/pandargs.h"
17
18#include <gtest/gtest.h>
19
20namespace panda::test {
21
22static const bool REF_DEF_BOOL = false;
23static const int REF_DEF_INT = 0;
24static const double REF_DEF_DOUBLE = 1.0;
25static const std::string REF_DEF_STRING = "noarg";
26static const uint32_t REF_DEF_UINT32 = 0;
27static const uint64_t REF_DEF_UINT64 = 0;
28static const arg_list_t REF_DEF_DLIST = arg_list_t();
29static const arg_list_t REF_DEF_LIST = arg_list_t();
30
31PandArg<bool> PAB("bool", REF_DEF_BOOL, "Sample boolean argument");
32PandArg<int> PAI("int", REF_DEF_INT, "Sample integer argument");
33PandArg<double> PAD("double", REF_DEF_DOUBLE, "Sample rational argument");
34PandArg<std::string> PAS("string", REF_DEF_STRING, "Sample string argument");
35PandArg<uint32_t> PAU32("uint32", REF_DEF_UINT32, "Sample uint32 argument");
36PandArg<uint64_t> PAU64("uint64", REF_DEF_UINT64, "Sample uint64 argument");
37PandArg<arg_list_t> PALD("dlist", REF_DEF_DLIST, "Sample delimiter list argument", ":");
38PandArg<arg_list_t> PAL("list", REF_DEF_LIST, "Sample list argument");
39
40// The numbers -100 and 100 are used to initialize the range of the variable PAIR
41PandArg<int> PAIR("rint", REF_DEF_INT, "Integer argument with range", -100, 100);
42
43// The numbers 0 and 1000000000 are used to initialize the range of the variable PAUR32
44PandArg<uint32_t> PAUR32("ruint32", REF_DEF_UINT64, "uint32 argument with range", 0, 1000000000);
45
46// The numbers 0 and 100000000000 are used to initialize the range of the variable PAUR64
47PandArg<uint64_t> PAUR64("ruint64", REF_DEF_UINT64, "uint64 argument with range", 0, 100000000000);
48
49PandArgParser PA_PARSER;
50
51HWTEST(libpandargs, TestAdd, testing::ext::TestSize.Level0)
52{
53    EXPECT_FALSE(PA_PARSER.Add(nullptr));
54    EXPECT_TRUE(PA_PARSER.Add(&PAB));
55    EXPECT_TRUE(PA_PARSER.Add(&PAI));
56    EXPECT_TRUE(PA_PARSER.Add(&PAD));
57    EXPECT_TRUE(PA_PARSER.Add(&PAS));
58    EXPECT_TRUE(PA_PARSER.Add(&PAU32));
59    EXPECT_TRUE(PA_PARSER.Add(&PAU64));
60    EXPECT_TRUE(PA_PARSER.Add(&PALD));
61    EXPECT_TRUE(PA_PARSER.Add(&PAL));
62    EXPECT_TRUE(PA_PARSER.Add(&PAIR));
63    EXPECT_TRUE(PA_PARSER.Add(&PAUR32));
64    EXPECT_TRUE(PA_PARSER.Add(&PAUR64));
65}
66
67PandArg<bool> T_PAB("tail_bool", REF_DEF_BOOL, "Sample tail boolean argument");
68PandArg<int> T_PAI("tail_int", REF_DEF_INT, "Sample tail integer argument");
69PandArg<double> T_PAD("tail_double", REF_DEF_DOUBLE, "Sample tail rational argument");
70PandArg<std::string> T_PAS("tail_string", REF_DEF_STRING, "Sample tail string argument");
71PandArg<uint32_t> T_PAU32("tail_uint32", REF_DEF_UINT32, "Sample tail uint32 argument");
72PandArg<uint64_t> T_PAU64("tail_uint64", REF_DEF_UINT64, "Sample tail uint64 argument");
73
74// expect all arguments are set in parser
75HWTEST(libpandargs, TestIsArgSet, testing::ext::TestSize.Level0)
76{
77    EXPECT_TRUE(PA_PARSER.IsArgSet(&PAB));
78    EXPECT_TRUE(PA_PARSER.IsArgSet(PAB.GetName()));
79    EXPECT_TRUE(PA_PARSER.IsArgSet(&PAI));
80    EXPECT_TRUE(PA_PARSER.IsArgSet(PAI.GetName()));
81    EXPECT_TRUE(PA_PARSER.IsArgSet(&PAD));
82    EXPECT_TRUE(PA_PARSER.IsArgSet(PAD.GetName()));
83    EXPECT_TRUE(PA_PARSER.IsArgSet(&PAS));
84    EXPECT_TRUE(PA_PARSER.IsArgSet(PAS.GetName()));
85    EXPECT_TRUE(PA_PARSER.IsArgSet(&PAU32));
86    EXPECT_TRUE(PA_PARSER.IsArgSet(PAU32.GetName()));
87    EXPECT_TRUE(PA_PARSER.IsArgSet(&PAU64));
88    EXPECT_TRUE(PA_PARSER.IsArgSet(PAU64.GetName()));
89    EXPECT_TRUE(PA_PARSER.IsArgSet(&PALD));
90    EXPECT_TRUE(PA_PARSER.IsArgSet(PALD.GetName()));
91    EXPECT_TRUE(PA_PARSER.IsArgSet(&PAL));
92    EXPECT_TRUE(PA_PARSER.IsArgSet(PAL.GetName()));
93    EXPECT_TRUE(PA_PARSER.IsArgSet(&PAIR));
94    EXPECT_TRUE(PA_PARSER.IsArgSet(PAIR.GetName()));
95    EXPECT_TRUE(PA_PARSER.IsArgSet(&PAUR32));
96    EXPECT_TRUE(PA_PARSER.IsArgSet(PAUR32.GetName()));
97    EXPECT_TRUE(PA_PARSER.IsArgSet(&PAUR64));
98    EXPECT_TRUE(PA_PARSER.IsArgSet(PAUR64.GetName()));
99}
100
101// expect default values and types are consistent
102HWTEST(libpandargs, TestConsistent, testing::ext::TestSize.Level0)
103{
104    EXPECT_EQ(PAB.GetDefaultValue(), REF_DEF_BOOL);
105    EXPECT_EQ(PAB.GetDefaultValue(), PAB.GetValue());
106    EXPECT_EQ(PAB.GetType(), PandArgType::BOOL);
107
108    EXPECT_EQ(PAI.GetDefaultValue(), REF_DEF_INT);
109    EXPECT_EQ(PAI.GetDefaultValue(), PAI.GetValue());
110    EXPECT_EQ(PAI.GetType(), PandArgType::INTEGER);
111
112    EXPECT_DOUBLE_EQ(PAD.GetValue(), REF_DEF_DOUBLE);
113    EXPECT_DOUBLE_EQ(PAD.GetDefaultValue(), PAD.GetValue());
114    EXPECT_EQ(PAD.GetType(), PandArgType::DOUBLE);
115
116    EXPECT_EQ(PAS.GetDefaultValue(), REF_DEF_STRING);
117    EXPECT_EQ(PAS.GetDefaultValue(), PAS.GetValue());
118    EXPECT_EQ(PAS.GetType(), PandArgType::STRING);
119
120    EXPECT_EQ(PAU32.GetDefaultValue(), REF_DEF_UINT32);
121    EXPECT_EQ(PAU32.GetDefaultValue(), PAU32.GetValue());
122    EXPECT_EQ(PAU32.GetType(), PandArgType::UINT32);
123
124    EXPECT_EQ(PAU64.GetDefaultValue(), REF_DEF_UINT64);
125    EXPECT_EQ(PAU64.GetDefaultValue(), PAU64.GetValue());
126    EXPECT_EQ(PAU64.GetType(), PandArgType::UINT64);
127
128    EXPECT_TRUE(PALD.GetValue().empty());
129    EXPECT_EQ(PALD.GetDefaultValue(), PALD.GetValue());
130    EXPECT_EQ(PALD.GetType(), PandArgType::LIST);
131
132    EXPECT_TRUE(PAL.GetValue().empty());
133    EXPECT_EQ(PAL.GetDefaultValue(), PAL.GetValue());
134    EXPECT_EQ(PAL.GetType(), PandArgType::LIST);
135
136    EXPECT_EQ(PAIR.GetDefaultValue(), REF_DEF_INT);
137    EXPECT_EQ(PAIR.GetDefaultValue(), PAIR.GetValue());
138    EXPECT_EQ(PAIR.GetType(), PandArgType::INTEGER);
139
140    EXPECT_EQ(PAUR32.GetDefaultValue(), REF_DEF_UINT64);
141    EXPECT_EQ(PAUR32.GetDefaultValue(), PAUR32.GetValue());
142    EXPECT_EQ(PAUR32.GetType(), PandArgType::UINT32);
143
144    EXPECT_EQ(PAUR64.GetDefaultValue(), REF_DEF_UINT64);
145    EXPECT_EQ(PAUR64.GetDefaultValue(), PAUR64.GetValue());
146    EXPECT_EQ(PAUR64.GetType(), PandArgType::UINT64);
147}
148
149// expect false on duplicate argument
150HWTEST(libpandargs, TestDuplicate, testing::ext::TestSize.Level0)
151{
152    PandArg<int> pai_dup("int", 0, "Integer number 0");
153    EXPECT_TRUE(PA_PARSER.IsArgSet(pai_dup.GetName()));
154    EXPECT_FALSE(PA_PARSER.Add(&pai_dup));
155}
156
157// add tail argument, expect false on duplicate
158// erase tail, expect 0 tail size
159HWTEST(libpandargs, TestTail, testing::ext::TestSize.Level0)
160{
161    {
162        EXPECT_EQ(PA_PARSER.GetTailSize(), 0U);
163        EXPECT_TRUE(PA_PARSER.PushBackTail(&T_PAI));
164        EXPECT_EQ(PA_PARSER.GetTailSize(), 1U);
165        EXPECT_FALSE(PA_PARSER.PushBackTail(&T_PAI));
166        PA_PARSER.PopBackTail();
167        EXPECT_EQ(PA_PARSER.GetTailSize(), 0U);
168    }
169
170    {
171        ASSERT_EQ(PA_PARSER.GetTailSize(), 0U);
172        ASSERT_FALSE(PA_PARSER.PushBackTail(nullptr));
173        ASSERT_EQ(PA_PARSER.GetTailSize(), 0U);
174        ASSERT_FALSE(PA_PARSER.PopBackTail());
175    }
176}
177
178// expect help string formed right
179HWTEST(libpandargs, TestString, testing::ext::TestSize.Level0)
180{
181    std::string ref_string = "--" + PAB.GetName() + ": " + PAB.GetDesc() + "\n";
182    ref_string += "--" + PALD.GetName() + ": " + PALD.GetDesc() + "\n";
183    ref_string += "--" + PAD.GetName() + ": " + PAD.GetDesc() + "\n";
184    ref_string += "--" + PAI.GetName() + ": " + PAI.GetDesc() + "\n";
185    ref_string += "--" + PAL.GetName() + ": " + PAL.GetDesc() + "\n";
186    ref_string += "--" + PAIR.GetName() + ": " + PAIR.GetDesc() + "\n";
187    ref_string += "--" + PAUR32.GetName() + ": " + PAUR32.GetDesc() + "\n";
188    ref_string += "--" + PAUR64.GetName() + ": " + PAUR64.GetDesc() + "\n";
189    ref_string += "--" + PAS.GetName() + ": " + PAS.GetDesc() + "\n";
190    ref_string += "--" + PAU32.GetName() + ": " + PAU32.GetDesc() + "\n";
191    ref_string += "--" + PAU64.GetName() + ": " + PAU64.GetDesc() + "\n";
192    EXPECT_EQ(PA_PARSER.GetHelpString(), ref_string);
193}
194
195// expect regular args list formed right
196HWTEST(libpandargs, TestRegular, testing::ext::TestSize.Level0)
197{
198    arg_list_t ref_arg_dlist = PALD.GetValue();
199    arg_list_t ref_arg_list = PAL.GetValue();
200    std::string ref_string = "--" + PAB.GetName() + "=" + std::to_string(PAB.GetValue()) + "\n";
201    ref_string += "--" + PALD.GetName() + "=";
202    for (const auto &i : ref_arg_dlist) {
203        ref_string += i + ", ";
204    }
205    ref_string += "\n";
206    ref_string += "--" + PAD.GetName() + "=" + std::to_string(PAD.GetValue()) + "\n";
207    ref_string += "--" + PAI.GetName() + "=" + std::to_string(PAI.GetValue()) + "\n";
208    ref_string += "--" + PAL.GetName() + "=";
209    for (const auto &i : ref_arg_list) {
210        ref_string += i + ", ";
211    }
212    ref_string += "\n";
213    ref_string += "--" + PAIR.GetName() + "=" + std::to_string(PAIR.GetValue()) + "\n";
214    ref_string += "--" + PAUR32.GetName() + "=" + std::to_string(PAUR32.GetValue()) + "\n";
215    ref_string += "--" + PAUR64.GetName() + "=" + std::to_string(PAUR64.GetValue()) + "\n";
216    ref_string += "--" + PAS.GetName() + "=" + PAS.GetValue() + "\n";
217    ref_string += "--" + PAU32.GetName() + "=" + std::to_string(PAU32.GetValue()) + "\n";
218    ref_string += "--" + PAU64.GetName() + "=" + std::to_string(PAU64.GetValue()) + "\n";
219    EXPECT_EQ(PA_PARSER.GetRegularArgs(), ref_string);
220}
221
222// expect all boolean values processed right
223HWTEST(libpandargs, TestAllBoolean, testing::ext::TestSize.Level0)
224{
225    static const char *true_values[] = {"true", "on", "1"};
226    static const char *false_values[] = {"false", "off", "0"};
227    static const int argc_bool_only = 3;
228    static const char *argv_bool_only[argc_bool_only];
229    argv_bool_only[0] = "gtest_app";
230    std::string s = "--" + PAB.GetName();
231    argv_bool_only[1] = s.c_str();
232
233    for (int i = 0; i < 3; i++) {
234        argv_bool_only[2] = true_values[i];
235        EXPECT_TRUE(PA_PARSER.Parse(argc_bool_only, argv_bool_only));
236        EXPECT_TRUE(PAB.GetValue());
237    }
238    for (int i = 0; i < 3; i++) {
239        argv_bool_only[2] = false_values[i];
240        EXPECT_TRUE(PA_PARSER.Parse(argc_bool_only, argv_bool_only));
241        EXPECT_FALSE(PAB.GetValue());
242    }
243}
244
245// expect wrong boolean arguments with "=" processed right
246HWTEST(libpandargs, TestWrongBoolean, testing::ext::TestSize.Level0)
247{
248    static const int argc_bool_only = 2;
249    static const char *argv_bool_only[argc_bool_only];
250    argv_bool_only[0] = "gtest_app";
251    std::string s = "--" + PAB.GetName() + "=";
252    argv_bool_only[1] = s.c_str();
253    EXPECT_FALSE(PA_PARSER.Parse(argc_bool_only, argv_bool_only));
254}
255
256// expect boolean at the end of arguments line is true
257HWTEST(libpandargs, TestBooleanEnd, testing::ext::TestSize.Level0)
258{
259    static const int argc_bool_only = 2;
260    static const char *argv_bool_only[argc_bool_only];
261    argv_bool_only[0] = "gtest_app";
262    std::string s = "--" + PAB.GetName();
263    argv_bool_only[1] = s.c_str();
264    EXPECT_TRUE(PA_PARSER.Parse(argc_bool_only, argv_bool_only));
265    EXPECT_TRUE(PAB.GetValue());
266}
267
268// expect positive and negative integer values processed right
269HWTEST(libpandargs, TestInteger, testing::ext::TestSize.Level0)
270{
271    static const int ref_int_pos = 42422424;
272    static const int ref_int_neg = -42422424;
273    static const int argc_int_only = 3;
274    static const char *argv_int_only[argc_int_only];
275    argv_int_only[0] = "gtest_app";
276    std::string s = "--" + PAI.GetName();
277    argv_int_only[1] = s.c_str();
278    argv_int_only[2] = "42422424";
279    EXPECT_TRUE(PA_PARSER.Parse(argc_int_only, argv_int_only));
280    EXPECT_EQ(PAI.GetValue(), ref_int_pos);
281    argv_int_only[2] = "-42422424";
282    EXPECT_TRUE(PA_PARSER.Parse(argc_int_only, argv_int_only));
283    EXPECT_EQ(PAI.GetValue(), ref_int_neg);
284}
285
286// expect positive and negative double values processed right
287HWTEST(libpandargs, TestDouble, testing::ext::TestSize.Level0)
288{
289    static const double ref_double_pos = 4242.2424;
290    static const double ref_double_neg = -4242.2424;
291    static const int argc_double_only = 3;
292    static const char *argv_double_only[argc_double_only];
293    argv_double_only[0] = "gtest_app";
294    std::string s = "--" + PAD.GetName();
295    argv_double_only[1] = s.c_str();
296    argv_double_only[2] = "4242.2424";
297    EXPECT_TRUE(PA_PARSER.Parse(argc_double_only, argv_double_only));
298    EXPECT_EQ(PAD.GetValue(), ref_double_pos);
299    argv_double_only[2] = "-4242.2424";
300    EXPECT_TRUE(PA_PARSER.Parse(argc_double_only, argv_double_only));
301    EXPECT_EQ(PAD.GetValue(), ref_double_neg);
302}
303
304// expect hex values processed right
305HWTEST(libpandargs, TestHex, testing::ext::TestSize.Level0)
306{
307    static const uint64_t refUint64 = 274877906959;
308    static const uint64_t refInt = 64;
309    static const int argcUint64Int = 3;
310    static const char* argvUint64Int[argcUint64Int];
311    argvUint64Int[0] = "gtest_app";
312    std::string s = "--" + PAU64.GetName();
313    argvUint64Int[1] = s.c_str();
314    argvUint64Int[2] = "0x400000000f";
315    EXPECT_TRUE(PA_PARSER.Parse(argcUint64Int, argvUint64Int));
316    EXPECT_EQ(PAU64.GetValue(), refUint64);
317    argvUint64Int[2] = "0x40";
318    EXPECT_TRUE(PA_PARSER.Parse(argcUint64Int, argvUint64Int));
319    EXPECT_EQ(PAU64.GetValue(), refInt);
320}
321
322// expect uint32_t values processed right
323HWTEST(libpandargs, TestUint32, testing::ext::TestSize.Level0)
324{
325    static const uint32_t ref_uint32_pos = 4242422424;
326    static const int argc_uint32_only = 3;
327    static const char *argv_uint32_only[argc_uint32_only];
328    argv_uint32_only[0] = "gtest_app";
329    std::string s = "--" + PAU32.GetName();
330    argv_uint32_only[1] = s.c_str();
331    argv_uint32_only[2] = "4242422424";
332    EXPECT_TRUE(PA_PARSER.Parse(argc_uint32_only, argv_uint32_only));
333    EXPECT_EQ(PAU32.GetValue(), ref_uint32_pos);
334}
335
336// expect uint64_t values processed right
337HWTEST(libpandargs, TestUint64, testing::ext::TestSize.Level0)
338{
339    static const uint64_t ref_uint64_pos = 424242422424;
340    static const int argc_uint64_only = 3;
341    static const char *argv_uint64_only[argc_uint64_only];
342    argv_uint64_only[0] = "gtest_app";
343    std::string s = "--" + PAU64.GetName();
344    argv_uint64_only[1] = s.c_str();
345    argv_uint64_only[2] = "424242422424";
346    EXPECT_TRUE(PA_PARSER.Parse(argc_uint64_only, argv_uint64_only));
347    EXPECT_EQ(PAU64.GetValue(), ref_uint64_pos);
348}
349
350// expect hex values processed right
351HWTEST(libpandargs, TestHexValues, testing::ext::TestSize.Level0)
352{
353    static const uint64_t ref_uint64 = 274877906944;
354    static const uint64_t ref_int = 64;
355    static const int argc_uint64_int = 3;
356    static const char *argv_uint64_int[argc_uint64_int];
357    argv_uint64_int[0] = "gtest_app";
358    std::string s = "--" + PAU64.GetName();
359    argv_uint64_int[1] = s.c_str();
360    argv_uint64_int[2] = "0x4000000000";
361    EXPECT_TRUE(PA_PARSER.Parse(argc_uint64_int, argv_uint64_int));
362    EXPECT_EQ(PAU64.GetValue(), ref_uint64);
363    argv_uint64_int[2] = "0x40";
364    EXPECT_TRUE(PA_PARSER.Parse(argc_uint64_int, argv_uint64_int));
365    EXPECT_EQ(PAU64.GetValue(), ref_int);
366}
367
368// expect out of range uint32_t values processed right
369HWTEST(libpandargs, TestOutUint32, testing::ext::TestSize.Level0)
370{
371    static const int argc_uint32_only = 3;
372    static const char *argv_uint32_only[argc_uint32_only];
373    argv_uint32_only[0] = "gtest_app";
374    std::string s = "--" + PAU32.GetName();
375    argv_uint32_only[1] = s.c_str();
376    argv_uint32_only[2] = "424224244242242442422424";
377    EXPECT_FALSE(PA_PARSER.Parse(argc_uint32_only, argv_uint32_only));
378    argv_uint32_only[2] = "0xffffffffffffffffffffffffff";
379    EXPECT_FALSE(PA_PARSER.Parse(argc_uint32_only, argv_uint32_only));
380}
381
382// expect out of range uint64_t values processed right
383HWTEST(libpandargs, TestOutUint64, testing::ext::TestSize.Level0)
384{
385    static const int argc_uint64_only = 3;
386    static const char *argv_uint64_only[argc_uint64_only];
387    argv_uint64_only[0] = "gtest_app";
388    std::string s = "--" + PAU64.GetName();
389    argv_uint64_only[1] = s.c_str();
390    argv_uint64_only[2] = "424224244242242442422424";
391    EXPECT_FALSE(PA_PARSER.Parse(argc_uint64_only, argv_uint64_only));
392    argv_uint64_only[2] = "0xffffffffffffffffffffffffff";
393    EXPECT_FALSE(PA_PARSER.Parse(argc_uint64_only, argv_uint64_only));
394}
395
396// expect string argument of one word and multiple word processed right
397HWTEST(libpandargs, TestStringRange, testing::ext::TestSize.Level0)
398{
399    static const std::string ref_one_string = "string";
400    static const std::string ref_multiple_string = "this is a string";
401    static const char *str_argname = "--string";
402    static const int argc_one_string = 3;
403    static const char *argv_one_string[argc_one_string] = {"gtest_app", str_argname, "string"};
404    static const int argc_multiple_string = 3;
405    static const char *argv_multiple_string[argc_multiple_string] = {"gtest_app", str_argname, "this is a string"};
406    EXPECT_TRUE(PA_PARSER.Parse(argc_multiple_string, argv_multiple_string));
407    EXPECT_EQ(PAS.GetValue(), ref_multiple_string);
408    EXPECT_TRUE(PA_PARSER.Parse(argc_one_string, argv_one_string));
409    EXPECT_EQ(PAS.GetValue(), ref_one_string);
410}
411
412// expect string at the end of line is an empty string
413HWTEST(libpandargs, TestStringLine, testing::ext::TestSize.Level0)
414{
415    static const int argc_string_only = 2;
416    static const char *argv_string_only[argc_string_only];
417    argv_string_only[0] = "gtest_app";
418    std::string s = "--" + PAS.GetName();
419    argv_string_only[1] = s.c_str();
420    EXPECT_TRUE(PA_PARSER.Parse(argc_string_only, argv_string_only));
421    EXPECT_EQ(PAS.GetValue(), "");
422}
423
424// expect list argument processed right
425HWTEST(libpandargs, TestList, testing::ext::TestSize.Level0)
426{
427    PALD.ResetDefaultValue();
428    static const arg_list_t ref_list = {"list1", "list2", "list3"};
429    std::string s = "--" + PALD.GetName();
430    static const char *list_argname = s.c_str();
431    static const int argc_list_only = 7;
432    static const char *argv_list_only[argc_list_only] = {"gtest_app", list_argname, "list1",
433        list_argname, "list2", list_argname, "list3"};
434    EXPECT_TRUE(PA_PARSER.Parse(argc_list_only, argv_list_only));
435    ASSERT_EQ(PALD.GetValue().size(), ref_list.size());
436    for (std::size_t i = 0; i < ref_list.size(); ++i) {
437        EXPECT_EQ(PALD.GetValue()[i], ref_list[i]);
438    }
439}
440
441// expect list argument without delimiter processed right
442HWTEST(libpandargs, TestListDelimiter, testing::ext::TestSize.Level0)
443{
444    PAL.ResetDefaultValue();
445    static const arg_list_t ref_list = {"list1", "list2", "list3", "list4"};
446    std::string s = "--" + PAL.GetName();
447    static const char *list_argname = s.c_str();
448    static const int argc_list_only = 9;
449    static const char *argv_list_only[argc_list_only] = {"gtest_app",
450        list_argname, "list1", list_argname, "list2", list_argname, "list3", list_argname, "list4"};
451    EXPECT_TRUE(PA_PARSER.Parse(argc_list_only, argv_list_only));
452    ASSERT_EQ(PAL.GetValue().size(), ref_list.size());
453    for (std::size_t i = 0; i < ref_list.size(); ++i) {
454        EXPECT_EQ(PAL.GetValue()[i], ref_list[i]);
455    }
456}
457
458// expect delimiter list argument processed right
459HWTEST(libpandargs, TestDelimiter, testing::ext::TestSize.Level0)
460{
461    PALD.ResetDefaultValue();
462    static const arg_list_t ref_dlist = {"dlist1", "dlist2", "dlist3"};
463    std::string s = "--" + PALD.GetName();
464    static const char *list_argname = s.c_str();
465    static const int argc_dlist_only = 3;
466    static const char *argv_dlist_only[argc_dlist_only] = {"gtest_app", list_argname, "dlist1:dlist2:dlist3"};
467    EXPECT_TRUE(PA_PARSER.Parse(argc_dlist_only, argv_dlist_only));
468    ASSERT_EQ(PALD.GetValue().size(), ref_dlist.size());
469    for (std::size_t i = 0; i < ref_dlist.size(); ++i) {
470        EXPECT_EQ(PALD.GetValue()[i], ref_dlist[i]);
471    }
472}
473
474// expect delimiter and multiple list argument processed right
475HWTEST(libpandargs, TestDelimiterList, testing::ext::TestSize.Level0)
476{
477    PALD.ResetDefaultValue();
478    static const arg_list_t ref_list = {"dlist1", "dlist2", "list1", "list2", "dlist3", "dlist4"};
479    std::string s = "--" + PALD.GetName();
480    static const char *list_argname = s.c_str();
481    static const int argc_list = 9;
482    static const char *argv_list[argc_list] = {"gtest_app",  list_argname, "dlist1:dlist2", list_argname, "list1",
483        list_argname, "list2", list_argname, "dlist3:dlist4"};
484    EXPECT_TRUE(PA_PARSER.Parse(argc_list, argv_list));
485    ASSERT_EQ(PALD.GetValue().size(), ref_list.size());
486    for (std::size_t i = 0; i < ref_list.size(); ++i) {
487        EXPECT_EQ(PALD.GetValue()[i], ref_list[i]);
488    }
489}
490
491// expect positive and negative integer values with range processed right
492HWTEST(libpandargs, TestIntegerRange, testing::ext::TestSize.Level0)
493{
494    static const int ref_int_pos = 99;
495    static const int ref_int_neg = -99;
496    static const int argc_int_only = 3;
497    static const char *argv_int_only[argc_int_only];
498    argv_int_only[0] = "gtest_app";
499    std::string s = "--" + PAIR.GetName();
500    argv_int_only[1] = s.c_str();
501    argv_int_only[2] = "99";
502    EXPECT_TRUE(PA_PARSER.Parse(argc_int_only, argv_int_only));
503    EXPECT_EQ(PAIR.GetValue(), ref_int_pos);
504    argv_int_only[2] = "-99";
505    EXPECT_TRUE(PA_PARSER.Parse(argc_int_only, argv_int_only));
506    EXPECT_EQ(PAIR.GetValue(), ref_int_neg);
507}
508
509// expect wrong positive and negative integer values with range processed right
510HWTEST(libpandargs, TestWrongInteger, testing::ext::TestSize.Level0)
511{
512    static const int argc_int_only = 3;
513    static const char *argv_int_only[argc_int_only];
514    argv_int_only[0] = "gtest_app";
515    std::string s = "--" + PAIR.GetName();
516    argv_int_only[1] = s.c_str();
517    argv_int_only[2] = "101";
518    EXPECT_FALSE(PA_PARSER.Parse(argc_int_only, argv_int_only));
519    argv_int_only[2] = "-101";
520    EXPECT_FALSE(PA_PARSER.Parse(argc_int_only, argv_int_only));
521}
522
523// expect uint32_t values with range processed right
524HWTEST(libpandargs, TestUint32Range, testing::ext::TestSize.Level0)
525{
526    static const uint32_t ref_int_min = 1;
527    static const uint32_t ref_int_max = 990000000;
528    static const int argc_int_only = 3;
529    static const char *argv_int_only[argc_int_only];
530    argv_int_only[0] = "gtest_app";
531    std::string s = "--" + PAUR32.GetName();
532    argv_int_only[1] = s.c_str();
533    argv_int_only[2] = "1";
534    EXPECT_TRUE(PA_PARSER.Parse(argc_int_only, argv_int_only));
535    EXPECT_EQ(PAUR32.GetValue(), ref_int_min);
536    argv_int_only[2] = "990000000";
537    EXPECT_TRUE(PA_PARSER.Parse(argc_int_only, argv_int_only));
538    EXPECT_EQ(PAUR32.GetValue(), ref_int_max);
539}
540
541// expect wrong uint32_t values with range processed right
542HWTEST(libpandargs, TestWrongUint32, testing::ext::TestSize.Level0)
543{
544    static const int argc_int_only = 3;
545    static const char *argv_int_only[argc_int_only];
546    argv_int_only[0] = "gtest_app";
547    std::string s = "--" + PAUR32.GetName();
548    argv_int_only[1] = s.c_str();
549    argv_int_only[2] = "-1";
550    EXPECT_FALSE(PA_PARSER.Parse(argc_int_only, argv_int_only));
551    argv_int_only[2] = "1000000001";
552    EXPECT_FALSE(PA_PARSER.Parse(argc_int_only, argv_int_only));
553}
554
555// expect uint64_t values with range processed right
556HWTEST(libpandargs, TestUint64Range, testing::ext::TestSize.Level0)
557{
558    static const uint64_t ref_int_min = 1;
559    static const uint64_t ref_int_max = 99000000000;
560    static const int argc_int_only = 3;
561    static const char *argv_int_only[argc_int_only];
562    argv_int_only[0] = "gtest_app";
563    std::string s = "--" + PAUR64.GetName();
564    argv_int_only[1] = s.c_str();
565    argv_int_only[2] = "1";
566    EXPECT_TRUE(PA_PARSER.Parse(argc_int_only, argv_int_only));
567    EXPECT_EQ(PAUR64.GetValue(), ref_int_min);
568    argv_int_only[2] = "99000000000";
569    EXPECT_TRUE(PA_PARSER.Parse(argc_int_only, argv_int_only));
570    EXPECT_EQ(PAUR64.GetValue(), ref_int_max);
571}
572
573// expect wrong uint64_t values with range processed right
574HWTEST(libpandargs, TestWrongUint364, testing::ext::TestSize.Level0)
575{
576    static const int argc_int_only = 3;
577    static const char *argv_int_only[argc_int_only];
578    argv_int_only[0] = "gtest_app";
579    std::string s = "--" + PAUR64.GetName();
580    argv_int_only[1] = s.c_str();
581    argv_int_only[2] = "-1";
582    EXPECT_FALSE(PA_PARSER.Parse(argc_int_only, argv_int_only));
583    argv_int_only[2] = "100000000001";
584    EXPECT_FALSE(PA_PARSER.Parse(argc_int_only, argv_int_only));
585}
586
587// expect list at the end of line is a list with empty string
588HWTEST(libpandargs, TestListRange, testing::ext::TestSize.Level0)
589{
590    PALD.ResetDefaultValue();
591    static const arg_list_t ref_list = {""};
592    static const int argc_list_only = 2;
593    static const char *argv_list_only[argc_list_only];
594    argv_list_only[0] = "gtest_app";
595    std::string s = "--" + PALD.GetName();
596    argv_list_only[1] = s.c_str();
597    EXPECT_TRUE(PA_PARSER.Parse(argc_list_only, argv_list_only));
598    EXPECT_EQ(PALD.GetValue(), ref_list);
599}
600
601// expect true on IsTailEnabled when tail is enabled, false otherwise
602HWTEST(libpandargs, TestIsTailEnabled, testing::ext::TestSize.Level0)
603{
604    PA_PARSER.EnableTail();
605    EXPECT_TRUE(PA_PARSER.IsTailEnabled());
606    PA_PARSER.DisableTail();
607    EXPECT_FALSE(PA_PARSER.IsTailEnabled());
608}
609
610// expect tail only argument is consistent
611HWTEST(libpandargs, TestTailConsistent, testing::ext::TestSize.Level0)
612{
613    static const int argc_tail_only = 2;
614    static const char *argv_tail_only[] = {"gtest_app", "tail1"};
615    static const std::string ref_str_tail = "tail1";
616    PA_PARSER.EnableTail();
617    PA_PARSER.PushBackTail(&T_PAS);
618    EXPECT_TRUE(PA_PARSER.Parse(argc_tail_only, argv_tail_only));
619    ASSERT_EQ(T_PAS.GetValue(), ref_str_tail);
620    PA_PARSER.DisableTail();
621    PA_PARSER.EraseTail();
622}
623
624// expect multiple tail only argument is consistent
625HWTEST(libpandargs, TestMultipleTail, testing::ext::TestSize.Level0)
626{
627    static const int argc_tail_only = 7;
628    static const char *argv_tail_only[] = {"gtest_app", "str_tail", "off", "-4", "3.14", "2", "4"};
629    static const std::string str_ref = "str_tail";
630    static const bool bool_ref = false;
631    static const int int_ref = -4;
632    static const double double_ref = 3.14;
633    static const uint32_t uint32_ref = 2;
634    static const uint64_t uint64_ref = 4;
635    PA_PARSER.EnableTail();
636    PA_PARSER.PushBackTail(&T_PAS);
637    PA_PARSER.PushBackTail(&T_PAB);
638    PA_PARSER.PushBackTail(&T_PAI);
639    PA_PARSER.PushBackTail(&T_PAD);
640    PA_PARSER.PushBackTail(&T_PAU32);
641    PA_PARSER.PushBackTail(&T_PAU64);
642    EXPECT_EQ(PA_PARSER.GetTailSize(), 6U);
643    EXPECT_TRUE(PA_PARSER.Parse(argc_tail_only, argv_tail_only));
644    EXPECT_EQ(T_PAS.GetValue(), str_ref);
645    EXPECT_EQ(T_PAB.GetValue(), bool_ref);
646    EXPECT_EQ(T_PAI.GetValue(), int_ref);
647    EXPECT_DOUBLE_EQ(T_PAD.GetValue(), double_ref);
648    EXPECT_EQ(T_PAU32.GetValue(), uint32_ref);
649    EXPECT_EQ(T_PAU64.GetValue(), uint64_ref);
650    PA_PARSER.DisableTail();
651    PA_PARSER.EraseTail();
652    EXPECT_EQ(PA_PARSER.GetTailSize(), 0U);
653}
654
655// expect parse fail on wrong tail argument type
656HWTEST(libpandargs, TestRrongTail, testing::ext::TestSize.Level0)
657{
658    PA_PARSER.EnableTail();
659    static const int argc_tail_only = 3;
660    // boolean value instead of integer
661    static const char *argv_tail_only[] = {"gtest_app", "str_tail", "off"};
662    static const std::string str_ref = "str_tail";
663    PA_PARSER.PushBackTail(&T_PAS);
664    PA_PARSER.PushBackTail(&T_PAI);
665    EXPECT_EQ(PA_PARSER.GetTailSize(), 2U);
666    EXPECT_FALSE(PA_PARSER.Parse(argc_tail_only, argv_tail_only));
667    EXPECT_EQ(T_PAS.GetValue(), str_ref);
668    PA_PARSER.DisableTail();
669    PA_PARSER.EraseTail();
670    EXPECT_EQ(PA_PARSER.GetTailSize(), 0U);
671}
672
673// expect right tail argument processing after preceiding string argument
674HWTEST(libpandargs, TestRightTail, testing::ext::TestSize.Level0)
675{
676    PA_PARSER.EnableTail();
677    static const char *str_argname = "--string";
678    static const std::string ref_string = "this is a reference string";
679    static const std::string ref_t_str = "string";
680    static const double ref_t_double = 0.1;
681    static const bool ref_t_bool = true;
682    static const uint32_t ref_t_uint32 = 32;
683    static const uint64_t ref_t_uint64 = 64;
684    static const int argc_tail_string = 8;
685    static const char *argv_tail_string[] = {"gtest_app",
686        str_argname, "this is a reference string", "string", ".1", "on", "32", "64"};
687    PA_PARSER.PushBackTail(&T_PAS);
688    PA_PARSER.PushBackTail(&T_PAD);
689    PA_PARSER.PushBackTail(&T_PAB);
690    PA_PARSER.PushBackTail(&T_PAU32);
691    PA_PARSER.PushBackTail(&T_PAU64);
692    EXPECT_TRUE(PA_PARSER.Parse(argc_tail_string, argv_tail_string));
693    EXPECT_EQ(PAS.GetValue(), ref_string);
694    EXPECT_EQ(T_PAS.GetValue(), ref_t_str);
695    EXPECT_EQ(T_PAD.GetValue(), ref_t_double);
696    EXPECT_EQ(T_PAB.GetValue(), ref_t_bool);
697    EXPECT_EQ(T_PAU32.GetValue(), ref_t_uint32);
698    EXPECT_EQ(T_PAU64.GetValue(), ref_t_uint64);
699    PA_PARSER.DisableTail();
700    PA_PARSER.EraseTail();
701}
702
703// expect right tail argument processing after preceiding list argument
704HWTEST(libpandargs, TestTailProceiding, testing::ext::TestSize.Level0)
705{
706    PALD.ResetDefaultValue();
707    PA_PARSER.EnableTail();
708    static const char *list_argname = "--dlist";
709    static const arg_list_t ref_list = {"list1", "list2", "list3", "list4", "list5"};
710    static const double ref_t_double = -7;
711    static const bool ref_t_bool = true;
712    static const int ref_t_int = 255;
713    static const uint32_t ref_t_uint32 = 32;
714    static const uint64_t ref_t_uint64 = 64;
715    static const int argc_tail_list = 16;
716    static const char *argv_tail_list[] = {"gtest_app", list_argname, "list1", list_argname, "list2", list_argname,
717        "list3", list_argname, "list4", list_argname, "list5", "true", "255", "-7", "32", "64"};
718    PA_PARSER.PushBackTail(&T_PAB);
719    PA_PARSER.PushBackTail(&T_PAI);
720    PA_PARSER.PushBackTail(&T_PAD);
721    PA_PARSER.PushBackTail(&T_PAU32);
722    PA_PARSER.PushBackTail(&T_PAU64);
723    EXPECT_TRUE(PA_PARSER.Parse(argc_tail_list, argv_tail_list));
724    ASSERT_EQ(PALD.GetValue().size(), ref_list.size());
725    for (std::size_t i = 0; i < ref_list.size(); i++) {
726        EXPECT_EQ(PALD.GetValue()[i], ref_list[i]);
727    }
728    EXPECT_EQ(T_PAB.GetValue(), ref_t_bool);
729    EXPECT_EQ(T_PAI.GetValue(), ref_t_int);
730    EXPECT_DOUBLE_EQ(T_PAD.GetValue(), ref_t_double);
731    EXPECT_EQ(T_PAU32.GetValue(), ref_t_uint32);
732    EXPECT_EQ(T_PAU64.GetValue(), ref_t_uint64);
733
734    PA_PARSER.DisableTail();
735    PA_PARSER.EraseTail();
736}
737
738// expect right tail argument processing after noparam boolean argument
739HWTEST(libpandargs, TestTailBoolean, testing::ext::TestSize.Level0)
740{
741    PA_PARSER.EnableTail();
742    PandArg<std::string> t_pas0("tail_string0", REF_DEF_STRING, "Sample tail string argument 0");
743    PandArg<std::string> t_pas1("tail_string1", REF_DEF_STRING, "Sample tail string argument 1");
744    static const std::string ref_t_str1 = "offtail1";
745    static const std::string ref_t_str2 = "offtail2";
746    static const std::string ref_t_str3 = "offtail3";
747    static const int argc_tail_bool = 5;
748    static const char *argv_tail_bool[] = {"gtest_app", "--bool", "offtail1", "offtail2", "offtail3"};
749    PA_PARSER.PushBackTail(&T_PAS);
750    PA_PARSER.PushBackTail(&t_pas0);
751    PA_PARSER.PushBackTail(&t_pas1);
752    EXPECT_TRUE(PA_PARSER.Parse(argc_tail_bool, argv_tail_bool));
753    EXPECT_TRUE(PAB.GetValue());
754    EXPECT_EQ(T_PAS.GetValue(), ref_t_str1);
755    EXPECT_EQ(t_pas0.GetValue(), ref_t_str2);
756    EXPECT_EQ(t_pas1.GetValue(), ref_t_str3);
757    PA_PARSER.DisableTail();
758    PA_PARSER.EraseTail();
759}
760
761// expect fail on amount of tail arguments more then PA_PARSER may have
762HWTEST(libpandargs, TestTailPa_parser, testing::ext::TestSize.Level0)
763{
764    PA_PARSER.EnableTail();
765    static const int argc_tail = 5;
766    static const char *argv_tail[] = {"gtest_app", "gdb", "--args", "file.bin", "entry"};
767
768    PandArg<std::string> t_pas1("tail_string1", REF_DEF_STRING, "Sample tail string argument 1");
769    PA_PARSER.PushBackTail(&T_PAS);
770    PA_PARSER.PushBackTail(&t_pas1);
771
772    EXPECT_EQ(PA_PARSER.GetTailSize(), 2U);
773    EXPECT_FALSE(PA_PARSER.Parse(argc_tail, argv_tail));
774    PA_PARSER.DisableTail();
775    PA_PARSER.EraseTail();
776}
777
778// expect remainder arguments only parsed as expected
779HWTEST(libpandargs, TestRemainder, testing::ext::TestSize.Level0)
780{
781    PA_PARSER.EnableRemainder();
782    static const arg_list_t ref_rem = {"rem1", "rem2", "rem3"};
783    static int argc_rem = 5;
784    static const char *argv_rem[] = {"gtest_app", "--", "rem1", "rem2", "rem3"};
785    PA_PARSER.Parse(argc_rem, argv_rem);
786    arg_list_t remainder = PA_PARSER.GetRemainder();
787    EXPECT_EQ(remainder.size(), ref_rem.size());
788    for (std::size_t i = 0; i < remainder.size(); i++) {
789        EXPECT_EQ(remainder[i], ref_rem[i]);
790    }
791    PA_PARSER.DisableRemainder();
792}
793
794// expect regular argument before remainder parsed right
795HWTEST(libpandargs, TestRegularRemainder, testing::ext::TestSize.Level0)
796{
797    PA_PARSER.EnableRemainder();
798    static const arg_list_t ref_rem = {"rem1", "rem2", "rem3"};
799    std::string bool_name = "--" + PAB.GetName();
800    static int argc_rem = 6;
801    static const char *argv_rem[] = {"gtest_app", bool_name.c_str(), "--", "rem1", "rem2", "rem3"};
802    PA_PARSER.Parse(argc_rem, argv_rem);
803    EXPECT_TRUE(PAB.GetValue());
804    arg_list_t remainder = PA_PARSER.GetRemainder();
805    EXPECT_EQ(remainder.size(), ref_rem.size());
806    for (std::size_t i = 0; i < remainder.size(); i++) {
807        EXPECT_EQ(remainder[i], ref_rem[i]);
808    }
809    PA_PARSER.DisableRemainder();
810}
811
812static const char *ARGV_CONSISTENT[] = {"gtest_app", "--bool", "on", "--int=42", "--string", "this is a string",
813    "--double", ".42", "--uint32=4294967295", "--uint64=18446744073709551615", "--dlist=dlist1:dlist2:dlist3:dlist4",
814    "--rint=42", "--ruint32=990000000", "--ruint64=99000000000", "tail1", "tail2 tail3", "tail4", "--", "rem1",
815    "rem2", "rem3"};
816
817// expect that all arguments parsed as expected
818HWTEST(libpandargs, TestAll, testing::ext::TestSize.Level0)
819{
820    PALD.ResetDefaultValue();
821    PA_PARSER.EnableTail();
822    PA_PARSER.EnableRemainder();
823    static const arg_list_t ref_rem = {"rem1", "rem2", "rem3"};
824    PandArg<std::string> t_pas0("tail_string0", REF_DEF_STRING, "Sample tail string argument 0");
825    PandArg<std::string> t_pas1("tail_string1", REF_DEF_STRING, "Sample tail string argument 1");
826    static const bool ref_bool = true;
827    static const int ref_int = 42;
828    static const arg_list_t ref_dlist = {"dlist1", "dlist2", "dlist3", "dlist4"};
829    static const std::string ref_t_str1 = "tail1";
830    static const std::string ref_t_str2 = "tail2 tail3";
831    static const std::string ref_t_str3 = "tail4";
832    static const std::string ref_str = "this is a string";
833    static const double ref_dbl = 0.42;
834    static const uint32_t ref_uint32 = std::numeric_limits<std::uint32_t>::max();
835    static const uint32_t ref_uint32r = 990000000;
836    static const uint64_t ref_uint64 = std::numeric_limits<std::uint64_t>::max();
837    static const uint64_t ref_uint64r = 99000000000;
838    static int argc_consistent = 21;
839    PA_PARSER.PushBackTail(&T_PAS);
840    PA_PARSER.PushBackTail(&t_pas0);
841    PA_PARSER.PushBackTail(&t_pas1);
842    EXPECT_TRUE(PA_PARSER.Parse(argc_consistent, ARGV_CONSISTENT));
843    EXPECT_EQ(PAB.GetValue(), ref_bool);
844    EXPECT_EQ(PAI.GetValue(), ref_int);
845    EXPECT_EQ(PAS.GetValue(), ref_str);
846    EXPECT_DOUBLE_EQ(PAD.GetValue(), ref_dbl);
847    EXPECT_EQ(PAU32.GetValue(), ref_uint32);
848    EXPECT_EQ(PAU64.GetValue(), ref_uint64);
849    ASSERT_EQ(PALD.GetValue().size(), ref_dlist.size());
850    for (std::size_t i = 0; i < ref_dlist.size(); ++i) {
851        EXPECT_EQ(PALD.GetValue()[i], ref_dlist[i]);
852    }
853    EXPECT_EQ(PAIR.GetValue(), ref_int);
854    EXPECT_EQ(PAUR32.GetValue(), ref_uint32r);
855    EXPECT_EQ(PAUR64.GetValue(), ref_uint64r);
856    EXPECT_EQ(T_PAS.GetValue(), ref_t_str1);
857    EXPECT_EQ(t_pas0.GetValue(), ref_t_str2);
858    EXPECT_EQ(t_pas1.GetValue(), ref_t_str3);
859    arg_list_t remainder = PA_PARSER.GetRemainder();
860    EXPECT_EQ(remainder.size(), ref_rem.size());
861    for (std::size_t i = 0; i < remainder.size(); i++) {
862        EXPECT_EQ(remainder[i], ref_rem[i]);
863    }
864    PA_PARSER.DisableRemainder();
865    PA_PARSER.DisableTail();
866    PA_PARSER.EraseTail();
867}
868
869PandArg<bool> SUB_BOOL_ARG("bool", false, "Sample boolean argument");
870
871// The number 12 is the default parameter for variable SUB_INT_ARG
872PandArg<int> SUB_INT_ARG("int", 12, "Sample integer argument");
873
874// The number 123.45 is the default parameter for variable SUB_DOUBLE_ARG
875PandArg<double> SUB_DOUBLE_ARG("double", 123.45, "Sample rational argument");
876
877PandArg<std::string> SUB_STRING_ARG("string", "Hello", "Sample string argument");
878
879// The number 123 is the default parameter for variable INT_ARG
880PandArg<int> INT_ARG("global_int", 123, "Global integer argument");
881
882PandArgCompound PARENT("compound", "Sample boolean argument", {
883    &SUB_BOOL_ARG, &SUB_INT_ARG, &SUB_DOUBLE_ARG, &SUB_STRING_ARG});
884
885PandArgParser C_PARSER;
886
887HWTEST(libpandargs, CompoundArgsAdd, testing::ext::TestSize.Level0)
888{
889    ASSERT_TRUE(C_PARSER.Add(&INT_ARG));
890    ASSERT_TRUE(C_PARSER.Add(&PARENT));
891}
892
893// Should work well with no sub arguments
894HWTEST(libpandargs, CompoundArgsNoSub, testing::ext::TestSize.Level0)
895{
896    {
897        PARENT.ResetDefaultValue();
898        static const char *argv[] = {"gtest_app", "--compound"};
899        ASSERT_TRUE(C_PARSER.Parse(2, argv)) << C_PARSER.GetErrorString();
900        ASSERT_EQ(PARENT.GetValue(), true);
901        ASSERT_EQ(SUB_BOOL_ARG.GetValue(), false);
902        ASSERT_EQ(SUB_INT_ARG.GetValue(), 12);
903        ASSERT_EQ(SUB_DOUBLE_ARG.GetValue(), 123.45);
904        ASSERT_EQ(SUB_STRING_ARG.GetValue(), "Hello");
905    }
906
907    {
908        PARENT.ResetDefaultValue();
909        static const char *argv[] = {"gtest_app", "--compound:bool,int=2,double=54.321,string=World"};
910        ASSERT_TRUE(C_PARSER.Parse(2, argv)) << C_PARSER.GetErrorString();
911        ASSERT_EQ(PARENT.GetValue(), true);
912        ASSERT_EQ(SUB_BOOL_ARG.GetValue(), true);
913        ASSERT_EQ(SUB_INT_ARG.GetValue(), 2);
914        ASSERT_EQ(SUB_DOUBLE_ARG.GetValue(), 54.321);
915        ASSERT_EQ(SUB_STRING_ARG.GetValue(), "World");
916    }
917}
918
919// ResetDefaultValue should reset all sub arguments
920HWTEST(libpandargs, CompoundArgsResetDefaultValue, testing::ext::TestSize.Level0)
921{
922    {
923        PARENT.ResetDefaultValue();
924        ASSERT_EQ(PARENT.GetValue(), false);
925        ASSERT_EQ(SUB_BOOL_ARG.GetValue(), false);
926        ASSERT_EQ(SUB_INT_ARG.GetValue(), 12);
927        ASSERT_EQ(SUB_DOUBLE_ARG.GetValue(), 123.45);
928        ASSERT_EQ(SUB_STRING_ARG.GetValue(), "Hello");
929    }
930
931    {
932        static const char *argv[] = {"gtest_app", "--compound:bool=true"};
933        ASSERT_TRUE(C_PARSER.Parse(2, argv)) << C_PARSER.GetErrorString();
934        ASSERT_EQ(PARENT.GetValue(), true);
935        ASSERT_EQ(SUB_BOOL_ARG.GetValue(), true);
936    }
937
938    {
939        PARENT.ResetDefaultValue();
940        static const char *argv[] = {"gtest_app", "--compound:bool"};
941        ASSERT_TRUE(C_PARSER.Parse(2, argv)) << C_PARSER.GetErrorString();
942        ASSERT_EQ(PARENT.GetValue(), true);
943        ASSERT_EQ(SUB_BOOL_ARG.GetValue(), true);
944    }
945
946    {
947        static const char *argv[] = {"gtest_app", "--compound:bool=false"};
948        ASSERT_TRUE(C_PARSER.Parse(2, argv)) << C_PARSER.GetErrorString();
949        ASSERT_EQ(PARENT.GetValue(), true);
950        ASSERT_EQ(SUB_BOOL_ARG.GetValue(), false);
951    }
952
953    {
954        PARENT.ResetDefaultValue();
955        static const char *argv[] = {"gtest_app", "--global_int=321"};
956        ASSERT_TRUE(C_PARSER.Parse(2, argv)) << C_PARSER.GetErrorString();
957        ASSERT_EQ(PARENT.GetValue(), false);
958        ASSERT_EQ(INT_ARG.GetValue(), 321);
959    }
960
961    {
962        PARENT.ResetDefaultValue();
963        static const char *argv[] = {"gtest_app", "--compound", "--global_int", "321"};
964        ASSERT_TRUE(C_PARSER.Parse(4, argv)) << C_PARSER.GetErrorString();
965        ASSERT_EQ(PARENT.GetValue(), true);
966        ASSERT_EQ(INT_ARG.GetValue(), 321);
967    }
968}
969
970// Test that sub arguments are not visible in the global space
971HWTEST(libpandargs, CompoundArgsSubArguments, testing::ext::TestSize.Level0)
972{
973    {
974        static const char *argv[] = {"gtest_app", "--bool"};
975        ASSERT_FALSE(C_PARSER.Parse(2, argv));
976    }
977    {
978        static const char *argv[] = {"gtest_app", "--int=2"};
979        ASSERT_FALSE(C_PARSER.Parse(2, argv));
980    }
981    {
982        static const char *argv[] = {"gtest_app", "--double=54.321"};
983        ASSERT_FALSE(C_PARSER.Parse(2, argv));
984    }
985    {
986        static const char *argv[] = {"gtest_app", "--string=World"};
987        ASSERT_FALSE(C_PARSER.Parse(2, argv));
988    }
989}
990
991HWTEST(libpandargs, GetHelpString, testing::ext::TestSize.Level0)
992{
993    PandArg<bool> g_pab("bool", false, "Sample boolean argument");
994    PandArg<int> g_pai("int", 0, "Sample integer argument");
995    PandArg<std::string> g_pas("tail_string", "arg", "Sample tail string argument");
996    PandArgCompound g_pac("compound", "Sample compound argument", {&g_pab, &g_pai});
997
998    PandArgParser g_parser;
999    ASSERT_TRUE(g_parser.Add(&g_pab));
1000    ASSERT_TRUE(g_parser.Add(&g_pai));
1001    ASSERT_TRUE(g_parser.PushBackTail(&g_pas));
1002    ASSERT_TRUE(g_parser.Add(&g_pac));
1003
1004    std::string ref_string = "--" + g_pab.GetName() + ": " + g_pab.GetDesc() + "\n";
1005    ref_string += "--" + g_pac.GetName() + ": " + g_pac.GetDesc() + "\n";
1006    ref_string += "  Sub arguments:\n";
1007    ref_string += "    " + g_pab.GetName() + ": " + g_pab.GetDesc() + "\n";
1008    ref_string += "    " + g_pai.GetName() + ": " + g_pai.GetDesc() + "\n";
1009    ref_string += "--" + g_pai.GetName() + ": " + g_pai.GetDesc() + "\n";
1010    ref_string += "Tail arguments:\n";
1011    ref_string += g_pas.GetName() + ": " + g_pas.GetDesc() + "\n";
1012    ASSERT_EQ(g_parser.GetHelpString(), ref_string);
1013}
1014
1015}  // namespace panda::test
1016
1017