resolve-before-loop-exit.js (3154B)
1 // Copyright (C) 2020 Rick Waldron. All rights reserved. 2 // This code is governed by the BSD license found in the LICENSE file. 3 4 /*--- 5 esid: sec-promise.any 6 description: > 7 Cannot tamper remainingElementsCount when two Promise.any Reject Element Function are called in succession. 8 info: | 9 Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability). 10 11 Runtime Semantics: PerformPromiseAny 12 13 ... 14 Let remainingElementsCount be a new Record { [[value]]: 1 }. 15 ... 16 8.d ... 17 ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1. 18 iii. If remainingElementsCount.[[value]] is 0, 19 1. Let error be a newly created AggregateError object. 20 2. Perform ! DefinePropertyOrThrow(error, "errors", Property Descriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: errors }). 21 3. Return ThrowCompletion(error). 22 ... 23 24 Promise.any Reject Element Functions 25 ... 26 Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot. 27 If alreadyCalled.[[value]] is true, return undefined. 28 Set alreadyCalled.[[value]] to true. 29 ... 30 31 features: [Promise.any, arrow-function] 32 ---*/ 33 34 let callCount = 0; 35 let errorArray; 36 37 function Constructor(executor) { 38 function reject(error) { 39 callCount += 1; 40 errorArray = error.errors; 41 42 assert(Array.isArray(error.errors), "error is array"); 43 assert.sameValue(error.errors.length, 3, "error.length"); 44 assert.sameValue(error.errors[0], "p1-rejection", "error.errors[0] === 'p1-rejection'"); 45 assert.sameValue(error.errors[1], "p2-rejection", "error.errors[1] === 'p2-rejection'"); 46 assert.sameValue(error.errors[2], "p3-rejection", "error.errors[2] === 'p3-rejection'"); 47 assert(error instanceof AggregateError, "error instanceof AggregateError"); 48 } 49 executor(Test262Error.thrower, reject); 50 } 51 Constructor.resolve = function(v) { 52 return v; 53 }; 54 55 let p1OnRejected; 56 57 let p1 = { 58 then(onResolved, onRejected) { 59 p1OnRejected = onRejected; 60 } 61 }; 62 let p2 = { 63 then(onResolved, onRejected) { 64 p1OnRejected("p1-rejection"); 65 onRejected("p2-rejection"); 66 } 67 }; 68 let p3 = { 69 then(onResolved, onRejected) { 70 onRejected("p3-rejection"); 71 } 72 }; 73 74 assert.sameValue(callCount, 0, "callCount before call to any()"); 75 76 Promise.any.call(Constructor, [p1, p2, p3]); 77 78 assert.sameValue(callCount, 1, "callCount after call to any()"); 79 assert.sameValue(errorArray[0], "p1-rejection", "errorArray[0] === 'p1-rejection'"); 80 assert.sameValue(errorArray[1], "p2-rejection", "errorArray[1] === 'p2-rejection'"); 81 assert.sameValue(errorArray[2], "p3-rejection", "errorArray[2] === 'p3-rejection'"); 82 83 p1OnRejected("unexpectedonRejectedValue"); 84 85 assert.sameValue(callCount, 1, "callCount after call to p1OnRejected()"); 86 assert.sameValue( 87 errorArray[0], 88 "p1-rejection", 89 "errorArray[0] === 'p1-rejection', after call to p1OnRejected(...)" 90 ); 91 assert.sameValue( 92 errorArray[1], 93 "p2-rejection", 94 "errorArray[1] === 'p2-rejection', after call to p1OnRejected(...)" 95 ); 96 assert.sameValue( 97 errorArray[2], 98 "p3-rejection", 99 "errorArray[2] === 'p3-rejection', after call to p1OnRejected(...)" 100 ); 101 102 reportCompare(0, 0);