Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simplify tests #1757

Merged
merged 10 commits into from
Dec 23, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
simplify tests
rbri committed Dec 21, 2024
commit e83e612e7670993c5ea87df527c61bc8d890f917
285 changes: 107 additions & 178 deletions rhino/src/test/java/org/mozilla/javascript/SuperTest.java
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

@@ -25,60 +24,49 @@ void superIsNotAKeywordUntilES6() {

@Test
void superIsAKeywordInES6AndCannotBeUsedAsVariableName() {
assertIsSyntaxErrorES6("var super = 42;", "missing variable name (test#1)");
Utils.assertEvaluatorExceptionES6("missing variable name (test#1)", "var super = 42;");
}

@Test
void isSyntaxErrorIfHasSuperCall() {
assertIsSyntaxErrorES6(
"({ method() { super(); }});",
"super should be inside a shorthand function (test#1)");
Utils.assertEvaluatorExceptionES6(
"super should be inside a shorthand function (test#1)",
"({ method() { super(); }});");
}

@Test
void superCannotBeUsedInAPropertyValue() {
assertIsSyntaxErrorES6(
"var o = { a: super.b }",
"super should be inside a shorthand function (test#1)");
Utils.assertEvaluatorExceptionES6(
"super should be inside a shorthand function (test#1)",
"var o = { a: super.b }");
}

@Test
void superCannotBeUsedInAComputedPropertyName() {
assertIsSyntaxErrorES6(
"var o = { [super.x]: 42 }",
"super should be inside a shorthand function (test#1)");
Utils.assertEvaluatorExceptionES6(
"super should be inside a shorthand function (test#1)",
"var o = { [super.x]: 42 }");
}

@Test
void superCannotBeUsedInANonShorthandMethod() {
assertIsSyntaxErrorES6(
"var o = { f: function() { super.x } }",
"super should be inside a shorthand function (test#1)");
Utils.assertEvaluatorExceptionES6(
"super should be inside a shorthand function (test#1)",
"var o = { f: function() { super.x } }");
}

@Test
void superCannotHaveOptionalPropertyAccess() {
assertIsSyntaxErrorES6(
"var o = { f() { super?.x } }",
"super is not allowed in an optional chaining expression (test#1)");
Utils.assertEvaluatorExceptionES6(
"super is not allowed in an optional chaining expression (test#1)",
"var o = { f() { super?.x } }");
}

@Test
void superNestedInAFunctionInsideAMethodIsNotAllowed() {
assertIsSyntaxErrorES6(
"var o = { f() {\n" + " (function() { super.x; })() \n" + "} }",
"super should be inside a shorthand function (test#2)");
}

private void assertIsSyntaxErrorES6(String source, String expected) {
try (Context cx = Context.enter()) {
cx.setLanguageVersion(Context.VERSION_ES6);
EvaluatorException err =
assertThrows(
EvaluatorException.class,
() -> cx.compileString(source, "test", 1, null));
assertEquals(expected, err.getMessage());
}
Utils.assertEvaluatorExceptionES6(
"super should be inside a shorthand function (test#2)",
"var o = { f() {\n" + " (function() { super.x; })() \n" + "} }");
}
}

@@ -97,6 +85,7 @@ void byName() {
+ "};\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "b.f();";

Utils.assertWithAllOptimizationLevelsES6(1, script);
}

@@ -112,6 +101,7 @@ void byIndex() {
+ "};\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "b.f();";

Utils.assertWithAllOptimizationLevelsES6(1, script);
}

@@ -127,6 +117,7 @@ void byIndexNegative() {
+ "};\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "b.f();";

Utils.assertWithAllOptimizationLevelsES6(1, script);
}

@@ -142,6 +133,7 @@ void byIndexFractional() {
+ "};\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "b.f();";

Utils.assertWithAllOptimizationLevelsES6(1, script);
}

@@ -158,6 +150,7 @@ void byElementString() {
+ "};\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "b.f();";

Utils.assertWithAllOptimizationLevelsES6(1, script);
}

@@ -174,6 +167,7 @@ void byElementIndex() {
+ "};\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "b.f();";

Utils.assertWithAllOptimizationLevelsES6(1, script);
}

@@ -191,6 +185,7 @@ void byElementSymbol() {
+ "};\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "b.f();";

Utils.assertWithAllOptimizationLevelsES6(1, script);
}

