diff options
Diffstat (limited to 'js/src/tests/ecma_5/Array')
28 files changed, 1361 insertions, 0 deletions
diff --git a/js/src/tests/ecma_5/Array/browser.js b/js/src/tests/ecma_5/Array/browser.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/js/src/tests/ecma_5/Array/browser.js diff --git a/js/src/tests/ecma_5/Array/frozen-dense-array.js b/js/src/tests/ecma_5/Array/frozen-dense-array.js new file mode 100644 index 000000000..9db63036f --- /dev/null +++ b/js/src/tests/ecma_5/Array/frozen-dense-array.js @@ -0,0 +1,61 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Author: Emilio Cobos Álvarez <ecoal95@gmail.com> + */ +var BUGNUMBER = 1310744; +var summary = "Dense array properties shouldn't be modified when they're frozen"; + +print(BUGNUMBER + ": " + summary); + +var a = Object.freeze([4, 5, 1]); + +function assertArrayIsExpected() { + assertEq(a.length, 3); + assertEq(a[0], 4); + assertEq(a[1], 5); + assertEq(a[2], 1); +} + +assertThrowsInstanceOf(() => a.reverse(), TypeError); +assertThrowsInstanceOf(() => a.shift(), TypeError); +assertThrowsInstanceOf(() => a.unshift(0), TypeError); +assertThrowsInstanceOf(() => a.sort(function() {}), TypeError); +assertThrowsInstanceOf(() => a.pop(), TypeError); +assertThrowsInstanceOf(() => a.fill(0), TypeError); +assertThrowsInstanceOf(() => a.splice(0, 1, 1), TypeError); +assertThrowsInstanceOf(() => a.push("foo"), TypeError); +assertThrowsInstanceOf(() => { "use strict"; a.length = 5; }, TypeError); +assertThrowsInstanceOf(() => { "use strict"; a[2] = "foo"; }, TypeError); +assertThrowsInstanceOf(() => { "use strict"; delete a[0]; }, TypeError); +assertThrowsInstanceOf(() => a.splice(Math.a), TypeError); + +// Shouldn't throw, since this is not strict mode, but shouldn't change the +// value of the property. +a.length = 5; +a[2] = "foo"; +assertEq(delete a[0], false); + +assertArrayIsExpected(); + +var watchpointCalled = false; +// NOTE: Be careful with the position of this test, since this sparsifies the +// elements and you might not test what you think you're testing otherwise. +a.watch(2, function(prop, oldValue, newValue) { + watchpointCalled = true; + assertEq(prop, 2); + assertEq(oldValue, 1); + assertEq(newValue, "foo"); +}); + +assertArrayIsExpected(); + +a.length = 5; +a[2] = "foo"; +assertEq(watchpointCalled, true); +assertEq(delete a[0], false); + +assertArrayIsExpected(); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_5/Array/frozen-dict-mode-length.js b/js/src/tests/ecma_5/Array/frozen-dict-mode-length.js new file mode 100644 index 000000000..e519b5892 --- /dev/null +++ b/js/src/tests/ecma_5/Array/frozen-dict-mode-length.js @@ -0,0 +1,18 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Author: Emilio Cobos Álvarez <ecoal95@gmail.com> + */ +var BUGNUMBER = 1312948; +var summary = "Freezing a dictionary mode object with a length property should make Object.isFrozen report true"; + +print(BUGNUMBER + ": " + summary); + +/* Convert to dictionary mode */ +delete Array.prototype.slice; + +Object.freeze(Array.prototype); +assertEq(Object.isFrozen(Array.prototype), true); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_5/Array/index-with-null-character.js b/js/src/tests/ecma_5/Array/index-with-null-character.js new file mode 100644 index 000000000..51e71bc8a --- /dev/null +++ b/js/src/tests/ecma_5/Array/index-with-null-character.js @@ -0,0 +1,18 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var testArray = [1, 2, 3] +assertEq(testArray['0' + '\0'], undefined); +assertEq(testArray['1' + '\0' + 'aaaa'], undefined) +assertEq(testArray['\0' + '2'], undefined); +assertEq(testArray['\0' + ' 2'], undefined); + +testArray['\0'] = 'hello'; +testArray[' \0'] = 'world'; +assertEq(testArray['\0'], 'hello'); +assertEq(testArray[' \0'], 'world'); + +if (typeof reportCompare == 'function') + reportCompare(true, true); diff --git a/js/src/tests/ecma_5/Array/join-01.js b/js/src/tests/ecma_5/Array/join-01.js new file mode 100644 index 000000000..3cc6cccd0 --- /dev/null +++ b/js/src/tests/ecma_5/Array/join-01.js @@ -0,0 +1,83 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +print("ES5: Array.prototype.join"); + +/************** + * BEGIN TEST * + **************/ + +var count; +var stringifyCounter = { toString: function() { count++; return "obj"; } }; + +var arr = [1, 2, 3, 4, 5]; +assertEq(arr.join(), "1,2,3,4,5"); +assertEq(arr.join(","), "1,2,3,4,5"); +assertEq(arr.join(undefined), "1,2,3,4,5"); +assertEq(arr.join(4), "142434445"); +assertEq(arr.join(""), "12345"); + +count = 0; +assertEq(arr.join(stringifyCounter), "1obj2obj3obj4obj5"); +assertEq(count, 1); + +var holey = [1, 2, , 4, 5]; +assertEq(holey.join(), "1,2,,4,5"); +assertEq(holey.join(","), "1,2,,4,5"); +assertEq(holey.join(undefined), "1,2,,4,5"); +assertEq(holey.join(4), "14244445"); + +count = 0; +assertEq(holey.join(stringifyCounter), "1obj2objobj4obj5"); +assertEq(count, 1); + +var nully = [1, 2, 3, null, 5]; +assertEq(nully.join(), "1,2,3,,5"); +assertEq(nully.join(","), "1,2,3,,5"); +assertEq(nully.join(undefined), "1,2,3,,5"); +assertEq(nully.join(4), "14243445"); + +count = 0; +assertEq(nully.join(stringifyCounter), "1obj2obj3objobj5"); +assertEq(count, 1); + +var undefiney = [1, undefined, 3, 4, 5]; +assertEq(undefiney.join(), "1,,3,4,5"); +assertEq(undefiney.join(","), "1,,3,4,5"); +assertEq(undefiney.join(undefined), "1,,3,4,5"); +assertEq(undefiney.join(4), "14434445"); + +count = 0; +assertEq(undefiney.join(stringifyCounter), "1objobj3obj4obj5"); +assertEq(count, 1); + +var log = ''; +arr = {length: {valueOf: function () { log += "L"; return 2; }}, + 0: "x", 1: "z"}; +var sep = {toString: function () { log += "S"; return "y"; }}; +assertEq(Array.prototype.join.call(arr, sep), "xyz"); +assertEq(log, "LS"); + +var funky = + { + toString: function() + { + Array.prototype[1] = "chorp"; + Object.prototype[3] = "fnord"; + return "funky"; + } + }; +var trailingHoles = [0, funky, /* 2 */, /* 3 */,]; +assertEq(trailingHoles.join(""), "0funkyfnord"); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/length-01.js b/js/src/tests/ecma_5/Array/length-01.js new file mode 100644 index 000000000..4fe81e2b6 --- /dev/null +++ b/js/src/tests/ecma_5/Array/length-01.js @@ -0,0 +1,71 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 600392; +var summary = + 'Object.preventExtensions([]).length = 0 should do nothing, not throw'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + + +function testEmpty() +{ + var a = []; + assertEq(a.length, 0); + assertEq(Object.preventExtensions(a), a); + assertEq(a.length, 0); + a.length = 0; + assertEq(a.length, 0); +} +testEmpty(); + +function testEmptyStrict() +{ + "use strict"; + var a = []; + assertEq(a.length, 0); + assertEq(Object.preventExtensions(a), a); + assertEq(a.length, 0); + a.length = 0; + assertEq(a.length, 0); +} +testEmptyStrict(); + +function testNonEmpty() +{ + var a = [1, 2, 3]; + assertEq(a.length, 3); + assertEq(Object.preventExtensions(a), a); + assertEq(a.length, 3); + a.length = 0; + assertEq(a.length, 0); +} +testNonEmpty(); + +function testNonEmptyStrict() +{ + "use strict"; + var a = [1, 2, 3]; + assertEq(a.length, 3); + assertEq(Object.preventExtensions(a), a); + assertEq(a.length, 3); + a.length = 0; + assertEq(a.length, 0); +} +testNonEmptyStrict(); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Array/length-nonwritable-redefine-nop.js b/js/src/tests/ecma_5/Array/length-nonwritable-redefine-nop.js new file mode 100644 index 000000000..1d7fe32c8 --- /dev/null +++ b/js/src/tests/ecma_5/Array/length-nonwritable-redefine-nop.js @@ -0,0 +1,70 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 858381; +var summary = "No-op array length redefinition"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var arr; + +// initializedLength == capacity == length +// 6 == 6 == 6 +arr = Object.defineProperty([0, 1, 2, 3, 4, 5], "length", { writable: false }); +Object.defineProperty(arr, "length", { value: 6 }); +Object.defineProperty(arr, "length", { writable: false }); +Object.defineProperty(arr, "length", { configurable: false }); +Object.defineProperty(arr, "length", { writable: false, configurable: false }); +Object.defineProperty(arr, "length", { writable: false, value: 6 }); +Object.defineProperty(arr, "length", { configurable: false, value: 6 }); +Object.defineProperty(arr, "length", { writable: false, configurable: false, value: 6 }); + +// initializedLength == capacity < length +// 6 == 6 < 8 +arr = Object.defineProperty([0, 1, 2, 3, 4, 5], "length", { value: 8, writable: false }); +Object.defineProperty(arr, "length", { value: 8 }); +Object.defineProperty(arr, "length", { writable: false }); +Object.defineProperty(arr, "length", { configurable: false }); +Object.defineProperty(arr, "length", { writable: false, configurable: false }); +Object.defineProperty(arr, "length", { writable: false, value: 8 }); +Object.defineProperty(arr, "length", { configurable: false, value: 8 }); +Object.defineProperty(arr, "length", { writable: false, configurable: false, value: 8 }); + +// initializedLength < capacity == length +// 7 < 8 == 8 +arr = Object.defineProperty([0, 1, 2, 3, 4, 5, 6, /* hole */, ], "length", + { value: 8, writable: false }); +Object.defineProperty(arr, "length", { value: 8 }); +Object.defineProperty(arr, "length", { writable: false }); +Object.defineProperty(arr, "length", { configurable: false }); +Object.defineProperty(arr, "length", { writable: false, configurable: false }); +Object.defineProperty(arr, "length", { writable: false, value: 8 }); +Object.defineProperty(arr, "length", { configurable: false, value: 8 }); +Object.defineProperty(arr, "length", { writable: false, configurable: false, value: 8 }); + +// initializedLength < capacity < length +// 3 < 6 < 8 +arr = Object.defineProperty([0, 1, 2], "length", { value: 8, writable: false }); +Object.defineProperty(arr, "length", { value: 8 }); +Object.defineProperty(arr, "length", { writable: false }); +Object.defineProperty(arr, "length", { configurable: false }); +Object.defineProperty(arr, "length", { writable: false, configurable: false }); +Object.defineProperty(arr, "length", { writable: false, value: 8 }); +Object.defineProperty(arr, "length", { configurable: false, value: 8 }); +Object.defineProperty(arr, "length", { writable: false, configurable: false, value: 8 }); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/length-set-object.js b/js/src/tests/ecma_5/Array/length-set-object.js new file mode 100644 index 000000000..bf80b592e --- /dev/null +++ b/js/src/tests/ecma_5/Array/length-set-object.js @@ -0,0 +1,68 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 657298; +var summary = 'Various quirks of setting array length properties to objects'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function invokeConversionTwice1() +{ + var count = 0; + [].length = { valueOf: function() { count++; return 1; } }; + assertEq(count, 2); +} +invokeConversionTwice1(); + +function invokeConversionTwice2() +{ + var count = 0; + [].length = { toString: function() { count++; return 1; }, valueOf: null }; + assertEq(count, 2); +} +invokeConversionTwice2(); + +function dontOverwriteError1() +{ + try + { + [].length = { valueOf: {}, toString: {} }; + throw new Error("didn't throw a TypeError"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "expected a TypeError running out of conversion options, got " + e); + } +} +dontOverwriteError1(); + +function dontOverwriteError2() +{ + try + { + [].length = { valueOf: function() { throw "error"; } }; + throw new Error("didn't throw a TypeError"); + } + catch (e) + { + assertEq(e, "error", "expected 'error' from failed conversion, got " + e); + } +} +dontOverwriteError2(); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Array/length-truncate-nonconfigurable-sparse.js b/js/src/tests/ecma_5/Array/length-truncate-nonconfigurable-sparse.js new file mode 100644 index 000000000..a51fd4089 --- /dev/null +++ b/js/src/tests/ecma_5/Array/length-truncate-nonconfigurable-sparse.js @@ -0,0 +1,110 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 858381; +var summary = + "Array length redefinition behavior with non-configurable elements"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function addDataProperty(obj, prop, value, enumerable, configurable, writable) +{ + var desc = + { enumerable: enumerable, + configurable: configurable, + writable: writable, + value: value }; + Object.defineProperty(obj, prop, desc); +} + +function nonstrict() +{ + var arr = [0, , 2, , , 5]; + + addDataProperty(arr, 31415926, "foo", true, true, true); + addDataProperty(arr, 123456789, "bar", true, true, false); + addDataProperty(arr, 8675309, "qux", false, true, true); + addDataProperty(arr, 1735039, "eit", false, true, false); + addDataProperty(arr, 987654321, "fun", false, true, false); + + // non-array indexes to spice things up + addDataProperty(arr, "foopy", "sdfsd", false, false, false); + addDataProperty(arr, 4294967296, "psych", true, false, false); + addDataProperty(arr, 4294967295, "psych", true, false, false); + + addDataProperty(arr, 27182818, "eep", false, false, false); + + // Truncate...but only as far as possible. + arr.length = 1; + + assertEq(arr.length, 27182819); + + var props = Object.getOwnPropertyNames(arr).sort(); + var expected = + ["0", "2", "5", "1735039", "8675309", "27182818", + "foopy", "4294967296", "4294967295", "length"].sort(); + + assertEq(props.length, expected.length); + for (var i = 0; i < props.length; i++) + assertEq(props[i], expected[i], "unexpected property: " + props[i]); +} +nonstrict(); + +function strict() +{ + "use strict"; + + var arr = [0, , 2, , , 5]; + + addDataProperty(arr, 31415926, "foo", true, true, true); + addDataProperty(arr, 123456789, "bar", true, true, false); + addDataProperty(arr, 8675309, "qux", false, true, true); + addDataProperty(arr, 1735039, "eit", false, true, false); + addDataProperty(arr, 987654321, "fun", false, true, false); + + // non-array indexes to spice things up + addDataProperty(arr, "foopy", "sdfsd", false, false, false); + addDataProperty(arr, 4294967296, "psych", true, false, false); + addDataProperty(arr, 4294967295, "psych", true, false, false); + + addDataProperty(arr, 27182818, "eep", false, false, false); + + try + { + arr.length = 1; + throw new Error("didn't throw?!"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "non-configurable property should trigger TypeError, got " + e); + } + + assertEq(arr.length, 27182819); + + var props = Object.getOwnPropertyNames(arr).sort(); + var expected = + ["0", "2", "5", "1735039", "8675309", "27182818", + "foopy", "4294967296", "4294967295", "length"].sort(); + + assertEq(props.length, expected.length); + for (var i = 0; i < props.length; i++) + assertEq(props[i], expected[i], "unexpected property: " + props[i]); +} +strict(); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/length-truncate-nonconfigurable.js b/js/src/tests/ecma_5/Array/length-truncate-nonconfigurable.js new file mode 100644 index 000000000..e9a66fe0a --- /dev/null +++ b/js/src/tests/ecma_5/Array/length-truncate-nonconfigurable.js @@ -0,0 +1,48 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 858381; +var summary = + "Array length redefinition behavior with non-configurable elements"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var arr = [0, 1, 2]; +Object.defineProperty(arr, 1, { configurable: false }); + +try +{ + Object.defineProperty(arr, "length", { value: 0, writable: false }); +} +catch (e) +{ + assertEq(e instanceof TypeError, true, + "must throw TypeError when array truncation would have to remove " + + "non-configurable elements"); +} + +assertEq(arr.length, 2, "length is highest remaining index plus one"); + +var desc = Object.getOwnPropertyDescriptor(arr, "length"); +assertEq(desc !== undefined, true); + +assertEq(desc.value, 2); +assertEq(desc.writable, false); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, false); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/length-truncate-with-indexed.js b/js/src/tests/ecma_5/Array/length-truncate-with-indexed.js new file mode 100644 index 000000000..9e4da812a --- /dev/null +++ b/js/src/tests/ecma_5/Array/length-truncate-with-indexed.js @@ -0,0 +1,101 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 858381; +var summary = + "Array length setting/truncating with non-dense, indexed elements"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function testTruncateDenseAndSparse() +{ + var arr; + + // initialized length 16, capacity same + arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + + // plus a sparse element + arr[987654321] = 987654321; + + // lop off the sparse element and half the dense elements, shrink capacity + arr.length = 8; + + assertEq(987654321 in arr, false); + assertEq(arr[987654321], undefined); + assertEq(arr.length, 8); +} +testTruncateDenseAndSparse(); + +function testTruncateSparse() +{ + // initialized length 8, capacity same + var arr = [0, 1, 2, 3, 4, 5, 6, 7]; + + // plus a sparse element + arr[987654321] = 987654321; + + // lop off the sparse element, leave initialized length/capacity unchanged + arr.length = 8; + + assertEq(987654321 in arr, false); + assertEq(arr[987654321], undefined); + assertEq(arr.length, 8); +} +testTruncateSparse(); + +function testTruncateDenseAndSparseShrinkCapacity() +{ + // initialized length 11, capacity...somewhat larger, likely 16 + var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + // plus a sparse element + arr[987654321] = 987654321; + + // lop off the sparse element, reduce initialized length, reduce capacity + arr.length = 8; + + assertEq(987654321 in arr, false); + assertEq(arr[987654321], undefined); + assertEq(arr.length, 8); +} +testTruncateDenseAndSparseShrinkCapacity(); + +function testTruncateSparseShrinkCapacity() +{ + // initialized length 8, capacity same + var arr = [0, 1, 2, 3, 4, 5, 6, 7]; + + // capacity expands to accommodate, initialized length remains same (not equal + // to capacity or length) + arr[15] = 15; + + // now no elements past initialized length + delete arr[15]; + + // ...except a sparse element + arr[987654321] = 987654321; + + // trims sparse element, doesn't change initialized length, shrinks capacity + arr.length = 8; + + assertEq(987654321 in arr, false); + assertEq(arr[987654321], undefined); + assertEq(arr.length, 8); +} +testTruncateSparseShrinkCapacity(); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/pop-empty-nonwritable.js b/js/src/tests/ecma_5/Array/pop-empty-nonwritable.js new file mode 100644 index 000000000..f42ca98f5 --- /dev/null +++ b/js/src/tests/ecma_5/Array/pop-empty-nonwritable.js @@ -0,0 +1,32 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 858381; +var summary = 'Object.freeze([]).pop() must throw a TypeError'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +try +{ + Object.freeze([]).pop(); + throw new Error("didn't throw"); +} +catch (e) +{ + assertEq(e instanceof TypeError, true, + "should have thrown TypeError, instead got: " + e); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/pop-nonarray-higher-elements.js b/js/src/tests/ecma_5/Array/pop-nonarray-higher-elements.js new file mode 100644 index 000000000..052eb4230 --- /dev/null +++ b/js/src/tests/ecma_5/Array/pop-nonarray-higher-elements.js @@ -0,0 +1,91 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 909602; +var summary = + "Array.prototype.pop shouldn't touch elements greater than length on " + + "non-arrays"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function doTest(obj, index) +{ + // print("testing " + JSON.stringify(obj) + " with index " + index); + assertEq(Array.prototype.pop.call(obj), undefined); + assertEq(index in obj, true); + assertEq(obj[index], 42); +} + +// not-super-much-later element + +// non-zero length +function testPop1() +{ + var obj = { length: 2, 3: 42 }; + doTest(obj, 3); +} +for (var i = 0; i < 50; i++) + testPop1(); + +// zero length +function testPop2() +{ + var obj = { length: 0, 3: 42 }; + doTest(obj, 3); +} +for (var i = 0; i < 50; i++) + testPop2(); + +// much-later (but dense) element + +// non-zero length +function testPop3() +{ + var obj = { length: 2, 55: 42 }; + doTest(obj, 55); +} +for (var i = 0; i < 50; i++) + testPop3(); + +// zero length +function testPop4() +{ + var obj = { length: 0, 55: 42 }; + doTest(obj, 55); +} +for (var i = 0; i < 50; i++) + testPop4(); + +// much much much later (sparse) element + +// non-zero length +function testPop5() +{ + var obj = { length: 2, 65530: 42 }; + doTest(obj, 65530); +} +for (var i = 0; i < 50; i++) + testPop5(); + +// zero length +function testPop6() +{ + var obj = { length: 0, 65530: 42 }; + doTest(obj, 65530); +} +for (var i = 0; i < 50; i++) + testPop6(); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/redefine-length-frozen-array.js b/js/src/tests/ecma_5/Array/redefine-length-frozen-array.js new file mode 100644 index 000000000..ca3b43018 --- /dev/null +++ b/js/src/tests/ecma_5/Array/redefine-length-frozen-array.js @@ -0,0 +1,26 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 866580; +var summary = "Assertion redefining length property of a frozen array"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var arr = Object.freeze([]); +Object.defineProperty(arr, "length", {}); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/redefine-length-frozen-dictionarymode-array.js b/js/src/tests/ecma_5/Array/redefine-length-frozen-dictionarymode-array.js new file mode 100644 index 000000000..bca6e0cd7 --- /dev/null +++ b/js/src/tests/ecma_5/Array/redefine-length-frozen-dictionarymode-array.js @@ -0,0 +1,36 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 880591; +var summary = + "Assertion redefining length property of a frozen dictionary-mode array"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function convertToDictionaryMode(arr) +{ + Object.defineProperty(arr, 0, { configurable: true }); + Object.defineProperty(arr, 1, { configurable: true }); + delete arr[0]; +} + +var arr = []; +convertToDictionaryMode(arr); +Object.freeze(arr); +Object.defineProperty(arr, "length", {}); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/redefine-nonwritable-length-custom-conversion-call-counts.js b/js/src/tests/ecma_5/Array/redefine-nonwritable-length-custom-conversion-call-counts.js new file mode 100644 index 000000000..b77f39675 --- /dev/null +++ b/js/src/tests/ecma_5/Array/redefine-nonwritable-length-custom-conversion-call-counts.js @@ -0,0 +1,45 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 866700; +var summary = "Assertion redefining non-writable length to a non-numeric value"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var count = 0; + +var convertible = + { + valueOf: function() + { + count++; + return 0; + } + }; + +var arr = []; +Object.defineProperty(arr, "length", { value: 0, writable: false }); + +Object.defineProperty(arr, "length", { value: convertible }); +assertEq(count, 2); + +Object.defineProperty(arr, "length", { value: convertible }); +assertEq(count, 4); + +assertEq(arr.length, 0); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/redefine-nonwritable-length-custom-conversion-throw.js b/js/src/tests/ecma_5/Array/redefine-nonwritable-length-custom-conversion-throw.js new file mode 100644 index 000000000..f3003a6bd --- /dev/null +++ b/js/src/tests/ecma_5/Array/redefine-nonwritable-length-custom-conversion-throw.js @@ -0,0 +1,58 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 866700; +var summary = "Assertion redefining non-writable length to a non-numeric value"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var count = 0; + +var convertible = + { + valueOf: function() + { + count++; + if (count > 2) + return 0; + throw new SyntaxError("fnord"); + } + }; + +var arr = []; +Object.defineProperty(arr, "length", { value: 0, writable: false }); + +try +{ + Object.defineProperty(arr, "length", + { + value: convertible, + writable: true, + configurable: true, + enumerable: true + }); + throw new Error("didn't throw"); +} +catch (e) +{ + assertEq(e instanceof SyntaxError, true, "expected SyntaxError, got " + e); +} + +assertEq(count, 1); +assertEq(arr.length, 0); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/redefine-nonwritable-length-nonnumeric.js b/js/src/tests/ecma_5/Array/redefine-nonwritable-length-nonnumeric.js new file mode 100644 index 000000000..aab9c1d5d --- /dev/null +++ b/js/src/tests/ecma_5/Array/redefine-nonwritable-length-nonnumeric.js @@ -0,0 +1,32 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 866700; +var summary = "Assertion redefining non-writable length to a non-numeric value"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var arr = []; +Object.defineProperty(arr, "length", { value: 0, writable: false }); + +// Per Array's magical behavior, the value in the descriptor gets canonicalized +// *before* SameValue comparisons occur, so this shouldn't throw. +Object.defineProperty(arr, "length", { value: '' }); + +assertEq(arr.length, 0); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/regress-599159.js b/js/src/tests/ecma_5/Array/regress-599159.js new file mode 100644 index 000000000..bd8225b52 --- /dev/null +++ b/js/src/tests/ecma_5/Array/regress-599159.js @@ -0,0 +1,10 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var b = Object.create(Array.prototype); +b.length = 12; +assertEq(b.length, 12); + +reportCompare(true,true); diff --git a/js/src/tests/ecma_5/Array/reverse-order-of-low-high-accesses.js b/js/src/tests/ecma_5/Array/reverse-order-of-low-high-accesses.js new file mode 100644 index 000000000..a9b1e80de --- /dev/null +++ b/js/src/tests/ecma_5/Array/reverse-order-of-low-high-accesses.js @@ -0,0 +1,88 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 858677; +var summary = + "[].reverse should swap elements low to high using accesses to low " + + "elements, then accesses to high elements"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var observed = []; + +// (0, 7) hits the lowerExists/upperExists case. +// (1, 6) hits the !lowerExists/upperExists case. +// (2, 5) hits the lowerExists/!upperExists case. +// (3, 4) hits the !lowerExists/!upperExists case. +// +// It'd be a good idea to have a second version of this test at some point +// where the "array" being reversed is a proxy, to detect proper ordering of +// getproperty, hasproperty, setproperty into a hole, and deleteproperty from a +// non-configurable element. But at present our Array.prototype.reverse +// implementation probably doesn't conform fully to all this (because our +// internal MOP is still slightly off), so punt for now. +var props = + { + 0: { + configurable: true, + get: function() { observed.push("index 0 get"); return "index 0 get"; }, + set: function(v) { observed.push("index 0 set: " + v); } + }, + /* 1: hole */ + 2: { + configurable: true, + get: function() { observed.push("index 2 get"); return "index 2 get"; }, + set: function(v) { observed.push("index 2 set: " + v); } + }, + /* 3: hole */ + /* 4: hole */ + /* 5: hole */ + 6: { + configurable: true, + get: function() { observed.push("index 6 get"); return "index 6 get"; }, + set: function(v) { observed.push("index 6 set: " + v); } + }, + 7: { + configurable: true, + get: function() { observed.push("index 7 get"); return "index 7 get"; }, + set: function(v) { observed.push("index 7 set: " + v); } + }, + }; + +var arr = Object.defineProperties(new Array(8), props); + +arr.reverse(); + +var expectedObserved = + ["index 0 get", "index 7 get", "index 0 set: index 7 get", "index 7 set: index 0 get", + "index 6 get", + "index 2 get" + /* nothing for 3/4 */]; +print(observed); +// Do this before the assertions below futz even more with |observed|. +assertEq(observed.length, expectedObserved.length); +for (var i = 0; i < expectedObserved.length; i++) + assertEq(observed[i], expectedObserved[i]); + +assertEq(arr[0], "index 0 get"); // no deletion, setting doesn't overwrite +assertEq(arr[1], "index 6 get"); // copies result of getter +assertEq(2 in arr, false); // deleted +assertEq(3 in arr, false); // never there +assertEq(4 in arr, false); // never there +assertEq(arr[5], "index 2 get"); // copies result of getter +assertEq(6 in arr, false); // deleted +assertEq(arr[7], "index 7 get"); // no deletion, setter doesn't overwrite + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/shell.js b/js/src/tests/ecma_5/Array/shell.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/js/src/tests/ecma_5/Array/shell.js diff --git a/js/src/tests/ecma_5/Array/sort-01.js b/js/src/tests/ecma_5/Array/sort-01.js new file mode 100644 index 000000000..da90220ae --- /dev/null +++ b/js/src/tests/ecma_5/Array/sort-01.js @@ -0,0 +1,23 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 604971; +var summary = 'array.sort compare-function gets incorrect this'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +[1, 2, 3].sort(function() { "use strict"; assertEq(this, undefined); }); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Array/sort-array-with-holes-and-undefined.js b/js/src/tests/ecma_5/Array/sort-array-with-holes-and-undefined.js new file mode 100644 index 000000000..b77c6d341 --- /dev/null +++ b/js/src/tests/ecma_5/Array/sort-array-with-holes-and-undefined.js @@ -0,0 +1,32 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 664528; +var summary = + "Sorting an array containing only holes and |undefined| should move all " + + "|undefined| to the start of the array"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var a = [, , , undefined]; +a.sort(); + +assertEq(a.hasOwnProperty(0), true); +assertEq(a[0], undefined); +assertEq(a.hasOwnProperty(1), false); +assertEq(a.hasOwnProperty(2), false); +assertEq(a.hasOwnProperty(3), false); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/splice-return-array-elements-defined-not-set.js b/js/src/tests/ecma_5/Array/splice-return-array-elements-defined-not-set.js new file mode 100644 index 000000000..2f5eca610 --- /dev/null +++ b/js/src/tests/ecma_5/Array/splice-return-array-elements-defined-not-set.js @@ -0,0 +1,46 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 668024; +var summary = + 'Array.prototype.splice should define, not set, the elements of the array ' + + 'it returns'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +Object.defineProperty(Object.prototype, 2, + { + set: function(v) + { + throw new Error("setter on Object.prototype called!"); + }, + get: function() { return "fnord"; }, + enumerable: false, + configurable: true + }); + +var arr = [0, 1, 2, 3, 4, 5]; +var removed = arr.splice(0, 6); + +assertEq(arr.length, 0); +assertEq(removed.length, 6); +assertEq(removed[0], 0); +assertEq(removed[1], 1); +assertEq(removed[2], 2); +assertEq(removed[3], 3); +assertEq(removed[4], 4); +assertEq(removed[5], 5); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/splice-suppresses-unvisited-indexes.js b/js/src/tests/ecma_5/Array/splice-suppresses-unvisited-indexes.js new file mode 100644 index 000000000..717116fa0 --- /dev/null +++ b/js/src/tests/ecma_5/Array/splice-suppresses-unvisited-indexes.js @@ -0,0 +1,61 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 668024; +var summary = + 'Array.prototype.splice, when it deletes elements, should make sure any ' + + 'deleted but not visited elements are suppressed from subsequent enumeration'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var arr = [0, 1, 2, 3, 4, 5, , 7]; + +var seen = []; +var sawOneBeforeThree = true; +for (var p in arr) +{ + if (p === "1") + { + // The order of enumeration of properties is unspecified, so technically, + // it would be kosher to enumerate "1" last, say, such that all properties + // in the array actually were enumerated, including an index which splice + // would delete. Don't flag that case as a failure. (SpiderMonkey doesn't + // do this, and neither do any of the other browser engines, but it is + // permissible behavior.) + if (seen.indexOf("3") >= 0) + { + sawOneBeforeThree = false; + break; + } + + arr.splice(2, 3); + } + + seen.push(p); +} + +if (sawOneBeforeThree) +{ + // ES5 12.6.4 states: + // + // If a property that has not yet been visited during enumeration is + // deleted, then it will not be visited. + // + // So if we haven't seen "3" by the time we see "1", the splice call above + // will delete "3", and therefore we must not see it. + assertEq(seen.indexOf("3"), -1); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/Array/toLocaleString-01.js b/js/src/tests/ecma_5/Array/toLocaleString-01.js new file mode 100644 index 000000000..458283e63 --- /dev/null +++ b/js/src/tests/ecma_5/Array/toLocaleString-01.js @@ -0,0 +1,36 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Jeff Walden <jwalden+code@mit.edu> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 562446; +var summary = 'ES5: Array.prototype.toLocaleString'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var o; + +o = { length: 2, 0: 7, 1: { toLocaleString: function() { return "baz" } } }; +assertEq(Array.prototype.toLocaleString.call(o), "7,baz"); + +o = {}; +assertEq(Array.prototype.toLocaleString.call(o), ""); + +var log = ''; +arr = {length: {valueOf: function () { log += "L"; return 2; }}, + 0: "x", 1: "z"}; +assertEq(Array.prototype.toLocaleString.call(arr), "x,z"); +assertEq(log, "L"); + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Array/toString-01.js b/js/src/tests/ecma_5/Array/toString-01.js new file mode 100644 index 000000000..a92fe6369 --- /dev/null +++ b/js/src/tests/ecma_5/Array/toString-01.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 = 562446; +var summary = 'ES5: Array.prototype.toString'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var o; + +o = { join: function() { assertEq(arguments.length, 0); return "ohai"; } }; +assertEq(Array.prototype.toString.call(o), "ohai"); + +o = {}; +assertEq(Array.prototype.toString.call(o), "[object Object]"); + +Array.prototype.join = function() { return "kthxbai"; }; +assertEq(Array.prototype.toString.call([]), "kthxbai"); + +o = { join: 17 }; +assertEq(Array.prototype.toString.call(o), "[object Object]"); + +o = { get join() { throw 42; } }; +try +{ + var str = Array.prototype.toString.call(o); + assertEq(true, false, + "expected an exception calling [].toString on an object with a " + + "join getter that throws, got " + str + " instead"); +} +catch (e) +{ + assertEq(e, 42, + "expected thrown e === 42 when calling [].toString on an object " + + "with a join getter that throws, got " + e); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/Array/unshift-01.js b/js/src/tests/ecma_5/Array/unshift-01.js new file mode 100644 index 000000000..84c9d88a5 --- /dev/null +++ b/js/src/tests/ecma_5/Array/unshift-01.js @@ -0,0 +1,45 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 614070; +var summary = 'Array.prototype.unshift without args'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +// ES6 ToLength clamps length values to 2^53 - 1. +// We currently clamp to 2^32 - 1 instead. See bug 924058. +var MAX_LENGTH = 0xffffffff; + +var a = {}; +a.length = MAX_LENGTH + 1; +assertEq([].unshift.call(a), MAX_LENGTH); +assertEq(a.length, MAX_LENGTH); + +function testGetSet(len, expected) { + var newlen; + var a = { get length() { return len; }, set length(v) { newlen = v; } }; + var res = [].unshift.call(a); + assertEq(res, expected); + assertEq(newlen, expected); +} + +testGetSet(0, 0); +testGetSet(10, 10); +testGetSet("1", 1); +testGetSet(null, 0); +testGetSet(MAX_LENGTH + 2, MAX_LENGTH); +testGetSet(-5, 0); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); |