From a2756aca4dcd67d49fde776176bc9c2a159d048e Mon Sep 17 00:00:00 2001 From: TheSilkMiner Date: Wed, 22 May 2024 12:39:02 +0200 Subject: [PATCH] Add support for multi-directory tests Note: this has also found a bug in the compiler, how great Signed-off-by: TheSilkMiner --- .../scriptingenginetester/cases/TestCase.java | 56 ++++++++++++++----- .../cases/TestGroup.java | 4 +- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/ScriptingEngineTester/src/main/java/org/openzen/scriptingenginetester/cases/TestCase.java b/ScriptingEngineTester/src/main/java/org/openzen/scriptingenginetester/cases/TestCase.java index 870a133d3..3ba55e605 100644 --- a/ScriptingEngineTester/src/main/java/org/openzen/scriptingenginetester/cases/TestCase.java +++ b/ScriptingEngineTester/src/main/java/org/openzen/scriptingenginetester/cases/TestCase.java @@ -1,7 +1,6 @@ package org.openzen.scriptingenginetester.cases; import org.junit.platform.engine.TestSource; -import org.junit.platform.engine.support.descriptor.FileSource; import org.junit.platform.engine.support.descriptor.UriSource; import org.openzen.scriptingenginetester.TestOutput; import org.openzen.zencode.shared.PathSourceFile; @@ -11,7 +10,11 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class TestCase { private final TestSource source; @@ -19,20 +22,17 @@ public class TestCase { private final List sourceFiles = new ArrayList<>(); private final TestAnnotations annotations; - public TestCase(Path path) throws IOException { - if(Files.isDirectory(path)) { - throw new IllegalArgumentException("Multi-file tests are not yet supported"); - } else if(Files.isRegularFile(path)) { - this.source = UriSource.from(path.toUri()); - String filename = path.getFileName().toString(); - this.name = withoutExtension(filename); - - PathSourceFile sourceFile = new PathSourceFile(filename, path); - this.sourceFiles.add(sourceFile); - annotations = TestAnnotations.extractFrom(sourceFile); - } else { - throw new IllegalArgumentException("Not a valid file or directory"); + public TestCase(Path testGroupPath, Path testCasePath) throws IOException { + if (!testCasePath.startsWith(testGroupPath)) { + throw new IllegalStateException("Test case is not a part of its group"); } + + this.source = UriSource.from(testCasePath.toUri()); + this.name = withoutExtension(testCasePath); + this.sourceFiles.addAll(gatherSourceFiles(testGroupPath, testCasePath)); + assert !this.sourceFiles.isEmpty(); + // We guarantee that sourceFiles.get(0) always exists and that it is the main file + this.annotations = TestAnnotations.extractFrom(this.sourceFiles.get(0)); } public String getName() { @@ -55,7 +55,33 @@ public TestSource getSource() { return source; } - private static String withoutExtension(String filename) { + private static List gatherSourceFiles(Path testGroupPath, Path testCasePath) throws IOException { + if (Files.isDirectory(testCasePath)) { + Path main = testCasePath.resolve("main.zc"); + if (Files.notExists(main)) { + throw new IllegalStateException("Main file does not exist in " + testCasePath); + } + + Stream contents = Files.walk(testCasePath).filter(it -> !it.equals(testCasePath) && !it.equals(main)); + return Stream.concat(Stream.of(main), Stream.of(contents).flatMap(Function.identity())) + .map(it -> new PathSourceFile(getFileName(testGroupPath, it, false), it)) + .collect(Collectors.toList()); + } else if (Files.isRegularFile(testCasePath)) { + return Collections.singletonList(new PathSourceFile(getFileName(testGroupPath, testCasePath, true), testCasePath)); + } else { + throw new IllegalArgumentException("Unknown file format for " + testCasePath); + } + } + + private static String getFileName(Path testGroupPath, Path testCasePath, boolean single) { + // TODO Make every file test case in its own package? + Path groupName = testGroupPath.getFileName(); + Path caseName = testGroupPath.relativize(testCasePath); + return groupName.resolve(caseName).toString(); + } + + private static String withoutExtension(Path testCasePath) { + String filename = testCasePath.getFileName().toString(); int index = filename.lastIndexOf('.'); return index <= 0 ? filename : filename.substring(0, index); } diff --git a/ScriptingEngineTester/src/main/java/org/openzen/scriptingenginetester/cases/TestGroup.java b/ScriptingEngineTester/src/main/java/org/openzen/scriptingenginetester/cases/TestGroup.java index 278279306..edad3e048 100644 --- a/ScriptingEngineTester/src/main/java/org/openzen/scriptingenginetester/cases/TestGroup.java +++ b/ScriptingEngineTester/src/main/java/org/openzen/scriptingenginetester/cases/TestGroup.java @@ -19,10 +19,10 @@ public final class TestGroup { public TestGroup(Path dir) { this.directory = UriSource.from(dir.toUri()); this.name = dir.getFileName().toString(); - try (Stream paths = Files.list(dir)){ + try (Stream paths = Files.list(dir)) { for(Iterator iterator = paths.iterator(); iterator.hasNext(); ) { final Path next = iterator.next(); - cases.add(new TestCase(next)); + cases.add(new TestCase(dir, next)); } } catch (IOException e) { throw new RuntimeException(e);