diff --git a/tests/pom.xml b/tests/pom.xml
index 002d0faef..c548b3c99 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -76,6 +76,7 @@
teavm-maven-plugin
${project.version}
+
run-javascript-tests
diff --git a/tools/core/src/main/java/org/teavm/tooling/testing/TeaVMTestTool.java b/tools/core/src/main/java/org/teavm/tooling/testing/TeaVMTestTool.java
index b65841aa6..07ed45c81 100644
--- a/tools/core/src/main/java/org/teavm/tooling/testing/TeaVMTestTool.java
+++ b/tools/core/src/main/java/org/teavm/tooling/testing/TeaVMTestTool.java
@@ -209,6 +209,7 @@ public class TeaVMTestTool implements BaseTeaVMTool {
resourceToFile("org/teavm/javascript/runtime.js", "res/runtime.js");
String prefix = "org/teavm/tooling/test";
resourceToFile(prefix + "/res/junit-support.js", "res/junit-support.js");
+ resourceToFile(prefix + "/res/junit-client.js", "res/junit-client.js");
resourceToFile(prefix + "/res/junit.css", "res/junit.css");
resourceToFile(prefix + "/res/class_obj.png", "res/class_obj.png");
resourceToFile(prefix + "/res/control-000-small.png", "res/control-000-small.png");
@@ -219,6 +220,7 @@ public class TeaVMTestTool implements BaseTeaVMTool {
resourceToFile(prefix + "/res/toggle-small-expand.png", "res/toggle-small-expand.png");
resourceToFile(prefix + "/res/toggle-small.png", "res/toggle-small.png");
resourceToFile(prefix + "/junit.html", "junit.html");
+ resourceToFile(prefix + "/junit-client.html", "junit-client.html");
ClassHolderSource classSource = new ClasspathClassHolderSource(classLoader);
if (incremental) {
classSource = new PreOptimizingClassHolderSource(classSource);
diff --git a/tools/core/src/main/resources/org/teavm/tooling/test/junit-client.html b/tools/core/src/main/resources/org/teavm/tooling/test/junit-client.html
new file mode 100644
index 000000000..81ad7fcf4
--- /dev/null
+++ b/tools/core/src/main/resources/org/teavm/tooling/test/junit-client.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tools/core/src/main/resources/org/teavm/tooling/test/junit.html b/tools/core/src/main/resources/org/teavm/tooling/test/junit.html
index 06b655d11..b16073ed8 100644
--- a/tools/core/src/main/resources/org/teavm/tooling/test/junit.html
+++ b/tools/core/src/main/resources/org/teavm/tooling/test/junit.html
@@ -18,7 +18,6 @@
TeaVM JUnit tests
- TeaVM JUnit tests
diff --git a/tools/core/src/main/resources/org/teavm/tooling/test/res/junit-client.js b/tools/core/src/main/resources/org/teavm/tooling/test/res/junit-client.js
new file mode 100644
index 000000000..638402aba
--- /dev/null
+++ b/tools/core/src/main/resources/org/teavm/tooling/test/res/junit-client.js
@@ -0,0 +1,95 @@
+"use strict";
+var JUnitClient = {};
+JUnitClient.run = function() {
+ var handler = function(event) {
+ switch (event.data.command) {
+ case "runTest":
+ window.removeEventListener("message", handler);
+ $rt_startThread(function() {
+ JUnitClient.runTest();
+ });
+ break;
+ }
+ }
+ window.addEventListener("message", handler);
+ window.parent.postMessage("ready", "*");
+}
+JUnitClient.runTest = 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(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;
+}
+JUnitClient.reportError = function(error) {
+ var handler = function() {
+ window.removeEventListener("message", handler);
+ var message = { status : "exception", stack : error };
+ window.parent.postMessage(message, "*");
+ };
+ window.addEventListener("message", handler);
+}
+JUnitClient.loadScript = function(scriptPath) {
+ var script = document.createElement("script");
+ script.src = scriptPath;
+ document.body.appendChild(script);
+}
+window.addEventListener("message", function(event) {
+ var data = event.data;
+ switch (data.command) {
+ case "loadScript":
+ JUnitClient.loadScript(data.script);
+ break;
+ }
+});
+window.parent.postMessage("loaded", "*");
\ No newline at end of file
diff --git a/tools/core/src/main/resources/org/teavm/tooling/test/res/junit-support.js b/tools/core/src/main/resources/org/teavm/tooling/test/res/junit-support.js
index 29e87ac6f..216fd3529 100644
--- a/tools/core/src/main/resources/org/teavm/tooling/test/res/junit-support.js
+++ b/tools/core/src/main/resources/org/teavm/tooling/test/res/junit-support.js
@@ -77,34 +77,29 @@ JUnitServer.prototype.isExpectedException = function(ex) {
}
JUnitServer.prototype.loadCode = function(path, additionalScripts, callback) {
this.frame = document.createElement("iframe");
+ this.frame.src = "junit-client.html";
document.body.appendChild(this.frame);
- var frameDoc = this.frame.contentWindow.document;
- var self = this;
- var sequence = ["res/junit-support.js", "res/runtime.js"];
- if (additionalScripts) {
- for (var i = 0; i < additionalScripts.length; ++i) {
- sequence.push(additionalScripts[i]);
- }
- }
+ var sequence = [];
sequence.push(path);
- self.loadScripts(sequence, 0, callback);
-}
-JUnitServer.prototype.loadScripts = function(scripts, index, callback) {
+ for (var i = 0; i < additionalScripts.length; ++i) {
+ sequence.push(additionalScripts[i]);
+ }
var self = this;
- if (index == scripts.length) {
- callback();
- } else {
- this.loadScript(scripts[index], function() { self.loadScripts(scripts, index + 1, callback) });
+ var handler = function() {
+ window.removeEventListener("message", handler);
+ self.loadScripts(sequence, callback);
}
+ window.addEventListener("message", handler);
}
-JUnitServer.prototype.loadScript = function(name, callback) {
- var doc = this.frame.contentWindow.document;
- var script = doc.createElement("script");
- script.src = name;
- doc.body.appendChild(script);
- script.onload = function() {
+JUnitServer.prototype.loadScripts = function(scripts, callback) {
+ for (var i = 0; i < scripts.length; ++i) {
+ this.frame.contentWindow.postMessage({ command : "loadScript", "script" : scripts[i] }, "*");
+ }
+ var handler = function() {
+ window.removeEventListener("message", handler);
callback();
}
+ window.addEventListener("message", handler);
}
JUnitServer.prototype.runTest = function(node, callback) {
node.indicator.className = "complete-indicator in-progress";
@@ -118,10 +113,10 @@ JUnitServer.prototype.runTest = function(node, callback) {
window.removeEventListener("message", messageHandler);
var timeSpent = new Date().getTime() - startTime;
node.timeIndicator.appendChild(document.createTextNode("(" + (timeSpent / 1000).toFixed(3) + ")"));
- self.handleEvent(JSON.parse(event.data), callback);
+ self.handleEvent(event.data, callback);
};
window.addEventListener("message", messageHandler);
- self.frame.contentWindow.postMessage("runTest", "*");
+ self.frame.contentWindow.postMessage({ command : "runTest" }, "*");
});
} else {
var self = this;
@@ -364,72 +359,4 @@ TreeNode.prototype.select = function() {
for (var i = 0; i < this.tree.selectionListeners.length; ++i) {
this.tree.selectionListeners[i](this);
}
-}
-
-var JUnitClient = {};
-JUnitClient.run = function() {
- var handler = window.addEventListener("message", $rt_threadStarter(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;
-}
-JUnitClient.reportError = function(error) {
- var handler = window.addEventListener("message", function() {
- window.removeEventListener("message", handler);
- var message = { status : "exception", stack : error };
- window.parent.postMessage(JSON.stringify(message), "*");
- });
}
\ No newline at end of file
diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/RunTestsMojo.java b/tools/maven/plugin/src/main/java/org/teavm/maven/RunTestsMojo.java
index 2c0b82354..982f87cd3 100644
--- a/tools/maven/plugin/src/main/java/org/teavm/maven/RunTestsMojo.java
+++ b/tools/maven/plugin/src/main/java/org/teavm/maven/RunTestsMojo.java
@@ -111,12 +111,6 @@ public class RunTestsMojo extends AbstractMojo {
}
}
- 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")) {
@@ -124,5 +118,11 @@ public class RunTestsMojo extends AbstractMojo {
} catch (IOException e) {
throw new MojoFailureException("Error writing test report", e);
}
+
+ 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");
+ }
}
}