@@ -207,6 +202,7 @@ void getter() {
+ "\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "b.f;";

Utils.assertWithAllOptimizationLevelsES6(1, script);
}

@@ -218,6 +214,7 @@ void getterWithThis() {
+ "const b = { x: 'b', get y() { return super['y'] + 'y'; } };\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "b.y;";

Utils.assertWithAllOptimizationLevelsES6("bxy", script);
}

@@ -229,6 +226,7 @@ void superInDefaultArguments() {
+ "const b = { x: 'b', f(p = super.x) { return p; } };\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "b.f();";

Utils.assertWithAllOptimizationLevelsES6("a", script);
}

@@ -246,6 +244,7 @@ void usesHomeObjectAndIgnoresThis1() {
+ "Object.setPrototypeOf(b, a);\n"
+ "var fn = b.f;\n"
+ "fn()\n";

Utils.assertWithAllOptimizationLevelsES6(1, script);
}

@@ -266,6 +265,7 @@ void usesHomeObjectAndIgnoresThis2() {
+ "var d = { fn };\n"
+ "Object.setPrototypeOf(d, c)\n"
+ "d.fn()\n";

Utils.assertWithAllOptimizationLevelsES6(1, script);
}

@@ -285,6 +285,7 @@ void nestedObjects() {
+ "};\n"
+ "Object.setPrototypeOf(obj, protoY);\n"
+ "obj.f();";

Utils.assertWithAllOptimizationLevelsES6("xy", script);
}

@@ -304,6 +305,7 @@ void nestedObjectsLambda() {
+ "};\n"
+ "Object.setPrototypeOf(obj, protoY);\n"
+ "obj.f();";

Utils.assertWithAllOptimizationLevelsES6("xy", script);
}

@@ -320,6 +322,7 @@ void getPropNoWarnPropertyFound() {
+ "};\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "b.f();";

Utils.assertWithAllOptimizationLevelsES6("number", script);
}

@@ -336,6 +339,7 @@ void getPropNoWarnPropertyMissing() {
+ "};\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "b.f();";

Utils.assertWithAllOptimizationLevelsES6("undefined", script);
}

@@ -426,6 +430,7 @@ void propertyNotFoundInSuper() {
+ " x: 42\n"
+ "};\n"
+ "o.f();";

Utils.assertWithAllOptimizationLevelsES6(Undefined.instance, script);
}

@@ -441,6 +446,7 @@ void propertyNotFoundInSuperByElement() {
+ " }"
+ "};\n"
+ "o.f();";

Utils.assertWithAllOptimizationLevelsES6(Undefined.instance, script);
}

@@ -455,6 +461,7 @@ void propertyNotFoundInSuperByIndex() {
+ " }"
+ "};\n"
+ "o.f();";

Utils.assertWithAllOptimizationLevelsES6(Undefined.instance, script);
}

@@ -469,24 +476,9 @@ void prototypeIsNull() {
+ "};\n"
+ "Object.setPrototypeOf(obj, null);\n"
+ "obj.method();";
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_ES6);
EcmaError error =
assertThrows(
EcmaError.class,
() ->
cx.evaluateString(
cx.initStandardObjects(),
script,
"test",
1,
null));
assertEquals(
"TypeError: Cannot read property \"x\" from null (test#3)",
error.getMessage());
return null;
});

Utils.assertEcmaErrorES6(
"TypeError: Cannot read property \"x\" from null (test#3)", script);
}
}

@@ -504,6 +496,7 @@ void byName() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();"
+ "object.x + ':' + proto.x";

Utils.assertWithAllOptimizationLevelsES6("new:proto", script);
}

@@ -519,6 +512,7 @@ void byIndex() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();"
+ "object[42] + ':' + proto[42]";

Utils.assertWithAllOptimizationLevelsES6("new:proto", script);
}

@@ -534,6 +528,7 @@ void byIndexNegative() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();"
+ "object[-1] + ':' + proto[-1]";

Utils.assertWithAllOptimizationLevelsES6("new:proto", script);
}

@@ -549,6 +544,7 @@ void byIndexFractional() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();"
+ "object[0.1] + ':' + proto[0.1]";

Utils.assertWithAllOptimizationLevelsES6("new:proto", script);
}

