1
2
3
4
5
6
7 package net.alchim31.maven.yuicompressor;
8
9 import java.nio.file.Path;
10
11 import org.apache.maven.plugin.logging.Log;
12 import org.codehaus.plexus.build.BuildContext;
13 import org.junit.jupiter.api.Assertions;
14 import org.junit.jupiter.api.Test;
15 import org.junit.jupiter.api.extension.ExtendWith;
16 import org.mockito.ArgumentCaptor;
17 import org.mockito.Mock;
18 import org.mockito.Mockito;
19 import org.mockito.junit.jupiter.MockitoExtension;
20 import org.mozilla.javascript.EvaluatorException;
21
22
23
24
25 @ExtendWith(MockitoExtension.class)
26 class ErrorReporter4MojoTest {
27
28
29 @Mock
30 private Log log;
31
32
33 @Mock
34 private BuildContext buildContext;
35
36
37
38
39
40
41 @Test
42 void testError_incrementsErrorCount() {
43 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
44 reporter.error("msg", "src.js", 1, "lineSource", 0);
45 Assertions.assertEquals(1, reporter.getErrorCnt());
46 }
47
48
49
50
51 @Test
52 void testError_logsToMavenLog() {
53 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
54 reporter.error("msg", "src.js", 2, "lineSource", 5);
55 Mockito.verify(log).error(Mockito.anyString());
56 }
57
58
59
60
61 @Test
62 void testError_addsBuildContextMessage() {
63 final var file = Path.of("src.js").toFile();
64 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
65 reporter.setFile(file);
66 reporter.error("msg", "src.js", 3, "lineSource", 1);
67 Mockito.verify(buildContext).addMessage(file, 3, 1, "msg", BuildContext.SEVERITY_ERROR, null);
68 }
69
70
71
72
73 @Test
74 void testError_multipleCallsAccumulateCount() {
75 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
76 reporter.error("e1", null, 1, null, 0);
77 reporter.error("e2", null, 2, null, 0);
78 reporter.error("e3", null, 3, null, 0);
79 Assertions.assertEquals(3, reporter.getErrorCnt());
80 }
81
82
83
84
85
86
87 @Test
88 void testWarning_whenAcceptWarnTrue_incrementsWarningCount() {
89 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
90 reporter.warning("warn", "src.js", 1, "lineSource", 0);
91 Assertions.assertEquals(1, reporter.getWarningCnt());
92 }
93
94
95
96
97 @Test
98 void testWarning_whenAcceptWarnTrue_logsWarning() {
99 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
100 reporter.warning("warn", "src.js", 1, "lineSource", 0);
101 Mockito.verify(log).warn(Mockito.anyString());
102 }
103
104
105
106
107 @Test
108 void testWarning_whenAcceptWarnTrue_addsBuildContextMessage() {
109 final var file = Path.of("src.js").toFile();
110 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
111 reporter.setFile(file);
112 reporter.warning("warn", "src.js", 7, "lineSource", 2);
113 Mockito.verify(buildContext).addMessage(file, 7, 2, "warn", BuildContext.SEVERITY_WARNING, null);
114 }
115
116
117
118
119 @Test
120 void testWarning_whenAcceptWarnFalse_doesNotIncrementCount() {
121 final var reporter = new ErrorReporter4Mojo(log, false, buildContext);
122 reporter.warning("warn", "src.js", 1, "lineSource", 0);
123 Assertions.assertEquals(0, reporter.getWarningCnt());
124 }
125
126
127
128
129 @Test
130 void testWarning_whenAcceptWarnFalse_doesNotLog() {
131 final var reporter = new ErrorReporter4Mojo(log, false, buildContext);
132 reporter.warning("warn", "src.js", 1, "lineSource", 0);
133 Mockito.verify(log, Mockito.never()).warn(Mockito.anyString());
134 }
135
136
137
138
139 @Test
140 void testWarning_whenAcceptWarnFalse_doesNotNotifyBuildContext() {
141 final var reporter = new ErrorReporter4Mojo(log, false, buildContext);
142 reporter.warning("warn", "src.js", 1, "lineSource", 0);
143 Mockito.verify(buildContext, Mockito.never()).addMessage(Mockito.any(), Mockito.anyInt(), Mockito.anyInt(),
144 Mockito.anyString(), Mockito.anyInt(), Mockito.any());
145 }
146
147
148
149
150
151
152 @Test
153 void testRuntimeError_throwsEvaluatorException() {
154 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
155 Assertions.assertThrows(EvaluatorException.class,
156 () -> reporter.runtimeError("runtime", "src.js", 1, "lineSource", 0));
157 }
158
159
160
161
162 @Test
163 void testRuntimeError_incrementsErrorCount() {
164 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
165 try {
166 reporter.runtimeError("runtime", "src.js", 1, "lineSource", 0);
167 } catch (EvaluatorException ignored) {
168
169 }
170 Assertions.assertEquals(1, reporter.getErrorCnt());
171 }
172
173
174
175
176
177
178 @Test
179 void testSetDefaultFileName_nonEmpty_usedInMessage() {
180 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
181 reporter.setDefaultFileName("myFile.js");
182
183 final var captor = ArgumentCaptor.forClass(String.class);
184 reporter.error("oops", null, 1, null, 0);
185 Mockito.verify(log).error(captor.capture());
186 Assertions.assertTrue(captor.getValue().contains("myFile.js"),
187 "Expected default filename to appear in the error message");
188 }
189
190
191
192
193 @Test
194 void testSetDefaultFileName_empty_clearsDefaultName() {
195 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
196 reporter.setDefaultFileName("myFile.js");
197 reporter.setDefaultFileName("");
198 final var captor = ArgumentCaptor.forClass(String.class);
199 reporter.error("oops", null, 1, null, 0);
200 Mockito.verify(log).error(captor.capture());
201
202 Assertions.assertFalse(captor.getValue().contains("myFile.js"),
203 "Expected cleared filename to not appear in the error message");
204 }
205
206
207
208
209
210
211 @Test
212 void testMessageFormat_includesSourceLineColumn() {
213 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
214 final var captor = ArgumentCaptor.forClass(String.class);
215 reporter.error("bad syntax", "app.js", 10, "var x =", 4);
216 Mockito.verify(log).error(captor.capture());
217 final var msg = captor.getValue();
218 Assertions.assertTrue(msg.contains("app.js"), "Expected source name in message");
219 Assertions.assertTrue(msg.contains("10"), "Expected line number in message");
220 Assertions.assertTrue(msg.contains("4"), "Expected column offset in message");
221 Assertions.assertTrue(msg.contains("bad syntax"), "Expected error text in message");
222 }
223
224
225
226
227 @Test
228 void testMessageFormat_includesLineSource() {
229 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
230 final var captor = ArgumentCaptor.forClass(String.class);
231 reporter.error("msg", "a.js", 1, "var x = $bad;", 0);
232 Mockito.verify(log).error(captor.capture());
233 Assertions.assertTrue(captor.getValue().contains("var x = $bad;"),
234 "Expected lineSource to be appended to message");
235 }
236
237
238
239
240 @Test
241 void testMessageFormat_nullMessage_showsUnknownError() {
242 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
243 final var captor = ArgumentCaptor.forClass(String.class);
244 reporter.error(null, "a.js", 1, null, 0);
245 Mockito.verify(log).error(captor.capture());
246 Assertions.assertTrue(captor.getValue().contains("unknown error"),
247 "Expected 'unknown error' placeholder for null message");
248 }
249
250
251
252
253 @Test
254 void testMessageFormat_nullSourceName_usesDefaultFilename() {
255 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
256 reporter.setDefaultFileName("fallback.js");
257 final var captor = ArgumentCaptor.forClass(String.class);
258 reporter.error("err", null, 5, null, 0);
259 Mockito.verify(log).error(captor.capture());
260 Assertions.assertTrue(captor.getValue().contains("fallback.js"),
261 "Expected default filename to be used when sourceName is null");
262 }
263
264
265
266
267 @Test
268 void testMessageFormat_noSourceAtAll_onlyMessageText() {
269 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
270 final var captor = ArgumentCaptor.forClass(String.class);
271 reporter.error("just the error", null, 1, null, 0);
272 Mockito.verify(log).error(captor.capture());
273
274 Assertions.assertFalse(captor.getValue().contains("null"),
275 "Message should not contain the literal string 'null'");
276 Assertions.assertTrue(captor.getValue().contains("just the error"), "Expected the error text to be present");
277 }
278
279
280
281
282
283
284 @Test
285 void testSetFile_updatesSourceFileForBuildContext() {
286 final var file1 = Path.of("first.js").toFile();
287 final var file2 = Path.of("second.js").toFile();
288 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
289
290 reporter.setFile(file1);
291 reporter.error("e", null, 1, null, 0);
292 Mockito.verify(buildContext).addMessage(Mockito.eq(file1), Mockito.anyInt(), Mockito.anyInt(),
293 Mockito.anyString(), Mockito.anyInt(), Mockito.isNull());
294
295 reporter.setFile(file2);
296 reporter.error("e", null, 2, null, 0);
297 Mockito.verify(buildContext).addMessage(Mockito.eq(file2), Mockito.anyInt(), Mockito.anyInt(),
298 Mockito.anyString(), Mockito.anyInt(), Mockito.isNull());
299 }
300
301
302
303
304
305
306 @Test
307 void testInitialCountersAreZero() {
308 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
309 Assertions.assertEquals(0, reporter.getErrorCnt());
310 Assertions.assertEquals(0, reporter.getWarningCnt());
311 }
312
313
314
315
316 @Test
317 void testErrorAndWarningCountersAreIndependent() {
318 final var reporter = new ErrorReporter4Mojo(log, true, buildContext);
319 reporter.error("e", null, 1, null, 0);
320 reporter.warning("w", null, 2, null, 0);
321 Assertions.assertEquals(1, reporter.getErrorCnt());
322 Assertions.assertEquals(1, reporter.getWarningCnt());
323 }
324 }