Skip to content

Commit

Permalink
Improve feature test support
Browse files Browse the repository at this point in the history
* improve support for feature tests
* migrate one test from core-js
* improved api
  • Loading branch information
rbri authored Jan 8, 2025
1 parent a750593 commit 3b3b5e2
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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; }");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,20 @@
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;

/**
* @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);
Expand All @@ -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);
Expand All @@ -60,18 +49,33 @@ 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
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);
Expand All @@ -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);
Expand All @@ -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')");
}
}
Loading

0 comments on commit 3b3b5e2

Please sign in to comment.