From 2a3b0cd5976d4b15daef0381105402fa92e303cc Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 4 Nov 2016 13:21:01 +0300 Subject: [PATCH] Fix generation of variable names in minified mode (fix #227). JUnit runner can be configured to run tests in minified and optimized modes. Apply these modes to travis config. --- .idea/runConfigurations/run_tests.xml | 4 +- .travis.yml | 4 +- .../javascript/rendering/RenderingUtil.java | 9 ++- .../teavm/junit/TeaVMTestConfiguration.java | 79 +++++++++++++++++++ .../java/org/teavm/junit/TeaVMTestRunner.java | 63 ++++++++++++--- 5 files changed, 139 insertions(+), 20 deletions(-) create mode 100644 tools/junit/src/main/java/org/teavm/junit/TeaVMTestConfiguration.java diff --git a/.idea/runConfigurations/run_tests.xml b/.idea/runConfigurations/run_tests.xml index ea56f5fb0..cc23b742d 100644 --- a/.idea/runConfigurations/run_tests.xml +++ b/.idea/runConfigurations/run_tests.xml @@ -13,7 +13,7 @@ - + diff --git a/.travis.yml b/.travis.yml index 999c9e059..1de572b60 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,8 @@ script: > mvn -e test \ -Dteavm.junit.target=target/js-tests \ -Dteavm.junit.js.runner=htmlunit \ - -Dteavm.junit.js.threads=1 + -Dteavm.junit.js.threads=1 \ + -Dteavm.junit.optimized=true \ + -Dteavm.junit.minified=true after_script: - rm -rf $HOME/.m2/repository/org/teavm \ No newline at end of file diff --git a/core/src/main/java/org/teavm/backend/javascript/rendering/RenderingUtil.java b/core/src/main/java/org/teavm/backend/javascript/rendering/RenderingUtil.java index f14be7d5c..226925e95 100644 --- a/core/src/main/java/org/teavm/backend/javascript/rendering/RenderingUtil.java +++ b/core/src/main/java/org/teavm/backend/javascript/rendering/RenderingUtil.java @@ -16,8 +16,8 @@ package org.teavm.backend.javascript.rendering; public final class RenderingUtil { - public static final String variableNames = "abcdefghijkmnopqrstuvwxyz"; - public static final String variablePartNames = "abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + private static final String variableNames = "abcdefghijkmnopqrstuvwxyz"; + private static final String variablePartNames = "abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; private RenderingUtil() { } @@ -75,10 +75,11 @@ public final class RenderingUtil { public static String indexToId(int index) { StringBuilder sb = new StringBuilder(); - do { + sb.append(variableNames.charAt(index % variableNames.length())); + while (index > 0) { sb.append(variablePartNames.charAt(index % variablePartNames.length())); index /= variablePartNames.length(); - } while (index > 0); + } return sb.toString(); } } diff --git a/tools/junit/src/main/java/org/teavm/junit/TeaVMTestConfiguration.java b/tools/junit/src/main/java/org/teavm/junit/TeaVMTestConfiguration.java new file mode 100644 index 000000000..98c0731ee --- /dev/null +++ b/tools/junit/src/main/java/org/teavm/junit/TeaVMTestConfiguration.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016 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.junit; + +import org.teavm.backend.javascript.JavaScriptTarget; +import org.teavm.vm.TeaVM; +import org.teavm.vm.TeaVMOptimizationLevel; + +interface TeaVMTestConfiguration { + String getSuffix(); + + void apply(TeaVM vm); + + void apply(JavaScriptTarget target); + + TeaVMTestConfiguration DEFAULT = new TeaVMTestConfiguration() { + @Override + public String getSuffix() { + return ""; + } + + @Override + public void apply(TeaVM vm) { + vm.setOptimizationLevel(TeaVMOptimizationLevel.SIMPLE); + } + + @Override + public void apply(JavaScriptTarget target) { + target.setMinifying(false); + } + }; + + TeaVMTestConfiguration OPTIMIZED = new TeaVMTestConfiguration() { + @Override + public String getSuffix() { + return "optimized"; + } + + @Override + public void apply(TeaVM vm) { + vm.setOptimizationLevel(TeaVMOptimizationLevel.FULL); + } + + @Override + public void apply(JavaScriptTarget target) { + target.setMinifying(false); + } + }; + + TeaVMTestConfiguration MINIFIED = new TeaVMTestConfiguration() { + @Override + public String getSuffix() { + return "min"; + } + + @Override + public void apply(TeaVM vm) { + vm.setOptimizationLevel(TeaVMOptimizationLevel.SIMPLE); + } + + @Override + public void apply(JavaScriptTarget target) { + target.setMinifying(true); + } + }; +} diff --git a/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java b/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java index acb8f5e8b..6a1daefc7 100644 --- a/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java +++ b/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java @@ -37,6 +37,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; import java.util.stream.Stream; import org.apache.commons.io.IOUtils; import org.junit.runner.Description; @@ -199,7 +200,21 @@ public class TeaVMTestRunner extends Runner { } if (success && outputDir != null) { - runInTeaVM(child, notifier, expectedExceptions); + Description description = describeChild(child); + List configurations = getConfigurations(); + int[] configurationIndex = new int[] { 0 }; + List> onSuccess = new ArrayList<>(); + + onSuccess.add(runSuccess -> { + if (runSuccess && configurationIndex[0] < configurations.size()) { + runInTeaVM(child, notifier, expectedExceptions, configurations.get(configurationIndex[0]++), + onSuccess.get(0)); + } else { + notifier.fireTestFinished(description); + latch.countDown(); + } + }); + onSuccess.get(0).accept(true); } else { if (!run) { notifier.fireTestIgnored(describeChild(child)); @@ -247,41 +262,41 @@ public class TeaVMTestRunner extends Runner { return true; } - private boolean runInTeaVM(Method child, RunNotifier notifier, Set> expectedExceptions) { + private boolean runInTeaVM(Method child, RunNotifier notifier, Set> expectedExceptions, + TeaVMTestConfiguration configuration, Consumer onComplete) { Description description = describeChild(child); CompileResult compileResult; try { - compileResult = compileTest(child); - } catch (IOException e) { + compileResult = compileTest(child, configuration); + } catch (Exception e) { notifier.fireTestFailure(new Failure(description, e)); + onComplete.accept(false); return false; } if (!compileResult.success) { notifier.fireTestFailure(new Failure(description, new AssertionError(compileResult.errorMessage))); - notifier.fireTestFinished(description); - latch.countDown(); + onComplete.accept(false); return false; } if (runStrategy == null) { - notifier.fireTestFinished(description); - latch.countDown(); + onComplete.accept(true); return true; } TestRunCallback callback = new TestRunCallback() { @Override public void complete() { - notifier.fireTestFinished(description); - latch.countDown(); + onComplete.accept(true); } @Override public void error(Throwable e) { notifier.fireTestFailure(new Failure(description, e)); + onComplete.accept(false); } }; @@ -325,14 +340,22 @@ public class TeaVMTestRunner extends Runner { } } - private CompileResult compileTest(Method method) throws IOException { + private CompileResult compileTest(Method method, TeaVMTestConfiguration configuration) throws IOException { CompileResult result = new CompileResult(); File path = outputDir; path = new File(path, method.getDeclaringClass().getName().replace('.', '/')); path = new File(path, method.getName()); path.mkdirs(); - File outputFile = new File(path, "test.js"); + + StringBuilder simpleName = new StringBuilder(); + simpleName.append("test"); + String suffix = configuration.getSuffix(); + if (!suffix.isEmpty()) { + simpleName.append('-').append(suffix); + } + simpleName.append(".js"); + File outputFile = new File(path, simpleName.toString()); result.file = outputFile; resourceToFile("org/teavm/backend/javascript/runtime.js", new File(path, "runtime.js")); @@ -345,12 +368,14 @@ public class TeaVMTestRunner extends Runner { Class runnerType = testAdapter.getRunner(methodHolder); JavaScriptTarget jsTarget = new JavaScriptTarget(); - jsTarget.setMinifying(false); + configuration.apply(jsTarget); + TeaVM vm = new TeaVMBuilder(jsTarget) .setClassLoader(classLoader) .setClassSource(classSource) .build(); vm.setIncremental(false); + configuration.apply(vm); vm.installPlugins(); new TestExceptionPlugin().install(vm); @@ -373,6 +398,18 @@ public class TeaVMTestRunner extends Runner { return result; } + private List getConfigurations() { + List configurations = new ArrayList<>(); + configurations.add(TeaVMTestConfiguration.DEFAULT); + if (Boolean.parseBoolean(System.getProperty("teavm.junit.minified", "false"))) { + configurations.add(TeaVMTestConfiguration.MINIFIED); + } + if (Boolean.parseBoolean(System.getProperty("teavm.junit.optimized", "false"))) { + configurations.add(TeaVMTestConfiguration.OPTIMIZED); + } + return configurations; + } + private void applyProperties(Class cls, Properties result) { if (cls.getSuperclass() != null) { applyProperties(cls.getSuperclass(), result);