diff --git a/web-view-components-compiler/src/main/java/groowt/view/component/web/util/ExtensionUtil.java b/web-view-components-compiler/src/main/java/groowt/view/component/web/util/ExtensionUtil.java new file mode 100644 index 0000000..c291599 --- /dev/null +++ b/web-view-components-compiler/src/main/java/groowt/view/component/web/util/ExtensionUtil.java @@ -0,0 +1,22 @@ +package groowt.view.component.web.util; + +import java.io.File; +import java.nio.file.Path; + +public final class ExtensionUtil { + + public static String getNameWithoutExtension(String fileName) { + return fileName.substring(0, fileName.lastIndexOf(".")); + } + + public static String getNameWithoutExtension(File file) { + return getNameWithoutExtension(file.getName()); + } + + public static String getNameWithoutExtension(Path path) { + return getNameWithoutExtension(path.getFileName().toString()); + } + + private ExtensionUtil() {} + +} diff --git a/web-view-components-compiler/src/main/java/groowt/view/component/web/util/FileUtil.java b/web-view-components-compiler/src/main/java/groowt/view/component/web/util/FileUtil.java new file mode 100644 index 0000000..b0b31fb --- /dev/null +++ b/web-view-components-compiler/src/main/java/groowt/view/component/web/util/FileUtil.java @@ -0,0 +1,19 @@ +package groowt.view.component.web.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +public final class FileUtil { + + public static String readFile(File file) { + try (final var fis = new FileInputStream(file)) { + return new String(fis.readAllBytes()); + } catch (IOException ioException) { + throw new RuntimeException(ioException); + } + } + + private FileUtil() {} + +} diff --git a/web-view-components-compiler/src/test/java/groowt/view/component/web/ast/DefaultAstBuilderTests.java b/web-view-components-compiler/src/test/java/groowt/view/component/web/ast/DefaultAstBuilderTests.java index 8bdf732..38e96e2 100644 --- a/web-view-components-compiler/src/test/java/groowt/view/component/web/ast/DefaultAstBuilderTests.java +++ b/web-view-components-compiler/src/test/java/groowt/view/component/web/ast/DefaultAstBuilderTests.java @@ -3,16 +3,15 @@ package groowt.view.component.web.ast; import groowt.view.component.web.antlr.ParserUtil; import groowt.view.component.web.antlr.TokenList; -import java.io.File; import java.nio.file.Path; public class DefaultAstBuilderTests extends AstBuilderTests { public DefaultAstBuilderTests() { super( - Path.of(String.join(File.separator, "src", "test", "ast")), + Path.of("src", "test", "ast"), "*.wvc", - new File(String.join(File.separator, "src", "test", "ast", "trees")), + Path.of("src", "test", "ast", "trees"), "_ast.txt" ); } diff --git a/web-view-components-compiler/src/testFixtures/java/groowt/view/component/web/ast/AstBuilderTests.java b/web-view-components-compiler/src/testFixtures/java/groowt/view/component/web/ast/AstBuilderTests.java index eebac54..1d507b2 100644 --- a/web-view-components-compiler/src/testFixtures/java/groowt/view/component/web/ast/AstBuilderTests.java +++ b/web-view-components-compiler/src/testFixtures/java/groowt/view/component/web/ast/AstBuilderTests.java @@ -2,51 +2,25 @@ package groowt.view.component.web.ast; import groowt.view.component.web.antlr.TokenList; import groowt.view.component.web.ast.node.Node; +import groowt.view.component.web.testutil.FileComparisonTestUtil; +import groowt.view.component.web.util.ExtensionUtil; +import groowt.view.component.web.util.FileUtil; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.PathMatcher; import java.util.Collection; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.*; public abstract class AstBuilderTests { protected record BuildResult(Node node, TokenList tokenList) {} - private static final Pattern withoutExtension = Pattern.compile("(?.*)\\..+"); - - protected static String getNameWithoutExtension(File file) { - final var m = withoutExtension.matcher(file.getName()); - if (m.matches()) { - return m.group("name"); - } else { - throw new IllegalArgumentException("Cannot get name without extension for " + file); - } - } - - protected static String readFile(File file) { - try (final var fis = new FileInputStream(file)) { - return new String(fis.readAllBytes()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - private final Path sourceFileDir; private final String sourceFileGlob; - private final File astTreeDir; + private final Path astTreeDir; private final String astFileSuffixAndExt; - public AstBuilderTests(Path sourceFileDir, String sourceFileGlob, File astTreeDir, String astFileSuffixAndExt) { + public AstBuilderTests(Path sourceFileDir, String sourceFileGlob, Path astTreeDir, String astFileSuffixAndExt) { this.sourceFileDir = sourceFileDir; this.sourceFileGlob = sourceFileGlob; this.astTreeDir = astTreeDir; @@ -57,35 +31,21 @@ public abstract class AstBuilderTests { protected abstract String format(BuildResult buildResult); - protected void doSourceFileTest(String source, String expected) { - final BuildResult buildResult = this.buildFromSource(source); - final var actual = this.format(buildResult); - assertEquals(expected, actual); - } - @TestFactory public Collection getSourceFileTests() { - final var fs = FileSystems.getDefault(); - final PathMatcher matcher = fs.getPathMatcher( - "glob:" + this.sourceFileDir.toString() + File.separator + this.sourceFileGlob + return FileComparisonTestUtil.getTestsFor( + this.sourceFileDir, + this.sourceFileGlob, + this.astTreeDir, + sourcePath -> { + final String nameWithoutExtension = ExtensionUtil.getNameWithoutExtension(sourcePath); + return Path.of(nameWithoutExtension + this.astFileSuffixAndExt); + }, + sourceFile -> { + final BuildResult buildResult = this.buildFromSource(FileUtil.readFile(sourceFile)); + return this.format(buildResult); + } ); - try (final Stream paths = Files.walk(this.sourceFileDir)) { - return paths.filter(matcher::matches) - .map(Path::toFile) - .filter(File::isFile) - .map(file -> { - final var name = getNameWithoutExtension(file); - final var expectedAstFile = new File(this.astTreeDir, name + this.astFileSuffixAndExt); - final var source = readFile(file); - final var expected = readFile(expectedAstFile); - return DynamicTest.dynamicTest( - name, - () -> this.doSourceFileTest(source, expected) - ); - }).toList(); - } catch (IOException e) { - throw new RuntimeException(e); - } } } diff --git a/web-view-components-compiler/src/testFixtures/java/groowt/view/component/web/testutil/FileComparisonTestUtil.java b/web-view-components-compiler/src/testFixtures/java/groowt/view/component/web/testutil/FileComparisonTestUtil.java new file mode 100644 index 0000000..4fba671 --- /dev/null +++ b/web-view-components-compiler/src/testFixtures/java/groowt/view/component/web/testutil/FileComparisonTestUtil.java @@ -0,0 +1,58 @@ +package groowt.view.component.web.testutil; + +import groowt.view.component.web.util.ExtensionUtil; +import groowt.view.component.web.util.FileUtil; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.DynamicTest; + +import java.io.File; +import java.io.IOException; +import java.nio.file.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.*; + +public final class FileComparisonTestUtil { + + public static void doComparisonTest(File expected, String actualText) { + if (!expected.isFile()) { + throw new IllegalArgumentException("expected is not a file or does not exist: " + expected); + } + final String expectedText = FileUtil.readFile(expected); + assertEquals(expectedText, actualText); + } + + public static Collection getTestsFor( + Path inputDirectory, + String inputFilesGlob, + Path outputDirectory, + Function inputFileToExpected, + Function inputToActual + ) { + final Collection result = new ArrayList<>(); + final FileSystem fileSystem = FileSystems.getDefault(); + final PathMatcher matcher = fileSystem.getPathMatcher("glob:" + inputDirectory.resolve(inputFilesGlob)); + try (final var files = Files.walk(inputDirectory)) { + files.filter(Files::isRegularFile) + .filter(matcher::matches) + .forEach(inputPath -> { + final @Nullable Path expected = inputFileToExpected.apply(inputPath); + if (expected != null) { + final File expectedResolvedFile = outputDirectory.resolve(expected).toFile(); + result.add(DynamicTest.dynamicTest(ExtensionUtil.getNameWithoutExtension(inputPath), () -> { + final String actual = inputToActual.apply(inputPath.toFile()); + doComparisonTest(expectedResolvedFile, actual); + })); + } + }); + } catch (IOException ioException) { + throw new RuntimeException(ioException); + } + return result; + } + + private FileComparisonTestUtil() {} + +}