@@ -564,6 +560,7 @@ void byElementString() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();"
+ "object.x+ ':' + proto.x";

Utils.assertWithAllOptimizationLevelsES6("new:proto", script);
}

@@ -579,6 +576,7 @@ void byElementIndex() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();"
+ "object[42] + ':' + proto[42]";

Utils.assertWithAllOptimizationLevelsES6("new:proto", script);
}

@@ -595,6 +593,7 @@ void byElementSymbol() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();"
+ "object[s] + ':' + proto[s]";

Utils.assertWithAllOptimizationLevelsES6("new:proto", script);
}

@@ -613,6 +612,7 @@ void setter() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f = 1;\n"
+ "object.x + ':' + proto.x";

Utils.assertWithAllOptimizationLevelsES6("1:0", script);
}

@@ -634,6 +634,7 @@ void setterWithThis() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.x = 1;\n"
+ "object._x + ':' + proto._x";

Utils.assertWithAllOptimizationLevelsES6("1:0", script);
}

@@ -650,13 +651,14 @@ void propertyNotFoundInSuper() {
+ "};\n"
+ "o.f();\n"
+ "o.x + ':' + Object.prototype.x";

Utils.assertWithAllOptimizationLevelsES6("1:undefined", script);
}

@Test
void superPropertyNotWritableIgnoredSilentlyInNonStrictMode() {
String script =
"\n"
""
+ "var proto = { x: 'proto' };\n"
+ "var object = {\n"
+ " x: 'obj',\n"
@@ -666,14 +668,14 @@ void superPropertyNotWritableIgnoredSilentlyInNonStrictMode() {
+ "Object.defineProperty(proto, 'x', {writable: false});\n"
+ "object.f();\n"
+ "object.x + ':' + proto.x";
;

Utils.assertWithAllOptimizationLevelsES6("obj:proto", script);
}

@Test
void thisPropertyNotWritableIgnoredSilentlyInNonStrictMode() {
String script =
"\n"
""
+ "var proto = { x: 'proto' };\n"
+ "var object = {\n"
+ " x: 'obj',\n"
@@ -683,14 +685,14 @@ void thisPropertyNotWritableIgnoredSilentlyInNonStrictMode() {
+ "Object.defineProperty(object, 'x', {writable: false});\n"
+ "object.f();\n"
+ "object.x + ':' + proto.x";
;

Utils.assertWithAllOptimizationLevelsES6("obj:proto", script);
}

@Test
void superPropertyNotWritableInStrictIsError() {
String script =
"\n"
""
+ "'use strict';\n"
+ "var proto = { x: 'proto' };\n"
+ "var object = {\n"
@@ -701,14 +703,15 @@ void superPropertyNotWritableInStrictIsError() {
+ "Object.defineProperty(proto, 'x', {writable: false});\n"
+ "object.f();\n"
+ "object.x + ':' + proto.x";
;
assertThrowsTypeErrorCannotWriteProperty(script);

Utils.assertEcmaErrorES6(
"TypeError: Cannot modify readonly property: x. (test#5)", script);
}

@Test
void thisPropertyNotWritableInStrictIsError() {
String script =
"\n"
""
+ "'use strict';\n"
+ "var proto = { x: 'proto' };\n"
+ "var object = {\n"
@@ -719,29 +722,9 @@ void thisPropertyNotWritableInStrictIsError() {
+ "Object.defineProperty(object, 'x', {writable: false});\n"
+ "object.f();\n"
+ "object.x + ':' + proto.x";
;
assertThrowsTypeErrorCannotWriteProperty(script);
}

private void assertThrowsTypeErrorCannotWriteProperty(String script) {
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_ES6);
EcmaError error =
assertThrows(
EcmaError.class,
() ->
cx.evaluateString(
cx.initStandardObjects(),
script,
"test",
1,
null));
assertEquals(
"TypeError: Cannot modify readonly property: x. (test#6)",
error.getMessage());
return null;
});
Utils.assertEcmaErrorES6(
"TypeError: Cannot modify readonly property: x. (test#5)", script);
}

@Test
@@ -755,30 +738,15 @@ void prototypeIsNull() {
+ "};\n"
+ "Object.setPrototypeOf(obj, null);\n"
+ "obj.method();";
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_ES6);
EcmaError error =
assertThrows(
EcmaError.class,
() ->
cx.evaluateString(
cx.initStandardObjects(),
script,
"test",
1,
null));
assertEquals(
"TypeError: Cannot set property \"x\" of null to \"42\" (test#3)",
error.getMessage());
return null;
});

