brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.3 KiB · 3da015e Raw
562 lines · cpp
1//===- unittest/Support/OptionParsingTest.cpp - OptTable tests ------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 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"15 16using namespace llvm;17using namespace llvm::opt;18 19#if defined(__clang__)20#pragma clang diagnostic ignored "-Wdeprecated-declarations"21#endif22 23#define OPTTABLE_STR_TABLE_CODE24#include "Opts.inc"25#undef OPTTABLE_STR_TABLE_CODE26 27enum ID {28  OPT_INVALID = 0, // This is not an option ID.29#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),30#include "Opts.inc"31  LastOption32#undef OPTION33};34 35#define OPTTABLE_PREFIXES_TABLE_CODE36#include "Opts.inc"37#undef OPTTABLE_PREFIXES_TABLE_CODE38 39#define OPTTABLE_PREFIXES_UNION_CODE40#include "Opts.inc"41#undef OPTTABLE_PREFIXES_UNION_CODE42 43enum OptionFlags {44  OptFlag1 = (1 << 4),45  OptFlag2 = (1 << 5),46  OptFlag3 = (1 << 6)47};48 49enum OptionVisibility {50  SubtoolVis = (1 << 2),51  MultiLineVis = (1 << 3),52};53 54static constexpr OptTable::Info InfoTable[] = {55#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),56#include "Opts.inc"57#undef OPTION58};59 60namespace {61class TestOptTable : public GenericOptTable {62public:63  TestOptTable(bool IgnoreCase = false)64      : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable,65                        IgnoreCase) {}66};67 68class TestPrecomputedOptTable : public PrecomputedOptTable {69public:70  TestPrecomputedOptTable(bool IgnoreCase = false)71      : PrecomputedOptTable(OptionStrTable, OptionPrefixesTable, InfoTable,72                            OptionPrefixesUnion, IgnoreCase) {}73};74}75 76const char *Args[] = {77  "-A",78  "-Bhi",79  "--C=desu",80  "-C", "bye",81  "-D,adena",82  "-E", "apple", "bloom",83  "-Fblarg",84  "-F", "42",85  "-Gchuu", "2"86  };87 88// Test fixture89template <typename T> class OptTableTest : public ::testing::Test {};90 91template <typename T> class DISABLED_OptTableTest : public ::testing::Test {};92 93// Test both precomputed and computed OptTables with the same suite of tests.94using OptTableTestTypes =95    ::testing::Types<TestOptTable, TestPrecomputedOptTable>;96 97TYPED_TEST_SUITE(OptTableTest, OptTableTestTypes, );98TYPED_TEST_SUITE(DISABLED_OptTableTest, OptTableTestTypes, );99 100TYPED_TEST(OptTableTest, OptionParsing) {101  TypeParam T;102  unsigned MAI, MAC;103  InputArgList AL = T.ParseArgs(Args, MAI, MAC);104 105  // Check they all exist.106  EXPECT_TRUE(AL.hasArg(OPT_A));107  EXPECT_TRUE(AL.hasArg(OPT_B));108  EXPECT_TRUE(AL.hasArg(OPT_C));109  EXPECT_TRUE(AL.hasArg(OPT_D));110  EXPECT_TRUE(AL.hasArg(OPT_E));111  EXPECT_TRUE(AL.hasArg(OPT_F));112  EXPECT_TRUE(AL.hasArg(OPT_G));113 114  // Check the values.115  EXPECT_EQ("hi", AL.getLastArgValue(OPT_B));116  EXPECT_EQ("bye", AL.getLastArgValue(OPT_C));117  EXPECT_EQ("adena", AL.getLastArgValue(OPT_D));118  std::vector<std::string> Es = AL.getAllArgValues(OPT_E);119  EXPECT_EQ("apple", Es[0]);120  EXPECT_EQ("bloom", Es[1]);121  EXPECT_EQ("42", AL.getLastArgValue(OPT_F));122  std::vector<std::string> Gs = AL.getAllArgValues(OPT_G);123  EXPECT_EQ("chuu", Gs[0]);124  EXPECT_EQ("2", Gs[1]);125 126  // Check the help text.127  std::string Help;128  raw_string_ostream RSO(Help);129  T.printHelp(RSO, "test", "title!");130  EXPECT_NE(std::string::npos, Help.find("-A"));131 132  // Check usage line.133  T.printHelp(RSO, "name [options] file...", "title!");134  EXPECT_NE(std::string::npos, Help.find("USAGE: name [options] file...\n"));135 136  // Test aliases.137  auto Cs = AL.filtered(OPT_C);138  ASSERT_NE(Cs.begin(), Cs.end());139  EXPECT_EQ("desu", StringRef((*Cs.begin())->getValue()));140  ArgStringList ASL;141  (*Cs.begin())->render(AL, ASL);142  ASSERT_EQ(2u, ASL.size());143  EXPECT_EQ("-C", StringRef(ASL[0]));144  EXPECT_EQ("desu", StringRef(ASL[1]));145}146 147TYPED_TEST(OptTableTest, ParseWithFlagExclusions) {148  TypeParam T;149  unsigned MAI, MAC;150 151  // Exclude flag3 to avoid parsing as OPT_SLASH_C.152  InputArgList AL = T.ParseArgs(Args, MAI, MAC,153                                /*FlagsToInclude=*/0,154                                /*FlagsToExclude=*/OptFlag3);155  EXPECT_TRUE(AL.hasArg(OPT_A));156  EXPECT_TRUE(AL.hasArg(OPT_C));157  EXPECT_FALSE(AL.hasArg(OPT_SLASH_C));158 159  // Exclude flag1 to avoid parsing as OPT_C.160  AL = T.ParseArgs(Args, MAI, MAC,161                   /*FlagsToInclude=*/0,162                   /*FlagsToExclude=*/OptFlag1);163  EXPECT_TRUE(AL.hasArg(OPT_B));164  EXPECT_FALSE(AL.hasArg(OPT_C));165  EXPECT_TRUE(AL.hasArg(OPT_SLASH_C));166 167  const char *NewArgs[] = { "/C", "foo", "--C=bar" };168  AL = T.ParseArgs(NewArgs, MAI, MAC);169  EXPECT_TRUE(AL.hasArg(OPT_SLASH_C));170  EXPECT_TRUE(AL.hasArg(OPT_C));171  EXPECT_EQ("foo", AL.getLastArgValue(OPT_SLASH_C));172  EXPECT_EQ("bar", AL.getLastArgValue(OPT_C));173}174 175TYPED_TEST(OptTableTest, ParseWithVisibility) {176  TypeParam T;177  unsigned MAI, MAC;178 179  const char *STArgs[] = {"-A", "-Q", "-R"};180 181  // With no visibility specified, we find all of the arguments.182  InputArgList AL = T.ParseArgs(STArgs, MAI, MAC);183  EXPECT_TRUE(AL.hasArg(OPT_A));184  EXPECT_TRUE(AL.hasArg(OPT_Q));185  EXPECT_TRUE(AL.hasArg(OPT_R));186 187  // Default visibility omits SubtoolVis.188  AL = T.ParseArgs(STArgs, MAI, MAC, Visibility(DefaultVis));189  EXPECT_TRUE(AL.hasArg(OPT_A));190  EXPECT_FALSE(AL.hasArg(OPT_Q));191  EXPECT_TRUE(AL.hasArg(OPT_R));192 193  // ~SubtoolVis still finds arguments that are visible in Default.194  AL = T.ParseArgs(STArgs, MAI, MAC, Visibility(~SubtoolVis));195  EXPECT_TRUE(AL.hasArg(OPT_A));196  EXPECT_FALSE(AL.hasArg(OPT_Q));197  EXPECT_TRUE(AL.hasArg(OPT_R));198 199  // Only SubtoolVis.200  AL = T.ParseArgs(STArgs, MAI, MAC, Visibility(SubtoolVis));201  EXPECT_FALSE(AL.hasArg(OPT_A));202  EXPECT_TRUE(AL.hasArg(OPT_Q));203  EXPECT_TRUE(AL.hasArg(OPT_R));204 205  // Both Default and SubtoolVis are found.206  AL = T.ParseArgs(STArgs, MAI, MAC, Visibility(DefaultVis | SubtoolVis));207  EXPECT_TRUE(AL.hasArg(OPT_A));208  EXPECT_TRUE(AL.hasArg(OPT_Q));209  EXPECT_TRUE(AL.hasArg(OPT_R));210}211 212TYPED_TEST(OptTableTest, ParseAliasInGroup) {213  TypeParam T;214  unsigned MAI, MAC;215 216  const char *MyArgs[] = { "-I" };217  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);218  EXPECT_TRUE(AL.hasArg(OPT_H));219}220 221TYPED_TEST(OptTableTest, AliasArgs) {222  TypeParam T;223  unsigned MAI, MAC;224 225  const char *MyArgs[] = { "-J", "-Joo" };226  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);227  EXPECT_TRUE(AL.hasArg(OPT_B));228  EXPECT_EQ("foo", AL.getAllArgValues(OPT_B)[0]);229  EXPECT_EQ("bar", AL.getAllArgValues(OPT_B)[1]);230}231 232TYPED_TEST(OptTableTest, IgnoreCase) {233  TypeParam T(true);234  unsigned MAI, MAC;235 236  const char *MyArgs[] = { "-a", "-joo" };237  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);238  EXPECT_TRUE(AL.hasArg(OPT_A));239  EXPECT_TRUE(AL.hasArg(OPT_B));240}241 242#if defined(__clang__)243// Disable the warning that triggers on exactly what is being tested.244#pragma clang diagnostic push245#pragma clang diagnostic ignored "-Wself-move"246#endif247 248TYPED_TEST(OptTableTest, InputArgListSelfAssign) {249  TypeParam T;250  unsigned MAI, MAC;251  InputArgList AL = T.ParseArgs(Args, MAI, MAC,252                                /*FlagsToInclude=*/0,253                                /*FlagsToExclude=*/OptFlag3);254  EXPECT_TRUE(AL.hasArg(OPT_A));255  EXPECT_TRUE(AL.hasArg(OPT_C));256  EXPECT_FALSE(AL.hasArg(OPT_SLASH_C));257 258  AL = std::move(AL);259 260  EXPECT_TRUE(AL.hasArg(OPT_A));261  EXPECT_TRUE(AL.hasArg(OPT_C));262  EXPECT_FALSE(AL.hasArg(OPT_SLASH_C));263}264 265#if defined(__clang__)266#pragma clang diagnostic pop267#endif268 269TYPED_TEST(OptTableTest, DoNotIgnoreCase) {270  TypeParam T;271  unsigned MAI, MAC;272 273  const char *MyArgs[] = { "-a", "-joo" };274  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);275  EXPECT_FALSE(AL.hasArg(OPT_A));276  EXPECT_FALSE(AL.hasArg(OPT_B));277}278 279TYPED_TEST(OptTableTest, SlurpEmpty) {280  TypeParam T;281  unsigned MAI, MAC;282 283  const char *MyArgs[] = { "-A", "-slurp" };284  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);285  EXPECT_TRUE(AL.hasArg(OPT_A));286  EXPECT_TRUE(AL.hasArg(OPT_Slurp));287  EXPECT_EQ(0U, AL.getAllArgValues(OPT_Slurp).size());288}289 290TYPED_TEST(OptTableTest, Slurp) {291  TypeParam T;292  unsigned MAI, MAC;293 294  const char *MyArgs[] = { "-A", "-slurp", "-B", "--", "foo" };295  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);296  EXPECT_EQ(AL.size(), 2U);297  EXPECT_TRUE(AL.hasArg(OPT_A));298  EXPECT_FALSE(AL.hasArg(OPT_B));299  EXPECT_TRUE(AL.hasArg(OPT_Slurp));300  EXPECT_EQ(3U, AL.getAllArgValues(OPT_Slurp).size());301  EXPECT_EQ("-B", AL.getAllArgValues(OPT_Slurp)[0]);302  EXPECT_EQ("--", AL.getAllArgValues(OPT_Slurp)[1]);303  EXPECT_EQ("foo", AL.getAllArgValues(OPT_Slurp)[2]);304}305 306TYPED_TEST(OptTableTest, SlurpJoinedEmpty) {307  TypeParam T;308  unsigned MAI, MAC;309 310  const char *MyArgs[] = { "-A", "-slurpjoined" };311  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);312  EXPECT_TRUE(AL.hasArg(OPT_A));313  EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));314  EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined).size(), 0U);315}316 317TYPED_TEST(OptTableTest, SlurpJoinedOneJoined) {318  TypeParam T;319  unsigned MAI, MAC;320 321  const char *MyArgs[] = { "-A", "-slurpjoinedfoo" };322  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);323  EXPECT_TRUE(AL.hasArg(OPT_A));324  EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));325  EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined).size(), 1U);326  EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined)[0], "foo");327}328 329TYPED_TEST(OptTableTest, SlurpJoinedAndSeparate) {330  TypeParam T;331  unsigned MAI, MAC;332 333  const char *MyArgs[] = { "-A", "-slurpjoinedfoo", "bar", "baz" };334  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);335  EXPECT_TRUE(AL.hasArg(OPT_A));336  EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));337  EXPECT_EQ(3U, AL.getAllArgValues(OPT_SlurpJoined).size());338  EXPECT_EQ("foo", AL.getAllArgValues(OPT_SlurpJoined)[0]);339  EXPECT_EQ("bar", AL.getAllArgValues(OPT_SlurpJoined)[1]);340  EXPECT_EQ("baz", AL.getAllArgValues(OPT_SlurpJoined)[2]);341}342 343TYPED_TEST(OptTableTest, SlurpJoinedButSeparate) {344  TypeParam T;345  unsigned MAI, MAC;346 347  const char *MyArgs[] = { "-A", "-slurpjoined", "foo", "bar", "baz" };348  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);349  EXPECT_TRUE(AL.hasArg(OPT_A));350  EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));351  EXPECT_EQ(3U, AL.getAllArgValues(OPT_SlurpJoined).size());352  EXPECT_EQ("foo", AL.getAllArgValues(OPT_SlurpJoined)[0]);353  EXPECT_EQ("bar", AL.getAllArgValues(OPT_SlurpJoined)[1]);354  EXPECT_EQ("baz", AL.getAllArgValues(OPT_SlurpJoined)[2]);355}356 357TYPED_TEST(OptTableTest, FlagAliasToJoined) {358  TypeParam T;359  unsigned MAI, MAC;360 361  // Check that a flag alias provides an empty argument to a joined option.362  const char *MyArgs[] = { "-K" };363  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);364  EXPECT_EQ(AL.size(), 1U);365  EXPECT_TRUE(AL.hasArg(OPT_B));366  EXPECT_EQ(1U, AL.getAllArgValues(OPT_B).size());367  EXPECT_EQ("", AL.getAllArgValues(OPT_B)[0]);368}369 370TYPED_TEST(OptTableTest, FindNearest) {371  TypeParam T;372  std::string Nearest;373 374  // Options that are too short should not be considered375  // "near" other short options.376  EXPECT_GT(T.findNearest("-A", Nearest), 4U);377  EXPECT_GT(T.findNearest("/C", Nearest), 4U);378  EXPECT_GT(T.findNearest("--C=foo", Nearest), 4U);379 380  // The nearest candidate should mirror the amount of prefix381  // characters used in the original string.382  EXPECT_EQ(1U, T.findNearest("-blorb", Nearest));383  EXPECT_EQ(Nearest, "-blorp");384  EXPECT_EQ(1U, T.findNearest("--blorm", Nearest));385  EXPECT_EQ(Nearest, "--blorp");386  EXPECT_EQ(1U, T.findNearest("-blarg", Nearest));387  EXPECT_EQ(Nearest, "-blarn");388  EXPECT_EQ(1U, T.findNearest("--blarm", Nearest));389  EXPECT_EQ(Nearest, "--blarn");390  EXPECT_EQ(1U, T.findNearest("-fjormp", Nearest));391  EXPECT_EQ(Nearest, "--fjormp");392 393  // The nearest candidate respects the prefix and value delimiter394  // of the original string.395  EXPECT_EQ(1U, T.findNearest("/framb:foo", Nearest));396  EXPECT_EQ(Nearest, "/cramb:foo");397 398  // `--glormp` should have an editing distance > 0 from `--glormp=`.399  EXPECT_GT(T.findNearest("--glorrmp", Nearest), 0U);400  EXPECT_EQ(Nearest, "--glorrmp=");401  EXPECT_EQ(0U, T.findNearest("--glorrmp=foo", Nearest));402 403  // `--blurmps` should correct to `--blurmp`, not `--blurmp=`, even though404  // both naively have an editing distance of 1.405  EXPECT_EQ(1U, T.findNearest("--blurmps", Nearest));406  EXPECT_EQ(Nearest, "--blurmp");407 408  // ...but `--blurmps=foo` should correct to `--blurmp=foo`.409  EXPECT_EQ(1U, T.findNearest("--blurmps=foo", Nearest));410  EXPECT_EQ(Nearest, "--blurmp=foo");411 412  // Flags should be included and excluded as specified.413  EXPECT_EQ(1U, T.findNearest("-doopf", Nearest,414                              /*FlagsToInclude=*/OptFlag2,415                              /*FlagsToExclude=*/0));416  EXPECT_EQ(Nearest, "-doopf2");417  EXPECT_EQ(1U, T.findNearest("-doopf", Nearest,418                              /*FlagsToInclude=*/0,419                              /*FlagsToExclude=*/OptFlag2));420  EXPECT_EQ(Nearest, "-doopf1");421 422  // Spelling should respect visibility.423  EXPECT_EQ(1U, T.findNearest("-xyzzy", Nearest, Visibility(DefaultVis)));424  EXPECT_EQ(Nearest, "-xyzzy2");425  EXPECT_EQ(1U, T.findNearest("-xyzzy", Nearest, Visibility(SubtoolVis)));426  EXPECT_EQ(Nearest, "-xyzzy1");427}428 429TYPED_TEST(DISABLED_OptTableTest, FindNearestFIXME) {430  TypeParam T;431  std::string Nearest;432 433  // FIXME: Options with joined values should not have those values considered434  // when calculating distance. The test below would fail if run, but it should435  // succeed.436  EXPECT_EQ(1U, T.findNearest("--erbghFoo", Nearest));437  EXPECT_EQ(Nearest, "--ermghFoo");438}439 440TYPED_TEST(OptTableTest, ParseGroupedShortOptions) {441  TypeParam T;442  T.setGroupedShortOptions(true);443  unsigned MAI, MAC;444 445  // Grouped short options can be followed by a long Flag (-Joo), or a non-Flag446  // option (-C=1).447  const char *Args1[] = {"-AIJ", "-AIJoo", "-AC=1"};448  InputArgList AL = T.ParseArgs(Args1, MAI, MAC);449  EXPECT_TRUE(AL.hasArg(OPT_A));450  EXPECT_TRUE(AL.hasArg(OPT_H));451  ASSERT_EQ((size_t)2, AL.getAllArgValues(OPT_B).size());452  EXPECT_EQ("foo", AL.getAllArgValues(OPT_B)[0]);453  EXPECT_EQ("bar", AL.getAllArgValues(OPT_B)[1]);454  ASSERT_TRUE(AL.hasArg(OPT_C));455  EXPECT_EQ("1", AL.getAllArgValues(OPT_C)[0]);456 457  // Prefer a long option to a short option.458  const char *Args2[] = {"-AB"};459  InputArgList AL2 = T.ParseArgs(Args2, MAI, MAC);460  EXPECT_TRUE(!AL2.hasArg(OPT_A));461  EXPECT_TRUE(AL2.hasArg(OPT_AB));462 463  // Short options followed by a long option. We probably should disallow this.464  const char *Args3[] = {"-AIblorp"};465  InputArgList AL3 = T.ParseArgs(Args3, MAI, MAC);466  EXPECT_TRUE(AL3.hasArg(OPT_A));467  EXPECT_TRUE(AL3.hasArg(OPT_Blorp));468}469 470TYPED_TEST(OptTableTest, ParseDashDash) {471  TypeParam T;472  T.setDashDashParsing(true);473  unsigned MAI, MAC;474 475  const char *Args1[] = {"-A", "--"};476  InputArgList AL = T.ParseArgs(Args1, MAI, MAC);477  EXPECT_TRUE(AL.hasArg(OPT_A));478  EXPECT_EQ(size_t(0), AL.getAllArgValues(OPT_INPUT).size());479  EXPECT_EQ(size_t(0), AL.getAllArgValues(OPT_UNKNOWN).size());480 481  const char *Args2[] = {"-A", "--", "-A", "--", "-B"};482  AL = T.ParseArgs(Args2, MAI, MAC);483  EXPECT_TRUE(AL.hasArg(OPT_A));484  EXPECT_FALSE(AL.hasArg(OPT_B));485  const std::vector<std::string> Input = AL.getAllArgValues(OPT_INPUT);486  ASSERT_EQ(size_t(3), Input.size());487  EXPECT_EQ("-A", Input[0]);488  EXPECT_EQ("--", Input[1]);489  EXPECT_EQ("-B", Input[2]);490  EXPECT_EQ(size_t(0), AL.getAllArgValues(OPT_UNKNOWN).size());491 492  T.setDashDashParsing(false);493  AL = T.ParseArgs(Args2, MAI, MAC);494  EXPECT_TRUE(AL.hasArg(OPT_A));495  EXPECT_TRUE(AL.hasArg(OPT_B));496  EXPECT_EQ(size_t(0), AL.getAllArgValues(OPT_INPUT).size());497  const std::vector<std::string> Unknown = AL.getAllArgValues(OPT_UNKNOWN);498  ASSERT_EQ(size_t(2), Unknown.size());499  EXPECT_EQ("--", Unknown[0]);500  EXPECT_EQ("--", Unknown[1]);501}502 503TYPED_TEST(OptTableTest, UnknownOptions) {504  TypeParam T;505  unsigned MAI, MAC;506  const char *Args[] = {"-u", "--long", "0"};507  for (int I = 0; I < 2; ++I) {508    T.setGroupedShortOptions(I != 0);509    InputArgList AL = T.ParseArgs(Args, MAI, MAC);510    const std::vector<std::string> Unknown = AL.getAllArgValues(OPT_UNKNOWN);511    ASSERT_EQ((size_t)2, Unknown.size());512    EXPECT_EQ("-u", Unknown[0]);513    EXPECT_EQ("--long", Unknown[1]);514  }515}516 517TYPED_TEST(OptTableTest, FlagsWithoutValues) {518  TypeParam T;519  T.setGroupedShortOptions(true);520  unsigned MAI, MAC;521  const char *Args[] = {"-A=1", "-A="};522  InputArgList AL = T.ParseArgs(Args, MAI, MAC);523  const std::vector<std::string> Unknown = AL.getAllArgValues(OPT_UNKNOWN);524  ASSERT_EQ((size_t)2, Unknown.size());525  EXPECT_EQ("-A=1", Unknown[0]);526  EXPECT_EQ("-A=", Unknown[1]);527}528 529TYPED_TEST(OptTableTest, UnknownGroupedShortOptions) {530  TypeParam T;531  T.setGroupedShortOptions(true);532  unsigned MAI, MAC;533  const char *Args[] = {"-AuzK", "-AuzK"};534  InputArgList AL = T.ParseArgs(Args, MAI, MAC);535  const std::vector<std::string> Unknown = AL.getAllArgValues(OPT_UNKNOWN);536  ASSERT_EQ((size_t)4, Unknown.size());537  EXPECT_EQ("-u", Unknown[0]);538  EXPECT_EQ("-z", Unknown[1]);539  EXPECT_EQ("-u", Unknown[2]);540  EXPECT_EQ("-z", Unknown[3]);541}542 543TYPED_TEST(OptTableTest, PrintMultilineHelpText) {544  TypeParam T;545  std::string Help;546  raw_string_ostream RSO(Help);547  T.printHelp(RSO, "usage", "title", /*ShowHidden=*/false,548              /*ShowAllAliases=*/false, Visibility(MultiLineVis));549  EXPECT_STREQ(Help.c_str(), R"(OVERVIEW: title550 551USAGE: usage552 553OPTIONS:554  -multiline-help-with-long-name555                  This a help text that has556                  multiple lines in it557                  and a long name558  -multiline-help This a help text that has559                  multiple lines in it560)");561}562