xref: /llvm-project/lldb/unittests/Utility/DiagnosticsRenderingTest.cpp (revision 6b4f67545d87d5305cbbc20a678fb97ede995579)
1089227feSAdrian Prantl #include "lldb/Utility/DiagnosticsRendering.h"
2089227feSAdrian Prantl #include "lldb/Utility/StreamString.h"
3089227feSAdrian Prantl #include "gtest/gtest.h"
4089227feSAdrian Prantl 
5089227feSAdrian Prantl using namespace lldb_private;
6089227feSAdrian Prantl using namespace lldb;
7089227feSAdrian Prantl using llvm::StringRef;
8089227feSAdrian Prantl namespace {
9089227feSAdrian Prantl class ErrorDisplayTest : public ::testing::Test {};
10089227feSAdrian Prantl 
11089227feSAdrian Prantl std::string Render(std::vector<DiagnosticDetail> details) {
12089227feSAdrian Prantl   StreamString stream;
13089227feSAdrian Prantl   RenderDiagnosticDetails(stream, 0, true, details);
14089227feSAdrian Prantl   return stream.GetData();
15089227feSAdrian Prantl }
16089227feSAdrian Prantl } // namespace
17089227feSAdrian Prantl 
18089227feSAdrian Prantl TEST_F(ErrorDisplayTest, RenderStatus) {
19889e6ad2SAdrian Prantl   using SourceLocation = DiagnosticDetail::SourceLocation;
20089227feSAdrian Prantl   {
21889e6ad2SAdrian Prantl     SourceLocation inline_loc;
22889e6ad2SAdrian Prantl     inline_loc.in_user_input = true;
23089227feSAdrian Prantl     std::string result =
24089227feSAdrian Prantl         Render({DiagnosticDetail{inline_loc, eSeverityError, "foo", ""}});
25089227feSAdrian Prantl     ASSERT_TRUE(StringRef(result).contains("error:"));
26089227feSAdrian Prantl     ASSERT_TRUE(StringRef(result).contains("foo"));
27089227feSAdrian Prantl   }
28889e6ad2SAdrian Prantl 
29889e6ad2SAdrian Prantl   {
30889e6ad2SAdrian Prantl     // Test that diagnostics on the same column can be handled and all
31889e6ad2SAdrian Prantl     // three errors are diagnosed.
32*6b4f6754SAdrian Prantl     SourceLocation loc1 = {FileSpec{"a.c"}, 13, 5, 0, false, true};
33*6b4f6754SAdrian Prantl     SourceLocation loc2 = {FileSpec{"a.c"}, 13, 7, 0, false, true};
34*6b4f6754SAdrian Prantl     SourceLocation loc3 = {FileSpec{"a.c"}, 13, 9, 0, false, true};
35889e6ad2SAdrian Prantl     std::string result =
36889e6ad2SAdrian Prantl         Render({DiagnosticDetail{loc1, eSeverityError, "1", "1"},
37*6b4f6754SAdrian Prantl                 DiagnosticDetail{loc2, eSeverityError, "2a", "2a"},
38*6b4f6754SAdrian Prantl                 DiagnosticDetail{loc2, eSeverityInfo, "2b", "2b"},
39*6b4f6754SAdrian Prantl                 DiagnosticDetail{loc3, eSeverityError, "3", "3"}});
40*6b4f6754SAdrian Prantl     llvm::SmallVector<StringRef> lines;
41*6b4f6754SAdrian Prantl     StringRef(result).split(lines, '\n');
42*6b4f6754SAdrian Prantl     //                1234567890123
43*6b4f6754SAdrian Prantl     ASSERT_EQ(lines[0], "    ^ ^ ^");
44*6b4f6754SAdrian Prantl     ASSERT_EQ(lines[1], "    | | error: 3");
45*6b4f6754SAdrian Prantl     ASSERT_EQ(lines[2], "    | error: 2a");
46*6b4f6754SAdrian Prantl     ASSERT_EQ(lines[3], "    | note: 2b");
47*6b4f6754SAdrian Prantl     ASSERT_EQ(lines[4], "    error: 1");
48889e6ad2SAdrian Prantl   }
49889e6ad2SAdrian Prantl   {
50889e6ad2SAdrian Prantl     // Test that diagnostics in reverse order are emitted correctly.
51889e6ad2SAdrian Prantl     SourceLocation loc1 = {FileSpec{"a.c"}, 1, 20, 0, false, true};
52889e6ad2SAdrian Prantl     SourceLocation loc2 = {FileSpec{"a.c"}, 2, 10, 0, false, true};
53889e6ad2SAdrian Prantl     std::string result =
54889e6ad2SAdrian Prantl         Render({DiagnosticDetail{loc2, eSeverityError, "X", "X"},
55889e6ad2SAdrian Prantl                 DiagnosticDetail{loc1, eSeverityError, "Y", "Y"}});
5674e1554dSAdrian Prantl     // Unintuitively the later diagnostic appears first in the string:
5774e1554dSAdrian Prantl     //    ^   ^
5874e1554dSAdrian Prantl     //    |   second
5974e1554dSAdrian Prantl     //    first
6074e1554dSAdrian Prantl     ASSERT_GT(StringRef(result).find("Y"), StringRef(result).find("X"));
61889e6ad2SAdrian Prantl   }
62889e6ad2SAdrian Prantl   {
63889e6ad2SAdrian Prantl     // Test that diagnostics in reverse order are emitted correctly.
6474e1554dSAdrian Prantl     SourceLocation loc1 = {FileSpec{"a.c"}, 1, 10, 0, false, true};
65889e6ad2SAdrian Prantl     SourceLocation loc2 = {FileSpec{"a.c"}, 1, 20, 0, false, true};
66889e6ad2SAdrian Prantl     std::string result =
67889e6ad2SAdrian Prantl         Render({DiagnosticDetail{loc2, eSeverityError, "X", "X"},
68889e6ad2SAdrian Prantl                 DiagnosticDetail{loc1, eSeverityError, "Y", "Y"}});
6974e1554dSAdrian Prantl     ASSERT_GT(StringRef(result).find("Y"), StringRef(result).find("X"));
70889e6ad2SAdrian Prantl   }
718046f15dSAdrian Prantl   {
728046f15dSAdrian Prantl     // Test that range diagnostics are emitted correctly.
738046f15dSAdrian Prantl     SourceLocation loc1 = {FileSpec{"a.c"}, 1, 1, 3, false, true};
748046f15dSAdrian Prantl     SourceLocation loc2 = {FileSpec{"a.c"}, 1, 5, 3, false, true};
758046f15dSAdrian Prantl     std::string result =
768046f15dSAdrian Prantl         Render({DiagnosticDetail{loc1, eSeverityError, "X", "X"},
778046f15dSAdrian Prantl                 DiagnosticDetail{loc2, eSeverityError, "Y", "Y"}});
78*6b4f6754SAdrian Prantl     llvm::SmallVector<StringRef> lines;
79*6b4f6754SAdrian Prantl     StringRef(result).split(lines, '\n');
808046f15dSAdrian Prantl     //                1234567
81*6b4f6754SAdrian Prantl     ASSERT_EQ(lines[0], "^~~ ^~~");
82*6b4f6754SAdrian Prantl     ASSERT_EQ(lines[1], "|   error: Y");
83*6b4f6754SAdrian Prantl     ASSERT_EQ(lines[2], "error: X");
848b2dff96SAdrian Prantl   }
858b2dff96SAdrian Prantl   {
868b2dff96SAdrian Prantl     // Test diagnostics on the same line are emitted correctly.
878b2dff96SAdrian Prantl     SourceLocation loc1 = {FileSpec{"a.c"}, 1, 2, 0, false, true};
888b2dff96SAdrian Prantl     SourceLocation loc2 = {FileSpec{"a.c"}, 1, 6, 0, false, true};
898b2dff96SAdrian Prantl     std::string result =
908b2dff96SAdrian Prantl         Render({DiagnosticDetail{loc1, eSeverityError, "X", "X"},
918b2dff96SAdrian Prantl                 DiagnosticDetail{loc2, eSeverityError, "Y", "Y"}});
92*6b4f6754SAdrian Prantl     llvm::SmallVector<StringRef> lines;
93*6b4f6754SAdrian Prantl     StringRef(result).split(lines, '\n');
948b2dff96SAdrian Prantl     //                1234567
95*6b4f6754SAdrian Prantl     ASSERT_EQ(lines[0], " ^   ^");
96*6b4f6754SAdrian Prantl     ASSERT_EQ(lines[1], " |   error: Y");
97*6b4f6754SAdrian Prantl     ASSERT_EQ(lines[2], " error: X");
988046f15dSAdrian Prantl   }
99089227feSAdrian Prantl }
100