Utils.assertEcmaErrorES6(
"TypeError: Cannot set property \"x\" of null to \"42\" (test#3)", script);
}

@Test
void missingPropertyPrototypeSealedCreatesItOnTheThisObject() {
String script =
"\n"
""
+ "var proto = {};\n"
+ "var object = {\n"
+ " f() { super.x = 1; }\n"
@@ -787,14 +755,14 @@ void missingPropertyPrototypeSealedCreatesItOnTheThisObject() {
+ "Object.seal(proto);\n"
+ "object.f();\n"
+ "object.x + ':' + proto.x";
;

Utils.assertWithAllOptimizationLevelsES6("1:undefined", script);
}

@Test
void missingPropertyThisSealedIsIgnoredSilentlyInNonStrictMode() {
String script =
"\n"
""
+ "var proto = {};\n"
+ "var object = {\n"
+ " f() { super.x = 1; }\n"
@@ -803,14 +771,14 @@ void missingPropertyThisSealedIsIgnoredSilentlyInNonStrictMode() {
+ "Object.seal(object);\n"
+ "object.f();\n"
+ "object.x + ':' + proto.x";
;

Utils.assertWithAllOptimizationLevelsES6("undefined:undefined", script);
}

@Test
void missingPropertyThisSealedIsErrorInStrictMode() {
String script =
"\n"
""
+ "'use strict';\n"
+ "var proto = {};\n"
+ "var object = {\n"
@@ -820,25 +788,10 @@ void missingPropertyThisSealedIsErrorInStrictMode() {
+ "Object.seal(object);\n"
+ "object.f();\n"
+ "object.x + ':' + proto.x";
;
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_ES6);
EcmaError error =
assertThrows(
EcmaError.class,
() ->
cx.evaluateString(
cx.initStandardObjects(),
script,
"test",
1,
null));
assertEquals(
"TypeError: Cannot add properties to this object because extensible is false. (test#5)",
error.getMessage());
return null;
});

Utils.assertEcmaErrorES6(
"TypeError: Cannot add properties to this object because extensible is false. (test#4)",
script);
}

@Test
@@ -854,6 +807,7 @@ void modifyOperatorByName() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();"
+ "object.x + ':' + proto.x";

Utils.assertWithAllOptimizationLevelsES6("proto1:proto", script);
}

@@ -871,6 +825,7 @@ void modifyOperatorByKey() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();"
+ "object.x + ':' + proto.x";

Utils.assertWithAllOptimizationLevelsES6("proto1:proto", script);
}

@@ -893,6 +848,7 @@ void deleteNotAllowed() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();\n"
+ "catchHit + ':' + getterCalled";

Utils.assertWithAllOptimizationLevelsES6("true:false", script);
}

@@ -916,6 +872,7 @@ void deleteSuperFirstEvaluatesPropertyKey() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();\n"
+ "catchHit + ':' + gCalled";

Utils.assertWithAllOptimizationLevelsES6("true:true", script);
}

@@ -931,6 +888,7 @@ void memberIncrementPostfix() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "var f = object.f();"
+ "f + ':' + object.x + ':' + proto.x";

Utils.assertWithAllOptimizationLevelsES6("1:2:1", script);
}

@@ -946,6 +904,7 @@ void memberIncrementPrefix() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "var f = object.f();"
+ "f + ':' + object.x + ':' + proto.x";

Utils.assertWithAllOptimizationLevelsES6("2:2:1", script);
}

@@ -961,6 +920,7 @@ void elementDecrementPostfix() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "var f = object.f();"
+ "f + ':' + object[0] + ':' + proto[0]";

Utils.assertWithAllOptimizationLevelsES6("1:0:1", script);
}

@@ -976,6 +936,7 @@ void elementDecrementPrefix() {
+ "Object.setPrototypeOf(object, proto);\n"
+ "var f = object.f();"
+ "f + ':' + object[0] + ':' + proto[0]";

Utils.assertWithAllOptimizationLevelsES6("0:0:1", script);
}
}
@@ -998,6 +959,7 @@ void methodsAreResolvedOnSuperObject() {
+ "};\n"
+ "Object.setPrototypeOf(obj, proto);\n"
+ "obj.f();";

Utils.assertWithAllOptimizationLevelsES6("prototype1", script);
}

