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