1 // Copyright 2020 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/diagnostic/formatter.h"
16
17 #include "gtest/gtest.h"
18 #include "src/diagnostic/diagnostic.h"
19
20 namespace tint {
21 namespace diag {
22 namespace {
23
24 constexpr const char* content = // Note: words are tab-delimited
25 R"(the cat says meow
26 the dog says woof
27 the snake says quack
28 the snail says ???
29 )";
30
31 class DiagFormatterTest : public testing::Test {
32 public:
33 Source::File file{"file.name", content};
34 Diagnostic diag_note{Severity::Note,
35 Source{Source::Range{Source::Location{1, 14}}, &file},
36 "purr", System::Test};
37 Diagnostic diag_warn{Severity::Warning,
38 Source{Source::Range{{2, 14}, {2, 18}}, &file}, "grrr",
39 System::Test};
40 Diagnostic diag_err{Severity::Error,
41 Source{Source::Range{{3, 16}, {3, 21}}, &file}, "hiss",
42 System::Test, "abc123"};
43 Diagnostic diag_ice{Severity::InternalCompilerError,
44 Source{Source::Range{{4, 16}, {4, 19}}, &file},
45 "unreachable", System::Test};
46 Diagnostic diag_fatal{Severity::Fatal,
47 Source{Source::Range{{4, 16}, {4, 19}}, &file},
48 "nothing", System::Test};
49 };
50
TEST_F(DiagFormatterTest,Simple)51 TEST_F(DiagFormatterTest, Simple) {
52 Formatter fmt{{false, false, false, false}};
53 auto got = fmt.format(List{diag_note, diag_warn, diag_err});
54 auto* expect = R"(1:14: purr
55 2:14: grrr
56 3:16 abc123: hiss)";
57 ASSERT_EQ(expect, got);
58 }
59
TEST_F(DiagFormatterTest,SimpleNewlineAtEnd)60 TEST_F(DiagFormatterTest, SimpleNewlineAtEnd) {
61 Formatter fmt{{false, false, false, true}};
62 auto got = fmt.format(List{diag_note, diag_warn, diag_err});
63 auto* expect = R"(1:14: purr
64 2:14: grrr
65 3:16 abc123: hiss
66 )";
67 ASSERT_EQ(expect, got);
68 }
69
TEST_F(DiagFormatterTest,SimpleNoSource)70 TEST_F(DiagFormatterTest, SimpleNoSource) {
71 Formatter fmt{{false, false, false, false}};
72 Diagnostic diag{Severity::Note, Source{}, "no source!", System::Test};
73 auto got = fmt.format(List{diag});
74 auto* expect = "no source!";
75 ASSERT_EQ(expect, got);
76 }
77
TEST_F(DiagFormatterTest,WithFile)78 TEST_F(DiagFormatterTest, WithFile) {
79 Formatter fmt{{true, false, false, false}};
80 auto got = fmt.format(List{diag_note, diag_warn, diag_err});
81 auto* expect = R"(file.name:1:14: purr
82 file.name:2:14: grrr
83 file.name:3:16 abc123: hiss)";
84 ASSERT_EQ(expect, got);
85 }
86
TEST_F(DiagFormatterTest,WithSeverity)87 TEST_F(DiagFormatterTest, WithSeverity) {
88 Formatter fmt{{false, true, false, false}};
89 auto got = fmt.format(List{diag_note, diag_warn, diag_err});
90 auto* expect = R"(1:14 note: purr
91 2:14 warning: grrr
92 3:16 error abc123: hiss)";
93 ASSERT_EQ(expect, got);
94 }
95
TEST_F(DiagFormatterTest,WithLine)96 TEST_F(DiagFormatterTest, WithLine) {
97 Formatter fmt{{false, false, true, false}};
98 auto got = fmt.format(List{diag_note, diag_warn, diag_err});
99 auto* expect = R"(1:14: purr
100 the cat says meow
101 ^
102
103 2:14: grrr
104 the dog says woof
105 ^^^^
106
107 3:16 abc123: hiss
108 the snake says quack
109 ^^^^^
110 )";
111 ASSERT_EQ(expect, got);
112 }
113
TEST_F(DiagFormatterTest,BasicWithFileSeverityLine)114 TEST_F(DiagFormatterTest, BasicWithFileSeverityLine) {
115 Formatter fmt{{true, true, true, false}};
116 auto got = fmt.format(List{diag_note, diag_warn, diag_err});
117 auto* expect = R"(file.name:1:14 note: purr
118 the cat says meow
119 ^
120
121 file.name:2:14 warning: grrr
122 the dog says woof
123 ^^^^
124
125 file.name:3:16 error abc123: hiss
126 the snake says quack
127 ^^^^^
128 )";
129 ASSERT_EQ(expect, got);
130 }
131
TEST_F(DiagFormatterTest,BasicWithMultiLine)132 TEST_F(DiagFormatterTest, BasicWithMultiLine) {
133 Diagnostic multiline{Severity::Warning,
134 Source{Source::Range{{2, 9}, {4, 15}}, &file},
135 "multiline", System::Test};
136 Formatter fmt{{false, false, true, false}};
137 auto got = fmt.format(List{multiline});
138 auto* expect = R"(2:9: multiline
139 the dog says woof
140 ^^^^^^^^^^
141 the snake says quack
142 ^^^^^^^^^^^^^^^^^^^^^^^
143 the snail says ???
144 ^^^^^^^^^^^^^^^^
145 )";
146 ASSERT_EQ(expect, got);
147 }
148
TEST_F(DiagFormatterTest,BasicWithFileSeverityLineTab4)149 TEST_F(DiagFormatterTest, BasicWithFileSeverityLineTab4) {
150 Formatter fmt{{true, true, true, false, 4u}};
151 auto got = fmt.format(List{diag_note, diag_warn, diag_err});
152 auto* expect = R"(file.name:1:14 note: purr
153 the cat says meow
154 ^
155
156 file.name:2:14 warning: grrr
157 the dog says woof
158 ^^^^
159
160 file.name:3:16 error abc123: hiss
161 the snake says quack
162 ^^^^^
163 )";
164 ASSERT_EQ(expect, got);
165 }
166
TEST_F(DiagFormatterTest,BasicWithMultiLineTab4)167 TEST_F(DiagFormatterTest, BasicWithMultiLineTab4) {
168 Diagnostic multiline{Severity::Warning,
169 Source{Source::Range{{2, 9}, {4, 15}}, &file},
170 "multiline", System::Test};
171 Formatter fmt{{false, false, true, false, 4u}};
172 auto got = fmt.format(List{multiline});
173 auto* expect = R"(2:9: multiline
174 the dog says woof
175 ^^^^^^^^^^^^
176 the snake says quack
177 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
178 the snail says ???
179 ^^^^^^^^^^^^^^^^^^^^
180 )";
181 ASSERT_EQ(expect, got);
182 }
183
TEST_F(DiagFormatterTest,ICE)184 TEST_F(DiagFormatterTest, ICE) {
185 Formatter fmt{{}};
186 auto got = fmt.format(List{diag_ice});
187 auto* expect = R"(file.name:4:16 internal compiler error: unreachable
188 the snail says ???
189 ^^^
190
191 )";
192 ASSERT_EQ(expect, got);
193 }
194
TEST_F(DiagFormatterTest,Fatal)195 TEST_F(DiagFormatterTest, Fatal) {
196 Formatter fmt{{}};
197 auto got = fmt.format(List{diag_fatal});
198 auto* expect = R"(file.name:4:16 fatal: nothing
199 the snail says ???
200 ^^^
201
202 )";
203 ASSERT_EQ(expect, got);
204 }
205
TEST_F(DiagFormatterTest,RangeOOB)206 TEST_F(DiagFormatterTest, RangeOOB) {
207 Formatter fmt{{true, true, true, true}};
208 diag::List list;
209 list.add_error(System::Test, "oob", Source{{{10, 20}, {30, 20}}, &file});
210 auto got = fmt.format(list);
211 auto* expect = R"(file.name:10:20 error: oob
212
213 )";
214 ASSERT_EQ(expect, got);
215 }
216
217 } // namespace
218 } // namespace diag
219 } // namespace tint
220