Merge branch 'selenium'
13
.travis.yml
Normal file
|
@ -0,0 +1,13 @@
|
|||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.m2
|
||||
script: >
|
||||
mvn test \
|
||||
-Dteavm.test.skip=false \
|
||||
-Dteavm.test.selenium="http://$SAUCE_USER_NAME:$SAUCE_ACCESS_KEY@ondemand.saucelabs.com:80/wd/hub" \
|
||||
-Dteavm.test.threads=2
|
||||
after_script:
|
||||
- rm -rf $HOME/.m2/repository/org/teavm
|
|
@ -1,6 +1,8 @@
|
|||
TeaVM
|
||||
=====
|
||||
|
||||
[![Build Status](https://travis-ci.org/konsoletyper/teavm.svg?branch=selenium)](https://travis-ci.org/konsoletyper/teavm)
|
||||
|
||||
What is TeaVM?
|
||||
--------------
|
||||
|
||||
|
|
|
@ -45,6 +45,11 @@
|
|||
<artifactId>hppc</artifactId>
|
||||
<version>0.6.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<name>TeaVM core</name>
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package org.teavm.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
|
@ -132,6 +134,7 @@ public class MethodReference {
|
|||
}
|
||||
|
||||
@Override
|
||||
@JsonValue
|
||||
public String toString() {
|
||||
if (reprCache == null) {
|
||||
reprCache = className + "." + name + signatureToString();
|
||||
|
@ -139,6 +142,7 @@ public class MethodReference {
|
|||
return reprCache;
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public static MethodReference parse(String string) {
|
||||
MethodReference reference = parseIfPossible(string);
|
||||
if (reference == null) {
|
||||
|
|
|
@ -74,12 +74,11 @@
|
|||
<execution>
|
||||
<id>generate-javascript-tests</id>
|
||||
<goals>
|
||||
<goal>build-test-javascript</goal>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
<phase>process-test-classes</phase>
|
||||
<configuration>
|
||||
<minifying>false</minifying>
|
||||
<outputDir>${project.build.directory}/javascript-test</outputDir>
|
||||
<targetDirectory>${project.build.directory}/javascript-test</targetDirectory>
|
||||
<debugInformationGenerated>true</debugInformationGenerated>
|
||||
<sourceMapsGenerated>true</sourceMapsGenerated>
|
||||
</configuration>
|
||||
|
@ -87,13 +86,12 @@
|
|||
<execution>
|
||||
<id>generate-javascript-tck</id>
|
||||
<goals>
|
||||
<goal>build-test-javascript</goal>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
<phase>process-test-classes</phase>
|
||||
<configuration>
|
||||
<minifying>false</minifying>
|
||||
<scanDependencies>true</scanDependencies>
|
||||
<outputDir>${project.build.directory}/javascript-tck</outputDir>
|
||||
<targetDirectory>${project.build.directory}/javascript-tck</targetDirectory>
|
||||
<adapterClass>org.teavm.html4j.testing.KOTestAdapter</adapterClass>
|
||||
<transformers>
|
||||
<param>org.teavm.javascript.NullPointerExceptionTransformer</param>
|
||||
|
|
|
@ -21,6 +21,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
|
|||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<artifactId>teavm-jso-apis</artifactId>
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
|
|||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<artifactId>teavm-jso</artifactId>
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
|
|||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<artifactId>teavm-jso-impl</artifactId>
|
||||
|
||||
|
|
|
@ -40,11 +40,6 @@
|
|||
<artifactId>teavm-jso-apis</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-dom</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
|
27
pom.xml
|
@ -69,7 +69,8 @@
|
|||
<html4j.version>1.2</html4j.version>
|
||||
<jetty.version>9.2.1.v20140609</jetty.version>
|
||||
<slf4j.version>1.7.7</slf4j.version>
|
||||
<checker.version>1.9.3</checker.version>
|
||||
<selenium.version>2.47.2</selenium.version>
|
||||
<jackson.version>2.6.2</jackson.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
|
@ -81,6 +82,7 @@
|
|||
<module>html4j</module>
|
||||
<module>samples</module>
|
||||
<module>platform</module>
|
||||
<module>tools/core</module>
|
||||
<module>tools/cli</module>
|
||||
<module>tools/maven</module>
|
||||
<module>tools/chrome-rdp</module>
|
||||
|
@ -166,13 +168,26 @@
|
|||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker</artifactId>
|
||||
<version>${checker.version}</version>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-java</artifactId>
|
||||
<version>${selenium.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-remote-driver</artifactId>
|
||||
<version>${selenium.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
-->
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
|
|
@ -57,9 +57,8 @@
|
|||
<executions>
|
||||
<execution>
|
||||
<id>web-client</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>build-javascript</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||
|
|
|
@ -27,13 +27,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-jso</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-dom</artifactId>
|
||||
<artifactId>teavm-jso-apis</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
@ -111,9 +105,8 @@
|
|||
<executions>
|
||||
<execution>
|
||||
<id>web-client</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>build-javascript</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||
|
|
|
@ -42,12 +42,6 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-dom</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
|
@ -76,9 +70,8 @@
|
|||
<executions>
|
||||
<execution>
|
||||
<id>web-client</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>build-javascript</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-dom</artifactId>
|
||||
<artifactId>teavm-jso-apis</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
@ -92,9 +92,8 @@
|
|||
<executions>
|
||||
<execution>
|
||||
<id>web-client</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>build-javascript</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||
|
|
|
@ -67,9 +67,8 @@
|
|||
<executions>
|
||||
<execution>
|
||||
<id>web-client</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>build-javascript</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||
|
|
|
@ -38,13 +38,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-jso</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-dom</artifactId>
|
||||
<artifactId>teavm-jso-apis</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
@ -78,12 +72,11 @@
|
|||
<id>web-client</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>build-javascript</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||
<mainClass>org.teavm.samples.storage.Application</mainClass>
|
||||
<runtime>SEPARATE</runtime>
|
||||
<minifying>false</minifying>
|
||||
<debugInformationGenerated>true</debugInformationGenerated>
|
||||
<sourceMapsGenerated>true</sourceMapsGenerated>
|
||||
|
|
|
@ -38,13 +38,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-jso</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-dom</artifactId>
|
||||
<artifactId>teavm-jso-apis</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
@ -76,9 +70,8 @@
|
|||
<executions>
|
||||
<execution>
|
||||
<id>web-client</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>build-javascript</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||
|
|
|
@ -27,6 +27,13 @@
|
|||
<name>TeaVM tests</name>
|
||||
<description>Project containing TeaVM tests, as it is impossible to test each module separately</description>
|
||||
|
||||
<properties>
|
||||
<teavm.test.incremental>false</teavm.test.incremental>
|
||||
<teavm.test.threads>1</teavm.test.threads>
|
||||
<teavm.test.selenium></teavm.test.selenium>
|
||||
<teavm.test.skip>true</teavm.test.skip>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
|
@ -72,9 +79,8 @@
|
|||
<execution>
|
||||
<id>generate-javascript-tests</id>
|
||||
<goals>
|
||||
<goal>build-test-javascript</goal>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
<phase>process-test-classes</phase>
|
||||
<configuration>
|
||||
<minifying>false</minifying>
|
||||
<scanDependencies>true</scanDependencies>
|
||||
|
@ -89,6 +95,17 @@
|
|||
<incremental>${teavm.test.incremental}</incremental>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>run-javascript-tests</id>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<skip>${teavm.test.skip}</skip>
|
||||
<numThreads>${teavm.test.threads}</numThreads>
|
||||
<seleniumURL>${teavm.test.selenium}</seleniumURL>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<artifactId>teavm-chrome-rdp</artifactId>
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<artifactId>teavm-cli</artifactId>
|
||||
|
||||
|
@ -30,7 +31,7 @@
|
|||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-core</artifactId>
|
||||
<artifactId>teavm-tooling</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -19,11 +19,17 @@ import java.io.File;
|
|||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import org.apache.commons.cli.*;
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.OptionBuilder;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.cli.PosixParser;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.testing.TestAdapter;
|
||||
import org.teavm.tooling.TeaVMTestTool;
|
||||
import org.teavm.tooling.TeaVMToolException;
|
||||
import org.teavm.tooling.testing.TeaVMTestTool;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -84,7 +90,7 @@ public final class TeaVMTestRunner {
|
|||
}
|
||||
|
||||
TeaVMTestTool tool = new TeaVMTestTool();
|
||||
tool.setOutputDir(new File(commandLine.getOptionValue("d", ".")));
|
||||
tool.setTargetDirectory(new File(commandLine.getOptionValue("d", ".")));
|
||||
tool.setMinifying(commandLine.hasOption("m"));
|
||||
try {
|
||||
tool.setNumThreads(Integer.parseInt(commandLine.getOptionValue("t", "1")));
|
||||
|
|
76
tools/core/pom.xml
Normal file
|
@ -0,0 +1,76 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<artifactId>teavm-tooling</artifactId>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>TeaVM tooling core</name>
|
||||
<description>TeaVM API that helps to create tooling</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<configuration>
|
||||
<configLocation>../../checkstyle.xml</configLocation>
|
||||
<propertyExpansion>config_loc=${basedir}/../..</propertyExpansion>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Export-Package>org.teavm.*</Export-Package>
|
||||
<Bundle-SymbolicName>teavm-tooling</Bundle-SymbolicName>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.tooling.sources.SourceFileProvider;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public interface BaseTeaVMTool {
|
||||
void setTargetDirectory(File targetDirectory);
|
||||
|
||||
void setMinifying(boolean minifying);
|
||||
|
||||
void setIncremental(boolean incremental);
|
||||
|
||||
void setDebugInformationGenerated(boolean debugInformationGenerated);
|
||||
|
||||
void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated);
|
||||
|
||||
void setSourceFilesCopied(boolean sourceFilesCopied);
|
||||
|
||||
Properties getProperties();
|
||||
|
||||
List<ClassHolderTransformer> getTransformers();
|
||||
|
||||
void setLog(TeaVMToolLog log);
|
||||
|
||||
void setClassLoader(ClassLoader classLoader);
|
||||
|
||||
void addSourceFileProvider(SourceFileProvider sourceFileProvider);
|
||||
}
|
|
@ -29,6 +29,8 @@ import org.teavm.diagnostics.ProblemProvider;
|
|||
import org.teavm.javascript.RenderingContext;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.parsing.ClasspathClassHolderSource;
|
||||
import org.teavm.tooling.sources.SourceFileProvider;
|
||||
import org.teavm.tooling.sources.SourceFilesCopier;
|
||||
import org.teavm.vm.*;
|
||||
import org.teavm.vm.spi.AbstractRendererListener;
|
||||
|
||||
|
@ -36,7 +38,7 @@ import org.teavm.vm.spi.AbstractRendererListener;
|
|||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TeaVMTool {
|
||||
public class TeaVMTool implements BaseTeaVMTool {
|
||||
private File targetDirectory = new File(".");
|
||||
private String targetFileName = "classes.js";
|
||||
private boolean minifying = true;
|
||||
|
@ -69,6 +71,7 @@ public class TeaVMTool {
|
|||
return targetDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDirectory(File targetDirectory) {
|
||||
this.targetDirectory = targetDirectory;
|
||||
}
|
||||
|
@ -85,6 +88,7 @@ public class TeaVMTool {
|
|||
return minifying;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMinifying(boolean minifying) {
|
||||
this.minifying = minifying;
|
||||
}
|
||||
|
@ -93,6 +97,7 @@ public class TeaVMTool {
|
|||
return incremental;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIncremental(boolean incremental) {
|
||||
this.incremental = incremental;
|
||||
}
|
||||
|
@ -133,6 +138,7 @@ public class TeaVMTool {
|
|||
return debugInformationGenerated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDebugInformationGenerated(boolean debugInformationGenerated) {
|
||||
this.debugInformationGenerated = debugInformationGenerated;
|
||||
}
|
||||
|
@ -149,6 +155,7 @@ public class TeaVMTool {
|
|||
return sourceMapsFileGenerated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated) {
|
||||
this.sourceMapsFileGenerated = sourceMapsFileGenerated;
|
||||
}
|
||||
|
@ -157,14 +164,17 @@ public class TeaVMTool {
|
|||
return sourceFilesCopied;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourceFilesCopied(boolean sourceFilesCopied) {
|
||||
this.sourceFilesCopied = sourceFilesCopied;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClassHolderTransformer> getTransformers() {
|
||||
return transformers;
|
||||
}
|
||||
|
@ -181,6 +191,7 @@ public class TeaVMTool {
|
|||
return log;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLog(TeaVMToolLog log) {
|
||||
this.log = log;
|
||||
}
|
||||
|
@ -189,6 +200,7 @@ public class TeaVMTool {
|
|||
return classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
@ -245,6 +257,7 @@ public class TeaVMTool {
|
|||
return resources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSourceFileProvider(SourceFileProvider sourceFileProvider) {
|
||||
sourceFileProviders.add(sourceFileProvider);
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.tooling;
|
||||
package org.teavm.tooling.sources;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.tooling;
|
||||
package org.teavm.tooling.sources;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.tooling;
|
||||
package org.teavm.tooling.sources;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.tooling;
|
||||
package org.teavm.tooling.sources;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.tooling;
|
||||
package org.teavm.tooling.sources;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.HashSet;
|
||||
|
@ -23,6 +23,8 @@ import org.apache.commons.io.IOUtils;
|
|||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.ListableClassReaderSource;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.tooling.EmptyTeaVMToolLog;
|
||||
import org.teavm.tooling.TeaVMToolLog;
|
||||
|
||||
/**
|
||||
*
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.tooling;
|
||||
package org.teavm.tooling.testing;
|
||||
|
||||
/**
|
||||
*
|
|
@ -13,10 +13,19 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.tooling;
|
||||
package org.teavm.tooling.testing;
|
||||
|
||||
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 java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.teavm.common.FiniteExecutor;
|
||||
import org.teavm.common.SimpleFiniteExecutor;
|
||||
|
@ -26,10 +35,26 @@ 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;
|
||||
import org.teavm.tooling.BaseTeaVMTool;
|
||||
import org.teavm.tooling.EmptyTeaVMToolLog;
|
||||
import org.teavm.tooling.TeaVMProblemRenderer;
|
||||
import org.teavm.tooling.TeaVMToolException;
|
||||
import org.teavm.tooling.TeaVMToolLog;
|
||||
import org.teavm.tooling.sources.SourceFileProvider;
|
||||
import org.teavm.tooling.sources.SourceFilesCopier;
|
||||
import org.teavm.vm.DirectoryBuildTarget;
|
||||
import org.teavm.vm.TeaVM;
|
||||
import org.teavm.vm.TeaVMBuilder;
|
||||
|
@ -38,10 +63,7 @@ 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<>();
|
||||
public class TeaVMTestTool implements BaseTeaVMTool {
|
||||
private File outputDir = new File(".");
|
||||
private boolean minifying = true;
|
||||
private int numThreads = 1;
|
||||
|
@ -54,19 +76,25 @@ public class TeaVMTestTool {
|
|||
private ClassLoader classLoader = TeaVMTestTool.class.getClassLoader();
|
||||
private TeaVMToolLog log = new EmptyTeaVMToolLog();
|
||||
private boolean debugInformationGenerated;
|
||||
private boolean sourceMapsGenerated;
|
||||
private boolean sourceMapsFileGenerated;
|
||||
private boolean sourceFilesCopied;
|
||||
private boolean incremental;
|
||||
private List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
|
||||
private MethodNodeCache astCache;
|
||||
private ProgramCache programCache;
|
||||
private SourceFilesCopier sourceFilesCopier;
|
||||
private List<TestClassBuilder> testPlan = new ArrayList<>();
|
||||
private int fileIndexGenerator;
|
||||
private long startTime;
|
||||
private int testCount;
|
||||
private AtomicInteger testsBuilt = new AtomicInteger();
|
||||
|
||||
public File getOutputDir() {
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
public void setOutputDir(File outputDir) {
|
||||
@Override
|
||||
public void setTargetDirectory(File outputDir) {
|
||||
this.outputDir = outputDir;
|
||||
}
|
||||
|
||||
|
@ -74,6 +102,7 @@ public class TeaVMTestTool {
|
|||
return minifying;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMinifying(boolean minifying) {
|
||||
this.minifying = minifying;
|
||||
}
|
||||
|
@ -94,6 +123,7 @@ public class TeaVMTestTool {
|
|||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClassHolderTransformer> getTransformers() {
|
||||
return transformers;
|
||||
}
|
||||
|
@ -102,6 +132,7 @@ public class TeaVMTestTool {
|
|||
return additionalScripts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
@ -114,6 +145,7 @@ public class TeaVMTestTool {
|
|||
return classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
@ -122,6 +154,7 @@ public class TeaVMTestTool {
|
|||
return log;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLog(TeaVMToolLog log) {
|
||||
this.log = log;
|
||||
}
|
||||
|
@ -130,6 +163,7 @@ public class TeaVMTestTool {
|
|||
return incremental;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIncremental(boolean incremental) {
|
||||
this.incremental = incremental;
|
||||
}
|
||||
|
@ -138,31 +172,36 @@ public class TeaVMTestTool {
|
|||
return debugInformationGenerated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDebugInformationGenerated(boolean debugInformationGenerated) {
|
||||
this.debugInformationGenerated = debugInformationGenerated;
|
||||
}
|
||||
|
||||
public boolean isSourceMapsGenerated() {
|
||||
return sourceMapsGenerated;
|
||||
public boolean isSourceMapsFileGenerated() {
|
||||
return sourceMapsFileGenerated;
|
||||
}
|
||||
|
||||
public void setSourceMapsGenerated(boolean sourceMapsGenerated) {
|
||||
this.sourceMapsGenerated = sourceMapsGenerated;
|
||||
@Override
|
||||
public void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated) {
|
||||
this.sourceMapsFileGenerated = sourceMapsFileGenerated;
|
||||
}
|
||||
|
||||
public boolean isSourceFilesCopied() {
|
||||
return sourceFilesCopied;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourceFilesCopied(boolean sourceFilesCopied) {
|
||||
this.sourceFilesCopied = sourceFilesCopied;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSourceFileProvider(SourceFileProvider sourceFileProvider) {
|
||||
sourceFileProviders.add(sourceFileProvider);
|
||||
}
|
||||
|
||||
public void generate() throws TeaVMToolException {
|
||||
public TestPlan generate() throws TeaVMToolException {
|
||||
testsBuilt.set(0);
|
||||
Runnable finalizer = null;
|
||||
try {
|
||||
new File(outputDir, "tests").mkdirs();
|
||||
|
@ -184,12 +223,17 @@ public class TeaVMTestTool {
|
|||
if (incremental) {
|
||||
classSource = new PreOptimizingClassHolderSource(classSource);
|
||||
}
|
||||
|
||||
List<TestGroup> groups = new ArrayList<>();
|
||||
for (String testClass : testClasses) {
|
||||
ClassHolder classHolder = classSource.get(testClass);
|
||||
if (classHolder == null) {
|
||||
throw new TeaVMToolException("Could not find class " + testClass);
|
||||
}
|
||||
findTests(classHolder);
|
||||
TestGroup group = findTests(classHolder);
|
||||
if (group != null) {
|
||||
groups.add(group);
|
||||
}
|
||||
}
|
||||
|
||||
includeAdditionalScripts(classLoader);
|
||||
|
@ -198,35 +242,59 @@ public class TeaVMTestTool {
|
|||
astCache = new InMemoryRegularMethodNodeCache();
|
||||
programCache = new InMemoryProgramCache();
|
||||
}
|
||||
writeMetadata();
|
||||
|
||||
FiniteExecutor executor = new SimpleFiniteExecutor();
|
||||
if (numThreads != 1) {
|
||||
int threads = numThreads != 0 ? numThreads : Runtime.getRuntime().availableProcessors();
|
||||
ThreadPoolFiniteExecutor threadedExecutor = new ThreadPoolFiniteExecutor(threads);
|
||||
finalizer = () -> threadedExecutor.stop();
|
||||
executor = threadedExecutor;
|
||||
}
|
||||
startTime = System.currentTimeMillis();
|
||||
int methodsGenerated = writeMethods(executor, classSource);
|
||||
|
||||
if (sourceFilesCopied) {
|
||||
sourceFilesCopier.copy(new File(new File(outputDir, "tests"), "src"));
|
||||
}
|
||||
long timeSpent = System.currentTimeMillis() - startTime;
|
||||
log.info("Test files successfully generated for " + methodsGenerated + " method(s) in "
|
||||
+ (timeSpent / 1000.0) + " seconds.");
|
||||
|
||||
return new TestPlan("res/runtime.js", groups);
|
||||
} catch (IOException e) {
|
||||
throw new TeaVMToolException("IO error occured generating JavaScript files", e);
|
||||
} finally {
|
||||
if (finalizer != null) {
|
||||
finalizer.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 (String testClass : testClasses) {
|
||||
Collection<MethodReference> methods = groupedMethods.get(testClass);
|
||||
if (methods == null) {
|
||||
continue;
|
||||
}
|
||||
for (TestClassBuilder testClass : testPlan) {
|
||||
if (!first) {
|
||||
allTestsWriter.append(",");
|
||||
}
|
||||
first = false;
|
||||
allTestsWriter.append("\n { name : \"").append(testClass).append("\", methods : [");
|
||||
allTestsWriter.append("\n { name : \"").append(testClass.getClassName())
|
||||
.append("\", methods : [");
|
||||
boolean firstMethod = true;
|
||||
for (MethodReference methodRef : methods) {
|
||||
String scriptName = "tests/" + fileNames.size() + ".js";
|
||||
fileNames.put(methodRef, scriptName);
|
||||
for (TestMethodBuilder testMethod : testClass.getMethods()) {
|
||||
String scriptName = testMethod.getFileName();
|
||||
if (!firstMethod) {
|
||||
allTestsWriter.append(",");
|
||||
}
|
||||
firstMethod = false;
|
||||
allTestsWriter.append("\n { name : \"" + methodRef.getName() + "\", script : \""
|
||||
+ scriptName + "\", expected : [");
|
||||
MethodHolder methodHolder = classSource.get(testClass).getMethod(
|
||||
methodRef.getDescriptor());
|
||||
allTestsWriter.append("\n { name : \"" + testMethod.getMethod().getName()
|
||||
+ "\", script : \"" + scriptName + "\", expected : [");
|
||||
boolean firstException = true;
|
||||
for (String exception : adapter.getExpectedExceptions(methodHolder)) {
|
||||
for (String exception : testMethod.getExpectedExceptions()) {
|
||||
if (!firstException) {
|
||||
allTestsWriter.append(", ");
|
||||
}
|
||||
|
@ -246,42 +314,29 @@ public class TeaVMTestTool {
|
|||
}
|
||||
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);
|
||||
FiniteExecutor executor = new SimpleFiniteExecutor();
|
||||
if (numThreads != 1) {
|
||||
int threads = numThreads != 0 ? numThreads : Runtime.getRuntime().availableProcessors();
|
||||
final ThreadPoolFiniteExecutor threadedExecutor = new ThreadPoolFiniteExecutor(threads);
|
||||
finalizer = () -> threadedExecutor.stop();
|
||||
executor = threadedExecutor;
|
||||
}
|
||||
for (final MethodReference method : testMethods) {
|
||||
final ClassHolderSource builderClassSource = classSource;
|
||||
for (TestClassBuilder testClass : testPlan) {
|
||||
for (TestMethodBuilder testMethod : testClass.getMethods()) {
|
||||
executor.execute(() -> {
|
||||
log.debug("Building test for " + method);
|
||||
log.debug("Building test for " + testMethod.getMethod());
|
||||
try {
|
||||
decompileClassesForTest(classLoader, new CopyClassHolderSource(builderClassSource), method,
|
||||
fileNames.get(method));
|
||||
decompileClassesForTest(classLoader, new CopyClassHolderSource(classSource),
|
||||
testMethod);
|
||||
} catch (IOException e) {
|
||||
log.error("Error generating JavaScript", e);
|
||||
}
|
||||
});
|
||||
++methodsGenerated;
|
||||
}
|
||||
}
|
||||
executor.complete();
|
||||
if (sourceFilesCopied) {
|
||||
sourceFilesCopier.copy(new File(new File(outputDir, "tests"), "src"));
|
||||
}
|
||||
log.info("Test files successfully generated for " + methodsGenerated + " method(s).");
|
||||
} catch (IOException e) {
|
||||
throw new TeaVMToolException("IO error occured generating JavaScript files", e);
|
||||
} finally {
|
||||
if (finalizer != null) {
|
||||
finalizer.run();
|
||||
}
|
||||
}
|
||||
return methodsGenerated;
|
||||
}
|
||||
|
||||
private void resourceToFile(String resource, String fileName) throws IOException {
|
||||
|
@ -292,19 +347,34 @@ public class TeaVMTestTool {
|
|||
}
|
||||
}
|
||||
|
||||
private void findTests(ClassHolder cls) {
|
||||
private TestGroup findTests(ClassHolder cls) {
|
||||
List<TestCase> cases = new ArrayList<>();
|
||||
TestClassBuilder testClass = new TestClassBuilder(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);
|
||||
|
||||
TestMethodBuilder testMethod = new TestMethodBuilder(ref, fileName, exceptions);
|
||||
testClass.getMethods().add(testMethod);
|
||||
|
||||
String debugTable = debugInformationGenerated ? testMethod.getFileName() + ".teavmdbg" : null;
|
||||
cases.add(new TestCase(ref.toString(), testMethod.getFileName(), debugTable,
|
||||
testMethod.getExpectedExceptions()));
|
||||
++testCount;
|
||||
}
|
||||
}
|
||||
if (!testClass.getMethods().isEmpty()) {
|
||||
testPlan.add(testClass);
|
||||
return new TestGroup(cls.getName(), cases);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void includeAdditionalScripts(ClassLoader classLoader) throws TeaVMToolException {
|
||||
|
@ -332,7 +402,8 @@ public class TeaVMTestTool {
|
|||
}
|
||||
|
||||
private void decompileClassesForTest(ClassLoader classLoader, ClassHolderSource classSource,
|
||||
MethodReference methodRef, String targetName) throws IOException {
|
||||
TestMethodBuilder testMethod) throws IOException {
|
||||
String targetName = testMethod.getFileName();
|
||||
TeaVM vm = new TeaVMBuilder()
|
||||
.setClassLoader(classLoader)
|
||||
.setClassSource(classSource)
|
||||
|
@ -347,9 +418,11 @@ public class TeaVMTestTool {
|
|||
for (ClassHolderTransformer transformer : transformers) {
|
||||
vm.add(transformer);
|
||||
}
|
||||
File file = new File(outputDir, targetName);
|
||||
DebugInformationBuilder debugInfoBuilder = sourceMapsGenerated || debugInformationGenerated
|
||||
|
||||
File file = new File(outputDir, testMethod.getFileName());
|
||||
DebugInformationBuilder debugInfoBuilder = sourceMapsFileGenerated || 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",
|
||||
|
@ -362,7 +435,7 @@ public class TeaVMTestTool {
|
|||
vm.build(innerWriter, new DirectoryBuildTarget(outputDir));
|
||||
innerWriter.append("\n");
|
||||
innerWriter.append("\nJUnitClient.run();");
|
||||
if (sourceMapsGenerated) {
|
||||
if (sourceMapsFileGenerated) {
|
||||
String sourceMapsFileName = targetName.substring(targetName.lastIndexOf('/') + 1) + ".map";
|
||||
innerWriter.append("\n//# sourceMappingURL=").append(sourceMapsFileName);
|
||||
}
|
||||
|
@ -376,13 +449,16 @@ public class TeaVMTestTool {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (sourceMapsGenerated) {
|
||||
|
||||
if (debugInformationGenerated) {
|
||||
DebugInformation debugInfo = debugInfoBuilder.getDebugInformation();
|
||||
try (OutputStream debugInfoOut = new FileOutputStream(new File(outputDir, targetName + ".teavmdbg"))) {
|
||||
File debugTableFile = new File(outputDir, targetName + ".teavmdbg");
|
||||
try (OutputStream debugInfoOut = new FileOutputStream(debugTableFile)) {
|
||||
debugInfo.write(debugInfoOut);
|
||||
}
|
||||
}
|
||||
if (sourceMapsGenerated) {
|
||||
|
||||
if (sourceMapsFileGenerated) {
|
||||
DebugInformation debugInfo = debugInfoBuilder.getDebugInformation();
|
||||
String sourceMapsFileName = targetName + ".map";
|
||||
try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream(
|
||||
|
@ -393,6 +469,20 @@ public class TeaVMTestTool {
|
|||
if (sourceFilesCopied && vm.getWrittenClasses() != null) {
|
||||
sourceFilesCopier.addClasses(vm.getWrittenClasses());
|
||||
}
|
||||
|
||||
incrementCounter();
|
||||
}
|
||||
|
||||
private void incrementCounter() {
|
||||
int count = testsBuilt.incrementAndGet();
|
||||
if (count % 10 != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
long timeSpent = System.currentTimeMillis() - startTime;
|
||||
|
||||
getLog().info(count + " of " + testCount + " tests built in " + (timeSpent / 1000.0) + " seconds ("
|
||||
+ String.format("%.2f", (double) count / timeSpent * 1000.0) + " tests per second avg.)");
|
||||
}
|
||||
|
||||
private void escapeString(String string, Writer writer) throws IOException {
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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.testing;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public interface TeaVMTestToolListener {
|
||||
void testGenerated(TestCase testCase);
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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.testing;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TestCase {
|
||||
private String testMethod;
|
||||
private String testScript;
|
||||
private String debugTable;
|
||||
private List<String> expectedExceptions = new ArrayList<>();
|
||||
|
||||
@JsonCreator
|
||||
public TestCase(
|
||||
@JsonProperty("testMethod") String testMethod,
|
||||
@JsonProperty("script") String testScript,
|
||||
@JsonProperty("debugTable") String debugTable,
|
||||
@JsonProperty("expectedExceptions") List<String> expectedExceptions) {
|
||||
this.testMethod = testMethod;
|
||||
this.testScript = testScript;
|
||||
this.debugTable = debugTable;
|
||||
this.expectedExceptions = Collections.unmodifiableList(new ArrayList<>(expectedExceptions));
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getTestMethod() {
|
||||
return testMethod;
|
||||
}
|
||||
|
||||
@JsonGetter("script")
|
||||
public String getTestScript() {
|
||||
return testScript;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getDebugTable() {
|
||||
return debugTable;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public List<String> getExpectedExceptions() {
|
||||
return expectedExceptions;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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.testing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
class TestClassBuilder {
|
||||
private String className;
|
||||
private List<TestMethodBuilder> methods = new ArrayList<>();
|
||||
|
||||
public TestClassBuilder(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public List<TestMethodBuilder> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.tooling;
|
||||
package org.teavm.tooling.testing;
|
||||
|
||||
import org.teavm.dependency.AbstractDependencyListener;
|
||||
import org.teavm.dependency.DependencyAgent;
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.tooling;
|
||||
package org.teavm.tooling.testing;
|
||||
|
||||
import org.teavm.vm.spi.TeaVMHost;
|
||||
import org.teavm.vm.spi.TeaVMPlugin;
|
|
@ -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.testing;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TestGroup {
|
||||
private String className;
|
||||
private List<TestCase> testCases;
|
||||
|
||||
@JsonCreator
|
||||
public TestGroup(@JsonProperty("className") String className,
|
||||
@JsonProperty("testCases") List<TestCase> testCases) {
|
||||
this.className = className;
|
||||
this.testCases = Collections.unmodifiableList(new ArrayList<>(testCases));
|
||||
}
|
||||
|
||||
@JsonGetter("className")
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
@JsonGetter("testCases")
|
||||
public List<TestCase> getTestCases() {
|
||||
return testCases;
|
||||
}
|
||||
}
|
|
@ -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.testing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
class TestMethodBuilder {
|
||||
private MethodReference method;
|
||||
private String fileName;
|
||||
private List<String> expectedExceptions = new ArrayList<>();
|
||||
|
||||
public TestMethodBuilder(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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.testing;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TestPlan {
|
||||
private String runtimeScript;
|
||||
private List<TestGroup> groups = new ArrayList<>();
|
||||
|
||||
@JsonCreator
|
||||
public TestPlan(
|
||||
@JsonProperty("runtimeScript") String runtimeScript,
|
||||
@JsonProperty("groups") List<TestGroup> groups) {
|
||||
this.runtimeScript = runtimeScript;
|
||||
this.groups = Collections.unmodifiableList(new ArrayList<>(groups));
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getRuntimeScript() {
|
||||
return runtimeScript;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public List<TestGroup> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 774 B After Width: | Height: | Size: 774 B |
Before Width: | Height: | Size: 297 B After Width: | Height: | Size: 297 B |
Before Width: | Height: | Size: 325 B After Width: | Height: | Size: 325 B |
Before Width: | Height: | Size: 345 B After Width: | Height: | Size: 345 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 321 B After Width: | Height: | Size: 321 B |
Before Width: | Height: | Size: 418 B After Width: | Height: | Size: 418 B |
Before Width: | Height: | Size: 394 B After Width: | Height: | Size: 394 B |
|
@ -39,6 +39,7 @@ Bundle-ClassPath: .,
|
|||
lib/slf4j-api-1.7.7.jar,
|
||||
lib/teavm-chrome-rdp-0.4.0-SNAPSHOT.jar,
|
||||
lib/teavm-core-0.4.0-SNAPSHOT.jar,
|
||||
lib/teavm-tooling-0.4.0-SNAPSHOT.jar,
|
||||
lib/websocket-api-9.2.1.v20140609.jar,
|
||||
lib/websocket-client-9.2.1.v20140609.jar,
|
||||
lib/websocket-common-9.2.1.v20140609.jar,
|
||||
|
@ -70,5 +71,6 @@ Export-Package: org.teavm.cache,
|
|||
org.teavm.resource,
|
||||
org.teavm.testing,
|
||||
org.teavm.tooling,
|
||||
org.teavm.tooling.sources,
|
||||
org.teavm.vm,
|
||||
org.teavm.vm.spi
|
||||
|
|
|
@ -36,6 +36,7 @@ bin.includes = META-INF/,\
|
|||
lib/slf4j-api-1.7.7.jar,\
|
||||
lib/teavm-chrome-rdp-0.4.0-SNAPSHOT.jar,\
|
||||
lib/teavm-core-0.4.0-SNAPSHOT.jar,\
|
||||
lib/teavm-tooling-0.4.0-SNAPSHOT.jar,\
|
||||
lib/websocket-api-9.2.1.v20140609.jar,\
|
||||
lib/websocket-client-9.2.1.v20140609.jar,\
|
||||
lib/websocket-common-9.2.1.v20140609.jar,\
|
||||
|
|
|
@ -79,6 +79,11 @@
|
|||
<artifactId>teavm-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-tooling</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-chrome-rdp</artifactId>
|
||||
|
|
|
@ -4,7 +4,7 @@ Bundle-Name: TeaVM plugin for m2e
|
|||
Bundle-SymbolicName: teavm-eclipse-m2e-plugin;singleton:=true
|
||||
Bundle-Version: 0.4.0.qualifier
|
||||
Bundle-Vendor: Alexey Andreev <konsoletyper@gmail.com>
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Require-Bundle: teavm-eclipse-plugin;bundle-version="[0.4.0,0.5.0)",
|
||||
org.eclipse.m2e.core;bundle-version="[1.3,2)",
|
||||
org.eclipse.core.runtime;bundle-version="[3.8,4.0)",
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<artifactId>teavm-maven-plugin</artifactId>
|
||||
<versionRange>0.4.0-SNAPSHOT</versionRange>
|
||||
<goals>
|
||||
<goal>build-javascript</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</pluginExecutionFilter>
|
||||
<action>
|
||||
|
|
|
@ -33,7 +33,7 @@ public class TeaVMProjectConfigurator extends AbstractProjectConfigurator {
|
|||
private static final String TOOL_ID = "teavm-eclipse-m2e-plugin.tool";
|
||||
private static final String TEAVM_ARTIFACT_ID = "teavm-maven-plugin";
|
||||
private static final String TEAVM_GROUP_ID = "org.teavm";
|
||||
private static final String TEAVM_MAIN_GOAL = "build-javascript";
|
||||
private static final String TEAVM_MAIN_GOAL = "compile";
|
||||
private int executionIdGenerator;
|
||||
private Set<String> usedExecutionIds = new HashSet<>();
|
||||
private IMaven maven;
|
||||
|
|
|
@ -4,7 +4,7 @@ Bundle-Name: TeaVM plugin for Eclipse
|
|||
Bundle-SymbolicName: teavm-eclipse-plugin;singleton:=true
|
||||
Bundle-Version: 0.4.0.qualifier
|
||||
Bundle-Vendor: Alexey Andreev <konsoletyper@gmail.com>
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Bundle-Activator: org.teavm.eclipse.TeaVMEclipsePlugin
|
||||
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.8.0,4.0)",
|
||||
org.eclipse.debug.core;bundle-version="[3.7.0,4.0)",
|
||||
|
@ -48,5 +48,6 @@ Import-Package: org.teavm.cache,
|
|||
org.teavm.resource,
|
||||
org.teavm.testing,
|
||||
org.teavm.tooling,
|
||||
org.teavm.tooling.sources,
|
||||
org.teavm.vm,
|
||||
org.teavm.vm.spi
|
||||
|
|
|
@ -21,22 +21,62 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.*;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.eclipse.core.resources.*;
|
||||
import org.eclipse.core.runtime.*;
|
||||
import org.eclipse.core.resources.IContainer;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IResourceDelta;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.IncrementalProjectBuilder;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.SubProgressMonitor;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.core.variables.IStringVariableManager;
|
||||
import org.eclipse.core.variables.VariablesPlugin;
|
||||
import org.eclipse.jdt.core.*;
|
||||
import org.eclipse.jdt.core.IClasspathEntry;
|
||||
import org.eclipse.jdt.core.ICompilationUnit;
|
||||
import org.eclipse.jdt.core.IJavaElement;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.IMethod;
|
||||
import org.eclipse.jdt.core.IType;
|
||||
import org.eclipse.jdt.core.JavaCore;
|
||||
import org.eclipse.jdt.core.Signature;
|
||||
import org.teavm.callgraph.CallGraph;
|
||||
import org.teavm.callgraph.CallGraphNode;
|
||||
import org.teavm.callgraph.CallSite;
|
||||
import org.teavm.diagnostics.Problem;
|
||||
import org.teavm.diagnostics.ProblemTextConsumer;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.tooling.*;
|
||||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.model.FieldReference;
|
||||
import org.teavm.model.InstructionLocation;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.tooling.ClassAlias;
|
||||
import org.teavm.tooling.RuntimeCopyOperation;
|
||||
import org.teavm.tooling.TeaVMTool;
|
||||
import org.teavm.tooling.TeaVMToolException;
|
||||
import org.teavm.tooling.sources.DirectorySourceFileProvider;
|
||||
import org.teavm.tooling.sources.JarSourceFileProvider;
|
||||
import org.teavm.tooling.sources.SourceFileProvider;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<artifactId>teavm-eclipse</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
|
|
@ -50,13 +50,30 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-core</artifactId>
|
||||
<artifactId>teavm-tooling</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-java</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-remote-driver</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<version>2.18</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
@ -91,6 +108,14 @@
|
|||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<configuration>
|
||||
<configLocation>../../../checkstyle.xml</configLocation>
|
||||
<propertyExpansion>config_loc=${basedir}/../../..</propertyExpansion>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* 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.maven;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import org.apache.maven.artifact.Artifact;
|
||||
import org.apache.maven.artifact.repository.MavenArtifactRepository;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
import org.apache.maven.plugins.annotations.Component;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.apache.maven.repository.RepositorySystem;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.tooling.BaseTeaVMTool;
|
||||
import org.teavm.tooling.sources.SourceFileProvider;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public abstract class AbstractJavascriptMojo extends AbstractMojo {
|
||||
@Component
|
||||
protected MavenProject project;
|
||||
|
||||
@Component
|
||||
protected RepositorySystem repositorySystem;
|
||||
|
||||
@Parameter(required = true, readonly = true, defaultValue = "${localRepository}")
|
||||
protected MavenArtifactRepository localRepository;
|
||||
|
||||
@Parameter(required = true, readonly = true, defaultValue = "${project.remoteArtifactRepositories}")
|
||||
protected List<MavenArtifactRepository> remoteRepositories;
|
||||
|
||||
@Parameter(readonly = true, defaultValue = "${plugin.artifacts}")
|
||||
protected List<Artifact> pluginArtifacts;
|
||||
|
||||
@Parameter(defaultValue = "${project.build.outputDirectory}")
|
||||
protected File classFiles;
|
||||
|
||||
@Parameter
|
||||
protected List<String> compileScopes;
|
||||
|
||||
@Parameter
|
||||
protected boolean minifying = true;
|
||||
|
||||
@Parameter
|
||||
protected String mainClass;
|
||||
|
||||
@Parameter
|
||||
protected Properties properties;
|
||||
|
||||
@Parameter
|
||||
protected boolean debugInformationGenerated;
|
||||
|
||||
@Parameter
|
||||
protected boolean sourceMapsGenerated;
|
||||
|
||||
@Parameter
|
||||
protected boolean sourceFilesCopied;
|
||||
|
||||
@Parameter
|
||||
protected boolean incremental;
|
||||
|
||||
@Parameter
|
||||
protected String[] transformers;
|
||||
|
||||
protected ClassLoader classLoader;
|
||||
|
||||
protected abstract File getTargetDirectory();
|
||||
|
||||
protected final List<ClassHolderTransformer> instantiateTransformers(ClassLoader classLoader)
|
||||
throws MojoExecutionException {
|
||||
List<ClassHolderTransformer> transformerInstances = new ArrayList<>();
|
||||
if (transformers == null) {
|
||||
return transformerInstances;
|
||||
}
|
||||
for (String transformerName : transformers) {
|
||||
Class<?> transformerRawType;
|
||||
try {
|
||||
transformerRawType = Class.forName(transformerName, true, classLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new MojoExecutionException("Transformer not found: " + transformerName, e);
|
||||
}
|
||||
if (!ClassHolderTransformer.class.isAssignableFrom(transformerRawType)) {
|
||||
throw new MojoExecutionException("Transformer " + transformerName + " is not subtype of "
|
||||
+ ClassHolderTransformer.class.getName());
|
||||
}
|
||||
Class<? extends ClassHolderTransformer> transformerType = transformerRawType.asSubclass(
|
||||
ClassHolderTransformer.class);
|
||||
Constructor<? extends ClassHolderTransformer> ctor;
|
||||
try {
|
||||
ctor = transformerType.getConstructor();
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new MojoExecutionException("Transformer " + transformerName + " has no default constructor");
|
||||
}
|
||||
try {
|
||||
ClassHolderTransformer transformer = ctor.newInstance();
|
||||
transformerInstances.add(transformer);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new MojoExecutionException("Error instantiating transformer " + transformerName, e);
|
||||
}
|
||||
}
|
||||
return transformerInstances;
|
||||
}
|
||||
|
||||
protected void setupTool(BaseTeaVMTool tool) throws MojoExecutionException {
|
||||
tool.setLog(new MavenTeaVMToolLog(getLog()));
|
||||
try {
|
||||
ClassLoader classLoader = prepareClassLoader();
|
||||
tool.setClassLoader(classLoader);
|
||||
tool.setMinifying(minifying);
|
||||
tool.setTargetDirectory(getTargetDirectory());
|
||||
tool.getTransformers().addAll(instantiateTransformers(classLoader));
|
||||
if (sourceFilesCopied) {
|
||||
for (SourceFileProvider provider : getSourceFileProviders()) {
|
||||
tool.addSourceFileProvider(provider);
|
||||
}
|
||||
}
|
||||
if (properties != null) {
|
||||
tool.getProperties().putAll(properties);
|
||||
}
|
||||
tool.setIncremental(incremental);
|
||||
tool.setDebugInformationGenerated(debugInformationGenerated);
|
||||
tool.setSourceMapsFileGenerated(sourceMapsGenerated);
|
||||
tool.setSourceFilesCopied(sourceFilesCopied);
|
||||
} catch (RuntimeException e) {
|
||||
throw new MojoExecutionException("Unexpected error occured", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected final ClassLoader prepareClassLoader() throws MojoExecutionException {
|
||||
try {
|
||||
Log log = getLog();
|
||||
log.info("Preparing classpath for JavaScript generation");
|
||||
List<URL> urls = new ArrayList<>();
|
||||
StringBuilder classpath = new StringBuilder();
|
||||
for (Artifact artifact : project.getArtifacts()) {
|
||||
if (!filterByScope(artifact)) {
|
||||
continue;
|
||||
}
|
||||
File file = artifact.getFile();
|
||||
if (classpath.length() > 0) {
|
||||
classpath.append(':');
|
||||
}
|
||||
classpath.append(file.getPath());
|
||||
urls.add(file.toURI().toURL());
|
||||
}
|
||||
if (classpath.length() > 0) {
|
||||
classpath.append(':');
|
||||
}
|
||||
classpath.append(classFiles.getPath());
|
||||
urls.add(classFiles.toURI().toURL());
|
||||
for (File additionalEntry : getAdditionalClassPath()) {
|
||||
classpath.append(':').append(additionalEntry.getPath());
|
||||
urls.add(additionalEntry.toURI().toURL());
|
||||
}
|
||||
log.info("Using the following classpath for JavaScript generation: " + classpath);
|
||||
classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]),
|
||||
AbstractJavascriptMojo.class.getClassLoader());
|
||||
return classLoader;
|
||||
} catch (MalformedURLException e) {
|
||||
throw new MojoExecutionException("Error gathering classpath information", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected List<File> getAdditionalClassPath() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
protected boolean filterByScope(Artifact artifact) {
|
||||
return compileScopes == null ? isSupportedScope(artifact.getScope())
|
||||
: compileScopes.contains(artifact.getScope());
|
||||
}
|
||||
|
||||
protected boolean isSupportedScope(String scope) {
|
||||
switch (scope) {
|
||||
case Artifact.SCOPE_COMPILE:
|
||||
case Artifact.SCOPE_PROVIDED:
|
||||
case Artifact.SCOPE_SYSTEM:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected final List<SourceFileProvider> getSourceFileProviders() {
|
||||
MavenSourceFileProviderLookup lookup = new MavenSourceFileProviderLookup();
|
||||
lookup.setMavenProject(project);
|
||||
lookup.setRepositorySystem(repositorySystem);
|
||||
lookup.setLocalRepository(localRepository);
|
||||
lookup.setRemoteRepositories(remoteRepositories);
|
||||
lookup.setPluginDependencies(pluginArtifacts);
|
||||
return lookup.resolve();
|
||||
}
|
||||
}
|
|
@ -16,96 +16,42 @@
|
|||
package org.teavm.maven;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.*;
|
||||
import org.apache.maven.artifact.Artifact;
|
||||
import org.apache.maven.artifact.repository.MavenArtifactRepository;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import java.util.Arrays;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
import org.apache.maven.plugins.annotations.Component;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.apache.maven.repository.RepositorySystem;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.tooling.*;
|
||||
import org.teavm.tooling.ClassAlias;
|
||||
import org.teavm.tooling.MethodAlias;
|
||||
import org.teavm.tooling.RuntimeCopyOperation;
|
||||
import org.teavm.tooling.TeaVMTool;
|
||||
import org.teavm.tooling.TeaVMToolException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
@Mojo(name = "build-javascript", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME,
|
||||
requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME)
|
||||
public class BuildJavascriptMojo extends AbstractMojo {
|
||||
@Component
|
||||
private MavenProject project;
|
||||
|
||||
@Component
|
||||
private RepositorySystem repositorySystem;
|
||||
|
||||
@Parameter(required = true, readonly = true, defaultValue = "${localRepository}")
|
||||
private MavenArtifactRepository localRepository;
|
||||
|
||||
@Parameter(required = true, readonly = true, defaultValue = "${project.remoteArtifactRepositories}")
|
||||
private List<MavenArtifactRepository> remoteRepositories;
|
||||
|
||||
@Parameter(readonly = true, defaultValue = "${plugin.artifacts}")
|
||||
private List<Artifact> pluginArtifacts;
|
||||
|
||||
@Mojo(name = "compile", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME,
|
||||
requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME,
|
||||
defaultPhase = LifecyclePhase.PROCESS_CLASSES)
|
||||
public class BuildJavascriptMojo extends AbstractJavascriptMojo {
|
||||
@Parameter(defaultValue = "${project.build.directory}/javascript")
|
||||
private File targetDirectory;
|
||||
|
||||
@Parameter(defaultValue = "${project.build.outputDirectory}")
|
||||
private File classFiles;
|
||||
|
||||
@Parameter
|
||||
private List<String> compileScopes;
|
||||
|
||||
@Parameter
|
||||
private String targetFileName = "classes.js";
|
||||
|
||||
@Parameter
|
||||
private boolean minifying = true;
|
||||
|
||||
@Parameter
|
||||
private String mainClass;
|
||||
|
||||
@Parameter
|
||||
private RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE;
|
||||
|
||||
@Parameter
|
||||
private Properties properties;
|
||||
|
||||
@Parameter
|
||||
private boolean mainPageIncluded;
|
||||
|
||||
@Parameter
|
||||
private boolean bytecodeLogging;
|
||||
|
||||
@Parameter
|
||||
private boolean debugInformationGenerated;
|
||||
|
||||
@Parameter
|
||||
private boolean sourceMapsGenerated;
|
||||
|
||||
@Parameter
|
||||
private boolean sourceFilesCopied;
|
||||
|
||||
@Parameter
|
||||
private boolean incremental;
|
||||
|
||||
@Parameter(defaultValue = "${project.build.directory}/teavm-cache")
|
||||
private File cacheDirectory;
|
||||
|
||||
@Parameter
|
||||
private String[] transformers;
|
||||
|
||||
@Parameter
|
||||
private ClassAlias[] classAliases;
|
||||
|
||||
|
@ -115,144 +61,37 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
|||
@Parameter
|
||||
private boolean stopOnErrors = true;
|
||||
|
||||
@Parameter
|
||||
protected RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE;
|
||||
|
||||
@Parameter(defaultValue = "${project.build.directory}/teavm-cache")
|
||||
protected File cacheDirectory;
|
||||
|
||||
private TeaVMTool tool = new TeaVMTool();
|
||||
|
||||
public void setProject(MavenProject project) {
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
public void setTargetDirectory(File targetDirectory) {
|
||||
this.targetDirectory = targetDirectory;
|
||||
}
|
||||
|
||||
public void setTargetFileName(String targetFileName) {
|
||||
this.targetFileName = targetFileName;
|
||||
}
|
||||
|
||||
public void setClassFiles(File classFiles) {
|
||||
this.classFiles = classFiles;
|
||||
}
|
||||
|
||||
public void setMinifying(boolean minifying) {
|
||||
this.minifying = minifying;
|
||||
}
|
||||
|
||||
public void setBytecodeLogging(boolean bytecodeLogging) {
|
||||
this.bytecodeLogging = bytecodeLogging;
|
||||
}
|
||||
|
||||
public void setRuntimeCopy(RuntimeCopyOperation runtimeCopy) {
|
||||
this.runtime = runtimeCopy;
|
||||
}
|
||||
|
||||
public void setMainPageIncluded(boolean mainPageIncluded) {
|
||||
this.mainPageIncluded = mainPageIncluded;
|
||||
}
|
||||
|
||||
public String[] getTransformers() {
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public void setTransformers(String[] transformers) {
|
||||
this.transformers = transformers;
|
||||
}
|
||||
|
||||
public void setProperties(Properties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public void setClassAliases(ClassAlias[] classAliases) {
|
||||
this.classAliases = classAliases;
|
||||
}
|
||||
|
||||
public void setMethodAliases(MethodAlias[] methodAliases) {
|
||||
this.methodAliases = methodAliases;
|
||||
}
|
||||
|
||||
public boolean isDebugInformationGenerated() {
|
||||
return debugInformationGenerated;
|
||||
}
|
||||
|
||||
public void setDebugInformationGenerated(boolean debugInformationGenerated) {
|
||||
this.debugInformationGenerated = debugInformationGenerated;
|
||||
}
|
||||
|
||||
public boolean isSourceMapsGenerated() {
|
||||
return sourceMapsGenerated;
|
||||
}
|
||||
|
||||
public void setSourceMapsGenerated(boolean sourceMapsGenerated) {
|
||||
this.sourceMapsGenerated = sourceMapsGenerated;
|
||||
}
|
||||
|
||||
public boolean isSourceFilesCopied() {
|
||||
return sourceFilesCopied;
|
||||
}
|
||||
|
||||
public void setSourceFilesCopied(boolean sourceFilesCopied) {
|
||||
this.sourceFilesCopied = sourceFilesCopied;
|
||||
}
|
||||
|
||||
public boolean isIncremental() {
|
||||
return incremental;
|
||||
}
|
||||
|
||||
public void setIncremental(boolean incremental) {
|
||||
this.incremental = incremental;
|
||||
}
|
||||
|
||||
public void setStopOnErrors(boolean stopOnErrors) {
|
||||
this.stopOnErrors = stopOnErrors;
|
||||
}
|
||||
|
||||
public File getCacheDirectory() {
|
||||
return cacheDirectory;
|
||||
}
|
||||
|
||||
public void setCacheDirectory(File cacheDirectory) {
|
||||
this.cacheDirectory = cacheDirectory;
|
||||
@Override
|
||||
protected File getTargetDirectory() {
|
||||
return targetDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException {
|
||||
Log log = getLog();
|
||||
setupTool(tool);
|
||||
tool.setLog(new MavenTeaVMToolLog(log));
|
||||
try {
|
||||
ClassLoader classLoader = prepareClassLoader();
|
||||
tool.setClassLoader(classLoader);
|
||||
tool.setBytecodeLogging(bytecodeLogging);
|
||||
tool.setMainClass(mainClass);
|
||||
tool.setMainPageIncluded(mainPageIncluded);
|
||||
tool.setMinifying(minifying);
|
||||
tool.setRuntime(runtime);
|
||||
tool.setTargetDirectory(targetDirectory);
|
||||
tool.setTargetFileName(targetFileName);
|
||||
tool.getTransformers().addAll(instantiateTransformers(classLoader));
|
||||
if (sourceFilesCopied) {
|
||||
MavenSourceFileProviderLookup lookup = new MavenSourceFileProviderLookup();
|
||||
lookup.setMavenProject(project);
|
||||
lookup.setRepositorySystem(repositorySystem);
|
||||
lookup.setLocalRepository(localRepository);
|
||||
lookup.setRemoteRepositories(remoteRepositories);
|
||||
lookup.setPluginDependencies(pluginArtifacts);
|
||||
for (SourceFileProvider provider : lookup.resolve()) {
|
||||
tool.addSourceFileProvider(provider);
|
||||
}
|
||||
}
|
||||
if (classAliases != null) {
|
||||
tool.getClassAliases().addAll(Arrays.asList(classAliases));
|
||||
}
|
||||
if (methodAliases != null) {
|
||||
tool.getMethodAliases().addAll(Arrays.asList(methodAliases));
|
||||
}
|
||||
if (properties != null) {
|
||||
tool.getProperties().putAll(properties);
|
||||
}
|
||||
tool.setCacheDirectory(cacheDirectory);
|
||||
tool.setIncremental(incremental);
|
||||
tool.setDebugInformationGenerated(debugInformationGenerated);
|
||||
tool.setSourceMapsFileGenerated(sourceMapsGenerated);
|
||||
tool.setSourceFilesCopied(sourceFilesCopied);
|
||||
tool.generate();
|
||||
if (stopOnErrors && !tool.getProblemProvider().getSevereProblems().isEmpty()) {
|
||||
throw new MojoExecutionException("Build error");
|
||||
|
@ -263,75 +102,4 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
|||
throw new MojoExecutionException("IO error occured", e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ClassHolderTransformer> instantiateTransformers(ClassLoader classLoader)
|
||||
throws MojoExecutionException {
|
||||
List<ClassHolderTransformer> transformerInstances = new ArrayList<>();
|
||||
if (transformers == null) {
|
||||
return transformerInstances;
|
||||
}
|
||||
for (String transformerName : transformers) {
|
||||
Class<?> transformerRawType;
|
||||
try {
|
||||
transformerRawType = Class.forName(transformerName, true, classLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new MojoExecutionException("Transformer not found: " + transformerName, e);
|
||||
}
|
||||
if (!ClassHolderTransformer.class.isAssignableFrom(transformerRawType)) {
|
||||
throw new MojoExecutionException("Transformer " + transformerName + " is not subtype of " +
|
||||
ClassHolderTransformer.class.getName());
|
||||
}
|
||||
Class<? extends ClassHolderTransformer> transformerType = transformerRawType.asSubclass(
|
||||
ClassHolderTransformer.class);
|
||||
Constructor<? extends ClassHolderTransformer> ctor;
|
||||
try {
|
||||
ctor = transformerType.getConstructor();
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new MojoExecutionException("Transformer " + transformerName + " has no default constructor");
|
||||
}
|
||||
try {
|
||||
ClassHolderTransformer transformer = ctor.newInstance();
|
||||
transformerInstances.add(transformer);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new MojoExecutionException("Error instantiating transformer " + transformerName, e);
|
||||
}
|
||||
}
|
||||
return transformerInstances;
|
||||
}
|
||||
|
||||
private ClassLoader prepareClassLoader() throws MojoExecutionException {
|
||||
try {
|
||||
Log log = getLog();
|
||||
log.info("Preparing classpath for JavaScript generation");
|
||||
List<URL> urls = new ArrayList<>();
|
||||
StringBuilder classpath = new StringBuilder();
|
||||
Set<String> scopes;
|
||||
if (compileScopes == null) {
|
||||
scopes = new HashSet<>(Arrays.asList(
|
||||
Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_SYSTEM));
|
||||
} else {
|
||||
scopes = new HashSet<>(compileScopes);
|
||||
}
|
||||
for (Artifact artifact : project.getArtifacts()) {
|
||||
if (!scopes.contains(artifact.getScope())) {
|
||||
continue;
|
||||
}
|
||||
File file = artifact.getFile();
|
||||
if (classpath.length() > 0) {
|
||||
classpath.append(':');
|
||||
}
|
||||
classpath.append(file.getPath());
|
||||
urls.add(file.toURI().toURL());
|
||||
}
|
||||
if (classpath.length() > 0) {
|
||||
classpath.append(':');
|
||||
}
|
||||
classpath.append(classFiles.getPath());
|
||||
urls.add(classFiles.toURI().toURL());
|
||||
log.info("Using the following classpath for JavaScript generation: " + classpath);
|
||||
return new URLClassLoader(urls.toArray(new URL[urls.size()]), BuildJavascriptMojo.class.getClassLoader());
|
||||
} catch (MalformedURLException e) {
|
||||
throw new MojoExecutionException("Error gathering classpath information", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,67 +15,50 @@
|
|||
*/
|
||||
package org.teavm.maven;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.maven.artifact.Artifact;
|
||||
import org.apache.maven.artifact.repository.MavenArtifactRepository;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
import org.apache.maven.plugins.annotations.Component;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.apache.maven.repository.RepositorySystem;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.testing.JUnitTestAdapter;
|
||||
import org.teavm.testing.TestAdapter;
|
||||
import org.teavm.tooling.SourceFileProvider;
|
||||
import org.teavm.tooling.TeaVMTestTool;
|
||||
import org.teavm.tooling.TeaVMToolException;
|
||||
import org.teavm.tooling.testing.TeaVMTestTool;
|
||||
import org.teavm.tooling.testing.TestPlan;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
@Mojo(name = "build-test-javascript", requiresDependencyResolution = ResolutionScope.TEST,
|
||||
requiresDependencyCollection = ResolutionScope.TEST)
|
||||
public class BuildJavascriptTestMojo extends AbstractMojo {
|
||||
@Mojo(name = "testCompile", requiresDependencyResolution = ResolutionScope.TEST,
|
||||
requiresDependencyCollection = ResolutionScope.TEST,
|
||||
defaultPhase = LifecyclePhase.PROCESS_TEST_CLASSES)
|
||||
public class BuildJavascriptTestMojo extends AbstractJavascriptMojo {
|
||||
private static Set<String> testScopes = new HashSet<>(Arrays.asList(
|
||||
Artifact.SCOPE_COMPILE, Artifact.SCOPE_TEST, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME,
|
||||
Artifact.SCOPE_PROVIDED));
|
||||
|
||||
@Component
|
||||
private MavenProject project;
|
||||
|
||||
@Component
|
||||
private RepositorySystem repositorySystem;
|
||||
|
||||
@Parameter(required = true, readonly = true, defaultValue = "${localRepository}")
|
||||
private MavenArtifactRepository localRepository;
|
||||
|
||||
@Parameter(required = true, readonly = true, defaultValue = "${project.remoteArtifactRepositories}")
|
||||
private List<MavenArtifactRepository> remoteRepositories;
|
||||
|
||||
@Parameter(readonly = true, defaultValue = "${plugin.artifacts}")
|
||||
private List<Artifact> pluginArtifacts;
|
||||
|
||||
@Parameter(defaultValue = "${project.build.directory}/javascript-test")
|
||||
private File outputDir;
|
||||
|
||||
@Parameter(defaultValue = "${project.build.outputDirectory}")
|
||||
private File classFiles;
|
||||
private File targetDirectory;
|
||||
|
||||
@Parameter(defaultValue = "${project.build.testOutputDirectory}")
|
||||
private File testFiles;
|
||||
|
@ -86,9 +69,6 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
|||
@Parameter
|
||||
private String[] excludeWildcards = new String[0];
|
||||
|
||||
@Parameter
|
||||
private boolean minifying = true;
|
||||
|
||||
@Parameter
|
||||
private boolean scanDependencies;
|
||||
|
||||
|
@ -98,153 +78,47 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
|||
@Parameter
|
||||
private String adapterClass = JUnitTestAdapter.class.getName();
|
||||
|
||||
@Parameter
|
||||
private String[] transformers;
|
||||
|
||||
@Parameter
|
||||
private String[] additionalScripts;
|
||||
|
||||
@Parameter
|
||||
private Properties properties;
|
||||
|
||||
@Parameter
|
||||
private boolean incremental;
|
||||
|
||||
@Parameter
|
||||
private boolean debugInformationGenerated;
|
||||
|
||||
@Parameter
|
||||
private boolean sourceMapsGenerated;
|
||||
|
||||
@Parameter
|
||||
private boolean sourceFilesCopied;
|
||||
|
||||
private TeaVMTestTool tool = new TeaVMTestTool();
|
||||
|
||||
public void setProject(MavenProject project) {
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
public void setOutputDir(File outputDir) {
|
||||
this.outputDir = outputDir;
|
||||
}
|
||||
|
||||
public void setClassFiles(File classFiles) {
|
||||
this.classFiles = classFiles;
|
||||
}
|
||||
|
||||
public void setTestFiles(File testFiles) {
|
||||
this.testFiles = testFiles;
|
||||
}
|
||||
|
||||
public void setMinifying(boolean minifying) {
|
||||
this.minifying = minifying;
|
||||
}
|
||||
|
||||
public void setNumThreads(int numThreads) {
|
||||
this.numThreads = numThreads;
|
||||
}
|
||||
|
||||
public void setAdapterClass(String adapterClass) {
|
||||
this.adapterClass = adapterClass;
|
||||
}
|
||||
|
||||
public void setWildcards(String[] wildcards) {
|
||||
this.wildcards = wildcards;
|
||||
}
|
||||
|
||||
public void setExcludeWildcards(String[] excludeWildcards) {
|
||||
this.excludeWildcards = excludeWildcards;
|
||||
}
|
||||
|
||||
public String[] getTransformers() {
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public void setTransformers(String[] transformers) {
|
||||
this.transformers = transformers;
|
||||
}
|
||||
|
||||
public void setProperties(Properties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public void setIncremental(boolean incremental) {
|
||||
this.incremental = incremental;
|
||||
}
|
||||
|
||||
public boolean isDebugInformationGenerated() {
|
||||
return debugInformationGenerated;
|
||||
}
|
||||
|
||||
public void setDebugInformationGenerated(boolean debugInformationGenerated) {
|
||||
this.debugInformationGenerated = debugInformationGenerated;
|
||||
}
|
||||
|
||||
public boolean isSourceMapsGenerated() {
|
||||
return sourceMapsGenerated;
|
||||
}
|
||||
|
||||
public void setSourceMapsGenerated(boolean sourceMapsGenerated) {
|
||||
this.sourceMapsGenerated = sourceMapsGenerated;
|
||||
}
|
||||
|
||||
public boolean isSourceFilesCopied() {
|
||||
return sourceFilesCopied;
|
||||
}
|
||||
|
||||
public void setSourceFilesCopied(boolean sourceFilesCopied) {
|
||||
this.sourceFilesCopied = sourceFilesCopied;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||
if (System.getProperty("maven.test.skip", "false").equals("true") ||
|
||||
System.getProperty("skipTests") != null) {
|
||||
if (System.getProperty("maven.test.skip", "false").equals("true")
|
||||
|| System.getProperty("skipTests") != null) {
|
||||
getLog().info("Tests build skipped as specified by system property");
|
||||
return;
|
||||
}
|
||||
|
||||
setupTool(tool);
|
||||
try {
|
||||
final ClassLoader classLoader = prepareClassLoader();
|
||||
getLog().info("Searching for tests in the directory `" + testFiles.getAbsolutePath() + "'");
|
||||
tool.setClassLoader(classLoader);
|
||||
tool.setAdapter(createAdapter(classLoader));
|
||||
findTestClasses(classLoader, testFiles, "");
|
||||
if (scanDependencies) {
|
||||
findTestsInDependencies(classLoader);
|
||||
}
|
||||
tool.getTransformers().addAll(instantiateTransformers(classLoader));
|
||||
tool.setLog(new MavenTeaVMToolLog(getLog()));
|
||||
tool.setOutputDir(outputDir);
|
||||
tool.setNumThreads(numThreads);
|
||||
tool.setMinifying(minifying);
|
||||
tool.setIncremental(incremental);
|
||||
tool.setDebugInformationGenerated(debugInformationGenerated);
|
||||
tool.setSourceMapsGenerated(sourceMapsGenerated);
|
||||
tool.setSourceFilesCopied(sourceFilesCopied);
|
||||
if (sourceFilesCopied) {
|
||||
MavenSourceFileProviderLookup lookup = new MavenSourceFileProviderLookup();
|
||||
lookup.setMavenProject(project);
|
||||
lookup.setRepositorySystem(repositorySystem);
|
||||
lookup.setLocalRepository(localRepository);
|
||||
lookup.setRemoteRepositories(remoteRepositories);
|
||||
lookup.setPluginDependencies(pluginArtifacts);
|
||||
for (SourceFileProvider provider : lookup.resolve()) {
|
||||
tool.addSourceFileProvider(provider);
|
||||
}
|
||||
}
|
||||
if (properties != null) {
|
||||
tool.getProperties().putAll(properties);
|
||||
}
|
||||
if (additionalScripts != null) {
|
||||
tool.getAdditionalScripts().addAll(Arrays.asList(additionalScripts));
|
||||
}
|
||||
tool.generate();
|
||||
writePlan(tool.generate());
|
||||
} catch (TeaVMToolException e) {
|
||||
throw new MojoFailureException("Error occured generating JavaScript files", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void writePlan(TestPlan plan) throws MojoExecutionException {
|
||||
File file = new File(targetDirectory, "plan.json");
|
||||
try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.writeValue(writer, plan);
|
||||
} catch (IOException e) {
|
||||
throw new MojoExecutionException("Error writing test plan", e);
|
||||
}
|
||||
}
|
||||
|
||||
private TestAdapter createAdapter(ClassLoader classLoader) throws MojoExecutionException {
|
||||
Class<?> adapterClsRaw;
|
||||
try {
|
||||
|
@ -253,8 +127,8 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
|||
throw new MojoExecutionException("Adapter not found: " + adapterClass, e);
|
||||
}
|
||||
if (!TestAdapter.class.isAssignableFrom(adapterClsRaw)) {
|
||||
throw new MojoExecutionException("Adapter " + adapterClass + " does not implement " +
|
||||
TestAdapter.class.getName());
|
||||
throw new MojoExecutionException("Adapter " + adapterClass + " does not implement "
|
||||
+ TestAdapter.class.getName());
|
||||
}
|
||||
Class<? extends TestAdapter> adapterCls = adapterClsRaw.asSubclass(TestAdapter.class);
|
||||
Constructor<? extends TestAdapter> cons;
|
||||
|
@ -272,38 +146,6 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
|||
}
|
||||
}
|
||||
|
||||
private ClassLoader prepareClassLoader() throws MojoExecutionException {
|
||||
try {
|
||||
Log log = getLog();
|
||||
log.info("Preparing classpath for JavaScript test generation");
|
||||
List<URL> urls = new ArrayList<>();
|
||||
StringBuilder classpath = new StringBuilder();
|
||||
for (Artifact artifact : project.getArtifacts()) {
|
||||
if (!testScopes.contains(artifact.getScope())) {
|
||||
continue;
|
||||
}
|
||||
File file = artifact.getFile();
|
||||
if (classpath.length() > 0) {
|
||||
classpath.append(':');
|
||||
}
|
||||
classpath.append(file.getPath());
|
||||
urls.add(file.toURI().toURL());
|
||||
}
|
||||
if (classpath.length() > 0) {
|
||||
classpath.append(':');
|
||||
}
|
||||
classpath.append(testFiles.getPath());
|
||||
urls.add(testFiles.toURI().toURL());
|
||||
classpath.append(':').append(classFiles.getPath());
|
||||
urls.add(classFiles.toURI().toURL());
|
||||
log.info("Using the following classpath for JavaScript test generation: " + classpath);
|
||||
return new URLClassLoader(urls.toArray(new URL[urls.size()]),
|
||||
BuildJavascriptTestMojo.class.getClassLoader());
|
||||
} catch (MalformedURLException e) {
|
||||
throw new MojoExecutionException("Error gathering classpath information", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void findTestsInDependencies(ClassLoader classLoader) throws MojoExecutionException {
|
||||
try {
|
||||
Log log = getLog();
|
||||
|
@ -384,39 +226,18 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected File getTargetDirectory() {
|
||||
return targetDirectory;
|
||||
}
|
||||
|
||||
private List<ClassHolderTransformer> instantiateTransformers(ClassLoader classLoader)
|
||||
throws MojoExecutionException {
|
||||
List<ClassHolderTransformer> transformerInstances = new ArrayList<>();
|
||||
if (transformers == null) {
|
||||
return transformerInstances;
|
||||
@Override
|
||||
protected List<File> getAdditionalClassPath() {
|
||||
return Arrays.asList(testFiles);
|
||||
}
|
||||
for (String transformerName : transformers) {
|
||||
Class<?> transformerRawType;
|
||||
try {
|
||||
transformerRawType = Class.forName(transformerName, true, classLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new MojoExecutionException("Transformer not found: " + transformerName, e);
|
||||
}
|
||||
if (!ClassHolderTransformer.class.isAssignableFrom(transformerRawType)) {
|
||||
throw new MojoExecutionException("Transformer " + transformerName + " is not subtype of " +
|
||||
ClassHolderTransformer.class.getName());
|
||||
}
|
||||
Class<? extends ClassHolderTransformer> transformerType = transformerRawType.asSubclass(
|
||||
ClassHolderTransformer.class);
|
||||
Constructor<? extends ClassHolderTransformer> ctor;
|
||||
try {
|
||||
ctor = transformerType.getConstructor();
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new MojoExecutionException("Transformer " + transformerName + " has no default constructor");
|
||||
}
|
||||
try {
|
||||
ClassHolderTransformer transformer = ctor.newInstance();
|
||||
transformerInstances.add(transformer);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new MojoExecutionException("Error instantiating transformer " + transformerName, e);
|
||||
}
|
||||
}
|
||||
return transformerInstances;
|
||||
|
||||
@Override
|
||||
protected boolean isSupportedScope(String scope) {
|
||||
return testScopes.contains(scope);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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.maven;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.BrowserVersion;
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.WebWindow;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.sourceforge.htmlunit.corejs.javascript.Function;
|
||||
import net.sourceforge.htmlunit.corejs.javascript.NativeJavaObject;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
import org.teavm.tooling.testing.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class HtmlUnitRunStrategy implements TestRunStrategy {
|
||||
private File directory;
|
||||
|
||||
public HtmlUnitRunStrategy(File directory) {
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeThread() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterThread() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String runTest(Log log, String runtimeScript, TestCase testCase) throws IOException {
|
||||
try (WebClient webClient = new WebClient(BrowserVersion.CHROME)) {
|
||||
HtmlPage page = webClient.getPage("about:blank");
|
||||
page.executeJavaScript(readFile(new File(directory, runtimeScript)));
|
||||
|
||||
AsyncResult asyncResult = new AsyncResult();
|
||||
Function function = (Function) page.executeJavaScript(readResource("teavm-htmlunit-adapter.js"))
|
||||
.getJavaScriptResult();
|
||||
Object[] args = new Object[] { new NativeJavaObject(function, asyncResult, AsyncResult.class) };
|
||||
page.executeJavaScriptFunctionIfPossible(function, function, args, page);
|
||||
|
||||
page.executeJavaScript(readFile(new File(directory, testCase.getTestScript())));
|
||||
page.cleanUp();
|
||||
for (WebWindow window : webClient.getWebWindows()) {
|
||||
window.getJobManager().removeAllJobs();
|
||||
}
|
||||
return (String) asyncResult.getResult();
|
||||
}
|
||||
}
|
||||
|
||||
private String readFile(File file) throws IOException {
|
||||
try (InputStream input = new FileInputStream(file)) {
|
||||
return IOUtils.toString(input, "UTF-8");
|
||||
}
|
||||
}
|
||||
|
||||
private String readResource(String resourceName) throws IOException {
|
||||
try (InputStream input = BuildJavascriptTestMojo.class.getClassLoader().getResourceAsStream(resourceName)) {
|
||||
if (input == null) {
|
||||
return "";
|
||||
}
|
||||
return IOUtils.toString(input, "UTF-8");
|
||||
}
|
||||
}
|
||||
|
||||
public class AsyncResult {
|
||||
private CountDownLatch latch = new CountDownLatch(1);
|
||||
private Object result;
|
||||
|
||||
public void complete(Object result) {
|
||||
this.result = result;
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
public Object getResult() {
|
||||
try {
|
||||
latch.await(5, TimeUnit.SECONDS);
|
||||
return result;
|
||||
} catch (InterruptedException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,9 +26,9 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
|
|||
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.apache.maven.repository.RepositorySystem;
|
||||
import org.teavm.tooling.DirectorySourceFileProvider;
|
||||
import org.teavm.tooling.JarSourceFileProvider;
|
||||
import org.teavm.tooling.SourceFileProvider;
|
||||
import org.teavm.tooling.sources.DirectorySourceFileProvider;
|
||||
import org.teavm.tooling.sources.JarSourceFileProvider;
|
||||
import org.teavm.tooling.sources.SourceFileProvider;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -85,7 +85,12 @@ public class MavenSourceFileProviderLookup {
|
|||
ArtifactResolutionResult result = repositorySystem.resolve(request);
|
||||
for (Artifact resolvedArtifact : result.getArtifacts()) {
|
||||
if (resolvedArtifact.getFile() != null) {
|
||||
providers.add(new JarSourceFileProvider(resolvedArtifact.getFile()));
|
||||
File file = resolvedArtifact.getFile();
|
||||
if (!file.isDirectory()) {
|
||||
providers.add(new JarSourceFileProvider(file));
|
||||
} else {
|
||||
providers.add(new DirectorySourceFileProvider(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
* 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.maven;
|
||||
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* 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.maven;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.teavm.tooling.testing.TestPlan;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
@Mojo(name = "test", defaultPhase = LifecyclePhase.TEST)
|
||||
public class RunTestsMojo extends AbstractMojo {
|
||||
@Parameter(defaultValue = "${project.build.directory}/javascript-test")
|
||||
private File testDirectory;
|
||||
|
||||
@Parameter(defaultValue = "${project.build.directory}/teavm-test-report.json")
|
||||
private File reportFile;
|
||||
|
||||
@Parameter
|
||||
private String seleniumURL;
|
||||
|
||||
@Parameter
|
||||
private int numThreads = 1;
|
||||
|
||||
@Parameter
|
||||
private boolean skip;
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||
if (skip) {
|
||||
getLog().info("Tests run skipped as specified by skip property");
|
||||
return;
|
||||
}
|
||||
|
||||
if (System.getProperty("maven.test.skip", "false").equals("true")
|
||||
|| System.getProperty("skipTests") != null) {
|
||||
getLog().info("Tests run skipped as specified by system property");
|
||||
return;
|
||||
}
|
||||
|
||||
TestRunner runner = new TestRunner(pickStrategy());
|
||||
runner.setLog(getLog());
|
||||
runner.setNumThreads(numThreads);
|
||||
|
||||
TestPlan plan;
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
File file = new File(testDirectory, "plan.json");
|
||||
try (Reader reader = new InputStreamReader(new FileInputStream(file), "UTF-8")) {
|
||||
plan = mapper.readValue(reader, TestPlan.class);
|
||||
} catch (IOException e) {
|
||||
throw new MojoExecutionException("Error reading test plan", e);
|
||||
}
|
||||
|
||||
runner.run(plan);
|
||||
processReport(runner.getReport());
|
||||
}
|
||||
|
||||
private TestRunStrategy pickStrategy() throws MojoFailureException {
|
||||
if (seleniumURL != null) {
|
||||
try {
|
||||
return new SeleniumRunStrategy(new URL(seleniumURL), testDirectory);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new MojoFailureException("Can't parse URL: " + seleniumURL, e);
|
||||
}
|
||||
} else {
|
||||
return new HtmlUnitRunStrategy(testDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
private void processReport(TestReport report) throws MojoExecutionException, MojoFailureException {
|
||||
if (report.getResults().isEmpty()) {
|
||||
getLog().info("No tests ran");
|
||||
return;
|
||||
}
|
||||
|
||||
int failedTests = 0;
|
||||
for (TestResult result : report.getResults()) {
|
||||
if (result.getStatus() != TestStatus.PASSED) {
|
||||
failedTests++;
|
||||
}
|
||||
}
|
||||
|
||||
if (failedTests > 0) {
|
||||
throw new MojoExecutionException(failedTests + " of " + report.getResults().size() + " test(s) failed");
|
||||
} else {
|
||||
getLog().info("All of " + report.getResults().size() + " tests successfully passed");
|
||||
}
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
try (Writer writer = new OutputStreamWriter(new FileOutputStream(reportFile), "UTF-8")) {
|
||||
mapper.writeValue(writer, report);
|
||||
} catch (IOException e) {
|
||||
throw new MojoFailureException("Error writing test report", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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.maven;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
import org.openqa.selenium.JavascriptExecutor;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebDriverException;
|
||||
import org.openqa.selenium.remote.DesiredCapabilities;
|
||||
import org.openqa.selenium.remote.RemoteWebDriver;
|
||||
import org.teavm.tooling.testing.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class SeleniumRunStrategy implements TestRunStrategy {
|
||||
private URL url;
|
||||
private File directory;
|
||||
private ThreadLocal<WebDriver> webDriver = new ThreadLocal<>();
|
||||
|
||||
public SeleniumRunStrategy(URL url, File directory) {
|
||||
this.url = url;
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeThread() {
|
||||
RemoteWebDriver driver = new RemoteWebDriver(url, DesiredCapabilities.chrome());
|
||||
webDriver.set(driver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterThread() {
|
||||
webDriver.get().close();
|
||||
webDriver.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String runTest(Log log, String runtimeScript, TestCase testCase) throws IOException {
|
||||
webDriver.get().manage().timeouts().setScriptTimeout(2, TimeUnit.SECONDS);
|
||||
JavascriptExecutor js = (JavascriptExecutor) webDriver.get();
|
||||
try {
|
||||
return (String) js.executeAsyncScript(
|
||||
readResource("teavm-selenium.js"),
|
||||
readFile(new File(directory, runtimeScript)),
|
||||
readFile(new File(directory, testCase.getTestScript())),
|
||||
readResource("teavm-selenium-adapter.js"));
|
||||
} catch (WebDriverException e) {
|
||||
log.error("Error occured running test " + testCase.getTestMethod(), e);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object> errors = (List<Object>) js.executeScript("return window.jsErrors;");
|
||||
for (Object error : errors) {
|
||||
log.error(" -- additional error: " + error);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String readFile(File file) throws IOException {
|
||||
try (InputStream input = new FileInputStream(file)) {
|
||||
return IOUtils.toString(input, "UTF-8");
|
||||
}
|
||||
}
|
||||
|
||||
private String readResource(String resourceName) throws IOException {
|
||||
try (InputStream input = BuildJavascriptTestMojo.class.getClassLoader().getResourceAsStream(resourceName)) {
|
||||
if (input == null) {
|
||||
return "";
|
||||
}
|
||||
return IOUtils.toString(input, "UTF-8");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.maven;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TestReport {
|
||||
private List<TestResult> results = new ArrayList<>();
|
||||
|
||||
public List<TestResult> getResults() {
|
||||
return results;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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.maven;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TestResult {
|
||||
private MethodReference method;
|
||||
private TestStatus status;
|
||||
private String exception;
|
||||
private String stack;
|
||||
|
||||
@JsonCreator
|
||||
TestResult(
|
||||
@JsonProperty("method") MethodReference method,
|
||||
@JsonProperty("status") TestStatus status,
|
||||
@JsonInclude(Include.NON_NULL) @JsonProperty("exception") String exception,
|
||||
@JsonInclude(Include.NON_NULL) @JsonProperty("stack") String stack) {
|
||||
this.method = method;
|
||||
this.status = status;
|
||||
this.exception = exception;
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
public static TestResult passed(MethodReference method) {
|
||||
return new TestResult(method, TestStatus.PASSED, null, null);
|
||||
}
|
||||
|
||||
public static TestResult exceptionNotThrown(MethodReference method) {
|
||||
return new TestResult(method, TestStatus.EXCEPTION_NOT_THROWN, null, null);
|
||||
}
|
||||
|
||||
public static TestResult error(MethodReference method, String exception, String stack) {
|
||||
return new TestResult(method, TestStatus.ERROR, exception, stack);
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public MethodReference getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public TestStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getStack() {
|
||||
return stack;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.maven;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
import org.teavm.tooling.testing.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public interface TestRunStrategy {
|
||||
void beforeThread();
|
||||
|
||||
void afterThread();
|
||||
|
||||
String runTest(Log log, String runtimeScript, TestCase testCase) throws IOException;
|
||||
}
|
164
tools/maven/plugin/src/main/java/org/teavm/maven/TestRunner.java
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* 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.maven;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.tooling.testing.TestCase;
|
||||
import org.teavm.tooling.testing.TestGroup;
|
||||
import org.teavm.tooling.testing.TestPlan;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TestRunner {
|
||||
private int numThreads = 1;
|
||||
private TestRunStrategy strategy;
|
||||
private BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>();
|
||||
private CountDownLatch latch;
|
||||
private volatile boolean stopped;
|
||||
private Log log;
|
||||
private List<TestResult> report = new CopyOnWriteArrayList<>();
|
||||
private ThreadLocal<List<TestResult>> localReport = new ThreadLocal<>();
|
||||
|
||||
public TestRunner(TestRunStrategy strategy) {
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
public void setLog(Log log) {
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public int getNumThreads() {
|
||||
return numThreads;
|
||||
}
|
||||
|
||||
public void setNumThreads(int numThreads) {
|
||||
this.numThreads = numThreads;
|
||||
}
|
||||
|
||||
public void run(TestPlan testPlan) {
|
||||
initSelenium();
|
||||
for (TestGroup group : testPlan.getGroups()) {
|
||||
for (TestCase testCase : group.getTestCases()) {
|
||||
run(testPlan.getRuntimeScript(), testCase);
|
||||
}
|
||||
}
|
||||
stopSelenium();
|
||||
waitForCompletion();
|
||||
}
|
||||
|
||||
private void initSelenium() {
|
||||
latch = new CountDownLatch(numThreads);
|
||||
for (int i = 0; i < numThreads; ++i) {
|
||||
new Thread(() -> {
|
||||
strategy.beforeThread();
|
||||
localReport.set(new ArrayList<>());
|
||||
while (!stopped || !taskQueue.isEmpty()) {
|
||||
Runnable task;
|
||||
try {
|
||||
task = taskQueue.poll(100, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
if (task != null) {
|
||||
task.run();
|
||||
}
|
||||
}
|
||||
report.addAll(localReport.get());
|
||||
localReport.remove();
|
||||
strategy.afterThread();
|
||||
latch.countDown();
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
private void addTask(Runnable runnable) {
|
||||
taskQueue.add(runnable);
|
||||
}
|
||||
|
||||
private void stopSelenium() {
|
||||
stopped = true;
|
||||
}
|
||||
|
||||
private void waitForCompletion() {
|
||||
try {
|
||||
latch.await();
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void run(String runtimeScript, TestCase testCase) {
|
||||
addTask(() -> runImpl(runtimeScript, testCase));
|
||||
}
|
||||
|
||||
private void runImpl(String runtimeScript, TestCase testCase) {
|
||||
MethodReference ref = MethodReference.parse(testCase.getTestMethod());
|
||||
try {
|
||||
String result = strategy.runTest(log, runtimeScript, testCase);
|
||||
if (result == null) {
|
||||
log.info("Test failed: " + testCase.getTestMethod());
|
||||
localReport.get().add(TestResult.error(ref, null, null));
|
||||
}
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
ObjectNode resultObject = (ObjectNode) mapper.readTree(result);
|
||||
String status = resultObject.get("status").asText();
|
||||
switch (status) {
|
||||
case "ok":
|
||||
if (testCase.getExpectedExceptions().isEmpty()) {
|
||||
log.info("Test passed: " + testCase.getTestMethod());
|
||||
localReport.get().add(TestResult.passed(ref));
|
||||
} else {
|
||||
log.info("Test failed: " + testCase.getTestMethod());
|
||||
localReport.get().add(TestResult.exceptionNotThrown(ref));
|
||||
}
|
||||
break;
|
||||
case "exception": {
|
||||
String stack = resultObject.get("stack").asText();
|
||||
String exception = resultObject.get("exception").asText();
|
||||
if (!testCase.getExpectedExceptions().contains(exception)) {
|
||||
log.info("Test failed: " + testCase.getTestMethod());
|
||||
localReport.get().add(TestResult.error(ref, exception, stack));
|
||||
} else {
|
||||
log.info("Test passed: " + testCase.getTestMethod());
|
||||
localReport.get().add(TestResult.passed(ref));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public TestReport getReport() {
|
||||
TestReport report = new TestReport();
|
||||
report.getResults().addAll(this.report);
|
||||
return report;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.maven;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public enum TestStatus {
|
||||
PASSED,
|
||||
ERROR,
|
||||
EXCEPTION_NOT_THROWN
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
function(callback) {
|
||||
var JUnitClient = {}
|
||||
JUnitClient.run = function() {
|
||||
$rt_startThread(function() {
|
||||
var thread = $rt_nativeThread();
|
||||
var instance;
|
||||
var ptr = 0;
|
||||
var message;
|
||||
if (thread.isResuming()) {
|
||||
ptr = thread.pop();
|
||||
instance = thread.pop();
|
||||
}
|
||||
loop: while (true) { switch (ptr) {
|
||||
case 0:
|
||||
instance = new TestClass();
|
||||
ptr = 1;
|
||||
case 1:
|
||||
try {
|
||||
initInstance(instance);
|
||||
} catch (e) {
|
||||
message = {};
|
||||
JUnitClient.makeErrorMessage(message, e);
|
||||
break loop;
|
||||
}
|
||||
if (thread.isSuspending()) {
|
||||
thread.push(instance);
|
||||
thread.push(ptr);
|
||||
return;
|
||||
}
|
||||
ptr = 2;
|
||||
case 2:
|
||||
try {
|
||||
runTest(instance);
|
||||
} catch (e) {
|
||||
message = {};
|
||||
JUnitClient.makeErrorMessage(message, e);
|
||||
break loop;
|
||||
}
|
||||
if (thread.isSuspending()) {
|
||||
thread.push(instance);
|
||||
thread.push(ptr);
|
||||
return;
|
||||
}
|
||||
message = {};
|
||||
message.status = "ok";
|
||||
break loop;
|
||||
}}
|
||||
callback.complete(JSON.stringify(message));
|
||||
})
|
||||
}
|
||||
|
||||
JUnitClient.makeErrorMessage = function(message, e) {
|
||||
message.status = "exception";
|
||||
var stack = e.stack;
|
||||
if (e.$javaException && e.$javaException.constructor.$meta) {
|
||||
message.exception = e.$javaException.constructor.$meta.name;
|
||||
message.stack = e.$javaException.constructor.$meta.name + ": ";
|
||||
var exceptionMessage = extractException(e.$javaException);
|
||||
message.stack += exceptionMessage ? $rt_ustr(exceptionMessage) : "";
|
||||
}
|
||||
message.stack += "\n" + stack;
|
||||
}
|
||||
|
||||
window.JUnitClient = JUnitClient;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
var JUnitClient = {}
|
||||
JUnitClient.run = function() {
|
||||
$rt_startThread(function() {
|
||||
var thread = $rt_nativeThread();
|
||||
var instance;
|
||||
var ptr = 0;
|
||||
var message;
|
||||
if (thread.isResuming()) {
|
||||
ptr = thread.pop();
|
||||
instance = thread.pop();
|
||||
}
|
||||
loop: while (true) { switch (ptr) {
|
||||
case 0:
|
||||
instance = new TestClass();
|
||||
ptr = 1;
|
||||
case 1:
|
||||
try {
|
||||
initInstance(instance);
|
||||
} catch (e) {
|
||||
message = {};
|
||||
JUnitClient.makeErrorMessage(message, e);
|
||||
break loop;
|
||||
}
|
||||
if (thread.isSuspending()) {
|
||||
thread.push(instance);
|
||||
thread.push(ptr);
|
||||
return;
|
||||
}
|
||||
ptr = 2;
|
||||
case 2:
|
||||
try {
|
||||
runTest(instance);
|
||||
} catch (e) {
|
||||
message = {};
|
||||
JUnitClient.makeErrorMessage(message, e);
|
||||
break loop;
|
||||
}
|
||||
if (thread.isSuspending()) {
|
||||
thread.push(instance);
|
||||
thread.push(ptr);
|
||||
return;
|
||||
}
|
||||
message = {};
|
||||
message.status = "ok";
|
||||
break loop;
|
||||
}}
|
||||
window.parent.postMessage(JSON.stringify(message), "*");
|
||||
})
|
||||
}
|
||||
|
||||
JUnitClient.makeErrorMessage = function(message, e) {
|
||||
message.status = "exception";
|
||||
var stack = e.stack;
|
||||
if (e.$javaException && e.$javaException.constructor.$meta) {
|
||||
message.exception = e.$javaException.constructor.$meta.name;
|
||||
message.stack = e.$javaException.constructor.$meta.name + ": ";
|
||||
var exceptionMessage = extractException(e.$javaException);
|
||||
message.stack += exceptionMessage ? $rt_ustr(exceptionMessage) : "";
|
||||
}
|
||||
message.stack += "\n" + stack;
|
||||
}
|
43
tools/maven/plugin/src/main/resources/teavm-selenium.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
var runtimeSource = arguments[0]
|
||||
var testSource = arguments[1]
|
||||
var adapterSource = arguments[2]
|
||||
var seleniumCallback = arguments[arguments.length - 1]
|
||||
|
||||
var iframe = document.createElement("iframe")
|
||||
document.body.appendChild(iframe)
|
||||
var doc = iframe.contentDocument
|
||||
|
||||
window.jsErrors = []
|
||||
window.onerror = reportError
|
||||
iframe.contentWindow.onerror = reportError
|
||||
|
||||
loadScripts([ runtimeSource, adapterSource, testSource ])
|
||||
window.addEventListener("message", handleMessage)
|
||||
|
||||
function handleMessage(event) {
|
||||
window.removeEventListener("message", handleMessage)
|
||||
document.body.removeChild(iframe)
|
||||
seleniumCallback(event.data)
|
||||
}
|
||||
|
||||
function loadScript(script, callback) {
|
||||
callback()
|
||||
}
|
||||
|
||||
function loadScripts(scripts) {
|
||||
for (var i = 0; i < scripts.length; ++i) {
|
||||
var elem = doc.createElement("script")
|
||||
elem.type = "text/javascript"
|
||||
doc.head.appendChild(elem)
|
||||
elem.text = scripts[i]
|
||||
}
|
||||
}
|
||||
function reportError(error, url, line) {
|
||||
window.jsErrors.push(error + " at " + line)
|
||||
}
|
||||
function report(error) {
|
||||
window.jsErrors.push(error)
|
||||
}
|
||||
function globalEval(window, arg) {
|
||||
eval.apply(window, [arg])
|
||||
}
|
|
@ -21,6 +21,7 @@
|
|||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<artifactId>teavm-maven</artifactId>
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<packaging>war</packaging>
|
||||
|
||||
<properties>
|
||||
<java.version>1.7</java.version>
|
||||
<java.version>1.8</java.version>
|
||||
<teavm.version>0.4.0-SNAPSHOT</teavm.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
@ -25,15 +25,7 @@
|
|||
<!-- JavaScriptObjects (JSO) - a JavaScript binding for TeaVM -->
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-jso</artifactId>
|
||||
<version>${teavm.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Different browser APIs for TeaVM in terms of JSO -->
|
||||
<dependency>
|
||||
<groupId>org.teavm</groupId>
|
||||
<artifactId>teavm-dom</artifactId>
|
||||
<artifactId>teavm-jso-apis</artifactId>
|
||||
<version>${teavm.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
@ -80,9 +72,8 @@
|
|||
<executions>
|
||||
<execution>
|
||||
<id>web-client</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>build-javascript</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- Directory where TeaVM should put generated files. This configuration conforms to the settings
|
||||
|
@ -92,9 +83,6 @@
|
|||
<!-- Main class, containing static void main(String[]) -->
|
||||
<mainClass>${package}.Client</mainClass>
|
||||
|
||||
<!-- How to attach runtime.js. Possible values are: SEPARATE, MERGED and NONE -->
|
||||
<runtime>SEPARATE</runtime>
|
||||
|
||||
<!-- Whether TeaVM should produce minified JavaScript. Can reduce JavaScript file size more than
|
||||
two times -->
|
||||
<minifying>true</minifying>
|
||||
|
|