mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Introduces TestAdapter to make maven plugin be aware of different test
frameworks
This commit is contained in:
parent
301d14e1ab
commit
b48cbc98a4
|
@ -29,7 +29,7 @@
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.10</version>
|
<version>4.10</version>
|
||||||
<scope>test</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 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.testing;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Collections;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.teavm.model.AnnotationReader;
|
||||||
|
import org.teavm.model.AnnotationValue;
|
||||||
|
import org.teavm.model.MethodReader;
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class JUnitTestAdapter implements TestAdapter {
|
||||||
|
@Override
|
||||||
|
public boolean acceptClass(Class<?> cls) {
|
||||||
|
for (Method method : cls.getDeclaredMethods()) {
|
||||||
|
for (Annotation annot : method.getAnnotations()) {
|
||||||
|
if (annot.annotationType().getName().equals(Test.class.getName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean acceptMethod(MethodReader method) {
|
||||||
|
return method.getAnnotations().get(Test.class.getName()) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<String> getExpectedExceptions(MethodReader method) {
|
||||||
|
AnnotationReader annot = method.getAnnotations().get(Test.class.getName());
|
||||||
|
AnnotationValue expectedAnnot = annot.getValue("expected");
|
||||||
|
if (expectedAnnot != null) {
|
||||||
|
String className = ((ValueType.Object)expectedAnnot.getJavaClass()).getClassName();
|
||||||
|
return Collections.singletonList(className);
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
30
teavm-core/src/main/java/org/teavm/testing/TestAdapter.java
Normal file
30
teavm-core/src/main/java/org/teavm/testing/TestAdapter.java
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 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.testing;
|
||||||
|
|
||||||
|
import org.teavm.model.MethodReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public interface TestAdapter {
|
||||||
|
boolean acceptClass(Class<?> cls);
|
||||||
|
|
||||||
|
boolean acceptMethod(MethodReader method);
|
||||||
|
|
||||||
|
Iterable<String> getExpectedExceptions(MethodReader method);
|
||||||
|
}
|
|
@ -48,6 +48,11 @@
|
||||||
<artifactId>teavm-core</artifactId>
|
<artifactId>teavm-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.4</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
package org.teavm.maven;
|
package org.teavm.maven;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
|
@ -33,7 +33,6 @@ import org.apache.maven.plugins.annotations.Mojo;
|
||||||
import org.apache.maven.plugins.annotations.Parameter;
|
import org.apache.maven.plugins.annotations.Parameter;
|
||||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||||
import org.apache.maven.project.MavenProject;
|
import org.apache.maven.project.MavenProject;
|
||||||
import org.junit.Test;
|
|
||||||
import org.teavm.common.FiniteExecutor;
|
import org.teavm.common.FiniteExecutor;
|
||||||
import org.teavm.common.SimpleFiniteExecutor;
|
import org.teavm.common.SimpleFiniteExecutor;
|
||||||
import org.teavm.common.ThreadPoolFiniteExecutor;
|
import org.teavm.common.ThreadPoolFiniteExecutor;
|
||||||
|
@ -42,6 +41,8 @@ import org.teavm.javascript.JavascriptBuilder;
|
||||||
import org.teavm.javascript.JavascriptBuilderFactory;
|
import org.teavm.javascript.JavascriptBuilderFactory;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.parsing.ClasspathClassHolderSource;
|
import org.teavm.parsing.ClasspathClassHolderSource;
|
||||||
|
import org.teavm.testing.JUnitTestAdapter;
|
||||||
|
import org.teavm.testing.TestAdapter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -49,7 +50,7 @@ import org.teavm.parsing.ClasspathClassHolderSource;
|
||||||
*/
|
*/
|
||||||
@Mojo(name = "build-junit", requiresDependencyResolution = ResolutionScope.TEST,
|
@Mojo(name = "build-junit", requiresDependencyResolution = ResolutionScope.TEST,
|
||||||
requiresDependencyCollection = ResolutionScope.TEST)
|
requiresDependencyCollection = ResolutionScope.TEST)
|
||||||
public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
public class BuildJavascriptTestMojo extends AbstractMojo {
|
||||||
private static Set<String> testScopes = new HashSet<>(Arrays.asList(
|
private static Set<String> testScopes = new HashSet<>(Arrays.asList(
|
||||||
Artifact.SCOPE_COMPILE, Artifact.SCOPE_TEST, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME,
|
Artifact.SCOPE_COMPILE, Artifact.SCOPE_TEST, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME,
|
||||||
Artifact.SCOPE_PROVIDED));
|
Artifact.SCOPE_PROVIDED));
|
||||||
|
@ -57,6 +58,7 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
private Map<MethodReference, String> fileNames = new HashMap<>();
|
private Map<MethodReference, String> fileNames = new HashMap<>();
|
||||||
private List<MethodReference> testMethods = new ArrayList<>();
|
private List<MethodReference> testMethods = new ArrayList<>();
|
||||||
private List<String> testClasses = new ArrayList<>();
|
private List<String> testClasses = new ArrayList<>();
|
||||||
|
private TestAdapter adapter;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
private MavenProject project;
|
private MavenProject project;
|
||||||
|
@ -70,12 +72,18 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
@Parameter(defaultValue = "${project.build.testOutputDirectory}")
|
@Parameter(defaultValue = "${project.build.testOutputDirectory}")
|
||||||
private File testFiles;
|
private File testFiles;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
private String[] testFilePatterns = { "*Test", "*UnitTest" };
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private boolean minifying = true;
|
private boolean minifying = true;
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private int numThreads = 1;
|
private int numThreads = 1;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
private Class<? extends TestAdapter> adapterClass = JUnitTestAdapter.class;
|
||||||
|
|
||||||
public void setProject(MavenProject project) {
|
public void setProject(MavenProject project) {
|
||||||
this.project = project;
|
this.project = project;
|
||||||
}
|
}
|
||||||
|
@ -100,9 +108,14 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
this.numThreads = numThreads;
|
this.numThreads = numThreads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAdapterClass(Class<? extends TestAdapter> adapterClass) {
|
||||||
|
this.adapterClass = adapterClass;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||||
Runnable finalizer = null;
|
Runnable finalizer = null;
|
||||||
|
createAdapter();
|
||||||
try {
|
try {
|
||||||
final ClassLoader classLoader = prepareClassLoader();
|
final ClassLoader classLoader = prepareClassLoader();
|
||||||
getLog().info("Searching for tests in the directory `" + testFiles.getAbsolutePath() + "'");
|
getLog().info("Searching for tests in the directory `" + testFiles.getAbsolutePath() + "'");
|
||||||
|
@ -145,11 +158,13 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
scriptName + "\", expected : [");
|
scriptName + "\", expected : [");
|
||||||
MethodHolder methodHolder = classSource.get(testClass).getMethod(
|
MethodHolder methodHolder = classSource.get(testClass).getMethod(
|
||||||
methodRef.getDescriptor());
|
methodRef.getDescriptor());
|
||||||
AnnotationHolder annot = methodHolder.getAnnotations().get("org.junit.Test");
|
boolean firstException = true;
|
||||||
AnnotationValue expectedAnnot = annot.getValues().get("expected");
|
for (String exception : adapter.getExpectedExceptions(methodHolder)) {
|
||||||
if (expectedAnnot != null) {
|
if (!firstException) {
|
||||||
String className = ((ValueType.Object)expectedAnnot.getJavaClass()).getClassName();
|
allTestsWriter.append(", ");
|
||||||
allTestsWriter.append("\"" + className + "\"");
|
}
|
||||||
|
firstException = false;
|
||||||
|
allTestsWriter.append("\"" + exception + "\"");
|
||||||
}
|
}
|
||||||
allTestsWriter.append("] }");
|
allTestsWriter.append("] }");
|
||||||
}
|
}
|
||||||
|
@ -195,6 +210,23 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createAdapter() throws MojoExecutionException {
|
||||||
|
Constructor<? extends TestAdapter> cons;
|
||||||
|
try {
|
||||||
|
cons = adapterClass.getConstructor();
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new MojoExecutionException("No default constructor found for test adapter " +
|
||||||
|
adapterClass.getName(), e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
adapter = cons.newInstance();
|
||||||
|
} catch (IllegalAccessException | InstantiationException e) {
|
||||||
|
throw new MojoExecutionException("Error creating test adapter", e);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
throw new MojoExecutionException("Error creating test adapter", e.getTargetException());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ClassLoader prepareClassLoader() throws MojoExecutionException {
|
private ClassLoader prepareClassLoader() throws MojoExecutionException {
|
||||||
try {
|
try {
|
||||||
Log log = getLog();
|
Log log = getLog();
|
||||||
|
@ -221,7 +253,7 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
urls.add(classFiles.toURI().toURL());
|
urls.add(classFiles.toURI().toURL());
|
||||||
log.info("Using the following classpath for JavaScript JUnit generation: " + classpath);
|
log.info("Using the following classpath for JavaScript JUnit generation: " + classpath);
|
||||||
return new URLClassLoader(urls.toArray(new URL[urls.size()]),
|
return new URLClassLoader(urls.toArray(new URL[urls.size()]),
|
||||||
BuildJavascriptJUnitMojo.class.getClassLoader());
|
BuildJavascriptTestMojo.class.getClassLoader());
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
throw new MojoExecutionException("Error gathering classpath information", e);
|
throw new MojoExecutionException("Error gathering classpath information", e);
|
||||||
}
|
}
|
||||||
|
@ -304,12 +336,6 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findTestClasses(ClassLoader classLoader, File folder, String prefix) {
|
private void findTestClasses(ClassLoader classLoader, File folder, String prefix) {
|
||||||
Class<? extends Annotation> testAnnot;
|
|
||||||
try {
|
|
||||||
testAnnot = Class.forName(Test.class.getName(), true, classLoader).asSubclass(Annotation.class);
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new RuntimeException("Could not load `" + Test.class.getName() + "` annotation");
|
|
||||||
}
|
|
||||||
for (File file : folder.listFiles()) {
|
for (File file : folder.listFiles()) {
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
String newPrefix = prefix.isEmpty() ? file.getName() : prefix + "." + file.getName();
|
String newPrefix = prefix.isEmpty() ? file.getName() : prefix + "." + file.getName();
|
||||||
|
@ -321,14 +347,7 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Class<?> candidate = Class.forName(className, true, classLoader);
|
Class<?> candidate = Class.forName(className, true, classLoader);
|
||||||
boolean hasTests = false;
|
if (adapter.acceptClass(candidate)) {
|
||||||
for (Method method : candidate.getDeclaredMethods()) {
|
|
||||||
if (method.isAnnotationPresent(testAnnot)) {
|
|
||||||
hasTests = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasTests) {
|
|
||||||
testClasses.add(candidate.getName());
|
testClasses.add(candidate.getName());
|
||||||
getLog().info("Test class detected: " + candidate.getName());
|
getLog().info("Test class detected: " + candidate.getName());
|
||||||
}
|
}
|
||||||
|
@ -341,7 +360,7 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
|
|
||||||
private void findTests(ClassHolder cls) {
|
private void findTests(ClassHolder cls) {
|
||||||
for (MethodHolder method : cls.getMethods()) {
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
if (method.getAnnotations().get("org.junit.Test") != null) {
|
if (adapter.acceptMethod(method)) {
|
||||||
MethodReference ref = new MethodReference(cls.getName(), method.getDescriptor());
|
MethodReference ref = new MethodReference(cls.getName(), method.getDescriptor());
|
||||||
testMethods.add(ref);
|
testMethods.add(ref);
|
||||||
List<MethodReference> group = groupedMethods.get(cls.getName());
|
List<MethodReference> group = groupedMethods.get(cls.getName());
|
||||||
|
@ -355,7 +374,7 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resourceToFile(String resource, String fileName) throws IOException {
|
private void resourceToFile(String resource, String fileName) throws IOException {
|
||||||
try (InputStream input = BuildJavascriptJUnitMojo.class.getClassLoader().getResourceAsStream(resource)) {
|
try (InputStream input = BuildJavascriptTestMojo.class.getClassLoader().getResourceAsStream(resource)) {
|
||||||
try (OutputStream output = new FileOutputStream(new File(outputDir, fileName))) {
|
try (OutputStream output = new FileOutputStream(new File(outputDir, fileName))) {
|
||||||
IOUtils.copy(input, output);
|
IOUtils.copy(input, output);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user