summaryrefslogtreecommitdiff
path: root/src/test/java/org/zwobble
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/org/zwobble')
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java114
1 files changed, 108 insertions, 6 deletions
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java
index fd38a84..999ae83 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/ExampleTests.java
@@ -5,7 +5,12 @@ import org.junit.jupiter.api.TestFactory;
import org.zwobble.hobgoblin.compiler.testing.TestProcessRunner;
import java.io.IOException;
-import java.util.List;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
import java.util.stream.Stream;
public class ExampleTests {
@@ -18,14 +23,111 @@ public class ExampleTests {
));
}
- private void runTest(ExampleSet exampleSet) throws IOException, InterruptedException {
+ private void runTest(ExampleSet exampleSet) throws IOException, InterruptedException, NoSuchAlgorithmException {
var javaProjectPath = exampleSet.path().resolve("output/java");
HobgoblinCompiler.compile(exampleSet.path());
- TestProcessRunner.command(List.of("mvn", "compile"))
- .cwd(javaProjectPath)
- .runCaptureOutput()
- .throwOnError();
+ var currentHash = hashJavaProject(javaProjectPath);
+
+ var lastTestRunPath = javaProjectPath.resolve("last-test-run.properties");
+ var lastTestRun = readLastTestRun(lastTestRunPath);
+
+ if (lastTestRun.isPresent() && lastTestRun.get().pass && lastTestRun.get().hash.equals(currentHash)) {
+ return;
+ }
+
+ try {
+ TestProcessRunner.command(List.of("mvn", "compile"))
+ .cwd(javaProjectPath)
+ .runCaptureOutput()
+ .throwOnError();
+ writeLastTestRun(lastTestRunPath, new LastTestRun(currentHash, true));
+ } catch (Throwable exception) {
+ writeLastTestRun(lastTestRunPath, new LastTestRun(currentHash, false));
+ throw exception;
+ }
+ }
+
+ private record LastTestRun(String hash, boolean pass) {}
+
+ private Optional<LastTestRun> readLastTestRun(Path path) throws IOException {
+ var properties = new Properties();
+ try (var reader = Files.newBufferedReader(path)) {
+ properties.load(reader);
+ var hash = properties.getProperty("hash");
+ var pass = properties.getProperty("result").equals("PASS");
+ return Optional.of(new LastTestRun(hash, pass));
+ } catch (NoSuchFileException exception) {
+ return Optional.empty();
+ }
+ }
+
+ private void writeLastTestRun(Path path, LastTestRun lastTestRun) throws IOException {
+ var properties = new Properties();
+ properties.setProperty("hash", lastTestRun.hash);
+ properties.setProperty("result", lastTestRun.pass ? "PASS" : "FAIL");
+ try (var writer = Files.newBufferedWriter(path)) {
+ properties.store(writer, null);
+ }
+ }
+
+ private String hashJavaProject(Path javaProjectPath) throws NoSuchAlgorithmException, IOException {
+ var paths = collectJavaProjectSourcePaths(javaProjectPath);
+
+ var digest = MessageDigest.getInstance("sha256");
+
+ for (var path : paths) {
+ digest.update(path.toString().getBytes(StandardCharsets.UTF_8));
+ digest.update(new byte[]{0});
+ var contents = Files.readAllBytes(path);
+ digest.update(contents);
+ digest.update(new byte[]{0});
+ }
+
+ return bytesToHex(digest.digest());
+ }
+
+ private static String bytesToHex(byte[] bytes) {
+ var hexString = new StringBuilder(2 * bytes.length);
+ for (var b : bytes) {
+ var hex = Integer.toHexString(0xff & b);
+ if (hex.length() == 1) {
+ hexString.append('0');
+ }
+ hexString.append(hex);
+ }
+ return hexString.toString();
+ }
+
+ private static List<Path> collectJavaProjectSourcePaths(Path javaProjectPath) throws IOException {
+ var paths = new ArrayList<Path>();
+
+ Files.walkFileTree(
+ javaProjectPath, new SimpleFileVisitor<>() {
+ @Override
+ public FileVisitResult visitFile(
+ Path file,
+ BasicFileAttributes attrs
+ ) {
+ if (!javaProjectPath.relativize(file).toString().equals("last-test-run.properties")) {
+ paths.add(file);
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+ if (javaProjectPath.relativize(dir).startsWith("target")) {
+ return FileVisitResult.SKIP_SUBTREE;
+ } else {
+ return FileVisitResult.CONTINUE;
+ }
+ }
+ });
+
+ paths.sort(Comparator.naturalOrder());
+
+ return paths;
}
}