driver_test.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/driver/driver.h"
  5. #include <gmock/gmock.h>
  6. #include <gtest/gtest.h>
  7. #include "llvm/ADT/SmallString.h"
  8. #include "llvm/Support/FileSystem.h"
  9. #include "llvm/Support/SourceMgr.h"
  10. #include "testing/base/test_raw_ostream.h"
  11. #include "toolchain/base/yaml_test_helpers.h"
  12. #include "toolchain/diagnostics/diagnostic_emitter.h"
  13. namespace Carbon::Testing {
  14. namespace {
  15. using ::testing::ElementsAre;
  16. using ::testing::HasSubstr;
  17. using ::testing::StrEq;
  18. class DriverTest : public testing::Test {
  19. protected:
  20. DriverTest() : driver_(fs_, test_output_stream_, test_error_stream_) {}
  21. auto CreateTestFile(llvm::StringRef text) -> llvm::StringRef {
  22. static constexpr llvm::StringLiteral TestFileName = "test_file.carbon";
  23. fs_.addFile(TestFileName, /*ModificationTime=*/0,
  24. llvm::MemoryBuffer::getMemBuffer(text));
  25. return TestFileName;
  26. }
  27. llvm::vfs::InMemoryFileSystem fs_;
  28. TestRawOstream test_output_stream_;
  29. TestRawOstream test_error_stream_;
  30. Driver driver_;
  31. };
  32. TEST_F(DriverTest, FullCommandErrors) {
  33. EXPECT_FALSE(driver_.RunFullCommand({}));
  34. EXPECT_THAT(test_error_stream_.TakeStr(), HasSubstr("ERROR"));
  35. EXPECT_FALSE(driver_.RunFullCommand({"foo"}));
  36. EXPECT_THAT(test_error_stream_.TakeStr(), HasSubstr("ERROR"));
  37. EXPECT_FALSE(driver_.RunFullCommand({"foo --bar --baz"}));
  38. EXPECT_THAT(test_error_stream_.TakeStr(), HasSubstr("ERROR"));
  39. }
  40. TEST_F(DriverTest, Help) {
  41. EXPECT_TRUE(driver_.RunHelpSubcommand(ConsoleDiagnosticConsumer(), {}));
  42. EXPECT_THAT(test_error_stream_.TakeStr(), StrEq(""));
  43. auto help_text = test_output_stream_.TakeStr();
  44. // Help text should mention each subcommand.
  45. #define CARBON_SUBCOMMAND(Name, Spelling, ...) \
  46. EXPECT_THAT(help_text, HasSubstr(Spelling));
  47. #include "toolchain/driver/flags.def"
  48. // Check that the subcommand dispatch works.
  49. EXPECT_TRUE(driver_.RunFullCommand({"help"}));
  50. EXPECT_THAT(test_error_stream_.TakeStr(), StrEq(""));
  51. EXPECT_THAT(test_output_stream_.TakeStr(), StrEq(help_text));
  52. }
  53. TEST_F(DriverTest, HelpErrors) {
  54. EXPECT_FALSE(driver_.RunHelpSubcommand(ConsoleDiagnosticConsumer(), {"foo"}));
  55. EXPECT_THAT(test_output_stream_.TakeStr(), StrEq(""));
  56. EXPECT_THAT(test_error_stream_.TakeStr(), HasSubstr("ERROR"));
  57. EXPECT_FALSE(
  58. driver_.RunHelpSubcommand(ConsoleDiagnosticConsumer(), {"help"}));
  59. EXPECT_THAT(test_output_stream_.TakeStr(), StrEq(""));
  60. EXPECT_THAT(test_error_stream_.TakeStr(), HasSubstr("ERROR"));
  61. EXPECT_FALSE(
  62. driver_.RunHelpSubcommand(ConsoleDiagnosticConsumer(), {"--xyz"}));
  63. EXPECT_THAT(test_output_stream_.TakeStr(), StrEq(""));
  64. EXPECT_THAT(test_error_stream_.TakeStr(), HasSubstr("ERROR"));
  65. }
  66. TEST_F(DriverTest, DumpTokens) {
  67. auto file = CreateTestFile("Hello World");
  68. EXPECT_TRUE(
  69. driver_.RunDumpSubcommand(ConsoleDiagnosticConsumer(), {"tokens", file}));
  70. EXPECT_THAT(test_error_stream_.TakeStr(), StrEq(""));
  71. auto tokenized_text = test_output_stream_.TakeStr();
  72. EXPECT_THAT(Yaml::Value::FromText(tokenized_text),
  73. ElementsAre(Yaml::SequenceValue{
  74. Yaml::MappingValue{{"index", "0"},
  75. {"kind", "Identifier"},
  76. {"line", "1"},
  77. {"column", "1"},
  78. {"indent", "1"},
  79. {"spelling", "Hello"},
  80. {"identifier", "0"},
  81. {"has_trailing_space", "true"}},
  82. Yaml::MappingValue{{"index", "1"},
  83. {"kind", "Identifier"},
  84. {"line", "1"},
  85. {"column", "7"},
  86. {"indent", "1"},
  87. {"spelling", "World"},
  88. {"identifier", "1"},
  89. {"has_trailing_space", "true"}},
  90. Yaml::MappingValue{{"index", "2"},
  91. {"kind", "EndOfFile"},
  92. {"line", "1"},
  93. {"column", "12"},
  94. {"indent", "1"},
  95. {"spelling", ""}}}));
  96. // Check that the subcommand dispatch works.
  97. EXPECT_TRUE(driver_.RunFullCommand({"dump", "tokens", file}));
  98. EXPECT_THAT(test_error_stream_.TakeStr(), StrEq(""));
  99. EXPECT_THAT(test_output_stream_.TakeStr(), StrEq(tokenized_text));
  100. }
  101. TEST_F(DriverTest, DumpErrors) {
  102. EXPECT_FALSE(driver_.RunDumpSubcommand(ConsoleDiagnosticConsumer(), {"foo"}));
  103. EXPECT_THAT(test_output_stream_.TakeStr(), StrEq(""));
  104. EXPECT_THAT(test_error_stream_.TakeStr(), HasSubstr("ERROR"));
  105. EXPECT_FALSE(
  106. driver_.RunDumpSubcommand(ConsoleDiagnosticConsumer(), {"--xyz"}));
  107. EXPECT_THAT(test_output_stream_.TakeStr(), StrEq(""));
  108. EXPECT_THAT(test_error_stream_.TakeStr(), HasSubstr("ERROR"));
  109. EXPECT_FALSE(
  110. driver_.RunDumpSubcommand(ConsoleDiagnosticConsumer(), {"tokens"}));
  111. EXPECT_THAT(test_output_stream_.TakeStr(), StrEq(""));
  112. EXPECT_THAT(test_error_stream_.TakeStr(), HasSubstr("ERROR"));
  113. EXPECT_FALSE(driver_.RunDumpSubcommand(ConsoleDiagnosticConsumer(),
  114. {"tokens", "/not/a/real/file/name"}));
  115. EXPECT_THAT(test_output_stream_.TakeStr(), StrEq(""));
  116. EXPECT_THAT(test_error_stream_.TakeStr(), HasSubstr("ERROR"));
  117. }
  118. TEST_F(DriverTest, DumpParseTree) {
  119. auto file = CreateTestFile("var v: Int = 42;");
  120. EXPECT_TRUE(driver_.RunDumpSubcommand(ConsoleDiagnosticConsumer(),
  121. {"parse-tree", file}));
  122. EXPECT_THAT(test_error_stream_.TakeStr(), StrEq(""));
  123. // Verify there is output without examining it.
  124. EXPECT_FALSE(test_output_stream_.TakeStr().empty());
  125. // Check that the subcommand dispatch works.
  126. EXPECT_TRUE(driver_.RunFullCommand({"dump", "parse-tree", file}));
  127. EXPECT_THAT(test_error_stream_.TakeStr(), StrEq(""));
  128. // Verify there is output without examining it.
  129. EXPECT_FALSE(test_output_stream_.TakeStr().empty());
  130. }
  131. } // namespace
  132. } // namespace Carbon::Testing