package org.shedlang.compiler.backends; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; import org.shedlang.compiler.ShedCompiler; import org.shedlang.compiler.backends.paths.TargetDir; import org.shedlang.compiler.errors.CompilerError; import org.shedlang.compiler.testing.ExecutionResult; import org.shedlang.compiler.testing.TestProcessRunner; import org.shedlang.compiler.util.P; import java.io.IOException; import java.util.List; import java.util.Optional; import java.util.stream.Stream; import static org.zwobble.precisely.AssertThat.assertThat; import static org.zwobble.precisely.Matchers.equalTo; public abstract class ExampleTests { @TestFactory public Stream tests() { return ExampleSet.exampleSets() .map(exampleSet -> DynamicTest.dynamicTest( exampleSet.name(), () -> runTest(exampleSet) )); } private void runTest(ExampleSet exampleSet) throws IOException, InterruptedException { var isWipTest = isDisabled(exampleSet.name()); var includeWipTests = includeWipTests(); Assumptions.assumeFalse(isWipTest && !includeWipTests); var backend = backend(); var compiler = new ShedCompiler(); var config = exampleSet.readConfig(); for (var example : config.examples()) { TargetDir targetDir; try { targetDir = compiler.compile(example.projectPath(), backend, Optional.empty()); } catch (CompilerError error) { if (example.expectedError().isPresent()) { assertThat(error.getMessage(), equalTo(example.expectedError().get())); continue; } System.err.println(error.source().describe()); throw error; } var binPath = targetDir.topLevel(example.bin() + this.executableExtension()) .toString(); var result = runExampleBinary(binPath); assertThat(result.exitCode(), equalTo((int)example.expectedExitCode().orElse(0))); assertThat(result.stdout(), equalTo(example.expectedOutput().orElse(""))); } if (isWipTest) { Assertions.fail("WIP test succeeded"); } } private static boolean includeWipTests() { var variable = System.getenv("INCLUDE_WIP_TESTS"); return variable != null && !variable.equals("0"); } private ExecutionResult runExampleBinary(String binary) throws IOException, InterruptedException { var fullCommand = P.vector() .plusAll(binaryRunner()) .plus(binary); return TestProcessRunner.runCaptureOutput(fullCommand); } protected abstract Backend backend(); protected abstract List binaryRunner(); protected abstract String executableExtension(); protected abstract boolean isDisabled(String testName); }