From bac0785dc665b9db615313c80de7183c20cc76c3 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sat, 10 Oct 2015 11:06:30 +0300 Subject: [PATCH] Add HtmlUnit test runner. Add travis + Sauce Labs config --- .travis.yml | 7 +- tests/pom.xml | 2 + tools/maven/plugin/pom.xml | 13 +++ .../teavm/maven/AbstractJavascriptMojo.java | 4 +- .../teavm/maven/BuildJavascriptTestMojo.java | 8 +- .../org/teavm/maven/HtmlUnitRunStrategy.java | 107 ++++++++++++++++++ .../org/teavm/maven/MavenTeaVMToolLog.java | 15 +++ .../java/org/teavm/maven/RunTestsMojo.java | 33 ++++-- .../org/teavm/maven/SeleniumRunStrategy.java | 95 ++++++++++++++++ .../main/java/org/teavm/maven/TestReport.java | 15 +++ .../java/org/teavm/maven/TestRunStrategy.java | 32 ++++++ ...eleniumTestRunner.java => TestRunner.java} | 90 ++++----------- .../main/resources/teavm-htmlunit-adapter.js | 65 +++++++++++ 13 files changed, 397 insertions(+), 89 deletions(-) create mode 100644 tools/maven/plugin/src/main/java/org/teavm/maven/HtmlUnitRunStrategy.java create mode 100644 tools/maven/plugin/src/main/java/org/teavm/maven/SeleniumRunStrategy.java create mode 100644 tools/maven/plugin/src/main/java/org/teavm/maven/TestRunStrategy.java rename tools/maven/plugin/src/main/java/org/teavm/maven/{SeleniumTestRunner.java => TestRunner.java} (61%) create mode 100644 tools/maven/plugin/src/main/resources/teavm-htmlunit-adapter.js diff --git a/.travis.yml b/.travis.yml index c892b40dc..92edf3e8c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,4 +5,9 @@ cache: directories: - $HOME/.m2 after_script: - - rm -rf $HOME/.m2/repository/org/teavm \ No newline at end of file + - rm -rf $HOME/.m2/repository/org/teavm +script: + - mvn test \ + - -Pteavm.test.skip=false \ + - -Pteavm.test.selenium="http://$SAUCE_USER_NAME:$SAUCE_ACCESS_KEY@ondemand.saucelabs.com:80/wd/hub" \ + - -Pteavm.test.threads=2 \ No newline at end of file diff --git a/tests/pom.xml b/tests/pom.xml index 17b57350d..002d0faef 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -31,6 +31,7 @@ false 1 + true @@ -100,6 +101,7 @@ test + ${teavm.test.skip} ${teavm.test.threads} ${teavm.test.selenium} diff --git a/tools/maven/plugin/pom.xml b/tools/maven/plugin/pom.xml index 34fe8454c..2c7e153df 100644 --- a/tools/maven/plugin/pom.xml +++ b/tools/maven/plugin/pom.xml @@ -69,6 +69,11 @@ com.fasterxml.jackson.core jackson-databind + + net.sourceforge.htmlunit + htmlunit + 2.18 + junit junit @@ -103,6 +108,14 @@ org.apache.maven.plugins maven-javadoc-plugin + + org.apache.maven.plugins + maven-checkstyle-plugin + + ../../../checkstyle.xml + config_loc=${basedir}/../../.. + + diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/AbstractJavascriptMojo.java b/tools/maven/plugin/src/main/java/org/teavm/maven/AbstractJavascriptMojo.java index 6446e3441..cb43846e3 100644 --- a/tools/maven/plugin/src/main/java/org/teavm/maven/AbstractJavascriptMojo.java +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/AbstractJavascriptMojo.java @@ -106,8 +106,8 @@ public abstract class AbstractJavascriptMojo extends AbstractMojo { 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()); + throw new MojoExecutionException("Transformer " + transformerName + " is not subtype of " + + ClassHolderTransformer.class.getName()); } Class transformerType = transformerRawType.asSubclass( ClassHolderTransformer.class); diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/BuildJavascriptTestMojo.java b/tools/maven/plugin/src/main/java/org/teavm/maven/BuildJavascriptTestMojo.java index 5beb6c135..7b8618570 100644 --- a/tools/maven/plugin/src/main/java/org/teavm/maven/BuildJavascriptTestMojo.java +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/BuildJavascriptTestMojo.java @@ -85,8 +85,8 @@ public class BuildJavascriptTestMojo extends AbstractJavascriptMojo { @Override public void execute() throws MojoExecutionException, MojoFailureException { - if (System.getProperty("maven.test.skip", "false").equals("true") || - System.getProperty("skipTests") != null) { + if (System.getProperty("maven.test.skip", "false").equals("true") + || System.getProperty("skipTests") != null) { getLog().info("Tests build skipped as specified by system property"); return; } @@ -127,8 +127,8 @@ public class BuildJavascriptTestMojo extends AbstractJavascriptMojo { throw new MojoExecutionException("Adapter not found: " + adapterClass, e); } if (!TestAdapter.class.isAssignableFrom(adapterClsRaw)) { - throw new MojoExecutionException("Adapter " + adapterClass + " does not implement " + - TestAdapter.class.getName()); + throw new MojoExecutionException("Adapter " + adapterClass + " does not implement " + + TestAdapter.class.getName()); } Class adapterCls = adapterClsRaw.asSubclass(TestAdapter.class); Constructor cons; diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/HtmlUnitRunStrategy.java b/tools/maven/plugin/src/main/java/org/teavm/maven/HtmlUnitRunStrategy.java new file mode 100644 index 000000000..0b7b24a57 --- /dev/null +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/HtmlUnitRunStrategy.java @@ -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; + } + } + } +} diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/MavenTeaVMToolLog.java b/tools/maven/plugin/src/main/java/org/teavm/maven/MavenTeaVMToolLog.java index 862f5c605..1208d4a25 100644 --- a/tools/maven/plugin/src/main/java/org/teavm/maven/MavenTeaVMToolLog.java +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/MavenTeaVMToolLog.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.teavm.maven; import org.apache.maven.plugin.logging.Log; 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 8bfd3857e..2c0b82354 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 @@ -53,28 +53,25 @@ public class RunTestsMojo extends AbstractMojo { @Parameter private int numThreads = 1; + @Parameter + private boolean skip; + @Override public void execute() throws MojoExecutionException, MojoFailureException { - if (seleniumURL == null || seleniumURL.isEmpty()) { - getLog().info("Tests build skipped as selenium URL was not specified"); + 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 build skipped as specified by system property"); + if (System.getProperty("maven.test.skip", "false").equals("true") + || System.getProperty("skipTests") != null) { + getLog().info("Tests run skipped as specified by system property"); return; } - SeleniumTestRunner runner = new SeleniumTestRunner(); + TestRunner runner = new TestRunner(pickStrategy()); runner.setLog(getLog()); - runner.setDirectory(testDirectory); runner.setNumThreads(numThreads); - try { - runner.setUrl(new URL(seleniumURL)); - } catch (MalformedURLException e) { - throw new MojoFailureException("Can't parse URL: " + seleniumURL, e); - } TestPlan plan; ObjectMapper mapper = new ObjectMapper(); @@ -89,6 +86,18 @@ public class RunTestsMojo extends AbstractMojo { 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"); diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/SeleniumRunStrategy.java b/tools/maven/plugin/src/main/java/org/teavm/maven/SeleniumRunStrategy.java new file mode 100644 index 000000000..1bb827c43 --- /dev/null +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/SeleniumRunStrategy.java @@ -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 = 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 errors = (List) 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"); + } + } +} diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/TestReport.java b/tools/maven/plugin/src/main/java/org/teavm/maven/TestReport.java index d8fab47b1..c6e57d502 100644 --- a/tools/maven/plugin/src/main/java/org/teavm/maven/TestReport.java +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/TestReport.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.teavm.maven; import java.util.ArrayList; diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/TestRunStrategy.java b/tools/maven/plugin/src/main/java/org/teavm/maven/TestRunStrategy.java new file mode 100644 index 000000000..8c1bcc745 --- /dev/null +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/TestRunStrategy.java @@ -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; +} diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/SeleniumTestRunner.java b/tools/maven/plugin/src/main/java/org/teavm/maven/TestRunner.java similarity index 61% rename from tools/maven/plugin/src/main/java/org/teavm/maven/SeleniumTestRunner.java rename to tools/maven/plugin/src/main/java/org/teavm/maven/TestRunner.java index b90e7da2c..3594cfec6 100644 --- a/tools/maven/plugin/src/main/java/org/teavm/maven/SeleniumTestRunner.java +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/TestRunner.java @@ -17,11 +17,7 @@ package org.teavm.maven; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; -import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.concurrent.BlockingQueue; @@ -29,13 +25,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; 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.model.MethodReference; import org.teavm.tooling.testing.TestCase; import org.teavm.tooling.testing.TestGroup; @@ -45,38 +35,24 @@ import org.teavm.tooling.testing.TestPlan; * * @author Alexey Andreev */ -public class SeleniumTestRunner { - private URL url; +public class TestRunner { private int numThreads = 1; - private ThreadLocal webDriver = new ThreadLocal<>(); - private BlockingQueue seleniumTaskQueue = new LinkedBlockingQueue<>(); + private TestRunStrategy strategy; + private BlockingQueue taskQueue = new LinkedBlockingQueue<>(); private CountDownLatch latch; - private volatile boolean seleniumStopped = false; + private volatile boolean stopped; private Log log; private List report = new CopyOnWriteArrayList<>(); private ThreadLocal> localReport = new ThreadLocal<>(); - private File directory = new File("."); - public URL getUrl() { - return url; - } - - public void setUrl(URL url) { - this.url = url; + public TestRunner(TestRunStrategy strategy) { + this.strategy = strategy; } public void setLog(Log log) { this.log = log; } - public File getDirectory() { - return directory; - } - - public void setDirectory(File directory) { - this.directory = directory; - } - public int getNumThreads() { return numThreads; } @@ -100,13 +76,12 @@ public class SeleniumTestRunner { latch = new CountDownLatch(numThreads); for (int i = 0; i < numThreads; ++i) { new Thread(() -> { - RemoteWebDriver driver = new RemoteWebDriver(DesiredCapabilities.chrome()); - webDriver.set(driver); + strategy.beforeThread(); localReport.set(new ArrayList<>()); - while (!seleniumStopped || !seleniumTaskQueue.isEmpty()) { + while (!stopped || !taskQueue.isEmpty()) { Runnable task; try { - task = seleniumTaskQueue.poll(100, TimeUnit.MILLISECONDS); + task = taskQueue.poll(100, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { break; } @@ -116,19 +91,18 @@ public class SeleniumTestRunner { } report.addAll(localReport.get()); localReport.remove(); - webDriver.get().close(); - webDriver.remove(); + strategy.afterThread(); latch.countDown(); }).start(); } } - private void addSeleniumTask(Runnable runnable) { - seleniumTaskQueue.add(runnable); + private void addTask(Runnable runnable) { + taskQueue.add(runnable); } private void stopSelenium() { - seleniumStopped = true; + stopped = true; } private void waitForCompletion() { @@ -140,22 +114,20 @@ public class SeleniumTestRunner { } private void run(String runtimeScript, TestCase testCase) { - addSeleniumTask(() -> runImpl(runtimeScript, testCase)); + addTask(() -> runImpl(runtimeScript, testCase)); } private void runImpl(String runtimeScript, TestCase testCase) { - webDriver.get().manage().timeouts().setScriptTimeout(2, TimeUnit.SECONDS); - JavascriptExecutor js = (JavascriptExecutor) webDriver.get(); + MethodReference ref = MethodReference.parse(testCase.getTestMethod()); try { - String result = (String) js.executeAsyncScript( - readResource("teavm-selenium.js"), - readFile(new File(directory, runtimeScript)), - readFile(new File(directory, testCase.getTestScript())), - readResource("teavm-selenium-adapter.js")); + 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(); - MethodReference ref = MethodReference.parse(testCase.getTestMethod()); switch (status) { case "ok": if (testCase.getExpectedExceptions().isEmpty()) { @@ -181,28 +153,6 @@ public class SeleniumTestRunner { } } catch (IOException e) { log.error(e); - } catch (WebDriverException e) { - log.error("Error occured running test " + testCase.getTestMethod(), e); - @SuppressWarnings("unchecked") - List errors = (List) js.executeScript("return window.jsErrors;"); - for (Object error : errors) { - log.error(" -- additional error: " + error); - } - } - } - - 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"); } } diff --git a/tools/maven/plugin/src/main/resources/teavm-htmlunit-adapter.js b/tools/maven/plugin/src/main/resources/teavm-htmlunit-adapter.js new file mode 100644 index 000000000..93d549474 --- /dev/null +++ b/tools/maven/plugin/src/main/resources/teavm-htmlunit-adapter.js @@ -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; +} \ No newline at end of file