@@ -1023,6 +985,7 @@ void thisIsSetCorrectly0Args() {
+ "};\n"
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.g();";

Utils.assertWithAllOptimizationLevelsES6("object", script);
}

@@ -1044,6 +1007,7 @@ void thisIsSetCorrectly1Arg() {
+ "};\n"
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.g();";

Utils.assertWithAllOptimizationLevelsES6("object:a", script);
}

@@ -1065,6 +1029,7 @@ void thisIsSetCorrectly2Args() {
+ "};\n"
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.g();";

Utils.assertWithAllOptimizationLevelsES6("object:a:b", script);
}

@@ -1086,6 +1051,7 @@ void thisIsSetCorrectlyNArgs() {
+ "};\n"
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.g();";

Utils.assertWithAllOptimizationLevelsES6("object:a:b:c", script);
}

@@ -1106,6 +1072,7 @@ void lastScratchScriptableIsCleanedUpProperly() {
+ "};\n"
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f3();";

Utils.assertWithAllOptimizationLevelsES6("f2f1", script);
}

@@ -1127,6 +1094,7 @@ void thisIsSetCorrectlyForTemplateLiteralCall() {
+ "};\n"
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();";

Utils.assertWithAllOptimizationLevelsES6("object", script);
}

@@ -1143,11 +1111,12 @@ void nestedLambdaCaptureSuper() {
+ "var object = {\n"
+ " x: 'object',\n"
+ " f() {\n"
+ " return () => { return super.f(); } ;\n"
+ " return () => { return super.f(); };\n"
+ " }\n"
+ "};\n"
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f()();";

Utils.assertWithAllOptimizationLevelsES6("object", script);
}

@@ -1164,11 +1133,12 @@ void doublyNestedLambdaCaptureSuper() {
+ "var object = {\n"
+ " x: 'object',\n"
+ " f() {\n"
+ " return () => { return () => { return super.f(); } } ;\n"
+ " return () => { return () => { return super.f(); } };\n"
+ " }\n"
+ "};\n"
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f()()();";

Utils.assertWithAllOptimizationLevelsES6("object", script);
}
}
@@ -1194,6 +1164,7 @@ void propertyGet() {
+ "Object.setPrototypeOf(c, b);\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "c.f();";

Utils.assertWithAllOptimizationLevelsES6("b", script);
}

@@ -1228,6 +1199,7 @@ void propertySet() {
+ "Object.setPrototypeOf(c, b);\n"
+ "Object.setPrototypeOf(b, a);\n"
+ "c.f();";

Utils.assertWithAllOptimizationLevelsES6("a", script);
}
}
@@ -1249,6 +1221,7 @@ void evalInsideMethodCanAccessSuper() {
+ "};\n"
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f();";

Utils.assertWithAllOptimizationLevelsES6("proto", script);
}

@@ -1267,6 +1240,7 @@ void evalFromLambdaInMethodCanAccessSuper() {
+ "};\n"
+ "Object.setPrototypeOf(object, proto);\n"
+ "object.f()();";

Utils.assertWithAllOptimizationLevelsES6("proto", script);
}

@@ -1280,47 +1254,17 @@ void superCannotBeUsedAsMethodInEval() {
+ " }\n"
+ "};"
+ "o.f();";
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_ES6);
EcmaError error =
assertThrows(
EcmaError.class,
() ->
cx.evaluateString(
cx.initStandardObjects(),
script,
"test",
1,
null));
assertEquals(
"SyntaxError: super should be inside a shorthand function (test#3(eval)#1)",
error.getMessage());
return null;
});

Utils.assertEcmaErrorES6(
"SyntaxError: super should be inside a shorthand function (test#3(eval)#1)",
script);
}

@Test
void evalOutsideMethodCannotAccessSuper() {
String script = "eval('super.x')";
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_ES6);
EcmaError error =
assertThrows(
EcmaError.class,
() ->
cx.evaluateString(
cx.initStandardObjects(),
script,
"test",
1,
null));
assertEquals(
"SyntaxError: super should be inside a shorthand function (test#1(eval)#1)",
error.getMessage());
return null;
});
Utils.assertEcmaErrorES6(
"SyntaxError: super should be inside a shorthand function (test#1(eval)#1)",
"eval('super.x')");
}

