Skip to content

Commit 28f7aea

Browse files
committed
Refactored how tests are printed
Small visual changes to how the tests are shown being ran, reducing noise by removing duplicated qualified paths. At the end of the test run, it prints, on a per-module base, the errors with the file, error message and code block, but Maven still duplicates it at the end.
1 parent 64fe267 commit 28f7aea

File tree

3 files changed

+125
-17
lines changed

3 files changed

+125
-17
lines changed

liquidjava-verifier/src/main/java/liquidjava/api/CommandLineLauncher.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package liquidjava.api;
22

33
import java.io.File;
4+
import java.nio.file.Path;
5+
import java.nio.file.Paths;
46
import java.util.Arrays;
57
import java.util.List;
68

@@ -20,6 +22,7 @@ public class CommandLineLauncher {
2022

2123
private static final Diagnostics diagnostics = Diagnostics.getInstance();
2224
private static final ContextHistory contextHistory = ContextHistory.getInstance();
25+
private static String lastPrintedParent = null;
2326

2427
public static void main(String[] args) {
2528
if (args.length == 0) {
@@ -45,7 +48,19 @@ public static void main(String[] args) {
4548
}
4649

4750
public static void launch(String... paths) {
48-
System.out.println("Running LiquidJava on: " + Arrays.toString(paths).replaceAll("[\\[\\]]", ""));
51+
StringBuilder output = new StringBuilder();
52+
for (String path : paths) {
53+
String currentParent = new File(path).getParent();
54+
if (output.length() > 0)
55+
output.append(System.lineSeparator());
56+
if (!(currentParent != null && currentParent.equals(lastPrintedParent))) {
57+
output.append(Template.LAUNCH_PREFIX).append(toRelativePath(path));
58+
} else {
59+
output.append(Template.LAUNCH_PREFIX_SPACER).append(getNonQualifiedName(path));
60+
}
61+
lastPrintedParent = currentParent;
62+
}
63+
System.out.println(output);
4964

5065
diagnostics.clear();
5166
contextHistory.clearHistory();
@@ -77,4 +92,19 @@ public static void launch(String... paths) {
7792
if (root != null)
7893
processingManager.process(root);
7994
}
95+
96+
private static String getNonQualifiedName(String path) {
97+
String name = new File(path).getName();
98+
return name.isEmpty() ? path : name;
99+
}
100+
101+
private static String toRelativePath(String path) {
102+
try {
103+
Path cwd = Paths.get(".").toAbsolutePath().normalize();
104+
Path target = Paths.get(path).toAbsolutePath().normalize();
105+
return cwd.relativize(target).toString();
106+
} catch (Exception e) {
107+
return path;
108+
}
109+
}
80110
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package liquidjava.api;
2+
3+
public final class Template {
4+
5+
public static final int TEST_MESSAGE_GAP = 5;
6+
public static final String LAUNCH_PREFIX = "Running LiquidJava on: ";
7+
public static final String LAUNCH_PREFIX_SPACER = String.format("%" + LAUNCH_PREFIX.length() + "s", "");
8+
9+
private Template() {
10+
// utility class
11+
}
12+
13+
public static String formatFailureAtRight(String testName, String message) {
14+
String gap = String.format("%" + TEST_MESSAGE_GAP + "s", "");
15+
return LAUNCH_PREFIX_SPACER + testName + gap + message;
16+
}
17+
}

liquidjava-verifier/src/test/java/liquidjava/api/tests/TestExamples.java

Lines changed: 77 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
package liquidjava.api.tests;
22

33
import static liquidjava.utils.TestUtils.*;
4-
import static org.junit.Assert.fail;
54

65
import java.io.IOException;
76
import java.nio.file.Files;
87
import java.nio.file.Path;
98
import java.nio.file.Paths;
109
import java.util.Optional;
10+
import java.util.Set;
11+
import java.util.stream.Collectors;
1112
import java.util.stream.Stream;
13+
14+
import static org.junit.Assert.fail;
15+
1216
import liquidjava.api.CommandLineLauncher;
17+
import liquidjava.api.Template;
1318
import liquidjava.diagnostics.Diagnostics;
1419

1520
import liquidjava.diagnostics.errors.LJError;
21+
1622
import org.junit.Test;
1723
import org.junit.jupiter.params.ParameterizedTest;
1824
import org.junit.jupiter.params.provider.MethodSource;
@@ -39,40 +45,43 @@ public void testPath(final Path path) {
3945

4046
// verification should pass, check if any errors were found
4147
if (shouldPass(pathName) && diagnostics.foundError()) {
42-
System.out.println("Error in: " + pathName + " --- should pass but an error was found");
43-
fail();
48+
LJError error = diagnostics.getErrors().iterator().next();
49+
printFailureAtRight(pathName, "should pass but an error was found");
50+
failCompact(formatShouldPassErrorMessage(pathName, error));
4451
}
4552
// verification should fail, check if it failed as expected (we assume each error test has exactly one error)
4653
else if (shouldFail(pathName)) {
4754
if (!diagnostics.foundError()) {
48-
System.out.println("Error in: " + pathName + " --- should fail but no errors were found");
49-
fail();
55+
printFailureAtRight(pathName, "should fail but no errors were found");
56+
failCompact("Expected an error but none were found");
5057
} else {
5158
// check if expected error was found
5259
Optional<String> expected = isDirectory ? getExpectedErrorFromDirectory(path)
5360
: getExpectedErrorFromFile(path);
5461
if (diagnostics.getErrors().size() > 1) {
55-
System.out.println("Multiple errors found in: " + pathName + " --- expected exactly one error");
56-
fail();
62+
Set<String> errorTitles = diagnostics.getErrors().stream().map(LJError::getTitle)
63+
.collect(Collectors.toSet());
64+
printFailureAtRight(pathName, "expected exactly one error, but found multiple: " + errorTitles);
65+
failCompact(errorTitles.toString());
5766
}
5867
LJError error = diagnostics.getErrors().iterator().next();
5968
if (error.getPosition() == null) {
60-
System.out.println("Error in: " + pathName + " --- error has no position information");
61-
fail();
69+
printFailureAtRight(pathName, "error has no position information");
70+
failCompact("Error has no position information");
6271
}
6372
if (expected.isPresent()) {
6473
String expectedError = expected.get();
6574
String foundError = error.getTitle();
6675
if (!foundError.equalsIgnoreCase(expectedError)) {
67-
System.out.println("Error in: " + pathName + " --- expected error: " + expectedError
68-
+ ", but found: " + foundError);
69-
fail();
76+
printFailureAtRight(pathName,
77+
"expected error: " + expectedError + ", but found: " + foundError);
78+
failCompact("Expected error: " + expectedError + ", but found: " + foundError);
7079
}
7180
} else {
72-
System.out.println("No expected error message found for: " + pathName);
81+
printFailureAtRight(pathName, "no expected error message found");
7382
System.out.println("Please provide an expected error in " + (isDirectory
7483
? "a .expected file in the directory" : "the first line of the test file as a comment"));
75-
fail();
84+
failCompact("No expected error message provided for: " + pathName);
7685
}
7786
}
7887
}
@@ -115,8 +124,60 @@ public void testMultiplePaths() {
115124
CommandLineLauncher.launch(paths);
116125
// Check if any of the paths that should be correct found an error
117126
if (diagnostics.foundError()) {
118-
System.out.println("Error found in files that should be correct");
119-
fail();
127+
printFailureAtRight("testMultiplePaths", "error found in files that should be correct");
128+
fail("Error found in files that should be correct");
129+
}
130+
}
131+
132+
private static void printFailureAtRight(String testName, String message) {
133+
System.out.println(Template.formatFailureAtRight(testName, message));
134+
}
135+
136+
private static void failCompact(String message) {
137+
throw new CompactAssertionError(message);
138+
}
139+
140+
private static String formatShouldPassErrorMessage(String pathName, LJError error) {
141+
String location;
142+
if (error.getPosition() != null) {
143+
location = pathName + ":" + error.getPosition().lineStart() + ":" + error.getPosition().colStart();
144+
} else {
145+
location = pathName;
146+
}
147+
StringBuilder message = new StringBuilder();
148+
message.append("Error found in file that should be correct: ").append(location).append("\n")
149+
.append(error.getTitle()).append(error.getMessage());
150+
151+
String snippet = error.getSnippet();
152+
if (snippet != null && !snippet.isBlank()) {
153+
message.append(System.lineSeparator()).append(System.lineSeparator()).append(snippet);
154+
}
155+
156+
return message.toString();
157+
}
158+
159+
// Keep assertion failures concise by suppressing stack trace population.
160+
private static final class CompactAssertionError extends AssertionError {
161+
private final String compactMessage;
162+
163+
CompactAssertionError(String message) {
164+
super(message);
165+
this.compactMessage = message;
166+
}
167+
168+
@Override
169+
public String getMessage() {
170+
return compactMessage;
171+
}
172+
173+
@Override
174+
public String toString() {
175+
return compactMessage;
176+
}
177+
178+
@Override
179+
public Throwable fillInStackTrace() {
180+
return this;
120181
}
121182
}
122183
}

0 commit comments

Comments
 (0)