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