@Test
@@ -1333,24 +1277,9 @@ void evalInFunctionInsideMethodDoesNotAllowSuper() {
+ " }\n"
+ "};"
+ "o.f();";
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_ES6);
EcmaError error =
assertThrows(
EcmaError.class,
() ->
cx.evaluateString(
cx.initStandardObjects(),
script,
"test",
1,
null));
assertEquals(
"SyntaxError: super should be inside a shorthand function (test#3(eval)#1)",
error.getMessage());
return null;
});
Utils.assertEcmaErrorES6(
"SyntaxError: super should be inside a shorthand function (test#3(eval)#1)",
script);
}
}
}
Original file line number Diff line number Diff line change
@@ -4,199 +4,107 @@

package org.mozilla.javascript.tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import org.junit.Test;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.EvaluatorException;
import org.mozilla.javascript.ScriptableObject;

public class ComputedPropertiesTest {
@Test
public void objectWithComputedPropertiesWorks() {
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_ES6);
String script =
"\n"
+ "function f(x) { return x; }\n"
+ "\n"
+ "var o = {\n"
+ " a: 1,\n"
+ " 0: 2,\n"
+ " [-1]: 3\n,"
+ " [f('b')]: 4\n"
+ "};\n"
+ "o.a + o[0] + o['-1'] + o.b";

ScriptableObject scope = cx.initStandardObjects();
Object value = cx.evaluateString(scope, script, "test", 1, null);
assertTrue(value instanceof Number);
assertEquals(10, ((Number) value).intValue());
return null;
});
String script =
"function f(x) { return x; }\n"
+ "var o = {\n"
+ " a: 1,\n"
+ " 0: 2,\n"
+ " [-1]: 3\n,"
+ " [f('b')]: 4\n"
+ "};\n"
+ "o.a + o[0] + o['-1'] + o.b";
Utils.assertWithAllOptimizationLevelsES6(10, script);
}

@Test
public void canCoerceFunctionToString() {
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_ES6);
String script =
"\n"
+ "function f(x) {\n"
+ " var o = {\n"
+ " 1: true,\n"
+ " [2]: false,\n"
+ " [g(x)]: 3\n"
+ " };\n"
+ "}\n"
+ "f.toString()";

ScriptableObject scope = cx.initStandardObjects();
Object value = cx.evaluateString(scope, script, "test", 1, null);
assertTrue(value instanceof String);
assertEquals(
"function f(x) {\n"
+ " var o = {\n"
+ " 1: true,\n"
+ " [2]: false,\n"
+ " [g(x)]: 3\n"
+ " };\n"
+ "}",
value);
return null;
});
String script =
"function f(x) {\n"
+ " var o = {\n"
+ " 1: true,\n"
+ " [2]: false,\n"
+ " [g(x)]: 3\n"
+ " };\n"
+ "}\n"
+ "f.toString()";
String expected =
"function f(x) {\n"
+ " var o = {\n"
+ " 1: true,\n"
+ " [2]: false,\n"
+ " [g(x)]: 3\n"
+ " };\n"
+ "}";

Utils.assertWithAllOptimizationLevelsES6(expected, script);
}

@Test
public void computedPropertiesWithSideEffectsWork() {
Utils.runWithAllOptimizationLevels(
cx -> {
;
cx.setLanguageVersion(Context.VERSION_ES6);
String script =
"'use strict';\n"
+ "var x = 0;\n"
+ "var o = {\n"
+ " [++x]: 'x',\n"
+ " a: ++x,\n"
+ " [++x]: 'y'\n"
+ "};\n"
+ "o[1] + o.a + o[3]";

ScriptableObject scope = cx.initStandardObjects();
Object value = cx.evaluateString(scope, script, "test", 1, null);
assertEquals("x2y", value);
return null;
});
String script =
"'use strict';\n"
+ "var x = 0;\n"
+ "var o = {\n"
+ " [++x]: 'x',\n"
+ " a: ++x,\n"
+ " [++x]: 'y'\n"
+ "};\n"
+ "o[1] + o.a + o[3]";
Utils.assertWithAllOptimizationLevelsES6("x2y", script);
}

