mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Refactoring test compiler
This commit is contained in:
parent
e83d4106d8
commit
90fec4e219
|
@ -16,6 +16,9 @@
|
|||
package org.teavm.tooling;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
/**
|
||||
|
@ -27,12 +30,15 @@ public class TeaVMTestCase {
|
|||
private File runtimeScript;
|
||||
private File testScript;
|
||||
private File debugTable;
|
||||
private List<String> expectedExceptions = new ArrayList<>();
|
||||
|
||||
public TeaVMTestCase(MethodReference testMethod, File runtimeScript, File testScript, File debugTable) {
|
||||
public TeaVMTestCase(MethodReference testMethod, File runtimeScript, File testScript, File debugTable,
|
||||
List<String> expectedExceptions) {
|
||||
this.testMethod = testMethod;
|
||||
this.runtimeScript = runtimeScript;
|
||||
this.testScript = testScript;
|
||||
this.debugTable = debugTable;
|
||||
this.expectedExceptions = Collections.unmodifiableList(new ArrayList<>(expectedExceptions));
|
||||
}
|
||||
|
||||
public MethodReference getTestMethod() {
|
||||
|
@ -50,4 +56,8 @@ public class TeaVMTestCase {
|
|||
public File getDebugTable() {
|
||||
return debugTable;
|
||||
}
|
||||
|
||||
public List<String> getExpectedExceptions() {
|
||||
return expectedExceptions;
|
||||
}
|
||||
}
|
||||
|
|
39
core/src/main/java/org/teavm/tooling/TeaVMTestClass.java
Normal file
39
core/src/main/java/org/teavm/tooling/TeaVMTestClass.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2015 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.tooling;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
class TeaVMTestClass {
|
||||
private String className;
|
||||
private List<TeaVMTestMethod> methods;
|
||||
|
||||
public TeaVMTestClass(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public List<TeaVMTestMethod> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
}
|
49
core/src/main/java/org/teavm/tooling/TeaVMTestMethod.java
Normal file
49
core/src/main/java/org/teavm/tooling/TeaVMTestMethod.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2015 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.tooling;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
class TeaVMTestMethod {
|
||||
private MethodReference method;
|
||||
private String fileName;
|
||||
private List<String> expectedExceptions = new ArrayList<>();
|
||||
|
||||
public TeaVMTestMethod(MethodReference method, String fileName, List<String> expectedExceptions) {
|
||||
this.method = method;
|
||||
this.fileName = fileName;
|
||||
this.expectedExceptions = Collections.unmodifiableList(new ArrayList<>(expectedExceptions));
|
||||
}
|
||||
|
||||
public MethodReference getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public List<String> getExpectedExceptions() {
|
||||
return expectedExceptions;
|
||||
}
|
||||
}
|
|
@ -15,8 +15,16 @@
|
|||
*/
|
||||
package org.teavm.tooling;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.teavm.common.FiniteExecutor;
|
||||
import org.teavm.common.SimpleFiniteExecutor;
|
||||
|
@ -26,7 +34,16 @@ import org.teavm.debugging.information.DebugInformationBuilder;
|
|||
import org.teavm.javascript.EmptyRegularMethodNodeCache;
|
||||
import org.teavm.javascript.InMemoryRegularMethodNodeCache;
|
||||
import org.teavm.javascript.MethodNodeCache;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.model.ClassHolder;
|
||||
import org.teavm.model.ClassHolderSource;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.model.CopyClassHolderSource;
|
||||
import org.teavm.model.InMemoryProgramCache;
|
||||
import org.teavm.model.MethodHolder;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.PreOptimizingClassHolderSource;
|
||||
import org.teavm.model.ProgramCache;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.parsing.ClasspathClassHolderSource;
|
||||
import org.teavm.testing.JUnitTestAdapter;
|
||||
import org.teavm.testing.TestAdapter;
|
||||
|
@ -39,9 +56,6 @@ import org.teavm.vm.TeaVMBuilder;
|
|||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TeaVMTestTool {
|
||||
private Map<String, List<MethodReference>> groupedMethods = new HashMap<>();
|
||||
private Map<MethodReference, String> fileNames = new HashMap<>();
|
||||
private List<MethodReference> testMethods = new ArrayList<>();
|
||||
private File outputDir = new File(".");
|
||||
private boolean minifying = true;
|
||||
private int numThreads = 1;
|
||||
|
@ -62,6 +76,8 @@ public class TeaVMTestTool {
|
|||
private ProgramCache programCache;
|
||||
private SourceFilesCopier sourceFilesCopier;
|
||||
private List<TeaVMTestToolListener> listeners = new ArrayList<>();
|
||||
private List<TeaVMTestClass> testPlan = new ArrayList<>();
|
||||
private int fileIndexGenerator;
|
||||
|
||||
public File getOutputDir() {
|
||||
return outputDir;
|
||||
|
@ -199,58 +215,8 @@ public class TeaVMTestTool {
|
|||
astCache = new InMemoryRegularMethodNodeCache();
|
||||
programCache = new InMemoryProgramCache();
|
||||
}
|
||||
File allTestsFile = new File(outputDir, "tests/all.js");
|
||||
try (Writer allTestsWriter = new OutputStreamWriter(new FileOutputStream(allTestsFile), "UTF-8")) {
|
||||
allTestsWriter.write("prepare = function() {\n");
|
||||
allTestsWriter.write(" return new JUnitServer(document.body).readTests([");
|
||||
boolean first = true;
|
||||
for (String testClass : testClasses) {
|
||||
Collection<MethodReference> methods = groupedMethods.get(testClass);
|
||||
if (methods == null) {
|
||||
continue;
|
||||
}
|
||||
if (!first) {
|
||||
allTestsWriter.append(",");
|
||||
}
|
||||
first = false;
|
||||
allTestsWriter.append("\n { name : \"").append(testClass).append("\", methods : [");
|
||||
boolean firstMethod = true;
|
||||
for (MethodReference methodRef : methods) {
|
||||
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.get(testClass).getMethod(
|
||||
methodRef.getDescriptor());
|
||||
boolean firstException = true;
|
||||
for (String exception : adapter.getExpectedExceptions(methodHolder)) {
|
||||
if (!firstException) {
|
||||
allTestsWriter.append(", ");
|
||||
}
|
||||
firstException = false;
|
||||
allTestsWriter.append("\"" + exception + "\"");
|
||||
}
|
||||
allTestsWriter.append("], additionalScripts : [");
|
||||
for (int i = 0; i < additionalScriptLocalPaths.size(); ++i) {
|
||||
if (i > 0) {
|
||||
allTestsWriter.append(", ");
|
||||
}
|
||||
escapeString(additionalScriptLocalPaths.get(i), allTestsWriter);
|
||||
}
|
||||
allTestsWriter.append("] }");
|
||||
}
|
||||
allTestsWriter.append("] }");
|
||||
}
|
||||
allTestsWriter.write("], function() {}); }");
|
||||
}
|
||||
int methodsGenerated = 0;
|
||||
log.info("Generating test files");
|
||||
sourceFilesCopier = new SourceFilesCopier(sourceFileProviders);
|
||||
sourceFilesCopier.setLog(log);
|
||||
writeMetadata();
|
||||
|
||||
FiniteExecutor executor = new SimpleFiniteExecutor();
|
||||
if (numThreads != 1) {
|
||||
int threads = numThreads != 0 ? numThreads : Runtime.getRuntime().availableProcessors();
|
||||
|
@ -258,20 +224,8 @@ public class TeaVMTestTool {
|
|||
finalizer = () -> threadedExecutor.stop();
|
||||
executor = threadedExecutor;
|
||||
}
|
||||
for (final MethodReference method : testMethods) {
|
||||
final ClassHolderSource builderClassSource = classSource;
|
||||
executor.execute(() -> {
|
||||
log.debug("Building test for " + method);
|
||||
try {
|
||||
decompileClassesForTest(classLoader, new CopyClassHolderSource(builderClassSource), method,
|
||||
fileNames.get(method));
|
||||
} catch (IOException e) {
|
||||
log.error("Error generating JavaScript", e);
|
||||
}
|
||||
});
|
||||
++methodsGenerated;
|
||||
}
|
||||
executor.complete();
|
||||
int methodsGenerated = writeMethods(executor, classSource);
|
||||
|
||||
if (sourceFilesCopied) {
|
||||
sourceFilesCopier.copy(new File(new File(outputDir, "tests"), "src"));
|
||||
}
|
||||
|
@ -285,6 +239,75 @@ public class TeaVMTestTool {
|
|||
}
|
||||
}
|
||||
|
||||
private void writeMetadata() throws IOException {
|
||||
File allTestsFile = new File(outputDir, "tests/all.js");
|
||||
try (Writer allTestsWriter = new OutputStreamWriter(new FileOutputStream(allTestsFile), "UTF-8")) {
|
||||
allTestsWriter.write("prepare = function() {\n");
|
||||
allTestsWriter.write(" return new JUnitServer(document.body).readTests([");
|
||||
boolean first = true;
|
||||
for (TeaVMTestClass testClass : testPlan) {
|
||||
if (!first) {
|
||||
allTestsWriter.append(",");
|
||||
}
|
||||
first = false;
|
||||
allTestsWriter.append("\n { name : \"").append(testClass.getClassName())
|
||||
.append("\", methods : [");
|
||||
boolean firstMethod = true;
|
||||
for (TeaVMTestMethod testMethod : testClass.getMethods()) {
|
||||
String scriptName = testMethod.getFileName();
|
||||
if (!firstMethod) {
|
||||
allTestsWriter.append(",");
|
||||
}
|
||||
firstMethod = false;
|
||||
allTestsWriter.append("\n { name : \"" + testMethod.getMethod().getName()
|
||||
+ "\", script : \"" + scriptName + "\", expected : [");
|
||||
boolean firstException = true;
|
||||
for (String exception : testMethod.getExpectedExceptions()) {
|
||||
if (!firstException) {
|
||||
allTestsWriter.append(", ");
|
||||
}
|
||||
firstException = false;
|
||||
allTestsWriter.append("\"" + exception + "\"");
|
||||
}
|
||||
allTestsWriter.append("], additionalScripts : [");
|
||||
for (int i = 0; i < additionalScriptLocalPaths.size(); ++i) {
|
||||
if (i > 0) {
|
||||
allTestsWriter.append(", ");
|
||||
}
|
||||
escapeString(additionalScriptLocalPaths.get(i), allTestsWriter);
|
||||
}
|
||||
allTestsWriter.append("] }");
|
||||
}
|
||||
allTestsWriter.append("] }");
|
||||
}
|
||||
allTestsWriter.write("], function() {}); }");
|
||||
}
|
||||
}
|
||||
|
||||
private int writeMethods(FiniteExecutor executor, ClassHolderSource classSource) {
|
||||
int methodsGenerated = 0;
|
||||
log.info("Generating test files");
|
||||
sourceFilesCopier = new SourceFilesCopier(sourceFileProviders);
|
||||
sourceFilesCopier.setLog(log);
|
||||
for (TeaVMTestClass testClass : testPlan) {
|
||||
for (TeaVMTestMethod testMethod : testClass.getMethods()) {
|
||||
final ClassHolderSource builderClassSource = classSource;
|
||||
executor.execute(() -> {
|
||||
log.debug("Building test for " + testMethod.getMethod());
|
||||
try {
|
||||
decompileClassesForTest(classLoader, new CopyClassHolderSource(builderClassSource),
|
||||
testMethod);
|
||||
} catch (IOException e) {
|
||||
log.error("Error generating JavaScript", e);
|
||||
}
|
||||
});
|
||||
++methodsGenerated;
|
||||
}
|
||||
}
|
||||
executor.complete();
|
||||
return methodsGenerated;
|
||||
}
|
||||
|
||||
private void resourceToFile(String resource, String fileName) throws IOException {
|
||||
try (InputStream input = TeaVMTestTool.class.getClassLoader().getResourceAsStream(resource)) {
|
||||
try (OutputStream output = new FileOutputStream(new File(outputDir, fileName))) {
|
||||
|
@ -294,18 +317,24 @@ public class TeaVMTestTool {
|
|||
}
|
||||
|
||||
private void findTests(ClassHolder cls) {
|
||||
TeaVMTestClass testClass = new TeaVMTestClass(cls.getName());
|
||||
for (MethodHolder method : cls.getMethods()) {
|
||||
if (adapter.acceptMethod(method)) {
|
||||
MethodReference ref = new MethodReference(cls.getName(), method.getDescriptor());
|
||||
testMethods.add(ref);
|
||||
List<MethodReference> group = groupedMethods.get(cls.getName());
|
||||
if (group == null) {
|
||||
group = new ArrayList<>();
|
||||
groupedMethods.put(cls.getName(), group);
|
||||
String fileName = "tests/" + fileIndexGenerator++ + ".js";
|
||||
|
||||
List<String> exceptions = new ArrayList<>();
|
||||
for (String exception : adapter.getExpectedExceptions(method)) {
|
||||
exceptions.add(exception);
|
||||
}
|
||||
group.add(ref);
|
||||
|
||||
TeaVMTestMethod testMethod = new TeaVMTestMethod(ref, fileName, exceptions);
|
||||
testClass.getMethods().add(testMethod);
|
||||
}
|
||||
}
|
||||
if (!testClass.getMethods().isEmpty()) {
|
||||
testPlan.add(testClass);
|
||||
}
|
||||
}
|
||||
|
||||
private void includeAdditionalScripts(ClassLoader classLoader) throws TeaVMToolException {
|
||||
|
@ -333,7 +362,8 @@ public class TeaVMTestTool {
|
|||
}
|
||||
|
||||
private void decompileClassesForTest(ClassLoader classLoader, ClassHolderSource classSource,
|
||||
MethodReference methodRef, String targetName) throws IOException {
|
||||
TeaVMTestMethod testMethod) throws IOException {
|
||||
String targetName = testMethod.getFileName();
|
||||
TeaVM vm = new TeaVMBuilder()
|
||||
.setClassLoader(classLoader)
|
||||
.setClassSource(classSource)
|
||||
|
@ -349,9 +379,10 @@ public class TeaVMTestTool {
|
|||
vm.add(transformer);
|
||||
}
|
||||
|
||||
File file = new File(outputDir, targetName);
|
||||
File file = new File(outputDir, testMethod.getFileName());
|
||||
DebugInformationBuilder debugInfoBuilder = sourceMapsGenerated || debugInformationGenerated
|
||||
? new DebugInformationBuilder() : null;
|
||||
MethodReference methodRef = testMethod.getMethod();
|
||||
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
||||
MethodReference cons = new MethodReference(methodRef.getClassName(), "<init>", ValueType.VOID);
|
||||
MethodReference exceptionMsg = new MethodReference(ExceptionHelper.class, "showException",
|
||||
|
@ -401,7 +432,7 @@ public class TeaVMTestTool {
|
|||
}
|
||||
|
||||
TeaVMTestCase testCase = new TeaVMTestCase(methodRef, new File(outputDir, "res/runtime.js"),
|
||||
file, debugTableFile);
|
||||
file, debugTableFile, testMethod.getExpectedExceptions());
|
||||
for (TeaVMTestToolListener listener : listeners) {
|
||||
listener.testGenerated(testCase);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user