|
@@ -13,7 +13,6 @@
|
|
|
#include "llvm/Config/config.h"
|
|
|
#include "llvm/Support/FileSystem.h"
|
|
|
#include "llvm/Support/InitLLVM.h"
|
|
|
-#include "llvm/Support/MemoryBuffer.h"
|
|
|
#include "llvm/Support/Path.h"
|
|
|
#include "llvm/Support/Program.h"
|
|
|
#include "llvm/Support/StringSaver.h"
|
|
@@ -840,137 +839,4 @@ TEST(CommandLineTest, GetCommandLineArguments) {
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-class OutputRedirector {
|
|
|
-public:
|
|
|
- OutputRedirector(int RedirectFD)
|
|
|
- : RedirectFD(RedirectFD), OldFD(dup(RedirectFD)) {
|
|
|
- if (OldFD == -1 ||
|
|
|
- sys::fs::createTemporaryFile("unittest-redirect", "", NewFD,
|
|
|
- FilePath) ||
|
|
|
- dup2(NewFD, RedirectFD) == -1)
|
|
|
- Valid = false;
|
|
|
- }
|
|
|
-
|
|
|
- ~OutputRedirector() {
|
|
|
- dup2(OldFD, RedirectFD);
|
|
|
- close(OldFD);
|
|
|
- close(NewFD);
|
|
|
- }
|
|
|
-
|
|
|
- SmallVector<char, 128> FilePath;
|
|
|
- bool Valid = true;
|
|
|
-
|
|
|
-private:
|
|
|
- int RedirectFD;
|
|
|
- int OldFD;
|
|
|
- int NewFD;
|
|
|
-};
|
|
|
-
|
|
|
-struct AutoDeleteFile {
|
|
|
- SmallVector<char, 128> FilePath;
|
|
|
- ~AutoDeleteFile() {
|
|
|
- if (!FilePath.empty())
|
|
|
- sys::fs::remove(std::string(FilePath.data(), FilePath.size()));
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-class PrintOptionInfoTest : 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.
|
|
|
- template <typename... Ts> std::string runTest(Ts... OptionAttributes) {
|
|
|
- AutoDeleteFile File;
|
|
|
- {
|
|
|
- OutputRedirector Stdout(fileno(stdout));
|
|
|
- if (!Stdout.Valid)
|
|
|
- return "";
|
|
|
- File.FilePath = Stdout.FilePath;
|
|
|
-
|
|
|
- StackOption<OptionValue> TestOption(Opt, cl::desc(HelpText),
|
|
|
- OptionAttributes...);
|
|
|
- printOptionInfo(TestOption, 25);
|
|
|
- outs().flush();
|
|
|
- }
|
|
|
- auto Buffer = MemoryBuffer::getFile(File.FilePath);
|
|
|
- if (!Buffer)
|
|
|
- return "";
|
|
|
- return Buffer->get()->getBuffer().str();
|
|
|
- }
|
|
|
-
|
|
|
- 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);
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-TEST_F(PrintOptionInfoTest, PrintOptionInfoValueOptionalWithoutSentinel) {
|
|
|
- std::string Output =
|
|
|
- runTest(cl::ValueOptional,
|
|
|
- cl::values(clEnumValN(OptionValue::Val, "v1", "desc1")));
|
|
|
-
|
|
|
- // clang-format off
|
|
|
- EXPECT_EQ(Output, (" -" + Opt + "=<value> - " + HelpText + "\n"
|
|
|
- " =v1 - desc1\n")
|
|
|
- .str());
|
|
|
- // clang-format on
|
|
|
-}
|
|
|
-
|
|
|
-TEST_F(PrintOptionInfoTest, PrintOptionInfoValueOptionalWithSentinel) {
|
|
|
- std::string Output = runTest(
|
|
|
- cl::ValueOptional, cl::values(clEnumValN(OptionValue::Val, "v1", "desc1"),
|
|
|
- clEnumValN(OptionValue::Val, "", "")));
|
|
|
-
|
|
|
- // clang-format off
|
|
|
- EXPECT_EQ(Output,
|
|
|
- (" -" + Opt + " - " + HelpText + "\n"
|
|
|
- " -" + Opt + "=<value> - " + HelpText + "\n"
|
|
|
- " =v1 - desc1\n")
|
|
|
- .str());
|
|
|
- // clang-format on
|
|
|
-}
|
|
|
-
|
|
|
-TEST_F(PrintOptionInfoTest, PrintOptionInfoValueOptionalWithSentinelWithHelp) {
|
|
|
- std::string Output = runTest(
|
|
|
- cl::ValueOptional, cl::values(clEnumValN(OptionValue::Val, "v1", "desc1"),
|
|
|
- clEnumValN(OptionValue::Val, "", "desc2")));
|
|
|
-
|
|
|
- // clang-format off
|
|
|
- EXPECT_EQ(Output, (" -" + Opt + " - " + HelpText + "\n"
|
|
|
- " -" + Opt + "=<value> - " + HelpText + "\n"
|
|
|
- " =v1 - desc1\n"
|
|
|
- " =<empty> - desc2\n")
|
|
|
- .str());
|
|
|
- // clang-format on
|
|
|
-}
|
|
|
-
|
|
|
-TEST_F(PrintOptionInfoTest, PrintOptionInfoValueRequiredWithEmptyValueName) {
|
|
|
- std::string Output = runTest(
|
|
|
- cl::ValueRequired, cl::values(clEnumValN(OptionValue::Val, "v1", "desc1"),
|
|
|
- clEnumValN(OptionValue::Val, "", "")));
|
|
|
-
|
|
|
- // clang-format off
|
|
|
- EXPECT_EQ(Output, (" -" + Opt + "=<value> - " + HelpText + "\n"
|
|
|
- " =v1 - desc1\n"
|
|
|
- " =<empty>\n")
|
|
|
- .str());
|
|
|
- // clang-format on
|
|
|
-}
|
|
|
-
|
|
|
-TEST_F(PrintOptionInfoTest, PrintOptionInfoEmptyValueDescription) {
|
|
|
- std::string Output = runTest(
|
|
|
- cl::ValueRequired, cl::values(clEnumValN(OptionValue::Val, "v1", "")));
|
|
|
-
|
|
|
- // clang-format off
|
|
|
- EXPECT_EQ(Output,
|
|
|
- (" -" + Opt + "=<value> - " + HelpText + "\n"
|
|
|
- " =v1\n").str());
|
|
|
- // clang-format on
|
|
|
-}
|
|
|
-
|
|
|
} // anonymous namespace
|