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
|
TeaVM
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.org/konsoletyper/teavm.svg?branch=selenium)](https://travis-ci.org/konsoletyper/teavm)
|
||||||
|
|
||||||
What is TeaVM?
|
What is TeaVM?
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,11 @@
|
||||||
<artifactId>hppc</artifactId>
|
<artifactId>hppc</artifactId>
|
||||||
<version>0.6.1</version>
|
<version>0.6.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-annotations</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<name>TeaVM core</name>
|
<name>TeaVM core</name>
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model;
|
package org.teavm.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,6 +134,7 @@ public class MethodReference {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@JsonValue
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (reprCache == null) {
|
if (reprCache == null) {
|
||||||
reprCache = className + "." + name + signatureToString();
|
reprCache = className + "." + name + signatureToString();
|
||||||
|
@ -139,6 +142,7 @@ public class MethodReference {
|
||||||
return reprCache;
|
return reprCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
public static MethodReference parse(String string) {
|
public static MethodReference parse(String string) {
|
||||||
MethodReference reference = parseIfPossible(string);
|
MethodReference reference = parseIfPossible(string);
|
||||||
if (reference == null) {
|
if (reference == null) {
|
||||||
|
|
|
@ -74,12 +74,11 @@
|
||||||
<execution>
|
<execution>
|
||||||
<id>generate-javascript-tests</id>
|
<id>generate-javascript-tests</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>build-test-javascript</goal>
|
<goal>testCompile</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<phase>process-test-classes</phase>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<minifying>false</minifying>
|
<minifying>false</minifying>
|
||||||
<outputDir>${project.build.directory}/javascript-test</outputDir>
|
<targetDirectory>${project.build.directory}/javascript-test</targetDirectory>
|
||||||
<debugInformationGenerated>true</debugInformationGenerated>
|
<debugInformationGenerated>true</debugInformationGenerated>
|
||||||
<sourceMapsGenerated>true</sourceMapsGenerated>
|
<sourceMapsGenerated>true</sourceMapsGenerated>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -87,13 +86,12 @@
|
||||||
<execution>
|
<execution>
|
||||||
<id>generate-javascript-tck</id>
|
<id>generate-javascript-tck</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>build-test-javascript</goal>
|
<goal>testCompile</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<phase>process-test-classes</phase>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<minifying>false</minifying>
|
<minifying>false</minifying>
|
||||||
<scanDependencies>true</scanDependencies>
|
<scanDependencies>true</scanDependencies>
|
||||||
<outputDir>${project.build.directory}/javascript-tck</outputDir>
|
<targetDirectory>${project.build.directory}/javascript-tck</targetDirectory>
|
||||||
<adapterClass>org.teavm.html4j.testing.KOTestAdapter</adapterClass>
|
<adapterClass>org.teavm.html4j.testing.KOTestAdapter</adapterClass>
|
||||||
<transformers>
|
<transformers>
|
||||||
<param>org.teavm.javascript.NullPointerExceptionTransformer</param>
|
<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>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm</artifactId>
|
<artifactId>teavm</artifactId>
|
||||||
<version>0.4.0-SNAPSHOT</version>
|
<version>0.4.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>teavm-jso-apis</artifactId>
|
<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>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm</artifactId>
|
<artifactId>teavm</artifactId>
|
||||||
<version>0.4.0-SNAPSHOT</version>
|
<version>0.4.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>teavm-jso</artifactId>
|
<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>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm</artifactId>
|
<artifactId>teavm</artifactId>
|
||||||
<version>0.4.0-SNAPSHOT</version>
|
<version>0.4.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>teavm-jso-impl</artifactId>
|
<artifactId>teavm-jso-impl</artifactId>
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,6 @@
|
||||||
<artifactId>teavm-jso-apis</artifactId>
|
<artifactId>teavm-jso-apis</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.teavm</groupId>
|
|
||||||
<artifactId>teavm-dom</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|
27
pom.xml
|
@ -69,7 +69,8 @@
|
||||||
<html4j.version>1.2</html4j.version>
|
<html4j.version>1.2</html4j.version>
|
||||||
<jetty.version>9.2.1.v20140609</jetty.version>
|
<jetty.version>9.2.1.v20140609</jetty.version>
|
||||||
<slf4j.version>1.7.7</slf4j.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>
|
</properties>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@ -81,6 +82,7 @@
|
||||||
<module>html4j</module>
|
<module>html4j</module>
|
||||||
<module>samples</module>
|
<module>samples</module>
|
||||||
<module>platform</module>
|
<module>platform</module>
|
||||||
|
<module>tools/core</module>
|
||||||
<module>tools/cli</module>
|
<module>tools/cli</module>
|
||||||
<module>tools/maven</module>
|
<module>tools/maven</module>
|
||||||
<module>tools/chrome-rdp</module>
|
<module>tools/chrome-rdp</module>
|
||||||
|
@ -166,13 +168,26 @@
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
<version>${slf4j.version}</version>
|
<version>${slf4j.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.checkerframework</groupId>
|
<groupId>org.seleniumhq.selenium</groupId>
|
||||||
<artifactId>checker</artifactId>
|
<artifactId>selenium-java</artifactId>
|
||||||
<version>${checker.version}</version>
|
<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>
|
</dependency>
|
||||||
-->
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|
|
@ -57,9 +57,8 @@
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>web-client</id>
|
<id>web-client</id>
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>build-javascript</goal>
|
<goal>compile</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||||
|
|
|
@ -27,13 +27,7 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-jso</artifactId>
|
<artifactId>teavm-jso-apis</artifactId>
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.teavm</groupId>
|
|
||||||
<artifactId>teavm-dom</artifactId>
|
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -111,9 +105,8 @@
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>web-client</id>
|
<id>web-client</id>
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>build-javascript</goal>
|
<goal>compile</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||||
|
|
|
@ -42,12 +42,6 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.teavm</groupId>
|
|
||||||
<artifactId>teavm-dom</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
@ -76,9 +70,8 @@
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>web-client</id>
|
<id>web-client</id>
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>build-javascript</goal>
|
<goal>compile</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-dom</artifactId>
|
<artifactId>teavm-jso-apis</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -92,9 +92,8 @@
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>web-client</id>
|
<id>web-client</id>
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>build-javascript</goal>
|
<goal>compile</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||||
|
|
|
@ -67,9 +67,8 @@
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>web-client</id>
|
<id>web-client</id>
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>build-javascript</goal>
|
<goal>compile</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||||
|
|
|
@ -38,13 +38,7 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-jso</artifactId>
|
<artifactId>teavm-jso-apis</artifactId>
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.teavm</groupId>
|
|
||||||
<artifactId>teavm-dom</artifactId>
|
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -78,12 +72,11 @@
|
||||||
<id>web-client</id>
|
<id>web-client</id>
|
||||||
<phase>prepare-package</phase>
|
<phase>prepare-package</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>build-javascript</goal>
|
<goal>compile</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||||
<mainClass>org.teavm.samples.storage.Application</mainClass>
|
<mainClass>org.teavm.samples.storage.Application</mainClass>
|
||||||
<runtime>SEPARATE</runtime>
|
|
||||||
<minifying>false</minifying>
|
<minifying>false</minifying>
|
||||||
<debugInformationGenerated>true</debugInformationGenerated>
|
<debugInformationGenerated>true</debugInformationGenerated>
|
||||||
<sourceMapsGenerated>true</sourceMapsGenerated>
|
<sourceMapsGenerated>true</sourceMapsGenerated>
|
||||||
|
|
|
@ -38,13 +38,7 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-jso</artifactId>
|
<artifactId>teavm-jso-apis</artifactId>
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.teavm</groupId>
|
|
||||||
<artifactId>teavm-dom</artifactId>
|
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -76,9 +70,8 @@
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>web-client</id>
|
<id>web-client</id>
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>build-javascript</goal>
|
<goal>compile</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
<targetDirectory>${project.build.directory}/generated/js/teavm</targetDirectory>
|
||||||
|
|
|
@ -27,6 +27,13 @@
|
||||||
<name>TeaVM tests</name>
|
<name>TeaVM tests</name>
|
||||||
<description>Project containing TeaVM tests, as it is impossible to test each module separately</description>
|
<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>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
|
@ -72,9 +79,8 @@
|
||||||
<execution>
|
<execution>
|
||||||
<id>generate-javascript-tests</id>
|
<id>generate-javascript-tests</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>build-test-javascript</goal>
|
<goal>testCompile</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<phase>process-test-classes</phase>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<minifying>false</minifying>
|
<minifying>false</minifying>
|
||||||
<scanDependencies>true</scanDependencies>
|
<scanDependencies>true</scanDependencies>
|
||||||
|
@ -89,6 +95,17 @@
|
||||||
<incremental>${teavm.test.incremental}</incremental>
|
<incremental>${teavm.test.incremental}</incremental>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</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>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm</artifactId>
|
<artifactId>teavm</artifactId>
|
||||||
<version>0.4.0-SNAPSHOT</version>
|
<version>0.4.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>teavm-chrome-rdp</artifactId>
|
<artifactId>teavm-chrome-rdp</artifactId>
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm</artifactId>
|
<artifactId>teavm</artifactId>
|
||||||
<version>0.4.0-SNAPSHOT</version>
|
<version>0.4.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>teavm-cli</artifactId>
|
<artifactId>teavm-cli</artifactId>
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-core</artifactId>
|
<artifactId>teavm-tooling</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -19,11 +19,17 @@ import java.io.File;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.Arrays;
|
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.model.ClassHolderTransformer;
|
||||||
import org.teavm.testing.TestAdapter;
|
import org.teavm.testing.TestAdapter;
|
||||||
import org.teavm.tooling.TeaVMTestTool;
|
|
||||||
import org.teavm.tooling.TeaVMToolException;
|
import org.teavm.tooling.TeaVMToolException;
|
||||||
|
import org.teavm.tooling.testing.TeaVMTestTool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -84,7 +90,7 @@ public final class TeaVMTestRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
TeaVMTestTool tool = new TeaVMTestTool();
|
TeaVMTestTool tool = new TeaVMTestTool();
|
||||||
tool.setOutputDir(new File(commandLine.getOptionValue("d", ".")));
|
tool.setTargetDirectory(new File(commandLine.getOptionValue("d", ".")));
|
||||||
tool.setMinifying(commandLine.hasOption("m"));
|
tool.setMinifying(commandLine.hasOption("m"));
|
||||||
try {
|
try {
|
||||||
tool.setNumThreads(Integer.parseInt(commandLine.getOptionValue("t", "1")));
|
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.javascript.RenderingContext;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.parsing.ClasspathClassHolderSource;
|
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.*;
|
||||||
import org.teavm.vm.spi.AbstractRendererListener;
|
import org.teavm.vm.spi.AbstractRendererListener;
|
||||||
|
|
||||||
|
@ -36,7 +38,7 @@ import org.teavm.vm.spi.AbstractRendererListener;
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class TeaVMTool {
|
public class TeaVMTool implements BaseTeaVMTool {
|
||||||
private File targetDirectory = new File(".");
|
private File targetDirectory = new File(".");
|
||||||
private String targetFileName = "classes.js";
|
private String targetFileName = "classes.js";
|
||||||
private boolean minifying = true;
|
private boolean minifying = true;
|
||||||
|
@ -69,6 +71,7 @@ public class TeaVMTool {
|
||||||
return targetDirectory;
|
return targetDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setTargetDirectory(File targetDirectory) {
|
public void setTargetDirectory(File targetDirectory) {
|
||||||
this.targetDirectory = targetDirectory;
|
this.targetDirectory = targetDirectory;
|
||||||
}
|
}
|
||||||
|
@ -85,6 +88,7 @@ public class TeaVMTool {
|
||||||
return minifying;
|
return minifying;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setMinifying(boolean minifying) {
|
public void setMinifying(boolean minifying) {
|
||||||
this.minifying = minifying;
|
this.minifying = minifying;
|
||||||
}
|
}
|
||||||
|
@ -93,6 +97,7 @@ public class TeaVMTool {
|
||||||
return incremental;
|
return incremental;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setIncremental(boolean incremental) {
|
public void setIncremental(boolean incremental) {
|
||||||
this.incremental = incremental;
|
this.incremental = incremental;
|
||||||
}
|
}
|
||||||
|
@ -133,6 +138,7 @@ public class TeaVMTool {
|
||||||
return debugInformationGenerated;
|
return debugInformationGenerated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setDebugInformationGenerated(boolean debugInformationGenerated) {
|
public void setDebugInformationGenerated(boolean debugInformationGenerated) {
|
||||||
this.debugInformationGenerated = debugInformationGenerated;
|
this.debugInformationGenerated = debugInformationGenerated;
|
||||||
}
|
}
|
||||||
|
@ -149,6 +155,7 @@ public class TeaVMTool {
|
||||||
return sourceMapsFileGenerated;
|
return sourceMapsFileGenerated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated) {
|
public void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated) {
|
||||||
this.sourceMapsFileGenerated = sourceMapsFileGenerated;
|
this.sourceMapsFileGenerated = sourceMapsFileGenerated;
|
||||||
}
|
}
|
||||||
|
@ -157,14 +164,17 @@ public class TeaVMTool {
|
||||||
return sourceFilesCopied;
|
return sourceFilesCopied;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setSourceFilesCopied(boolean sourceFilesCopied) {
|
public void setSourceFilesCopied(boolean sourceFilesCopied) {
|
||||||
this.sourceFilesCopied = sourceFilesCopied;
|
this.sourceFilesCopied = sourceFilesCopied;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Properties getProperties() {
|
public Properties getProperties() {
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public List<ClassHolderTransformer> getTransformers() {
|
public List<ClassHolderTransformer> getTransformers() {
|
||||||
return transformers;
|
return transformers;
|
||||||
}
|
}
|
||||||
|
@ -181,6 +191,7 @@ public class TeaVMTool {
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setLog(TeaVMToolLog log) {
|
public void setLog(TeaVMToolLog log) {
|
||||||
this.log = log;
|
this.log = log;
|
||||||
}
|
}
|
||||||
|
@ -189,6 +200,7 @@ public class TeaVMTool {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setClassLoader(ClassLoader classLoader) {
|
public void setClassLoader(ClassLoader classLoader) {
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
}
|
}
|
||||||
|
@ -245,6 +257,7 @@ public class TeaVMTool {
|
||||||
return resources;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void addSourceFileProvider(SourceFileProvider sourceFileProvider) {
|
public void addSourceFileProvider(SourceFileProvider sourceFileProvider) {
|
||||||
sourceFileProviders.add(sourceFileProvider);
|
sourceFileProviders.add(sourceFileProvider);
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.tooling;
|
package org.teavm.tooling.sources;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.tooling;
|
package org.teavm.tooling.sources;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.tooling;
|
package org.teavm.tooling.sources;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.tooling;
|
package org.teavm.tooling.sources;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.tooling;
|
package org.teavm.tooling.sources;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -23,6 +23,8 @@ import org.apache.commons.io.IOUtils;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.ListableClassReaderSource;
|
import org.teavm.model.ListableClassReaderSource;
|
||||||
import org.teavm.model.MethodReader;
|
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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.tooling;
|
package org.teavm.tooling.testing;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.teavm.common.FiniteExecutor;
|
import org.teavm.common.FiniteExecutor;
|
||||||
import org.teavm.common.SimpleFiniteExecutor;
|
import org.teavm.common.SimpleFiniteExecutor;
|
||||||
|
@ -26,10 +35,26 @@ import org.teavm.debugging.information.DebugInformationBuilder;
|
||||||
import org.teavm.javascript.EmptyRegularMethodNodeCache;
|
import org.teavm.javascript.EmptyRegularMethodNodeCache;
|
||||||
import org.teavm.javascript.InMemoryRegularMethodNodeCache;
|
import org.teavm.javascript.InMemoryRegularMethodNodeCache;
|
||||||
import org.teavm.javascript.MethodNodeCache;
|
import org.teavm.javascript.MethodNodeCache;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.ClassHolder;
|
||||||
|
import org.teavm.model.ClassHolderSource;
|
||||||
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
|
import org.teavm.model.CopyClassHolderSource;
|
||||||
|
import org.teavm.model.InMemoryProgramCache;
|
||||||
|
import org.teavm.model.MethodHolder;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
import org.teavm.model.PreOptimizingClassHolderSource;
|
||||||
|
import org.teavm.model.ProgramCache;
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
import org.teavm.parsing.ClasspathClassHolderSource;
|
import org.teavm.parsing.ClasspathClassHolderSource;
|
||||||
import org.teavm.testing.JUnitTestAdapter;
|
import org.teavm.testing.JUnitTestAdapter;
|
||||||
import org.teavm.testing.TestAdapter;
|
import org.teavm.testing.TestAdapter;
|
||||||
|
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.DirectoryBuildTarget;
|
||||||
import org.teavm.vm.TeaVM;
|
import org.teavm.vm.TeaVM;
|
||||||
import org.teavm.vm.TeaVMBuilder;
|
import org.teavm.vm.TeaVMBuilder;
|
||||||
|
@ -38,10 +63,7 @@ import org.teavm.vm.TeaVMBuilder;
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class TeaVMTestTool {
|
public class TeaVMTestTool implements BaseTeaVMTool {
|
||||||
private Map<String, List<MethodReference>> groupedMethods = new HashMap<>();
|
|
||||||
private Map<MethodReference, String> fileNames = new HashMap<>();
|
|
||||||
private List<MethodReference> testMethods = new ArrayList<>();
|
|
||||||
private File outputDir = new File(".");
|
private File outputDir = new File(".");
|
||||||
private boolean minifying = true;
|
private boolean minifying = true;
|
||||||
private int numThreads = 1;
|
private int numThreads = 1;
|
||||||
|
@ -54,19 +76,25 @@ public class TeaVMTestTool {
|
||||||
private ClassLoader classLoader = TeaVMTestTool.class.getClassLoader();
|
private ClassLoader classLoader = TeaVMTestTool.class.getClassLoader();
|
||||||
private TeaVMToolLog log = new EmptyTeaVMToolLog();
|
private TeaVMToolLog log = new EmptyTeaVMToolLog();
|
||||||
private boolean debugInformationGenerated;
|
private boolean debugInformationGenerated;
|
||||||
private boolean sourceMapsGenerated;
|
private boolean sourceMapsFileGenerated;
|
||||||
private boolean sourceFilesCopied;
|
private boolean sourceFilesCopied;
|
||||||
private boolean incremental;
|
private boolean incremental;
|
||||||
private List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
|
private List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
|
||||||
private MethodNodeCache astCache;
|
private MethodNodeCache astCache;
|
||||||
private ProgramCache programCache;
|
private ProgramCache programCache;
|
||||||
private SourceFilesCopier sourceFilesCopier;
|
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() {
|
public File getOutputDir() {
|
||||||
return outputDir;
|
return outputDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOutputDir(File outputDir) {
|
@Override
|
||||||
|
public void setTargetDirectory(File outputDir) {
|
||||||
this.outputDir = outputDir;
|
this.outputDir = outputDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +102,7 @@ public class TeaVMTestTool {
|
||||||
return minifying;
|
return minifying;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setMinifying(boolean minifying) {
|
public void setMinifying(boolean minifying) {
|
||||||
this.minifying = minifying;
|
this.minifying = minifying;
|
||||||
}
|
}
|
||||||
|
@ -94,6 +123,7 @@ public class TeaVMTestTool {
|
||||||
this.adapter = adapter;
|
this.adapter = adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public List<ClassHolderTransformer> getTransformers() {
|
public List<ClassHolderTransformer> getTransformers() {
|
||||||
return transformers;
|
return transformers;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +132,7 @@ public class TeaVMTestTool {
|
||||||
return additionalScripts;
|
return additionalScripts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Properties getProperties() {
|
public Properties getProperties() {
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
@ -114,6 +145,7 @@ public class TeaVMTestTool {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setClassLoader(ClassLoader classLoader) {
|
public void setClassLoader(ClassLoader classLoader) {
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
}
|
}
|
||||||
|
@ -122,6 +154,7 @@ public class TeaVMTestTool {
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setLog(TeaVMToolLog log) {
|
public void setLog(TeaVMToolLog log) {
|
||||||
this.log = log;
|
this.log = log;
|
||||||
}
|
}
|
||||||
|
@ -130,6 +163,7 @@ public class TeaVMTestTool {
|
||||||
return incremental;
|
return incremental;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setIncremental(boolean incremental) {
|
public void setIncremental(boolean incremental) {
|
||||||
this.incremental = incremental;
|
this.incremental = incremental;
|
||||||
}
|
}
|
||||||
|
@ -138,31 +172,36 @@ public class TeaVMTestTool {
|
||||||
return debugInformationGenerated;
|
return debugInformationGenerated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setDebugInformationGenerated(boolean debugInformationGenerated) {
|
public void setDebugInformationGenerated(boolean debugInformationGenerated) {
|
||||||
this.debugInformationGenerated = debugInformationGenerated;
|
this.debugInformationGenerated = debugInformationGenerated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSourceMapsGenerated() {
|
public boolean isSourceMapsFileGenerated() {
|
||||||
return sourceMapsGenerated;
|
return sourceMapsFileGenerated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSourceMapsGenerated(boolean sourceMapsGenerated) {
|
@Override
|
||||||
this.sourceMapsGenerated = sourceMapsGenerated;
|
public void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated) {
|
||||||
|
this.sourceMapsFileGenerated = sourceMapsFileGenerated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSourceFilesCopied() {
|
public boolean isSourceFilesCopied() {
|
||||||
return sourceFilesCopied;
|
return sourceFilesCopied;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setSourceFilesCopied(boolean sourceFilesCopied) {
|
public void setSourceFilesCopied(boolean sourceFilesCopied) {
|
||||||
this.sourceFilesCopied = sourceFilesCopied;
|
this.sourceFilesCopied = sourceFilesCopied;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void addSourceFileProvider(SourceFileProvider sourceFileProvider) {
|
public void addSourceFileProvider(SourceFileProvider sourceFileProvider) {
|
||||||
sourceFileProviders.add(sourceFileProvider);
|
sourceFileProviders.add(sourceFileProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generate() throws TeaVMToolException {
|
public TestPlan generate() throws TeaVMToolException {
|
||||||
|
testsBuilt.set(0);
|
||||||
Runnable finalizer = null;
|
Runnable finalizer = null;
|
||||||
try {
|
try {
|
||||||
new File(outputDir, "tests").mkdirs();
|
new File(outputDir, "tests").mkdirs();
|
||||||
|
@ -184,12 +223,17 @@ public class TeaVMTestTool {
|
||||||
if (incremental) {
|
if (incremental) {
|
||||||
classSource = new PreOptimizingClassHolderSource(classSource);
|
classSource = new PreOptimizingClassHolderSource(classSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<TestGroup> groups = new ArrayList<>();
|
||||||
for (String testClass : testClasses) {
|
for (String testClass : testClasses) {
|
||||||
ClassHolder classHolder = classSource.get(testClass);
|
ClassHolder classHolder = classSource.get(testClass);
|
||||||
if (classHolder == null) {
|
if (classHolder == null) {
|
||||||
throw new TeaVMToolException("Could not find class " + testClass);
|
throw new TeaVMToolException("Could not find class " + testClass);
|
||||||
}
|
}
|
||||||
findTests(classHolder);
|
TestGroup group = findTests(classHolder);
|
||||||
|
if (group != null) {
|
||||||
|
groups.add(group);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
includeAdditionalScripts(classLoader);
|
includeAdditionalScripts(classLoader);
|
||||||
|
@ -198,83 +242,26 @@ public class TeaVMTestTool {
|
||||||
astCache = new InMemoryRegularMethodNodeCache();
|
astCache = new InMemoryRegularMethodNodeCache();
|
||||||
programCache = new InMemoryProgramCache();
|
programCache = new InMemoryProgramCache();
|
||||||
}
|
}
|
||||||
File allTestsFile = new File(outputDir, "tests/all.js");
|
writeMetadata();
|
||||||
try (Writer allTestsWriter = new OutputStreamWriter(new FileOutputStream(allTestsFile), "UTF-8")) {
|
|
||||||
allTestsWriter.write("prepare = function() {\n");
|
|
||||||
allTestsWriter.write(" return new JUnitServer(document.body).readTests([");
|
|
||||||
boolean first = true;
|
|
||||||
for (String testClass : testClasses) {
|
|
||||||
Collection<MethodReference> methods = groupedMethods.get(testClass);
|
|
||||||
if (methods == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!first) {
|
|
||||||
allTestsWriter.append(",");
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
allTestsWriter.append("\n { name : \"").append(testClass).append("\", methods : [");
|
|
||||||
boolean firstMethod = true;
|
|
||||||
for (MethodReference methodRef : methods) {
|
|
||||||
String scriptName = "tests/" + fileNames.size() + ".js";
|
|
||||||
fileNames.put(methodRef, scriptName);
|
|
||||||
if (!firstMethod) {
|
|
||||||
allTestsWriter.append(",");
|
|
||||||
}
|
|
||||||
firstMethod = false;
|
|
||||||
allTestsWriter.append("\n { name : \"" + methodRef.getName() + "\", script : \""
|
|
||||||
+ scriptName + "\", expected : [");
|
|
||||||
MethodHolder methodHolder = classSource.get(testClass).getMethod(
|
|
||||||
methodRef.getDescriptor());
|
|
||||||
boolean firstException = true;
|
|
||||||
for (String exception : adapter.getExpectedExceptions(methodHolder)) {
|
|
||||||
if (!firstException) {
|
|
||||||
allTestsWriter.append(", ");
|
|
||||||
}
|
|
||||||
firstException = false;
|
|
||||||
allTestsWriter.append("\"" + exception + "\"");
|
|
||||||
}
|
|
||||||
allTestsWriter.append("], additionalScripts : [");
|
|
||||||
for (int i = 0; i < additionalScriptLocalPaths.size(); ++i) {
|
|
||||||
if (i > 0) {
|
|
||||||
allTestsWriter.append(", ");
|
|
||||||
}
|
|
||||||
escapeString(additionalScriptLocalPaths.get(i), allTestsWriter);
|
|
||||||
}
|
|
||||||
allTestsWriter.append("] }");
|
|
||||||
}
|
|
||||||
allTestsWriter.append("] }");
|
|
||||||
}
|
|
||||||
allTestsWriter.write("], function() {}); }");
|
|
||||||
}
|
|
||||||
int methodsGenerated = 0;
|
|
||||||
log.info("Generating test files");
|
|
||||||
sourceFilesCopier = new SourceFilesCopier(sourceFileProviders);
|
|
||||||
sourceFilesCopier.setLog(log);
|
|
||||||
FiniteExecutor executor = new SimpleFiniteExecutor();
|
FiniteExecutor executor = new SimpleFiniteExecutor();
|
||||||
if (numThreads != 1) {
|
if (numThreads != 1) {
|
||||||
int threads = numThreads != 0 ? numThreads : Runtime.getRuntime().availableProcessors();
|
int threads = numThreads != 0 ? numThreads : Runtime.getRuntime().availableProcessors();
|
||||||
final ThreadPoolFiniteExecutor threadedExecutor = new ThreadPoolFiniteExecutor(threads);
|
ThreadPoolFiniteExecutor threadedExecutor = new ThreadPoolFiniteExecutor(threads);
|
||||||
finalizer = () -> threadedExecutor.stop();
|
finalizer = () -> threadedExecutor.stop();
|
||||||
executor = threadedExecutor;
|
executor = threadedExecutor;
|
||||||
}
|
}
|
||||||
for (final MethodReference method : testMethods) {
|
startTime = System.currentTimeMillis();
|
||||||
final ClassHolderSource builderClassSource = classSource;
|
int methodsGenerated = writeMethods(executor, classSource);
|
||||||
executor.execute(() -> {
|
|
||||||
log.debug("Building test for " + method);
|
|
||||||
try {
|
|
||||||
decompileClassesForTest(classLoader, new CopyClassHolderSource(builderClassSource), method,
|
|
||||||
fileNames.get(method));
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Error generating JavaScript", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
++methodsGenerated;
|
|
||||||
}
|
|
||||||
executor.complete();
|
|
||||||
if (sourceFilesCopied) {
|
if (sourceFilesCopied) {
|
||||||
sourceFilesCopier.copy(new File(new File(outputDir, "tests"), "src"));
|
sourceFilesCopier.copy(new File(new File(outputDir, "tests"), "src"));
|
||||||
}
|
}
|
||||||
log.info("Test files successfully generated for " + methodsGenerated + " method(s).");
|
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) {
|
} catch (IOException e) {
|
||||||
throw new TeaVMToolException("IO error occured generating JavaScript files", e);
|
throw new TeaVMToolException("IO error occured generating JavaScript files", e);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -284,6 +271,74 @@ public class TeaVMTestTool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeMetadata() throws IOException {
|
||||||
|
File allTestsFile = new File(outputDir, "tests/all.js");
|
||||||
|
try (Writer allTestsWriter = new OutputStreamWriter(new FileOutputStream(allTestsFile), "UTF-8")) {
|
||||||
|
allTestsWriter.write("prepare = function() {\n");
|
||||||
|
allTestsWriter.write(" return new JUnitServer(document.body).readTests([");
|
||||||
|
boolean first = true;
|
||||||
|
for (TestClassBuilder testClass : testPlan) {
|
||||||
|
if (!first) {
|
||||||
|
allTestsWriter.append(",");
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
allTestsWriter.append("\n { name : \"").append(testClass.getClassName())
|
||||||
|
.append("\", methods : [");
|
||||||
|
boolean firstMethod = true;
|
||||||
|
for (TestMethodBuilder testMethod : testClass.getMethods()) {
|
||||||
|
String scriptName = testMethod.getFileName();
|
||||||
|
if (!firstMethod) {
|
||||||
|
allTestsWriter.append(",");
|
||||||
|
}
|
||||||
|
firstMethod = false;
|
||||||
|
allTestsWriter.append("\n { name : \"" + testMethod.getMethod().getName()
|
||||||
|
+ "\", script : \"" + scriptName + "\", expected : [");
|
||||||
|
boolean firstException = true;
|
||||||
|
for (String exception : testMethod.getExpectedExceptions()) {
|
||||||
|
if (!firstException) {
|
||||||
|
allTestsWriter.append(", ");
|
||||||
|
}
|
||||||
|
firstException = false;
|
||||||
|
allTestsWriter.append("\"" + exception + "\"");
|
||||||
|
}
|
||||||
|
allTestsWriter.append("], additionalScripts : [");
|
||||||
|
for (int i = 0; i < additionalScriptLocalPaths.size(); ++i) {
|
||||||
|
if (i > 0) {
|
||||||
|
allTestsWriter.append(", ");
|
||||||
|
}
|
||||||
|
escapeString(additionalScriptLocalPaths.get(i), allTestsWriter);
|
||||||
|
}
|
||||||
|
allTestsWriter.append("] }");
|
||||||
|
}
|
||||||
|
allTestsWriter.append("] }");
|
||||||
|
}
|
||||||
|
allTestsWriter.write("], function() {}); }");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int writeMethods(FiniteExecutor executor, ClassHolderSource classSource) {
|
||||||
|
int methodsGenerated = 0;
|
||||||
|
log.info("Generating test files");
|
||||||
|
sourceFilesCopier = new SourceFilesCopier(sourceFileProviders);
|
||||||
|
sourceFilesCopier.setLog(log);
|
||||||
|
for (TestClassBuilder testClass : testPlan) {
|
||||||
|
for (TestMethodBuilder testMethod : testClass.getMethods()) {
|
||||||
|
executor.execute(() -> {
|
||||||
|
log.debug("Building test for " + testMethod.getMethod());
|
||||||
|
try {
|
||||||
|
decompileClassesForTest(classLoader, new CopyClassHolderSource(classSource),
|
||||||
|
testMethod);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error generating JavaScript", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
++methodsGenerated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
executor.complete();
|
||||||
|
return methodsGenerated;
|
||||||
|
}
|
||||||
|
|
||||||
private void resourceToFile(String resource, String fileName) throws IOException {
|
private void resourceToFile(String resource, String fileName) throws IOException {
|
||||||
try (InputStream input = TeaVMTestTool.class.getClassLoader().getResourceAsStream(resource)) {
|
try (InputStream input = TeaVMTestTool.class.getClassLoader().getResourceAsStream(resource)) {
|
||||||
try (OutputStream output = new FileOutputStream(new File(outputDir, fileName))) {
|
try (OutputStream output = new FileOutputStream(new File(outputDir, fileName))) {
|
||||||
|
@ -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()) {
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
if (adapter.acceptMethod(method)) {
|
if (adapter.acceptMethod(method)) {
|
||||||
MethodReference ref = new MethodReference(cls.getName(), method.getDescriptor());
|
MethodReference ref = new MethodReference(cls.getName(), method.getDescriptor());
|
||||||
testMethods.add(ref);
|
String fileName = "tests/" + fileIndexGenerator++ + ".js";
|
||||||
List<MethodReference> group = groupedMethods.get(cls.getName());
|
|
||||||
if (group == null) {
|
List<String> exceptions = new ArrayList<>();
|
||||||
group = new ArrayList<>();
|
for (String exception : adapter.getExpectedExceptions(method)) {
|
||||||
groupedMethods.put(cls.getName(), group);
|
exceptions.add(exception);
|
||||||
}
|
}
|
||||||
group.add(ref);
|
|
||||||
|
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 {
|
private void includeAdditionalScripts(ClassLoader classLoader) throws TeaVMToolException {
|
||||||
|
@ -332,7 +402,8 @@ public class TeaVMTestTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void decompileClassesForTest(ClassLoader classLoader, ClassHolderSource classSource,
|
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()
|
TeaVM vm = new TeaVMBuilder()
|
||||||
.setClassLoader(classLoader)
|
.setClassLoader(classLoader)
|
||||||
.setClassSource(classSource)
|
.setClassSource(classSource)
|
||||||
|
@ -347,9 +418,11 @@ public class TeaVMTestTool {
|
||||||
for (ClassHolderTransformer transformer : transformers) {
|
for (ClassHolderTransformer transformer : transformers) {
|
||||||
vm.add(transformer);
|
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;
|
? new DebugInformationBuilder() : null;
|
||||||
|
MethodReference methodRef = testMethod.getMethod();
|
||||||
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
||||||
MethodReference cons = new MethodReference(methodRef.getClassName(), "<init>", ValueType.VOID);
|
MethodReference cons = new MethodReference(methodRef.getClassName(), "<init>", ValueType.VOID);
|
||||||
MethodReference exceptionMsg = new MethodReference(ExceptionHelper.class, "showException",
|
MethodReference exceptionMsg = new MethodReference(ExceptionHelper.class, "showException",
|
||||||
|
@ -362,7 +435,7 @@ public class TeaVMTestTool {
|
||||||
vm.build(innerWriter, new DirectoryBuildTarget(outputDir));
|
vm.build(innerWriter, new DirectoryBuildTarget(outputDir));
|
||||||
innerWriter.append("\n");
|
innerWriter.append("\n");
|
||||||
innerWriter.append("\nJUnitClient.run();");
|
innerWriter.append("\nJUnitClient.run();");
|
||||||
if (sourceMapsGenerated) {
|
if (sourceMapsFileGenerated) {
|
||||||
String sourceMapsFileName = targetName.substring(targetName.lastIndexOf('/') + 1) + ".map";
|
String sourceMapsFileName = targetName.substring(targetName.lastIndexOf('/') + 1) + ".map";
|
||||||
innerWriter.append("\n//# sourceMappingURL=").append(sourceMapsFileName);
|
innerWriter.append("\n//# sourceMappingURL=").append(sourceMapsFileName);
|
||||||
}
|
}
|
||||||
|
@ -376,13 +449,16 @@ public class TeaVMTestTool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sourceMapsGenerated) {
|
|
||||||
|
if (debugInformationGenerated) {
|
||||||
DebugInformation debugInfo = debugInfoBuilder.getDebugInformation();
|
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);
|
debugInfo.write(debugInfoOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sourceMapsGenerated) {
|
|
||||||
|
if (sourceMapsFileGenerated) {
|
||||||
DebugInformation debugInfo = debugInfoBuilder.getDebugInformation();
|
DebugInformation debugInfo = debugInfoBuilder.getDebugInformation();
|
||||||
String sourceMapsFileName = targetName + ".map";
|
String sourceMapsFileName = targetName + ".map";
|
||||||
try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream(
|
try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream(
|
||||||
|
@ -393,6 +469,20 @@ public class TeaVMTestTool {
|
||||||
if (sourceFilesCopied && vm.getWrittenClasses() != null) {
|
if (sourceFilesCopied && vm.getWrittenClasses() != null) {
|
||||||
sourceFilesCopier.addClasses(vm.getWrittenClasses());
|
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 {
|
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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.tooling;
|
package org.teavm.tooling.testing;
|
||||||
|
|
||||||
import org.teavm.dependency.AbstractDependencyListener;
|
import org.teavm.dependency.AbstractDependencyListener;
|
||||||
import org.teavm.dependency.DependencyAgent;
|
import org.teavm.dependency.DependencyAgent;
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.tooling;
|
package org.teavm.tooling.testing;
|
||||||
|
|
||||||
import org.teavm.vm.spi.TeaVMHost;
|
import org.teavm.vm.spi.TeaVMHost;
|
||||||
import org.teavm.vm.spi.TeaVMPlugin;
|
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/slf4j-api-1.7.7.jar,
|
||||||
lib/teavm-chrome-rdp-0.4.0-SNAPSHOT.jar,
|
lib/teavm-chrome-rdp-0.4.0-SNAPSHOT.jar,
|
||||||
lib/teavm-core-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-api-9.2.1.v20140609.jar,
|
||||||
lib/websocket-client-9.2.1.v20140609.jar,
|
lib/websocket-client-9.2.1.v20140609.jar,
|
||||||
lib/websocket-common-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.resource,
|
||||||
org.teavm.testing,
|
org.teavm.testing,
|
||||||
org.teavm.tooling,
|
org.teavm.tooling,
|
||||||
|
org.teavm.tooling.sources,
|
||||||
org.teavm.vm,
|
org.teavm.vm,
|
||||||
org.teavm.vm.spi
|
org.teavm.vm.spi
|
||||||
|
|
|
@ -36,6 +36,7 @@ bin.includes = META-INF/,\
|
||||||
lib/slf4j-api-1.7.7.jar,\
|
lib/slf4j-api-1.7.7.jar,\
|
||||||
lib/teavm-chrome-rdp-0.4.0-SNAPSHOT.jar,\
|
lib/teavm-chrome-rdp-0.4.0-SNAPSHOT.jar,\
|
||||||
lib/teavm-core-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-api-9.2.1.v20140609.jar,\
|
||||||
lib/websocket-client-9.2.1.v20140609.jar,\
|
lib/websocket-client-9.2.1.v20140609.jar,\
|
||||||
lib/websocket-common-9.2.1.v20140609.jar,\
|
lib/websocket-common-9.2.1.v20140609.jar,\
|
||||||
|
|
|
@ -79,6 +79,11 @@
|
||||||
<artifactId>teavm-core</artifactId>
|
<artifactId>teavm-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.teavm</groupId>
|
||||||
|
<artifactId>teavm-tooling</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-chrome-rdp</artifactId>
|
<artifactId>teavm-chrome-rdp</artifactId>
|
||||||
|
|
|
@ -4,7 +4,7 @@ Bundle-Name: TeaVM plugin for m2e
|
||||||
Bundle-SymbolicName: teavm-eclipse-m2e-plugin;singleton:=true
|
Bundle-SymbolicName: teavm-eclipse-m2e-plugin;singleton:=true
|
||||||
Bundle-Version: 0.4.0.qualifier
|
Bundle-Version: 0.4.0.qualifier
|
||||||
Bundle-Vendor: Alexey Andreev <konsoletyper@gmail.com>
|
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)",
|
Require-Bundle: teavm-eclipse-plugin;bundle-version="[0.4.0,0.5.0)",
|
||||||
org.eclipse.m2e.core;bundle-version="[1.3,2)",
|
org.eclipse.m2e.core;bundle-version="[1.3,2)",
|
||||||
org.eclipse.core.runtime;bundle-version="[3.8,4.0)",
|
org.eclipse.core.runtime;bundle-version="[3.8,4.0)",
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<artifactId>teavm-maven-plugin</artifactId>
|
<artifactId>teavm-maven-plugin</artifactId>
|
||||||
<versionRange>0.4.0-SNAPSHOT</versionRange>
|
<versionRange>0.4.0-SNAPSHOT</versionRange>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>build-javascript</goal>
|
<goal>compile</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</pluginExecutionFilter>
|
</pluginExecutionFilter>
|
||||||
<action>
|
<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 TOOL_ID = "teavm-eclipse-m2e-plugin.tool";
|
||||||
private static final String TEAVM_ARTIFACT_ID = "teavm-maven-plugin";
|
private static final String TEAVM_ARTIFACT_ID = "teavm-maven-plugin";
|
||||||
private static final String TEAVM_GROUP_ID = "org.teavm";
|
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 int executionIdGenerator;
|
||||||
private Set<String> usedExecutionIds = new HashSet<>();
|
private Set<String> usedExecutionIds = new HashSet<>();
|
||||||
private IMaven maven;
|
private IMaven maven;
|
||||||
|
|
|
@ -4,7 +4,7 @@ Bundle-Name: TeaVM plugin for Eclipse
|
||||||
Bundle-SymbolicName: teavm-eclipse-plugin;singleton:=true
|
Bundle-SymbolicName: teavm-eclipse-plugin;singleton:=true
|
||||||
Bundle-Version: 0.4.0.qualifier
|
Bundle-Version: 0.4.0.qualifier
|
||||||
Bundle-Vendor: Alexey Andreev <konsoletyper@gmail.com>
|
Bundle-Vendor: Alexey Andreev <konsoletyper@gmail.com>
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||||
Bundle-Activator: org.teavm.eclipse.TeaVMEclipsePlugin
|
Bundle-Activator: org.teavm.eclipse.TeaVMEclipsePlugin
|
||||||
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.8.0,4.0)",
|
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.8.0,4.0)",
|
||||||
org.eclipse.debug.core;bundle-version="[3.7.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.resource,
|
||||||
org.teavm.testing,
|
org.teavm.testing,
|
||||||
org.teavm.tooling,
|
org.teavm.tooling,
|
||||||
|
org.teavm.tooling.sources,
|
||||||
org.teavm.vm,
|
org.teavm.vm,
|
||||||
org.teavm.vm.spi
|
org.teavm.vm.spi
|
||||||
|
|
|
@ -21,22 +21,62 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
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.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import org.eclipse.core.resources.*;
|
import org.eclipse.core.resources.IContainer;
|
||||||
import org.eclipse.core.runtime.*;
|
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.runtime.jobs.Job;
|
||||||
import org.eclipse.core.variables.IStringVariableManager;
|
import org.eclipse.core.variables.IStringVariableManager;
|
||||||
import org.eclipse.core.variables.VariablesPlugin;
|
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.CallGraph;
|
||||||
import org.teavm.callgraph.CallGraphNode;
|
import org.teavm.callgraph.CallGraphNode;
|
||||||
import org.teavm.callgraph.CallSite;
|
import org.teavm.callgraph.CallSite;
|
||||||
import org.teavm.diagnostics.Problem;
|
import org.teavm.diagnostics.Problem;
|
||||||
import org.teavm.diagnostics.ProblemTextConsumer;
|
import org.teavm.diagnostics.ProblemTextConsumer;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.tooling.*;
|
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>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm</artifactId>
|
<artifactId>teavm</artifactId>
|
||||||
<version>0.4.0-SNAPSHOT</version>
|
<version>0.4.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>teavm-eclipse</artifactId>
|
<artifactId>teavm-eclipse</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
|
@ -50,13 +50,30 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-core</artifactId>
|
<artifactId>teavm-tooling</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
</dependency>
|
</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>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
@ -91,6 +108,14 @@
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
</plugin>
|
</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>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</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;
|
package org.teavm.maven;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Constructor;
|
import java.util.Arrays;
|
||||||
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 org.apache.maven.plugin.MojoExecutionException;
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
import org.apache.maven.plugin.logging.Log;
|
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.Mojo;
|
||||||
import org.apache.maven.plugins.annotations.Parameter;
|
import org.apache.maven.plugins.annotations.Parameter;
|
||||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||||
import org.apache.maven.project.MavenProject;
|
import org.teavm.tooling.ClassAlias;
|
||||||
import org.apache.maven.repository.RepositorySystem;
|
import org.teavm.tooling.MethodAlias;
|
||||||
import org.teavm.model.ClassHolderTransformer;
|
import org.teavm.tooling.RuntimeCopyOperation;
|
||||||
import org.teavm.tooling.*;
|
import org.teavm.tooling.TeaVMTool;
|
||||||
|
import org.teavm.tooling.TeaVMToolException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
@Mojo(name = "build-javascript", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME,
|
@Mojo(name = "compile", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME,
|
||||||
requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME)
|
requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME,
|
||||||
public class BuildJavascriptMojo extends AbstractMojo {
|
defaultPhase = LifecyclePhase.PROCESS_CLASSES)
|
||||||
@Component
|
public class BuildJavascriptMojo extends AbstractJavascriptMojo {
|
||||||
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")
|
@Parameter(defaultValue = "${project.build.directory}/javascript")
|
||||||
private File targetDirectory;
|
private File targetDirectory;
|
||||||
|
|
||||||
@Parameter(defaultValue = "${project.build.outputDirectory}")
|
|
||||||
private File classFiles;
|
|
||||||
|
|
||||||
@Parameter
|
|
||||||
private List<String> compileScopes;
|
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private String targetFileName = "classes.js";
|
private String targetFileName = "classes.js";
|
||||||
|
|
||||||
@Parameter
|
|
||||||
private boolean minifying = true;
|
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private String mainClass;
|
private String mainClass;
|
||||||
|
|
||||||
@Parameter
|
|
||||||
private RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE;
|
|
||||||
|
|
||||||
@Parameter
|
|
||||||
private Properties properties;
|
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private boolean mainPageIncluded;
|
private boolean mainPageIncluded;
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private boolean bytecodeLogging;
|
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
|
@Parameter
|
||||||
private ClassAlias[] classAliases;
|
private ClassAlias[] classAliases;
|
||||||
|
|
||||||
|
@ -115,144 +61,37 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
@Parameter
|
@Parameter
|
||||||
private boolean stopOnErrors = true;
|
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();
|
private TeaVMTool tool = new TeaVMTool();
|
||||||
|
|
||||||
public void setProject(MavenProject project) {
|
@Override
|
||||||
this.project = project;
|
protected File getTargetDirectory() {
|
||||||
}
|
return targetDirectory;
|
||||||
|
|
||||||
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
|
@Override
|
||||||
public void execute() throws MojoExecutionException {
|
public void execute() throws MojoExecutionException {
|
||||||
Log log = getLog();
|
Log log = getLog();
|
||||||
|
setupTool(tool);
|
||||||
tool.setLog(new MavenTeaVMToolLog(log));
|
tool.setLog(new MavenTeaVMToolLog(log));
|
||||||
try {
|
try {
|
||||||
ClassLoader classLoader = prepareClassLoader();
|
|
||||||
tool.setClassLoader(classLoader);
|
|
||||||
tool.setBytecodeLogging(bytecodeLogging);
|
tool.setBytecodeLogging(bytecodeLogging);
|
||||||
tool.setMainClass(mainClass);
|
tool.setMainClass(mainClass);
|
||||||
tool.setMainPageIncluded(mainPageIncluded);
|
tool.setMainPageIncluded(mainPageIncluded);
|
||||||
tool.setMinifying(minifying);
|
|
||||||
tool.setRuntime(runtime);
|
tool.setRuntime(runtime);
|
||||||
tool.setTargetDirectory(targetDirectory);
|
|
||||||
tool.setTargetFileName(targetFileName);
|
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) {
|
if (classAliases != null) {
|
||||||
tool.getClassAliases().addAll(Arrays.asList(classAliases));
|
tool.getClassAliases().addAll(Arrays.asList(classAliases));
|
||||||
}
|
}
|
||||||
if (methodAliases != null) {
|
if (methodAliases != null) {
|
||||||
tool.getMethodAliases().addAll(Arrays.asList(methodAliases));
|
tool.getMethodAliases().addAll(Arrays.asList(methodAliases));
|
||||||
}
|
}
|
||||||
if (properties != null) {
|
|
||||||
tool.getProperties().putAll(properties);
|
|
||||||
}
|
|
||||||
tool.setCacheDirectory(cacheDirectory);
|
tool.setCacheDirectory(cacheDirectory);
|
||||||
tool.setIncremental(incremental);
|
|
||||||
tool.setDebugInformationGenerated(debugInformationGenerated);
|
|
||||||
tool.setSourceMapsFileGenerated(sourceMapsGenerated);
|
|
||||||
tool.setSourceFilesCopied(sourceFilesCopied);
|
|
||||||
tool.generate();
|
tool.generate();
|
||||||
if (stopOnErrors && !tool.getProblemProvider().getSevereProblems().isEmpty()) {
|
if (stopOnErrors && !tool.getProblemProvider().getSevereProblems().isEmpty()) {
|
||||||
throw new MojoExecutionException("Build error");
|
throw new MojoExecutionException("Build error");
|
||||||
|
@ -263,75 +102,4 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
throw new MojoExecutionException("IO error occured", e);
|
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;
|
package org.teavm.maven;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.Writer;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.util.Arrays;
|
||||||
import java.net.URLClassLoader;
|
import java.util.Enumeration;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.apache.maven.artifact.Artifact;
|
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.MojoExecutionException;
|
||||||
import org.apache.maven.plugin.MojoFailureException;
|
import org.apache.maven.plugin.MojoFailureException;
|
||||||
import org.apache.maven.plugin.logging.Log;
|
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.Mojo;
|
||||||
import org.apache.maven.plugins.annotations.Parameter;
|
import org.apache.maven.plugins.annotations.Parameter;
|
||||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||||
import org.apache.maven.project.MavenProject;
|
|
||||||
import org.apache.maven.repository.RepositorySystem;
|
|
||||||
import org.teavm.model.ClassHolderTransformer;
|
|
||||||
import org.teavm.testing.JUnitTestAdapter;
|
import org.teavm.testing.JUnitTestAdapter;
|
||||||
import org.teavm.testing.TestAdapter;
|
import org.teavm.testing.TestAdapter;
|
||||||
import org.teavm.tooling.SourceFileProvider;
|
|
||||||
import org.teavm.tooling.TeaVMTestTool;
|
|
||||||
import org.teavm.tooling.TeaVMToolException;
|
import org.teavm.tooling.TeaVMToolException;
|
||||||
|
import org.teavm.tooling.testing.TeaVMTestTool;
|
||||||
|
import org.teavm.tooling.testing.TestPlan;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
@Mojo(name = "build-test-javascript", requiresDependencyResolution = ResolutionScope.TEST,
|
@Mojo(name = "testCompile", requiresDependencyResolution = ResolutionScope.TEST,
|
||||||
requiresDependencyCollection = ResolutionScope.TEST)
|
requiresDependencyCollection = ResolutionScope.TEST,
|
||||||
public class BuildJavascriptTestMojo extends AbstractMojo {
|
defaultPhase = LifecyclePhase.PROCESS_TEST_CLASSES)
|
||||||
|
public class BuildJavascriptTestMojo extends AbstractJavascriptMojo {
|
||||||
private static Set<String> testScopes = new HashSet<>(Arrays.asList(
|
private static Set<String> testScopes = new HashSet<>(Arrays.asList(
|
||||||
Artifact.SCOPE_COMPILE, Artifact.SCOPE_TEST, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME,
|
Artifact.SCOPE_COMPILE, Artifact.SCOPE_TEST, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME,
|
||||||
Artifact.SCOPE_PROVIDED));
|
Artifact.SCOPE_PROVIDED));
|
||||||
|
|
||||||
@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")
|
@Parameter(defaultValue = "${project.build.directory}/javascript-test")
|
||||||
private File outputDir;
|
private File targetDirectory;
|
||||||
|
|
||||||
@Parameter(defaultValue = "${project.build.outputDirectory}")
|
|
||||||
private File classFiles;
|
|
||||||
|
|
||||||
@Parameter(defaultValue = "${project.build.testOutputDirectory}")
|
@Parameter(defaultValue = "${project.build.testOutputDirectory}")
|
||||||
private File testFiles;
|
private File testFiles;
|
||||||
|
@ -86,9 +69,6 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
||||||
@Parameter
|
@Parameter
|
||||||
private String[] excludeWildcards = new String[0];
|
private String[] excludeWildcards = new String[0];
|
||||||
|
|
||||||
@Parameter
|
|
||||||
private boolean minifying = true;
|
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private boolean scanDependencies;
|
private boolean scanDependencies;
|
||||||
|
|
||||||
|
@ -98,153 +78,47 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
||||||
@Parameter
|
@Parameter
|
||||||
private String adapterClass = JUnitTestAdapter.class.getName();
|
private String adapterClass = JUnitTestAdapter.class.getName();
|
||||||
|
|
||||||
@Parameter
|
|
||||||
private String[] transformers;
|
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private String[] additionalScripts;
|
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();
|
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
|
@Override
|
||||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||||
if (System.getProperty("maven.test.skip", "false").equals("true") ||
|
if (System.getProperty("maven.test.skip", "false").equals("true")
|
||||||
System.getProperty("skipTests") != null) {
|
|| System.getProperty("skipTests") != null) {
|
||||||
getLog().info("Tests build skipped as specified by system property");
|
getLog().info("Tests build skipped as specified by system property");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setupTool(tool);
|
||||||
try {
|
try {
|
||||||
final ClassLoader classLoader = prepareClassLoader();
|
|
||||||
getLog().info("Searching for tests in the directory `" + testFiles.getAbsolutePath() + "'");
|
getLog().info("Searching for tests in the directory `" + testFiles.getAbsolutePath() + "'");
|
||||||
tool.setClassLoader(classLoader);
|
|
||||||
tool.setAdapter(createAdapter(classLoader));
|
tool.setAdapter(createAdapter(classLoader));
|
||||||
findTestClasses(classLoader, testFiles, "");
|
findTestClasses(classLoader, testFiles, "");
|
||||||
if (scanDependencies) {
|
if (scanDependencies) {
|
||||||
findTestsInDependencies(classLoader);
|
findTestsInDependencies(classLoader);
|
||||||
}
|
}
|
||||||
tool.getTransformers().addAll(instantiateTransformers(classLoader));
|
|
||||||
tool.setLog(new MavenTeaVMToolLog(getLog()));
|
|
||||||
tool.setOutputDir(outputDir);
|
|
||||||
tool.setNumThreads(numThreads);
|
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) {
|
if (additionalScripts != null) {
|
||||||
tool.getAdditionalScripts().addAll(Arrays.asList(additionalScripts));
|
tool.getAdditionalScripts().addAll(Arrays.asList(additionalScripts));
|
||||||
}
|
}
|
||||||
tool.generate();
|
writePlan(tool.generate());
|
||||||
} catch (TeaVMToolException e) {
|
} catch (TeaVMToolException e) {
|
||||||
throw new MojoFailureException("Error occured generating JavaScript files", 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 {
|
private TestAdapter createAdapter(ClassLoader classLoader) throws MojoExecutionException {
|
||||||
Class<?> adapterClsRaw;
|
Class<?> adapterClsRaw;
|
||||||
try {
|
try {
|
||||||
|
@ -253,8 +127,8 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
||||||
throw new MojoExecutionException("Adapter not found: " + adapterClass, e);
|
throw new MojoExecutionException("Adapter not found: " + adapterClass, e);
|
||||||
}
|
}
|
||||||
if (!TestAdapter.class.isAssignableFrom(adapterClsRaw)) {
|
if (!TestAdapter.class.isAssignableFrom(adapterClsRaw)) {
|
||||||
throw new MojoExecutionException("Adapter " + adapterClass + " does not implement " +
|
throw new MojoExecutionException("Adapter " + adapterClass + " does not implement "
|
||||||
TestAdapter.class.getName());
|
+ TestAdapter.class.getName());
|
||||||
}
|
}
|
||||||
Class<? extends TestAdapter> adapterCls = adapterClsRaw.asSubclass(TestAdapter.class);
|
Class<? extends TestAdapter> adapterCls = adapterClsRaw.asSubclass(TestAdapter.class);
|
||||||
Constructor<? extends TestAdapter> cons;
|
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 {
|
private void findTestsInDependencies(ClassLoader classLoader) throws MojoExecutionException {
|
||||||
try {
|
try {
|
||||||
Log log = getLog();
|
Log log = getLog();
|
||||||
|
@ -384,39 +226,18 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected File getTargetDirectory() {
|
||||||
|
return targetDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
private List<ClassHolderTransformer> instantiateTransformers(ClassLoader classLoader)
|
@Override
|
||||||
throws MojoExecutionException {
|
protected List<File> getAdditionalClassPath() {
|
||||||
List<ClassHolderTransformer> transformerInstances = new ArrayList<>();
|
return Arrays.asList(testFiles);
|
||||||
if (transformers == null) {
|
}
|
||||||
return transformerInstances;
|
|
||||||
}
|
@Override
|
||||||
for (String transformerName : transformers) {
|
protected boolean isSupportedScope(String scope) {
|
||||||
Class<?> transformerRawType;
|
return testScopes.contains(scope);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.artifact.resolver.ArtifactResolutionResult;
|
||||||
import org.apache.maven.project.MavenProject;
|
import org.apache.maven.project.MavenProject;
|
||||||
import org.apache.maven.repository.RepositorySystem;
|
import org.apache.maven.repository.RepositorySystem;
|
||||||
import org.teavm.tooling.DirectorySourceFileProvider;
|
import org.teavm.tooling.sources.DirectorySourceFileProvider;
|
||||||
import org.teavm.tooling.JarSourceFileProvider;
|
import org.teavm.tooling.sources.JarSourceFileProvider;
|
||||||
import org.teavm.tooling.SourceFileProvider;
|
import org.teavm.tooling.sources.SourceFileProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -85,7 +85,12 @@ public class MavenSourceFileProviderLookup {
|
||||||
ArtifactResolutionResult result = repositorySystem.resolve(request);
|
ArtifactResolutionResult result = repositorySystem.resolve(request);
|
||||||
for (Artifact resolvedArtifact : result.getArtifacts()) {
|
for (Artifact resolvedArtifact : result.getArtifacts()) {
|
||||||
if (resolvedArtifact.getFile() != null) {
|
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;
|
package org.teavm.maven;
|
||||||
|
|
||||||
import org.apache.maven.plugin.logging.Log;
|
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>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm</artifactId>
|
<artifactId>teavm</artifactId>
|
||||||
<version>0.4.0-SNAPSHOT</version>
|
<version>0.4.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>teavm-maven</artifactId>
|
<artifactId>teavm-maven</artifactId>
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<packaging>war</packaging>
|
<packaging>war</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>1.7</java.version>
|
<java.version>1.8</java.version>
|
||||||
<teavm.version>0.4.0-SNAPSHOT</teavm.version>
|
<teavm.version>0.4.0-SNAPSHOT</teavm.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
@ -25,15 +25,7 @@
|
||||||
<!-- JavaScriptObjects (JSO) - a JavaScript binding for TeaVM -->
|
<!-- JavaScriptObjects (JSO) - a JavaScript binding for TeaVM -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-jso</artifactId>
|
<artifactId>teavm-jso-apis</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>
|
|
||||||
<version>${teavm.version}</version>
|
<version>${teavm.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -80,9 +72,8 @@
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>web-client</id>
|
<id>web-client</id>
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>build-javascript</goal>
|
<goal>compile</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<!-- Directory where TeaVM should put generated files. This configuration conforms to the settings
|
<!-- Directory where TeaVM should put generated files. This configuration conforms to the settings
|
||||||
|
@ -92,9 +83,6 @@
|
||||||
<!-- Main class, containing static void main(String[]) -->
|
<!-- Main class, containing static void main(String[]) -->
|
||||||
<mainClass>${package}.Client</mainClass>
|
<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
|
<!-- Whether TeaVM should produce minified JavaScript. Can reduce JavaScript file size more than
|
||||||
two times -->
|
two times -->
|
||||||
<minifying>true</minifying>
|
<minifying>true</minifying>
|
||||||
|
|