mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Refactoring test compiler
This commit is contained in:
parent
e83d4106d8
commit
90fec4e219
|
@ -16,6 +16,9 @@
|
||||||
package org.teavm.tooling;
|
package org.teavm.tooling;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,12 +30,15 @@ public class TeaVMTestCase {
|
||||||
private File runtimeScript;
|
private File runtimeScript;
|
||||||
private File testScript;
|
private File testScript;
|
||||||
private File debugTable;
|
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.testMethod = testMethod;
|
||||||
this.runtimeScript = runtimeScript;
|
this.runtimeScript = runtimeScript;
|
||||||
this.testScript = testScript;
|
this.testScript = testScript;
|
||||||
this.debugTable = debugTable;
|
this.debugTable = debugTable;
|
||||||
|
this.expectedExceptions = Collections.unmodifiableList(new ArrayList<>(expectedExceptions));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodReference getTestMethod() {
|
public MethodReference getTestMethod() {
|
||||||
|
@ -50,4 +56,8 @@ public class TeaVMTestCase {
|
||||||
public File getDebugTable() {
|
public File getDebugTable() {
|
||||||
return debugTable;
|
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;
|
package org.teavm.tooling;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
import java.util.*;
|
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.apache.commons.io.IOUtils;
|
||||||
import org.teavm.common.FiniteExecutor;
|
import org.teavm.common.FiniteExecutor;
|
||||||
import org.teavm.common.SimpleFiniteExecutor;
|
import org.teavm.common.SimpleFiniteExecutor;
|
||||||
|
@ -26,7 +34,16 @@ import org.teavm.debugging.information.DebugInformationBuilder;
|
||||||
import org.teavm.javascript.EmptyRegularMethodNodeCache;
|
import org.teavm.javascript.EmptyRegularMethodNodeCache;
|
||||||
import org.teavm.javascript.InMemoryRegularMethodNodeCache;
|
import org.teavm.javascript.InMemoryRegularMethodNodeCache;
|
||||||
import org.teavm.javascript.MethodNodeCache;
|
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.parsing.ClasspathClassHolderSource;
|
||||||
import org.teavm.testing.JUnitTestAdapter;
|
import org.teavm.testing.JUnitTestAdapter;
|
||||||
import org.teavm.testing.TestAdapter;
|
import org.teavm.testing.TestAdapter;
|
||||||
|
@ -39,9 +56,6 @@ import org.teavm.vm.TeaVMBuilder;
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class TeaVMTestTool {
|
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 File outputDir = new File(".");
|
||||||
private boolean minifying = true;
|
private boolean minifying = true;
|
||||||
private int numThreads = 1;
|
private int numThreads = 1;
|
||||||
|
@ -62,6 +76,8 @@ public class TeaVMTestTool {
|
||||||
private ProgramCache programCache;
|
private ProgramCache programCache;
|
||||||
private SourceFilesCopier sourceFilesCopier;
|
private SourceFilesCopier sourceFilesCopier;
|
||||||
private List<TeaVMTestToolListener> listeners = new ArrayList<>();
|
private List<TeaVMTestToolListener> listeners = new ArrayList<>();
|
||||||
|
private List<TeaVMTestClass> testPlan = new ArrayList<>();
|
||||||
|
private int fileIndexGenerator;
|
||||||
|
|
||||||
public File getOutputDir() {
|
public File getOutputDir() {
|
||||||
return outputDir;
|
return outputDir;
|
||||||
|
@ -199,58 +215,8 @@ public class TeaVMTestTool {
|
||||||
astCache = new InMemoryRegularMethodNodeCache();
|
astCache = new InMemoryRegularMethodNodeCache();
|
||||||
programCache = new InMemoryProgramCache();
|
programCache = new InMemoryProgramCache();
|
||||||
}
|
}
|
||||||
File allTestsFile = new File(outputDir, "tests/all.js");
|
writeMetadata();
|
||||||
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);
|
|
||||||
FiniteExecutor executor = new SimpleFiniteExecutor();
|
FiniteExecutor executor = new SimpleFiniteExecutor();
|
||||||
if (numThreads != 1) {
|
if (numThreads != 1) {
|
||||||
int threads = numThreads != 0 ? numThreads : Runtime.getRuntime().availableProcessors();
|
int threads = numThreads != 0 ? numThreads : Runtime.getRuntime().availableProcessors();
|
||||||
|
@ -258,20 +224,8 @@ public class TeaVMTestTool {
|
||||||
finalizer = () -> threadedExecutor.stop();
|
finalizer = () -> threadedExecutor.stop();
|
||||||
executor = threadedExecutor;
|
executor = threadedExecutor;
|
||||||
}
|
}
|
||||||
for (final MethodReference method : testMethods) {
|
int methodsGenerated = writeMethods(executor, classSource);
|
||||||
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();
|
|
||||||
if (sourceFilesCopied) {
|
if (sourceFilesCopied) {
|
||||||
sourceFilesCopier.copy(new File(new File(outputDir, "tests"), "src"));
|
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 {
|
private void resourceToFile(String resource, String fileName) throws IOException {
|
||||||
try (InputStream input = TeaVMTestTool.class.getClassLoader().getResourceAsStream(resource)) {
|
try (InputStream input = TeaVMTestTool.class.getClassLoader().getResourceAsStream(resource)) {
|
||||||
try (OutputStream output = new FileOutputStream(new File(outputDir, fileName))) {
|
try (OutputStream output = new FileOutputStream(new File(outputDir, fileName))) {
|
||||||
|
@ -294,18 +317,24 @@ public class TeaVMTestTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findTests(ClassHolder cls) {
|
private void findTests(ClassHolder cls) {
|
||||||
|
TeaVMTestClass testClass = new TeaVMTestClass(cls.getName());
|
||||||
for (MethodHolder method : cls.getMethods()) {
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
if (adapter.acceptMethod(method)) {
|
if (adapter.acceptMethod(method)) {
|
||||||
MethodReference ref = new MethodReference(cls.getName(), method.getDescriptor());
|
MethodReference ref = new MethodReference(cls.getName(), method.getDescriptor());
|
||||||
testMethods.add(ref);
|
String fileName = "tests/" + fileIndexGenerator++ + ".js";
|
||||||
List<MethodReference> group = groupedMethods.get(cls.getName());
|
|
||||||
if (group == null) {
|
List<String> exceptions = new ArrayList<>();
|
||||||
group = new ArrayList<>();
|
for (String exception : adapter.getExpectedExceptions(method)) {
|
||||||
groupedMethods.put(cls.getName(), group);
|
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 {
|
private void includeAdditionalScripts(ClassLoader classLoader) throws TeaVMToolException {
|
||||||
|
@ -333,7 +362,8 @@ public class TeaVMTestTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void decompileClassesForTest(ClassLoader classLoader, ClassHolderSource classSource,
|
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()
|
TeaVM vm = new TeaVMBuilder()
|
||||||
.setClassLoader(classLoader)
|
.setClassLoader(classLoader)
|
||||||
.setClassSource(classSource)
|
.setClassSource(classSource)
|
||||||
|
@ -349,9 +379,10 @@ public class TeaVMTestTool {
|
||||||
vm.add(transformer);
|
vm.add(transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
File file = new File(outputDir, targetName);
|
File file = new File(outputDir, testMethod.getFileName());
|
||||||
DebugInformationBuilder debugInfoBuilder = sourceMapsGenerated || debugInformationGenerated
|
DebugInformationBuilder debugInfoBuilder = sourceMapsGenerated || debugInformationGenerated
|
||||||
? new DebugInformationBuilder() : null;
|
? new DebugInformationBuilder() : null;
|
||||||
|
MethodReference methodRef = testMethod.getMethod();
|
||||||
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
||||||
MethodReference cons = new MethodReference(methodRef.getClassName(), "<init>", ValueType.VOID);
|
MethodReference cons = new MethodReference(methodRef.getClassName(), "<init>", ValueType.VOID);
|
||||||
MethodReference exceptionMsg = new MethodReference(ExceptionHelper.class, "showException",
|
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"),
|
TeaVMTestCase testCase = new TeaVMTestCase(methodRef, new File(outputDir, "res/runtime.js"),
|
||||||
file, debugTableFile);
|
file, debugTableFile, testMethod.getExpectedExceptions());
|
||||||
for (TeaVMTestToolListener listener : listeners) {
|
for (TeaVMTestToolListener listener : listeners) {
|
||||||
listener.testGenerated(testCase);
|
listener.testGenerated(testCase);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user