Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More readable negative test expects #1266

Merged
merged 4 commits into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cli-impl/src/test/java/org/aya/test/LibraryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class LibraryTest {
@ParameterizedTest
@ValueSource(strings = {"success"})
public void testOnDisk(@NotNull String libName) throws IOException {
var libRoot = TestRunner.DEFAULT_TEST_DIR.resolve(libName);
var libRoot = TestRunner.TEST_DIR.resolve(libName);

FileUtil.deleteRecursively(libRoot.resolve("build"));
// Full rebuild
Expand Down Expand Up @@ -143,7 +143,7 @@ public void assertDelegate() {
}
}

public static final Path DIR = TestRunner.DEFAULT_TEST_DIR.resolve("success");
public static final Path DIR = TestRunner.TEST_DIR.resolve("success");

private static int compile(@NotNull Path root) throws IOException {
return compile(TestRunner.flags(), root);
Expand Down
83 changes: 40 additions & 43 deletions cli-impl/src/test/java/org/aya/test/TestRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Use of this source code is governed by the MIT license that can be found in the LICENSE.md file.
package org.aya.test;

import com.intellij.openapi.util.text.Strings;
import kala.collection.Seq;
import kala.collection.SeqView;
import org.aya.cli.single.CompilerFlags;
Expand All @@ -25,17 +24,18 @@
import java.nio.file.Paths;
import java.util.Locale;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

public class TestRunner {
public static final @NotNull Path DEFAULT_TEST_DIR = Paths.get("src", "test", "resources").toAbsolutePath();
public static final @NotNull Path TMP_FILE = DEFAULT_TEST_DIR.resolve("tmp.aya");
public static final @NotNull Path TEST_DIR = Paths.get("src", "test", "resources").toAbsolutePath();
private static final @NotNull Path FIXTURE_DIR = TEST_DIR.resolve("negative");
private static final @NotNull Path TMP_FILE = TEST_DIR.resolve("tmp.aya");
public static final @NotNull SourceFileLocator LOCATOR = new SourceFileLocator() { };
@BeforeAll public static void startDash() { Global.NO_RANDOM_NAME = true; }

@Test public void negative() throws Exception {
Seq.of(
var toCheck = Seq.of(
ParseError.class,
ExprTyckError.class,
GoalAndMeta.class,
Expand All @@ -45,7 +45,19 @@ public class TestRunner {
TerckError.class,
PatCohError.class,
ClassError.class
).forEachChecked(TestRunner::expectFixture);
).mapNotNullChecked(TestRunner::expectFixture);
if (toCheck.isNotEmpty()) {
new ProcessBuilder("git", "add", FIXTURE_DIR.toString())
.inheritIO()
.start()
.waitFor();
}
for (var file : toCheck) {
var name = file.toString();
var proc = new ProcessBuilder("git", "diff", "--cached", name).start();
var output = new String(proc.getInputStream().readAllBytes());
assertTrue(output.isBlank(), output);
}
Files.deleteIfExists(TMP_FILE);
}

Expand All @@ -60,55 +72,40 @@ public static void main(String... args) throws Exception {
new TestRunner().negative();
}

private static String instantiateVars(String template) {
return template.replace("$FILE", TMP_FILE.toString());
}

private static String instantiateHoles(String template) {
private static String replaceFileName(String template) {
return template.replace(TMP_FILE.toString(), "$FILE");
}

private static void checkOutput(Path expectedOutFile, String hookOut) {
try {
var output = Strings.convertLineSeparators(hookOut);
var expected = instantiateVars(Strings.convertLineSeparators(
Files.readString(expectedOutFile, StandardCharsets.UTF_8)));
assertEquals(expected, output, expectedOutFile.getFileName().toString());
} catch (IOException e) {
fail("error reading file " + expectedOutFile.toAbsolutePath());
}
}

private static void expectFixture(Class<?> fixturesClass) throws IllegalAccessException, IOException {
var result = runFixtureClass(fixturesClass);
var expectedOutFile = DEFAULT_TEST_DIR
.resolve("negative")
.resolve(fixturesClass.getSimpleName() + ".txt");
/// @return not null for a file to check, null if we're good to go
private static Path expectFixture(Class<?> fixturesClass) throws IllegalAccessException, IOException, InterruptedException {
var result = replaceFileName(runFixtureClass(fixturesClass));
var expectedOutFile = FIXTURE_DIR.resolve(fixturesClass.getSimpleName() + ".txt");
if (Files.exists(expectedOutFile)) {
checkOutput(expectedOutFile, result);
writeWorkflow(expectedOutFile, result);
return expectedOutFile;
} else {
System.out.println(); // add line break after `--->`
generateWorkflow(expectedOutFile, result);
System.out.println(); // add line break before `NOTE`
writeWorkflow(expectedOutFile, result);
System.out.printf(Locale.getDefault(),
"""
NOTE: write the following output to `%s`.
----------------------------------------
%s
----------------------------------------
""",
expectedOutFile.getFileName(),
result
);
}
return null;
}

private static void generateWorkflow(Path expectedOutFile, String hookOut) {
hookOut = instantiateHoles(hookOut);
private static void writeWorkflow(Path expectedOutFile, String hookOut) {
try {
FileUtil.writeString(expectedOutFile, hookOut);
} catch (IOException e) {
fail("error generating todo file " + expectedOutFile.toAbsolutePath());
}
System.out.printf(Locale.getDefault(),
"""
NOTE: write the following output to `%s`.
----------------------------------------
%s
----------------------------------------
""",
expectedOutFile.getFileName(),
hookOut
);
}

private static String runFixtureClass(Class<?> fixturesClass)
Expand Down Expand Up @@ -141,7 +138,7 @@ private static void runSingleCase(String code, SingleFileCompiler compiler) thro
}

public static @NotNull CompilerFlags flags() {
var modulePaths = SeqView.of(DEFAULT_TEST_DIR.resolve("shared/src"));
var modulePaths = SeqView.of(TEST_DIR.resolve("shared/src"));
return new CompilerFlags(CompilerFlags.Message.ASCII,
false, false, null, modulePaths, null);
}
Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ java = "22"
# https://github.com/JetBrains/java-annotations
annotations = "26.0.1"
# https://github.com/Glavo/kala-common
kala = "0.76.0"
kala = "0.78.0"
# https://picocli.info
picocli = "4.7.6"
# https://repo1.maven.org/maven2/org/aya-prover/upstream/build-util
aya-upstream = "0.0.31"
aya-upstream = "0.0.33"
# https://github.com/jline/jline3
jline = "3.28.0"
# https://junit.org/junit5
Expand Down
2 changes: 1 addition & 1 deletion producer/src/main/java/org/aya/producer/AyaParserImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
public record AyaParserImpl(@NotNull Reporter reporter) implements GenericAyaParser {
public @NotNull GenericNode<?> parseNode(@NotNull String code) {
var parser = new AyaFleetParser();
return new MarkerNodeWrapper(code, parser.parse(code));
return new MarkerNodeWrapper(parser.parse(code), code);
}

@Override public @NotNull WithPos<Expr> expr(@NotNull String code, @NotNull SourcePos sourcePos) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public FlclParser(@NotNull Reporter reporter, @NotNull SourceFile file) {

public @NotNull FlclToken.File computeAst() {
var text = file.sourceCode();
var node = new MarkerNodeWrapper(text, new FlclFleetParser().parse(text));
var node = new MarkerNodeWrapper(new FlclFleetParser().parse(text), text);
node.childrenOfType(FlclPsiElementTypes.RULE).forEach(rule -> {
var idChildren = rule.childrenOfType(FlclPsiElementTypes.ID)
.map(MarkerNodeWrapper::tokenText)
Expand Down
Loading