Add test snapshot utility
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user