Clang Project

clang_source_code/unittests/Tooling/DiagnosticsYamlTest.cpp
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
13#include "clang/Tooling/DiagnosticsYaml.h"
14#include "clang/Tooling/Core/Diagnostic.h"
15#include "clang/Tooling/ReplacementsYaml.h"
16#include "gtest/gtest.h"
17
18using namespace llvm;
19using namespace clang::tooling;
20using clang::tooling::Diagnostic;
21
22static DiagnosticMessage makeMessage(const std::string &Messageint FileOffset,
23                                     const std::string &FilePath) {
24  DiagnosticMessage DiagMessage;
25  DiagMessage.Message = Message;
26  DiagMessage.FileOffset = FileOffset;
27  DiagMessage.FilePath = FilePath;
28  return DiagMessage;
29}
30
31static Diagnostic makeDiagnostic(StringRef DiagnosticName,
32                                 const std::string &Messageint FileOffset,
33                                 const std::string &FilePath,
34                                 const StringMap<Replacements> &Fix) {
35  return Diagnostic(DiagnosticName, makeMessage(Message, FileOffset, FilePath),
36                    Fix, {}, Diagnostic::Warning, "path/to/build/directory");
37}
38
39TEST(DiagnosticsYamlTest, serializesDiagnostics) {
40  TranslationUnitDiagnostics TUD;
41  TUD.MainSourceFile = "path/to/source.cpp";
42
43  StringMap<Replacements> Fix1 = {
44      {"path/to/source.cpp",
45       Replacements({"path/to/source.cpp"10012"replacement #1"})}};
46  TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#1""message #1"55,
47                                           "path/to/source.cpp", Fix1));
48
49  StringMap<Replacements> Fix2 = {
50      {"path/to/header.h",
51       Replacements({"path/to/header.h"622"replacement #2"})}};
52  TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#2""message #2"60,
53                                           "path/to/header.h", Fix2));
54
55  TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#3""message #3"72,
56                                           "path/to/source2.cpp", {}));
57  TUD.Diagnostics.back().Notes.push_back(
58      makeMessage("Note1"88"path/to/note1.cpp"));
59  TUD.Diagnostics.back().Notes.push_back(
60      makeMessage("Note2"99"path/to/note2.cpp"));
61
62  std::string YamlContent;
63  raw_string_ostream YamlContentStream(YamlContent);
64
65  yaml::Output YAML(YamlContentStream);
66  YAML << TUD;
67
68  EXPECT_EQ("---\n"
69            "MainSourceFile:  'path/to/source.cpp'\n"
70            "Diagnostics:     \n"
71            "  - DiagnosticName:  'diagnostic#1\'\n"
72            "    Message:         'message #1'\n"
73            "    FileOffset:      55\n"
74            "    FilePath:        'path/to/source.cpp'\n"
75            "    Replacements:    \n"
76            "      - FilePath:        'path/to/source.cpp'\n"
77            "        Offset:          100\n"
78            "        Length:          12\n"
79            "        ReplacementText: 'replacement #1'\n"
80            "  - DiagnosticName:  'diagnostic#2'\n"
81            "    Message:         'message #2'\n"
82            "    FileOffset:      60\n"
83            "    FilePath:        'path/to/header.h'\n"
84            "    Replacements:    \n"
85            "      - FilePath:        'path/to/header.h'\n"
86            "        Offset:          62\n"
87            "        Length:          2\n"
88            "        ReplacementText: 'replacement #2'\n"
89            "  - DiagnosticName:  'diagnostic#3'\n"
90            "    Message:         'message #3'\n"
91            "    FileOffset:      72\n"
92            "    FilePath:        'path/to/source2.cpp'\n"
93            "    Notes:           \n"
94            "      - Message:         Note1\n"
95            "        FilePath:        'path/to/note1.cpp'\n"
96            "        FileOffset:      88\n"
97            "      - Message:         Note2\n"
98            "        FilePath:        'path/to/note2.cpp'\n"
99            "        FileOffset:      99\n"
100            "    Replacements:    []\n"
101            "...\n",
102            YamlContentStream.str());
103}
104
105TEST(DiagnosticsYamlTest, deserializesDiagnostics) {
106  std::string YamlContent = "---\n"
107                            "MainSourceFile:  path/to/source.cpp\n"
108                            "Diagnostics:     \n"
109                            "  - DiagnosticName:  'diagnostic#1'\n"
110                            "    Message:         'message #1'\n"
111                            "    FileOffset:      55\n"
112                            "    FilePath:        path/to/source.cpp\n"
113                            "    Replacements:    \n"
114                            "      - FilePath:        path/to/source.cpp\n"
115                            "        Offset:          100\n"
116                            "        Length:          12\n"
117                            "        ReplacementText: 'replacement #1'\n"
118                            "  - DiagnosticName:  'diagnostic#2'\n"
119                            "    Message:         'message #2'\n"
120                            "    FileOffset:      60\n"
121                            "    FilePath:        path/to/header.h\n"
122                            "    Replacements:    \n"
123                            "      - FilePath:        path/to/header.h\n"
124                            "        Offset:          62\n"
125                            "        Length:          2\n"
126                            "        ReplacementText: 'replacement #2'\n"
127                            "  - DiagnosticName:  'diagnostic#3'\n"
128                            "    Message:         'message #3'\n"
129                            "    FileOffset:      98\n"
130                            "    FilePath:        path/to/source.cpp\n"
131                            "    Notes:\n"
132                            "      - Message:         Note1\n"
133                            "        FilePath:        'path/to/note1.cpp'\n"
134                            "        FileOffset:      66\n"
135                            "      - Message:         Note2\n"
136                            "        FilePath:        'path/to/note2.cpp'\n"
137                            "        FileOffset:      77\n"
138                            "    Replacements:    []\n"
139                            "...\n";
140  TranslationUnitDiagnostics TUDActual;
141  yaml::Input YAML(YamlContent);
142  YAML >> TUDActual;
143
144  ASSERT_FALSE(YAML.error());
145  ASSERT_EQ(3uTUDActual.Diagnostics.size());
146  EXPECT_EQ("path/to/source.cpp"TUDActual.MainSourceFile);
147
148  auto getFixes = [](const StringMap<Replacements> &Fix) {
149    std::vector<ReplacementFixes;
150    for (auto &Replacements : Fix) {
151      for (auto &Replacement : Replacements.second) {
152        Fixes.push_back(Replacement);
153      }
154    }
155    return Fixes;
156  };
157
158  Diagnostic D1 = TUDActual.Diagnostics[0];
159  EXPECT_EQ("diagnostic#1"D1.DiagnosticName);
160  EXPECT_EQ("message #1"D1.Message.Message);
161  EXPECT_EQ(55uD1.Message.FileOffset);
162  EXPECT_EQ("path/to/source.cpp"D1.Message.FilePath);
163  std::vector<ReplacementFixes1 = getFixes(D1.Fix);
164  ASSERT_EQ(1uFixes1.size());
165  EXPECT_EQ("path/to/source.cpp"Fixes1[0].getFilePath());
166  EXPECT_EQ(100uFixes1[0].getOffset());
167  EXPECT_EQ(12uFixes1[0].getLength());
168  EXPECT_EQ("replacement #1"Fixes1[0].getReplacementText());
169
170  Diagnostic D2 = TUDActual.Diagnostics[1];
171  EXPECT_EQ("diagnostic#2"D2.DiagnosticName);
172  EXPECT_EQ("message #2"D2.Message.Message);
173  EXPECT_EQ(60uD2.Message.FileOffset);
174  EXPECT_EQ("path/to/header.h"D2.Message.FilePath);
175  std::vector<ReplacementFixes2 = getFixes(D2.Fix);
176  ASSERT_EQ(1uFixes2.size());
177  EXPECT_EQ("path/to/header.h"Fixes2[0].getFilePath());
178  EXPECT_EQ(62uFixes2[0].getOffset());
179  EXPECT_EQ(2uFixes2[0].getLength());
180  EXPECT_EQ("replacement #2"Fixes2[0].getReplacementText());
181
182  Diagnostic D3 = TUDActual.Diagnostics[2];
183  EXPECT_EQ("diagnostic#3"D3.DiagnosticName);
184  EXPECT_EQ("message #3"D3.Message.Message);
185  EXPECT_EQ(98uD3.Message.FileOffset);
186  EXPECT_EQ("path/to/source.cpp"D3.Message.FilePath);
187  EXPECT_EQ(2uD3.Notes.size());
188  EXPECT_EQ("Note1"D3.Notes[0].Message);
189  EXPECT_EQ(66uD3.Notes[0].FileOffset);
190  EXPECT_EQ("path/to/note1.cpp"D3.Notes[0].FilePath);
191  EXPECT_EQ("Note2"D3.Notes[1].Message);
192  EXPECT_EQ(77uD3.Notes[1].FileOffset);
193  EXPECT_EQ("path/to/note2.cpp"D3.Notes[1].FilePath);
194  std::vector<ReplacementFixes3 = getFixes(D3.Fix);
195  EXPECT_TRUE(Fixes3.empty());
196}
197