diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /js/src/tests/non262/object | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/non262/object')
133 files changed, 6658 insertions, 0 deletions
diff --git a/js/src/tests/non262/object/15.2.3.12.js b/js/src/tests/non262/object/15.2.3.12.js new file mode 100644 index 0000000000..00593a2409 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.12.js @@ -0,0 +1,46 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +/* Object.isFrozen */ + +assertEq(Object.isFrozen({}), false); + +assertEq(Object.isFrozen(Object.preventExtensions({})), true); + +var o = Object.defineProperty({}, 'x', { writable:true, configurable:true }); +Object.preventExtensions(o); +assertEq(Object.isFrozen(o), false); + +var o = Object.defineProperty({}, 'x', { writable:false, configurable:true }); +Object.preventExtensions(o); +assertEq(Object.isFrozen(o), false); + +var o = Object.defineProperty({}, 'x', { writable:true, configurable:false }); +Object.preventExtensions(o); +assertEq(Object.isFrozen(o), false); + +var o = Object.defineProperty({}, 'x', { writable:false, configurable:false }); +assertEq(Object.isFrozen(o), false); + +var o = Object.defineProperty({}, 'x', { writable:false, configurable:false }); +Object.preventExtensions(o); +assertEq(Object.isFrozen(o), true); + +var o = Object.defineProperties({}, { x: { writable:true, configurable:true }, + y: { writable:false, configurable:false } }); +Object.preventExtensions(o); +assertEq(Object.isFrozen(o), false); + +var o = Object.defineProperties({}, { x: { writable:false, configurable:false }, + y: { writable:true, configurable:true } }); +Object.preventExtensions(o); +assertEq(Object.isFrozen(o), false); + +var o = Object.defineProperties({}, { x: { writable:true, configurable:true }, + y: { writable:true, configurable:true } }); +Object.preventExtensions(o); +assertEq(Object.isFrozen(o), false); + +reportCompare(true, true); diff --git a/js/src/tests/non262/object/15.2.3.14-01.js b/js/src/tests/non262/object/15.2.3.14-01.js new file mode 100644 index 0000000000..6cb8965a6c --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.14-01.js @@ -0,0 +1,92 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 307791; +var summary = 'ES5 Object.keys(O)'; +var actual = ''; +var expect = ''; + +printBugNumber(BUGNUMBER); +printStatus(summary); + +function arraysEqual(a1, a2) +{ + return a1.length === a2.length && + a1.every(function(v, i) { return v === a2[i]; }); +} + +/************** + * BEGIN TEST * + **************/ + +assertEq(Object.keys.length, 1); + +var o, keys; + +o = { a: 3, b: 2 }; +keys = Object.keys(o); +assertEq(arraysEqual(keys, ["a", "b"]), true, + "" + keys); + +o = { get a() { return 17; }, b: 2 }; +keys = Object.keys(o), +assertEq(arraysEqual(keys, ["a", "b"]), true, + "" + keys); + +o = { __iterator__: function() { throw new Error("non-standard __iterator__ called?"); } }; +keys = Object.keys(o); +assertEq(arraysEqual(keys, ["__iterator__"]), true, + "" + keys); + +o = { a: 1, b: 2 }; +delete o.a; +o.a = 3; +keys = Object.keys(o); +assertEq(arraysEqual(keys, ["b", "a"]), true, + "" + keys); + +o = [0, 1, 2]; +keys = Object.keys(o); +assertEq(arraysEqual(keys, ["0", "1", "2"]), true, + "" + keys); + +o = /./.exec("abc"); +keys = Object.keys(o); +assertEq(arraysEqual(keys, ["0", "index", "input", "groups"]), true, + "" + keys); + +o = { a: 1, b: 2, c: 3 }; +delete o.b; +o.b = 5; +keys = Object.keys(o); +assertEq(arraysEqual(keys, ["a", "c", "b"]), true, + "" + keys); + +function f() { } +f.prototype.p = 1; +o = new f(); +o.g = 1; +keys = Object.keys(o); +assertEq(arraysEqual(keys, ["g"]), true, + "" + keys); + +if (typeof Namespace !== "undefined" && typeof QName !== "undefined") +{ + var o2 = {}; + var qn = new QName(new Namespace("foo"), "v"); + o2.f = 1; + o2[qn] = 3; + o2.baz = 4; + var keys2 = Object.keys(o2); + assertEq(arraysEqual(keys2, ["f", "foo::v", "baz"]), true, + "" + keys2); +} + +/******************************************************************************/ + +reportCompare(expect, actual, "Object.keys"); + +printStatus("All tests passed!"); diff --git a/js/src/tests/non262/object/15.2.3.3-01.js b/js/src/tests/non262/object/15.2.3.3-01.js new file mode 100644 index 0000000000..ed94a14f4a --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.3-01.js @@ -0,0 +1,285 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 505587; +var summary = 'ES5 Object.getOwnPropertyDescriptor(O)'; +var actual = ''; +var expect = ''; + +printBugNumber(BUGNUMBER); +printStatus (summary); + +/************** + * BEGIN TEST * + **************/ + +function assertEq(a, e, msg) +{ + function SameValue(v1, v2) + { + if (v1 === 0 && v2 === 0) + return 1 / v1 === 1 / v2; + if (v1 !== v1 && v2 !== v2) + return true; + return v1 === v2; + } + + if (!SameValue(a, e)) + { + var stack = new Error().stack || ""; + throw "Assertion failed: got " + a + ", expected " + e + + (msg ? ": " + msg : "") + + (stack ? "\nStack:\n" + stack : ""); + } +} + +function expectDescriptor(actual, expected) +{ + if (actual === undefined && expected === undefined) + return; + + assertEq(typeof actual, "object"); + assertEq(typeof expected, "object"); + + var fields = + { + value: true, + get: true, + set: true, + enumerable: true, + writable: true, + configurable: true + }; + for (var p in fields) + assertEq(actual.hasOwnProperty(p), expected.hasOwnProperty(p), p); + for (var p in actual) + assertEq(p in fields, true, p); + for (var p in expected) + assertEq(p in fields, true, p); + + assertEq(actual.hasOwnProperty("value"), actual.hasOwnProperty("writable")); + assertEq(actual.hasOwnProperty("get"), actual.hasOwnProperty("set")); + if (actual.hasOwnProperty("value")) + { + assertEq(actual.value, expected.value); + assertEq(actual.writable, expected.writable); + } + else + { + assertEq(actual.get, expected.get); + assertEq(actual.set, expected.set); + } + + assertEq(actual.hasOwnProperty("enumerable"), true); + assertEq(actual.hasOwnProperty("configurable"), true); + assertEq(actual.enumerable, expected.enumerable); + assertEq(actual.configurable, expected.configurable); +} + +function adjustDescriptorField(o, actual, expect, field) +{ + assertEq(field === "get" || field === "set", true); + var lookup = "__lookup" + (field === "get" ? "G" : "S") + "etter"; + if (typeof o[lookup] === "function") + expect[field] = o[lookup](field); + else + actual[field] = expect[field] = undefined; /* censor if we can't lookup */ +} + +/******************************************************************************/ + +var o, pd, expected; + +o = { get x() { return 12; } }; + +pd = Object.getOwnPropertyDescriptor(o, "x"); +expected = + { + set: undefined, + enumerable: true, + configurable: true + }; +adjustDescriptorField(o, pd, expected, "get"); + +expectDescriptor(pd, expected); + +/******************************************************************************/ + +var o2; + +o = Object.create(Object.prototype, { x: {get: function () { return 12; } } }); + +pd = Object.getOwnPropertyDescriptor(o, "x"); +expected = + { + set: undefined, + enumerable: false, + configurable: false + }; +adjustDescriptorField(o, pd, expected, "get"); + +expectDescriptor(pd, expected); + +o2 = Object.create(o); +assertEq(Object.getOwnPropertyDescriptor(o2, "x"), undefined); + +/******************************************************************************/ + +o = {}; +o.b = 12; + +pd = Object.getOwnPropertyDescriptor(o, "b"); +expected = + { + value: 12, + writable: true, + enumerable: true, + configurable: true + }; +expectDescriptor(pd, expected); + +/******************************************************************************/ + +o = { get y() { return 17; }, set y(z) { } }; + +pd = Object.getOwnPropertyDescriptor(o, "y"); +expected = + { + enumerable: true, + configurable: true + }; +adjustDescriptorField(o, pd, expected, "get"); +adjustDescriptorField(o, pd, expected, "set"); + +expectDescriptor(pd, expected); + +/******************************************************************************/ + +o = {}; + +pd = Object.getOwnPropertyDescriptor(o, "absent"); + +expectDescriptor(pd, undefined); + +/******************************************************************************/ + +pd = Object.getOwnPropertyDescriptor([], "length"); +expected = + { + value: 0, + writable: true, + enumerable: false, + configurable: false + }; + +expectDescriptor(pd, expected); + +pd = Object.getOwnPropertyDescriptor([1], "length"); +expected = + { + value: 1, + writable: true, + enumerable: false, + configurable: false + }; + +expectDescriptor(pd, expected); + +pd = Object.getOwnPropertyDescriptor([1,], "length"); +expected = + { + value: 1, + writable: true, + enumerable: false, + configurable: false + }; + +expectDescriptor(pd, expected); + +pd = Object.getOwnPropertyDescriptor([1,,], "length"); +expected = + { + value: 2, + writable: true, + enumerable: false, + configurable: false + }; + +expectDescriptor(pd, expected); + +/******************************************************************************/ + +pd = Object.getOwnPropertyDescriptor(new String("foobar"), "length"); +expected = + { + value: 6, + writable: false, + enumerable: false, + configurable: false + }; + +expectDescriptor(pd, expected); + +/******************************************************************************/ + +function foo() { } +o = foo; + +pd = Object.getOwnPropertyDescriptor(o, "length"); +expected = + { + value: 0, + writable: false, + enumerable: false, + configurable: true + }; + +expectDescriptor(pd, expected); + +pd = Object.getOwnPropertyDescriptor(o, "prototype"); +expected = + { + value: foo.prototype, + writable: true, + enumerable: false, + configurable: false + }; + +expectDescriptor(pd, expected); + +/******************************************************************************/ + +pd = Object.getOwnPropertyDescriptor(Function, "length"); +expected = + { + value: 1, + writable: false, + enumerable: false, + configurable: true + }; + +expectDescriptor(pd, expected); + +/******************************************************************************/ + +o = /foo/im; + +pd = Object.getOwnPropertyDescriptor(o, "lastIndex"); +expected = + { + value: 0, + writable: true, + enumerable: false, + configurable: false + }; + +expectDescriptor(pd, expected); + +/******************************************************************************/ + +reportCompare(expect, actual, "Object.getOwnPropertyDescriptor"); + +printStatus("All tests passed"); diff --git a/js/src/tests/non262/object/15.2.3.4-01.js b/js/src/tests/non262/object/15.2.3.4-01.js new file mode 100644 index 0000000000..3a84f0b667 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.4-01.js @@ -0,0 +1,30 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 518663; +var summary = + 'Object.getOwnPropertyNames should play nicely with enumerator caching'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +for (var p in JSON); +var names = Object.getOwnPropertyNames(JSON); +assertEq(names.length >= 2, true, + "wrong number of property names? [" + names + "]"); +assertEq(names.indexOf("parse") >= 0, true); +assertEq(names.indexOf("stringify") >= 0, true); + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/15.2.3.4-02.js b/js/src/tests/non262/object/15.2.3.4-02.js new file mode 100644 index 0000000000..b5e0842c26 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.4-02.js @@ -0,0 +1,52 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 518663; +var summary = 'Object.getOwnPropertyNames: array objects'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var a, names, expected; + +function arraysEqual(a1, a2) +{ + return a1.length === a2.length && + a1.every(function(v, i) { return v === a2[i]; }); +} + + +a = [0, 1, 2]; + +names = Object.getOwnPropertyNames(a).sort(); +expected = ["0", "1", "2", "length"].sort(); + +a = [1, , , 7]; +a.p = 2; +Object.defineProperty(a, "q", { value: 42, enumerable: false }); + +names = Object.getOwnPropertyNames(a).sort(); +expected = ["0", "3", "p", "q", "length"].sort(); +assertEq(arraysEqual(names, expected), true); + + +a = []; + +names = Object.getOwnPropertyNames(a).sort(); +expected = ["length"]; +assertEq(arraysEqual(names, expected), true); + + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/15.2.3.4-03.js b/js/src/tests/non262/object/15.2.3.4-03.js new file mode 100644 index 0000000000..55dcc139c5 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.4-03.js @@ -0,0 +1,55 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 518663; +var summary = 'Object.getOwnPropertyNames: function objects'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function two(a, b) { } + +assertEq(Object.getOwnPropertyNames(two).indexOf("length") >= 0, true); + +var bound0 = Function.prototype.bind + ? two.bind("this") + : function two(a, b) { }; + +assertEq(Object.getOwnPropertyNames(bound0).indexOf("length") >= 0, true); +assertEq(bound0.length, 2); + +var bound1 = Function.prototype.bind + ? two.bind("this", 1) + : function one(a) { }; + +assertEq(Object.getOwnPropertyNames(bound1).indexOf("length") >= 0, true); +assertEq(bound1.length, 1); + +var bound2 = Function.prototype.bind + ? two.bind("this", 1, 2) + : function zero() { }; + +assertEq(Object.getOwnPropertyNames(bound2).indexOf("length") >= 0, true); +assertEq(bound2.length, 0); + +var bound3 = Function.prototype.bind + ? two.bind("this", 1, 2, 3) + : function zero() { }; + +assertEq(Object.getOwnPropertyNames(bound3).indexOf("length") >= 0, true); +assertEq(bound3.length, 0); + + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/15.2.3.4-04.js b/js/src/tests/non262/object/15.2.3.4-04.js new file mode 100644 index 0000000000..2561c7affc --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.4-04.js @@ -0,0 +1,31 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 518663; +var summary = 'Object.getOwnPropertyNames: regular expression objects'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var actual = Object.getOwnPropertyNames(/a/); +var expected = ["lastIndex"]; + +for (var i = 0; i < expected.length; i++) +{ + reportCompare(actual.indexOf(expected[i]) >= 0, true, + expected[i] + " should be a property name on a RegExp"); +} + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/15.2.3.5-01.js b/js/src/tests/non262/object/15.2.3.5-01.js new file mode 100644 index 0000000000..70cfd64f59 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.5-01.js @@ -0,0 +1,60 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 492840; +var summary = 'ES5 Object.create(O [, Properties])'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +assertEq("create" in Object, true); +assertEq(Object.create.length, 2); + +var o, desc, props, proto; + +o = Object.create(null); +assertEq(Object.getPrototypeOf(o), null, "bad null-proto"); + +o = Object.create(null, { a: { value: 17, enumerable: false } }); +assertEq(Object.getPrototypeOf(o), null, "bad null-proto"); +assertEq("a" in o, true); +desc = Object.getOwnPropertyDescriptor(o, "a"); +assertEq(desc !== undefined, true, "no descriptor?"); +assertEq(desc.value, 17); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, false); +assertEq(desc.writable, false); + +props = Object.create({ bar: 15 }); +Object.defineProperty(props, "foo", { enumerable: false, value: 42 }); +proto = { baz: 12 }; +o = Object.create(proto, props); +assertEq(Object.getPrototypeOf(o), proto); +assertEq(Object.getOwnPropertyDescriptor(o, "foo"), undefined); +assertEq("foo" in o, false); +assertEq(Object.getOwnPropertyDescriptor(o, "bar"), undefined); +assertEq("bar" in o, false); +assertEq(Object.getOwnPropertyDescriptor(o, "baz"), undefined); +assertEq(o.baz, 12); +assertEq(o.hasOwnProperty("baz"), false); + +try { + var actual = + Object.create(Object.create({}, + { boom: { get: function() { return "base"; }}}), + { boom: { get: function() { return "overridden"; }}}).boom +} catch (e) { +} +assertEq(actual, "overridden"); + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/15.2.3.6-define-over-method.js b/js/src/tests/non262/object/15.2.3.6-define-over-method.js new file mode 100644 index 0000000000..1cc9e13e14 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-define-over-method.js @@ -0,0 +1,24 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 568786; +var summary = + 'Do not assert: !(attrs & (JSPROP_GETTER | JSPROP_SETTER)) with ' + + 'Object.defineProperty'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var o = { x: function(){} }; +Object.defineProperty(o, "x", { get: function(){} }); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-01-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-01-of-32.js new file mode 100644 index 0000000000..aea3a41f92 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-01-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(1, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-02-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-02-of-32.js new file mode 100644 index 0000000000..833ecfe937 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-02-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(2, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-03-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-03-of-32.js new file mode 100644 index 0000000000..2f4673c49d --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-03-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(3, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-04-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-04-of-32.js new file mode 100644 index 0000000000..7b2b89c878 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-04-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(4, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-05-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-05-of-32.js new file mode 100644 index 0000000000..87bed4dbe2 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-05-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(5, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-06-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-06-of-32.js new file mode 100644 index 0000000000..16b16d22d6 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-06-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(6, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-07-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-07-of-32.js new file mode 100644 index 0000000000..2a0509c30a --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-07-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(7, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-08-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-08-of-32.js new file mode 100644 index 0000000000..7d49565b44 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-08-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(8, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-09-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-09-of-32.js new file mode 100644 index 0000000000..cf8e39e658 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-09-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(9, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-10-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-10-of-32.js new file mode 100644 index 0000000000..a65d17dff1 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-10-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(10, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-11-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-11-of-32.js new file mode 100644 index 0000000000..60e07c1c28 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-11-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(11, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-12-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-12-of-32.js new file mode 100644 index 0000000000..69045d0d1d --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-12-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(12, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-13-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-13-of-32.js new file mode 100644 index 0000000000..95d39424ee --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-13-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(13, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-14-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-14-of-32.js new file mode 100644 index 0000000000..58bdb5e9f5 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-14-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(14, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-15-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-15-of-32.js new file mode 100644 index 0000000000..5828adec23 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-15-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(15, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-16-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-16-of-32.js new file mode 100644 index 0000000000..6e797312d8 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-16-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(16, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-17-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-17-of-32.js new file mode 100644 index 0000000000..f2dbb6ae9a --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-17-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(17, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-18-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-18-of-32.js new file mode 100644 index 0000000000..f062ceabf8 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-18-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(18, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-19-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-19-of-32.js new file mode 100644 index 0000000000..96310b7bd7 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-19-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(19, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-20-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-20-of-32.js new file mode 100644 index 0000000000..9c3c52a25f --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-20-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(20, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-21-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-21-of-32.js new file mode 100644 index 0000000000..e3f99899f2 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-21-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(21, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-22-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-22-of-32.js new file mode 100644 index 0000000000..85d6cf9645 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-22-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(22, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-23-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-23-of-32.js new file mode 100644 index 0000000000..a1a8d40e3f --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-23-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(23, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-24-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-24-of-32.js new file mode 100644 index 0000000000..ff561a5dd3 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-24-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(24, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-25-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-25-of-32.js new file mode 100644 index 0000000000..0748343eec --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-25-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(25, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-26-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-26-of-32.js new file mode 100644 index 0000000000..4ab28fe386 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-26-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(26, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-27-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-27-of-32.js new file mode 100644 index 0000000000..f97d13b8f9 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-27-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(27, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-28-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-28-of-32.js new file mode 100644 index 0000000000..1d28e785aa --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-28-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(28, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-29-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-29-of-32.js new file mode 100644 index 0000000000..3d72404a0c --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-29-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(29, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-30-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-30-of-32.js new file mode 100644 index 0000000000..d5ec96f312 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-30-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(30, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-31-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-31-of-32.js new file mode 100644 index 0000000000..182499268c --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-31-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(31, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-32-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-32-of-32.js new file mode 100644 index 0000000000..6f78157b59 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-32-of-32.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runDictionaryPropertyPresentTestsFraction(32, 32); diff --git a/js/src/tests/non262/object/15.2.3.6-function-length.js b/js/src/tests/non262/object/15.2.3.6-function-length.js new file mode 100644 index 0000000000..ddbb7b9f88 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-function-length.js @@ -0,0 +1,35 @@ +// |reftest| skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 430133; +var summary = 'ES5 Object.defineProperty(O, P, Attributes): Function.length'; + +print(BUGNUMBER + ": " + summary); + +loadRelativeToScript("defineProperty-setup.js"); + +/************** + * BEGIN TEST * + **************/ + +try +{ + new TestRunner().runFunctionLengthTests(); +} +catch (e) +{ + throw "Error thrown during testing: " + e + + " at line " + e.lineNumber + "\n" + + (e.stack + ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n" + : ""); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete!"); diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-1-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-1-of-8.js new file mode 100644 index 0000000000..2b693853ed --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-1-of-8.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runNonTerminalPropertyPresentTestsFraction(1, 8); diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-2-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-2-of-8.js new file mode 100644 index 0000000000..483485ab22 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-2-of-8.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runNonTerminalPropertyPresentTestsFraction(2, 8); diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-3-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-3-of-8.js new file mode 100644 index 0000000000..8dd876e1f6 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-3-of-8.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runNonTerminalPropertyPresentTestsFraction(3, 8); diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-4-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-4-of-8.js new file mode 100644 index 0000000000..14a2f0907f --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-4-of-8.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runNonTerminalPropertyPresentTestsFraction(4, 8); diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-5-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-5-of-8.js new file mode 100644 index 0000000000..d671a8ce49 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-5-of-8.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runNonTerminalPropertyPresentTestsFraction(5, 8); diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-6-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-6-of-8.js new file mode 100644 index 0000000000..5ff5922429 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-6-of-8.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runNonTerminalPropertyPresentTestsFraction(6, 8); diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-7-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-7-of-8.js new file mode 100644 index 0000000000..4a792d2f34 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-7-of-8.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runNonTerminalPropertyPresentTestsFraction(7, 8); diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-8-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-8-of-8.js new file mode 100644 index 0000000000..8cea528150 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-8-of-8.js @@ -0,0 +1,6 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +loadRelativeToScript("defineProperty-setup.js"); +runNonTerminalPropertyPresentTestsFraction(8, 8); diff --git a/js/src/tests/non262/object/15.2.3.6-miscellaneous.js b/js/src/tests/non262/object/15.2.3.6-miscellaneous.js new file mode 100644 index 0000000000..9f671c52ce --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-miscellaneous.js @@ -0,0 +1,74 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 430133; +var summary = 'ES5 Object.defineProperty(O, P, Attributes)'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var o = []; +Object.defineProperty(o, 0, { value: 17 }); +var desc = Object.getOwnPropertyDescriptor(o, 0); +assertEq(desc !== undefined, true); +assertEq(desc.value, 17); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, false); +assertEq(desc.writable, false); + +desc = Object.getOwnPropertyDescriptor(o, "length"); +assertEq(desc !== undefined, true); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, false); +assertEq(desc.writable, true); +assertEq(desc.value, 1); +assertEq(o.length, 1); + +Object.defineProperty(o, "foobar", + { value: 42, enumerable: false, configurable: true }); +assertEq(o.foobar, 42); +desc = Object.getOwnPropertyDescriptor(o, "foobar"); +assertEq(desc !== undefined, true); +assertEq(desc.value, 42); +assertEq(desc.configurable, true); +assertEq(desc.enumerable, false); +assertEq(desc.writable, false); + +var called = false; +o = { set x(a) { called = true; } }; +Object.defineProperty(o, "x", { get: function() { return "get"; } }); +desc = Object.getOwnPropertyDescriptor(o, "x"); +assertEq("set" in desc, true); +assertEq("get" in desc, true); +assertEq(called, false); +o.x = 13; +assertEq(called, true); + +var toSource = Object.prototype.toSource || function() { }; +toSource.call(o); // a test for this not crashing + +var called = false; +var o = + Object.defineProperty({}, "foo", + { get: function() { return 17; }, + set: function(v) { called = true; } }); + +assertEq(o.foo, 17); +o.foo = 42; +assertEq(called, true); + +/* + * XXX need tests for Object.defineProperty(array, "length", { ... }) when we + * support it! + */ + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/15.2.3.6-new-definition.js b/js/src/tests/non262/object/15.2.3.6-new-definition.js new file mode 100644 index 0000000000..7f938203e9 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-new-definition.js @@ -0,0 +1,35 @@ +// |reftest| skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 430133; +var summary = 'ES5 Object.defineProperty(O, P, Attributes): new definition'; + +print(BUGNUMBER + ": " + summary); + +loadRelativeToScript("defineProperty-setup.js"); + +/************** + * BEGIN TEST * + **************/ + +try +{ + new TestRunner().runNotPresentTests(); +} +catch (e) +{ + throw "Error thrown during testing: " + e + + " at line " + e.lineNumber + "\n" + + (e.stack + ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n" + : ""); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete!"); diff --git a/js/src/tests/non262/object/15.2.3.6-redefinition-1-of-4.js b/js/src/tests/non262/object/15.2.3.6-redefinition-1-of-4.js new file mode 100644 index 0000000000..d826a77551 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-redefinition-1-of-4.js @@ -0,0 +1,39 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var PART = 1, PARTS = 4; + +//----------------------------------------------------------------------------- +var BUGNUMBER = 430133; +var summary = + 'ES5 Object.defineProperty(O, P, Attributes): redefinition ' + + PART + ' of ' + PARTS; + +print(BUGNUMBER + ": " + summary); + +loadRelativeToScript("defineProperty-setup.js"); + +/************** + * BEGIN TEST * + **************/ + +try +{ + new TestRunner().runPropertyPresentTestsFraction(PART, PARTS); +} +catch (e) +{ + throw "Error thrown during testing: " + e + + " at line " + e.lineNumber + "\n" + + (e.stack + ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n" + : ""); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete!"); diff --git a/js/src/tests/non262/object/15.2.3.6-redefinition-2-of-4.js b/js/src/tests/non262/object/15.2.3.6-redefinition-2-of-4.js new file mode 100644 index 0000000000..78f862cb7e --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-redefinition-2-of-4.js @@ -0,0 +1,39 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var PART = 2, PARTS = 4; + +//----------------------------------------------------------------------------- +var BUGNUMBER = 430133; +var summary = + 'ES5 Object.defineProperty(O, P, Attributes): redefinition ' + + PART + ' of ' + PARTS; + +print(BUGNUMBER + ": " + summary); + +loadRelativeToScript("defineProperty-setup.js"); + +/************** + * BEGIN TEST * + **************/ + +try +{ + new TestRunner().runPropertyPresentTestsFraction(PART, PARTS); +} +catch (e) +{ + throw "Error thrown during testing: " + e + + " at line " + e.lineNumber + "\n" + + (e.stack + ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n" + : ""); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete!"); diff --git a/js/src/tests/non262/object/15.2.3.6-redefinition-3-of-4.js b/js/src/tests/non262/object/15.2.3.6-redefinition-3-of-4.js new file mode 100644 index 0000000000..0458a79577 --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-redefinition-3-of-4.js @@ -0,0 +1,39 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var PART = 3, PARTS = 4; + +//----------------------------------------------------------------------------- +var BUGNUMBER = 430133; +var summary = + 'ES5 Object.defineProperty(O, P, Attributes): redefinition ' + + PART + ' of ' + PARTS; + +print(BUGNUMBER + ": " + summary); + +loadRelativeToScript("defineProperty-setup.js"); + +/************** + * BEGIN TEST * + **************/ + +try +{ + new TestRunner().runPropertyPresentTestsFraction(PART, PARTS); +} +catch (e) +{ + throw "Error thrown during testing: " + e + + " at line " + e.lineNumber + "\n" + + (e.stack + ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n" + : ""); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete!"); diff --git a/js/src/tests/non262/object/15.2.3.6-redefinition-4-of-4.js b/js/src/tests/non262/object/15.2.3.6-redefinition-4-of-4.js new file mode 100644 index 0000000000..8aa6d0a95a --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.6-redefinition-4-of-4.js @@ -0,0 +1,39 @@ +// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var PART = 4, PARTS = 4; + +//----------------------------------------------------------------------------- +var BUGNUMBER = 430133; +var summary = + 'ES5 Object.defineProperty(O, P, Attributes): redefinition ' + + PART + ' of ' + PARTS; + +print(BUGNUMBER + ": " + summary); + +loadRelativeToScript("defineProperty-setup.js"); + +/************** + * BEGIN TEST * + **************/ + +try +{ + new TestRunner().runPropertyPresentTestsFraction(PART, PARTS); +} +catch (e) +{ + throw "Error thrown during testing: " + e + + " at line " + e.lineNumber + "\n" + + (e.stack + ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n" + : ""); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete!"); diff --git a/js/src/tests/non262/object/15.2.3.7-01.js b/js/src/tests/non262/object/15.2.3.7-01.js new file mode 100644 index 0000000000..5220e1483f --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.7-01.js @@ -0,0 +1,137 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 430133; +var summary = 'ES5 Object.defineProperties(O, Properties)'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +assertEq("defineProperties" in Object, true); +assertEq(Object.defineProperties.length, 2); + +var o, props, desc, passed; + +o = {}; +props = + { + a: { value: 17, enumerable: true, configurable: true, writable: true }, + b: { value: 42, enumerable: false, configurable: false, writable: false } + }; +Object.defineProperties(o, props); +assertEq("a" in o, true); +assertEq("b" in o, true); +desc = Object.getOwnPropertyDescriptor(o, "a"); +assertEq(desc.value, 17); +assertEq(desc.enumerable, true); +assertEq(desc.configurable, true); +assertEq(desc.writable, true); +desc = Object.getOwnPropertyDescriptor(o, "b"); +assertEq(desc.value, 42); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, false); +assertEq(desc.writable, false); + +props = + { + c: { value: NaN, enumerable: false, configurable: true, writable: true }, + b: { value: 44 } + }; +var error = "before"; +try +{ + Object.defineProperties(o, props); + error = "no exception thrown"; +} +catch (e) +{ + if (e instanceof TypeError) + error = "typeerror"; + else + error = "bad exception: " + e; +} +assertEq(error, "typeerror", "didn't throw or threw wrongly"); +assertEq("c" in o, true, "new property added"); +assertEq(o.b, 42, "old property value preserved"); + +function Properties() { } +Properties.prototype = { b: { value: 42, enumerable: true } }; +props = new Properties(); +Object.defineProperty(props, "a", { enumerable: false }); +o = {}; +Object.defineProperties(o, props); +assertEq("a" in o, false); +assertEq(Object.getOwnPropertyDescriptor(o, "a"), undefined, + "Object.defineProperties(O, Properties) should only use enumerable " + + "properties on Properties"); +assertEq("b" in o, false); +assertEq(Object.getOwnPropertyDescriptor(o, "b"), undefined, + "Object.defineProperties(O, Properties) should only use enumerable " + + "properties directly on Properties"); + +Number.prototype.foo = { value: 17, enumerable: true }; +Boolean.prototype.bar = { value: 8675309, enumerable: true }; +String.prototype.quux = { value: "Are you HAPPY yet?", enumerable: true }; +o = {}; +Object.defineProperties(o, 5); // ToObject only throws for null/undefined +assertEq("foo" in o, false, "foo is not an enumerable own property"); +Object.defineProperties(o, false); +assertEq("bar" in o, false, "bar is not an enumerable own property"); +Object.defineProperties(o, ""); +assertEq("quux" in o, false, "quux is not an enumerable own property"); + +error = "before"; +try +{ + Object.defineProperties(o, "1"); +} +catch (e) +{ + if (e instanceof TypeError) + error = "typeerror"; + else + error = "bad exception: " + e; +} +assertEq(error, "typeerror", + "should throw on Properties == '1' due to '1'[0] not being a " + + "property descriptor"); + +error = "before"; +try +{ + Object.defineProperties(o, null); +} +catch (e) +{ + if (e instanceof TypeError) + error = "typeerror"; + else + error = "bad exception: " + e; +} +assertEq(error, "typeerror", "should throw on Properties == null"); + +error = "before"; +try +{ + Object.defineProperties(o, undefined); +} +catch (e) +{ + if (e instanceof TypeError) + error = "typeerror"; + else + error = "bad exception: " + e; +} +assertEq(error, "typeerror", "should throw on Properties == undefined"); + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/15.2.3.9.js b/js/src/tests/non262/object/15.2.3.9.js new file mode 100644 index 0000000000..c73437fa7d --- /dev/null +++ b/js/src/tests/non262/object/15.2.3.9.js @@ -0,0 +1,51 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +/* Object.freeze */ + +function getme() { return 42; }; +function setme(x) { }; + +var properties = { all: { value:1, writable:true, configurable:true, enumerable: true }, + readOnly: { value:2, writable:false, configurable:true, enumerable: true }, + nonConfig: { value:3, writable:true, configurable:false, enumerable: true }, + none: { value:4, writable:false, configurable:false, enumerable: true }, + getter: { get: getme, configurable:false, enumerable: true }, + setter: { set: setme, configurable:false, enumerable: true }, + getandset: { get: getme, set: setme, configurable:false, enumerable: true } + }; +var o = Object.defineProperties({}, properties); + +Object.freeze(o); + +function getPropertyOf(obj) { + return function (prop) { + return Object.getOwnPropertyDescriptor(obj, prop); + }; +}; + +assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'all'), + { value: 1, writable:false, enumerable:true, configurable:false }), + true); +assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'readOnly'), + { value: 2, writable:false, enumerable:true, configurable:false }), + true); +assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'nonConfig'), + { value: 3, writable:false, enumerable:true, configurable:false }), + true); +assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'none'), + { value: 4, writable:false, enumerable:true, configurable:false }), + true); +assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'getter'), + { get: getme, set: (void 0), enumerable:true, configurable:false }), + true); +assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'setter'), + { set: setme, get: (void 0), enumerable:true, configurable:false }), + true); +assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'getandset'), + { get: getme, set: setme, enumerable:true, configurable:false }), + true); + +reportCompare(true, true); diff --git a/js/src/tests/non262/object/accessor-arguments-rest.js b/js/src/tests/non262/object/accessor-arguments-rest.js new file mode 100644 index 0000000000..82f37b62e3 --- /dev/null +++ b/js/src/tests/non262/object/accessor-arguments-rest.js @@ -0,0 +1,24 @@ +assertThrowsInstanceOf(() => eval("({ get x(...a) { } })"), SyntaxError); +assertThrowsInstanceOf(() => eval("({ get x(a, ...b) { } })"), SyntaxError); +assertThrowsInstanceOf(() => eval("({ get x([a], ...b) { } })"), SyntaxError); +assertThrowsInstanceOf(() => eval("({ get x({a}, ...b) { } })"), SyntaxError); +assertThrowsInstanceOf(() => eval("({ get x({a: A}, ...b) { } })"), SyntaxError); + +assertThrowsInstanceOf(() => eval("({ set x(...a) { } })"), SyntaxError); +assertThrowsInstanceOf(() => eval("({ set x(a, ...b) { } })"), SyntaxError); +assertThrowsInstanceOf(() => eval("({ set x([a], ...b) { } })"), SyntaxError); +assertThrowsInstanceOf(() => eval("({ set x({a: A}, ...b) { } })"), SyntaxError); + +({ get(...a) { } }); +({ get(a, ...b) { } }); +({ get([a], ...b) { } }); +({ get({a}, ...b) { } }); +({ get({a: A}, ...b) { } }); + +({ set(...a) { } }); +({ set(a, ...b) { } }); +({ set([a], ...b) { } }); +({ set({a: A}, ...b) { } }); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/accessor-name.js b/js/src/tests/non262/object/accessor-name.js new file mode 100644 index 0000000000..f238a2aefc --- /dev/null +++ b/js/src/tests/non262/object/accessor-name.js @@ -0,0 +1,35 @@ +function name(obj, property, get) { + let desc = Object.getOwnPropertyDescriptor(obj, property); + return (get ? desc.get : desc.set).name; +} + +assertEq(name({get a() {}}, "a", true), "get a"); +assertEq(name({set a(v) {}}, "a", false), "set a"); + +assertEq(name({get 123() {}}, "123", true), "get 123"); +assertEq(name({set 123(v) {}}, "123", false), "set 123"); + +assertEq(name({get case() {}}, "case", true), "get case"); +assertEq(name({set case(v) {}}, "case", false), "set case"); + +assertEq(name({get get() {}}, "get", true), "get get"); +assertEq(name({set set(v) {}}, "set", false), "set set"); + +let o = {get a() { }, set a(v) {}}; +assertEq(name(o, "a", true), "get a"); +assertEq(name(o, "a", false), "set a"); + +o = {get 123() { }, set 123(v) {}} +assertEq(name(o, "123", true), "get 123"); +assertEq(name(o, "123", false), "set 123"); + +o = {get case() { }, set case(v) {}} +assertEq(name(o, "case", true), "get case"); +assertEq(name(o, "case", false), "set case"); + +assertEq(name({get ["a"]() {}}, "a", true), "get a"); +assertEq(name({get [123]() {}}, "123", true), "get 123"); +assertEq(name({set ["a"](v) {}}, "a", false), "set a"); +assertEq(name({set [123](v) {}}, "123", false), "set 123"); + +reportCompare(true, true); diff --git a/js/src/tests/non262/object/accessor-non-constructor.js b/js/src/tests/non262/object/accessor-non-constructor.js new file mode 100644 index 0000000000..32d1d34673 --- /dev/null +++ b/js/src/tests/non262/object/accessor-non-constructor.js @@ -0,0 +1,20 @@ +var obj = { get a() { return 1; } }; +assertThrowsInstanceOf(() => { + new Object.getOwnPropertyDescriptor(obj, "a").get +}, TypeError); + +obj = { set a(b) { } }; +assertThrowsInstanceOf(() => { + new Object.getOwnPropertyDescriptor(obj, "a").set +}, TypeError); + +obj = { get a() { return 1; }, set a(b) { } }; +assertThrowsInstanceOf(() => { + new Object.getOwnPropertyDescriptor(obj, "a").get +}, TypeError); +assertThrowsInstanceOf(() => { + new Object.getOwnPropertyDescriptor(obj, "a").set +}, TypeError); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/add-property-non-extensible.js b/js/src/tests/non262/object/add-property-non-extensible.js new file mode 100644 index 0000000000..2089a5678b --- /dev/null +++ b/js/src/tests/non262/object/add-property-non-extensible.js @@ -0,0 +1,118 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +var gTestfile = 'add-property-non-extensible.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 602144; +var summary = + 'Properly method-compile attempted addition of properties to ' + + 'non-extensible objects'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +// No property + +var o1 = {}; +for (var i = 0; i < 5; i++) + o1.a = 3; +assertEq(o1.a, 3); + +var o2 = Object.preventExtensions({}); +for (var i = 0; i < 5; i++) + o2.a = 3; +assertEq(Object.getOwnPropertyDescriptor(o2, "a"), undefined); + +var o3 = Object.seal({}); +for (var i = 0; i < 5; i++) + o3.a = 3; +assertEq(Object.getOwnPropertyDescriptor(o3, "a"), undefined); + +var o4 = Object.freeze({}); +for (var i = 0; i < 5; i++) + o4.a = 3; +assertEq(Object.getOwnPropertyDescriptor(o4, "a"), undefined); + + +// Has property + +var o5 = { a: 2 }; +for (var i = 0; i < 5; i++) + o5.a = 3; +assertEq(o5.a, 3); + +var o6 = Object.preventExtensions({ a: 2 }); +for (var i = 0; i < 5; i++) + o6.a = 3; +assertEq(o6.a, 3); + +var o7 = Object.seal({ a: 2 }); +for (var i = 0; i < 5; i++) + o7.a = 3; +assertEq(o7.a, 3); + +var o8 = Object.freeze({ a: 2 }); +for (var i = 0; i < 5; i++) + o8.a = 3; +assertEq(o8.a, 2); + + +// Extensible, hit up the prototype chain + +var o9 = Object.create({ a: 2 }); +for (var i = 0; i < 5; i++) + o9.a = 3; +assertEq(o9.a, 3); + +var o10 = Object.create(Object.preventExtensions({ a: 2 })); +for (var i = 0; i < 5; i++) + o10.a = 3; +assertEq(o10.a, 3); + +var o11 = Object.create(Object.seal({ a: 2 })); +for (var i = 0; i < 5; i++) + o11.a = 3; +assertEq(o11.a, 3); + +var o12 = Object.create(Object.freeze({ a: 2 })); +for (var i = 0; i < 5; i++) + o12.a = 3; +assertEq(Object.getOwnPropertyDescriptor(o12, "a"), undefined); + + +// Not extensible, hit up the prototype chain + +var o13 = Object.preventExtensions(Object.create({ a: 2 })); +for (var i = 0; i < 5; i++) + o13.a = 3; +assertEq(Object.getOwnPropertyDescriptor(o13, "a"), undefined); + +var o14 = + Object.preventExtensions(Object.create(Object.preventExtensions({ a: 2 }))); +for (var i = 0; i < 5; i++) + o14.a = 3; +assertEq(Object.getOwnPropertyDescriptor(o14, "a"), undefined); + +var o15 = Object.preventExtensions(Object.create(Object.seal({ a: 2 }))); +for (var i = 0; i < 5; i++) + o15.a = 3; +assertEq(Object.getOwnPropertyDescriptor(o15, "a"), undefined); + +var o16 = Object.preventExtensions(Object.create(Object.freeze({ a: 2 }))); +for (var i = 0; i < 5; i++) + o16.a = 3; +assertEq(Object.getOwnPropertyDescriptor(o16, "a"), undefined); + + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/assign.js b/js/src/tests/non262/object/assign.js new file mode 100644 index 0000000000..8828bdb21c --- /dev/null +++ b/js/src/tests/non262/object/assign.js @@ -0,0 +1,303 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function checkDataProperty(object, propertyKey, value, writable, enumerable, configurable) { + var desc = Object.getOwnPropertyDescriptor(object, propertyKey); + assertEq(desc === undefined, false); + assertEq('value' in desc, true); + assertEq(desc.value, value); + assertEq(desc.writable, writable); + assertEq(desc.enumerable, enumerable); + assertEq(desc.configurable, configurable); +} + +/* 19.1.2.1 Object.assign ( target, ...sources ) */ +assertEq(Object.assign.length, 2); + +// Basic functionality works with multiple sources +function basicMultipleSources() { + var a = {}; + var b = { bProp : 7 }; + var c = { cProp : 8 }; + Object.assign(a, b, c); + assertEq(a.bProp, 7); + assertEq(a.cProp, 8); +} +basicMultipleSources(); + +// Basic functionality works with symbols (Bug 1052358) +function basicSymbols() { + var a = {}; + var b = { bProp : 7 }; + var aSymbol = Symbol("aSymbol"); + b[aSymbol] = 22; + Object.assign(a, b); + assertEq(a.bProp, 7); + assertEq(a[aSymbol], 22); +} +basicSymbols(); + +// Calls ToObject() for target, skips null/undefined sources, uses +// ToObject(source) otherwise. +function testToObject() { + assertThrowsInstanceOf(() => Object.assign(null, null), TypeError); + assertThrowsInstanceOf(() => Object.assign(), TypeError); + assertThrowsInstanceOf(() => Object.assign(null, {}), TypeError); + assertEq(Object.assign({}, null) instanceof Object, true); + assertEq(Object.assign({}, undefined) instanceof Object, true); + + // Technically an embedding could have this as extension acting differently + // from ours, so a feature-test is inadequate. We can move this subtest + // into extensions/ if that ever matters. + if (typeof createIsHTMLDDA === "function") { + var falsyObject = createIsHTMLDDA(); + falsyObject.foo = 7; + + var obj = Object.assign({}, falsyObject); + assertEq(obj instanceof Object, true); + assertEq(obj.foo, 7); + } + + assertEq(Object.assign(true, {}) instanceof Boolean, true); + assertEq(Object.assign(1, {}) instanceof Number, true); + assertEq(Object.assign("string", {}) instanceof String, true); + var o = {}; + assertEq(Object.assign(o, {}), o); +} +testToObject(); + +// Invokes [[OwnPropertyKeys]] on ToObject(source) +function testOwnPropertyKeys() { + assertThrowsInstanceOf(() => Object.assign(null, new Proxy({}, { + getOwnPropertyNames: () => { throw new Error("not called"); } + })), TypeError); + + var ownKeysCalled = false; + Object.assign({}, new Proxy({}, { + ownKeys: function() { + ownKeysCalled = true; + return []; + } + })); + assertEq(ownKeysCalled, true); +}; +testOwnPropertyKeys(); + +// Ensure correct property traversal +function correctPropertyTraversal() { + var log = ""; + var source = new Proxy({a: 1, b: 2}, { + ownKeys: () => ["b", "c", "a"], + getOwnPropertyDescriptor: function(t, pk) { + log += "#" + pk; + return Object.getOwnPropertyDescriptor(t, pk); + }, + get: function(t, pk, r) { + log += "-" + pk; + return t[pk]; + }, + }); + Object.assign({}, source); + assertEq(log, "#b-b#c#a-a"); +} +correctPropertyTraversal(); + +// Only [[Enumerable]] properties are assigned to target +function onlyEnumerablePropertiesAssigned() { + var source = Object.defineProperties({}, { + a: {value: 1, enumerable: true}, + b: {value: 2, enumerable: false}, + }); + var target = Object.assign({}, source); + assertEq("a" in target, true); + assertEq("b" in target, false); +} +onlyEnumerablePropertiesAssigned(); + + +// Enumerability is decided on-time, not before main loop (1) +function testEnumerabilityDeterminedInLoop1() +{ + var getterCalled = false; + var sourceTarget = { + get a() { getterCalled = true }, + get b() { Object.defineProperty(sourceTarget, "a", {enumerable: false}) }, + }; + var source = new Proxy(sourceTarget, { ownKeys: () => ["b", "a"] }); + Object.assign({}, source); + assertEq(getterCalled, false); +} +testEnumerabilityDeterminedInLoop1(); + +// Enumerability is decided on-time, not before main loop (2) +function testEnumerabilityDeterminedInLoop2() +{ + var getterCalled = false; + var sourceTarget = { + get a() { getterCalled = true }, + get b() { Object.defineProperty(sourceTarget, "a", {enumerable: true}) }, + }; + var source = new Proxy(sourceTarget, { + ownKeys: () => ["b", "a"] + }); + Object.defineProperty(sourceTarget, "a", {enumerable: false}); + Object.assign({}, source); + assertEq(getterCalled, true); +} +testEnumerabilityDeterminedInLoop2(); + +// Properties are retrieved through Get() and assigned onto +// the target as data properties, not in any sense cloned over as descriptors +function testPropertiesRetrievedThroughGet() { + var getterCalled = false; + Object.assign({}, {get a() { getterCalled = true }}); + assertEq(getterCalled, true); +} +testPropertiesRetrievedThroughGet(); + +// Properties are retrieved through Get() +// Properties are assigned through Put() +function testPropertiesAssignedThroughPut() { + var setterCalled = false; + Object.assign({set a(v) { setterCalled = v }}, {a: true}); + assertEq(setterCalled, true); +} +testPropertiesAssignedThroughPut(); + +// Properties are retrieved through Get() +// Properties are assigned through Put(): Existing property attributes are not altered +function propertiesAssignedExistingNotAltered() { + var source = {a: 1, b: 2, c: 3}; + var target = {a: 0, b: 0, c: 0}; + Object.defineProperty(target, "a", {enumerable: false}); + Object.defineProperty(target, "b", {configurable: false}); + Object.defineProperty(target, "c", {enumerable: false, configurable: false}); + Object.assign(target, source); + checkDataProperty(target, "a", 1, true, false, true); + checkDataProperty(target, "b", 2, true, true, false); + checkDataProperty(target, "c", 3, true, false, false); +} +propertiesAssignedExistingNotAltered(); + +// Properties are retrieved through Get() +// Properties are assigned through Put(): Throws TypeError if non-writable +function propertiesAssignedTypeErrorNonWritable() { + var source = {a: 1}; + var target = {a: 0}; + Object.defineProperty(target, "a", {writable: false}); + assertThrowsInstanceOf(() => Object.assign(target, source), TypeError); + checkDataProperty(target, "a", 0, false, true, true); +} +propertiesAssignedTypeErrorNonWritable(); + +// Properties are retrieved through Get() +// Put() creates standard properties; Property attributes from source are ignored +function createsStandardProperties() { + var source = {a: 1, b: 2, c: 3, get d() { return 4 }}; + Object.defineProperty(source, "b", {writable: false}); + Object.defineProperty(source, "c", {configurable: false}); + var target = Object.assign({}, source); + checkDataProperty(target, "a", 1, true, true, true); + checkDataProperty(target, "b", 2, true, true, true); + checkDataProperty(target, "c", 3, true, true, true); + checkDataProperty(target, "d", 4, true, true, true); +} +createsStandardProperties(); + +// Properties created during traversal are not copied +function propertiesCreatedDuringTraversalNotCopied() { + var source = {get a() { this.b = 2 }}; + var target = Object.assign({}, source); + assertEq("a" in target, true); + assertEq("b" in target, false); +} +propertiesCreatedDuringTraversalNotCopied(); + +// Properties deleted during traversal are not copied +function testDeletePropertiesNotCopied() { + var source = new Proxy({ + get a() { delete this.b }, + b: 2, + }, { + getOwnPropertyNames: () => ["a", "b"] + }); + var target = Object.assign({}, source); + assertEq("a" in target, true); + assertEq("b" in target, false); +} +testDeletePropertiesNotCopied(); + +function testDeletionExposingShadowedProperty() +{ + var srcProto = { b: 42 }; + var src = + Object.create(srcProto, + { a: { enumerable: true, get: function() { delete this.b; } }, + b: { value: 2, configurable: true, enumerable: true } }); + var source = new Proxy(src, { getOwnPropertyNames: () => ["a", "b"] }); + var target = Object.assign({}, source); + assertEq("a" in target, true); + assertEq("b" in target, false); +} +testDeletionExposingShadowedProperty(); + +// Properties first deleted and then recreated during traversal are copied (1) +function testDeletedAndRecreatedPropertiesCopied1() { + var source = new Proxy({ + get a() { delete this.c }, + get b() { this.c = 4 }, + c: 3, + }, { + getOwnPropertyNames: () => ["a", "b", "c"] + }); + var target = Object.assign({}, source); + assertEq("a" in target, true); + assertEq("b" in target, true); + assertEq("c" in target, true); + checkDataProperty(target, "c", 4, true, true, true); +} +testDeletedAndRecreatedPropertiesCopied1(); + +// Properties first deleted and then recreated during traversal are copied (2) +function testDeletedAndRecreatedPropertiesCopied2() { + var source = new Proxy({ + get a() { delete this.c }, + get b() { this.c = 4 }, + c: 3, + }, { + ownKeys: () => ["a", "c", "b"] + }); + var target = Object.assign({}, source); + assertEq("a" in target, true); + assertEq("b" in target, true); + assertEq("c" in target, false); +} +testDeletedAndRecreatedPropertiesCopied2(); + +// String and Symbol valued properties are copied +function testStringAndSymbolPropertiesCopied() { + var keyA = "str-prop"; + var source = {"str-prop": 1}; + var target = Object.assign({}, source); + checkDataProperty(target, keyA, 1, true, true, true); +} +testStringAndSymbolPropertiesCopied(); + +// Intermediate exceptions stop traversal and throw exception +function testExceptionsDoNotStopFirstReported1() { + var TestError = function TestError() {}; + var source = new Proxy({}, { + getOwnPropertyDescriptor: function(t, pk) { + assertEq(pk, "b"); + throw new TestError(); + }, + ownKeys: () => ["b", "a"] + }); + assertThrowsInstanceOf(() => Object.assign({}, source), TestError); +} +testExceptionsDoNotStopFirstReported1(); + + +if (typeof reportCompare == "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/browser.js b/js/src/tests/non262/object/browser.js new file mode 100644 index 0000000000..0e57d1fcd0 --- /dev/null +++ b/js/src/tests/non262/object/browser.js @@ -0,0 +1,7 @@ +var GLOBAL = 'Window'; + +function isObject(obj) +{ + return obj instanceof Object || obj == window; +} + diff --git a/js/src/tests/non262/object/bug-1150906.js b/js/src/tests/non262/object/bug-1150906.js new file mode 100644 index 0000000000..27403cccfe --- /dev/null +++ b/js/src/tests/non262/object/bug-1150906.js @@ -0,0 +1,13 @@ +function f(x) { + Object.defineProperty(arguments, 0, { + get: function() {} + }); + return arguments; +} + +var obj = f(1); +assertEq(obj[0], undefined); +assertEq(Object.getOwnPropertyDescriptor(obj, 0).set, undefined); +assertThrowsInstanceOf(() => { "use strict"; obj[0] = 1; }, TypeError); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/object/bug-1206700.js b/js/src/tests/non262/object/bug-1206700.js new file mode 100644 index 0000000000..4918bcbec5 --- /dev/null +++ b/js/src/tests/non262/object/bug-1206700.js @@ -0,0 +1,10 @@ +var x = {}; +Reflect.set(x, "prop", 5, Object.prototype); +var y = {}; +Reflect.set(y, "prop", 6, Object.prototype); +assertEq(x.hasOwnProperty("prop"), false); +assertEq(y.hasOwnProperty("prop"), false); +assertEq(Object.prototype.hasOwnProperty("prop"), true); +assertEq(Object.prototype.prop, 6); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/non262/object/clear-dictionary-accessor-getset.js b/js/src/tests/non262/object/clear-dictionary-accessor-getset.js new file mode 100644 index 0000000000..f0d9e11ca6 --- /dev/null +++ b/js/src/tests/non262/object/clear-dictionary-accessor-getset.js @@ -0,0 +1,55 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = "clear-dictionary-accessor-getset.js"; +var BUGNUMBER = 1082662; +var summary = + "Properly handle GC of a dictionary accessor property whose [[Get]] or " + + "[[Set]] has been changed to |undefined|"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function test(field) +{ + var prop = "[[" + field[0].toUpperCase() + field.substring(1) + "]]"; + print("Testing for GC crashes after setting " + prop + " to undefined..."); + + function inner() + { + // Create an object with an accessor property. + var obj = { x: 42, get y() {}, set y(v) {} }; + + // 1) convert it to dictionary mode, in the process 2) creating a new + // version of that accessor property whose [[Get]] and [[Set]] are objects + // that trigger post barriers. + delete obj.x; + + var desc = {}; + desc[field] = undefined; + + // Overwrite [[field]] with undefined. Note #1 above is necessary so this + // is an actual *overwrite*, and not (possibly) a shape-tree fork that + // doesn't overwrite. + Object.defineProperty(obj, "y", desc); + + } + + inner(); + gc(); // In unfixed code, this crashes trying to mark a null [[field]]. +} + +test("get"); +test("set"); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/non262/object/defineGetter-defineSetter.js b/js/src/tests/non262/object/defineGetter-defineSetter.js new file mode 100644 index 0000000000..b2bb21f67c --- /dev/null +++ b/js/src/tests/non262/object/defineGetter-defineSetter.js @@ -0,0 +1,92 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +let count = 0; +let verifyProxy = new Proxy({}, { + defineProperty(target, property, descriptor) { + assertEq(property, "x"); + + assertEq(descriptor.enumerable, true); + assertEq(descriptor.configurable, true); + + if ("set" in descriptor) + assertEq(descriptor.set, Object.prototype.__defineSetter__); + else + assertEq(descriptor.get, Object.prototype.__defineGetter__); + + assertEq(Object.keys(descriptor).length, 3); + + count++; + return true; + } +}); + +for (let define of [Object.prototype.__defineGetter__, Object.prototype.__defineSetter__]) { + // null/undefined |this| value + for (let thisv of [undefined, null]) + assertThrowsInstanceOf(() => define.call(thisv, "x", define), TypeError); + + // non-callable getter/setter + let nonCallable = [{}, [], new Proxy({}, {})]; + for (let value of nonCallable) + assertThrowsInstanceOf(() => define.call(verifyProxy, "x", value), TypeError); + + // ToPropertyKey + let key = { + [Symbol.toPrimitive](hint) { + assertEq(hint, "string"); + // Throws, because non-primitive is returned + return {}; + }, + valueOf() { throw "wrongly invoked"; }, + toString() { throw "wrongly invoked"; } + }; + assertThrowsInstanceOf(() => define.call(verifyProxy, key, define), TypeError); + + key = { + [Symbol.toPrimitive](hint) { + assertEq(hint, "string"); + return "x"; + }, + valueOf() { throw "wrongly invoked"; }, + toString() { throw "wrongly invoked"; } + } + define.call(verifyProxy, key, define); + + key = { + [Symbol.toPrimitive]: undefined, + + valueOf() { throw "wrongly invoked"; }, + toString() { return "x"; } + } + define.call(verifyProxy, key, define); + + // Bog standard call + define.call(verifyProxy, "x", define); + + let obj = {}; + define.call(obj, "x", define); + let descriptor = Object.getOwnPropertyDescriptor(obj, "x"); + + assertEq(descriptor.enumerable, true); + assertEq(descriptor.configurable, true); + + if (define == Object.prototype.__defineSetter__) { + assertEq(descriptor.get, undefined); + assertEq(descriptor.set, define); + } else { + assertEq(descriptor.get, define); + assertEq(descriptor.set, undefined); + } + + assertEq(Object.keys(descriptor).length, 4); + + +} + +// Number of calls that should succeed +assertEq(count, 6); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/object/defineProperties-callable-accessor.js b/js/src/tests/non262/object/defineProperties-callable-accessor.js new file mode 100644 index 0000000000..1e92a2c92e --- /dev/null +++ b/js/src/tests/non262/object/defineProperties-callable-accessor.js @@ -0,0 +1,19 @@ +// ObjectDefineProperties with non callable accessor throws. +const descriptors = [ + {get: 1}, {set: 1}, + {get: []}, {set: []}, + {get: {}}, {set: {}}, + {get: new Number}, {set: new Number}, + + {get: 1, set: 1}, + {get: [], set: []}, + {get: {}, set: {}}, + {get: new Number, set: new Number}, +]; + +for (const descriptor of descriptors) { + assertThrowsInstanceOf(() => Object.create(null, {x: descriptor}), TypeError); + assertThrowsInstanceOf(() => Object.defineProperties({}, {x: descriptor}), TypeError); +} + +reportCompare(true, true); diff --git a/js/src/tests/non262/object/defineProperties-order.js b/js/src/tests/non262/object/defineProperties-order.js new file mode 100644 index 0000000000..417d101833 --- /dev/null +++ b/js/src/tests/non262/object/defineProperties-order.js @@ -0,0 +1,17 @@ +// Based on testcases provided by André Bargull + +let log = []; +let logger = new Proxy({}, { + get(target, key) { + log.push(key); + } +}); + +Object.create(null, new Proxy({a: {value: 0}, b: {value: 1}}, logger)); +assertEq(log.join(), "ownKeys,getOwnPropertyDescriptor,get,getOwnPropertyDescriptor,get"); + +log = []; +Object.defineProperties({}, new Proxy({a: {value: 0}, b: {value: 1}}, logger)); +assertEq(log.join(), "ownKeys,getOwnPropertyDescriptor,get,getOwnPropertyDescriptor,get"); + +reportCompare(true, true); diff --git a/js/src/tests/non262/object/defineProperty-proxy.js b/js/src/tests/non262/object/defineProperty-proxy.js new file mode 100644 index 0000000000..b5ece940bc --- /dev/null +++ b/js/src/tests/non262/object/defineProperty-proxy.js @@ -0,0 +1,54 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ */ + +// Test details of the implementation of ToPropertyDescriptor exposed to scripts +// thanks to scriptable proxies. + +// A LoggingProxy object logs certain operations performed on it. +var log = []; +function LoggingProxy(target) { + return new Proxy(target, { + has: function (t, id) { + log.push("has " + id); + return id in t; + }, + get: function (t, id) { + log.push("get " + id); + return t[id]; + } + }); +} + +// Tragically, we use separate code to implement Object.defineProperty on +// arrays and on proxies. So run the test three times. +var testSubjects = [ + {}, + [], + new Proxy({}, {}) +]; + +for (var obj of testSubjects) { + log = []; + + // Object.defineProperty is one public method that performs a + // ToPropertyDescriptor call. + Object.defineProperty(obj, "x", new LoggingProxy({ + enumerable: true, + configurable: true, + value: 3, + writable: true + })); + + // It should have performed exactly these operations on the proxy, in this + // order. See ES6 rev 24 (2014 April 27) 6.2.4.5 ToPropertyDescriptor. + assertDeepEq(log, [ + "has enumerable", "get enumerable", + "has configurable", "get configurable", + "has value", "get value", + "has writable", "get writable", + "has get", + "has set" + ]); +} + +reportCompare(0, 0); diff --git a/js/src/tests/non262/object/defineProperty-setup.js b/js/src/tests/non262/object/defineProperty-setup.js new file mode 100644 index 0000000000..da6fe8f496 --- /dev/null +++ b/js/src/tests/non262/object/defineProperty-setup.js @@ -0,0 +1,1071 @@ +// |reftest| skip -- not a test. +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +assertEq("defineProperty" in Object, true); +assertEq(Object.defineProperty.length, 3); + +/* + * Disable an assertion that is pathologically slow given the exhaustiveness of + * these tests. + */ +if (typeof enableStackWalkingAssertion === "function") + enableStackWalkingAssertion(false); + +if (!Object.prototype.toSource) +{ + Object.defineProperty(Object.prototype, "toSource", + { + value: function toSource() + { + if (this instanceof RegExp) + { + var v = "new RegExp(" + uneval(this.source); + var f = (this.multiline ? "m" : "") + + (this.global ? "g" : "") + + (this.ignoreCase ? "i" : ""); + return v + (f ? ", '" + f + "'" : "") + ")"; + } + return JSON.stringify(this); + }, + enumerable: false, + configurable: true, + writable: true + }); +} +if (!("uneval" in this)) +{ + Object.defineProperty(this, "uneval", + { + value: function uneval(v) + { + if (v === null) + return "null"; + if (typeof v === "object") + return v.toSource(); + if (typeof v === "string") + { + v = JSON.stringify({v:v}); + return v.substring(5, v.length - 1); + } + return "" + v; + }, + enumerable: false, + configurable: true, + writable: true + }); +} + +// reimplemented for the benefit of engines which don't have this helper +function assertEq(v1, v2, m) +{ + if (!SameValue(v1, v2)) + { + throw "assertion failed: " + + "got " + uneval(v1) + ", expected " + uneval(v2) + + (m ? ": " + m : ""); + } +} + +function SameValue(v1, v2) +{ + if (v1 === 0 && v2 === 0) + return 1 / v1 === 1 / v2; + if (v1 !== v1 && v2 !== v2) + return true; + return v1 === v2; +} + +function PropertyDescriptor(pd) +{ + if (pd) + this.update(pd); +} +PropertyDescriptor.prototype.update = function update(pd) +{ + if ("get" in pd) + this.get = pd.get; + if ("set" in pd) + this.set = pd.set; + if ("configurable" in pd) + this.configurable = pd.configurable; + if ("writable" in pd) + this.writable = pd.writable; + if ("enumerable" in pd) + this.enumerable = pd.enumerable; + if ("value" in pd) + this.value = pd.value; +}; +PropertyDescriptor.prototype.convertToDataDescriptor = function convertToDataDescriptor() +{ + delete this.get; + delete this.set; + this.writable = false; + this.value = undefined; +}; +PropertyDescriptor.prototype.convertToAccessorDescriptor = function convertToAccessorDescriptor() +{ + delete this.writable; + delete this.value; + this.get = undefined; + this.set = undefined; +}; + +function compareDescriptors(d1, d2) +{ + if (d1 === undefined) + { + assertEq(d2, undefined, "non-descriptors"); + return; + } + if (d2 === undefined) + { + assertEq(true, false, "descriptor-equality mismatch: " + uneval(d1) + ", " + uneval(d2)); + return; + } + + var props = ["value", "get", "set", "enumerable", "configurable", "writable"]; + for (var i = 0, sz = props.length; i < sz; i++) + { + var p = props[i]; + assertEq(p in d1, p in d2, p + " different in d1/d2"); + if (p in d1) + assertEq(d1[p], d2[p], p); + } +} + +function examine(desc, field, allowDefault) +{ + if (field in desc) + return desc[field]; + assertEq(allowDefault, true, "reimplementation error"); + switch (field) + { + case "value": + case "get": + case "set": + return undefined; + case "writable": + case "enumerable": + case "configurable": + return false; + default: + assertEq(true, false, "bad field name: " + field); + } +} + +function IsAccessorDescriptor(desc) +{ + if (!desc) + return false; + if (!("get" in desc) && !("set" in desc)) + return false; + return true; +} + +function IsDataDescriptor(desc) +{ + if (!desc) + return false; + if (!("value" in desc) && !("writable" in desc)) + return false; + return true; +} + +function IsGenericDescriptor(desc) +{ + if (!desc) + return false; + if (!IsAccessorDescriptor(desc) && !IsDataDescriptor(desc)) + return true; + return false; +} + + + +function CustomObject() +{ + this.properties = {}; + this.extensible = true; +} +CustomObject.prototype = +{ + _reject: function _reject(throwing, msg) + { + if (throwing) + throw new TypeError(msg + "; rejected!"); + return false; + }, + defineOwnProperty: function defineOwnProperty(propname, desc, throwing) + { + assertEq(typeof propname, "string", "non-string propname"); + + // Step 1. + var current = this.properties[propname]; + + // Step 2. + var extensible = this.extensible; + + // Step 3. + if (current === undefined && !extensible) + return this._reject(throwing, "object not extensible"); + + // Step 4. + if (current === undefined && extensible) + { + var p; + // Step 4(a). + if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) + { + p = new PropertyDescriptor(); + p.value = examine(desc, "value", true); + p.writable = examine(desc, "writable", true); + p.enumerable = examine(desc, "enumerable", true); + p.configurable = examine(desc, "configurable", true); + } + // Step 4(b). + else + { + p = new PropertyDescriptor(); + p.get = examine(desc, "get", true); + p.set = examine(desc, "set", true); + p.enumerable = examine(desc, "enumerable", true); + p.configurable = examine(desc, "configurable", true); + } + + this.properties[propname] = p; + + // Step 4(c). + return true; + } + + // Step 5. + if (!("value" in desc) && !("get" in desc) && !("set" in desc) && + !("writable" in desc) && !("enumerable" in desc) && + !("configurable" in desc)) + { + return; + } + + // Step 6. + do + { + if ("value" in desc) + { + if (!("value" in current) || !SameValue(desc.value, current.value)) + break; + } + if ("get" in desc) + { + if (!("get" in current) || !SameValue(desc.get, current.get)) + break; + } + if ("set" in desc) + { + if (!("set" in current) || !SameValue(desc.set, current.set)) + break; + } + if ("writable" in desc) + { + if (!("writable" in current) || + !SameValue(desc.writable, current.writable)) + { + break; + } + } + if ("enumerable" in desc) + { + if (!("enumerable" in current) || + !SameValue(desc.enumerable, current.enumerable)) + { + break; + } + } + if ("configurable" in desc) + { + if (!("configurable" in current) || + !SameValue(desc.configurable, current.configurable)) + { + break; + } + } + + // all fields in desc also in current, with the same values + return true; + } + while (false); + + // Step 7. + if (!examine(current, "configurable")) + { + if ("configurable" in desc && examine(desc, "configurable")) + return this._reject(throwing, "can't make configurable again"); + if ("enumerable" in desc && + examine(current, "enumerable") !== examine(desc, "enumerable")) + { + return this._reject(throwing, "can't change enumerability"); + } + } + + // Step 8. + if (IsGenericDescriptor(desc)) + { + // do nothing + } + // Step 9. + else if (IsDataDescriptor(current) !== IsDataDescriptor(desc)) + { + // Step 9(a). + if (!examine(current, "configurable")) + return this._reject(throwing, "can't change unconfigurable descriptor's type"); + // Step 9(b). + if (IsDataDescriptor(current)) + current.convertToAccessorDescriptor(); + // Step 9(c). + else + current.convertToDataDescriptor(); + } + // Step 10. + else if (IsDataDescriptor(current) && IsDataDescriptor(desc)) + { + // Step 10(a) + if (!examine(current, "configurable")) + { + // Step 10(a).i. + if (!examine(current, "writable") && + "writable" in desc && examine(desc, "writable")) + { + return this._reject(throwing, "can't make data property writable again"); + } + // Step 10(a).ii. + if (!examine(current, "writable")) + { + if ("value" in desc && + !SameValue(examine(desc, "value"), examine(current, "value"))) + { + return this._reject(throwing, "can't change value if not writable"); + } + } + } + // Step 10(b). + else + { + assertEq(examine(current, "configurable"), true, + "spec bug step 10(b)"); + } + } + // Step 11. + else + { + assertEq(IsAccessorDescriptor(current) && IsAccessorDescriptor(desc), + true, + "spec bug"); + + // Step 11(a). + if (!examine(current, "configurable")) + { + // Step 11(a).i. + if ("set" in desc && + !SameValue(examine(desc, "set"), examine(current, "set"))) + { + return this._reject(throwing, "can't change setter if not configurable"); + } + // Step 11(a).ii. + if ("get" in desc && + !SameValue(examine(desc, "get"), examine(current, "get"))) + { + return this._reject(throwing, "can't change getter if not configurable"); + } + } + } + + // Step 12. + current.update(desc); + + // Step 13. + return true; + } +}; + +function IsCallable(v) +{ + return typeof v === "undefined" || typeof v === "function"; +} + +var NativeTest = + { + newObject: function newObject() + { + return {}; + }, + defineProperty: function defineProperty(obj, propname, propdesc) + { + Object.defineProperty(obj, propname, propdesc); + }, + getDescriptor: function getDescriptor(obj, propname) + { + return Object.getOwnPropertyDescriptor(obj, propname); + } + }; + +var ReimplTest = + { + newObject: function newObject() + { + return new CustomObject(); + }, + defineProperty: function defineProperty(obj, propname, propdesc) + { + assertEq(obj instanceof CustomObject, true, "obj not instanceof CustomObject"); + if ("get" in propdesc || "set" in propdesc) + { + if ("value" in propdesc || "writable" in propdesc) + throw new TypeError("get/set and value/writable"); + if (!IsCallable(propdesc.get)) + throw new TypeError("get defined, uncallable"); + if (!IsCallable(propdesc.set)) + throw new TypeError("set defined, uncallable"); + } + return obj.defineOwnProperty(propname, propdesc, true); + }, + getDescriptor: function getDescriptor(obj, propname) + { + if (!(propname in obj.properties)) + return undefined; + + return new PropertyDescriptor(obj.properties[propname]); + } + }; + +var JSVAL_INT_MAX = Math.pow(2, 30) - 1; +var JSVAL_INT_MIN = -Math.pow(2, 30); + + +function isValidDescriptor(propdesc) +{ + if ("get" in propdesc || "set" in propdesc) + { + if ("value" in propdesc || "writable" in propdesc) + return false; + + // We permit null here simply because this test's author believes the + // implementation may sometime be susceptible to making mistakes in this + // regard and would prefer to be cautious. + if (propdesc.get !== null && propdesc.get !== undefined && !IsCallable(propdesc.get)) + return false; + if (propdesc.set !== null && propdesc.set !== undefined && !IsCallable(propdesc.set)) + return false; + } + + return true; +} + + +var OMIT = {}; +var VALUES = + [-Infinity, JSVAL_INT_MIN, -0, +0, 1.5, JSVAL_INT_MAX, Infinity, + NaN, "foo", "bar", null, undefined, true, false, {}, /a/, OMIT]; +var GETS = + [undefined, function get1() { return 1; }, function get2() { return 2; }, + null, 5, OMIT]; +var SETS = + [undefined, function set1() { return 1; }, function set2() { return 2; }, + null, 5, OMIT]; +var ENUMERABLES = [true, false, OMIT]; +var CONFIGURABLES = [true, false, OMIT]; +var WRITABLES = [true, false, OMIT]; + +function mapTestDescriptors(filter) +{ + var descs = []; + var desc = {}; + + function put(field, value) + { + if (value !== OMIT) + desc[field] = value; + } + + VALUES.forEach(function(value) + { + GETS.forEach(function(get) + { + SETS.forEach(function(set) + { + ENUMERABLES.forEach(function(enumerable) + { + CONFIGURABLES.forEach(function(configurable) + { + WRITABLES.forEach(function(writable) + { + desc = {}; + put("value", value); + put("get", get); + put("set", set); + put("enumerable", enumerable); + put("configurable", configurable); + put("writable", writable); + if (filter(desc)) + descs.push(desc); + }); + }); + }); + }); + }); + }); + + return descs; +} + +var ALL_DESCRIPTORS = mapTestDescriptors(function(d) { return true; }); +var VALID_DESCRIPTORS = mapTestDescriptors(isValidDescriptor); + +function TestRunner() +{ + this._logLines = []; +} +TestRunner.prototype = + { + // MAIN METHODS + + runFunctionLengthTests: function runFunctionLengthTests() + { + var self = this; + function functionLengthTests() + { + self._fullFunctionLengthTests(() => Function("one", "/* body */"), 1); + self._fullFunctionLengthTests(() => function(one, two, three=null) { }, 2); + self._fullFunctionLengthTests(() => (one, two, ...etc) => 0, 2); + self._fullFunctionLengthTests(() => ({method(){}}.method), 0); + self._fullFunctionLengthTests(() => Object.getOwnPropertyDescriptor({set x(v){}}, "x").set, 1); + } + + this._runTestSet(functionLengthTests, "Function length tests completed!"); + }, + + runNotPresentTests: function runNotPresentTests() + { + var self = this; + function notPresentTests() + { + print("Running not-present tests now..."); + + for (var i = 0, sz = ALL_DESCRIPTORS.length; i < sz; i++) + self._runSingleNotPresentTest(ALL_DESCRIPTORS[i]); + }; + + this._runTestSet(notPresentTests, "Not-present length tests completed!"); + }, + + runPropertyPresentTestsFraction: + function runPropertyPresentTestsFraction(part, parts) + { + var self = this; + function propertyPresentTests() + { + print("Running already-present tests now..."); + + var total = VALID_DESCRIPTORS.length; + var start = Math.floor((part - 1) / parts * total); + var end = Math.floor(part / parts * total); + + for (var i = start; i < end; i++) + { + var old = VALID_DESCRIPTORS[i]; + print("Starting test with old descriptor " + old.toSource() + "..."); + + for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++) + self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], []); + } + } + + this._runTestSet(propertyPresentTests, + "Property-present fraction " + part + " of " + parts + + " completed!"); + }, + + runNonTerminalPropertyPresentTestsFraction: + function runNonTerminalPropertyPresentTestsFraction(part, parts) + { + var self = this; + + /* + * A plain old property to define on the object before redefining the + * originally-added property, to test redefinition of a property that's + * not also lastProperty. NB: we could loop over every possible + * descriptor here if we wanted, even try adding more than one, but we'd + * hit cubic complexity and worse, and SpiderMonkey only distinguishes by + * the mere presence of the middle property, not its precise details. + */ + var middleDefines = + [{ + property: "middle", + descriptor: + { value: 17, writable: true, configurable: true, enumerable: true } + }]; + + function nonTerminalPropertyPresentTests() + { + print("Running non-terminal already-present tests now..."); + + var total = VALID_DESCRIPTORS.length; + var start = Math.floor((part - 1) / parts * total); + var end = Math.floor(part / parts * total); + + for (var i = start; i < end; i++) + { + var old = VALID_DESCRIPTORS[i]; + print("Starting test with old descriptor " + old.toSource() + "..."); + + for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++) + { + self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], + middleDefines); + } + } + } + + this._runTestSet(nonTerminalPropertyPresentTests, + "Non-terminal property-present fraction " + + part + " of " + parts + " completed!"); + }, + + runDictionaryPropertyPresentTestsFraction: + function runDictionaryPropertyPresentTestsFraction(part, parts) + { + var self = this; + + /* + * Add and readd properties such that the scope for the object is in + * dictionary mode. + */ + var middleDefines = + [ + { + property: "mid1", + descriptor: + { value: 17, writable: true, configurable: true, enumerable: true } + }, + { + property: "mid2", + descriptor: + { value: 17, writable: true, configurable: true, enumerable: true } + }, + { + property: "mid1", + descriptor: + { get: function g() { }, set: function s(v){}, configurable: false, + enumerable: true } + }, + ]; + + function dictionaryPropertyPresentTests() + { + print("Running dictionary already-present tests now..."); + + var total = VALID_DESCRIPTORS.length; + var start = Math.floor((part - 1) / parts * total); + var end = Math.floor(part / parts * total); + + for (var i = start; i < end; i++) + { + var old = VALID_DESCRIPTORS[i]; + print("Starting test with old descriptor " + old.toSource() + "..."); + + for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++) + { + self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], + middleDefines); + } + } + } + + this._runTestSet(dictionaryPropertyPresentTests, + "Dictionary property-present fraction " + + part + " of " + parts + " completed!"); + }, + + + // HELPERS + + runPropertyPresentTests: function runPropertyPresentTests() + { + print("Running already-present tests now..."); + + for (var i = 0, sz = VALID_DESCRIPTORS.length; i < sz; i++) + { + var old = VALID_DESCRIPTORS[i]; + print("Starting test with old descriptor " + old.toSource() + "..."); + + for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++) + this._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], []); + } + }, + _runTestSet: function _runTestSet(fun, completeMessage) + { + try + { + fun(); + + print(completeMessage); + } + catch (e) + { + print("ERROR, EXITING (line " + (e.lineNumber || -1) + "): " + e); + throw e; + } + finally + { + this._reportAllErrors(); + } + }, + _reportAllErrors: function _reportAllErrors() + { + var errorCount = this._logLines.length; + print("Full accumulated number of errors: " + errorCount); + if (errorCount > 0) + throw errorCount + " errors detected, FAIL"; + }, + _fullFunctionLengthTests: function _fullFunctionLengthTests(funFactory, len) + { + print("Running Function.length (" + funFactory + ") tests now..."); + + for (var i = 0, sz = VALID_DESCRIPTORS.length; i < sz; i++) + { + var desc = VALID_DESCRIPTORS[i]; + this._runSingleFunctionLengthTest(funFactory(), len, desc); + } + }, + _log: function _log(v) + { + var m = "" + v; + print(m); + this._logLines.push(m); + }, + _runSingleNotPresentTest: function _runSingleNotPresentTest(desc) + { + var nativeObj = NativeTest.newObject(); + var reimplObj = ReimplTest.newObject(); + + try + { + NativeTest.defineProperty(nativeObj, "foo", desc); + } + catch (e) + { + try + { + ReimplTest.defineProperty(reimplObj, "foo", desc); + } + catch (e2) + { + if (e.constructor !== e2.constructor) + { + this._log("Difference when comparing native/reimplementation " + + "behavior for new descriptor " + desc.toSource() + + ", native threw " + e + ", reimpl threw " + e2); + } + return; + } + this._log("Difference when comparing native/reimplementation " + + "behavior for new descriptor " + desc.toSource() + + ", error " + e); + return; + } + + try + { + ReimplTest.defineProperty(reimplObj, "foo", desc); + } + catch (e) + { + this._log("Reimpl threw defining new descriptor " + desc.toSource() + + ", error: " + e); + return; + } + + var nativeDesc = NativeTest.getDescriptor(nativeObj, "foo"); + var reimplDesc = ReimplTest.getDescriptor(reimplObj, "foo"); + try + { + compareDescriptors(nativeDesc, reimplDesc); + } + catch (e) + { + this._log("Difference comparing returned descriptors for new " + + "property defined with descriptor " + desc.toSource() + + "; error: " + e); + return; + } + }, + _runSinglePropertyPresentTest: + function _runSinglePropertyPresentTest(old, add, middleDefines) + { + var nativeObj = NativeTest.newObject(); + var reimplObj = ReimplTest.newObject(); + + try + { + NativeTest.defineProperty(nativeObj, "foo", old); + } + catch (e) + { + if (!SameValue(NativeTest.getDescriptor(nativeObj, "foo"), undefined)) + { + this._log("defining bad property descriptor: " + old.toSource()); + return; + } + + try + { + ReimplTest.defineProperty(reimplObj, "foo", old); + } + catch (e2) + { + if (!SameValue(ReimplTest.getDescriptor(reimplObj, "foo"), + undefined)) + { + this._log("defining bad property descriptor: " + old.toSource() + + "; reimplObj: " + uneval(reimplObj)); + } + + if (e.constructor !== e2.constructor) + { + this._log("Different errors defining bad property descriptor: " + + old.toSource() + "; native threw " + e + ", reimpl " + + "threw " + e2); + } + + return; + } + + this._log("Difference defining a property with descriptor " + + old.toSource() + ", error " + e); + return; + } + + try + { + ReimplTest.defineProperty(reimplObj, "foo", old); + } + catch (e) + { + this._log("Difference when comparing native/reimplementation " + + "behavior when adding descriptor " + add.toSource() + + ", error: " + e); + return; + } + + // Now add (or even readd) however many properties were specified between + // the original property to add and the new one, to test redefining + // non-last-properties and properties in scopes in dictionary mode. + for (var i = 0, sz = middleDefines.length; i < sz; i++) + { + var middle = middleDefines[i]; + var prop = middle.property; + var desc = middle.descriptor; + + try + { + NativeTest.defineProperty(nativeObj, prop, desc); + ReimplTest.defineProperty(reimplObj, prop, desc); + } + catch (e) + { + this._log("failure defining middle descriptor: " + desc.toSource() + + ", error " + e); + return; + } + + // Sanity check + var nativeDesc = NativeTest.getDescriptor(nativeObj, prop); + var reimplDesc = ReimplTest.getDescriptor(reimplObj, prop); + + compareDescriptors(nativeDesc, reimplDesc); + compareDescriptors(nativeDesc, desc); + } + + try + { + NativeTest.defineProperty(nativeObj, "foo", add); + } + catch (e) + { + try + { + ReimplTest.defineProperty(reimplObj, "foo", add); + } + catch (e2) + { + if (e.constructor !== e2.constructor) + { + this._log("Difference when comparing native/reimplementation " + + "behavior for descriptor " + add.toSource() + + " overwriting descriptor " + old.toSource() + "; " + + "native threw " + e + ", reimpl threw " + e2); + } + return; + } + this._log("Difference when comparing native/reimplementation " + + "behavior for added descriptor " + add.toSource() + ", " + + "initial was " + old.toSource() + "; error: " + e); + return; + } + + try + { + ReimplTest.defineProperty(reimplObj, "foo", add); + } + catch (e) + { + this._log("Difference when comparing native/reimplementation " + + "behavior for readded descriptor " + add.toSource() + ", " + + "initial was " + old.toSource() + "; native readd didn't " + + "throw, reimpl add did, error: " + e); + return; + } + + var nativeDesc = NativeTest.getDescriptor(nativeObj, "foo"); + var reimplDesc = ReimplTest.getDescriptor(reimplObj, "foo"); + try + { + compareDescriptors(nativeDesc, reimplDesc); + } + catch (e) + { + this._log("Difference comparing returned descriptors for readded " + + "property defined with descriptor " + add.toSource() + "; " + + "initial was " + old.toSource() + "; error: " + e); + return; + } + }, + _runSingleFunctionLengthTest: function _runSingleFunctionLengthTest(fun, len, desc) + { + var nativeObj = fun; + var reimplObj = ReimplTest.newObject(); + ReimplTest.defineProperty(reimplObj, "length", + { + value: len, + enumerable: false, + configurable: true, + writable: false + }); + + try + { + NativeTest.defineProperty(nativeObj, "length", desc); + } + catch (e) + { + try + { + ReimplTest.defineProperty(reimplObj, "length", desc); + } + catch (e2) + { + if (e.constructor !== e2.constructor) + { + this._log("Difference when comparing native/reimplementation " + + "behavior defining fun.length with " + desc.toSource() + + "; native threw " + e + ", reimpl threw " + e2); + } + return; + } + this._log("Difference when comparing Function.length native/reimpl " + + "behavior for descriptor " + desc.toSource() + + ", native impl threw error " + e); + return; + } + + try + { + ReimplTest.defineProperty(reimplObj, "length", desc); + } + catch (e) + { + this._log("Difference defining new Function.length descriptor: impl " + + "succeeded, reimpl threw for descriptor " + + desc.toSource() + ", error: " + e); + return; + } + + var nativeDesc = NativeTest.getDescriptor(nativeObj, "length"); + var reimplDesc = ReimplTest.getDescriptor(reimplObj, "length"); + try + { + compareDescriptors(nativeDesc, reimplDesc); + } + catch (e) + { + this._log("Difference comparing returned descriptors for " + + "Function.length with descriptor " + desc.toSource() + + "; error: " + e); + return; + } + } + }; + +function runDictionaryPropertyPresentTestsFraction(PART, PARTS) +{ + var testfile = + '15.2.3.6-dictionary-redefinition-' + PART + '-of-' + PARTS + '.js'; + var BUGNUMBER = 560566; + var summary = + 'ES5 Object.defineProperty(O, P, Attributes): dictionary redefinition ' + + PART + ' of ' + PARTS; + + print(BUGNUMBER + ": " + summary); + + try + { + new TestRunner().runDictionaryPropertyPresentTestsFraction(PART, PARTS); + } + catch (e) + { + throw "Error thrown during testing: " + e + + " at line " + e.lineNumber + "\n" + + (e.stack + ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n" + : ""); + } + + if (typeof reportCompare === "function") + reportCompare(true, true); + + print("Tests complete!"); +} + +function runNonTerminalPropertyPresentTestsFraction(PART, PARTS) +{ + var BUGNUMBER = 560566; + var summary = + 'ES5 Object.defineProperty(O, P, Attributes): middle redefinition ' + + PART + ' of ' + PARTS; + + print(BUGNUMBER + ": " + summary); + + + /************** + * BEGIN TEST * + **************/ + + try + { + new TestRunner().runNonTerminalPropertyPresentTestsFraction(PART, PARTS); + } + catch (e) + { + throw "Error thrown during testing: " + e + + " at line " + e.lineNumber + "\n" + + (e.stack + ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n" + : ""); + } + + /******************************************************************************/ + + if (typeof reportCompare === "function") + reportCompare(true, true); + + print("Tests complete!"); +} diff --git a/js/src/tests/non262/object/destructuring-shorthand-defaults.js b/js/src/tests/non262/object/destructuring-shorthand-defaults.js new file mode 100644 index 0000000000..3ca240e0b7 --- /dev/null +++ b/js/src/tests/non262/object/destructuring-shorthand-defaults.js @@ -0,0 +1,127 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Ensure that the syntax used in shorthand destructuring with defaults +// e.g. |{x=1, y=2} = {}| properly raises a syntax error within an object +// literal. As per ES6 12.2.6 Object Initializer, "NOTE 3." + +const SYNTAX_ERROR_STMTS = [ + // expressions + "({x={}={}}),", + "({y={x={}={}={}={}={}={}={}={}}={}}),", + "({a=1, b=2, c=3, x=({}={})}),", + "({x=1, y={z={1}}})", + "({x=1} = {y=1});", + "({x: y={z=1}}={})", + "({x=1}),", + "({z={x=1}})=>{};", + "({x = ({y=1}) => y})", + "(({x=1})) => x", + "({e=[]}==(;", + "({x=1}[-1]);", + "({x=y}[-9])", + "({x=y}.x.z[-9])", + "({x=y}`${-9}`)", + "(new {x=y}(-9))", + "new {x=1}", + "new {x=1}={}", + "typeof {x=1}", + "typeof ({x=1})", + "({x=y, [-9]:0})", + "((({w = x} >(-9)", + "++({x=1})", + "--{x=1}", + "!{x=1}={}", + "delete {x=1}", + "delete ({x=1})", + "delete {x=1} = {}", + "({x=1}.abc)", + "x > (0, {a = b} );", + // declarations + "var x = 0 + {a=1} = {}", + "let o = {x=1};", + "var j = {x=1};", + "var j = {x={y=1}}={};", + "const z = {x=1};", + "const z = {x={y=1}}={};", + "const {x=1};", + "const {x={y=33}}={};", + "var {x=1};", + "let {x=1};", + "let x, y, {z=1}={}, {w=2}, {e=3};", + // array initialization + "[{x=1, y = ({z=2} = {})}];", + // try/catch + "try {throw 'a';} catch ({x={y=1}}) {}", + // if/else + "if ({k: 1, x={y=2}={}}) {}", + "if (false) {} else if (true) { ({x=1}) }", + // switch + "switch ('c') { case 'c': ({x=1}); }", + // for + "for ({x=1}; 1;) {1}", + "for ({x={y=2}}; 1;) {1}", + "for (var x = 0; x < 2; x++) { ({x=1, y=2}) }", + "for (let x=1;{x=1};){}", + "for (let x=1;{x={y=2}};){}", + "for (let x=1;1;{x=1}){}", + "for (let x=1;1;{x={y=2}}){}", + // while + "while ({x=1}) {1};", + "while ({x={y=2}}={}) {1};", + // with + "with ({x=1}) {};", + "with ({x={y=3}={}}) {};", + "with (Math) { ({x=1}) };", + // ternary + "true ? {x=1} : 1;", + "false ? 1 : {x=1};", + "{x=1} ? 2 : 3;", + // assignment + "({x} += {});", + "({x = 1}) = {x: 2};", +] + +for (var stmt of SYNTAX_ERROR_STMTS) { + assertThrowsInstanceOf(() => { + Function(stmt); + }, SyntaxError); +} + +// A few tricky but acceptable cases: +// see https://bugzilla.mozilla.org/show_bug.cgi?id=932080#c2 + +assertEq((({a = 0}) => a)({}), 0); +assertEq((({a = 0} = {}) => a)({}), 0); +assertEq((({a = 0} = {}) => a)({a: 1}), 1); + +{ + let x, y; + ({x=1} = {}); + assertEq(x, 1); + ({x=1} = {x: 4}); + assertEq(x, 4); + ({x=1, y=2} = {}) + assertEq(x, 1); + assertEq(y, 2); +} + +{ + let {x={i=1, j=2}={}}={}; + assertDeepEq(x, ({})); + assertEq(i, 1); + assertEq(j, 2); +} + +// Default destructuring values, which are variables, should be defined +// within closures (Bug 1255167). +{ + let f = function(a){ + return (function({aa = a}){ return aa; })({}); + }; + assertEq(f(9999), 9999); +} + +if (typeof reportCompare == "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/duplProps.js b/js/src/tests/non262/object/duplProps.js new file mode 100644 index 0000000000..41b8d67fb0 --- /dev/null +++ b/js/src/tests/non262/object/duplProps.js @@ -0,0 +1,116 @@ +/* + * ES6 allows duplicate property names in object literals, even in strict mode. + * These tests modify the tests in test262 to reflect this change. + */ + +// test262/ch11/11.1/11.1.5/11.1.5-4-4-a-1-s.js +a = function() { "use strict"; return { foo: 0, foo : 1 }}; +assertEq(a().foo, 1); +a = function() { return { foo: 0, foo : 1 }}; +assertEq(a().foo, 1); + +// test262/ch11/11.1/11.1.5/11.1.5_4-4-b-1.js +a = function() { "use strict"; return { foo : 1, get foo() { return 2; }}}; +assertEq(a().foo, 2); +a = function() { return { foo : 1, get foo() { return 2;} }}; +assertEq(a().foo, 2); + +// test262/ch11/11.1/11.1.5/11.1.5_4-4-c-1.js +a = function() { "use strict"; return { get foo() { return 2; }, foo : 1 }}; +assertEq(a().foo, 1); +a = function() { return { get foo() { return 2; }, foo : 1 }}; +assertEq(a().foo, 1); + +// test262/ch11/11.1/11.1.5/11.1.5_4-4-b-2.js +a = function() { "use strict"; return { foo : 1, set foo(a) { throw 2; }}}; +try { + a().foo = 5; + throw new Error("2 should be thrown here"); +} catch (e) { + if (e !== 2) + throw new Error("2 should be thrown here"); +} +a = function() { return { foo : 1, set foo(a) { throw 2;} }}; +try { + a().foo = 5; + throw new Error("2 should be thrown here"); +} catch (e) { + if (e !== 2) + throw new Error("2 should be thrown here"); +} + +// test262/ch11/11.1/11.1.5/11.1.5_4-4-d-1.js +a = function() { "use strict"; return { get foo() { return 2; }, get foo() { return 3; } }}; +assertEq(a().foo, 3); +a = function() { return { get foo() { return 2; }, get foo() { return 3; } }}; +assertEq(a().foo, 3); + +// test262/ch11/11.1/11.1.5/11.1.5_4-4-c-2.js +a = function() { "use strict"; return { set foo(a) { throw 2; }, foo : 1 }}; +assertEq(a().foo, 1); +a = function() { return { set foo(a) { throw 2; }, foo : 1 }}; +assertEq(a().foo, 1); + +// test262/ch11/11.1/11.1.5/11.1.5_4-4-d-2.js +a = function() { "use strict"; return { set foo(a) { throw 2; }, set foo(a) { throw 3; }}}; +try { + a().foo = 5; + throw new Error("3 should be thrown here"); +} catch (e) { + if (e !== 3) + throw new Error("3 should be thrown here"); +} +a = function() { return { set foo(a) { throw 2; }, set foo(a) { throw 3; }}}; +try { + a().foo = 5; + throw new Error("3 should be thrown here"); +} catch (e) { + if (e !== 3) + throw new Error("3 should be thrown here"); +} + +// test262/ch11/11.1/11.1.5/11.1.5_4-4-d-3.js +a = function() { "use strict"; return { get foo() { return 2; }, set foo(a) { throw 3; }, + get foo() { return 4; }}}; +try { + assertEq(a().foo, 4); + a().foo = 5; + throw new Error("3 should be thrown here"); +} catch (e) { + if (e !== 3) + throw new Error("3 should be thrown here"); +} +a = function() { return { get foo() { return 2; }, set foo(a) { throw 3; }, + get foo() { return 4; }}}; +try { + assertEq(a().foo, 4); + a().foo = 5; + throw new Error("3 should be thrown here"); +} catch (e) { + if (e !== 3) + throw new Error("3 should be thrown here"); +} + +// test262/ch11/11.1/11.1.5/11.1.5_4-4-d-4.js +a = function() { "use strict"; return { set foo(a) { throw 2; }, get foo() { return 4; }, + set foo(a) { throw 3; }}}; +try { + assertEq(a().foo, 4); + a().foo = 5; + throw new Error("3 should be thrown here"); +} catch (e) { + if (e !== 3) + throw new Error("3 should be thrown here"); +} +a = function() { return { set foo(a) { throw 2; }, get foo() { return 4; }, + set foo(a) { throw 3; }}}; +try { + assertEq(a().foo, 4); + a().foo = 5; + throw new Error("3 should be thrown here"); +} catch (e) { + if (e !== 3) + throw new Error("3 should be thrown here"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/non262/object/entries.js b/js/src/tests/non262/object/entries.js new file mode 100644 index 0000000000..1a03ceb421 --- /dev/null +++ b/js/src/tests/non262/object/entries.js @@ -0,0 +1,94 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +if ("entries" in Object) { + assertEq(Object.entries.length, 1); + + var o, entries; + + o = { a: 3, b: 2 }; + entries = Object.entries(o); + assertDeepEq(entries, [["a", 3], ["b", 2]]); + + o = { get a() { return 17; }, b: 2 }; + entries = Object.entries(o), + assertDeepEq(entries, [["a", 17], ["b", 2]]); + + o = { __iterator__: function() { throw new Error("non-standard __iterator__ called?"); } }; + entries = Object.entries(o); + assertDeepEq(entries, [["__iterator__", o.__iterator__]]); + + o = { a: 1, b: 2 }; + delete o.a; + o.a = 3; + entries = Object.entries(o); + assertDeepEq(entries, [["b", 2], ["a", 3]]); + + o = [0, 1, 2]; + entries = Object.entries(o); + assertDeepEq(entries, [["0", 0], ["1", 1], ["2", 2]]); + + o = /./.exec("abc"); + entries = Object.entries(o); + assertDeepEq(entries, [["0", "a"], ["index", 0], ["input", "abc"], ["groups", undefined]]); + + o = { a: 1, b: 2, c: 3 }; + delete o.b; + o.b = 5; + entries = Object.entries(o); + assertDeepEq(entries, [["a", 1], ["c", 3], ["b", 5]]); + + function f() { } + f.prototype.p = 1; + o = new f(); + o.g = 1; + entries = Object.entries(o); + assertDeepEq(entries, [["g", 1]]); + + var o = {get a() {delete this.b; return 1}, b: 2, c: 3}; + entries = Object.entries(o); + assertDeepEq(entries, [["a", 1], ["c", 3]]); + + assertThrowsInstanceOf(() => Object.entries(), TypeError); + assertThrowsInstanceOf(() => Object.entries(undefined), TypeError); + assertThrowsInstanceOf(() => Object.entries(null), TypeError); + + assertDeepEq(Object.entries(1), []); + assertDeepEq(Object.entries(true), []); + if (typeof Symbol === "function") + assertDeepEq(Object.entries(Symbol("foo")), []); + + assertDeepEq(Object.entries("foo"), [["0", "f"], ["1", "o"], ["2", "o"]]); + + entries = Object.entries({ + get a(){ + Object.defineProperty(this, "b", {enumerable: false}); + return "A"; + }, + b: "B" + }); + assertDeepEq(entries, [["a", "A"]]); + + let ownKeysCallCount = 0; + let getOwnPropertyDescriptorCalls = []; + let target = { a: 1, b: 2, c: 3 }; + o = new Proxy(target, { + ownKeys() { + ownKeysCallCount++; + return ["c", "a"]; + }, + getOwnPropertyDescriptor(target, key) { + getOwnPropertyDescriptorCalls.push(key); + return Object.getOwnPropertyDescriptor(target, key); + } + }); + entries = Object.entries(o); + assertEq(ownKeysCallCount, 1); + assertDeepEq(entries, [["c", 3], ["a", 1]]); + assertDeepEq(getOwnPropertyDescriptorCalls, ["c", "a"]); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/extensibility-01.js b/js/src/tests/non262/object/extensibility-01.js new file mode 100644 index 0000000000..c001f38254 --- /dev/null +++ b/js/src/tests/non262/object/extensibility-01.js @@ -0,0 +1,103 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +var gTestfile = '15.2.3.10-01.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 492849; +var summary = 'ES5: Implement Object.preventExtensions, Object.isExtensible'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function trySetProperty(o, p, v, strict) +{ + function strictSetProperty() + { + "use strict"; + o[p] = v; + } + + function setProperty() + { + o[p] = v; + } + + assertEq(Object.prototype.hasOwnProperty.call(o, p), false); + + try + { + if (strict) + strictSetProperty(); + else + setProperty(); + if (o[p] === v) + return "set"; + if (p in o) + return "set-converted"; + return "swallowed"; + } + catch (e) + { + return "throw"; + } +} + +function tryDefineProperty(o, p, v) +{ + assertEq(Object.prototype.hasOwnProperty.call(o, p), false); + + try + { + Object.defineProperty(o, p, { value: v }); + if (o[p] === v) + return "set"; + if (p in o) + return "set-converted"; + return "swallowed"; + } + catch (e) + { + return "throw"; + } +} + +assertEq(typeof Object.preventExtensions, "function"); +assertEq(Object.preventExtensions.length, 1); + +var slowArray = [1, 2, 3]; +slowArray.slow = 5; +var objs = + [{}, { 1: 2 }, { a: 3 }, [], [1], [, 1], slowArray, function a(){}, /a/]; + +for (var i = 0, sz = objs.length; i < sz; i++) +{ + var o = objs[i]; + assertEq(Object.isExtensible(o), true, "object " + i + " not extensible?"); + + var o2 = Object.preventExtensions(o); + assertEq(o, o2); + + assertEq(Object.isExtensible(o), false, "object " + i + " is extensible?"); + + assertEq(trySetProperty(o, "baz", 17, true), "throw", + "unexpected behavior for strict-mode property-addition to " + + "object " + i); + assertEq(trySetProperty(o, "baz", 17, false), "swallowed", + "unexpected behavior for property-addition to object " + i); + + assertEq(tryDefineProperty(o, "baz", 17), "throw", + "unexpected behavior for new property definition on object " + i); +} + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/extensibility-02.js b/js/src/tests/non262/object/extensibility-02.js new file mode 100644 index 0000000000..c61e367281 --- /dev/null +++ b/js/src/tests/non262/object/extensibility-02.js @@ -0,0 +1,42 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +var gTestfile = '15.2.3.4-01.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 492849; +var summary = 'ES5: Implement Object.preventExtensions, Object.isExtensible'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +assertEq(typeof Object.isExtensible, "function"); +assertEq(Object.isExtensible.length, 1); + +var slowArray = [1, 2, 3]; +slowArray.slow = 5; +var objs = + [{}, { 1: 2 }, { a: 3 }, [], [1], [, 1], slowArray, function a(){}, /a/]; + +for (var i = 0, sz = objs.length; i < sz; i++) +{ + var o = objs[i]; + assertEq(Object.isExtensible(o), true, "object " + i + " not extensible?"); + + var o2 = Object.preventExtensions(o); + assertEq(o, o2); + + assertEq(Object.isExtensible(o), false, "object " + i + " is extensible?"); +} + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/freeze-global-eval-const.js b/js/src/tests/non262/object/freeze-global-eval-const.js new file mode 100644 index 0000000000..a43f5c51c9 --- /dev/null +++ b/js/src/tests/non262/object/freeze-global-eval-const.js @@ -0,0 +1,13 @@ +// |reftest| skip-if(!xulRuntime.shell) -- uses evalcx +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +try { + evalcx("Object.freeze(this); eval('const q = undefined;')"); +} catch (e) { + assertEq(e.message, "({lazy:false}) is not extensible"); +} + +reportCompare(0, 0, "don't crash"); diff --git a/js/src/tests/non262/object/freeze-proxy.js b/js/src/tests/non262/object/freeze-proxy.js new file mode 100644 index 0000000000..3d95a28d4f --- /dev/null +++ b/js/src/tests/non262/object/freeze-proxy.js @@ -0,0 +1,27 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function logProxy(object = {}, handler = {}) { + var log = []; + var proxy = new Proxy(object, new Proxy(handler, { + get(target, propertyKey, receiver) { + log.push(propertyKey); + return target[propertyKey]; + } + })); + return {proxy, log}; +} + +// The order of operations is backwards when compared to ES6 draft rev 27 +// (2014 August 24), but see https://bugs.ecmascript.org/show_bug.cgi?id=3215 +// for an explanation on why the spec version is clearly wrong. + +var {proxy, log} = logProxy(); +Object.freeze(proxy); +assertDeepEq(log, ["preventExtensions", "ownKeys"]); + +var {proxy, log} = logProxy(); +Object.freeze(Object.freeze(proxy)); +assertDeepEq(log, ["preventExtensions", "ownKeys", "preventExtensions", "ownKeys"]); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/object/freeze.js b/js/src/tests/non262/object/freeze.js new file mode 100644 index 0000000000..18f71f76d6 --- /dev/null +++ b/js/src/tests/non262/object/freeze.js @@ -0,0 +1,21 @@ +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +var BUGNUMBER = 1076588; +var summary = "Object.freeze() should return its argument with no conversion when the argument is a primitive value"; + +print(BUGNUMBER + ": " + summary); +assertEq(Object.freeze(), undefined); +assertEq(Object.freeze(undefined), undefined); +assertEq(Object.freeze(null), null); +assertEq(Object.freeze(1), 1); +assertEq(Object.freeze("foo"), "foo"); +assertEq(Object.freeze(true), true); +if (typeof Symbol === "function") { + assertEq(Object.freeze(Symbol.for("foo")), Symbol.for("foo")); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/gOPD-vs-prototype-accessor.js b/js/src/tests/non262/object/gOPD-vs-prototype-accessor.js new file mode 100644 index 0000000000..472887f90b --- /dev/null +++ b/js/src/tests/non262/object/gOPD-vs-prototype-accessor.js @@ -0,0 +1,15 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +assertEq(function testcase() { + var proto = {}; + Object.defineProperty(proto, "prop", {get: function () {return {};}, enumerable: true}); + var ConstructFun = function () {}; + ConstructFun.prototype = proto; + var child = new ConstructFun; + return Object.getOwnPropertyNames(child).indexOf('prop'); +}(), -1); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/non262/object/getOwnPropertyDescriptor.js b/js/src/tests/non262/object/getOwnPropertyDescriptor.js new file mode 100644 index 0000000000..7aaba7b5ee --- /dev/null +++ b/js/src/tests/non262/object/getOwnPropertyDescriptor.js @@ -0,0 +1,35 @@ +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +var BUGNUMBER = 1079188; +var summary = "Coerce the argument passed to Object.getOwnPropertyDescriptor using ToObject"; +print(BUGNUMBER + ": " + summary); + +assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(), TypeError); +assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(undefined), TypeError); +assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(null), TypeError); + +Object.getOwnPropertyDescriptor(1); +Object.getOwnPropertyDescriptor(true); +if (typeof Symbol === "function") { + Object.getOwnPropertyDescriptor(Symbol("foo")); +} + +assertDeepEq(Object.getOwnPropertyDescriptor("foo", "length"), { + value: 3, + writable: false, + enumerable: false, + configurable: false +}); + +assertDeepEq(Object.getOwnPropertyDescriptor("foo", 0), { + value: "f", + writable: false, + enumerable: true, + configurable: false +}); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/getOwnPropertySymbols-proxy.js b/js/src/tests/non262/object/getOwnPropertySymbols-proxy.js new file mode 100644 index 0000000000..c538b3015c --- /dev/null +++ b/js/src/tests/non262/object/getOwnPropertySymbols-proxy.js @@ -0,0 +1,28 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ */ + +// getOwnPropertySymbols(proxy) calls the getOwnPropertyNames hook (only). + +var symbols = [Symbol(), Symbol("moon"), Symbol.for("sun"), Symbol.iterator]; +var hits = 0; + +function HandlerProxy() { + return new Proxy({}, { + get: function (t, key) { + if (key !== "ownKeys") + throw new Error("tried to access handler[" + String(key) + "]"); + hits++; + return t => symbols; + } + }); +} + +function OwnKeysProxy() { + return new Proxy({}, new HandlerProxy); +} + +assertDeepEq(Object.getOwnPropertySymbols(new OwnKeysProxy), symbols); +assertEq(hits, 1); + +if (typeof reportCompare === "function") + reportCompare(0, 0); diff --git a/js/src/tests/non262/object/getOwnPropertySymbols.js b/js/src/tests/non262/object/getOwnPropertySymbols.js new file mode 100644 index 0000000000..b92d14ef17 --- /dev/null +++ b/js/src/tests/non262/object/getOwnPropertySymbols.js @@ -0,0 +1,46 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ */ + +assertDeepEq(Object.getOwnPropertySymbols({}), []); + +// String keys are ignored. +assertEq(Object.getOwnPropertySymbols({a: 1, b: 2}).length, 0); +assertEq(Object.getOwnPropertySymbols([0, 1, 2, 3]).length, 0); + +// Symbol keys are observed. +var iterable = {}; +Object.defineProperty(iterable, Symbol.iterator, { + value: () => [][Symbol.iterator]() +}); +assertDeepEq(Object.getOwnPropertySymbols(iterable), [Symbol.iterator]); +assertDeepEq(Object.getOwnPropertySymbols(new Proxy(iterable, {})), [Symbol.iterator]); + +// Test on an object with a thousand own properties. +var obj = {}; +for (var i = 0; i < 1000; i++) { + obj[Symbol.for("x" + i)] = 1; +} +assertEq(Object.getOwnPropertyNames(obj).length, 0); +var symbols = Object.getOwnPropertySymbols(obj); +assertEq(symbols.length, 1000); +assertEq(symbols.indexOf(Symbol.for("x0")) !== -1, true); +assertEq(symbols.indexOf(Symbol.for("x241")) !== -1, true); +assertEq(symbols.indexOf(Symbol.for("x999")) !== -1, true); +assertEq(Object.getOwnPropertySymbols(new Proxy(obj, {})).length, 1000); + +// The prototype chain is not consulted. +assertEq(Object.getOwnPropertySymbols(Object.create(obj)).length, 0); +assertEq(Object.getOwnPropertySymbols(new Proxy(Object.create(obj), {})).length, 0); + +// Primitives are coerced to objects; but there are never any symbol-keyed +// properties on the resulting wrapper objects. +assertThrowsInstanceOf(() => Object.getOwnPropertySymbols(), TypeError); +assertThrowsInstanceOf(() => Object.getOwnPropertySymbols(undefined), TypeError); +assertThrowsInstanceOf(() => Object.getOwnPropertySymbols(null), TypeError); +for (var primitive of [true, 1, 3.14, "hello", Symbol()]) + assertEq(Object.getOwnPropertySymbols(primitive).length, 0); + +assertEq(Object.getOwnPropertySymbols.length, 1); + +if (typeof reportCompare === "function") + reportCompare(0, 0); diff --git a/js/src/tests/non262/object/getPrototypeOf-array.js b/js/src/tests/non262/object/getPrototypeOf-array.js new file mode 100644 index 0000000000..e482f89be7 --- /dev/null +++ b/js/src/tests/non262/object/getPrototypeOf-array.js @@ -0,0 +1,32 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = 'getPrototypeOf-array.js'; +var BUGNUMBER = 769041; +var summary = + "The [[Prototype]] of an object whose prototype chain contains an array " + + "isn't that array's [[Prototype]]"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var arr = []; +assertEq(Array.isArray(arr), true); +var objWithArrPrototype = Object.create(arr); +assertEq(!Array.isArray(objWithArrPrototype), true); +assertEq(Object.getPrototypeOf(objWithArrPrototype), arr); +var objWithArrGrandPrototype = Object.create(objWithArrPrototype); +assertEq(!Array.isArray(objWithArrGrandPrototype), true); +assertEq(Object.getPrototypeOf(objWithArrGrandPrototype), objWithArrPrototype); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/non262/object/getPrototypeOf.js b/js/src/tests/non262/object/getPrototypeOf.js new file mode 100644 index 0000000000..71cd30c62c --- /dev/null +++ b/js/src/tests/non262/object/getPrototypeOf.js @@ -0,0 +1,22 @@ +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +var BUGNUMBER = 1079090; +var summary = "Coerce the argument passed to Object.getPrototypeOf using ToObject"; +print(BUGNUMBER + ": " + summary); + +assertThrowsInstanceOf(() => Object.getPrototypeOf(), TypeError); +assertThrowsInstanceOf(() => Object.getPrototypeOf(undefined), TypeError); +assertThrowsInstanceOf(() => Object.getPrototypeOf(null), TypeError); + +assertEq(Object.getPrototypeOf(1), Number.prototype); +assertEq(Object.getPrototypeOf(true), Boolean.prototype); +assertEq(Object.getPrototypeOf("foo"), String.prototype); +if (typeof Symbol === "function") { + assertEq(Object.getPrototypeOf(Symbol("foo")), Symbol.prototype); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/getter-name.js b/js/src/tests/non262/object/getter-name.js new file mode 100644 index 0000000000..601d6b4778 --- /dev/null +++ b/js/src/tests/non262/object/getter-name.js @@ -0,0 +1,10 @@ +var BUGNUMBER = 1180290; +var summary = 'Object accessors should have get prefix'; + +print(BUGNUMBER + ": " + summary); + +assertEq(Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").get.name, "get __proto__"); +assertEq(Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").set.name, "set __proto__"); + +if (typeof reportCompare === 'function') + reportCompare(true, true); diff --git a/js/src/tests/non262/object/hasOwn.js b/js/src/tests/non262/object/hasOwn.js new file mode 100644 index 0000000000..cb9ebda5db --- /dev/null +++ b/js/src/tests/non262/object/hasOwn.js @@ -0,0 +1,18 @@ +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +assertEq(Object.hasOwn({}, "any"), false); +assertThrowsInstanceOf(() => Object.hasOwn(null, "any"), TypeError); + +var x = { test: 'test value'} +var y = {} +var z = Object.create(x); + +assertEq(Object.hasOwn(x, "test"), true); +assertEq(Object.hasOwn(y, "test"), false); +assertEq(Object.hasOwn(z, "test"), false); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/isExtensible.js b/js/src/tests/non262/object/isExtensible.js new file mode 100644 index 0000000000..f1fa008782 --- /dev/null +++ b/js/src/tests/non262/object/isExtensible.js @@ -0,0 +1,21 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 1060873; +var summary = "Object.isExtensible() should return false when given primitive values as input"; + +print(BUGNUMBER + ": " + summary); +assertEq(Object.isExtensible(), false); +assertEq(Object.isExtensible(undefined), false); +assertEq(Object.isExtensible(null), false); +assertEq(Object.isExtensible(1), false); +assertEq(Object.isExtensible("foo"), false); +assertEq(Object.isExtensible(true), false); +if (typeof Symbol === "function") { + assertEq(Object.isExtensible(Symbol()), false); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/isFrozen.js b/js/src/tests/non262/object/isFrozen.js new file mode 100644 index 0000000000..02056802d7 --- /dev/null +++ b/js/src/tests/non262/object/isFrozen.js @@ -0,0 +1,21 @@ +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +var BUGNUMBER = 1071464; +var summary = "Object.isFrozen() should return true when given primitive values as input"; + +print(BUGNUMBER + ": " + summary); +assertEq(Object.isFrozen(), true); +assertEq(Object.isFrozen(undefined), true); +assertEq(Object.isFrozen(null), true); +assertEq(Object.isFrozen(1), true); +assertEq(Object.isFrozen("foo"), true); +assertEq(Object.isFrozen(true), true); +if (typeof Symbol === "function") { + assertEq(Object.isFrozen(Symbol()), true); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/isPrototypeOf.js b/js/src/tests/non262/object/isPrototypeOf.js new file mode 100644 index 0000000000..a2d78f6507 --- /dev/null +++ b/js/src/tests/non262/object/isPrototypeOf.js @@ -0,0 +1,86 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = 'isPrototypeOf.js'; +var BUGNUMBER = 619283; +var summary = "Object.prototype.isPrototypeOf"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function expectThrowTypeError(fun) +{ + try + { + var r = fun(); + throw new Error("didn't throw TypeError, returned " + r); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "didn't throw TypeError, got: " + e); + } +} + +var isPrototypeOf = Object.prototype.isPrototypeOf; + +/* + * 1. If V is not an Object, return false. + */ +assertEq(isPrototypeOf(), false); +assertEq(isPrototypeOf(1), false); +assertEq(isPrototypeOf(Number.MAX_VALUE), false); +assertEq(isPrototypeOf(NaN), false); +assertEq(isPrototypeOf(""), false); +assertEq(isPrototypeOf("sesquicentennial"), false); +assertEq(isPrototypeOf(true), false); +assertEq(isPrototypeOf(false), false); +assertEq(isPrototypeOf(0.72), false); +assertEq(isPrototypeOf(undefined), false); +assertEq(isPrototypeOf(null), false); + + +/* + * 2. Let O be the result of calling ToObject passing the this value as the + * argument. + */ +var protoGlobal = Object.create(this); +expectThrowTypeError(function() { isPrototypeOf.call(null, {}); }); +expectThrowTypeError(function() { isPrototypeOf.call(undefined, {}); }); +expectThrowTypeError(function() { isPrototypeOf({}); }); +expectThrowTypeError(function() { isPrototypeOf.call(null, protoGlobal); }); +expectThrowTypeError(function() { isPrototypeOf.call(undefined, protoGlobal); }); +expectThrowTypeError(function() { isPrototypeOf(protoGlobal); }); + + +/* + * 3. Repeat + */ + +/* + * 3a. Let V be the value of the [[Prototype]] internal property of V. + * 3b. If V is null, return false. + */ +assertEq(Object.prototype.isPrototypeOf(Object.prototype), false); +assertEq(String.prototype.isPrototypeOf({}), false); +assertEq(Object.prototype.isPrototypeOf(Object.create(null)), false); + +/* 3c. If O and V refer to the same object, return true. */ +assertEq(Object.prototype.isPrototypeOf({}), true); +assertEq(this.isPrototypeOf(protoGlobal), true); +assertEq(Object.prototype.isPrototypeOf({}), true); +assertEq(Object.prototype.isPrototypeOf(new Number(17)), true); +assertEq(Object.prototype.isPrototypeOf(function(){}), true); + + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/isSealed.js b/js/src/tests/non262/object/isSealed.js new file mode 100644 index 0000000000..cd363a87e1 --- /dev/null +++ b/js/src/tests/non262/object/isSealed.js @@ -0,0 +1,21 @@ +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +var BUGNUMBER = 1062860; +var summary = "Object.isSealed() should return true when given primitive values as input"; + +print(BUGNUMBER + ": " + summary); +assertEq(Object.isSealed(), true); +assertEq(Object.isSealed(undefined), true); +assertEq(Object.isSealed(null), true); +assertEq(Object.isSealed(1), true); +assertEq(Object.isSealed("foo"), true); +assertEq(Object.isSealed(true), true); +if (typeof Symbol === "function") { + assertEq(Object.isSealed(Symbol()), true); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/keys.js b/js/src/tests/non262/object/keys.js new file mode 100644 index 0000000000..5766f16d11 --- /dev/null +++ b/js/src/tests/non262/object/keys.js @@ -0,0 +1,23 @@ +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +var BUGNUMBER = 1038545; +var summary = "Coerce the argument passed to Object.keys using ToObject"; +print(BUGNUMBER + ": " + summary); + +assertThrowsInstanceOf(() => Object.keys(), TypeError); +assertThrowsInstanceOf(() => Object.keys(undefined), TypeError); +assertThrowsInstanceOf(() => Object.keys(null), TypeError); + +assertDeepEq(Object.keys(1), []); +assertDeepEq(Object.keys(true), []); +if (typeof Symbol === "function") { + assertDeepEq(Object.keys(Symbol("foo")), []); +} + +assertDeepEq(Object.keys("foo"), ["0", "1", "2"]); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/method-non-constructor.js b/js/src/tests/non262/object/method-non-constructor.js new file mode 100644 index 0000000000..fd1d589b97 --- /dev/null +++ b/js/src/tests/non262/object/method-non-constructor.js @@ -0,0 +1,12 @@ +var obj = { method() { } }; +assertThrowsInstanceOf(() => { + new obj.method; +}, TypeError); + +obj = { constructor() { } }; +assertThrowsInstanceOf(() => { + new obj.constructor; +}, TypeError); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/mutation-prevention-methods.js b/js/src/tests/non262/object/mutation-prevention-methods.js new file mode 100644 index 0000000000..01b4c19cbe --- /dev/null +++ b/js/src/tests/non262/object/mutation-prevention-methods.js @@ -0,0 +1,124 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +var gTestfile = 'mutation-prevention-methods.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 492849; +var summary = 'Object.is{Sealed,Frozen}, Object.{seal,freeze}'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +// Empty object + +var o1 = {}; + +assertEq(Object.isExtensible(o1), true); +assertEq(Object.isSealed(o1), false); +assertEq(Object.isFrozen(o1), false); + +Object.preventExtensions(o1); + +// An non-extensible empty object has no properties, so it is vacuously sealed +// and frozen. +assertEq(Object.isExtensible(o1), false); +assertEq(Object.isSealed(o1), true); +assertEq(Object.isFrozen(o1), true); + + +// Object with a data property + +var o2 = { 1: 2 }; + +assertEq(Object.isExtensible(o2), true); +assertEq(Object.isSealed(o2), false); +assertEq(Object.isFrozen(o2), false); + +Object.preventExtensions(o2); + +assertEq(Object.isExtensible(o2), false); +assertEq(Object.isSealed(o2), false); +assertEq(Object.isFrozen(o2), false); + +Object.seal(o2); + +assertEq(Object.isExtensible(o2), false); +assertEq(Object.isSealed(o2), true); +assertEq(Object.isFrozen(o2), false); + +assertEq(o2[1], 2); + +var desc; + +desc = Object.getOwnPropertyDescriptor(o2, "1"); +assertEq(typeof desc, "object"); +assertEq(desc.enumerable, true); +assertEq(desc.configurable, false); +assertEq(desc.value, 2); +assertEq(desc.writable, true); + +o2[1] = 17; + +assertEq(o2[1], 17); + +desc = Object.getOwnPropertyDescriptor(o2, "1"); +assertEq(typeof desc, "object"); +assertEq(desc.enumerable, true); +assertEq(desc.configurable, false); +assertEq(desc.value, 17); +assertEq(desc.writable, true); + +Object.freeze(o2); + +assertEq(o2[1], 17); + +desc = Object.getOwnPropertyDescriptor(o2, "1"); +assertEq(typeof desc, "object"); +assertEq(desc.enumerable, true); +assertEq(desc.configurable, false); +assertEq(desc.value, 17); +assertEq(desc.writable, false); + + +// Object with an accessor property + +var o3 = { get foo() { return 17; } }; + +assertEq(Object.isExtensible(o3), true); +assertEq(Object.isSealed(o3), false); +assertEq(Object.isFrozen(o3), false); + +Object.preventExtensions(o3); + +assertEq(Object.isExtensible(o3), false); +assertEq(Object.isSealed(o3), false); +assertEq(Object.isFrozen(o3), false); + +Object.seal(o3); + +// An accessor property in a sealed object is unchanged if that object is +// frozen, so a sealed object containing only accessor properties is also +// vacuously frozen. +assertEq(Object.isExtensible(o3), false); +assertEq(Object.isSealed(o3), true); +assertEq(Object.isFrozen(o3), true); + +Object.freeze(o3); + +assertEq(Object.isExtensible(o3), false); +assertEq(Object.isSealed(o3), true); +assertEq(Object.isFrozen(o3), true); + + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/object-create-with-primitive-second-arg.js b/js/src/tests/non262/object/object-create-with-primitive-second-arg.js new file mode 100644 index 0000000000..44afd53c25 --- /dev/null +++ b/js/src/tests/non262/object/object-create-with-primitive-second-arg.js @@ -0,0 +1,8 @@ +[1, "", true, Symbol(), undefined].forEach(props => { + assertEq(Object.getPrototypeOf(Object.create(null, props)), null); +}); + +assertThrowsInstanceOf(() => Object.create(null, null), TypeError); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/object-toString-01.js b/js/src/tests/non262/object/object-toString-01.js new file mode 100644 index 0000000000..6a8c4e86a9 --- /dev/null +++ b/js/src/tests/non262/object/object-toString-01.js @@ -0,0 +1,46 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +var gTestfile = 'object-toString-01.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 575522; +var summary = '({}).toString.call(null) == "[object Null]", ' + + '({}).toString.call(undefined) == "[object Undefined]", '; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var toString = Object.prototype.toString; + +assertEq(toString.call(null), "[object Null]"); +assertEq(toString.call(undefined), "[object Undefined]"); + +assertEq(toString.call(true), "[object Boolean]"); +assertEq(toString.call(false), "[object Boolean]"); + +assertEq(toString.call(0), "[object Number]"); +assertEq(toString.call(-0), "[object Number]"); +assertEq(toString.call(1), "[object Number]"); +assertEq(toString.call(-1), "[object Number]"); +assertEq(toString.call(NaN), "[object Number]"); +assertEq(toString.call(Infinity), "[object Number]"); +assertEq(toString.call(-Infinity), "[object Number]"); + +assertEq(toString.call("foopy"), "[object String]"); + +assertEq(toString.call({}), "[object Object]"); + + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/preventExtensions-idempotent.js b/js/src/tests/non262/object/preventExtensions-idempotent.js new file mode 100644 index 0000000000..c0b16d890f --- /dev/null +++ b/js/src/tests/non262/object/preventExtensions-idempotent.js @@ -0,0 +1,30 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +var gTestfile = 'preventExtensions-idempotent.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 599459; +var summary = 'Object.preventExtensions should be idempotent'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var obj = {}; +assertEq(Object.preventExtensions(obj), obj); +assertEq(Object.isExtensible(obj), false); +assertEq(Object.preventExtensions(obj), obj); +assertEq(Object.isExtensible(obj), false); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/preventExtensions-proxy.js b/js/src/tests/non262/object/preventExtensions-proxy.js new file mode 100644 index 0000000000..347a63bc3a --- /dev/null +++ b/js/src/tests/non262/object/preventExtensions-proxy.js @@ -0,0 +1,23 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function logProxy(object = {}, handler = {}) { + var log = []; + var proxy = new Proxy(object, new Proxy(handler, { + get(target, propertyKey, receiver) { + log.push(propertyKey); + return target[propertyKey]; + } + })); + return {proxy, log}; +} + +var {proxy, log} = logProxy(); +Object.preventExtensions(proxy); +assertDeepEq(log, ["preventExtensions"]); + +var {proxy, log} = logProxy(); +Object.preventExtensions(Object.preventExtensions(proxy)); +assertDeepEq(log, ["preventExtensions", "preventExtensions"]); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/object/preventExtensions.js b/js/src/tests/non262/object/preventExtensions.js new file mode 100644 index 0000000000..75c8ed3db5 --- /dev/null +++ b/js/src/tests/non262/object/preventExtensions.js @@ -0,0 +1,21 @@ +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +var BUGNUMBER = 1073446; +var summary = "Object.preventExtensions() should return its argument with no conversion when the argument is a primitive value"; + +print(BUGNUMBER + ": " + summary); +assertEq(Object.preventExtensions(), undefined); +assertEq(Object.preventExtensions(undefined), undefined); +assertEq(Object.preventExtensions(null), null); +assertEq(Object.preventExtensions(1), 1); +assertEq(Object.preventExtensions("foo"), "foo"); +assertEq(Object.preventExtensions(true), true); +if (typeof Symbol === "function") { + assertEq(Object.preventExtensions(Symbol.for("foo")), Symbol.for("foo")); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/property-descriptor-order.js b/js/src/tests/non262/object/property-descriptor-order.js new file mode 100644 index 0000000000..337d247dae --- /dev/null +++ b/js/src/tests/non262/object/property-descriptor-order.js @@ -0,0 +1,17 @@ +var names = Object.getOwnPropertyNames(Object.getOwnPropertyDescriptor({foo: 0}, "foo")); +assertDeepEq(names, ["value", "writable", "enumerable", "configurable"]); + +names = Object.getOwnPropertyNames(Object.getOwnPropertyDescriptor({get foo(){}}, "foo")); +assertDeepEq(names, ["get", "set", "enumerable", "configurable"]); + +var proxy = new Proxy({}, { + defineProperty(target, key, desc) { + var names = Object.getOwnPropertyNames(desc); + assertDeepEq(names, ["set", "configurable"]); + return true; + } +}); + +Object.defineProperty(proxy, "foo", {configurable: true, set: function() {}}); + +reportCompare(true, true); diff --git a/js/src/tests/non262/object/propertyIsEnumerable-proxy.js b/js/src/tests/non262/object/propertyIsEnumerable-proxy.js new file mode 100644 index 0000000000..a1dda90e0a --- /dev/null +++ b/js/src/tests/non262/object/propertyIsEnumerable-proxy.js @@ -0,0 +1,59 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function logProxy(object) { + var log = []; + var handler = { + getOwnPropertyDescriptor(target, propertyKey) { + log.push(propertyKey); + return Object.getOwnPropertyDescriptor(target, propertyKey); + } + }; + var proxy = new Proxy(object, new Proxy(handler, { + get(target, propertyKey, receiver) { + if (!(propertyKey in target)) { + throw new Error(`Unexpected call to trap: "${propertyKey}"`); + } + return target[propertyKey]; + } + })); + return {proxy, log}; +} + +var properties = ["string-property"]; +if (typeof Symbol === 'function') + properties.push(Symbol("symbol-property")); + +for (var property of properties) { + // Test 1: property is not present on object + var {proxy, log} = logProxy({}); + var result = Object.prototype.propertyIsEnumerable.call(proxy, property); + assertEq(result, false); + assertDeepEq(log, [property]); + + // Test 2: property is present on object and enumerable + var {proxy, log} = logProxy({[property]: 0}); + var result = Object.prototype.propertyIsEnumerable.call(proxy, property); + assertEq(result, true); + assertDeepEq(log, [property]); + + // Test 3: property is present on object, but not enumerable + var {proxy, log} = logProxy(Object.defineProperty({[property]: 0}, property, {enumerable: false})); + var result = Object.prototype.propertyIsEnumerable.call(proxy, property); + assertEq(result, false); + assertDeepEq(log, [property]); + + // Test 4: property is present on prototype object + var {proxy, log} = logProxy(Object.create({[property]: 0})); + var result = Object.prototype.propertyIsEnumerable.call(proxy, property); + assertEq(result, false); + assertDeepEq(log, [property]); + + // Test 5: property is present on prototype object, prototype is proxy object + var {proxy, log} = logProxy({[property]: 0}); + var result = Object.prototype.propertyIsEnumerable.call(Object.create(proxy), property); + assertEq(result, false); + assertDeepEq(log, []); +} + +reportCompare(0, 0); diff --git a/js/src/tests/non262/object/propertyIsEnumerable.js b/js/src/tests/non262/object/propertyIsEnumerable.js new file mode 100644 index 0000000000..e9b09d0bfb --- /dev/null +++ b/js/src/tests/non262/object/propertyIsEnumerable.js @@ -0,0 +1,199 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = 'propertyIsEnumerable.js'; +var BUGNUMBER = 619283; +var summary = "Object.prototype.propertyIsEnumerable"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function expectThrowError(errorCtor, fun) +{ + try + { + var r = fun(); + throw "didn't throw TypeError, returned " + r; + } + catch (e) + { + assertEq(e instanceof errorCtor, true, + "didn't throw " + errorCtor.prototype.name + ", got: " + e); + } +} + +function expectThrowTypeError(fun) +{ + expectThrowError(TypeError, fun); +} + +function withToString(fun) +{ + return { toString: fun }; +} + +function withValueOf(fun) +{ + return { toString: null, valueOf: fun }; +} + +var propertyIsEnumerable = Object.prototype.propertyIsEnumerable; + +/* + * 1. Let P be ToString(V). + */ +expectThrowError(ReferenceError, function() +{ + propertyIsEnumerable(withToString(function() { fahslkjdfhlkjdsl; })); +}); +expectThrowError(ReferenceError, function() +{ + propertyIsEnumerable.call(null, withToString(function() { fahslkjdfhlkjdsl; })); +}); +expectThrowError(ReferenceError, function() +{ + propertyIsEnumerable.call(undefined, withToString(function() { fahslkjdfhlkjdsl; })); +}); + +expectThrowError(ReferenceError, function() +{ + propertyIsEnumerable(withValueOf(function() { fahslkjdfhlkjdsl; })); +}); +expectThrowError(ReferenceError, function() +{ + propertyIsEnumerable.call(null, withValueOf(function() { fahslkjdfhlkjdsl; })); +}); +expectThrowError(ReferenceError, function() +{ + propertyIsEnumerable.call(undefined, withValueOf(function() { fahslkjdfhlkjdsl; })); +}); + +expectThrowError(SyntaxError, function() +{ + propertyIsEnumerable(withToString(function() { eval("}"); })); +}); +expectThrowError(SyntaxError, function() +{ + propertyIsEnumerable.call(null, withToString(function() { eval("}"); })); +}); +expectThrowError(SyntaxError, function() +{ + propertyIsEnumerable.call(undefined, withToString(function() { eval("}"); })); +}); + +expectThrowError(SyntaxError, function() +{ + propertyIsEnumerable(withValueOf(function() { eval("}"); })); +}); +expectThrowError(SyntaxError, function() +{ + propertyIsEnumerable.call(null, withValueOf(function() { eval("}"); })); +}); +expectThrowError(SyntaxError, function() +{ + propertyIsEnumerable.call(undefined, withValueOf(function() { eval("}"); })); +}); + +expectThrowError(RangeError, function() +{ + propertyIsEnumerable(withToString(function() { [].length = -1; })); +}); +expectThrowError(RangeError, function() +{ + propertyIsEnumerable.call(null, withToString(function() { [].length = -1; })); +}); +expectThrowError(RangeError, function() +{ + propertyIsEnumerable.call(undefined, withToString(function() { [].length = -1; })); +}); + +expectThrowError(RangeError, function() +{ + propertyIsEnumerable(withValueOf(function() { [].length = -1; })); +}); +expectThrowError(RangeError, function() +{ + propertyIsEnumerable.call(null, withValueOf(function() { [].length = -1; })); +}); +expectThrowError(RangeError, function() +{ + propertyIsEnumerable.call(undefined, withValueOf(function() { [].length = -1; })); +}); + +expectThrowError(RangeError, function() +{ + propertyIsEnumerable(withToString(function() { [].length = 0.7; })); +}); +expectThrowError(RangeError, function() +{ + propertyIsEnumerable.call(null, withToString(function() { [].length = 0.7; })); +}); +expectThrowError(RangeError, function() +{ + propertyIsEnumerable.call(undefined, withToString(function() { [].length = 0.7; })); +}); + +expectThrowError(RangeError, function() +{ + propertyIsEnumerable(withValueOf(function() { [].length = 0.7; })); +}); +expectThrowError(RangeError, function() +{ + propertyIsEnumerable.call(null, withValueOf(function() { [].length = 0.7; })); +}); +expectThrowError(RangeError, function() +{ + propertyIsEnumerable.call(undefined, withValueOf(function() { [].length = 0.7; })); +}); + +/* + * 2. Let O be the result of calling ToObject passing the this value as the + * argument. + */ +expectThrowTypeError(function() { propertyIsEnumerable("s"); }); +expectThrowTypeError(function() { propertyIsEnumerable.call(null, "s"); }); +expectThrowTypeError(function() { propertyIsEnumerable.call(undefined, "s"); }); +expectThrowTypeError(function() { propertyIsEnumerable(true); }); +expectThrowTypeError(function() { propertyIsEnumerable.call(null, true); }); +expectThrowTypeError(function() { propertyIsEnumerable.call(undefined, true); }); +expectThrowTypeError(function() { propertyIsEnumerable(NaN); }); +expectThrowTypeError(function() { propertyIsEnumerable.call(null, NaN); }); +expectThrowTypeError(function() { propertyIsEnumerable.call(undefined, NaN); }); + +expectThrowTypeError(function() { propertyIsEnumerable({}); }); +expectThrowTypeError(function() { propertyIsEnumerable.call(null, {}); }); +expectThrowTypeError(function() { propertyIsEnumerable.call(undefined, {}); }); + +/* + * 3. Let desc be the result of calling the [[GetOwnProperty]] internal method + * of O passing P as the argument. + * 4. If desc is undefined, return false. + */ +assertEq(propertyIsEnumerable.call({}, "valueOf"), false); +assertEq(propertyIsEnumerable.call({}, "toString"), false); +assertEq(propertyIsEnumerable.call("s", 1), false); +assertEq(propertyIsEnumerable.call({}, "dsfiodjfs"), false); +assertEq(propertyIsEnumerable.call(true, "toString"), false); +assertEq(propertyIsEnumerable.call({}, "__proto__"), false); + +assertEq(propertyIsEnumerable.call(Object, "getOwnPropertyDescriptor"), false); +assertEq(propertyIsEnumerable.call(this, "expectThrowTypeError"), true); +assertEq(propertyIsEnumerable.call("s", "length"), false); +assertEq(propertyIsEnumerable.call("s", 0), true); +assertEq(propertyIsEnumerable.call(Number, "MAX_VALUE"), false); +assertEq(propertyIsEnumerable.call({ x: 9 }, "x"), true); +assertEq(propertyIsEnumerable.call(function() { }, "prototype"), false); +assertEq(propertyIsEnumerable.call(function() { }, "length"), false); +assertEq(propertyIsEnumerable.call(function() { "use strict"; }, "caller"), false); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/proto-property-change-writability-set.js b/js/src/tests/non262/object/proto-property-change-writability-set.js new file mode 100644 index 0000000000..d81f844e93 --- /dev/null +++ b/js/src/tests/non262/object/proto-property-change-writability-set.js @@ -0,0 +1,56 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributors: + * Gary Kwong + * Jeff Walden + * Jason Orendorff + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 713944; +var summary = + "Don't assert anything about a shape from the property cache until it's " + + "known the cache entry matches"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var accDesc = { set: function() {} }; +var dataDesc = { value: 3 }; + +function f() +{ + propertyIsEnumerable = {}; +} +function g() +{ + propertyIsEnumerable = {}; +} + +Object.defineProperty(Object.prototype, "propertyIsEnumerable", accDesc); +f(); +Object.defineProperty(Object.prototype, "propertyIsEnumerable", dataDesc); +assertEq(propertyIsEnumerable, 3); +f(); +assertEq(propertyIsEnumerable, 3); +g(); +assertEq(propertyIsEnumerable, 3); + + + +var a = { p1: 1, p2: 2 }; +var b = Object.create(a); +Object.defineProperty(a, "p1", {set: function () {}}); +for (var i = 0; i < 2; i++) +{ + b.p1 = {}; + Object.defineProperty(a, "p1", {value: 3}); +} +assertEq(b.p1, 3); +assertEq(a.p1, 3); + +reportCompare(true, true); diff --git a/js/src/tests/non262/object/regress-137000.js b/js/src/tests/non262/object/regress-137000.js new file mode 100644 index 0000000000..7e4ce268dd --- /dev/null +++ b/js/src/tests/non262/object/regress-137000.js @@ -0,0 +1,203 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 03 June 2002 + * SUMMARY: Function param or local var with same name as a function property + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=137000 + * See http://bugzilla.mozilla.org/show_bug.cgi?id=138708 + * See http://bugzilla.mozilla.org/show_bug.cgi?id=150032 + * See http://bugzilla.mozilla.org/show_bug.cgi?id=150859 + * + */ +//----------------------------------------------------------------------------- +var UBound = 0; +var BUGNUMBER = 137000; +var summary = 'Function param or local var with same name as a function prop'; +var status = ''; +var statusitems = []; +var actual = ''; +var actualvalues = []; +var expect= ''; +var expectedvalues = []; + + +/* + * Note use of 'x' both for the parameter to f, + * and as a property name for |f| as an object + */ +function f(x) +{ +} + +status = inSection(1); +f.x = 12; +actual = f.x; +expect = 12; +addThis(); + + + +/* + * A more elaborate example, using the call() method + * to chain constructors from child to parent. + * + * The key point is the use of the same name 'p' for both + * the parameter to the constructor, and as a property name + */ +function parentObject(p) +{ + this.p = 1; +} + +function childObject() +{ + parentObject.call(this); +} +childObject.prototype = parentObject; + +status = inSection(2); +var objParent = new parentObject(); +actual = objParent.p; +expect = 1; +addThis(); + +status = inSection(3); +var objChild = new childObject(); +actual = objChild.p; +expect = 1; +addThis(); + + + +/* + * A similar set-up. Here the same name is being used for + * the parameter to both the Base and Child constructors, + */ +function Base(id) +{ +} + +function Child(id) +{ + this.prop = id; +} +Child.prototype=Base; + +status = inSection(4); +var c1 = new Child('child1'); +actual = c1.prop; +expect = 'child1'; +addThis(); + + + +/* + * Use same identifier as a property name, too - + */ +function BaseX(id) +{ +} + +function ChildX(id) +{ + this.id = id; +} +ChildX.prototype=BaseX; + +status = inSection(5); +c1 = new ChildX('child1'); +actual = c1.id; +expect = 'child1'; +addThis(); + + + +/* + * From http://bugzilla.mozilla.org/show_bug.cgi?id=150032 + * + * Here the same name is being used both for a local variable + * declared in g(), and as a property name for |g| as an object + */ +function g() +{ + var propA = g.propA; + var propB = g.propC; + + this.getVarA = function() {return propA;} + this.getVarB = function() {return propB;} +} +g.propA = 'A'; +g.propB = 'B'; +g.propC = 'C'; +var obj = new g(); + +status = inSection(6); +actual = obj.getVarA(); // this one was returning 'undefined' +expect = 'A'; +addThis(); + +status = inSection(7); +actual = obj.getVarB(); // this one is easy; it never failed +expect = 'C'; +addThis(); + + + +/* + * By martin.honnen@gmx.de + * From http://bugzilla.mozilla.org/show_bug.cgi?id=150859 + * + * Here the same name is being used for a local var in F + * and as a property name for |F| as an object + * + * Twist: the property is added via another function. + */ +function setFProperty(val) +{ + F.propA = val; +} + +function F() +{ + var propA = 'Local variable in F'; +} + +status = inSection(8); +setFProperty('Hello'); +actual = F.propA; // this was returning 'undefined' +expect = 'Hello'; +addThis(); + + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusitems[UBound] = status; + actualvalues[UBound] = actual; + expectedvalues[UBound] = expect; + UBound++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus(summary); + + for (var i=0; i<UBound; i++) + { + reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); + } +} diff --git a/js/src/tests/non262/object/regress-192105.js b/js/src/tests/non262/object/regress-192105.js new file mode 100644 index 0000000000..d29c2d7565 --- /dev/null +++ b/js/src/tests/non262/object/regress-192105.js @@ -0,0 +1,146 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 06 February 2003 + * SUMMARY: Using |instanceof| to check if function is called as a constructor + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=192105 + * + */ +//----------------------------------------------------------------------------- +var UBound = 0; +var BUGNUMBER = 192105; +var summary = 'Using |instanceof| to check if f() is called as constructor'; +var status = ''; +var statusitems = []; +var actual = ''; +var actualvalues = []; +var expect= ''; +var expectedvalues = []; + + +/* + * This function is the heart of the test. It sets the result + * variable |actual|, which we will compare against |expect|. + * + * Note |actual| will be set to |true| or |false| according + * to whether or not this function is called as a constructor; + * i.e. whether it is called via the |new| keyword or not - + */ +function f() +{ + actual = (this instanceof f); +} + + +/* + * Call f as a constructor from global scope + */ +status = inSection(1); +new f(); // sets |actual| +expect = true; +addThis(); + +/* + * Now, not as a constructor + */ +status = inSection(2); +f(); // sets |actual| +expect = false; +addThis(); + + +/* + * Call f as a constructor from function scope + */ +function F() +{ + new f(); +} +status = inSection(3); +F(); // sets |actual| +expect = true; +addThis(); + +/* + * Now, not as a constructor + */ +function G() +{ + f(); +} +status = inSection(4); +G(); // sets |actual| +expect = false; +addThis(); + + +/* + * Now make F() and G() methods of an object + */ +var obj = {F:F, G:G}; +status = inSection(5); +obj.F(); // sets |actual| +expect = true; +addThis(); + +status = inSection(6); +obj.G(); // sets |actual| +expect = false; +addThis(); + + +/* + * Now call F() and G() from yet other functions, and use eval() + */ +function A() +{ + eval('F();'); +} +status = inSection(7); +A(); // sets |actual| +expect = true; +addThis(); + + +function B() +{ + eval('G();'); +} +status = inSection(8); +B(); // sets |actual| +expect = false; +addThis(); + + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusitems[UBound] = status; + actualvalues[UBound] = actual; + expectedvalues[UBound] = expect; + UBound++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus(summary); + + for (var i=0; i<UBound; i++) + { + reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); + } +} diff --git a/js/src/tests/non262/object/regress-308806-01.js b/js/src/tests/non262/object/regress-308806-01.js new file mode 100644 index 0000000000..8e0a66839c --- /dev/null +++ b/js/src/tests/non262/object/regress-308806-01.js @@ -0,0 +1,20 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 308806; +var summary = 'Object.prototype.toLocaleString() should track Object.prototype.toString() '; +var actual = ''; +var expect = ''; + +printBugNumber(BUGNUMBER); +printStatus (summary); + +var o = {toString: function() { return 'foo'; }}; + +expect = o.toString(); +actual = o.toLocaleString(); + +reportCompare(expect, actual, summary); diff --git a/js/src/tests/non262/object/regress-338709.js b/js/src/tests/non262/object/regress-338709.js new file mode 100644 index 0000000000..ca82e7fbcb --- /dev/null +++ b/js/src/tests/non262/object/regress-338709.js @@ -0,0 +1,74 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 338709; +var summary = 'ReadOnly properties should not be overwritten by using ' + + 'Object and try..throw..catch'; +var actual = ''; +var expect = ''; + +printBugNumber(BUGNUMBER); +printStatus (summary); + +Object = function () { return Math }; +expect = Math.LN2; +try +{ + throw 1990; +} +catch (LN2) +{ +} +actual = Math.LN2; +print("Math.LN2 = " + Math.LN2) + reportCompare(expect, actual, summary); + +var s = new String("abc"); +Object = function () { return s }; +expect = s.length; +try +{ + throw -8 + } +catch (length) +{ +} +actual = s.length; +print("length of '" + s + "' = " + s.length) + reportCompare(expect, actual, summary); + +var re = /xy/m; +Object = function () { return re }; +expect = re.multiline; +try +{ + throw false + } +catch (multiline) +{ +} +actual = re.multiline; +print("re.multiline = " + re.multiline) + reportCompare(expect, actual, summary); + +if ("document" in this) { + // Let the document be its own documentElement. + Object = function () { return document } + expect = document.documentElement + ''; + try + { + throw document; + } + catch (documentElement) + { + } + actual = document.documentElement + ''; + print("document.documentElement = " + document.documentElement) + } +else + Object = this.constructor + + reportCompare(expect, actual, summary); diff --git a/js/src/tests/non262/object/regress-361274.js b/js/src/tests/non262/object/regress-361274.js new file mode 100644 index 0000000000..dd3d15f328 --- /dev/null +++ b/js/src/tests/non262/object/regress-361274.js @@ -0,0 +1,30 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 361274; +var summary = 'Embedded nulls in property names'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + var x='123'+'\0'+'456'; + var y='123'+'\0'+'789'; + var a={}; + a[x]=1; + a[y]=2; + + reportCompare(1, a[x], summary + ': 123\\0456'); + reportCompare(2, a[y], summary + ': 123\\0789'); +} diff --git a/js/src/tests/non262/object/regress-382503.js b/js/src/tests/non262/object/regress-382503.js new file mode 100644 index 0000000000..373b45f6e2 --- /dev/null +++ b/js/src/tests/non262/object/regress-382503.js @@ -0,0 +1,29 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 382503; +var summary = 'Do not assert: with prototype=regexp'; +var actual = ''; +var expect = ''; + +printBugNumber(BUGNUMBER); +printStatus (summary); + +function f(x) +{ + prototype = /a/; + + if (x) { + return /b/; + return /c/; + } else { + return /d/; + } +} + +void f(false); + +reportCompare(expect, actual, summary); diff --git a/js/src/tests/non262/object/regress-382532.js b/js/src/tests/non262/object/regress-382532.js new file mode 100644 index 0000000000..a65651a1c6 --- /dev/null +++ b/js/src/tests/non262/object/regress-382532.js @@ -0,0 +1,33 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 382532; +var summary = 'instanceof,... broken by use of |prototype| in heavyweight constructor'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + var prototype; + + function Bug() { + var func = function () { x; }; + prototype; + } + + expect = true; + actual = (new Bug instanceof Bug); + + reportCompare(expect, actual, summary); +} diff --git a/js/src/tests/non262/object/regress-385393-07.js b/js/src/tests/non262/object/regress-385393-07.js new file mode 100644 index 0000000000..eea506aba2 --- /dev/null +++ b/js/src/tests/non262/object/regress-385393-07.js @@ -0,0 +1,31 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +//----------------------------------------------------------------------------- +var BUGNUMBER = 385393; +var summary = 'Regression test for bug 385393'; +var actual = 'No Crash'; +var expect = 'No Crash'; + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + try + { + (2).eval(); + } + catch(ex) + { + } + + reportCompare(expect, actual, summary); +} diff --git a/js/src/tests/non262/object/regress-444787.js b/js/src/tests/non262/object/regress-444787.js new file mode 100644 index 0000000000..08e1496860 --- /dev/null +++ b/js/src/tests/non262/object/regress-444787.js @@ -0,0 +1,101 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 444787; +var summary = 'Object.getPrototypeOf'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + var i; + var type; + var instance; + var types = [ + Array, + Boolean, + Date, + Error, + Function, + Math, + Number, + Object, + RegExp, + String, + ]; + + for (i = 0; i < types.length; i++) + { + type = types[i]; + + if (typeof type.__proto__ != 'undefined') + { + expect = type.__proto__; + actual = Object.getPrototypeOf(type); + reportCompare(expect, actual, summary + ': ' + type.name); + } + + try + { + eval('instance = new ' + type.name); + expect = type.prototype; + actual = Object.getPrototypeOf(instance); + reportCompare(expect, actual, summary + ': new ' + type.name); + } + catch(ex) { + if (ex instanceof TypeError) { + print('Ignore ' + ex); + } else { + actual = ex + ''; + reportCompare(expect, actual, summary + ': new ' + type.name); + } + } + + } + + types = [null, undefined]; + + for (i = 0; i < types.length; i++) + { + type = types[i]; + expect = 'TypeError: Object.getPrototype is not a function'; + try + { + actual = Object.getPrototype(null); + } + catch(ex) + { + actual = ex + ''; + } + reportCompare(expect, actual, summary + ': ' + type); + } + + var objects = [ + {instance: [0], type: Array}, + {instance: (function () {}), type: Function}, + {instance: eval, type: Function}, + {instance: parseInt, type: Function}, + {instance: {a: ''}, type: Object}, + {instance: /foo/, type: RegExp} + ]; + + for (i = 0; i < objects.length; i++) + { + instance = objects[i].instance; + type = objects[i].type; + expect = type.prototype; + actual = Object.getPrototypeOf(instance); + reportCompare(expect, actual, summary + ' instance: ' + instance + ', type: ' + type.name); + } +} diff --git a/js/src/tests/non262/object/regress-459405.js b/js/src/tests/non262/object/regress-459405.js new file mode 100644 index 0000000000..524bc6a092 --- /dev/null +++ b/js/src/tests/non262/object/regress-459405.js @@ -0,0 +1,37 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: Robert Sayre + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 459405; +var summary = 'Math is not ReadOnly'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + expect = 'foo'; + + try + { + var Math = 'foo'; + actual = Math; + } + catch(ex) + { + actual = ex + ''; + } + + reportCompare(expect, actual, summary); +} diff --git a/js/src/tests/non262/object/regress-465476.js b/js/src/tests/non262/object/regress-465476.js new file mode 100644 index 0000000000..1d998f1e71 --- /dev/null +++ b/js/src/tests/non262/object/regress-465476.js @@ -0,0 +1,60 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 465476; +var summary = '"-0" and "0" are distinct properties.'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + var x = { "0": 3, "-0": 7 }; + + expect = actual = 'No Exception'; + + try + { + if (!("0" in x)) + throw "0 not in x"; + if (!("-0" in x)) + throw "-0 not in x"; + delete x[0]; + if ("0" in x) + throw "0 in x after delete"; + if (!("-0" in x)) + throw "-0 removed from x after unassociated delete"; + delete x["-0"]; + if ("-0" in x) + throw "-0 in x after delete"; + x[0] = 3; + if (!("0" in x)) + throw "0 not in x after insertion of 0 property"; + if ("-0" in x) + throw "-0 in x after insertion of 0 property"; + x["-0"] = 7; + if (!("-0" in x)) + throw "-0 not in x after reinsertion"; + + var props = []; + for (var i in x) + props.push(i); + if (props.length !== 2) + throw "not all props found!"; + } + catch(ex) + { + actual = ex + ''; + } + reportCompare(expect, actual, summary); +} diff --git a/js/src/tests/non262/object/regress-72773.js b/js/src/tests/non262/object/regress-72773.js new file mode 100644 index 0000000000..77f75c3dc0 --- /dev/null +++ b/js/src/tests/non262/object/regress-72773.js @@ -0,0 +1,60 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 09 May 2001 + * + * SUMMARY: Regression test: we shouldn't crash on this code + * See http://bugzilla.mozilla.org/show_bug.cgi?id=72773 + * + * See ECMA-262 Edition 3 13-Oct-1999, Section 8.6.2 re [[Class]] property. + * + * Same as class-001.js - but testing user-defined types here, not + * native types. Therefore we expect the [[Class]] property to equal + * 'Object' in each case - + * + * The getJSClass() function we use is in a utility file, e.g. "shell.js" + */ +//----------------------------------------------------------------------------- +var BUGNUMBER = 72773; +var summary = "Regression test: we shouldn't crash on this code"; +var status = ''; +var actual = ''; +var expect = ''; +var sToEval = ''; + +/* + * This code should produce an error, but not a crash. + * 'TypeError: Function.prototype.toString called on incompatible object' + */ +sToEval += 'function Cow(name){this.name = name;}' +sToEval += 'function Calf(str){this.name = str;}' +sToEval += 'Calf.prototype = Cow;' +sToEval += 'new Calf().toString();' + +status = 'Trying to catch an expected error'; +try +{ + eval(sToEval); +} +catch(e) +{ + actual = getJSClass(e); + expect = 'Error'; +} + + +//---------------------------------------------------------------------------------------------- +test(); +//---------------------------------------------------------------------------------------------- + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + reportCompare(expect, actual, status); +} diff --git a/js/src/tests/non262/object/regress-79129-001.js b/js/src/tests/non262/object/regress-79129-001.js new file mode 100644 index 0000000000..b9689429ee --- /dev/null +++ b/js/src/tests/non262/object/regress-79129-001.js @@ -0,0 +1,44 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 06 May 2001 + * + * SUMMARY: Regression test: we shouldn't crash on this code + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=79129 + */ +//----------------------------------------------------------------------------- +var BUGNUMBER = 79129; +var summary = "Regression test: we shouldn't crash on this code"; + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + tryThis(); + reportCompare('No Crash', 'No Crash', 'Should not crash'); +} + + +function tryThis() +{ + obj={}; + obj.a = obj.b = obj.c = 1; + delete obj.a; + delete obj.b; + delete obj.c; + obj.d = obj.e = 1; + obj.a=1; + obj.b=1; + obj.c=1; + obj.d=1; + obj.e=1; +} diff --git a/js/src/tests/non262/object/regress-90596-003.js b/js/src/tests/non262/object/regress-90596-003.js new file mode 100644 index 0000000000..ea0c161592 --- /dev/null +++ b/js/src/tests/non262/object/regress-90596-003.js @@ -0,0 +1,275 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 28 August 2001 + * + * SUMMARY: A [DontEnum] prop, if overridden, should appear in for-in loops. + * See http://bugzilla.mozilla.org/show_bug.cgi?id=90596 + * + * NOTE: some inefficiencies in the test are made for the sake of readability. + * For example, we quote string values like "Hi" in lines like this: + * + * actual = enumerateThis(obj); + * expect = '{prop:"Hi"}'; + * + * But enumerateThis(obj) gets literal value Hi for obj.prop, not + * literal "Hi". We take care of all these details in the + * compactThis(), sortThis() functions. Sorting properties + * alphabetically is necessary for the test to work in Rhino. + */ +//----------------------------------------------------------------------------- +var UBound = 0; +var BUGNUMBER = 90596; +var summary = '[DontEnum] props (if overridden) should appear in for-in loops'; +var cnCOMMA = ','; +var cnCOLON = ':'; +var cnLBRACE = '{'; +var cnRBRACE = '}'; +var status = ''; +var statusitems = []; +var actual = ''; +var actualvalues = []; +var expect= ''; +var expectedvalues = []; +var obj = {}; + + +status = inSection(1); +obj = {toString:9}; +actual = enumerateThis(obj); +expect = '{toString:9}'; +addThis(); + +status = inSection(2); +obj = {hasOwnProperty:"Hi"}; +actual = enumerateThis(obj); +expect = '{hasOwnProperty:"Hi"}'; +addThis(); + +status = inSection(3); +obj = {toString:9, hasOwnProperty:"Hi"}; +actual = enumerateThis(obj); +expect = '{toString:9, hasOwnProperty:"Hi"}'; +addThis(); + +status = inSection(4); +obj = {prop1:1, toString:9, hasOwnProperty:"Hi"}; +actual = enumerateThis(obj); +expect = '{prop1:1, toString:9, hasOwnProperty:"Hi"}'; +addThis(); + + +// TRY THE SAME THING IN EVAL CODE +var s = ''; + +status = inSection(5); +s = 'obj = {toString:9}'; +eval(s); +actual = enumerateThis(obj); +expect = '{toString:9}'; +addThis(); + +status = inSection(6); +s = 'obj = {hasOwnProperty:"Hi"}'; +eval(s); +actual = enumerateThis(obj); +expect = '{hasOwnProperty:"Hi"}'; +addThis(); + +status = inSection(7); +s = 'obj = {toString:9, hasOwnProperty:"Hi"}'; +eval(s); +actual = enumerateThis(obj); +expect = '{toString:9, hasOwnProperty:"Hi"}'; +addThis(); + +status = inSection(8); +s = 'obj = {prop1:1, toString:9, hasOwnProperty:"Hi"}'; +eval(s); +actual = enumerateThis(obj); +expect = '{prop1:1, toString:9, hasOwnProperty:"Hi"}'; +addThis(); + + +// TRY THE SAME THING IN FUNCTION CODE +function A() +{ + status = inSection(9); + var s = 'obj = {toString:9}'; + eval(s); + actual = enumerateThis(obj); + expect = '{toString:9}'; + addThis(); +} +A(); + +function B() +{ + status = inSection(10); + var s = 'obj = {hasOwnProperty:"Hi"}'; + eval(s); + actual = enumerateThis(obj); + expect = '{hasOwnProperty:"Hi"}'; + addThis(); +} +B(); + +function C() +{ + status = inSection(11); + var s = 'obj = {toString:9, hasOwnProperty:"Hi"}'; + eval(s); + actual = enumerateThis(obj); + expect = '{toString:9, hasOwnProperty:"Hi"}'; + addThis(); +} +C(); + +function D() +{ + status = inSection(12); + var s = 'obj = {prop1:1, toString:9, hasOwnProperty:"Hi"}'; + eval(s); + actual = enumerateThis(obj); + expect = '{prop1:1, toString:9, hasOwnProperty:"Hi"}'; + addThis(); +} +D(); + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function enumerateThis(obj) +{ + var arr = new Array(); + + for (var prop in obj) + { + arr.push(prop + cnCOLON + obj[prop]); + } + + var ret = addBraces(String(arr)); + return ret; +} + + +function addBraces(text) +{ + return cnLBRACE + text + cnRBRACE; +} + + +/* + * Sort properties alphabetically so the test will work in Rhino + */ +function addThis() +{ + statusitems[UBound] = status; + actualvalues[UBound] = sortThis(actual); + expectedvalues[UBound] = sortThis(expect); + UBound++; +} + + +/* + * Takes a string of the form '{"c", "b", "a", 2}' and returns '{2,a,b,c}' + */ +function sortThis(sList) +{ + sList = compactThis(sList); + sList = stripBraces(sList); + var arr = sList.split(cnCOMMA); + arr = arr.sort(); + var ret = String(arr); + ret = addBraces(ret); + return ret; +} + + +/* + * Strips out any whitespace or quotes from the text - + */ +function compactThis(text) +{ + var charCode = 0; + var ret = ''; + + for (var i=0; i<text.length; i++) + { + charCode = text.charCodeAt(i); + + if (!isWhiteSpace(charCode) && !isQuote(charCode)) + ret += text.charAt(i); + } + + return ret; +} + + +function isWhiteSpace(charCode) +{ + switch (charCode) + { + case (0x0009): + case (0x000B): + case (0x000C): + case (0x0020): + case (0x000A): // '\n' + case (0x000D): // '\r' + return true; + break; + + default: + return false; + } +} + + +function isQuote(charCode) +{ + switch (charCode) + { + case (0x0027): // single quote + case (0x0022): // double quote + return true; + break; + + default: + return false; + } +} + + +/* + * strips off braces at beginning and end of text - + */ +function stripBraces(text) +{ + // remember to escape the braces... + var arr = text.match(/^\{(.*)\}$/); + + // defend against a null match... + if (arr != null && arr[1] != null) + return arr[1]; + return text; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + for (var i=0; i<UBound; i++) + { + reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); + } +} diff --git a/js/src/tests/non262/object/seal-proxy.js b/js/src/tests/non262/object/seal-proxy.js new file mode 100644 index 0000000000..44bb685c87 --- /dev/null +++ b/js/src/tests/non262/object/seal-proxy.js @@ -0,0 +1,27 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function logProxy(object = {}, handler = {}) { + var log = []; + var proxy = new Proxy(object, new Proxy(handler, { + get(target, propertyKey, receiver) { + log.push(propertyKey); + return target[propertyKey]; + } + })); + return {proxy, log}; +} + +// The order of operations is backwards when compared to ES6 draft rev 27 +// (2014 August 24), but see https://bugs.ecmascript.org/show_bug.cgi?id=3215 +// for an explanation on why the spec version is clearly wrong. + +var {proxy, log} = logProxy(); +Object.seal(proxy); +assertDeepEq(log, ["preventExtensions", "ownKeys"]); + +var {proxy, log} = logProxy(); +Object.seal(Object.seal(proxy)); +assertDeepEq(log, ["preventExtensions", "ownKeys", "preventExtensions", "ownKeys"]); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/object/seal.js b/js/src/tests/non262/object/seal.js new file mode 100644 index 0000000000..e325c80d9d --- /dev/null +++ b/js/src/tests/non262/object/seal.js @@ -0,0 +1,21 @@ +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +var BUGNUMBER = 1075294; +var summary = "Object.seal() should return its argument with no conversion when the argument is a primitive value"; + +print(BUGNUMBER + ": " + summary); +assertEq(Object.seal(), undefined); +assertEq(Object.seal(undefined), undefined); +assertEq(Object.seal(null), null); +assertEq(Object.seal(1), 1); +assertEq(Object.seal("foo"), "foo"); +assertEq(Object.seal(true), true); +if (typeof Symbol === "function") { + assertEq(Object.seal(Symbol.for("foo")), Symbol.for("foo")); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/setPrototypeOf-cross-realm-cycle.js b/js/src/tests/non262/object/setPrototypeOf-cross-realm-cycle.js new file mode 100644 index 0000000000..e2efe010eb --- /dev/null +++ b/js/src/tests/non262/object/setPrototypeOf-cross-realm-cycle.js @@ -0,0 +1,11 @@ +// The cycle check in 9.1.2 [[SetPrototypeOf]] prevents cross-realm cycles +// involving only ordinary objects. + +var gw = newGlobal(); + +var obj = {}; +var w = gw.Object.create(obj); +assertThrowsInstanceOf(() => Object.setPrototypeOf(obj, w), TypeError); +assertThrowsInstanceOf(() => gw.Object.setPrototypeOf(obj, w), gw.TypeError); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/object/setPrototypeOf-cycle.js b/js/src/tests/non262/object/setPrototypeOf-cycle.js new file mode 100644 index 0000000000..a8b5aa75cd --- /dev/null +++ b/js/src/tests/non262/object/setPrototypeOf-cycle.js @@ -0,0 +1,16 @@ +// The cycle check in 9.1.2 [[SetPrototypeOf]] does not walk proxies. +// Therefore it's very easy to create prototype chain cycles involving proxies, +// and the spec requires us to accept this. + +var t = {}; +var p = new Proxy(t, {}); +Object.setPrototypeOf(t, p); // 🙈 + +// Actually doing anything that searches this object's prototype chain +// technically should not terminate. We instead throw "too much recursion". +for (var obj of [t, p]) { + assertThrowsInstanceOf(() => "x" in obj, InternalError); + assertThrowsInstanceOf(() => obj.x, InternalError); + assertThrowsInstanceOf(() => { obj.x = 1; }, InternalError); +} +reportCompare(0, 0); diff --git a/js/src/tests/non262/object/setPrototypeOf-same-value.js b/js/src/tests/non262/object/setPrototypeOf-same-value.js new file mode 100644 index 0000000000..3375509462 --- /dev/null +++ b/js/src/tests/non262/object/setPrototypeOf-same-value.js @@ -0,0 +1,11 @@ +// Setting a "new" prototype to the current [[Prototype]] value should never fail + +var x = {}, t = Object.create(x); +Object.preventExtensions(t); +// Should not fail, because it is the same [[Prototype]] value +Object.setPrototypeOf(t, x); + +// Object.prototype's [[Prototype]] is immutable, make sure we can still set null +Object.setPrototypeOf(Object.prototype, null); + +reportCompare(true, true); diff --git a/js/src/tests/non262/object/shell.js b/js/src/tests/non262/object/shell.js new file mode 100644 index 0000000000..49d875f264 --- /dev/null +++ b/js/src/tests/non262/object/shell.js @@ -0,0 +1,62 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 14 Mar 2001 + * + * SUMMARY: Utility functions for testing objects - + * + * Suppose obj is an instance of a native type, e.g. Number. + * Then obj.toString() invokes Number.prototype.toString(). + * We would also like to access Object.prototype.toString(). + * + * The difference is this: suppose obj = new Number(7). + * Invoking Number.prototype.toString() on this just returns 7. + * Object.prototype.toString() on this returns '[object Number]'. + * + * The getJSClass() function returns 'Number', the [[Class]] property of obj. + * See ECMA-262 Edition 3, 13-Oct-1999, Section 8.6.2 + */ +//----------------------------------------------------------------------------- + + +var cnNoObject = 'Unexpected Error!!! Parameter to this function must be an object'; +var cnNoClass = 'Unexpected Error!!! Cannot find Class property'; +var cnObjectToString = Object.prototype.toString; +var GLOBAL = 'global'; + + +// checks that it's safe to call findType() +function getJSClass(obj) +{ + if (isObject(obj)) + return findClass(findType(obj)); + return cnNoObject; +} + + +function findType(obj) +{ + return cnObjectToString.apply(obj); +} + + +// given '[object Number]', return 'Number' +function findClass(sType) +{ + var re = /^\[.*\s+(\w+)\s*\]$/; + var a = sType.match(re); + + if (a && a[1]) + return a[1]; + return cnNoClass; +} + + +function isObject(obj) +{ + return obj instanceof Object; +} + diff --git a/js/src/tests/non262/object/toLocaleString-01.js b/js/src/tests/non262/object/toLocaleString-01.js new file mode 100644 index 0000000000..3fa2acc746 --- /dev/null +++ b/js/src/tests/non262/object/toLocaleString-01.js @@ -0,0 +1,13 @@ +"use strict"; + +Object.defineProperty(String.prototype, "toString", { + get() { + assertEq(typeof this, "string"); + + return function() { return typeof this; }; + } +}) +assertEq(Object.prototype.toLocaleString.call("test"), "string"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/toLocaleString.js b/js/src/tests/non262/object/toLocaleString.js new file mode 100644 index 0000000000..e42c4a09e5 --- /dev/null +++ b/js/src/tests/non262/object/toLocaleString.js @@ -0,0 +1,102 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = 'toLocaleString.js'; +var BUGNUMBER = 653789; +var summary = "Object.prototype.toLocaleString"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function expectThrowTypeError(fun) +{ + try + { + var r = fun(); + throw "didn't throw TypeError, returned " + r; + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "didn't throw TypeError, got: " + e); + } +} + +var toLocaleString = Object.prototype.toLocaleString; + +/* + * 1. Let O be the result of calling ToObject passing the this value as the + * argument. + */ +expectThrowTypeError(function() { toLocaleString.call(null); }); +expectThrowTypeError(function() { toLocaleString.call(undefined); }); +expectThrowTypeError(function() { toLocaleString.apply(null); }); +expectThrowTypeError(function() { toLocaleString.apply(undefined); }); + + +/* + * 2. Let toString be the result of calling the [[Get]] internal method of O + * passing "toString" as the argument. + */ +try +{ + toLocaleString.call({ get toString() { throw 17; } }); + throw new Error("didn't throw"); +} +catch (e) +{ + assertEq(e, 17); +} + + +/* 3. If IsCallable(toString) is false, throw a TypeError exception. */ +expectThrowTypeError(function() { toLocaleString.call({ toString: 12 }); }); +expectThrowTypeError(function() { toLocaleString.call({ toString: 0.3423423452352e9 }); }); +expectThrowTypeError(function() { toLocaleString.call({ toString: undefined }); }); +expectThrowTypeError(function() { toLocaleString.call({ toString: false }); }); +expectThrowTypeError(function() { toLocaleString.call({ toString: [] }); }); +expectThrowTypeError(function() { toLocaleString.call({ toString: {} }); }); +expectThrowTypeError(function() { toLocaleString.call({ toString: new String }); }); +expectThrowTypeError(function() { toLocaleString.call({ toString: new Number(7.7) }); }); +expectThrowTypeError(function() { toLocaleString.call({ toString: new Boolean(true) }); }); +expectThrowTypeError(function() { toLocaleString.call({ toString: JSON }); }); + +expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: 12 }); }); +expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: 0.3423423452352e9 }); }); +expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: undefined }); }); +expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: false }); }); +expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: [] }); }); +expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: {} }); }); +expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: new String }); }); +expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: new Number(7.7) }); }); +expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: new Boolean(true) }); }); +expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: JSON }); }); + + +/* + * 4. Return the result of calling the [[Call]] internal method of toString + * passing O as the this value and no arguments. + */ +assertEq(toLocaleString.call({ get toString() { return function() { return "foo"; } } }), + "foo"); + +var obj = { toString: function() { assertEq(this, obj); assertEq(arguments.length, 0); return 5; } }; +assertEq(toLocaleString.call(obj), 5); + +assertEq(toLocaleString.call({ toString: function() { return obj; } }), obj); + +assertEq(toLocaleString.call({ toString: function() { return obj; }, + valueOf: function() { return "abc"; } }), + obj); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/toPrimitive-callers.js b/js/src/tests/non262/object/toPrimitive-callers.js new file mode 100644 index 0000000000..ffeef2225c --- /dev/null +++ b/js/src/tests/non262/object/toPrimitive-callers.js @@ -0,0 +1,57 @@ +// Check all the algorithms that call ToPrimitive. Confirm that they're passing +// the correct hint, per spec. + +var STRING = "xyzzy"; +var NUMBER = 42; + +function assertCallsToPrimitive(f, expectedHint, expectedResult) { + var hint = undefined; + var testObj = { + [Symbol.toPrimitive](h) { + assertEq(hint, undefined); + hint = h; + return h === "number" ? NUMBER : STRING; + } + }; + var result = f(testObj); + assertEq(hint, expectedHint, String(f)); + assertEq(result, expectedResult, String(f)); +} + +// ToNumber +assertCallsToPrimitive(Number, "number", NUMBER); + +// ToString +assertCallsToPrimitive(String, "string", STRING); + +// ToPropertyKey +var obj = {[STRING]: "pass"}; +assertCallsToPrimitive(key => obj[key], "string", "pass"); + +// Abstract Relational Comparison +assertCallsToPrimitive(x => x >= 42, "number", true); +assertCallsToPrimitive(x => x > "42", "number", false); + +// Abstract Equality Comparison +assertCallsToPrimitive(x => x != STRING, "default", false); +assertCallsToPrimitive(x => STRING == x, "default", true); +assertCallsToPrimitive(x => x == NUMBER, "default", false); +assertCallsToPrimitive(x => NUMBER != x, "default", true); + +// Addition +assertCallsToPrimitive(x => 1 + x, "default", "1" + STRING); +assertCallsToPrimitive(x => "" + x, "default", STRING); + +// Date constructor +assertCallsToPrimitive(x => (new Date(x)).valueOf(), "default", Number(STRING)); + +// Date.prototype.toJSON +var expected = "a suffusion of yellow"; +function testJSON(x) { + x.toJSON = Date.prototype.toJSON; + x.toISOString = function () { return expected; }; + return JSON.stringify(x); +} +assertCallsToPrimitive(testJSON, "number", JSON.stringify(expected)); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/object/toPrimitive.js b/js/src/tests/non262/object/toPrimitive.js new file mode 100644 index 0000000000..59ed6ac475 --- /dev/null +++ b/js/src/tests/non262/object/toPrimitive.js @@ -0,0 +1,101 @@ +// ES6 7.1.1 ToPrimitive(input [, PreferredType]) specifies a new extension +// point in the language. Objects can override the behavior of ToPrimitive +// somewhat by supporting the method obj[@@toPrimitive](hint). +// +// (Rationale: ES5 had a [[DefaultValue]] internal method, overridden only by +// Date objects. The change in ES6 is to make [[DefaultValue]] a plain old +// method. This allowed ES6 to eliminate the [[DefaultValue]] internal method, +// simplifying the meta-object protocol and thus proxies.) + +// obj[Symbol.toPrimitive]() is called whenever the ToPrimitive algorithm is invoked. +var expectedThis, expectedHint; +var obj = { + [Symbol.toPrimitive](hint, ...rest) { + assertEq(this, expectedThis); + assertEq(hint, expectedHint); + assertEq(rest.length, 0); + return 2015; + } +}; +expectedThis = obj; +expectedHint = "string"; +assertEq(String(obj), "2015"); +expectedHint = "number"; +assertEq(Number(obj), 2015); + +// It is called even through proxies. +var proxy = new Proxy(obj, {}); +expectedThis = proxy; +expectedHint = "default"; +assertEq("ES" + proxy, "ES2015"); + +// It is called even through additional proxies and the prototype chain. +proxy = new Proxy(Object.create(proxy), {}); +expectedThis = proxy; +expectedHint = "default"; +assertEq("ES" + (proxy + 1), "ES2016"); + +// It is not called if the operand is already a primitive. +var ok = true; +for (var constructor of [Boolean, Number, String, Symbol]) { + constructor.prototype[Symbol.toPrimitive] = function () { + ok = false; + throw "FAIL"; + }; +} +assertEq(Number(true), 1); +assertEq(Number(77.7), 77.7); +assertEq(Number("123"), 123); +assertThrowsInstanceOf(() => Number(Symbol.iterator), TypeError); +assertEq(String(true), "true"); +assertEq(String(77.7), "77.7"); +assertEq(String("123"), "123"); +assertEq(String(Symbol.iterator), "Symbol(Symbol.iterator)"); +assertEq(ok, true); + +// Converting a primitive symbol to another primitive type throws even if you +// delete the @@toPrimitive method from Symbol.prototype. +delete Symbol.prototype[Symbol.toPrimitive]; +var sym = Symbol("ok"); +assertThrowsInstanceOf(() => `${sym}`, TypeError); +assertThrowsInstanceOf(() => Number(sym), TypeError); +assertThrowsInstanceOf(() => "" + sym, TypeError); + +// However, having deleted that method, converting a Symbol wrapper object does +// work: it calls Symbol.prototype.toString(). +obj = Object(sym); +assertEq(String(obj), "Symbol(ok)"); +assertEq(`${obj}`, "Symbol(ok)"); + +// Deleting valueOf as well makes numeric conversion also call toString(). +delete Symbol.prototype.valueOf; +delete Object.prototype.valueOf; +assertEq(Number(obj), NaN); +Symbol.prototype.toString = function () { return "2060"; }; +assertEq(Number(obj), 2060); + +// Deleting Date.prototype[Symbol.toPrimitive] changes the result of addition +// involving Date objects. +var d = new Date; +assertEq(0 + d, 0 + d.toString()); +delete Date.prototype[Symbol.toPrimitive]; +assertEq(0 + d, 0 + d.valueOf()); + +// If @@toPrimitive, .toString, and .valueOf are all missing, we get a +// particular sequence of property accesses, followed by a TypeError exception. +var log = []; +function doGet(target, propertyName, receiver) { + log.push(propertyName); +} +var handler = new Proxy({}, { + get(target, trapName, receiver) { + if (trapName !== "get") + throw `FAIL: system tried to access handler method: ${String(trapName)}`; + return doGet; + } +}); +proxy = new Proxy(Object.create(null), handler); +assertThrowsInstanceOf(() => proxy == 0, TypeError); +assertDeepEq(log, [Symbol.toPrimitive, "valueOf", "toString"]); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/object/vacuous-accessor-unqualified-name.js b/js/src/tests/non262/object/vacuous-accessor-unqualified-name.js new file mode 100644 index 0000000000..768b1050b9 --- /dev/null +++ b/js/src/tests/non262/object/vacuous-accessor-unqualified-name.js @@ -0,0 +1,26 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = 'vacuous-accessor-unqualified-name.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 560216; +var summary = + "Using a name referring to a { get: undefined, set: undefined } descriptor " + + "shouldn't assert"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +Object.defineProperty(this, "x", { set: undefined, configurable: true }); +x; + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/object/values-entries-indexed.js b/js/src/tests/non262/object/values-entries-indexed.js new file mode 100644 index 0000000000..f4d801c272 --- /dev/null +++ b/js/src/tests/non262/object/values-entries-indexed.js @@ -0,0 +1,71 @@ +function assertSameEntries(actual, expected) { + assertEq(actual.length, expected.length); + for (let i = 0; i < expected.length; ++i) + assertEqArray(actual[i], expected[i]); +} + +// Test Object.keys/values/entries on objects with indexed properties. + +// Empty dense elements, test with array and plain object. +{ + let array = []; + assertEqArray(Object.keys(array), []); + assertEqArray(Object.values(array), []); + assertSameEntries(Object.entries(array), []); + + let object = {}; + assertEqArray(Object.keys(object), []); + assertEqArray(Object.values(object), []); + assertSameEntries(Object.entries(object), []); +} + +// Dense elements only, test with array and plain object. +{ + let array = [1, 2, 3]; + assertEqArray(Object.keys(array), ["0", "1", "2"]); + assertEqArray(Object.values(array), [1, 2, 3]); + assertSameEntries(Object.entries(array), [["0", 1], ["1", 2], ["2", 3]]); + + let object = {0: 4, 1: 5, 2: 6}; + assertEqArray(Object.keys(object), ["0", "1", "2"]); + assertEqArray(Object.values(object), [4, 5, 6]); + assertSameEntries(Object.entries(object), [["0", 4], ["1", 5], ["2", 6]]); +} + +// Extra indexed properties only, test with array and plain object. +{ + let array = []; + Object.defineProperty(array, 0, {configurable: true, enumerable: true, value: 123}); + + assertEqArray(Object.keys(array), ["0"]); + assertEqArray(Object.values(array), [123]); + assertSameEntries(Object.entries(array), [["0", 123]]); + + let object = []; + Object.defineProperty(object, 0, {configurable: true, enumerable: true, value: 123}); + + assertEqArray(Object.keys(object), ["0"]); + assertEqArray(Object.values(object), [123]); + assertSameEntries(Object.entries(object), [["0", 123]]); +} + +// Dense and extra indexed properties, test with array and plain object. +{ + let array = [1, 2, 3]; + Object.defineProperty(array, 0, {writable: false}); + + assertEqArray(Object.keys(array), ["0", "1", "2"]); + assertEqArray(Object.values(array), [1, 2, 3]); + assertSameEntries(Object.entries(array), [["0", 1], ["1", 2], ["2", 3]]); + + let object = {0: 4, 1: 5, 2: 6}; + Object.defineProperty(object, 0, {writable: false}); + + assertEqArray(Object.keys(object), ["0", "1", "2"]); + assertEqArray(Object.values(object), [4, 5, 6]); + assertSameEntries(Object.entries(object), [["0", 4], ["1", 5], ["2", 6]]); +} + + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/values-entries-lazy-props.js b/js/src/tests/non262/object/values-entries-lazy-props.js new file mode 100644 index 0000000000..0631c048af --- /dev/null +++ b/js/src/tests/non262/object/values-entries-lazy-props.js @@ -0,0 +1,93 @@ +// Return new objects for each test case. +function makeTestCases() { + // Call the resolve hook for arguments/string objects. + const resolveIndex = object => 0 in object; + + // Calls the resolve hook for functions. + const resolveFunction = object => "length" in object; + + const expected = array => ({ + keys: Object.keys(array), + values: Object.values(array), + entries: Object.entries(array), + }); + + return [ + // Mapped arguments objects. + { + object: function(){ return arguments; }(), + resolve: resolveIndex, + ...expected([]), + }, + { + object: function(x){ return arguments; }(1), + resolve: resolveIndex, + ...expected([1]), + }, + { + object: function(x, y, z){ return arguments; }(1, 2, 3), + resolve: resolveIndex, + ...expected([1, 2, 3]), + }, + + // Unmapped arguments objects. + { + object: function(){ "use strict"; return arguments; }(), + resolve: resolveIndex, + ...expected([]), + }, + { + object: function(x){ "use strict"; return arguments; }(1), + resolve: resolveIndex, + ...expected([1]), + }, + { + object: function(x, y, z){ "use strict"; return arguments; }(1, 2, 3), + resolve: resolveIndex, + ...expected([1, 2, 3]), + }, + + // String objects. + { object: new String(""), resolve: resolveIndex, ...expected([]), }, + { object: new String("a"), resolve: resolveIndex, ...expected(["a"]), }, + { object: new String("abc"), resolve: resolveIndex, ...expected(["a","b","c"]), }, + + // Function objects. + { object: function(){}, resolve: resolveFunction, ...expected([]), }, + ]; +} + +var assertWith = { + keys: assertEqArray, + values: assertEqArray, + entries(actual, expected) { + assertEq(actual.length, expected.length); + for (let i = 0; i < expected.length; ++i) + assertEqArray(actual[i], expected[i]); + } +}; + +// Test Object.keys/values/entries on objects with enumerate/resolve hooks. + +for (let method of ["keys", "values", "entries"]) { + let assert = assertWith[method]; + + // Call each method twice to test the case when + // - the enumerate hook wasn't yet called, + // - the enumerate hook was already called. + for (let {object, [method]: expected} of makeTestCases()) { + assert(Object[method](object), expected); + assert(Object[method](object), expected); + } + + // Test the case when enumerate wasn't yet called, but a property was already resolved. + for (let {object, resolve, [method]: expected} of makeTestCases()) { + resolve(object); // Call the resolve hook. + + assert(Object[method](object), expected); + assert(Object[method](object), expected); + } +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/values-entries-typedarray.js b/js/src/tests/non262/object/values-entries-typedarray.js new file mode 100644 index 0000000000..b0ac5a51bb --- /dev/null +++ b/js/src/tests/non262/object/values-entries-typedarray.js @@ -0,0 +1,53 @@ +function assertSameEntries(actual, expected) { + assertEq(actual.length, expected.length); + for (let i = 0; i < expected.length; ++i) + assertEqArray(actual[i], expected[i]); +} + +function throwsTypeError(fn) { + try { + fn(); + } catch (e) { + assertEq(e instanceof TypeError, true); + return true; + } + return false; +} + +// Non-standard: Accessing elements of detached array buffers should throw, but +// this is currently not implemented. +const ACCESS_ON_DETACHED_ARRAY_BUFFER_THROWS = (() => { + let ta = new Int32Array(10); + detachArrayBuffer(ta.buffer); + let throws = throwsTypeError(() => ta[0]); + // Ensure [[Get]] and [[GetOwnProperty]] return consistent results. + assertEq(throwsTypeError(() => Object.getOwnPropertyDescriptor(ta, 0)), throws); + return throws; +})(); + +function maybeThrowOnDetached(fn, returnValue) { + if (ACCESS_ON_DETACHED_ARRAY_BUFFER_THROWS) { + assertThrowsInstanceOf(fn, TypeError); + return returnValue; + } + return fn(); +} + +// Ensure Object.keys/values/entries work correctly on typed arrays. +for (let len of [0, 1, 10]) { + let array = new Array(len).fill(1); + let ta = new Int32Array(array); + + assertEqArray(Object.keys(ta), Object.keys(array)); + assertEqArray(Object.values(ta), Object.values(array)); + assertSameEntries(Object.entries(ta), Object.entries(array)); + + detachArrayBuffer(ta.buffer); + + assertEqArray(maybeThrowOnDetached(() => Object.keys(ta), []), []); + assertEqArray(maybeThrowOnDetached(() => Object.values(ta), []), []); + assertSameEntries(maybeThrowOnDetached(() => Object.entries(ta), []), []); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/object/values.js b/js/src/tests/non262/object/values.js new file mode 100644 index 0000000000..189bea7605 --- /dev/null +++ b/js/src/tests/non262/object/values.js @@ -0,0 +1,94 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +if ("values" in Object) { + assertEq(Object.values.length, 1); + + var o, values; + + o = { a: 3, b: 2 }; + values = Object.values(o); + assertDeepEq(values, [3, 2]); + + o = { get a() { return 17; }, b: 2 }; + values = Object.values(o), + assertDeepEq(values, [17, 2]); + + o = { __iterator__: function() { throw new Error("non-standard __iterator__ called?"); } }; + values = Object.values(o); + assertDeepEq(values, [o.__iterator__]); + + o = { a: 1, b: 2 }; + delete o.a; + o.a = 3; + values = Object.values(o); + assertDeepEq(values, [2, 3]); + + o = [0, 1, 2]; + values = Object.values(o); + assertDeepEq(values, [0, 1, 2]); + + o = /./.exec("abc"); + values = Object.values(o); + assertDeepEq(values, ["a", 0, "abc", undefined]); + + o = { a: 1, b: 2, c: 3 }; + delete o.b; + o.b = 5; + values = Object.values(o); + assertDeepEq(values, [1, 3, 5]); + + function f() { } + f.prototype.p = 1; + o = new f(); + o.g = 1; + values = Object.values(o); + assertDeepEq(values, [1]); + + var o = {get a() {delete this.b; return 1}, b: 2, c: 3}; + values = Object.values(o); + assertDeepEq(values, [1, 3]); + + assertThrowsInstanceOf(() => Object.values(), TypeError); + assertThrowsInstanceOf(() => Object.values(undefined), TypeError); + assertThrowsInstanceOf(() => Object.values(null), TypeError); + + assertDeepEq(Object.values(1), []); + assertDeepEq(Object.values(true), []); + if (typeof Symbol === "function") + assertDeepEq(Object.values(Symbol("foo")), []); + + assertDeepEq(Object.values("foo"), ["f", "o", "o"]); + + values = Object.values({ + get a(){ + Object.defineProperty(this, "b", {enumerable: false}); + return "A"; + }, + b: "B" + }); + assertDeepEq(values, ["A"]); + + let ownKeysCallCount = 0; + let getOwnPropertyDescriptorCalls = []; + let target = { a: 1, b: 2, c: 3 }; + o = new Proxy(target, { + ownKeys() { + ownKeysCallCount++; + return ["c", "a"]; + }, + getOwnPropertyDescriptor(target, key) { + getOwnPropertyDescriptorCalls.push(key); + return Object.getOwnPropertyDescriptor(target, key); + } + }); + values = Object.values(o); + assertEq(ownKeysCallCount, 1); + assertDeepEq(values, [3, 1]); + assertDeepEq(getOwnPropertyDescriptorCalls, ["c", "a"]); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); |