diff --git a/teavm-classlib/src/main/java/org/teavm/classlibgen/ClasslibTestGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlibgen/ClasslibTestGenerator.java index ecedd8f31..0cef8d25b 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlibgen/ClasslibTestGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlibgen/ClasslibTestGenerator.java @@ -26,6 +26,7 @@ public class ClasslibTestGenerator { private static Renderer renderer; private static List testMethods = new ArrayList<>(); private static Map> groupedMethods = new HashMap<>(); + private static Map fileNames = new HashMap<>(); private static String[] testClasses = { "java.lang.ObjectTests", "java.lang.SystemTests", "java.lang.StringBuilderTests", "java.lang.ClassTests", "java.lang.StringTests", "java.lang.VMTests" }; @@ -33,9 +34,11 @@ public class ClasslibTestGenerator { public static void main(String[] args) throws IOException { outputDir = new File(args[0]); outputDir.mkdirs(); + new File(outputDir, "tests").mkdirs(); resourceToFile("org/teavm/javascript/runtime.js", "runtime.js"); resourceToFile("org/teavm/classlib/junit-support.js", "junit-support.js"); resourceToFile("org/teavm/classlib/junit.css", "junit.css"); + resourceToFile("org/teavm/classlib/junit.html", "junit.html"); classSource = new ClasspathClassHolderSource(); for (int i = 0; i < testClasses.length; ++i) { testClasses[i] = "org.teavm.classlib." + testClasses[i]; @@ -44,21 +47,56 @@ public class ClasslibTestGenerator { ClassHolder classHolder = classSource.getClassHolder(testClass); findTests(classHolder); } - writer.append("runTests = function() {").newLine().indent(); - writer.append("document.getElementById(\"start-button\").style.display = 'none';").newLine(); - for (String testClass : testClasses) { - renderClassTest(classSource.getClassHolder(testClass)); + + File allTestsFile = new File(outputDir, "tests/all.js"); + try (Writer allTestsWriter = new OutputStreamWriter(new FileOutputStream(allTestsFile), "UTF-8")) { + allTestsWriter.write("doRunTests = function() {\n"); + allTestsWriter.write(" new JUnitServer(document.body).runAllTests(["); + boolean first = true; + for (String testClass : testClasses) { + if (!first) { + allTestsWriter.append(","); + } + first = false; + allTestsWriter.append("\n { name : \"").append(testClass).append("\", methods : ["); + boolean firstMethod = true; + for (MethodReference methodRef : groupedMethods.get(testClass)) { + String scriptName = "tests/" + fileNames.size() + ".js"; + fileNames.put(methodRef, scriptName); + if (!firstMethod) { + allTestsWriter.append(","); + } + firstMethod = false; + allTestsWriter.append("\n { name : \"" + methodRef.getName() + "\", script : \"" + + scriptName + "\", expected : ["); + MethodHolder methodHolder = classSource.getClassHolder(testClass).getMethod( + methodRef.getDescriptor()); + AnnotationHolder annot = methodHolder.getAnnotations().get("org.junit.Test"); + AnnotationValue expectedAnnot = annot.getValues().get("expected"); + if (expectedAnnot != null) { + String className = ((ValueType.Object)expectedAnnot.getJavaClass()).getClassName(); + allTestsWriter.append("\"" + className + "\""); + } + allTestsWriter.append("] }"); + } + allTestsWriter.append("] }"); + } + allTestsWriter.write("], function() {}); }"); + } + for (MethodReference method : testMethods) { + System.out.println("Building test for " + method); + decompileClassesForTest(method, fileNames.get(method)); } - writer.outdent().append("}").newLine(); } private static void decompileClassesForTest(MethodReference methodRef, String targetName) throws IOException { + classSource = new ClasspathClassHolderSource(); decompiler = new Decompiler(classSource); - aliasProvider = new MinifyingAliasProvider(); + aliasProvider = new DefaultAliasProvider(); naming = new DefaultNamingStrategy(aliasProvider, classSource); - naming.setMinifying(true); + naming.setMinifying(false); SourceWriterBuilder builder = new SourceWriterBuilder(naming); - builder.setMinified(true); + builder.setMinified(false); writer = builder.build(); renderer = new Renderer(writer, classSource); renderer.renderRuntime(); @@ -67,12 +105,21 @@ public class ClasslibTestGenerator { new MethodDescriptor("", ValueType.VOID)); dependencyChecker.addEntryPoint(cons); dependencyChecker.addEntryPoint(methodRef); + dependencyChecker.attachMethodGraph(new MethodReference("java.lang.Class", new MethodDescriptor("createNew", + ValueType.object("java.lang.Class")))); + dependencyChecker.attachMethodGraph(new MethodReference("java.lang.String", new MethodDescriptor("", + ValueType.arrayOf(ValueType.CHARACTER), ValueType.VOID))); dependencyChecker.checkDependencies(); ListableClassHolderSource classSet = dependencyChecker.cutUnachievableClasses(); ClassSetOptimizer optimizer = new ClassSetOptimizer(); optimizer.optimizeAll(classSet); renderer.renderRuntime(); decompileClasses(classSet.getClassNames()); + writer.append("JUnitClient.run(function() {").softNewLine().indent(); + writer.append("var testObj = ").appendClass(methodRef.getClassName()).append(".") + .appendMethod(cons).append("();").softNewLine(); + writer.append("testObj.").appendMethod(methodRef).append("();").softNewLine(); + writer.outdent().append("});").newLine(); try (Writer out = new OutputStreamWriter(new FileOutputStream(new File(outputDir, targetName)), "UTF-8")) { out.write(writer.toString()); } @@ -85,27 +132,6 @@ public class ClasslibTestGenerator { } } - private static void renderClassTest(ClassHolder cls) { - List methods = groupedMethods.get(cls.getName()); - writer.append("testClass(\"" + cls.getName() + "\", function() {").newLine().indent(); - MethodReference cons = new MethodReference(cls.getName(), new MethodDescriptor("", ValueType.VOID)); - for (MethodReference method : methods) { - writer.append("runTestCase(").appendClass(cls.getName()).append(".").appendMethod(cons) - .append("(), \"" + method.getDescriptor().getName() + "\", \"").appendMethod(method) - .append("\", ["); - MethodHolder methodHolder = classSource.getClassHolder(method.getClassName()).getMethod( - method.getDescriptor()); - AnnotationHolder annot = methodHolder.getAnnotations().get("org.junit.Test"); - AnnotationValue expectedAnnot = annot.getValues().get("expected"); - if (expectedAnnot != null) { - String className = ((ValueType.Object)expectedAnnot.getJavaClass()).getClassName(); - writer.appendClass(className); - } - writer.append("]);").newLine(); - } - writer.outdent().append("})").newLine(); - } - private static void findTests(ClassHolder cls) { for (MethodHolder method : cls.getMethods()) { if (method.getAnnotations().get("org.junit.Test") != null) { diff --git a/teavm-classlib/src/main/resources/org/teavm/classlib/junit-support.js b/teavm-classlib/src/main/resources/org/teavm/classlib/junit-support.js index b155cb754..c716310d0 100644 --- a/teavm-classlib/src/main/resources/org/teavm/classlib/junit-support.js +++ b/teavm-classlib/src/main/resources/org/teavm/classlib/junit-support.js @@ -102,10 +102,26 @@ JUnitServer.prototype.runTest = function(test, callback) { this.timeSpent = 0; this.methodCount = 0; this.createTable(test.name); + var self = this; this.runMethodFromList(test.methods, 0, function() { + self.createFooter(); callback(); }); } +JUnitServer.prototype.runAllTests = function(tests, callback) { + this.runTestFromList(tests, 0, callback); +} +JUnitServer.prototype.runTestFromList = function(tests, index, callback) { + if (index < tests.length) { + var test = tests[index]; + var self = this; + this.runTest(test, function() { + self.runTestFromList(tests, index + 1, callback); + }); + } else { + callback(); + } +} JUnitServer.prototype.runMethodFromList = function(methods, index, callback) { if (index < methods.length) { var method = methods[index]; diff --git a/teavm-classlib/src/main/resources/org/teavm/classlib/junit.html b/teavm-classlib/src/main/resources/org/teavm/classlib/junit.html index eea39474f..d50175346 100644 --- a/teavm-classlib/src/main/resources/org/teavm/classlib/junit.html +++ b/teavm-classlib/src/main/resources/org/teavm/classlib/junit.html @@ -5,7 +5,8 @@ TeaVM JUnit tests - + +