]> gerrit.simantics Code Review - simantics/platform.git/blob - tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestBase.java
Merge commit '31664b6'
[simantics/platform.git] / tests / org.simantics.scl.compiler.tests / src / org / simantics / scl / compiler / tests / TestBase.java
1 package org.simantics.scl.compiler.tests;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.nio.charset.Charset;
6 import java.util.ArrayList;
7 import java.util.Arrays;
8 import java.util.regex.Pattern;
9
10 import org.junit.Assert;
11 import org.simantics.scl.compiler.errors.Failable;
12 import org.simantics.scl.compiler.errors.Failure;
13 import org.simantics.scl.compiler.module.ImportDeclaration;
14 import org.simantics.scl.compiler.module.Module;
15 import org.simantics.scl.compiler.module.repository.ModuleRepository;
16 import org.simantics.scl.compiler.module.repository.UpdateListener;
17 import org.simantics.scl.compiler.source.ModuleSource;
18 import org.simantics.scl.compiler.source.StringModuleSource;
19 import org.simantics.scl.compiler.source.repository.CompositeModuleSourceRepository;
20 import org.simantics.scl.compiler.source.repository.MapModuleSourceRepository;
21 import org.simantics.scl.compiler.source.repository.SourceRepositories;
22 import org.simantics.scl.compiler.top.ValueNotFound;
23
24 public class TestBase {
25     
26     public static final ModuleRepository PRELUDE_MODULE_REPOSITORY = InitialRepository.getInitialRepository();
27     private static final Pattern TEST_SEPARATOR = Pattern.compile("^--+ *$", Pattern.MULTILINE);
28     private static final Charset UTF8 = Charset.forName("UTF-8");
29
30     String path;
31
32     public TestBase(String path) {
33         this.path = path;
34     }
35     
36     protected void test() {
37         String testModuleName = Thread.currentThread().getStackTrace()[2].getMethodName();
38         String testPath = path + "/" + testModuleName + ".scl";
39         
40         try {
41             String[] testParts = readTestParts(testPath);
42             
43             int j=0;
44             ArrayList<String> auxModuleNameList = new ArrayList<String>();
45             while(j < testParts.length) {
46                 String part = testParts[j]; 
47                 if(part.startsWith("// module "))
48                     auxModuleNameList.add(part.substring(10).split("\\n", 2)[0].trim());
49                 else
50                     break;
51                 ++j;
52             }
53             int mainId = j;
54             String[] moduleNames = new String[mainId+1];
55             String[] moduleTexts = new String[mainId+1];
56             for(int i=0;i<mainId;++i) {
57                 moduleNames[i] = auxModuleNameList.get(i);
58                 moduleTexts[i] = testParts[i];
59             }
60             moduleNames[mainId] = testModuleName;
61             
62             for(;j<testParts.length;j+=2) {
63                 moduleTexts[mainId] = testParts[j];
64                 String expectedOutput = j+1<testParts.length ? testParts[j+1] : "";
65                 String actualOutput = test(moduleNames, moduleTexts);
66                 Assert.assertEquals(
67                         canonicalizeOutput(expectedOutput),
68                         canonicalizeOutput(actualOutput));
69             }
70         } catch(IOException e) {
71             throw new RuntimeException(e);
72         } catch (ValueNotFound e) {
73             throw new RuntimeException(e);
74         }
75     }
76     
77     private static String canonicalizeOutput(String text) {
78         return text.trim().replace("\r\n", "\n");
79     }
80
81     protected String test(String[] moduleNames, String[] moduleTexts) throws ValueNotFound {
82         if(moduleNames.length != moduleTexts.length)
83             throw new IllegalArgumentException();
84         /*for(int i=0;i<moduleNames.length;++i) {
85             System.out.println("-- " + moduleNames[i] + " --");
86             System.out.println(moduleTexts[i]);
87         }*/
88         
89         ModuleSource[] moduleSources = new ModuleSource[moduleNames.length];
90         for(int i=0;i<moduleNames.length;++i)
91             moduleSources[i] = new StringModuleSource(
92                     moduleNames[i], getClass().getClassLoader(), moduleTexts[i]) {
93                 @Override
94                 protected ImportDeclaration[] getBuiltinImports(UpdateListener listener) {
95                     return ImportDeclaration.ONLY_BUILTINS;
96                 }
97             };
98         ModuleRepository testEnvironment = new ModuleRepository(
99                 PRELUDE_MODULE_REPOSITORY,
100                 new MapModuleSourceRepository(moduleSources));
101         int lastId = moduleNames.length-1;
102         Failable<Module> result = testEnvironment.getModule(moduleNames[lastId]);
103         if(!result.didSucceed())
104             return ((Failure)result).toString(moduleTexts[lastId]);
105         else {
106             Object main = testEnvironment.getRuntimeModule(moduleNames[lastId]).getResult().getValue("main");
107             return String.valueOf(main);
108         }
109     }
110
111     private String[] readTestParts(String testPath) throws IOException {
112         InputStream stream = getClass().getResourceAsStream(testPath);
113         try {
114             byte[] buffer = new byte[1024];
115             int pos = 0;
116             while(true) {
117                 int c = stream.read(buffer, pos, buffer.length-pos);
118                 if(c <= 0)
119                     break;
120                 pos += c;
121                 if(pos < buffer.length)
122                     break;
123                 buffer = Arrays.copyOf(buffer, pos*2);
124             }
125             String text = new String(buffer, 0, pos, UTF8);
126             String[] result = TEST_SEPARATOR.split(text);
127             for(int i=1;i<result.length;++i) {
128                 if(result[i].startsWith("\r\n"))
129                     result[i] = result[i].substring(2);
130                 if(result[i].startsWith("\n") || result[i].startsWith("\r"))
131                     result[i] = result[i].substring(1);
132             }
133             return result;
134         } finally {
135             stream.close();
136         }
137     }
138 }