diff options
Diffstat (limited to '')
18 files changed, 307 insertions, 0 deletions
diff --git a/js/src/tests/non262/Iterator/prototype/reduce/accumulator-set-to-initial-value.js b/js/src/tests/non262/Iterator/prototype/reduce/accumulator-set-to-initial-value.js new file mode 100644 index 0000000000..4395e1c7d4 --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/accumulator-set-to-initial-value.js @@ -0,0 +1,9 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +const reducer = (acc, value) => acc; +const iterator = [1, 2, 3].values(); + +assertEq(iterator.reduce(reducer, 0), 0); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/check-fn-after-getting-iterator.js b/js/src/tests/non262/Iterator/prototype/reduce/check-fn-after-getting-iterator.js new file mode 100644 index 0000000000..4e4852326a --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/check-fn-after-getting-iterator.js @@ -0,0 +1,26 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +const log = []; +const handlerProxy = new Proxy({}, { + get: (target, key, receiver) => (...args) => { + log.push(`${key}: ${args[1]?.toString()}`); + return Reflect[key](...args); + }, +}); + +class TestIterator extends Iterator { + next() { + return {done: true}; + } +} + +const iter = new Proxy(new TestIterator(), handlerProxy); +assertThrowsInstanceOf(() => iter.reduce(1), TypeError); + +assertEq( + log.join('\n'), + `get: reduce +get: next` +); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/descriptor.js b/js/src/tests/non262/Iterator/prototype/reduce/descriptor.js new file mode 100644 index 0000000000..0fb0ff01b3 --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/descriptor.js @@ -0,0 +1,13 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +/*--- + Descriptor property of Iterator.prototype.reduce +---*/ + +const propDesc = Reflect.getOwnPropertyDescriptor(Iterator.prototype, 'reduce'); +assertEq(typeof propDesc.value, 'function'); +assertEq(propDesc.writable, true); +assertEq(propDesc.enumerable, false); +assertEq(propDesc.configurable, true); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/empty-iterator-without-initial-value-throws.js b/js/src/tests/non262/Iterator/prototype/reduce/empty-iterator-without-initial-value-throws.js new file mode 100644 index 0000000000..d8e0a595cf --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/empty-iterator-without-initial-value-throws.js @@ -0,0 +1,7 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +const iter = [].values(); +assertThrowsInstanceOf(() => iter.reduce((x, y) => x + y), TypeError); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/error-from-correct-realm.js b/js/src/tests/non262/Iterator/prototype/reduce/error-from-correct-realm.js new file mode 100644 index 0000000000..96634ba62b --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/error-from-correct-realm.js @@ -0,0 +1,16 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +const otherGlobal = newGlobal({newCompartment: true}); +assertEq(TypeError !== otherGlobal.TypeError, true); + +const iter = [].values(); + +assertThrowsInstanceOf(() => iter.reduce(), TypeError); +assertThrowsInstanceOf( + otherGlobal.Iterator.prototype.reduce.bind(iter), + otherGlobal.TypeError, + 'TypeError comes from the realm of the method.', +); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/iterator-empty-return-initial-value.js b/js/src/tests/non262/Iterator/prototype/reduce/iterator-empty-return-initial-value.js new file mode 100644 index 0000000000..30c15a48fe --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/iterator-empty-return-initial-value.js @@ -0,0 +1,9 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +const reducer = (x, y) => 0; +const iterator = [].values(); + +assertEq(iterator.reduce(reducer, 1), 1); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/iterator-next-return-non-object-throws.js b/js/src/tests/non262/Iterator/prototype/reduce/iterator-next-return-non-object-throws.js new file mode 100644 index 0000000000..d77789f04a --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/iterator-next-return-non-object-throws.js @@ -0,0 +1,30 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +class TestIterator extends Iterator { + constructor(value) { + super(); + this.value = value; + } + + next() { + return this.value; + } +} + +const sum = (x, y) => x + y; + +let iter = new TestIterator(undefined); +assertThrowsInstanceOf(() => iter.reduce(sum), TypeError); +iter = new TestIterator(null); +assertThrowsInstanceOf(() => iter.reduce(sum), TypeError); +iter = new TestIterator(0); +assertThrowsInstanceOf(() => iter.reduce(sum), TypeError); +iter = new TestIterator(false); +assertThrowsInstanceOf(() => iter.reduce(sum), TypeError); +iter = new TestIterator(''); +assertThrowsInstanceOf(() => iter.reduce(sum), TypeError); +iter = new TestIterator(Symbol('')); +assertThrowsInstanceOf(() => iter.reduce(sum), TypeError); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/left-associative.js b/js/src/tests/non262/Iterator/prototype/reduce/left-associative.js new file mode 100644 index 0000000000..a6208504b6 --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/left-associative.js @@ -0,0 +1,7 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +assertEq([1, 2, 3].values().reduce((x, y) => `(${x}+${y})`, 0), '(((0+1)+2)+3)'); +assertEq([1, 2, 3].values().reduce((x, y) => `(${x}+${y})`), '((1+2)+3)'); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/length.js b/js/src/tests/non262/Iterator/prototype/reduce/length.js new file mode 100644 index 0000000000..0780e684a8 --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/length.js @@ -0,0 +1,17 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +/*--- + The `length` property of Iterator.prototype.reduce. +info: | + ES7 section 17: Unless otherwise specified, the length property of a built-in + Function object has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +---*/ + +const propDesc = Reflect.getOwnPropertyDescriptor(Iterator.prototype.reduce, 'length'); +assertEq(propDesc.value, 1); +assertEq(propDesc.writable, false); +assertEq(propDesc.enumerable, false); +assertEq(propDesc.configurable, true); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/name.js b/js/src/tests/non262/Iterator/prototype/reduce/name.js new file mode 100644 index 0000000000..1269bb4b52 --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/name.js @@ -0,0 +1,13 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +/*--- + `name` property of Iterator.prototype.reduce. +---*/ + +const propDesc = Reflect.getOwnPropertyDescriptor(Iterator.prototype.reduce, 'name'); +assertEq(propDesc.value, 'reduce'); +assertEq(propDesc.writable, false); +assertEq(propDesc.enumerable, false); +assertEq(propDesc.configurable, true); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/next-throws-iterator-not-closed.js b/js/src/tests/non262/Iterator/prototype/reduce/next-throws-iterator-not-closed.js new file mode 100644 index 0000000000..0fbeb995f1 --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/next-throws-iterator-not-closed.js @@ -0,0 +1,22 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +class TestIterator extends Iterator { + next() { + throw new Error(); + } + + closed = false; + return() { + this.closed = true; + } +} + +const sum = (x, y) => x + y; +const iter = new TestIterator(); + +assertEq(iter.closed, false); +assertThrowsInstanceOf(() => iter.reduce(sum), Error); +assertEq(iter.closed, false); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/no-initial-value-set-accumulator-to-first-value.js b/js/src/tests/non262/Iterator/prototype/reduce/no-initial-value-set-accumulator-to-first-value.js new file mode 100644 index 0000000000..a2b0008e6a --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/no-initial-value-set-accumulator-to-first-value.js @@ -0,0 +1,9 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +const reducer = (acc, value) => acc; +const iterator = [1, 2, 3].values(); + +assertEq(iterator.reduce(reducer), 1); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/proxy.js b/js/src/tests/non262/Iterator/prototype/reduce/proxy.js new file mode 100644 index 0000000000..34569cf044 --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/proxy.js @@ -0,0 +1,44 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +// +// This test checks that %Iterator.prototype%.reduce only gets the `next` method off of the +// iterator once, and never accesses the @@iterator property. +const log = []; +const handlerProxy = new Proxy({}, { + get: (target, key, receiver) => (...args) => { + log.push(`${key}: ${args[1]?.toString()}`); + return Reflect[key](...args); + }, +}); + +class Counter extends Iterator { + value = 0; + next() { + const value = this.value; + if (value < 2) { + this.value = value + 1; + return {done: false, value}; + } + return {done: true}; + } +} + +const iter = new Proxy(new Counter(), handlerProxy); +iter.reduce((x, y) => x + y); + +assertEq( + log.join('\n'), + `get: reduce +get: next +get: value +set: value +getOwnPropertyDescriptor: value +defineProperty: value +get: value +set: value +getOwnPropertyDescriptor: value +defineProperty: value +get: value` +); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/reduce.js b/js/src/tests/non262/Iterator/prototype/reduce/reduce.js new file mode 100644 index 0000000000..d824da211d --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/reduce.js @@ -0,0 +1,9 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +const reducer = (acc, value) => acc + value; +const iterator = [1, 2, 3].values(); + +assertEq(iterator.reduce(reducer, 0), 6); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/reducer-not-callable-throws.js b/js/src/tests/non262/Iterator/prototype/reduce/reducer-not-callable-throws.js new file mode 100644 index 0000000000..c33e5e4f9c --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/reducer-not-callable-throws.js @@ -0,0 +1,20 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +class TestIterator extends Iterator { + next() { + return { done: false, value: 0 }; + } +} + +const iter = new TestIterator(); +assertThrowsInstanceOf(() => iter.reduce(), TypeError); +assertThrowsInstanceOf(() => iter.reduce(undefined), TypeError); +assertThrowsInstanceOf(() => iter.reduce(null), TypeError); +assertThrowsInstanceOf(() => iter.reduce(0), TypeError); +assertThrowsInstanceOf(() => iter.reduce(false), TypeError); +assertThrowsInstanceOf(() => iter.reduce(''), TypeError); +assertThrowsInstanceOf(() => iter.reduce(Symbol('')), TypeError); +assertThrowsInstanceOf(() => iter.reduce({}), TypeError); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/reducer-throws-iterator-closed.js b/js/src/tests/non262/Iterator/prototype/reduce/reducer-throws-iterator-closed.js new file mode 100644 index 0000000000..592fa80d17 --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/reducer-throws-iterator-closed.js @@ -0,0 +1,22 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +class TestIterator extends Iterator { + next() { + return { done: this.closed, value: undefined }; + } + + closed = false; + return() { + this.closed = true; + } +} + +const reducer = (x, y) => { throw new Error(); }; +const iter = new TestIterator(); + +assertEq(iter.closed, false); +assertThrowsInstanceOf(() => iter.reduce(reducer), Error); +assertEq(iter.closed, true); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/this-not-iterator-throws.js b/js/src/tests/non262/Iterator/prototype/reduce/this-not-iterator-throws.js new file mode 100644 index 0000000000..d4804c51e2 --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/this-not-iterator-throws.js @@ -0,0 +1,9 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +const sum = (x, y) => x + y; +assertThrowsInstanceOf(Iterator.prototype.reduce.bind(undefined, sum), TypeError); +assertThrowsInstanceOf(Iterator.prototype.reduce.bind({}, sum), TypeError); +assertThrowsInstanceOf(Iterator.prototype.reduce.bind({next: 0}, sum), TypeError); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/prototype/reduce/value-throws-iterator-not-closed.js b/js/src/tests/non262/Iterator/prototype/reduce/value-throws-iterator-not-closed.js new file mode 100644 index 0000000000..7b43eedcc6 --- /dev/null +++ b/js/src/tests/non262/Iterator/prototype/reduce/value-throws-iterator-not-closed.js @@ -0,0 +1,25 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally + +class TestError extends Error {} +class TestIterator extends Iterator { + next() { + return new Proxy({done: false}, {get: (target, key, receiver) => { + if (key === 'value') + throw new TestError(); + return 0; + }}); + } + + closed = false; + return() { + closed = true; + } +} + +const iterator = new TestIterator(); +assertEq(iterator.closed, false, 'iterator starts unclosed'); +assertThrowsInstanceOf(() => iterator.reduce((x, y) => x + y, 0), TestError); +assertEq(iterator.closed, false, 'iterator remains unclosed'); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); |