1 //===- unittest/Support/OptionParsingTest.cpp - OptTable tests ------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/STLExtras.h"
10 #include "llvm/Option/Arg.h"
11 #include "llvm/Option/ArgList.h"
12 #include "llvm/Option/OptTable.h"
13 #include "llvm/Option/Option.h"
14 #include "gtest/gtest.h"
17 using namespace llvm::opt
;
19 #if defined(__clang__)
20 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
24 OPT_INVALID
= 0, // This is not an option ID.
25 #define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),
31 #define PREFIX(NAME, VALUE) \
32 static constexpr StringLiteral NAME##_init[] = VALUE; \
33 static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
34 std::size(NAME##_init) - 1);
38 static constexpr const StringLiteral PrefixTable_init
[] =
39 #define PREFIX_UNION(VALUES) VALUES
43 static constexpr const ArrayRef
<StringLiteral
>
44 PrefixTable(PrefixTable_init
, std::size(PrefixTable_init
) - 1);
52 enum OptionVisibility
{
53 SubtoolVis
= (1 << 2),
54 MultiLineVis
= (1 << 3),
57 static constexpr OptTable::Info InfoTable
[] = {
58 #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
64 class TestOptTable
: public GenericOptTable
{
66 TestOptTable(bool IgnoreCase
= false)
67 : GenericOptTable(InfoTable
, IgnoreCase
) {}
70 class TestPrecomputedOptTable
: public PrecomputedOptTable
{
72 TestPrecomputedOptTable(bool IgnoreCase
= false)
73 : PrecomputedOptTable(InfoTable
, PrefixTable
, IgnoreCase
) {}
77 const char *Args
[] = {
83 "-E", "apple", "bloom",
90 template <typename T
> class OptTableTest
: public ::testing::Test
{};
92 template <typename T
> class DISABLED_OptTableTest
: public ::testing::Test
{};
94 // Test both precomputed and computed OptTables with the same suite of tests.
95 using OptTableTestTypes
=
96 ::testing::Types
<TestOptTable
, TestPrecomputedOptTable
>;
98 TYPED_TEST_SUITE(OptTableTest
, OptTableTestTypes
, );
99 TYPED_TEST_SUITE(DISABLED_OptTableTest
, OptTableTestTypes
, );
101 TYPED_TEST(OptTableTest
, OptionParsing
) {
104 InputArgList AL
= T
.ParseArgs(Args
, MAI
, MAC
);
106 // Check they all exist.
107 EXPECT_TRUE(AL
.hasArg(OPT_A
));
108 EXPECT_TRUE(AL
.hasArg(OPT_B
));
109 EXPECT_TRUE(AL
.hasArg(OPT_C
));
110 EXPECT_TRUE(AL
.hasArg(OPT_D
));
111 EXPECT_TRUE(AL
.hasArg(OPT_E
));
112 EXPECT_TRUE(AL
.hasArg(OPT_F
));
113 EXPECT_TRUE(AL
.hasArg(OPT_G
));
116 EXPECT_EQ("hi", AL
.getLastArgValue(OPT_B
));
117 EXPECT_EQ("bye", AL
.getLastArgValue(OPT_C
));
118 EXPECT_EQ("adena", AL
.getLastArgValue(OPT_D
));
119 std::vector
<std::string
> Es
= AL
.getAllArgValues(OPT_E
);
120 EXPECT_EQ("apple", Es
[0]);
121 EXPECT_EQ("bloom", Es
[1]);
122 EXPECT_EQ("42", AL
.getLastArgValue(OPT_F
));
123 std::vector
<std::string
> Gs
= AL
.getAllArgValues(OPT_G
);
124 EXPECT_EQ("chuu", Gs
[0]);
125 EXPECT_EQ("2", Gs
[1]);
127 // Check the help text.
129 raw_string_ostream
RSO(Help
);
130 T
.printHelp(RSO
, "test", "title!");
131 EXPECT_NE(std::string::npos
, Help
.find("-A"));
134 T
.printHelp(RSO
, "name [options] file...", "title!");
135 EXPECT_NE(std::string::npos
, Help
.find("USAGE: name [options] file...\n"));
138 auto Cs
= AL
.filtered(OPT_C
);
139 ASSERT_NE(Cs
.begin(), Cs
.end());
140 EXPECT_EQ("desu", StringRef((*Cs
.begin())->getValue()));
142 (*Cs
.begin())->render(AL
, ASL
);
143 ASSERT_EQ(2u, ASL
.size());
144 EXPECT_EQ("-C", StringRef(ASL
[0]));
145 EXPECT_EQ("desu", StringRef(ASL
[1]));
148 TYPED_TEST(OptTableTest
, ParseWithFlagExclusions
) {
152 // Exclude flag3 to avoid parsing as OPT_SLASH_C.
153 InputArgList AL
= T
.ParseArgs(Args
, MAI
, MAC
,
154 /*FlagsToInclude=*/0,
155 /*FlagsToExclude=*/OptFlag3
);
156 EXPECT_TRUE(AL
.hasArg(OPT_A
));
157 EXPECT_TRUE(AL
.hasArg(OPT_C
));
158 EXPECT_FALSE(AL
.hasArg(OPT_SLASH_C
));
160 // Exclude flag1 to avoid parsing as OPT_C.
161 AL
= T
.ParseArgs(Args
, MAI
, MAC
,
162 /*FlagsToInclude=*/0,
163 /*FlagsToExclude=*/OptFlag1
);
164 EXPECT_TRUE(AL
.hasArg(OPT_B
));
165 EXPECT_FALSE(AL
.hasArg(OPT_C
));
166 EXPECT_TRUE(AL
.hasArg(OPT_SLASH_C
));
168 const char *NewArgs
[] = { "/C", "foo", "--C=bar" };
169 AL
= T
.ParseArgs(NewArgs
, MAI
, MAC
);
170 EXPECT_TRUE(AL
.hasArg(OPT_SLASH_C
));
171 EXPECT_TRUE(AL
.hasArg(OPT_C
));
172 EXPECT_EQ("foo", AL
.getLastArgValue(OPT_SLASH_C
));
173 EXPECT_EQ("bar", AL
.getLastArgValue(OPT_C
));
176 TYPED_TEST(OptTableTest
, ParseWithVisibility
) {
180 const char *STArgs
[] = {"-A", "-Q", "-R"};
182 // With no visibility specified, we find all of the arguments.
183 InputArgList AL
= T
.ParseArgs(STArgs
, MAI
, MAC
);
184 EXPECT_TRUE(AL
.hasArg(OPT_A
));
185 EXPECT_TRUE(AL
.hasArg(OPT_Q
));
186 EXPECT_TRUE(AL
.hasArg(OPT_R
));
188 // Default visibility omits SubtoolVis.
189 AL
= T
.ParseArgs(STArgs
, MAI
, MAC
, Visibility(DefaultVis
));
190 EXPECT_TRUE(AL
.hasArg(OPT_A
));
191 EXPECT_FALSE(AL
.hasArg(OPT_Q
));
192 EXPECT_TRUE(AL
.hasArg(OPT_R
));
194 // ~SubtoolVis still finds arguments that are visible in Default.
195 AL
= T
.ParseArgs(STArgs
, MAI
, MAC
, Visibility(~SubtoolVis
));
196 EXPECT_TRUE(AL
.hasArg(OPT_A
));
197 EXPECT_FALSE(AL
.hasArg(OPT_Q
));
198 EXPECT_TRUE(AL
.hasArg(OPT_R
));
201 AL
= T
.ParseArgs(STArgs
, MAI
, MAC
, Visibility(SubtoolVis
));
202 EXPECT_FALSE(AL
.hasArg(OPT_A
));
203 EXPECT_TRUE(AL
.hasArg(OPT_Q
));
204 EXPECT_TRUE(AL
.hasArg(OPT_R
));
206 // Both Default and SubtoolVis are found.
207 AL
= T
.ParseArgs(STArgs
, MAI
, MAC
, Visibility(DefaultVis
| SubtoolVis
));
208 EXPECT_TRUE(AL
.hasArg(OPT_A
));
209 EXPECT_TRUE(AL
.hasArg(OPT_Q
));
210 EXPECT_TRUE(AL
.hasArg(OPT_R
));
213 TYPED_TEST(OptTableTest
, ParseAliasInGroup
) {
217 const char *MyArgs
[] = { "-I" };
218 InputArgList AL
= T
.ParseArgs(MyArgs
, MAI
, MAC
);
219 EXPECT_TRUE(AL
.hasArg(OPT_H
));
222 TYPED_TEST(OptTableTest
, AliasArgs
) {
226 const char *MyArgs
[] = { "-J", "-Joo" };
227 InputArgList AL
= T
.ParseArgs(MyArgs
, MAI
, MAC
);
228 EXPECT_TRUE(AL
.hasArg(OPT_B
));
229 EXPECT_EQ("foo", AL
.getAllArgValues(OPT_B
)[0]);
230 EXPECT_EQ("bar", AL
.getAllArgValues(OPT_B
)[1]);
233 TYPED_TEST(OptTableTest
, IgnoreCase
) {
237 const char *MyArgs
[] = { "-a", "-joo" };
238 InputArgList AL
= T
.ParseArgs(MyArgs
, MAI
, MAC
);
239 EXPECT_TRUE(AL
.hasArg(OPT_A
));
240 EXPECT_TRUE(AL
.hasArg(OPT_B
));
243 #if defined(__clang__)
244 // Disable the warning that triggers on exactly what is being tested.
245 #pragma clang diagnostic push
246 #pragma clang diagnostic ignored "-Wself-move"
249 TYPED_TEST(OptTableTest
, InputArgListSelfAssign
) {
252 InputArgList AL
= T
.ParseArgs(Args
, MAI
, MAC
,
253 /*FlagsToInclude=*/0,
254 /*FlagsToExclude=*/OptFlag3
);
255 EXPECT_TRUE(AL
.hasArg(OPT_A
));
256 EXPECT_TRUE(AL
.hasArg(OPT_C
));
257 EXPECT_FALSE(AL
.hasArg(OPT_SLASH_C
));
261 EXPECT_TRUE(AL
.hasArg(OPT_A
));
262 EXPECT_TRUE(AL
.hasArg(OPT_C
));
263 EXPECT_FALSE(AL
.hasArg(OPT_SLASH_C
));
266 #if defined(__clang__)
267 #pragma clang diagnostic pop
270 TYPED_TEST(OptTableTest
, DoNotIgnoreCase
) {
274 const char *MyArgs
[] = { "-a", "-joo" };
275 InputArgList AL
= T
.ParseArgs(MyArgs
, MAI
, MAC
);
276 EXPECT_FALSE(AL
.hasArg(OPT_A
));
277 EXPECT_FALSE(AL
.hasArg(OPT_B
));
280 TYPED_TEST(OptTableTest
, SlurpEmpty
) {
284 const char *MyArgs
[] = { "-A", "-slurp" };
285 InputArgList AL
= T
.ParseArgs(MyArgs
, MAI
, MAC
);
286 EXPECT_TRUE(AL
.hasArg(OPT_A
));
287 EXPECT_TRUE(AL
.hasArg(OPT_Slurp
));
288 EXPECT_EQ(0U, AL
.getAllArgValues(OPT_Slurp
).size());
291 TYPED_TEST(OptTableTest
, Slurp
) {
295 const char *MyArgs
[] = { "-A", "-slurp", "-B", "--", "foo" };
296 InputArgList AL
= T
.ParseArgs(MyArgs
, MAI
, MAC
);
297 EXPECT_EQ(AL
.size(), 2U);
298 EXPECT_TRUE(AL
.hasArg(OPT_A
));
299 EXPECT_FALSE(AL
.hasArg(OPT_B
));
300 EXPECT_TRUE(AL
.hasArg(OPT_Slurp
));
301 EXPECT_EQ(3U, AL
.getAllArgValues(OPT_Slurp
).size());
302 EXPECT_EQ("-B", AL
.getAllArgValues(OPT_Slurp
)[0]);
303 EXPECT_EQ("--", AL
.getAllArgValues(OPT_Slurp
)[1]);
304 EXPECT_EQ("foo", AL
.getAllArgValues(OPT_Slurp
)[2]);
307 TYPED_TEST(OptTableTest
, SlurpJoinedEmpty
) {
311 const char *MyArgs
[] = { "-A", "-slurpjoined" };
312 InputArgList AL
= T
.ParseArgs(MyArgs
, MAI
, MAC
);
313 EXPECT_TRUE(AL
.hasArg(OPT_A
));
314 EXPECT_TRUE(AL
.hasArg(OPT_SlurpJoined
));
315 EXPECT_EQ(AL
.getAllArgValues(OPT_SlurpJoined
).size(), 0U);
318 TYPED_TEST(OptTableTest
, SlurpJoinedOneJoined
) {
322 const char *MyArgs
[] = { "-A", "-slurpjoinedfoo" };
323 InputArgList AL
= T
.ParseArgs(MyArgs
, MAI
, MAC
);
324 EXPECT_TRUE(AL
.hasArg(OPT_A
));
325 EXPECT_TRUE(AL
.hasArg(OPT_SlurpJoined
));
326 EXPECT_EQ(AL
.getAllArgValues(OPT_SlurpJoined
).size(), 1U);
327 EXPECT_EQ(AL
.getAllArgValues(OPT_SlurpJoined
)[0], "foo");
330 TYPED_TEST(OptTableTest
, SlurpJoinedAndSeparate
) {
334 const char *MyArgs
[] = { "-A", "-slurpjoinedfoo", "bar", "baz" };
335 InputArgList AL
= T
.ParseArgs(MyArgs
, MAI
, MAC
);
336 EXPECT_TRUE(AL
.hasArg(OPT_A
));
337 EXPECT_TRUE(AL
.hasArg(OPT_SlurpJoined
));
338 EXPECT_EQ(3U, AL
.getAllArgValues(OPT_SlurpJoined
).size());
339 EXPECT_EQ("foo", AL
.getAllArgValues(OPT_SlurpJoined
)[0]);
340 EXPECT_EQ("bar", AL
.getAllArgValues(OPT_SlurpJoined
)[1]);
341 EXPECT_EQ("baz", AL
.getAllArgValues(OPT_SlurpJoined
)[2]);
344 TYPED_TEST(OptTableTest
, SlurpJoinedButSeparate
) {
348 const char *MyArgs
[] = { "-A", "-slurpjoined", "foo", "bar", "baz" };
349 InputArgList AL
= T
.ParseArgs(MyArgs
, MAI
, MAC
);
350 EXPECT_TRUE(AL
.hasArg(OPT_A
));
351 EXPECT_TRUE(AL
.hasArg(OPT_SlurpJoined
));
352 EXPECT_EQ(3U, AL
.getAllArgValues(OPT_SlurpJoined
).size());
353 EXPECT_EQ("foo", AL
.getAllArgValues(OPT_SlurpJoined
)[0]);
354 EXPECT_EQ("bar", AL
.getAllArgValues(OPT_SlurpJoined
)[1]);
355 EXPECT_EQ("baz", AL
.getAllArgValues(OPT_SlurpJoined
)[2]);
358 TYPED_TEST(OptTableTest
, FlagAliasToJoined
) {
362 // Check that a flag alias provides an empty argument to a joined option.
363 const char *MyArgs
[] = { "-K" };
364 InputArgList AL
= T
.ParseArgs(MyArgs
, MAI
, MAC
);
365 EXPECT_EQ(AL
.size(), 1U);
366 EXPECT_TRUE(AL
.hasArg(OPT_B
));
367 EXPECT_EQ(1U, AL
.getAllArgValues(OPT_B
).size());
368 EXPECT_EQ("", AL
.getAllArgValues(OPT_B
)[0]);
371 TYPED_TEST(OptTableTest
, FindNearest
) {
375 // Options that are too short should not be considered
376 // "near" other short options.
377 EXPECT_GT(T
.findNearest("-A", Nearest
), 4U);
378 EXPECT_GT(T
.findNearest("/C", Nearest
), 4U);
379 EXPECT_GT(T
.findNearest("--C=foo", Nearest
), 4U);
381 // The nearest candidate should mirror the amount of prefix
382 // characters used in the original string.
383 EXPECT_EQ(1U, T
.findNearest("-blorb", Nearest
));
384 EXPECT_EQ(Nearest
, "-blorp");
385 EXPECT_EQ(1U, T
.findNearest("--blorm", Nearest
));
386 EXPECT_EQ(Nearest
, "--blorp");
387 EXPECT_EQ(1U, T
.findNearest("-blarg", Nearest
));
388 EXPECT_EQ(Nearest
, "-blarn");
389 EXPECT_EQ(1U, T
.findNearest("--blarm", Nearest
));
390 EXPECT_EQ(Nearest
, "--blarn");
391 EXPECT_EQ(1U, T
.findNearest("-fjormp", Nearest
));
392 EXPECT_EQ(Nearest
, "--fjormp");
394 // The nearest candidate respects the prefix and value delimiter
395 // of the original string.
396 EXPECT_EQ(1U, T
.findNearest("/framb:foo", Nearest
));
397 EXPECT_EQ(Nearest
, "/cramb:foo");
399 // `--glormp` should have an editing distance > 0 from `--glormp=`.
400 EXPECT_GT(T
.findNearest("--glorrmp", Nearest
), 0U);
401 EXPECT_EQ(Nearest
, "--glorrmp=");
402 EXPECT_EQ(0U, T
.findNearest("--glorrmp=foo", Nearest
));
404 // `--blurmps` should correct to `--blurmp`, not `--blurmp=`, even though
405 // both naively have an editing distance of 1.
406 EXPECT_EQ(1U, T
.findNearest("--blurmps", Nearest
));
407 EXPECT_EQ(Nearest
, "--blurmp");
409 // ...but `--blurmps=foo` should correct to `--blurmp=foo`.
410 EXPECT_EQ(1U, T
.findNearest("--blurmps=foo", Nearest
));
411 EXPECT_EQ(Nearest
, "--blurmp=foo");
413 // Flags should be included and excluded as specified.
414 EXPECT_EQ(1U, T
.findNearest("-doopf", Nearest
,
415 /*FlagsToInclude=*/OptFlag2
,
416 /*FlagsToExclude=*/0));
417 EXPECT_EQ(Nearest
, "-doopf2");
418 EXPECT_EQ(1U, T
.findNearest("-doopf", Nearest
,
419 /*FlagsToInclude=*/0,
420 /*FlagsToExclude=*/OptFlag2
));
421 EXPECT_EQ(Nearest
, "-doopf1");
423 // Spelling should respect visibility.
424 EXPECT_EQ(1U, T
.findNearest("-xyzzy", Nearest
, Visibility(DefaultVis
)));
425 EXPECT_EQ(Nearest
, "-xyzzy2");
426 EXPECT_EQ(1U, T
.findNearest("-xyzzy", Nearest
, Visibility(SubtoolVis
)));
427 EXPECT_EQ(Nearest
, "-xyzzy1");
430 TYPED_TEST(DISABLED_OptTableTest
, FindNearestFIXME
) {
434 // FIXME: Options with joined values should not have those values considered
435 // when calculating distance. The test below would fail if run, but it should
437 EXPECT_EQ(1U, T
.findNearest("--erbghFoo", Nearest
));
438 EXPECT_EQ(Nearest
, "--ermghFoo");
441 TYPED_TEST(OptTableTest
, ParseGroupedShortOptions
) {
443 T
.setGroupedShortOptions(true);
446 // Grouped short options can be followed by a long Flag (-Joo), or a non-Flag
448 const char *Args1
[] = {"-AIJ", "-AIJoo", "-AC=1"};
449 InputArgList AL
= T
.ParseArgs(Args1
, MAI
, MAC
);
450 EXPECT_TRUE(AL
.hasArg(OPT_A
));
451 EXPECT_TRUE(AL
.hasArg(OPT_H
));
452 ASSERT_EQ((size_t)2, AL
.getAllArgValues(OPT_B
).size());
453 EXPECT_EQ("foo", AL
.getAllArgValues(OPT_B
)[0]);
454 EXPECT_EQ("bar", AL
.getAllArgValues(OPT_B
)[1]);
455 ASSERT_TRUE(AL
.hasArg(OPT_C
));
456 EXPECT_EQ("1", AL
.getAllArgValues(OPT_C
)[0]);
458 // Prefer a long option to a short option.
459 const char *Args2
[] = {"-AB"};
460 InputArgList AL2
= T
.ParseArgs(Args2
, MAI
, MAC
);
461 EXPECT_TRUE(!AL2
.hasArg(OPT_A
));
462 EXPECT_TRUE(AL2
.hasArg(OPT_AB
));
464 // Short options followed by a long option. We probably should disallow this.
465 const char *Args3
[] = {"-AIblorp"};
466 InputArgList AL3
= T
.ParseArgs(Args3
, MAI
, MAC
);
467 EXPECT_TRUE(AL3
.hasArg(OPT_A
));
468 EXPECT_TRUE(AL3
.hasArg(OPT_Blorp
));
471 TYPED_TEST(OptTableTest
, ParseDashDash
) {
473 T
.setDashDashParsing(true);
476 const char *Args1
[] = {"-A", "--"};
477 InputArgList AL
= T
.ParseArgs(Args1
, MAI
, MAC
);
478 EXPECT_TRUE(AL
.hasArg(OPT_A
));
479 EXPECT_EQ(size_t(0), AL
.getAllArgValues(OPT_INPUT
).size());
480 EXPECT_EQ(size_t(0), AL
.getAllArgValues(OPT_UNKNOWN
).size());
482 const char *Args2
[] = {"-A", "--", "-A", "--", "-B"};
483 AL
= T
.ParseArgs(Args2
, MAI
, MAC
);
484 EXPECT_TRUE(AL
.hasArg(OPT_A
));
485 EXPECT_FALSE(AL
.hasArg(OPT_B
));
486 const std::vector
<std::string
> Input
= AL
.getAllArgValues(OPT_INPUT
);
487 ASSERT_EQ(size_t(3), Input
.size());
488 EXPECT_EQ("-A", Input
[0]);
489 EXPECT_EQ("--", Input
[1]);
490 EXPECT_EQ("-B", Input
[2]);
491 EXPECT_EQ(size_t(0), AL
.getAllArgValues(OPT_UNKNOWN
).size());
493 T
.setDashDashParsing(false);
494 AL
= T
.ParseArgs(Args2
, MAI
, MAC
);
495 EXPECT_TRUE(AL
.hasArg(OPT_A
));
496 EXPECT_TRUE(AL
.hasArg(OPT_B
));
497 EXPECT_EQ(size_t(0), AL
.getAllArgValues(OPT_INPUT
).size());
498 const std::vector
<std::string
> Unknown
= AL
.getAllArgValues(OPT_UNKNOWN
);
499 ASSERT_EQ(size_t(2), Unknown
.size());
500 EXPECT_EQ("--", Unknown
[0]);
501 EXPECT_EQ("--", Unknown
[1]);
504 TYPED_TEST(OptTableTest
, UnknownOptions
) {
507 const char *Args
[] = {"-u", "--long", "0"};
508 for (int I
= 0; I
< 2; ++I
) {
509 T
.setGroupedShortOptions(I
!= 0);
510 InputArgList AL
= T
.ParseArgs(Args
, MAI
, MAC
);
511 const std::vector
<std::string
> Unknown
= AL
.getAllArgValues(OPT_UNKNOWN
);
512 ASSERT_EQ((size_t)2, Unknown
.size());
513 EXPECT_EQ("-u", Unknown
[0]);
514 EXPECT_EQ("--long", Unknown
[1]);
518 TYPED_TEST(OptTableTest
, FlagsWithoutValues
) {
520 T
.setGroupedShortOptions(true);
522 const char *Args
[] = {"-A=1", "-A="};
523 InputArgList AL
= T
.ParseArgs(Args
, MAI
, MAC
);
524 const std::vector
<std::string
> Unknown
= AL
.getAllArgValues(OPT_UNKNOWN
);
525 ASSERT_EQ((size_t)2, Unknown
.size());
526 EXPECT_EQ("-A=1", Unknown
[0]);
527 EXPECT_EQ("-A=", Unknown
[1]);
530 TYPED_TEST(OptTableTest
, UnknownGroupedShortOptions
) {
532 T
.setGroupedShortOptions(true);
534 const char *Args
[] = {"-AuzK", "-AuzK"};
535 InputArgList AL
= T
.ParseArgs(Args
, MAI
, MAC
);
536 const std::vector
<std::string
> Unknown
= AL
.getAllArgValues(OPT_UNKNOWN
);
537 ASSERT_EQ((size_t)4, Unknown
.size());
538 EXPECT_EQ("-u", Unknown
[0]);
539 EXPECT_EQ("-z", Unknown
[1]);
540 EXPECT_EQ("-u", Unknown
[2]);
541 EXPECT_EQ("-z", Unknown
[3]);
544 TYPED_TEST(OptTableTest
, PrintMultilineHelpText
) {
547 raw_string_ostream
RSO(Help
);
548 T
.printHelp(RSO
, "usage", "title", /*ShowHidden=*/false,
549 /*ShowAllAliases=*/false, Visibility(MultiLineVis
));
550 EXPECT_STREQ(Help
.c_str(), R
"(OVERVIEW: title
555 -multiline-help-with-long-name
556 This a help text that has
559 -multiline-help This a help text that has