1 package org.simantics.scl.compiler.tests;
3 import java.io.FileNotFoundException;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.StringWriter;
7 import java.nio.charset.Charset;
8 import java.util.ArrayList;
9 import java.util.Arrays;
10 import java.util.regex.Pattern;
12 import org.junit.Assert;
13 import org.simantics.scl.compiler.errors.Failable;
14 import org.simantics.scl.compiler.errors.Failure;
15 import org.simantics.scl.compiler.module.ImportDeclaration;
16 import org.simantics.scl.compiler.module.Module;
17 import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
18 import org.simantics.scl.compiler.module.repository.ModuleRepository;
19 import org.simantics.scl.compiler.module.repository.UpdateListener;
20 import org.simantics.scl.compiler.source.ModuleSource;
21 import org.simantics.scl.compiler.source.StringModuleSource;
22 import org.simantics.scl.compiler.source.repository.MapModuleSourceRepository;
23 import org.simantics.scl.compiler.top.ValueNotFound;
24 import org.simantics.scl.runtime.SCLContext;
25 import org.simantics.scl.runtime.reporting.SCLReportingHandler;
26 import org.simantics.scl.runtime.reporting.WriterSCLReportingHandler;
28 public class TestBase {
30 public static final ModuleRepository PRELUDE_MODULE_REPOSITORY = InitialRepository.getInitialRepository();
31 private static final Pattern TEST_SEPARATOR = Pattern.compile("^--+ *$", Pattern.MULTILINE);
32 private static final Charset UTF8 = Charset.forName("UTF-8");
36 public TestBase(String path) {
40 protected void test() {
41 String testModuleName = Thread.currentThread().getStackTrace()[2].getMethodName();
42 String testPath = path + "/" + testModuleName + ".scl";
45 String[] testParts = readTestParts(testPath);
48 ArrayList<String> auxModuleNameList = new ArrayList<String>();
49 while(j < testParts.length) {
50 String part = testParts[j];
51 if(part.startsWith("// module "))
52 auxModuleNameList.add(part.substring(10).split("\\n", 2)[0].trim());
58 String[] moduleNames = new String[mainId+1];
59 String[] moduleTexts = new String[mainId+1];
60 for(int i=0;i<mainId;++i) {
61 moduleNames[i] = auxModuleNameList.get(i);
62 moduleTexts[i] = testParts[i];
64 moduleNames[mainId] = testModuleName;
66 for(;j<testParts.length;j+=2) {
67 moduleTexts[mainId] = testParts[j];
68 String expectedOutput = j+1<testParts.length ? testParts[j+1] : "";
69 String actualOutput = test(moduleNames, moduleTexts);
71 canonicalizeOutput(expectedOutput),
72 canonicalizeOutput(actualOutput));
74 } catch(IOException e) {
75 throw new RuntimeException(e);
76 } catch (ValueNotFound e) {
77 throw new RuntimeException(e);
81 private static String canonicalizeOutput(String text) {
82 return text.trim().replace("\r\n", "\n");
85 protected String test(String[] moduleNames, String[] moduleTexts) throws ValueNotFound {
86 if(moduleNames.length != moduleTexts.length)
87 throw new IllegalArgumentException();
88 /*for(int i=0;i<moduleNames.length;++i) {
89 System.out.println("-- " + moduleNames[i] + " --");
90 System.out.println(moduleTexts[i]);
93 ModuleSource[] moduleSources = new ModuleSource[moduleNames.length];
94 for(int i=0;i<moduleNames.length;++i)
95 moduleSources[i] = new StringModuleSource(
96 moduleNames[i], getClass().getClassLoader(), moduleTexts[i]) {
98 public ImportDeclaration[] getBuiltinImports(UpdateListener listener) {
99 return ImportDeclaration.ONLY_BUILTINS;
102 ModuleRepository testRepository = new ModuleRepository(
103 PRELUDE_MODULE_REPOSITORY,
104 new MapModuleSourceRepository(moduleSources));
105 testRepository.setAdvisor(moduleName -> ModuleCompilationOptions.SILENT);
106 int lastId = moduleNames.length-1;
107 Failable<Module> result = testRepository.getModule(moduleNames[lastId]);
108 if(!result.didSucceed())
109 return ((Failure)result).toString(moduleTexts[lastId]);
111 SCLContext context = SCLContext.getCurrent();
112 StringWriter writer = new StringWriter();
113 Object oldReportingHandler = context.put(SCLReportingHandler.REPORTING_HANDLER, new WriterSCLReportingHandler(writer));
115 Object main = testRepository.getRuntimeModule(moduleNames[lastId]).getResult().getValue("main");
116 writer.write(String.valueOf(main));
117 return writer.toString();
119 context.put(SCLReportingHandler.REPORTING_HANDLER, oldReportingHandler);
124 private String[] readTestParts(String testPath) throws IOException {
125 InputStream stream = getClass().getResourceAsStream(testPath);
127 throw new FileNotFoundException(testPath);
129 byte[] buffer = new byte[1024];
132 int c = stream.read(buffer, pos, buffer.length-pos);
136 if(pos < buffer.length)
138 buffer = Arrays.copyOf(buffer, pos*2);
140 String text = new String(buffer, 0, pos, UTF8);
141 String[] result = TEST_SEPARATOR.split(text);
142 for(int i=1;i<result.length;++i) {
143 if(result[i].startsWith("\r\n"))
144 result[i] = result[i].substring(2);
145 if(result[i].startsWith("\n") || result[i].startsWith("\r"))
146 result[i] = result[i].substring(1);