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