diff --git a/rhino/src/test/java/org/mozilla/javascript/tests/Bug421071Test.java b/rhino/src/test/java/org/mozilla/javascript/tests/Bug421071Test.java index 50a66b7a13..6db9cdf28e 100644 --- a/rhino/src/test/java/org/mozilla/javascript/tests/Bug421071Test.java +++ b/rhino/src/test/java/org/mozilla/javascript/tests/Bug421071Test.java @@ -63,16 +63,8 @@ private void runTestScript() throws InterruptedException { thread.join(); } - static class DynamicScopeContextFactory extends ContextFactory { - @Override - public boolean hasFeature(Context cx, int featureIndex) { - if (featureIndex == Context.FEATURE_DYNAMIC_SCOPE) return true; - return super.hasFeature(cx, featureIndex); - } - } - private TopLevelScope createGlobalScope() { - factory = new DynamicScopeContextFactory(); + factory = Utils.contextFactoryWithFeatures(Context.FEATURE_DYNAMIC_SCOPE); try (Context context = factory.enterContext()) { // noinspection deprecation diff --git a/rhino/src/test/java/org/mozilla/javascript/tests/Bug637811Test.java b/rhino/src/test/java/org/mozilla/javascript/tests/Bug637811Test.java index 801abf27dd..c0a81d62f7 100755 --- a/rhino/src/test/java/org/mozilla/javascript/tests/Bug637811Test.java +++ b/rhino/src/test/java/org/mozilla/javascript/tests/Bug637811Test.java @@ -4,45 +4,23 @@ package org.mozilla.javascript.tests; -import org.junit.After; -import org.junit.Before; import org.junit.Test; import org.mozilla.javascript.Context; -import org.mozilla.javascript.ContextFactory; +import org.mozilla.javascript.Undefined; /** * @author André Bargull */ public class Bug637811Test { - private Context cx; - - @Before - public void setUp() throws Exception { - cx = - new ContextFactory() { - @Override - protected boolean hasFeature(Context cx, int featureIndex) { - switch (featureIndex) { - case Context.FEATURE_STRICT_MODE: - case Context.FEATURE_WARNING_AS_ERROR: - return true; - } - return super.hasFeature(cx, featureIndex); - } - }.enterContext(); - } - - @After - public void tearDown() throws Exception { - Context.exit(); - } - @Test public void test() { - String source = ""; - source += "var x = 0;"; - source += "bar: while (x < 0) { x = x + 1; }"; - cx.compileString(source, "", 1, null); + Utils.assertWithAllModes( + Utils.contextFactoryWithFeatures( + Context.FEATURE_STRICT_MODE, Context.FEATURE_WARNING_AS_ERROR), + Context.VERSION_ES6, + null, + Undefined.instance, + "var x = 0; bar: while (x < 0) { x = x + 1; }"); } } diff --git a/tests/src/test/java/org/mozilla/javascript/tests/StrictModeApiTest.java b/tests/src/test/java/org/mozilla/javascript/tests/StrictModeApiTest.java index 8720c03cc0..51a054579e 100644 --- a/tests/src/test/java/org/mozilla/javascript/tests/StrictModeApiTest.java +++ b/tests/src/test/java/org/mozilla/javascript/tests/StrictModeApiTest.java @@ -4,14 +4,11 @@ package org.mozilla.javascript.tests; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import java.lang.reflect.Method; import org.junit.Test; -import org.mozilla.javascript.Context; -import org.mozilla.javascript.ContextFactory; -import org.mozilla.javascript.EvaluatorException; -import org.mozilla.javascript.ScriptableObject; +import org.mozilla.javascript.*; /** * Test of strict mode APIs. @@ -20,40 +17,65 @@ */ public class StrictModeApiTest { - private ScriptableObject global; - private ContextFactory contextFactory; + @Test + public void strictModeError() { + final ContextFactory contextFactory = + Utils.contextFactoryWithFeatures( + Context.FEATURE_STRICT_MODE, + Context.FEATURE_STRICT_VARS, + Context.FEATURE_STRICT_EVAL, + Context.FEATURE_WARNING_AS_ERROR); - static class MyContextFactory extends ContextFactory { - @Override - protected boolean hasFeature(Context cx, int featureIndex) { - switch (featureIndex) { - case Context.FEATURE_STRICT_MODE: - case Context.FEATURE_STRICT_VARS: - case Context.FEATURE_STRICT_EVAL: - case Context.FEATURE_WARNING_AS_ERROR: - return true; - } - return super.hasFeature(cx, featureIndex); - } + Utils.assertException( + contextFactory, + Context.VERSION_ES6, + EvaluatorException.class, + "Reference to undefined property", + "({}.nonexistent);"); } + /** Unit test for bug 604674 https://bugzilla.mozilla.org/show_bug.cgi?id=604674 */ @Test - public void strictModeError() { - contextFactory = new MyContextFactory(); - try (Context cx = contextFactory.enterContext()) { - global = cx.initStandardObjects(); - try { - runScript("({}.nonexistent);"); - fail(); - } catch (EvaluatorException e) { - assertTrue(e.getMessage().startsWith("Reference to undefined property")); - } - } + public void onlyGetterError() { + final String script = "o.readonlyProp = 123"; + + Utils.runWithAllModes( + Utils.contextFactoryWithFeatures(Context.FEATURE_STRICT_MODE), + cx -> { + try { + Scriptable scope = cx.initSafeStandardObjects(); + final MyHostObject prototype = new MyHostObject(); + ScriptableObject.defineClass(scope, MyHostObject.class); + final Method readMethod = MyHostObject.class.getMethod("jsxGet_x"); + prototype.defineProperty( + "readonlyProp", null, readMethod, null, ScriptableObject.EMPTY); + + ScriptableObject.defineProperty( + scope, "o", prototype, ScriptableObject.DONTENUM); + + cx.evaluateString(scope, script, "test_script", 1, null); + throw new RuntimeException("Should have failed!"); + } catch (final EcmaError e) { + assertEquals( + "TypeError: Cannot set property [MyHostObject].readonlyProp that has only a getter to value '123'. (test_script#1)", + e.getMessage()); + return null; + } catch (final Exception e) { + throw new RuntimeException(e); + } + }); } - private Object runScript(final String scriptSourceText) { - return this.contextFactory.call( - context -> - context.evaluateString(global, scriptSourceText, "test source", 1, null)); + public static class MyHostObject extends ScriptableObject { + private int x; + + @Override + public String getClassName() { + return getClass().getSimpleName(); + } + + public int jsxGet_x() { + return x; + } } } diff --git a/tests/src/test/java/org/mozilla/javascript/tests/es6/PropertyTest.java b/tests/src/test/java/org/mozilla/javascript/tests/es6/PropertyTest.java index a721c1b5cc..985f61aed2 100644 --- a/tests/src/test/java/org/mozilla/javascript/tests/es6/PropertyTest.java +++ b/tests/src/test/java/org/mozilla/javascript/tests/es6/PropertyTest.java @@ -125,15 +125,7 @@ public void redefineSetterProperty() throws Exception { public void redefinePropertyWithThreadSafeSlotMap() { final ContextFactory factory = - new ContextFactory() { - @Override - protected boolean hasFeature(Context cx, int featureIndex) { - if (featureIndex == Context.FEATURE_THREAD_SAFE_OBJECTS) { - return true; - } - return super.hasFeature(cx, featureIndex); - } - }; + Utils.contextFactoryWithFeatures(Context.FEATURE_THREAD_SAFE_OBJECTS); try (Context cx = factory.enterContext()) { cx.setLanguageVersion(Context.VERSION_ES6); diff --git a/tests/src/test/java/org/mozilla/javascript/tests/intl402/NativeStringTest.java b/tests/src/test/java/org/mozilla/javascript/tests/intl402/NativeStringTest.java index 37567b1af6..d710015c88 100644 --- a/tests/src/test/java/org/mozilla/javascript/tests/intl402/NativeStringTest.java +++ b/tests/src/test/java/org/mozilla/javascript/tests/intl402/NativeStringTest.java @@ -10,7 +10,6 @@ import java.util.Locale; import org.junit.Test; import org.mozilla.javascript.Context; -import org.mozilla.javascript.ContextFactory; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.tests.Utils; @@ -18,23 +17,13 @@ * @author Ronald Brill */ public class NativeStringTest { - private ContextFactory contextFactoryIntl402 = - new ContextFactory() { - @Override - protected boolean hasFeature(Context cx, int featureIndex) { - if (featureIndex == Context.FEATURE_INTL_402) { - return true; - } - return super.hasFeature(cx, featureIndex); - } - }; @Test public void toLocaleLowerCase() { String js = "'\\u0130'.toLocaleLowerCase()"; Utils.runWithAllModes( - contextFactoryIntl402, + Utils.contextFactoryWithFeatures(Context.FEATURE_INTL_402), cx -> { final Scriptable scope = cx.initStandardObjects(); cx.setLanguageVersion(Context.VERSION_ES6); @@ -46,7 +35,7 @@ public void toLocaleLowerCase() { }); Utils.runWithAllModes( - contextFactoryIntl402, + Utils.contextFactoryWithFeatures(Context.FEATURE_INTL_402), cx -> { final Scriptable scope = cx.initStandardObjects(); cx.setLanguageVersion(Context.VERSION_ES6); @@ -60,10 +49,25 @@ public void toLocaleLowerCase() { @Test public void toLocaleLowerCaseParam() { - assertEvaluatesES6("\u0069\u0307", "'\\u0130'.toLocaleLowerCase('en')"); - assertEvaluatesES6("\u0069", "'\\u0130'.toLocaleLowerCase('tr')"); - - assertEvaluatesES6("\u0069\u0307", "'\\u0130'.toLocaleLowerCase('Absurdistan')"); + Utils.assertWithAllModes( + Utils.contextFactoryWithFeatures(Context.FEATURE_INTL_402), + Context.VERSION_ES6, + null, + "\u0069\u0307", + "'\\u0130'.toLocaleLowerCase('en')"); + Utils.assertWithAllModes( + Utils.contextFactoryWithFeatures(Context.FEATURE_INTL_402), + Context.VERSION_ES6, + null, + "\u0069", + "'\\u0130'.toLocaleLowerCase('tr')"); + + Utils.assertWithAllModes( + Utils.contextFactoryWithFeatures(Context.FEATURE_INTL_402), + Context.VERSION_ES6, + null, + "\u0069\u0307", + "'\\u0130'.toLocaleLowerCase('Absurdistan')"); } @Test @@ -71,7 +75,7 @@ public void toLocaleUpperCase() { String js = "'\\u0069'.toLocaleUpperCase()"; Utils.runWithAllModes( - contextFactoryIntl402, + Utils.contextFactoryWithFeatures(Context.FEATURE_INTL_402), cx -> { final Scriptable scope = cx.initStandardObjects(); cx.setLanguageVersion(Context.VERSION_ES6); @@ -83,7 +87,7 @@ public void toLocaleUpperCase() { }); Utils.runWithAllModes( - contextFactoryIntl402, + Utils.contextFactoryWithFeatures(Context.FEATURE_INTL_402), cx -> { final Scriptable scope = cx.initStandardObjects(); cx.setLanguageVersion(Context.VERSION_ES6); @@ -97,21 +101,24 @@ public void toLocaleUpperCase() { @Test public void toLocaleUpperCaseParam() { - assertEvaluatesES6("\u0049", "'\\u0069'.toLocaleUpperCase('en')"); - assertEvaluatesES6("\u0130", "'\\u0069'.toLocaleUpperCase('tr')"); - - assertEvaluatesES6("\u0049", "'\\u0069'.toLocaleUpperCase('Absurdistan')"); - } - - private void assertEvaluatesES6(final Object expected, final String source) { - Utils.runWithAllModes( - contextFactoryIntl402, - cx -> { - final Scriptable scope = cx.initStandardObjects(); - cx.setLanguageVersion(Context.VERSION_ES6); - final Object rep = cx.evaluateString(scope, source, "test.js", 0, null); - assertEquals(expected, rep); - return null; - }); + Utils.assertWithAllModes( + Utils.contextFactoryWithFeatures(Context.FEATURE_INTL_402), + Context.VERSION_ES6, + null, + "\u0049", + "'\\u0069'.toLocaleUpperCase('en')"); + Utils.assertWithAllModes( + Utils.contextFactoryWithFeatures(Context.FEATURE_INTL_402), + Context.VERSION_ES6, + null, + "\u0130", + "'\\u0069'.toLocaleUpperCase('tr')"); + + Utils.assertWithAllModes( + Utils.contextFactoryWithFeatures(Context.FEATURE_INTL_402), + Context.VERSION_ES6, + null, + "\u0049", + "'\\u0069'.toLocaleUpperCase('Absurdistan')"); } } diff --git a/testutils/src/main/java/org/mozilla/javascript/tests/Utils.java b/testutils/src/main/java/org/mozilla/javascript/tests/Utils.java index 4baeaa53ba..7a30bc1d6c 100644 --- a/testutils/src/main/java/org/mozilla/javascript/tests/Utils.java +++ b/testutils/src/main/java/org/mozilla/javascript/tests/Utils.java @@ -6,6 +6,7 @@ import static org.junit.Assert.*; +import java.util.stream.IntStream; import org.mozilla.javascript.Context; import org.mozilla.javascript.ContextAction; import org.mozilla.javascript.ContextFactory; @@ -168,7 +169,27 @@ public static void assertWithAllModes( final String message, final Object expected, final String script) { + assertWithAllModes(new ContextFactory(), languageVersion, message, expected, script); + } + + /** + * Execute the provided script and assert the result. + * + * @param contextFactory a user defined {@link ContextFactory} + * @param languageVersion the language version constant from @{@link Context} or -1 to not + * change the language version at all + * @param message the message to be used if this fails + * @param expected the expected result + * @param script the javascript script to execute + */ + public static void assertWithAllModes( + final ContextFactory contextFactory, + final int languageVersion, + final String message, + final Object expected, + final String script) { runWithAllModes( + contextFactory, cx -> { if (languageVersion > -1) { cx.setLanguageVersion(languageVersion); @@ -272,7 +293,14 @@ public static void assertEcmaErrorES6(final String expectedMessage, final String assertException(Context.VERSION_ES6, EcmaError.class, expectedMessage, script); } - private static void assertException( + public static void assertException( + final int languageVersion, + final Class expectedThrowable, + final String expectedMessage, + String js) {} + + public static void assertException( + final ContextFactory contextFactory, final int languageVersion, final Class expectedThrowable, final String expectedMessage, @@ -284,6 +312,7 @@ private static void assertException( expectedMessage != null && !expectedMessage.isEmpty()); Utils.runWithAllModes( + contextFactory, cx -> { if (languageVersion > -1) { cx.setLanguageVersion(languageVersion); @@ -305,4 +334,30 @@ private static void assertException( return null; }); } + + /** + * @param features the features to enable in addition to the already enabled featured from the + * {@link ContextFactory} + * @return a new {@link ContextFactory} with all provided features enabled + */ + public static ContextFactory contextFactoryWithFeatures(int... features) { + return new ContextFactoryWithFeatures(features); + } + + private static class ContextFactoryWithFeatures extends ContextFactory { + private final int[] features; + + private ContextFactoryWithFeatures(int... features) { + this.features = features; + } + + @Override + protected boolean hasFeature(Context cx, int featureIndex) { + if (IntStream.of(features).anyMatch(x -> x == featureIndex)) { + return true; + } + + return super.hasFeature(cx, featureIndex); + } + } }