summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_6/Function
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/ecma_6/Function')
-rw-r--r--js/src/tests/ecma_6/Function/function-name-assignment.js139
-rw-r--r--js/src/tests/ecma_6/Function/function-name-binding.js54
-rw-r--r--js/src/tests/ecma_6/Function/function-name-class.js32
-rw-r--r--js/src/tests/ecma_6/Function/function-name-for.js31
-rw-r--r--js/src/tests/ecma_6/Function/function-name-method.js70
-rw-r--r--js/src/tests/ecma_6/Function/function-name-property.js58
-rw-r--r--js/src/tests/ecma_6/Function/invalid-parameter-list.js27
7 files changed, 411 insertions, 0 deletions
diff --git a/js/src/tests/ecma_6/Function/function-name-assignment.js b/js/src/tests/ecma_6/Function/function-name-assignment.js
new file mode 100644
index 000000000..5e4d1c004
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/function-name-assignment.js
@@ -0,0 +1,139 @@
+var BUGNUMBER = 883377;
+var summary = "Anonymous function name should be set based on assignment";
+
+print(BUGNUMBER + ": " + summary);
+
+var fooSymbol = Symbol("foo");
+var emptySymbol = Symbol("");
+var undefSymbol = Symbol();
+var globalVar;
+
+var exprs = [
+ ["function() {}", false],
+ ["function named() {}", true],
+ ["function*() {}", false],
+ ["function* named() {}", true],
+ ["async function() {}", false],
+ ["async function named() {}", true],
+ ["() => {}", false],
+ ["async () => {}", false],
+ ["class {}", false],
+ ["class named {}", true],
+];
+
+function testAssignmentExpression(expr, named) {
+ eval(`
+ var assignment;
+ assignment = ${expr};
+ assertEq(assignment.name, named ? "named" : "assignment");
+
+ globalVar = ${expr};
+ assertEq(globalVar.name, named ? "named" : "globalVar");
+
+ var obj = { dynamic: null };
+ with (obj) {
+ dynamic = ${expr};
+ }
+ assertEq(obj.dynamic.name, named ? "named" : "dynamic");
+
+ (function namedLambda(param1, param2) {
+ var assignedToNamedLambda;
+ assignedToNamedLambda = namedLambda = ${expr};
+ assertEq(namedLambda.name, "namedLambda");
+ assertEq(assignedToNamedLambda.name, named ? "named" : "namedLambda");
+
+ param1 = ${expr};
+ assertEq(param1.name, named ? "named" : "param1");
+
+ {
+ let param1 = ${expr};
+ assertEq(param1.name, named ? "named" : "param1");
+
+ param2 = ${expr};
+ assertEq(param2.name, named ? "named" : "param2");
+ }
+ })();
+
+ {
+ let nextedLexical1, nextedLexical2;
+ {
+ let nextedLexical1 = ${expr};
+ assertEq(nextedLexical1.name, named ? "named" : "nextedLexical1");
+
+ nextedLexical2 = ${expr};
+ assertEq(nextedLexical2.name, named ? "named" : "nextedLexical2");
+ }
+ }
+ `);
+
+ // Not applicable cases: not IsIdentifierRef.
+ eval(`
+ var inParen;
+ (inParen) = ${expr};
+ assertEq(inParen.name, named ? "named" : "");
+ `);
+
+ // Not applicable cases: not direct RHS.
+ if (!expr.includes("=>")) {
+ eval(`
+ var a = true && ${expr};
+ assertEq(a.name, named ? "named" : "");
+ `);
+ } else {
+ // Arrow function cannot be RHS of &&.
+ eval(`
+ var a = true && (${expr});
+ assertEq(a.name, named ? "named" : "");
+ `);
+ }
+
+ // Not applicable cases: property.
+ eval(`
+ var obj = {};
+
+ obj.prop = ${expr};
+ assertEq(obj.prop.name, named ? "named" : "");
+
+ obj["literal"] = ${expr};
+ assertEq(obj["literal"].name, named ? "named" : "");
+ `);
+
+ // Not applicable cases: assigned again.
+ eval(`
+ var tmp = [${expr}];
+ assertEq(tmp[0].name, named ? "named" : "");
+
+ var assignment;
+ assignment = tmp[0];
+ assertEq(assignment.name, named ? "named" : "");
+ `);
+}
+for (var [expr, named] of exprs) {
+ testAssignmentExpression(expr, named);
+}
+
+function testVariableDeclaration(expr, named) {
+ eval(`
+ var varDecl = ${expr};
+ assertEq(varDecl.name, named ? "named" : "varDecl");
+ `);
+}
+for (var [expr, named] of exprs) {
+ testVariableDeclaration(expr, named);
+}
+
+function testLexicalBinding(expr, named) {
+ eval(`
+ let lexical = ${expr};
+ assertEq(lexical.name, named ? "named" : "lexical");
+
+ const constLexical = ${expr};
+ assertEq(constLexical.name, named ? "named" : "constLexical");
+ `);
+}
+for (var [expr, named] of exprs) {
+ testLexicalBinding(expr, named);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Function/function-name-binding.js b/js/src/tests/ecma_6/Function/function-name-binding.js
new file mode 100644
index 000000000..bdd6c131c
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/function-name-binding.js
@@ -0,0 +1,54 @@
+var BUGNUMBER = 883377;
+var summary = "Anonymous function name should be set based on binding pattern";
+
+print(BUGNUMBER + ": " + summary);
+
+var exprs = [
+ ["function() {}", false],
+ ["function named() {}", true],
+ ["function*() {}", false],
+ ["function* named() {}", true],
+ ["async function() {}", false],
+ ["async function named() {}", true],
+ ["() => {}", false],
+ ["async () => {}", false],
+ ["class {}", false],
+ ["class named {}", true],
+];
+
+function testAssignmentProperty(expr, named) {
+ var f = eval(`(function({ prop1 = ${expr} }) { return prop1; })`);
+ assertEq(f({}).name, named ? "named" : "prop1");
+
+ eval(`
+ var { prop1 = ${expr} } = {};
+ assertEq(prop1.name, named ? "named" : "prop1");
+ `);
+}
+for (var [expr, named] of exprs) {
+ testAssignmentProperty(expr, named);
+}
+
+function testAssignmentElement(expr, named) {
+ var f = eval(`(function([elem1 = ${expr}]) { return elem1; })`);
+ assertEq(f([]).name, named ? "named" : "elem1");
+
+ eval(`
+ var [elem1 = ${expr}] = [];
+ assertEq(elem1.name, named ? "named" : "elem1");
+ `);
+}
+for (var [expr, named] of exprs) {
+ testAssignmentElement(expr, named);
+}
+
+function testSingleNameBinding(expr, named) {
+ var f = eval(`(function(param1 = ${expr}) { return param1; })`);
+ assertEq(f().name, named ? "named" : "param1");
+}
+for (var [expr, named] of exprs) {
+ testSingleNameBinding(expr, named);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Function/function-name-class.js b/js/src/tests/ecma_6/Function/function-name-class.js
new file mode 100644
index 000000000..edde69055
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/function-name-class.js
@@ -0,0 +1,32 @@
+var BUGNUMBER = 883377;
+var summary = "Anonymous class with name method shouldn't be affected by assignment";
+
+print(BUGNUMBER + ": " + summary);
+
+var classWithStaticNameMethod = class { static name() {} };
+assertEq(typeof classWithStaticNameMethod.name, "function");
+
+var classWithStaticNameGetter = class { static get name() { return "static name"; } };
+assertEq(typeof Object.getOwnPropertyDescriptor(classWithStaticNameGetter, "name").get, "function");
+assertEq(classWithStaticNameGetter.name, "static name");
+
+var classWithStaticNameSetter = class { static set name(v) {} };
+assertEq(typeof Object.getOwnPropertyDescriptor(classWithStaticNameSetter, "name").set, "function");
+
+var n = "NAME".toLowerCase();
+var classWithStaticNameMethodComputed = class { static [n]() {} };
+assertEq(typeof classWithStaticNameMethodComputed.name, "function");
+
+// It doesn't apply for non-static method.
+
+var classWithNameMethod = class { name() {} };
+assertEq(classWithNameMethod.name, "classWithNameMethod");
+
+var classWithNameGetter = class { get name() { return "name"; } };
+assertEq(classWithNameGetter.name, "classWithNameGetter");
+
+var classWithNameSetter = class { set name(v) {} };
+assertEq(classWithNameSetter.name, "classWithNameSetter");
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Function/function-name-for.js b/js/src/tests/ecma_6/Function/function-name-for.js
new file mode 100644
index 000000000..2f04a5fa8
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/function-name-for.js
@@ -0,0 +1,31 @@
+var BUGNUMBER = 883377;
+var summary = "Anonymous function name should be set based on for-in initializer";
+
+print(BUGNUMBER + ": " + summary);
+
+var exprs = [
+ ["function() {}", false],
+ ["function named() {}", true],
+ ["function*() {}", false],
+ ["function* named() {}", true],
+ ["async function() {}", false],
+ ["async function named() {}", true],
+ ["() => {}", false],
+ ["async () => {}", false],
+ ["class {}", false],
+ ["class named {}", true],
+];
+
+function testForInHead(expr, named) {
+ eval(`
+ for (var forInHead = ${expr} in {}) {
+ }
+ `);
+ assertEq(forInHead.name, named ? "named" : "forInHead");
+}
+for (var [expr, named] of exprs) {
+ testForInHead(expr, named);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Function/function-name-method.js b/js/src/tests/ecma_6/Function/function-name-method.js
new file mode 100644
index 000000000..3b2eeee79
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/function-name-method.js
@@ -0,0 +1,70 @@
+var BUGNUMBER = 883377;
+var summary = "Anonymous function name should be set based on method definition";
+
+print(BUGNUMBER + ": " + summary);
+
+var fooSymbol = Symbol("foo");
+var emptySymbol = Symbol("");
+var undefSymbol = Symbol();
+
+function testMethod(prefix, classPrefix="", prototype=false) {
+ var param = (prefix == "set" || prefix == "static set") ? "v" : "";
+ var sep = classPrefix ? "" : ",";
+ var objOrClass = eval(`(${classPrefix}{
+ ${prefix} prop(${param}) {} ${sep}
+ ${prefix} "literal"(${param}) {} ${sep}
+ ${prefix} ""(${param}) {} ${sep}
+ ${prefix} 5(${param}) {} ${sep}
+ ${prefix} [Symbol.iterator](${param}) {} ${sep}
+ ${prefix} [fooSymbol](${param}) {} ${sep}
+ ${prefix} [emptySymbol](${param}) {} ${sep}
+ ${prefix} [undefSymbol](${param}) {} ${sep}
+ ${prefix} [/a/](${param}) {} ${sep}
+ })`);
+
+ var target = prototype ? objOrClass.prototype : objOrClass;
+
+ function testOne(methodName, expectedName) {
+ var f;
+ if (prefix == "get" || prefix == "static get") {
+ f = Object.getOwnPropertyDescriptor(target, methodName).get;
+ expectedName = "get " + expectedName;
+ } else if (prefix == "set" || prefix == "static set") {
+ f = Object.getOwnPropertyDescriptor(target, methodName).set;
+ expectedName = "set " + expectedName;
+ } else {
+ f = Object.getOwnPropertyDescriptor(target, methodName).value;
+ }
+
+ assertEq(f.name, expectedName);
+ }
+ testOne("prop", "prop");
+ testOne("literal", "literal");
+ testOne("", "");
+ testOne(5, "5");
+ testOne(Symbol.iterator, "[Symbol.iterator]");
+ testOne(fooSymbol, "[foo]");
+ testOne(emptySymbol, "[]");
+ testOne(undefSymbol, "");
+ testOne(/a/, "/a/");
+}
+testMethod("");
+testMethod("*");
+testMethod("async");
+testMethod("get");
+testMethod("set");
+
+testMethod("", "class", true);
+testMethod("*", "class", true);
+testMethod("async", "class", true);
+testMethod("get", "class", true);
+testMethod("set", "class", true);
+
+testMethod("static", "class");
+testMethod("static *", "class");
+testMethod("static async", "class");
+testMethod("static get", "class");
+testMethod("static set", "class");
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Function/function-name-property.js b/js/src/tests/ecma_6/Function/function-name-property.js
new file mode 100644
index 000000000..7ad174b10
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/function-name-property.js
@@ -0,0 +1,58 @@
+var BUGNUMBER = 883377;
+var summary = "Anonymous function name should be set based on property name";
+
+print(BUGNUMBER + ": " + summary);
+
+var fooSymbol = Symbol("foo");
+var emptySymbol = Symbol("");
+var undefSymbol = Symbol();
+
+var exprs = [
+ ["function() {}", false],
+ ["function named() {}", true],
+ ["function*() {}", false],
+ ["function* named() {}", true],
+ ["async function() {}", false],
+ ["async function named() {}", true],
+ ["() => {}", false],
+ ["async () => {}", false],
+ ["class {}", false],
+ ["class named {}", true],
+];
+
+function testPropertyDefinition(expr, named) {
+ var obj = eval(`({
+ prop: ${expr},
+ "literal": ${expr},
+ "": ${expr},
+ 5: ${expr},
+ 0.4: ${expr},
+ [Symbol.iterator]: ${expr},
+ [fooSymbol]: ${expr},
+ [emptySymbol]: ${expr},
+ [undefSymbol]: ${expr},
+ [/a/]: ${expr},
+ })`);
+ assertEq(obj.prop.name, named ? "named" : "prop");
+ assertEq(obj["literal"].name, named ? "named" : "literal");
+ assertEq(obj[""].name, named ? "named" : "");
+ assertEq(obj[5].name, named ? "named" : "5");
+ assertEq(obj[0.4].name, named ? "named" : "0.4");
+ assertEq(obj[Symbol.iterator].name, named ? "named" : "[Symbol.iterator]");
+ assertEq(obj[fooSymbol].name, named ? "named" : "[foo]");
+ assertEq(obj[emptySymbol].name, named ? "named" : "[]");
+ assertEq(obj[undefSymbol].name, named ? "named" : "");
+ assertEq(obj[/a/].name, named ? "named" : "/a/");
+
+ // Not applicable cases: __proto__.
+ obj = {
+ __proto__: function() {}
+ };
+ assertEq(obj.__proto__.name, "");
+}
+for (var [expr, named] of exprs) {
+ testPropertyDefinition(expr, named);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Function/invalid-parameter-list.js b/js/src/tests/ecma_6/Function/invalid-parameter-list.js
new file mode 100644
index 000000000..8aae89ef1
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/invalid-parameter-list.js
@@ -0,0 +1,27 @@
+// This constructor behaves like `Function` without checking
+// if the parameter list end is at the expected position.
+// We use this to make sure that the tests we use are otherwise
+// syntactically correct.
+function DumpFunction(...args) {
+ let code = "function anonymous(";
+ code += args.slice(0, -1).join(", ");
+ code += ") {\n";
+ code += args[args.length -1];
+ code += "\n}";
+ eval(code);
+}
+
+const tests = [
+ ["/*", "*/) {"],
+ ["//", ") {"],
+ ["a = `", "` ) {"],
+ [") { var x = function (", "} "],
+ ["x = function (", "}) {"]
+];
+
+for (const test of tests) {
+ DumpFunction(...test);
+ assertThrowsInstanceOf(() => new Function(...test), SyntaxError);
+}
+
+reportCompare(0, 0, 'ok');