1//===-- DiagnosticManagerTest.cpp -----------------------------------------===//
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#include "lldb/Expression/DiagnosticManager.h"
10#include "gtest/gtest.h"
11
12using namespace lldb_private;
13
14static const uint32_t custom_diag_id = 42;
15
16namespace {
17class FixItDiag : public Diagnostic {
18 bool m_has_fixits;
19
20public:
21 FixItDiag(llvm::StringRef msg, bool has_fixits)
22 : Diagnostic(DiagnosticOrigin::eDiagnosticOriginLLDB, custom_diag_id,
23 DiagnosticDetail{.source_location: {}, .severity: lldb::eSeverityError, .message: msg.str(), .rendered: {}}),
24 m_has_fixits(has_fixits) {}
25 bool HasFixIts() const override { return m_has_fixits; }
26};
27} // namespace
28
29namespace {
30class TextDiag : public Diagnostic {
31public:
32 TextDiag(llvm::StringRef msg, lldb::Severity severity)
33 : Diagnostic(DiagnosticOrigin::eDiagnosticOriginLLDB, custom_diag_id,
34 DiagnosticDetail{.source_location: {}, .severity: severity, .message: msg.str(), .rendered: msg.str()}) {}
35};
36} // namespace
37
38TEST(DiagnosticManagerTest, AddDiagnostic) {
39 DiagnosticManager mgr;
40 EXPECT_EQ(0U, mgr.Diagnostics().size());
41
42 std::string msg = "foo bar has happened";
43 lldb::Severity severity = lldb::eSeverityError;
44 DiagnosticOrigin origin = DiagnosticOrigin::eDiagnosticOriginLLDB;
45 auto diag = std::make_unique<Diagnostic>(
46 args&: origin, args: custom_diag_id, args: DiagnosticDetail{.source_location: {}, .severity: severity, .message: msg, .rendered: {}});
47 mgr.AddDiagnostic(diagnostic: std::move(diag));
48 EXPECT_EQ(1U, mgr.Diagnostics().size());
49 const Diagnostic *got = mgr.Diagnostics().front().get();
50 EXPECT_EQ(DiagnosticOrigin::eDiagnosticOriginLLDB, got->getKind());
51 EXPECT_EQ(msg, got->GetMessage());
52 EXPECT_EQ(severity, got->GetSeverity());
53 EXPECT_EQ(custom_diag_id, got->GetCompilerID());
54 EXPECT_EQ(false, got->HasFixIts());
55}
56
57TEST(DiagnosticManagerTest, HasFixits) {
58 DiagnosticManager mgr;
59 // By default we shouldn't have any fixits.
60 EXPECT_FALSE(mgr.HasFixIts());
61 // Adding a diag without fixits shouldn't make HasFixIts return true.
62 mgr.AddDiagnostic(diagnostic: std::make_unique<FixItDiag>(args: "no fixit", args: false));
63 EXPECT_FALSE(mgr.HasFixIts());
64 // Adding a diag with fixits will mark the manager as containing fixits.
65 mgr.AddDiagnostic(diagnostic: std::make_unique<FixItDiag>(args: "fixit", args: true));
66 EXPECT_TRUE(mgr.HasFixIts());
67 // Adding another diag without fixit shouldn't make it return false.
68 mgr.AddDiagnostic(diagnostic: std::make_unique<FixItDiag>(args: "no fixit", args: false));
69 EXPECT_TRUE(mgr.HasFixIts());
70 // Adding a diag with fixits. The manager should still return true.
71 mgr.AddDiagnostic(diagnostic: std::make_unique<FixItDiag>(args: "fixit", args: true));
72 EXPECT_TRUE(mgr.HasFixIts());
73}
74
75static std::string toString(DiagnosticManager &mgr) {
76 // The error code doesn't really matter since we just convert the
77 // diagnostics to a string.
78 auto result = lldb::eExpressionCompleted;
79 return llvm::toString(E: mgr.GetAsError(result));
80}
81
82TEST(DiagnosticManagerTest, GetStringNoDiags) {
83 DiagnosticManager mgr;
84 EXPECT_EQ("", toString(mgr));
85 std::unique_ptr<Diagnostic> empty;
86 mgr.AddDiagnostic(diagnostic: std::move(empty));
87 EXPECT_EQ("", toString(mgr));
88}
89
90TEST(DiagnosticManagerTest, GetStringBasic) {
91 DiagnosticManager mgr;
92 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "abc", args: lldb::eSeverityError));
93 EXPECT_EQ("error: abc\n", toString(mgr));
94}
95
96TEST(DiagnosticManagerTest, GetStringMultiline) {
97 DiagnosticManager mgr;
98
99 // Multiline diagnostics should only get one severity label.
100 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "b\nc", args: lldb::eSeverityError));
101 EXPECT_EQ("error: b\nc\n", toString(mgr));
102}
103
104TEST(DiagnosticManagerTest, GetStringMultipleDiags) {
105 DiagnosticManager mgr;
106 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "abc", args: lldb::eSeverityError));
107 EXPECT_EQ("error: abc\n", toString(mgr));
108 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "def", args: lldb::eSeverityError));
109 EXPECT_EQ("error: abc\nerror: def\n", toString(mgr));
110}
111
112TEST(DiagnosticManagerTest, GetStringSeverityLabels) {
113 DiagnosticManager mgr;
114
115 // Different severities should cause different labels.
116 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "foo", args: lldb::eSeverityError));
117 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "bar", args: lldb::eSeverityWarning));
118 // Remarks have no labels.
119 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "baz", args: lldb::eSeverityInfo));
120 EXPECT_EQ("error: foo\nwarning: bar\nbaz\n", toString(mgr));
121}
122
123TEST(DiagnosticManagerTest, GetStringPreserveOrder) {
124 DiagnosticManager mgr;
125
126 // Make sure we preserve the diagnostic order and do not sort them in any way.
127 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "baz", args: lldb::eSeverityInfo));
128 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "bar", args: lldb::eSeverityWarning));
129 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "foo", args: lldb::eSeverityError));
130 EXPECT_EQ("baz\nwarning: bar\nerror: foo\n", toString(mgr));
131}
132
133TEST(DiagnosticManagerTest, AppendMessageNoDiag) {
134 DiagnosticManager mgr;
135
136 // FIXME: This *really* should not just fail silently.
137 mgr.AppendMessageToDiagnostic(str: "no diag has been pushed yet");
138 EXPECT_EQ(0U, mgr.Diagnostics().size());
139}
140
141TEST(DiagnosticManagerTest, AppendMessageAttachToLastDiag) {
142 DiagnosticManager mgr;
143
144 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "foo", args: lldb::eSeverityError));
145 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "bar", args: lldb::eSeverityError));
146 // This should append to 'bar' and not to 'foo'.
147 mgr.AppendMessageToDiagnostic(str: "message text");
148
149 EXPECT_EQ("error: foo\nerror: bar\nmessage text\n", toString(mgr));
150}
151
152TEST(DiagnosticManagerTest, AppendMessageSubsequentDiags) {
153 DiagnosticManager mgr;
154
155 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "bar", args: lldb::eSeverityError));
156 mgr.AppendMessageToDiagnostic(str: "message text");
157 // Pushing another diag after the message should work fine.
158 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "foo", args: lldb::eSeverityError));
159
160 EXPECT_EQ("error: bar\nmessage text\nerror: foo\n", toString(mgr));
161}
162
163TEST(DiagnosticManagerTest, PutString) {
164 DiagnosticManager mgr;
165
166 mgr.PutString(severity: lldb::eSeverityError, str: "foo");
167 EXPECT_EQ(1U, mgr.Diagnostics().size());
168 EXPECT_EQ(eDiagnosticOriginLLDB, mgr.Diagnostics().front()->getKind());
169 EXPECT_EQ("error: foo\n", toString(mgr));
170}
171
172TEST(DiagnosticManagerTest, PutStringMultiple) {
173 DiagnosticManager mgr;
174
175 // Multiple PutString should behave like multiple diagnostics.
176 mgr.PutString(severity: lldb::eSeverityError, str: "foo");
177 mgr.PutString(severity: lldb::eSeverityError, str: "bar");
178 EXPECT_EQ(2U, mgr.Diagnostics().size());
179 EXPECT_EQ("error: foo\nerror: bar\n", toString(mgr));
180}
181
182TEST(DiagnosticManagerTest, PutStringSeverities) {
183 DiagnosticManager mgr;
184
185 // Multiple PutString with different severities should behave like we
186 // created multiple diagnostics.
187 mgr.PutString(severity: lldb::eSeverityError, str: "foo");
188 mgr.PutString(severity: lldb::eSeverityWarning, str: "bar");
189 EXPECT_EQ(2U, mgr.Diagnostics().size());
190 EXPECT_EQ("error: foo\nwarning: bar\n", toString(mgr));
191}
192
193TEST(DiagnosticManagerTest, FixedExpression) {
194 DiagnosticManager mgr;
195
196 // By default there should be no fixed expression.
197 EXPECT_EQ("", mgr.GetFixedExpression());
198
199 // Setting the fixed expression should change it.
200 mgr.SetFixedExpression("foo");
201 EXPECT_EQ("foo", mgr.GetFixedExpression());
202
203 // Setting the fixed expression again should also change it.
204 mgr.SetFixedExpression("bar");
205 EXPECT_EQ("bar", mgr.GetFixedExpression());
206}
207
208TEST(DiagnosticManagerTest, StatusConversion) {
209 DiagnosticManager mgr;
210 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "abc", args: lldb::eSeverityError));
211 mgr.AddDiagnostic(diagnostic: std::make_unique<TextDiag>(args: "def", args: lldb::eSeverityWarning));
212 Status status =
213 Status::FromError(error: mgr.GetAsError(result: lldb::eExpressionParseError));
214 EXPECT_EQ(std::string("error: abc\nwarning: def\n"),
215 std::string(status.AsCString()));
216}
217

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of lldb/unittests/Expression/DiagnosticManagerTest.cpp