Add test snapshot utility

This commit is contained in:
2025-03-29 00:33:44 +03:00
parent bb5b00da11
commit 1116758902
5 changed files with 63 additions and 21 deletions

View File

@@ -63,7 +63,7 @@ public class Build {
case "test":
buildJtags(mainClass, sourcePaths, classPaths);
runTests();
runTests(arguments.toArray(String[]::new));
break;
default:
@@ -96,7 +96,7 @@ public class Build {
".");
}
static void runTests() {
static void runTests(String[] args) {
String mainClass = "TestJtags";
String[] sourcePaths = glob("src/test/java/**.java");
@@ -107,6 +107,6 @@ public class Build {
}
}
System.exit(runJava(new String[0], new String[] {"-enableassertions"}, mainClass));
System.exit(runJava(new String[0], new String[] {"-enableassertions"}, mainClass, args));
}
}

View File

@@ -33,7 +33,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ProcessBuilder.Redirect;
import java.net.URI;
import java.net.URL;
import java.nio.file.FileSystems;

View File

@@ -1,9 +1,6 @@
import static notest.Test.Util.*;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import notest.Test;
class TestJtags {
@@ -17,19 +14,14 @@ class TestJtags {
static void basicExample() throws IOException {
var process =
runJava(
new String[] {"-Dlogger.level=CONFIG"},
Jtags,
"-o",
"-",
"src/test/java/examples/BasicExample.java");
new String[] {"-Dlogger.level=CONFIG"},
Jtags,
"-o",
"-",
"src/test/java/examples/BasicExample.java");
var tags = readAllLines(process.inputReader());
Diff.diff(
tags,
readAllLines(new BufferedReader(new FileReader(
Path.of("src", "test", "java", "snapshots", "BasicExample.basicExample.1")
.toFile()))))
.assertEqual();
getSnapshot().assertEquals(tags);
}
}

View File

@@ -39,10 +39,13 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -57,9 +60,27 @@ public @interface Test {
public static Path javaHome = Paths.get(System.getProperty("java.home"));
public static String javaClassPath = System.getProperty("java.class.path");
public static String javaBin = javaHome.resolve("bin", "java").toString();
public static Path snapshotsPath = Path.of("src", "test", "java", "snapshots");
private static class Options {
boolean updateSnapshots = false;
}
private static Options options = new Options();
/** Runs all tests in {@code testClass} */
public static void runTests(Class<?> testClass, String[] args) {
var arguments = new ArrayDeque<String>(Arrays.asList(args));
switch (arguments.poll()) {
case "-u", "-update-snapshots":
options.updateSnapshots = true;
break;
case null:
default:
break;
}
System.exit(doRunTests(testClass) ? 0 : 1);
}
@@ -173,6 +194,11 @@ public @interface Test {
/** Creates a {@code Diff} representing changes from {@code a} to {@code b} */
public static Diff diff(List<String> a, List<String> b) {
if (a.equals(b)) return new Diff(List.of());
if (a.isEmpty()) a = List.of("");
if (b.isEmpty()) b = List.of("");
int diffSize = 0;
// longest common subsequence algorithm
int[][] dp = new int[a.size() + 1][b.size() + 1];
@@ -251,6 +277,31 @@ public @interface Test {
return lines;
}
public static record Snapshot(Path path) {
public void assertEquals(List<String> result) throws IOException {
var lines = Files.readAllLines(path);
if (options.updateSnapshots && !lines.equals(result)) {
Files.write(path, result);
return;
}
Diff.diff(lines, result).assertEqual();
}
}
private static Map<String, Integer> snapshotCount = new HashMap<>();
public static Snapshot getSnapshot() throws IOException {
var stackFrame = new Throwable().getStackTrace()[1];
var className = stackFrame.getClassName();
var methodName = stackFrame.getMethodName();
var prefix = className + "." + methodName;
var snapshotNumber = snapshotCount.compute(prefix, (k, v) -> v == null ? 1 : ++v);
Path path = snapshotsPath.resolve(prefix + "." + snapshotNumber);
if (!snapshotsPath.toFile().exists()) snapshotsPath.toFile().mkdirs();
if (!path.toFile().exists()) Files.write(path, List.of());
return new Snapshot(path);
}
/**
* Pads string to center.
*

View File

@@ -1,9 +1,9 @@
ABC
!_TAG_FILE_ENCODING utf-8
!_TAG_FILE_SORTED 2 /0=unsorted, 1=sorted, 2=foldcase/
BasicExample src/test/java/examples/BasicExample.java /^public class BasicExample {$/;" Cls package:examples
InnerClass src/test/java/examples/BasicExample.java /^ class InnerClass {$/;" Cls package:examples class:BasicExample
method1 src/test/java/examples/BasicExample.java /^ private boolean method1() {$/;" mthd class:BasicExample
ABC lorem ipsum dolor
method2 src/test/java/examples/BasicExample.java /^ public static void method2($/;" mthd file: class:BasicExample
method2 src/test/java/examples/BasicExample.java /^ void method2() {}$/;" mthd class:(Anonymous)
methodX src/test/java/examples/BasicExample.java /^ public static void method2($/;" mthd file: class:BasicExample
method3 src/test/java/examples/BasicExample.java /^ void method3() {}$/;" mthd class:InnerClass
method4 src/test/java/examples/BasicExample.java /^ private void method4() {}$/;" mthd class:InnerClass