diff options
Diffstat (limited to 'js/src/tests/non262/Iterator/from')
23 files changed, 536 insertions, 0 deletions
diff --git a/js/src/tests/non262/Iterator/from/Iterator.from-descriptor.js b/js/src/tests/non262/Iterator/from/Iterator.from-descriptor.js new file mode 100644 index 0000000000..19bdde852b --- /dev/null +++ b/js/src/tests/non262/Iterator/from/Iterator.from-descriptor.js @@ -0,0 +1,12 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +/*--- + Descriptor property of Iterator.from +---*/ + +const propDesc = Reflect.getOwnPropertyDescriptor(Iterator, 'from'); +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/from/Iterator.from-length.js b/js/src/tests/non262/Iterator/from/Iterator.from-length.js new file mode 100644 index 0000000000..0833538da1 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/Iterator.from-length.js @@ -0,0 +1,17 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +/*--- + The `length` property of Iterator.from. +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.from, '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/from/Iterator.from-name.js b/js/src/tests/non262/Iterator/from/Iterator.from-name.js new file mode 100644 index 0000000000..6f48d3e891 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/Iterator.from-name.js @@ -0,0 +1,13 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +/*--- + `name` property of Iterator.from. +---*/ + +const propDesc = Reflect.getOwnPropertyDescriptor(Iterator.from, 'name'); +assertEq(propDesc.value, 'from'); +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/from/call-from-with-different-this.js b/js/src/tests/non262/Iterator/from/call-from-with-different-this.js new file mode 100644 index 0000000000..90328d117d --- /dev/null +++ b/js/src/tests/non262/Iterator/from/call-from-with-different-this.js @@ -0,0 +1,18 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +const iter = { + next: () => ({done: false, value: 0}), +}; +const wrap = Iterator.from.call(undefined, iter); + +const result = wrap.next(); +assertEq(result.done, false); +assertEq(result.value, 0); + +const returnResult = wrap.return(1); +assertEq(returnResult.done, true); +assertEq(returnResult.value, 1); + +assertThrowsInstanceOf(() => wrap.throw(new Error()), Error); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/iterator-not-callable-throws.js b/js/src/tests/non262/Iterator/from/iterator-not-callable-throws.js new file mode 100644 index 0000000000..a7c98f9e2a --- /dev/null +++ b/js/src/tests/non262/Iterator/from/iterator-not-callable-throws.js @@ -0,0 +1,13 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +/*--- + Iterator.from throws when called with an object with a non-callable @@iterator property. +---*/ + +assertThrowsInstanceOf(() => Iterator.from({ [Symbol.iterator]: 0 }), TypeError); +assertThrowsInstanceOf(() => Iterator.from({ [Symbol.iterator]: false }), TypeError); +assertThrowsInstanceOf(() => Iterator.from({ [Symbol.iterator]: "" }), TypeError); +assertThrowsInstanceOf(() => Iterator.from({ [Symbol.iterator]: {} }), TypeError); +assertThrowsInstanceOf(() => Iterator.from({ [Symbol.iterator]: Symbol('') }), TypeError); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/modify-next.js b/js/src/tests/non262/Iterator/from/modify-next.js new file mode 100644 index 0000000000..d347abd2cd --- /dev/null +++ b/js/src/tests/non262/Iterator/from/modify-next.js @@ -0,0 +1,15 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +const iter = { + next: () => ({ done: false, value: 0 }), +}; + +const wrap = Iterator.from(iter); + +iter.next = () => ({ done: true, value: undefined }); + +let {done, value} = wrap.next(); +assertEq(done, false); +assertEq(value, 0); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/modify-return.js b/js/src/tests/non262/Iterator/from/modify-return.js new file mode 100644 index 0000000000..733eec69d7 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/modify-return.js @@ -0,0 +1,22 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +const iter = { + next: () => ({ done: false, value: 0 }), + return: (value) => ({ done: true, value }), +}; + +const wrap = Iterator.from(iter); + +let {done, value} = wrap.return(1); +assertEq(done, true); +assertEq(value, 1); + +iter.return = () => { throw new Error(); }; +assertThrowsInstanceOf(wrap.return, Error); + +iter.return = null; +let nullResult = wrap.return(2); +assertEq(nullResult.done, true); +assertEq(nullResult.value, 2); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/modify-throw.js b/js/src/tests/non262/Iterator/from/modify-throw.js new file mode 100644 index 0000000000..0db7cf6f61 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/modify-throw.js @@ -0,0 +1,18 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +const iter = { + next: () => ({ done: false, value: 0 }), + throw: (value) => ({ done: true, value }), +}; + +const wrap = Iterator.from(iter); + +let {done, value} = wrap.throw(0); +assertEq(done, true); +assertEq(value, 0); + +class TestError extends Error {} +iter.throw = () => { throw new TestError(); }; +assertThrowsInstanceOf(() => wrap.throw(), TestError); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/o-not-object-throws.js b/js/src/tests/non262/Iterator/from/o-not-object-throws.js new file mode 100644 index 0000000000..3e6c00e59a --- /dev/null +++ b/js/src/tests/non262/Iterator/from/o-not-object-throws.js @@ -0,0 +1,13 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +/*--- + Iterator.from throws when called with a non-object. +---*/ + +assertThrowsInstanceOf(() => Iterator.from(undefined), TypeError); +assertThrowsInstanceOf(() => Iterator.from(null), TypeError); +assertThrowsInstanceOf(() => Iterator.from(0), TypeError); +assertThrowsInstanceOf(() => Iterator.from(false), TypeError); +assertThrowsInstanceOf(() => Iterator.from(Symbol('')), TypeError); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/proxy-not-wrapped.js b/js/src/tests/non262/Iterator/from/proxy-not-wrapped.js new file mode 100644 index 0000000000..df38e0fc86 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/proxy-not-wrapped.js @@ -0,0 +1,34 @@ +// |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()}`); + + const item = Reflect[key](...args); + if (typeof item === 'function') + return (...args) => new Proxy(item.apply(receiver, args), handlerProxy); + return item; + }, +}); + +class Iter extends Iterator { + [Symbol.iterator]() { + return this; + } + next() { + return { done: false, value: 0 }; + } +} +const iter = new Iter(); +const proxy = new Proxy(iter, handlerProxy); +const wrap = Iterator.from(proxy); + +assertEq( + log.join('\n'), + `get: Symbol(Symbol.iterator) +get: next +getPrototypeOf: undefined` +); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/proxy-wrap-next.js b/js/src/tests/non262/Iterator/from/proxy-wrap-next.js new file mode 100644 index 0000000000..7630535402 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/proxy-wrap-next.js @@ -0,0 +1,30 @@ +// |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()}`); + + const item = Reflect[key](...args); + if (typeof item === 'function') + return item.bind(receiver); + return item; + }, +}); +const iter = new Proxy({ + next: () => ({ done: false, value: 0 }), +}, handlerProxy); + +const wrap = Iterator.from(iter); +// Call next multiple times. Should not call `get` on proxy. +wrap.next(); +wrap.next(); +wrap.next(); + +assertEq( + log.join('\n'), + `get: Symbol(Symbol.iterator) +get: next` +); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/proxy-wrap-return.js b/js/src/tests/non262/Iterator/from/proxy-wrap-return.js new file mode 100644 index 0000000000..34caeb2176 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/proxy-wrap-return.js @@ -0,0 +1,31 @@ +// |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()}`); + + const item = Reflect[key](...args); + if (typeof item === 'function') + return item.bind(receiver); + return item; + }, +}); +const iter = new Proxy({ + next: () => ({ done: false, value: 0 }), + return: (value) => ({ done: true, value }), +}, handlerProxy); + +const wrap = Iterator.from(iter); +wrap.return(); +wrap.return(); + +assertEq( + log.join('\n'), + `get: Symbol(Symbol.iterator) +get: next +get: return +get: return` +); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/proxy-wrap-throw.js b/js/src/tests/non262/Iterator/from/proxy-wrap-throw.js new file mode 100644 index 0000000000..92a51f4a26 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/proxy-wrap-throw.js @@ -0,0 +1,31 @@ +// |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()}`); + + const item = Reflect[key](...args); + if (typeof item === 'function') + return item.bind(receiver); + return item; + }, +}); +const iter = new Proxy({ + next: () => ({ done: false, value: 0 }), + throw: (value) => ({ done: true, value }), +}, handlerProxy); + +const wrap = Iterator.from(iter); +wrap.throw(); +wrap.throw(); + +assertEq( + log.join('\n'), + `get: Symbol(Symbol.iterator) +get: next +get: throw +get: throw` +); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/return-iterator-if-iterable.js b/js/src/tests/non262/Iterator/from/return-iterator-if-iterable.js new file mode 100644 index 0000000000..e83e25185d --- /dev/null +++ b/js/src/tests/non262/Iterator/from/return-iterator-if-iterable.js @@ -0,0 +1,25 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +/*--- + Iterator.from returns O if it is iterable, an iterator, and an instance of Iterator. +---*/ + +class TestIterator extends Iterator { + [Symbol.iterator]() { + return this; + } + + next() { + return { done: false, value: this.value++ }; + } + + value = 0; +} + +const iter = new TestIterator(); +assertEq(iter, Iterator.from(iter)); + +const arrayIter = [1, 2, 3][Symbol.iterator](); +assertEq(arrayIter, Iterator.from(arrayIter)); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/return-wrapper-if-not-iterable.js b/js/src/tests/non262/Iterator/from/return-wrapper-if-not-iterable.js new file mode 100644 index 0000000000..09b974f327 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/return-wrapper-if-not-iterable.js @@ -0,0 +1,28 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +/*--- + Iterator.from returns an iterator wrapper if O is not an iterable. +---*/ + +class TestIterator { + next() { + return { done: false, value: 0 }; + } +} + +const iter = new TestIterator(); +assertEq( + Symbol.iterator in iter, + false, + 'iter is not an iterable.' +); + +const wrapper = Iterator.from(iter); +assertEq(iter !== wrapper, true); +assertEq( + Symbol.iterator in wrapper, + true, + 'wrapper is an iterable.' +); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/return-wrapper-if-not-iterator-instance.js b/js/src/tests/non262/Iterator/from/return-wrapper-if-not-iterator-instance.js new file mode 100644 index 0000000000..4045801277 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/return-wrapper-if-not-iterator-instance.js @@ -0,0 +1,24 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +/*--- + Iterator.from returns an iterator wrapper if O is not an instance of Iterator. +---*/ + +class TestIterator { + [Symbol.iterator]() { + return this; + } + + next() { + return { done: false, value: 0 }; + } +} + +const iter = new TestIterator(); +assertEq(iter instanceof Iterator, false); + +const wrapper = Iterator.from(iter); +assertEq(iter !== wrapper, true); +assertEq(wrapper instanceof Iterator, true); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/wrap-functions-on-other-global.js b/js/src/tests/non262/Iterator/from/wrap-functions-on-other-global.js new file mode 100644 index 0000000000..186e4e62d0 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/wrap-functions-on-other-global.js @@ -0,0 +1,31 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) + +class TestError extends Error {} + +function checkIterResult({done, value}, expectedDone, expectedValue) { + assertEq(done, expectedDone); + assertEq(value, expectedValue); +} + +const iter = { + next(value) { + return {done: false, value: arguments.length}; + }, + return() { + throw new TestError(); + }, + throw: (value) => ({done: true, value}), +}; +const thisWrap = Iterator.from(iter); +const otherGlobal = newGlobal({newCompartment: true}); +const otherWrap = otherGlobal.Iterator.from(iter); + +checkIterResult(thisWrap.next.call(otherWrap), false, 0); +checkIterResult(thisWrap.next.call(otherWrap, 'value'), false, 1); + +assertThrowsInstanceOf(thisWrap.return.bind(otherWrap), TestError); + +checkIterResult(thisWrap.throw.call(otherWrap, 'value'), true, 'value'); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/wrap-method-with-non-wrap-this-throws.js b/js/src/tests/non262/Iterator/from/wrap-method-with-non-wrap-this-throws.js new file mode 100644 index 0000000000..7ff8539923 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/wrap-method-with-non-wrap-this-throws.js @@ -0,0 +1,42 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +// All methods on %WrapForValidIteratorPrototype% require an [[Iterated]] +// internal slot on the `this` object. + +class TestIterator { + next() { + return { + done: false, + value: 0, + }; + } +} + +const nextMethod = Iterator.from(new TestIterator()).next; +assertThrowsInstanceOf(() => nextMethod.call(undefined), TypeError); +assertThrowsInstanceOf(() => nextMethod.call(null), TypeError); +assertThrowsInstanceOf(() => nextMethod.call(0), TypeError); +assertThrowsInstanceOf(() => nextMethod.call(false), TypeError); +assertThrowsInstanceOf(() => nextMethod.call('test'), TypeError); +assertThrowsInstanceOf(() => nextMethod.call(Object(1)), TypeError); +assertThrowsInstanceOf(() => nextMethod.call({}), TypeError); + +const returnMethod = Iterator.from(new TestIterator()).next; +assertThrowsInstanceOf(() => returnMethod.call(undefined), TypeError); +assertThrowsInstanceOf(() => returnMethod.call(null), TypeError); +assertThrowsInstanceOf(() => returnMethod.call(0), TypeError); +assertThrowsInstanceOf(() => returnMethod.call(false), TypeError); +assertThrowsInstanceOf(() => returnMethod.call('test'), TypeError); +assertThrowsInstanceOf(() => returnMethod.call(Object(1)), TypeError); +assertThrowsInstanceOf(() => returnMethod.call({}), TypeError); + +const throwMethod = Iterator.from(new TestIterator()).next; +assertThrowsInstanceOf(() => throwMethod.call(undefined), TypeError); +assertThrowsInstanceOf(() => throwMethod.call(null), TypeError); +assertThrowsInstanceOf(() => throwMethod.call(0), TypeError); +assertThrowsInstanceOf(() => throwMethod.call(false), TypeError); +assertThrowsInstanceOf(() => throwMethod.call('test'), TypeError); +assertThrowsInstanceOf(() => throwMethod.call(Object(1)), TypeError); +assertThrowsInstanceOf(() => throwMethod.call({}), TypeError); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/wrap-new-global.js b/js/src/tests/non262/Iterator/from/wrap-new-global.js new file mode 100644 index 0000000000..a9a26b41b0 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/wrap-new-global.js @@ -0,0 +1,9 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +const otherGlobal = newGlobal({newCompartment: true}); + +const iter = [1, 2, 3].values(); +assertEq(iter, Iterator.from(iter)); +assertEq(iter !== otherGlobal.Iterator.from(iter), true); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/wrap-next-forwards-value.js b/js/src/tests/non262/Iterator/from/wrap-next-forwards-value.js new file mode 100644 index 0000000000..095ddd692a --- /dev/null +++ b/js/src/tests/non262/Iterator/from/wrap-next-forwards-value.js @@ -0,0 +1,18 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +class Iter { + next(value) { + this.v = value; + return { done: false, value }; + } +} + +const iter = new Iter(); +const wrap = Iterator.from(iter); +assertEq(iter !== wrap, true); + +assertEq(iter.v, undefined); +wrap.next(1); +assertEq(iter.v, 1); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/wrap-next-not-object-throws.js b/js/src/tests/non262/Iterator/from/wrap-next-not-object-throws.js new file mode 100644 index 0000000000..0e5b559f3b --- /dev/null +++ b/js/src/tests/non262/Iterator/from/wrap-next-not-object-throws.js @@ -0,0 +1,14 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +const iter = (value) => Iterator.from({ + next: () => value, +}); + +assertThrowsInstanceOf(() => iter(undefined).next(), TypeError); +assertThrowsInstanceOf(() => iter(null).next(), TypeError); +assertThrowsInstanceOf(() => iter(0).next(), TypeError); +assertThrowsInstanceOf(() => iter(false).next(), TypeError); +assertThrowsInstanceOf(() => iter('test').next(), TypeError); +assertThrowsInstanceOf(() => iter(Symbol('')).next(), TypeError); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/wrap-return-closes-iterator.js b/js/src/tests/non262/Iterator/from/wrap-return-closes-iterator.js new file mode 100644 index 0000000000..22518871f3 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/wrap-return-closes-iterator.js @@ -0,0 +1,33 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +class Iter { + next() { + if (this.closed) + return { done: true, value: undefined }; + return { done: false, value: 0 }; + } + + return(value) { + this.closed = true; + return { done: true, value }; + } +} + +const iter = new Iter(); +const wrap = Iterator.from(iter); +assertEq(iter.closed, undefined); + +let result = wrap.next(); +assertEq(result.done, false); +assertEq(result.value, 0); + +result = wrap.return(1); +assertEq(result.done, true); +assertEq(result.value, 1); + +assertEq(iter.closed, true); +result = wrap.next(); +assertEq(result.done, true); +assertEq(result.value, undefined); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/Iterator/from/wrap-throw.js b/js/src/tests/non262/Iterator/from/wrap-throw.js new file mode 100644 index 0000000000..ffe17c80e8 --- /dev/null +++ b/js/src/tests/non262/Iterator/from/wrap-throw.js @@ -0,0 +1,45 @@ +// |reftest| skip-if(!this.hasOwnProperty('Iterator')) -- Iterator is not enabled unconditionally +class Iter { + next() { + return { done: false, value: 0 }; + } +} + +const iter = new Iter(); +const wrap = Iterator.from(iter); + +assertThrowsInstanceOf(() => wrap.throw(new Error()), Error); +assertThrows(() => wrap.throw()); +assertThrows(() => wrap.throw(1)); + +class IterThrowNull { + next() { + return { done: false, value: 0 }; + } + throw = null; +} + +const iterNull = new IterThrowNull(); +const wrapNull = Iterator.from(iter); + +assertThrowsInstanceOf(() => wrapNull.throw(new Error()), Error); +assertThrows(() => wrapNull.throw()); +assertThrows(() => wrapNull.throw(1)); + +class IterWithThrow { + next() { + return { done: false, value: 0 }; + } + + throw(value) { + return value; + } +} + +const iterWithThrow = new IterWithThrow(); +const wrapWithThrow = Iterator.from(iterWithThrow); + +assertEq(wrapWithThrow.throw(1), 1); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); |