xref: /llvm-project/lldb/unittests/Utility/DiagnosticsRenderingTest.cpp (revision 6b4f67545d87d5305cbbc20a678fb97ede995579)
1 #include "lldb/Utility/DiagnosticsRendering.h"
2 #include "lldb/Utility/StreamString.h"
3 #include "gtest/gtest.h"
4 
5 using namespace lldb_private;
6 using namespace lldb;
7 using llvm::StringRef;
8 namespace {
9 class ErrorDisplayTest : public ::testing::Test {};
10 
11 std::string Render(std::vector<DiagnosticDetail> details) {
12   StreamString stream;
13   RenderDiagnosticDetails(stream, 0, true, details);
14   return stream.GetData();
15 }
16 } // namespace
17 
18 TEST_F(ErrorDisplayTest, RenderStatus) {
19   using SourceLocation = DiagnosticDetail::SourceLocation;
20   {
21     SourceLocation inline_loc;
22     inline_loc.in_user_input = true;
23     std::string result =
24         Render({DiagnosticDetail{inline_loc, eSeverityError, "foo", ""}});
25     ASSERT_TRUE(StringRef(result).contains("error:"));
26     ASSERT_TRUE(StringRef(result).contains("foo"));
27   }
28 
29   {
30     // Test that diagnostics on the same column can be handled and all
31     // three errors are diagnosed.
32     SourceLocation loc1 = {FileSpec{"a.c"}, 13, 5, 0, false, true};
33     SourceLocation loc2 = {FileSpec{"a.c"}, 13, 7, 0, false, true};
34     SourceLocation loc3 = {FileSpec{"a.c"}, 13, 9, 0, false, true};
35     std::string result =
36         Render({DiagnosticDetail{loc1, eSeverityError, "1", "1"},
37                 DiagnosticDetail{loc2, eSeverityError, "2a", "2a"},
38                 DiagnosticDetail{loc2, eSeverityInfo, "2b", "2b"},
39                 DiagnosticDetail{loc3, eSeverityError, "3", "3"}});
40     llvm::SmallVector<StringRef> lines;
41     StringRef(result).split(lines, '\n');
42     //                1234567890123
43     ASSERT_EQ(lines[0], "    ^ ^ ^");
44     ASSERT_EQ(lines[1], "    | | error: 3");
45     ASSERT_EQ(lines[2], "    | error: 2a");
46     ASSERT_EQ(lines[3], "    | note: 2b");
47     ASSERT_EQ(lines[4], "    error: 1");
48   }
49   {
50     // Test that diagnostics in reverse order are emitted correctly.
51     SourceLocation loc1 = {FileSpec{"a.c"}, 1, 20, 0, false, true};
52     SourceLocation loc2 = {FileSpec{"a.c"}, 2, 10, 0, false, true};
53     std::string result =
54         Render({DiagnosticDetail{loc2, eSeverityError, "X", "X"},
55                 DiagnosticDetail{loc1, eSeverityError, "Y", "Y"}});
56     // Unintuitively the later diagnostic appears first in the string:
57     //    ^   ^
58     //    |   second
59     //    first
60     ASSERT_GT(StringRef(result).find("Y"), StringRef(result).find("X"));
61   }
62   {
63     // Test that diagnostics in reverse order are emitted correctly.
64     SourceLocation loc1 = {FileSpec{"a.c"}, 1, 10, 0, false, true};
65     SourceLocation loc2 = {FileSpec{"a.c"}, 1, 20, 0, false, true};
66     std::string result =
67         Render({DiagnosticDetail{loc2, eSeverityError, "X", "X"},
68                 DiagnosticDetail{loc1, eSeverityError, "Y", "Y"}});
69     ASSERT_GT(StringRef(result).find("Y"), StringRef(result).find("X"));
70   }
71   {
72     // Test that range diagnostics are emitted correctly.
73     SourceLocation loc1 = {FileSpec{"a.c"}, 1, 1, 3, false, true};
74     SourceLocation loc2 = {FileSpec{"a.c"}, 1, 5, 3, false, true};
75     std::string result =
76         Render({DiagnosticDetail{loc1, eSeverityError, "X", "X"},
77                 DiagnosticDetail{loc2, eSeverityError, "Y", "Y"}});
78     llvm::SmallVector<StringRef> lines;
79     StringRef(result).split(lines, '\n');
80     //                1234567
81     ASSERT_EQ(lines[0], "^~~ ^~~");
82     ASSERT_EQ(lines[1], "|   error: Y");
83     ASSERT_EQ(lines[2], "error: X");
84   }
85   {
86     // Test diagnostics on the same line are emitted correctly.
87     SourceLocation loc1 = {FileSpec{"a.c"}, 1, 2, 0, false, true};
88     SourceLocation loc2 = {FileSpec{"a.c"}, 1, 6, 0, false, true};
89     std::string result =
90         Render({DiagnosticDetail{loc1, eSeverityError, "X", "X"},
91                 DiagnosticDetail{loc2, eSeverityError, "Y", "Y"}});
92     llvm::SmallVector<StringRef> lines;
93     StringRef(result).split(lines, '\n');
94     //                1234567
95     ASSERT_EQ(lines[0], " ^   ^");
96     ASSERT_EQ(lines[1], " |   error: Y");
97     ASSERT_EQ(lines[2], " error: X");
98   }
99 }
100