padding-iteration-get-abrupt-completion.js (3359B)
1 // Copyright (C) 2025 André Bargull. All rights reserved. 2 // This code is governed by the BSD license found in the LICENSE file. 3 4 /*--- 5 esid: sec-iterator.zipkeyed 6 description: > 7 Abrupt completion for Get in "padding" option iteration. 8 info: | 9 Iterator.zipKeyed ( iterables [ , options ] ) 10 ... 11 14. If mode is "longest", then 12 ... 13 b. Else, 14 i. For each element key of keys, do 15 1. Let value be Completion(Get(paddingOption, key)). 16 2. IfAbruptCloseIterators(value, iters). 17 ... 18 19 IfAbruptCloseIterators ( value, iteratorRecords ) 20 1. Assert: value is a Completion Record. 21 2. If value is an abrupt completion, return ? IteratorCloseAll(iteratorRecords, value). 22 3. Else, set value to value.[[Value]]. 23 24 IteratorCloseAll ( iters, completion ) 25 1. For each element iter of iters, in reverse List order, do 26 a. Set completion to Completion(IteratorClose(iter, completion)). 27 2. Return ? completion. 28 29 IteratorClose ( iteratorRecord, completion ) 30 1. Assert: iteratorRecord.[[Iterator]] is an Object. 31 2. Let iterator be iteratorRecord.[[Iterator]]. 32 3. Let innerResult be Completion(GetMethod(iterator, "return")). 33 4. If innerResult is a normal completion, then 34 a. Let return be innerResult.[[Value]]. 35 b. If return is undefined, return ? completion. 36 c. Set innerResult to Completion(Call(return, iterator)). 37 5. If completion is a throw completion, return ? completion. 38 ... 39 includes: [compareArray.js] 40 features: [joint-iteration] 41 ---*/ 42 43 var log = []; 44 45 var first = { 46 next() { 47 log.push("unexpected call to next method"); 48 }, 49 return() { 50 // Called with the correct receiver and no arguments. 51 assert.sameValue(this, first); 52 assert.sameValue(arguments.length, 0); 53 54 // NB: Log after above asserts, because failures aren't propagated. 55 log.push("first return"); 56 57 // This exception is ignored. 58 throw new Test262Error(); 59 } 60 }; 61 62 var second = { 63 next() { 64 log.push("unexpected call to next method"); 65 }, 66 return() { 67 // Called with the correct receiver and no arguments. 68 assert.sameValue(this, second); 69 assert.sameValue(arguments.length, 0); 70 71 // NB: Log after above asserts, because failures aren't propagated. 72 log.push("second return"); 73 74 // This exception is ignored. 75 throw new Test262Error(); 76 } 77 }; 78 79 var third = { 80 next() { 81 log.push("unexpected call to next method"); 82 }, 83 get return() { 84 // Called with the correct receiver and no arguments. 85 assert.sameValue(this, third); 86 assert.sameValue(arguments.length, 0); 87 88 // NB: Log after above asserts, because failures aren't propagated. 89 log.push("third return"); 90 91 // This exception is ignored. 92 throw new Test262Error(); 93 } 94 }; 95 96 function ExpectedError() {} 97 98 // Padding object throws from |get second|. 99 var padding = { 100 get first() { 101 log.push("padding first"); 102 }, 103 get second() { 104 log.push("padding second"); 105 throw new ExpectedError(); 106 }, 107 get third() { 108 log.push("unexpected padding third"); 109 }, 110 }; 111 112 assert.throws(ExpectedError, function() { 113 Iterator.zipKeyed({ 114 first, 115 second, 116 third 117 }, {mode: "longest", padding}); 118 }); 119 120 assert.compareArray(log, [ 121 "padding first", 122 "padding second", 123 "third return", 124 "second return", 125 "first return", 126 ]); 127 128 reportCompare(0, 0);