diff --git a/test/built-ins/Iterator/from/get-return-method-when-call-return.js b/test/built-ins/Iterator/from/get-return-method-when-call-return.js new file mode 100644 index 00000000000..18290f3e0b2 --- /dev/null +++ b/test/built-ins/Iterator/from/get-return-method-when-call-return.js @@ -0,0 +1,35 @@ +// Copyright (C) 2024 Sosuke Suzuki. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + Gets the base iterator return method when the wrapper return method is called. +info: | + %WrapForValidIteratorPrototype%.return ( ) + ... + 5. Let returnMethod be ? GetMethod(iterator, "return"). + +features: [iterator-helpers] +includes: [temporalHelpers.js, compareArray.js] +---*/ + +const calls = []; + +const iter = TemporalHelpers.propertyBagObserver(calls, { + return () { + return { value: 5, done: true }; + }, +}, "originalIter"); + +const wrapper = Iterator.from(iter); +assert.compareArray(calls, [ + "get originalIter[Symbol.iterator]", + "get originalIter.next", +]); + +wrapper.return(); +assert.compareArray(calls, [ + "get originalIter[Symbol.iterator]", + "get originalIter.next", + "get originalIter.return" +]); diff --git a/test/built-ins/Iterator/from/return-method-calls-base-return-method.js b/test/built-ins/Iterator/from/return-method-calls-base-return-method.js new file mode 100644 index 00000000000..01121f65ce2 --- /dev/null +++ b/test/built-ins/Iterator/from/return-method-calls-base-return-method.js @@ -0,0 +1,41 @@ +// Copyright (C) 2024 Sosuke Suzuki. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + %WrapForValidIteratorPrototype%.return() call base iterator's return method when it exists. +info: | + %WrapForValidIteratorPrototype%.return ( ) + 5. Let returnMethod be ? GetMethod(iterator, "return"). + 6. If returnMethod is undefined, then + ... + 7. Return ? Call(returnMethod, iterator). + +features: [iterator-helpers] +includes: [temporalHelpers.js, compareArray.js] +---*/ + +const calls = []; + +const expectedIteratorResult = { value: 5, done: true }; +const originalIter = { + return () { + return expectedIteratorResult; + }, +}; +TemporalHelpers.observeMethod(calls, originalIter, "return", "originalIter"); +const iter = TemporalHelpers.propertyBagObserver(calls, originalIter, "originalIter"); + +const wrapper = Iterator.from(iter); +assert.compareArray(calls, [ + "get originalIter[Symbol.iterator]", + "get originalIter.next", +]); + +assert.sameValue(wrapper.return(), expectedIteratorResult); +assert.compareArray(calls, [ + "get originalIter[Symbol.iterator]", + "get originalIter.next", + "get originalIter.return", + "call originalIter.return", +]); diff --git a/test/built-ins/Iterator/from/return-method-returns-iterator-result.js b/test/built-ins/Iterator/from/return-method-returns-iterator-result.js new file mode 100644 index 00000000000..36ada0f1a38 --- /dev/null +++ b/test/built-ins/Iterator/from/return-method-returns-iterator-result.js @@ -0,0 +1,23 @@ +// Copyright (C) 2024 Sosuke Suzuki. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + %WrapForValidIteratorPrototype%.return() should return an iterator result object that value is undefined when base object does not have return method. +info: | + %WrapForValidIteratorPrototype%.return ( ) + ... + 5. Let returnMethod be ? GetMethod(iterator, "return"). + 6. If returnMethod is undefined, then + a. Return CreateIterResultObject(undefined, true). + +features: [iterator-helpers] +---*/ + +const iter = {}; +const wrapper = Iterator.from(iter); + +const result = wrapper.return(); +assert(result.hasOwnProperty("value")); +assert.sameValue(result.value, undefined); +assert.sameValue(result.done, true); diff --git a/test/built-ins/Iterator/from/return-method-throws-for-invalid-this.js b/test/built-ins/Iterator/from/return-method-throws-for-invalid-this.js new file mode 100644 index 00000000000..a30bed4c655 --- /dev/null +++ b/test/built-ins/Iterator/from/return-method-throws-for-invalid-this.js @@ -0,0 +1,39 @@ +// Copyright (C) 2024 Sosuke Suzuki. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iterator.from +description: > + %WrapForValidIteratorPrototype%.return() requires [[iterated]] internal slot +info: | + %WrapForValidIteratorPrototype%.return ( ) + ... + 2. Perform ? RequireInternalSlot(O, [[Iterated]]). + +features: [iterator-helpers] +includes: [temporalHelpers.js, compareArray.js] +---*/ + +const WrapForValidIteratorPrototype = Object.getPrototypeOf(Iterator.from({})); + +{ + assert.throws(TypeError, function() { + WrapForValidIteratorPrototype.return.call({}); + }); +} + +{ + const originalIter = { + return() { + return { value: 5, done: true }; + }, + }; + + const calls = []; + TemporalHelpers.observeMethod(calls, originalIter, "return", "originalIter"); + const iter = TemporalHelpers.propertyBagObserver(calls, originalIter, "originalIter"); + + assert.throws(TypeError, function() { + WrapForValidIteratorPrototype.return.call(iter); + }); + assert.compareArray(calls, []); +}