@Test
public void computedPropertyNameForGetterSetterWork() {
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_ES6);
String script = "var o = { get ['x' + 1]() { return 42; }}; o.x1";

ScriptableObject scope = cx.initStandardObjects();
Object value = cx.evaluateString(scope, script, "test", 1, null);
assertTrue(value instanceof Number);
assertEquals(42, ((Number) value).intValue());
return null;
});
Utils.assertWithAllOptimizationLevelsES6(
42, "var o = { get ['x' + 1]() { return 42; }}; o.x1");
}

@Test
public void computedPropertyNameAsSymbolForGetterSetterWork() {
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_ES6);
String script =
"var o = { get [Symbol.toStringTag]() { return 'foo'; }}; o.toString()";

ScriptableObject scope = cx.initStandardObjects();
Object value = cx.evaluateString(scope, script, "test", 1, null);
assertEquals("[object foo]", value);
return null;
});
Utils.assertWithAllOptimizationLevelsES6(
"[object foo]",
"var o = { get [Symbol.toStringTag]() { return 'foo'; }}; o.toString()");
}

@Test
public void yieldWorksForPropertyValues() {
Utils.runWithAllOptimizationLevels(
cx -> {
cx.setLanguageVersion(Context.VERSION_ES6);
String script =
"\n"
+ "function *gen() {\n"
+ " ({x: yield 1});\n"
+ "}\n"
+ "var g = gen()\n"
+ "var res1 = g.next();\n"
+ "var res2 = g.next();\n"
+ "res1.value === 1 && !res1.done && res2.done\n";

ScriptableObject scope = cx.initStandardObjects();
Object value = cx.evaluateString(scope, script, "test", 1, null);
assertEquals(Boolean.TRUE, value);
return null;
});
String script =
"function *gen() {\n"
+ " ({x: yield 1});\n"
+ "}\n"
+ "var g = gen()\n"
+ "var res1 = g.next();\n"
+ "var res2 = g.next();\n"
+ "res1.value === 1 && !res1.done && res2.done\n";

Utils.assertWithAllOptimizationLevelsES6(Boolean.TRUE, script);
}

@Test
public void cannotParseInvalidUnclosedBracket() {
String script = "o = { [3 : 2 }";

try (Context cx = Context.enter()) {
cx.setLanguageVersion(Context.VERSION_ES6);
EvaluatorException ex =
assertThrows(
EvaluatorException.class,
() -> cx.compileString(script, "test", 1, null));
assertEquals("invalid property id (test#1)", ex.getMessage());
}
Utils.assertEvaluatorExceptionES6("invalid property id (test#1)", "o = { [3 : 2 }");
}

@Test
public void notSupportedUnderVersionLesserThanEsLatest() {
String script = "o = { [1] : 2 }";

try (Context cx = Context.enter()) {
cx.setLanguageVersion(Context.VERSION_1_8);
EvaluatorException ex =
assertThrows(
EvaluatorException.class,
() -> cx.compileString(script, "test", 1, null));
assertEquals("invalid property id (test#1)", ex.getMessage());
}
Utils.assertEvaluatorException_1_8("invalid property id (test#1)", "o = { [1] : 2 }");
}

@Test
public void unsupportedInDestructuringInFunctionArguments() {
String script = "function({ [a]: b }) {};";
assertComputedPropertiesAreUnsupportedInDestructuring(
script, "Unsupported computed property in destructuring. (test#1)");
Utils.assertEvaluatorExceptionES6(
"Unsupported computed property in destructuring. (test#1)",
"function({ [a]: b }) {};");
}

@Test
public void unsupportedInDestructuringInVariableDeclaration() {
String script = "var { [a]: b } = {};";
assertComputedPropertiesAreUnsupportedInDestructuring(
script, "Unsupported computed property in destructuring. (test#1)");
}

private void assertComputedPropertiesAreUnsupportedInDestructuring(
String script, String message) {
try (Context cx = Context.enter()) {
cx.setLanguageVersion(Context.VERSION_ES6);
EvaluatorException ex =
assertThrows(
EvaluatorException.class,
() -> cx.compileString(script, "test", 1, null));
assertEquals(message, ex.getMessage());
}
Utils.assertEvaluatorExceptionES6(
"Unsupported computed property in destructuring. (test#1)", "var { [a]: b } = {};");
}
}