From 710b5a12324e54d42632985c46a3071fc2504fc9 Mon Sep 17 00:00:00 2001 From: Christian Sigg Date: Sun, 10 Sep 2023 12:25:19 +0200 Subject: Fix logic to detect cl::option equality. (#65754) This is a new attempt of https://reviews.llvm.org/D159481, this time as GitHub PR. `GenericOptionValue::compare()` should return `true` for a match. - `OptionValueBase::compare()` always returns `false` and shouldn't match anything. - `OptionValueCopy::compare()` returns `false` if not `Valid` which corresponds to no match. Also adding some tests. --- llvm/unittests/Support/CommandLineTest.cpp | 49 ++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'llvm/unittests/Support/CommandLineTest.cpp') diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp index 4f7cb40..41cc826 100644 --- a/llvm/unittests/Support/CommandLineTest.cpp +++ b/llvm/unittests/Support/CommandLineTest.cpp @@ -1294,7 +1294,8 @@ struct AutoDeleteFile { } }; -class PrintOptionInfoTest : public ::testing::Test { +template +class PrintOptionTestBase : public ::testing::Test { public: // Return std::string because the output of a failing EXPECT check is // unreadable for StringRef. It also avoids any lifetime issues. @@ -1309,7 +1310,7 @@ public: StackOption TestOption(Opt, cl::desc(HelpText), OptionAttributes...); - printOptionInfo(TestOption, 26); + Func(TestOption); outs().flush(); } auto Buffer = MemoryBuffer::getFile(File.FilePath); @@ -1321,14 +1322,15 @@ public: enum class OptionValue { Val }; const StringRef Opt = "some-option"; const StringRef HelpText = "some help"; +}; -private: // This is a workaround for cl::Option sub-classes having their // printOptionInfo functions private. - void printOptionInfo(const cl::Option &O, size_t Width) { - O.printOptionInfo(Width); - } -}; +void printOptionInfo(const cl::Option &O) { + O.printOptionInfo(/*GlobalWidth=*/26); +} + +using PrintOptionInfoTest = PrintOptionTestBase; TEST_F(PrintOptionInfoTest, PrintOptionInfoValueOptionalWithoutSentinel) { std::string Output = @@ -1402,7 +1404,7 @@ TEST_F(PrintOptionInfoTest, PrintOptionInfoMultilineValueDescription) { "which has a really long description\n" "thus it is multi-line."), clEnumValN(OptionValue::Val, "", - "This is an unnamed enum value option\n" + "This is an unnamed enum value\n" "Should be indented as well"))); // clang-format off @@ -1411,11 +1413,40 @@ TEST_F(PrintOptionInfoTest, PrintOptionInfoMultilineValueDescription) { " =v1 - This is the first enum value\n" " which has a really long description\n" " thus it is multi-line.\n" - " = - This is an unnamed enum value option\n" + " = - This is an unnamed enum value\n" " Should be indented as well\n").str()); // clang-format on } +void printOptionValue(const cl::Option &O) { + O.printOptionValue(/*GlobalWidth=*/12, /*Force=*/true); +} + +using PrintOptionValueTest = PrintOptionTestBase; + +TEST_F(PrintOptionValueTest, PrintOptionDefaultValue) { + std::string Output = + runTest(cl::init(OptionValue::Val), + cl::values(clEnumValN(OptionValue::Val, "v1", "desc1"))); + + EXPECT_EQ(Output, (" --" + Opt + " = v1 (default: v1)\n").str()); +} + +TEST_F(PrintOptionValueTest, PrintOptionNoDefaultValue) { + std::string Output = + runTest(cl::values(clEnumValN(OptionValue::Val, "v1", "desc1"))); + + // Note: the option still has a (zero-initialized) value, but the default + // is invalid and doesn't match any value. + EXPECT_EQ(Output, (" --" + Opt + " = v1 (default: )\n").str()); +} + +TEST_F(PrintOptionValueTest, PrintOptionUnknownValue) { + std::string Output = runTest(cl::init(OptionValue::Val)); + + EXPECT_EQ(Output, (" --" + Opt + " = *unknown option value*\n").str()); +} + class GetOptionWidthTest : public ::testing::Test { public: enum class OptionValue { Val }; -- cgit v1.1