]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestBase.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / tests / org / simantics / scl / compiler / tests / TestBase.java
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestBase.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestBase.java
new file mode 100644 (file)
index 0000000..7a44539
--- /dev/null
@@ -0,0 +1,109 @@
+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();
+        }
+    }
+}