DiagnosticsYamlTest.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. //===- unittests/Tooling/DiagnosticsYamlTest.cpp - Serialization 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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Tests for serialization of Diagnostics.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/Tooling/DiagnosticsYaml.h"
  13. #include "clang/Tooling/Core/Diagnostic.h"
  14. #include "clang/Tooling/ReplacementsYaml.h"
  15. #include "gtest/gtest.h"
  16. using namespace llvm;
  17. using namespace clang::tooling;
  18. using clang::tooling::Diagnostic;
  19. static DiagnosticMessage makeMessage(const std::string &Message, int FileOffset,
  20. const std::string &FilePath,
  21. const StringMap<Replacements> &Fix) {
  22. DiagnosticMessage DiagMessage;
  23. DiagMessage.Message = Message;
  24. DiagMessage.FileOffset = FileOffset;
  25. DiagMessage.FilePath = FilePath;
  26. DiagMessage.Fix = Fix;
  27. return DiagMessage;
  28. }
  29. static Diagnostic makeDiagnostic(StringRef DiagnosticName,
  30. const std::string &Message, int FileOffset,
  31. const std::string &FilePath,
  32. const StringMap<Replacements> &Fix) {
  33. return Diagnostic(DiagnosticName,
  34. makeMessage(Message, FileOffset, FilePath, Fix), {},
  35. Diagnostic::Warning, "path/to/build/directory");
  36. }
  37. static const char *YAMLContent =
  38. "---\n"
  39. "MainSourceFile: 'path/to/source.cpp'\n"
  40. "Diagnostics:\n"
  41. " - DiagnosticName: 'diagnostic#1\'\n"
  42. " DiagnosticMessage:\n"
  43. " Message: 'message #1'\n"
  44. " FilePath: 'path/to/source.cpp'\n"
  45. " FileOffset: 55\n"
  46. " Replacements:\n"
  47. " - FilePath: 'path/to/source.cpp'\n"
  48. " Offset: 100\n"
  49. " Length: 12\n"
  50. " ReplacementText: 'replacement #1'\n"
  51. " - DiagnosticName: 'diagnostic#2'\n"
  52. " DiagnosticMessage:\n"
  53. " Message: 'message #2'\n"
  54. " FilePath: 'path/to/header.h'\n"
  55. " FileOffset: 60\n"
  56. " Replacements:\n"
  57. " - FilePath: 'path/to/header.h'\n"
  58. " Offset: 62\n"
  59. " Length: 2\n"
  60. " ReplacementText: 'replacement #2'\n"
  61. " - DiagnosticName: 'diagnostic#3'\n"
  62. " DiagnosticMessage:\n"
  63. " Message: 'message #3'\n"
  64. " FilePath: 'path/to/source2.cpp'\n"
  65. " FileOffset: 72\n"
  66. " Replacements: []\n"
  67. " Notes:\n"
  68. " - Message: Note1\n"
  69. " FilePath: 'path/to/note1.cpp'\n"
  70. " FileOffset: 88\n"
  71. " Replacements: []\n"
  72. " - Message: Note2\n"
  73. " FilePath: 'path/to/note2.cpp'\n"
  74. " FileOffset: 99\n"
  75. " Replacements: []\n"
  76. "...\n";
  77. TEST(DiagnosticsYamlTest, serializesDiagnostics) {
  78. TranslationUnitDiagnostics TUD;
  79. TUD.MainSourceFile = "path/to/source.cpp";
  80. StringMap<Replacements> Fix1 = {
  81. {"path/to/source.cpp",
  82. Replacements({"path/to/source.cpp", 100, 12, "replacement #1"})}};
  83. TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#1", "message #1", 55,
  84. "path/to/source.cpp", Fix1));
  85. StringMap<Replacements> Fix2 = {
  86. {"path/to/header.h",
  87. Replacements({"path/to/header.h", 62, 2, "replacement #2"})}};
  88. TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#2", "message #2", 60,
  89. "path/to/header.h", Fix2));
  90. TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#3", "message #3", 72,
  91. "path/to/source2.cpp", {}));
  92. TUD.Diagnostics.back().Notes.push_back(
  93. makeMessage("Note1", 88, "path/to/note1.cpp", {}));
  94. TUD.Diagnostics.back().Notes.push_back(
  95. makeMessage("Note2", 99, "path/to/note2.cpp", {}));
  96. std::string YamlContent;
  97. raw_string_ostream YamlContentStream(YamlContent);
  98. yaml::Output YAML(YamlContentStream);
  99. YAML << TUD;
  100. EXPECT_EQ(YAMLContent, YamlContentStream.str());
  101. }
  102. TEST(DiagnosticsYamlTest, deserializesDiagnostics) {
  103. TranslationUnitDiagnostics TUDActual;
  104. yaml::Input YAML(YAMLContent);
  105. YAML >> TUDActual;
  106. ASSERT_FALSE(YAML.error());
  107. ASSERT_EQ(3u, TUDActual.Diagnostics.size());
  108. EXPECT_EQ("path/to/source.cpp", TUDActual.MainSourceFile);
  109. auto getFixes = [](const StringMap<Replacements> &Fix) {
  110. std::vector<Replacement> Fixes;
  111. for (auto &Replacements : Fix) {
  112. for (auto &Replacement : Replacements.second) {
  113. Fixes.push_back(Replacement);
  114. }
  115. }
  116. return Fixes;
  117. };
  118. Diagnostic D1 = TUDActual.Diagnostics[0];
  119. EXPECT_EQ("diagnostic#1", D1.DiagnosticName);
  120. EXPECT_EQ("message #1", D1.Message.Message);
  121. EXPECT_EQ(55u, D1.Message.FileOffset);
  122. EXPECT_EQ("path/to/source.cpp", D1.Message.FilePath);
  123. std::vector<Replacement> Fixes1 = getFixes(D1.Message.Fix);
  124. ASSERT_EQ(1u, Fixes1.size());
  125. EXPECT_EQ("path/to/source.cpp", Fixes1[0].getFilePath());
  126. EXPECT_EQ(100u, Fixes1[0].getOffset());
  127. EXPECT_EQ(12u, Fixes1[0].getLength());
  128. EXPECT_EQ("replacement #1", Fixes1[0].getReplacementText());
  129. Diagnostic D2 = TUDActual.Diagnostics[1];
  130. EXPECT_EQ("diagnostic#2", D2.DiagnosticName);
  131. EXPECT_EQ("message #2", D2.Message.Message);
  132. EXPECT_EQ(60u, D2.Message.FileOffset);
  133. EXPECT_EQ("path/to/header.h", D2.Message.FilePath);
  134. std::vector<Replacement> Fixes2 = getFixes(D2.Message.Fix);
  135. ASSERT_EQ(1u, Fixes2.size());
  136. EXPECT_EQ("path/to/header.h", Fixes2[0].getFilePath());
  137. EXPECT_EQ(62u, Fixes2[0].getOffset());
  138. EXPECT_EQ(2u, Fixes2[0].getLength());
  139. EXPECT_EQ("replacement #2", Fixes2[0].getReplacementText());
  140. Diagnostic D3 = TUDActual.Diagnostics[2];
  141. EXPECT_EQ("diagnostic#3", D3.DiagnosticName);
  142. EXPECT_EQ("message #3", D3.Message.Message);
  143. EXPECT_EQ(72u, D3.Message.FileOffset);
  144. EXPECT_EQ("path/to/source2.cpp", D3.Message.FilePath);
  145. EXPECT_EQ(2u, D3.Notes.size());
  146. EXPECT_EQ("Note1", D3.Notes[0].Message);
  147. EXPECT_EQ(88u, D3.Notes[0].FileOffset);
  148. EXPECT_EQ("path/to/note1.cpp", D3.Notes[0].FilePath);
  149. EXPECT_EQ("Note2", D3.Notes[1].Message);
  150. EXPECT_EQ(99u, D3.Notes[1].FileOffset);
  151. EXPECT_EQ("path/to/note2.cpp", D3.Notes[1].FilePath);
  152. std::vector<Replacement> Fixes3 = getFixes(D3.Message.Fix);
  153. EXPECT_TRUE(Fixes3.empty());
  154. }