// Copyright 2019 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Flags: --allow-natives-syntax --ignore-unhandled-promises class MyError extends Error {} const descriptor = Object.getOwnPropertyDescriptor(Promise, "allSettled"); assertTrue(descriptor.configurable); assertTrue(descriptor.writable); assertFalse(descriptor.enumerable); // 1. Let C be the this value. // 2. If Type(C) is not Object, throw a TypeError exception. assertThrows(() => Promise.allSettled.call(1), TypeError); { // 3. Let promiseCapability be ? NewPromiseCapability(C). let called = false; class MyPromise extends Promise { constructor(...args) { called = true; super(...args); } } MyPromise.allSettled([]); assertTrue(called); } { // 4. Let iteratorRecord be GetIterator(iterable). // 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability). let caught = false; (async function() { class MyError extends Error {} let err; try { await Promise.allSettled({ [Symbol.iterator]() { throw new MyError(); } }); } catch (e) { assertTrue(e instanceof MyError); caught = true; } })(); %PerformMicrotaskCheckpoint(); assertTrue(caught); } { // 6. a. Let next be IteratorStep(iteratorRecord). let iteratorStep = false; (async function() { try { await Promise.allSettled({ [Symbol.iterator]() { return { next() { iteratorStep = true; return { done: true } } }; } }); } catch (e) { %AbortJS(e.stack); } })(); %PerformMicrotaskCheckpoint(); assertTrue(iteratorStep); } { // 6. a. Let next be IteratorStep(iteratorRecord). // 6. b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true. // 6. c. ReturnIfAbrupt(next). let caught = false; (async function() { try { await Promise.allSettled({ [Symbol.iterator]() { return { next() { throw new MyError(); } }; } }); } catch (e) { assertTrue(e instanceof MyError); caught = true; } })(); %PerformMicrotaskCheckpoint(); assertTrue(caught); } { // 6. e. Let nextValue be IteratorValue(next). let iteratorValue = false; (async function() { try { await Promise.allSettled({ [Symbol.iterator]() { let done = false; return { next() { let result = { value: 1, done }; iteratorValue = true; done = true; return result; } }; } }); } catch (e) { %AbortJS(e.stack); } })(); %PerformMicrotaskCheckpoint(); assertTrue(iteratorValue); } { // 6. e. Let nextValue be IteratorValue(next). // 6. f. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true. // 6. g. ReturnIfAbrupt(nextValue). let caught = false; (async function() { try { await Promise.allSettled({ [Symbol.iterator]() { let done = false; return { next() { return result = { get value() {throw new MyError(''); }, done: false }; } }; } }); } catch (e) { assertTrue(e instanceof MyError); caught = true; } })(); %PerformMicrotaskCheckpoint(); assertTrue(caught); } { // TODO(mathias): https://github.com/tc39/proposal-promise-allSettled/pull/40 // 6. i. Let nextPromise be ? Invoke(constructor, "resolve", « nextValue »). let called = false; class MyPromise extends Promise { static resolve(...args) { called = true; super.resolve(...args); } } MyPromise.allSettled([1]); assertTrue(called); } { // 6. z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »). let called = false; class MyPromise extends Promise { then(...args) { called = true; super.resolve(...args); } } MyPromise.allSettled([1]); assertTrue(called); } { let called = false; let result; Promise.allSettled([]).then(x => { called = true; result = x; }); %PerformMicrotaskCheckpoint(); assertTrue(called); assertEquals(result, []); } { let called = false; Promise.allSettled([Promise.resolve("foo")]).then(v => { assertEquals(v.length, 1); const [x] = v; assertSame(Object.getPrototypeOf(x), Object.getPrototypeOf({})); const descs = Object.getOwnPropertyDescriptors(x); assertEquals(Object.keys(descs).length, 2); const { value: desc } = descs; assertTrue(desc.writable); assertTrue(desc.enumerable); assertTrue(desc.configurable); assertEquals(x.value, "foo"); assertEquals(x.status, "fulfilled"); called = true; }); %PerformMicrotaskCheckpoint(); assertTrue(called); } { let called = false; Promise.allSettled([Promise.reject("foo")]).then(v => { assertEquals(v.length, 1); const [x] = v; assertEquals(x.reason, "foo"); assertEquals(x.status, "rejected"); called = true; }); %PerformMicrotaskCheckpoint(); assertTrue(called); } { let called = false; Promise.allSettled([Promise.resolve("bar"), Promise.reject("foo")]).then(v => { assertEquals(v.length, 2); const [x, y] = v; assertEquals(x.value, "bar"); assertEquals(x.status, "fulfilled"); assertEquals(y.reason, "foo"); assertEquals(y.status, "rejected"); called = true; }); %PerformMicrotaskCheckpoint(); assertTrue(called); }