Skip to content
Snippets Groups Projects
Commit aeb1e3f9 authored by Johannes Mey's avatar Johannes Mey
Browse files

update test infrastructure

parent 988e7143
Branches
Tags
No related merge requests found
Showing
with 186 additions and 73 deletions
......@@ -53,6 +53,7 @@ dependencies {
testFixturesApi group: 'org.assertj', name: 'assertj-core', version: '3.18.0'
testFixturesApi group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.0-rc1'
testFixturesApi group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.12.0-rc1'
testFixturesApi group: 'commons-io', name: 'commons-io', version: '2.8.0'
}
test {
......
......@@ -43,15 +43,17 @@ aspect BackendAbstractGrammar {
if (getAbstract()) {
b.append("abstract ");
}
b.append(getName()).append(" ");
b.append(getName());
if (hasSuperType()) {
b.append(": ").append(getSuperType().getName()).append(" ");
b.append(" : ").append(getSuperType().getName());
}
if (getNumComponent() > 0) {
b.append(" ::=");
for (Component component : getComponentList()) {
b.append(" ");
component.generateAbstractGrammar(b);
}
}
b.append(";");
super.generateAbstractGrammar(b);
}
......@@ -62,8 +64,7 @@ aspect BackendAbstractGrammar {
if (getNTA()) {
b.append("/");
}
if (!getName().equals("")) {
if (!getName().equals("") && !getName().equals(getTypeDecl().getName())) {
b.append(getName()).append(":");
}
b.append(getTypeDecl().getName());
......@@ -76,8 +77,7 @@ aspect BackendAbstractGrammar {
if (getNTA()) {
b.append("/");
}
if (!getName().equals("")) {
if (!getName().equals("") && !getName().equals(getTypeDecl().getName())) {
b.append(getName()).append(":");
}
b.append(getTypeDecl().getName()).append("*");
......@@ -91,7 +91,7 @@ aspect BackendAbstractGrammar {
b.append("/");
}
b.append("[");
if (!getName().equals("")) {
if (!getName().equals("") && !getName().equals(getTypeDecl().getName())) {
b.append(getName()).append(":");
}
b.append(getTypeDecl().getName()).append("]");
......@@ -187,7 +187,7 @@ aspect BackendAbstractGrammar {
}
public void SingleLineComment.generateAbstractGrammar(StringBuilder b) {
b.append("//").append(getText()).append("\n");
b.append("//").append(getText());
}
public void MultiLineComment.generateAbstractGrammar(StringBuilder b) {
......
......@@ -6,16 +6,34 @@ import com.github.jknack.handlebars.io.ClassPathTemplateLoader;
import com.github.jknack.handlebars.io.TemplateLoader;
import org.yaml.snakeyaml.Yaml;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.io.*;
import java.nio.file.Paths;
public class Mustache {
public static void javaMustache(String templateFileName, String yamlFileName, String outputFileName) throws IOException {
private Mustache() {
// hide public constructor
}
public static void javaMustache(String templateFileName, File yamlFile, String outputFileName) throws IOException {
//noinspection ResultOfMethodCallIgnored
Paths.get(outputFileName).getParent().toFile().mkdirs(); // create directory structure if necessary
Object context = new Yaml().load(new FileReader(yamlFile));
applyTemplate(templateFileName, outputFileName, context);
}
public static void javaMustache(String templateFileName, String yaml, String outputFileName) throws IOException {
//noinspection ResultOfMethodCallIgnored
Paths.get(outputFileName).getParent().toFile().mkdirs(); // create directory structure if necessary
Object context = new Yaml().load(new StringReader(yaml));
applyTemplate(templateFileName, outputFileName, context);
}
Object context = new Yaml().load(new FileReader(yamlFileName));
private static void applyTemplate(String templateFileName, String outputFileName, Object context) throws IOException {
TemplateLoader loader = new ClassPathTemplateLoader();
loader.setSuffix(".mustache"); // the default is ".hbs"
......
......@@ -21,7 +21,7 @@ public abstract class RelAstProcessor extends AbstractCompiler {
protected ValueOption optionOutputBaseDir;
protected ValueOption optionInputBaseDir;
public RelAstProcessor(String name, boolean jastAddCompliant) {
protected RelAstProcessor(String name, boolean jastAddCompliant) {
super(name, jastAddCompliant);
}
......
package org.jastadd.relast.tests;
import org.jastadd.relast.compiler.RelastSourceToSourceCompiler;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.file.Paths;
import org.junit.jupiter.api.BeforeAll;
public class PreprocessorTest extends RelAstProcessorTestBase {
@Test
void testMinimalGrammar() throws IOException, InterruptedException {
directoryTest(RelastSourceToSourceCompiler.class, Paths.get("src/test/resources/MinimalGrammar"));
@BeforeAll
static void init() {
mainClass = RelastSourceToSourceCompiler.class;
}
}
- name: "Parse and reprint tests"
args:
- "--inputBaseDir=in"
- "--outputBaseDir=out"
- "CommentsA.relast"
out: "out"
expected: "in"
compare: true
// this file only contains comments
//
//
// like this one
/* or this one */
/* or this
one */
/**/
//test
/*test*/
//
- name: "MinimalGrammar"
- name: "Parse and reprint tests"
args:
- "--inputBaseDir=in"
- "--outputBaseDir=out"
- "Example.relast"
- name: "Comments in front"
args:
- "--inputBaseDir=in"
- "--outputBaseDir=out"
- "CommentInFront.relast"
out: "out"
expected: "in"
compare: true
......@@ -3,25 +3,25 @@ package org.jastadd.relast.tests;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.assertj.core.util.Files;
import org.jastadd.relast.tests.config.Configuration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.*;
import java.util.stream.Stream;
public class RelAstProcessorTestBase {
protected static Class<?> mainClass;
protected static int runProcess(File workingDirectory, List<String> command, StringBuilder outStringBuider, StringBuilder errStringBuilder) throws IOException, InterruptedException {
File outFile = Files.newTemporaryFile();
......@@ -72,7 +72,7 @@ public class RelAstProcessorTestBase {
command.addAll(args);
}
System.out.println("Running java -jar -cp [...] " + className + " " + args.stream().reduce((s1, s2) -> s1 + " " + s2).orElse(""));
System.out.println("Running java -jar -cp [...] " + className + " " + (args != null ? args.stream().reduce((s1, s2) -> s1 + " " + s2).orElse("") : ""));
return runProcess(workingDirectory, command, outStringBuider, errStringBuilder);
}
......@@ -86,6 +86,9 @@ public class RelAstProcessorTestBase {
for (Configuration config : configs) {
FileUtils.forceMkdir(dir.resolve(config.getOut()).toFile());
FileUtils.cleanDirectory(dir.resolve(config.getOut()).toFile());
StringBuilder outBuilder = new StringBuilder();
StringBuilder errBuilder = new StringBuilder();
int returnValue = runJavaProcess(mainClass, dir.toFile(), Arrays.asList(config.getArgs()), outBuilder, errBuilder);
......@@ -96,11 +99,22 @@ public class RelAstProcessorTestBase {
System.err.println(err);
if (config.shouldFail()) {
Assertions.assertNotEquals(0, returnValue, "Zero return value of preprocessor for negative test.");
Assertions.assertNotEquals(0, returnValue, config.getName() + ": Zero return value of preprocessor for negative test.");
} else {
Assertions.assertEquals(0, returnValue, "Non-Zero return value of preprocessor for positive test.");
Assertions.assertEquals(0, returnValue, config.getName() + ": Non-Zero return value of preprocessor for positive test.");
}
checkOutput(config, out, err);
if (config.shouldCompare()) {
Path outPath = dir.resolve(config.getOut());
Path expectedPath = dir.resolve(config.getExpected());
comparePaths(outPath, expectedPath);
}
}
}
private void checkOutput(Configuration config, String out, String err) {
for (String errMatchString : config.getErrMatches()) {
if (!err.matches(errMatchString)) {
Assertions.fail("Error stream does not match '" + errMatchString + "'");
......@@ -115,27 +129,48 @@ public class RelAstProcessorTestBase {
for (String outMatchString : config.getOutMatches()) {
if (!out.matches(outMatchString)) {
Assertions.fail("Error stream does not match '" + outMatchString + "'");
Assertions.fail("Output stream does not match '" + outMatchString + "'");
}
}
for (String outContainsString : config.getOutContains()) {
if (!out.contains(outContainsString)) {
Assertions.fail("Error stream does not contain '" + outContainsString + "'");
}
Assertions.fail("Output stream does not contain '" + outContainsString + "'");
}
}
}
protected void ensureOutputDir(String outputDir) {
File outputDirFile = Paths.get(outputDir).toFile();
if (outputDirFile.exists()) {
assertTrue(outputDirFile.isDirectory());
if (Objects.requireNonNull(outputDirFile.list(), "Could not read output directory").length != 0) {
System.out.println("output directory is not empty!");
private void comparePaths(Path outPath, Path expectedPath) {
final Collection<File> files = FileUtils.listFiles(expectedPath.toFile(), TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);
files.forEach(f -> {
final Path relative = expectedPath.relativize(f.toPath());
final String relativePath = relative.toFile().getPath();
final File bfile = new File(outPath.toFile(), relativePath);
if (bfile.exists()) {
try {
final Charset charset = Charset.defaultCharset();
final String expected = FileUtils.readFileToString(f, charset);
final String result = FileUtils.readFileToString(bfile, charset);
Assertions.assertEquals(expected, result);
} catch (IOException e) {
Assertions.fail("Unable to compare input files '" + f + "' and '" + bfile + "'", e);
}
} else {
assertTrue(outputDirFile.mkdirs());
Assertions.fail(relativePath + " expected to exist");
}
});
}
@TestFactory
Stream<DynamicTest> testAll() {
File baseDir = new File("src/test/resources/");
Assertions.assertTrue(baseDir.exists());
Assertions.assertTrue(baseDir.isDirectory());
File[] files = baseDir.listFiles((FileFilter) FileFilterUtils.directoryFileFilter());
Assertions.assertNotNull(files);
return Arrays.stream(files).map(File::toPath).map(f -> DynamicTest.dynamicTest(f.getFileName().toString(),
() -> directoryTest(mainClass, f)));
}
}
......@@ -9,6 +9,35 @@ public class Configuration {
private String[] errContains = new String[]{};
private String[] outMatches = new String[]{};
private String[] outContains = new String[]{};
private String in = "in";
private String out = "out";
private String expected = "expected";
private boolean compare = false;
public String getIn() {
return in;
}
public void setIn(String in) {
this.in = in;
}
public String getOut() {
return out;
}
public void setOut(String out) {
this.out = out;
}
public String getExpected() {
return expected;
}
public void setExpected(String expected) {
this.expected = expected;
}
@com.fasterxml.jackson.annotation.JsonGetter("out-matches")
public String[] getOutMatches() {
......@@ -46,7 +75,7 @@ public class Configuration {
}
@com.fasterxml.jackson.annotation.JsonSetter("err-contains")
public void setErrContains(String[] errMatches) {
public void setErrContains(String[] errContains) {
this.errContains = errContains;
}
......@@ -75,4 +104,14 @@ public class Configuration {
public void shouldFail(boolean fail) {
this.fail = fail;
}
@com.fasterxml.jackson.annotation.JsonGetter("compare")
public boolean shouldCompare() {
return compare;
}
@com.fasterxml.jackson.annotation.JsonSetter("compare")
public void shouldCompare(boolean compare) {
this.compare = compare;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment