--- /dev/null
+package org.simantics.scl.compiler.tests;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+import org.junit.Assert;
+import org.simantics.scl.compiler.errors.Failable;
+import org.simantics.scl.compiler.errors.Failure;
+import org.simantics.scl.compiler.module.ImportDeclaration;
+import org.simantics.scl.compiler.module.Module;
+import org.simantics.scl.compiler.module.repository.ModuleRepository;
+import org.simantics.scl.compiler.module.repository.UpdateListener;
+import org.simantics.scl.compiler.source.StringModuleSource;
+import org.simantics.scl.compiler.source.repository.CompositeModuleSourceRepository;
+import org.simantics.scl.compiler.source.repository.MapModuleSourceRepository;
+import org.simantics.scl.compiler.source.repository.SourceRepositories;
+import org.simantics.scl.compiler.top.ValueNotFound;
+
+public class TestBase {
+
+ public static final ModuleRepository PRELUDE_MODULE_REPOSITORY = new ModuleRepository(
+ new CompositeModuleSourceRepository(
+ SourceRepositories.BUILTIN_SOURCE_REPOSITORY,
+ SourceRepositories.PRELUDE_SOURCE_REPOSITORY
+ ));
+ private static final Pattern TEST_SEPARATOR = Pattern.compile("^-- *$", Pattern.MULTILINE);
+ private static final Charset UTF8 = Charset.forName("UTF-8");
+
+ String path;
+
+ public TestBase(String path) {
+ this.path = path;
+ }
+
+
+ protected void test() {
+ String testModuleName = Thread.currentThread().getStackTrace()[2].getMethodName();
+ String testPath = path + "/" + testModuleName + ".scl";
+
+ try {
+ String[] testParts = readTestParts(testPath);
+ for(int i=0;i<testParts.length;i+=2) {
+ String input = testParts[i];
+ String expectedOutput = testParts[i+1];
+ String actualOutput = test(testModuleName, input);
+ Assert.assertEquals(
+ canonicalizeOutput(expectedOutput),
+ canonicalizeOutput(actualOutput));
+ }
+ } catch(IOException e) {
+ throw new RuntimeException(e);
+ } catch (ValueNotFound e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static String canonicalizeOutput(String text) {
+ return text.trim().replace("\r\n", "\n");
+ }
+
+ protected String test(String testModuleName, String input) throws ValueNotFound {
+ ModuleRepository testEnvironment = new ModuleRepository(
+ PRELUDE_MODULE_REPOSITORY,
+ new MapModuleSourceRepository(new StringModuleSource(
+ testModuleName, getClass().getClassLoader(), input) {
+ @Override
+ protected ImportDeclaration[] getBuiltinImports(UpdateListener listener) {
+ return ImportDeclaration.ONLY_BUILTINS;
+ }
+ }
+ ));
+ Failable<Module> result = testEnvironment.getModule(testModuleName);
+ if(!result.didSucceed())
+ return ((Failure)result).toString(input);
+ else {
+ Object main = testEnvironment.getRuntimeModule(testModuleName).getResult().getValue("main");
+ return String.valueOf(main);
+ }
+ }
+
+ private String[] readTestParts(String testPath) throws IOException {
+ InputStream stream = getClass().getResourceAsStream(testPath);
+ try {
+ byte[] buffer = new byte[1024];
+ int pos = 0;
+ while(true) {
+ int c = stream.read(buffer, pos, buffer.length-pos);
+ if(c <= 0)
+ break;
+ pos += c;
+ if(pos < buffer.length)
+ break;
+ buffer = Arrays.copyOf(buffer, pos*2);
+ }
+ String text = new String(buffer, 0, pos, UTF8);
+ String[] result = TEST_SEPARATOR.split(text);
+ if(result.length % 2 == 1) {
+ result = Arrays.copyOf(result, result.length+2);
+ result[result.length-1] = "";
+ }
+ return result;
+ } finally {
+ stream.close();
+ }
+ }
+}