mirror of
https://github.com/hanzoai/core-js.git
synced 2026-09-24 16:58:15 +00:00
backport await dictionary stage 3 proposal
This commit is contained in:
@@ -19,6 +19,10 @@
|
||||
- Added [`Iterator` join stage 3 proposal](https://github.com/tc39/proposal-iterator-join):
|
||||
- Added built-in:
|
||||
- `Iterator.prototype.join`
|
||||
- Added [Await dictionary of Promises stage 3 proposal](https://github.com/tc39/proposal-await-dictionary):
|
||||
- Added built-ins:
|
||||
- `Promise.allKeyed`
|
||||
- `Promise.allSettledKeyed`
|
||||
- Throw a `RangeError` on finite unsafe integer `limit` in `Iterator.prototype.{ drop, take }`, following [tc39/ecma262/#3776](https://github.com/tc39/ecma262/pull/3776)
|
||||
- Deno 2.9+ [*replaces* `Object.prototype.__proto__`](https://github.com/denoland/deno/pull/35192) instead of removing it, so the feature detection updated
|
||||
- Ensure opaque paths always roundtrip in URL polyfill (still without adding to feature detection), [whatwg/url#844](https://github.com/whatwg/url/pull/844)
|
||||
|
||||
@@ -175,6 +175,7 @@ structuredClone(new Set([1, 2, 3])); // => new Set([1, 2, 3])
|
||||
- [`Iterator` chunking](#iterator-chunking)
|
||||
- [`Iterator` includes](#iterator-includes)
|
||||
- [`Iterator` join](#iterator-join)
|
||||
- [Await dictionary](#await-dictionary)
|
||||
- [Stage 2.7 proposals](#stage-27-proposals)
|
||||
- [`Symbol.metadata` for decorators metadata proposal](#symbolmetadata-for-decorators-metadata-proposal)
|
||||
- [Stage 2 proposals](#stage-2-proposals)
|
||||
@@ -2941,6 +2942,35 @@ core-js(-pure)/actual|full/iterator/join
|
||||
[1, null, 3].values().join(); // => '1,,3'
|
||||
```
|
||||
|
||||
##### [Await dictionary](https://github.com/tc39/proposal-await-dictionary)[⬆](#index)
|
||||
Modules [`esnext.promise.all-keyed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.promise.all-keyed.js)
|
||||
and [`esnext.promise.all-settled-keyed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.promise.all-settled-keyed.js)
|
||||
```ts
|
||||
class Promise {
|
||||
allKeyed(obj: Record<string | symbol, any>): Promise<Record<string | symbol, any>>;
|
||||
allSettledKeyed(obj: Record<string | symbol, any>): Promise<Record<string | symbol, { status: 'fulfilled', value: any } | { status: 'rejected', reason: any }>>;
|
||||
}
|
||||
```
|
||||
[*CommonJS entry points:*](#commonjs-api)
|
||||
```
|
||||
core-js/proposals/await-dictionary
|
||||
core-js(-pure)/actual|full/promise/all-keyed
|
||||
core-js(-pure)/actual|full/promise/all-settled-keyed
|
||||
```
|
||||
```js
|
||||
await Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.resolve(2),
|
||||
c: 3,
|
||||
}); // => { a: 1, b: 2, c: 3 }
|
||||
|
||||
await Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.reject(2),
|
||||
c: 3,
|
||||
}); // => { a: { status: "fulfilled", value: 1 }, b: { status: "rejected", reason: 2 }, c: { status: "fulfilled", value: 3 } }
|
||||
```
|
||||
|
||||
#### Stage 2.7 proposals[⬆](#index)
|
||||
[*CommonJS entry points:*](#commonjs-api)
|
||||
```
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# Await dictionary
|
||||
[Specification](https://tc39.es/proposal-await-dictionary/)\
|
||||
[Proposal repo](https://github.com/tc39/proposal-await-dictionary)
|
||||
|
||||
## Modules
|
||||
[`esnext.promise.all-keyed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.promise.all-keyed.js), [`esnext.promise.all-settled-keyed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.promise.all-settled-keyed.js)
|
||||
|
||||
## Built-ins signatures
|
||||
```ts
|
||||
class Promise {
|
||||
allKeyed<T extends Record<string, unknown>>(
|
||||
obj: T
|
||||
): Promise<{ [K in keyof T]: Awaited<T[K]> }>;
|
||||
|
||||
allSettledKeyed<T extends Record<string, unknown>>(
|
||||
obj: T
|
||||
): Promise<{ [K in keyof T]: PromiseSettledResult<Awaited<T[K]>> }>;
|
||||
}
|
||||
```
|
||||
|
||||
## [Entry points]({docs-version}/docs/usage#h-entry-points)
|
||||
```plaintext
|
||||
core-js/proposals/await-dictionary
|
||||
core-js(-pure)/actual|full/promise/all-keyed
|
||||
core-js(-pure)/actual|full/promise/all-settled-keyed
|
||||
```
|
||||
|
||||
## Examples
|
||||
```js
|
||||
await Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.resolve(2),
|
||||
c: 3,
|
||||
}); // => { a: 1, b: 2, c: 3 }
|
||||
|
||||
await Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.reject(2),
|
||||
c: 3,
|
||||
}); // => { a: { status: "fulfilled", value: 1 }, b: { status: "rejected", reason: 2 }, c: { status: "fulfilled", value: 3 } }
|
||||
```
|
||||
@@ -254,6 +254,10 @@
|
||||
{
|
||||
"title": "Stage 3 proposals",
|
||||
"children": [
|
||||
{
|
||||
"title": "Await dictionary",
|
||||
"url": "{docs-version}/docs/features/proposals/await-dictionary"
|
||||
},
|
||||
{
|
||||
"title": "Iterator chunking",
|
||||
"url": "{docs-version}/docs/features/proposals/iterator-chunking"
|
||||
|
||||
@@ -2786,8 +2786,12 @@ export const data = {
|
||||
},
|
||||
'esnext.observable.of': {
|
||||
},
|
||||
'esnext.promise.all-keyed': {
|
||||
},
|
||||
// TODO: Remove from `core-js@4`
|
||||
'esnext.promise.all-settled': null,
|
||||
'esnext.promise.all-settled-keyed': {
|
||||
},
|
||||
// TODO: Remove from `core-js@4`
|
||||
'esnext.promise.any': null,
|
||||
// TODO: Remove from `core-js@4`
|
||||
|
||||
@@ -328,5 +328,7 @@ export default {
|
||||
'es.iterator.zip-keyed',
|
||||
'esnext.iterator.includes',
|
||||
'esnext.iterator.join',
|
||||
'esnext.promise.all-keyed',
|
||||
'esnext.promise.all-settled-keyed',
|
||||
],
|
||||
};
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
require('../../modules/es.object.create');
|
||||
require('../../modules/es.object.to-string');
|
||||
require('../../modules/es.promise');
|
||||
require('../../modules/es.reflect.own-keys');
|
||||
require('../../modules/esnext.promise.all-keyed');
|
||||
var call = require('../../internals/function-call');
|
||||
var isCallable = require('../../internals/is-callable');
|
||||
var path = require('../../internals/path');
|
||||
|
||||
var Promise = path.Promise;
|
||||
var $allKeyed = Promise.allKeyed;
|
||||
|
||||
module.exports = function allKeyed(promises) {
|
||||
return call($allKeyed, isCallable(this) ? this : Promise, promises);
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
require('../../modules/es.object.create');
|
||||
require('../../modules/es.object.to-string');
|
||||
require('../../modules/es.promise');
|
||||
require('../../modules/es.reflect.own-keys');
|
||||
require('../../modules/esnext.promise.all-settled-keyed');
|
||||
var call = require('../../internals/function-call');
|
||||
var isCallable = require('../../internals/is-callable');
|
||||
var path = require('../../internals/path');
|
||||
|
||||
var Promise = path.Promise;
|
||||
var $allSettledKeyed = Promise.allSettledKeyed;
|
||||
|
||||
module.exports = function allSettledKeyed(promises) {
|
||||
return call($allSettledKeyed, isCallable(this) ? this : Promise, promises);
|
||||
};
|
||||
@@ -1,5 +1,9 @@
|
||||
'use strict';
|
||||
var parent = require('../../stable/promise');
|
||||
require('../../modules/es.object.create');
|
||||
require('../../modules/es.reflect.own-keys');
|
||||
require('../../modules/esnext.promise.all-keyed');
|
||||
require('../../modules/esnext.promise.all-settled-keyed');
|
||||
// TODO: Remove from `core-js@4`
|
||||
require('../../modules/esnext.promise.try');
|
||||
require('../../modules/esnext.promise.with-resolvers');
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
'use strict';
|
||||
var parent = require('../../actual/promise/all-keyed');
|
||||
|
||||
module.exports = parent;
|
||||
@@ -0,0 +1,4 @@
|
||||
'use strict';
|
||||
var parent = require('../../actual/promise/all-settled-keyed');
|
||||
|
||||
module.exports = parent;
|
||||
@@ -0,0 +1,57 @@
|
||||
'use strict';
|
||||
var $ = require('../internals/export');
|
||||
var aCallable = require('../internals/a-callable');
|
||||
var anObject = require('../internals/an-object');
|
||||
var call = require('../internals/function-call');
|
||||
var createProperty = require('../internals/create-property');
|
||||
var getBuiltIn = require('../internals/get-built-in');
|
||||
var getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor');
|
||||
var newPromiseCapabilityModule = require('../internals/new-promise-capability');
|
||||
var perform = require('../internals/perform');
|
||||
|
||||
var create = getBuiltIn('Object', 'create');
|
||||
var ownKeys = getBuiltIn('Reflect', 'ownKeys');
|
||||
|
||||
// `Promise.allKeyed` method
|
||||
// https://github.com/tc39/proposal-await-dictionary
|
||||
$({ target: 'Promise', stat: true }, {
|
||||
allKeyed: function allKeyed(promises) {
|
||||
var C = this;
|
||||
var capability = newPromiseCapabilityModule.f(C);
|
||||
var resolve = capability.resolve;
|
||||
var reject = capability.reject;
|
||||
var result = perform(function () {
|
||||
var promiseResolve = aCallable(C.resolve);
|
||||
var allKeys = ownKeys(anObject(promises));
|
||||
var keys = [];
|
||||
var values = [];
|
||||
var remaining = 1;
|
||||
var counter = 0;
|
||||
for (var i = 0; i < allKeys.length; i++) (function (key) {
|
||||
var desc = getOwnPropertyDescriptor.f(promises, key);
|
||||
if (desc && desc.enumerable) {
|
||||
var index = counter;
|
||||
var alreadyCalled = false;
|
||||
remaining++;
|
||||
keys[index] = key;
|
||||
values[index] = undefined;
|
||||
call(promiseResolve, C, promises[key]).then(function (value) {
|
||||
if (alreadyCalled) return;
|
||||
alreadyCalled = true;
|
||||
values[index] = value;
|
||||
--remaining;
|
||||
if (remaining === 0) {
|
||||
var res = create(null);
|
||||
for (var j = 0; j < keys.length; j++) createProperty(res, keys[j], values[j]);
|
||||
resolve(res);
|
||||
}
|
||||
}, reject);
|
||||
counter++;
|
||||
}
|
||||
})(allKeys[i]);
|
||||
--remaining || resolve(create(null));
|
||||
});
|
||||
if (result.error) reject(result.value);
|
||||
return capability.promise;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
'use strict';
|
||||
var $ = require('../internals/export');
|
||||
var aCallable = require('../internals/a-callable');
|
||||
var anObject = require('../internals/an-object');
|
||||
var call = require('../internals/function-call');
|
||||
var createProperty = require('../internals/create-property');
|
||||
var getBuiltIn = require('../internals/get-built-in');
|
||||
var getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor');
|
||||
var newPromiseCapabilityModule = require('../internals/new-promise-capability');
|
||||
var perform = require('../internals/perform');
|
||||
|
||||
var create = getBuiltIn('Object', 'create');
|
||||
var ownKeys = getBuiltIn('Reflect', 'ownKeys');
|
||||
|
||||
// `Promise.allSettledKeyed` method
|
||||
// https://github.com/tc39/proposal-await-dictionary
|
||||
$({ target: 'Promise', stat: true }, {
|
||||
allSettledKeyed: function allSettledKeyed(promises) {
|
||||
var C = this;
|
||||
var capability = newPromiseCapabilityModule.f(C);
|
||||
var resolve = capability.resolve;
|
||||
var reject = capability.reject;
|
||||
var result = perform(function () {
|
||||
var promiseResolve = aCallable(C.resolve);
|
||||
var allKeys = ownKeys(anObject(promises));
|
||||
var keys = [];
|
||||
var values = [];
|
||||
var remaining = 1;
|
||||
var counter = 0;
|
||||
for (var i = 0; i < allKeys.length; i++) (function (key) {
|
||||
var desc = getOwnPropertyDescriptor.f(promises, key);
|
||||
if (desc && desc.enumerable) {
|
||||
var createElementResolver = function (rejection) {
|
||||
return function (value) {
|
||||
if (alreadyCalled) return;
|
||||
alreadyCalled = true;
|
||||
values[index] = rejection
|
||||
? { status: 'rejected', reason: value }
|
||||
: { status: 'fulfilled', value: value };
|
||||
if (--remaining) return;
|
||||
var res = create(null);
|
||||
for (var j = 0; j < keys.length; j++) createProperty(res, keys[j], values[j]);
|
||||
resolve(res);
|
||||
};
|
||||
};
|
||||
var index = counter;
|
||||
var alreadyCalled = false;
|
||||
remaining++;
|
||||
keys[index] = key;
|
||||
values[index] = undefined;
|
||||
call(promiseResolve, C, promises[key]).then(createElementResolver(false), createElementResolver(true));
|
||||
counter++;
|
||||
}
|
||||
})(allKeys[i]);
|
||||
--remaining || resolve(create(null));
|
||||
});
|
||||
if (result.error) reject(result.value);
|
||||
return capability.promise;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
'use strict';
|
||||
// https://github.com/tc39/proposal-await-dictionary
|
||||
require('../modules/esnext.promise.all-keyed');
|
||||
require('../modules/esnext.promise.all-settled-keyed');
|
||||
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
var parent = require('./4');
|
||||
|
||||
require('../proposals/await-dictionary');
|
||||
require('../proposals/decorator-metadata-v2');
|
||||
require('../proposals/iterator-includes');
|
||||
require('../proposals/iterator-join');
|
||||
|
||||
@@ -2068,6 +2068,12 @@ GLOBAL.tests = {
|
||||
'esnext.set.add-all': function () {
|
||||
return Set.prototype.addAll;
|
||||
},
|
||||
'esnext.promise.all-keyed': function () {
|
||||
return Promise.allKeyed;
|
||||
},
|
||||
'esnext.promise.all-settled-keyed': function () {
|
||||
return Promise.allSettledKeyed;
|
||||
},
|
||||
'esnext.set.delete-all': function () {
|
||||
return Set.prototype.deleteAll;
|
||||
},
|
||||
|
||||
@@ -725,6 +725,8 @@ for (PATH of ['core-js-pure', 'core-js']) {
|
||||
ok(load(NS, 'iterator/join')([1, 2].values()) === '1,2');
|
||||
ok(typeof load(NS, 'iterator/to-async') == 'function');
|
||||
ok(typeof load(NS, 'iterator/windows') == 'function');
|
||||
ok(load(NS, 'promise/all-keyed')({}) instanceof Promise);
|
||||
ok(load(NS, 'promise/all-settled-keyed')({}) instanceof Promise);
|
||||
ok(load(NS, 'symbol/metadata'));
|
||||
|
||||
const instanceGroup = load(NS, 'instance/group');
|
||||
@@ -933,6 +935,7 @@ for (PATH of ['core-js-pure', 'core-js']) {
|
||||
load('proposals/async-explicit-resource-management');
|
||||
load('proposals/async-iteration');
|
||||
load('proposals/async-iterator-helpers');
|
||||
load('proposals/await-dictionary');
|
||||
load('proposals/change-array-by-copy');
|
||||
load('proposals/change-array-by-copy-stage-4');
|
||||
load('proposals/collection-methods');
|
||||
|
||||
@@ -1364,6 +1364,10 @@ const forbidCompletelyNonExistentBuiltIns = {
|
||||
'iterateKeys',
|
||||
'iterateValues',
|
||||
] }],
|
||||
'es/no-nonstandard-promise-properties': [ERROR, { allow: [
|
||||
'allKeyed',
|
||||
'allSettledKeyed',
|
||||
] }],
|
||||
'es/no-nonstandard-reflect-properties': [ERROR, { allow: [
|
||||
// TODO: drop from `core-js@4`
|
||||
'defineMetadata',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Promise from 'core-js-pure/es/promise';
|
||||
import create from 'core-js-pure/es/object/create';
|
||||
import ITERATOR from 'core-js-pure/es/symbol/iterator';
|
||||
import ASYNC_ITERATOR from 'core-js-pure/es/symbol/async-iterator';
|
||||
|
||||
@@ -7,6 +8,18 @@ export function is(a, b) {
|
||||
return a === b ? a !== 0 || 1 / a === 1 / b : a !== a && b !== b;
|
||||
}
|
||||
|
||||
// null-proto copy of the expected object: `deepEqual` of a null-proto result against
|
||||
// a plain literal is sensitive to prototype identity in some QUnit versions / realms
|
||||
export function nullProto(source) {
|
||||
// plain copy loop: helpers run inside the unit-pure bundles too, where the modern
|
||||
// standard library must not be touched
|
||||
const result = create(null);
|
||||
for (const key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) result[key] = source[key];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function createIterator(elements, methods) {
|
||||
let index = 0;
|
||||
const iterator = {
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
QUnit.test('Promise.allKeyed', assert => {
|
||||
assert.isFunction(Promise.allKeyed);
|
||||
assert.arity(Promise.allKeyed, 1);
|
||||
assert.looksNative(Promise.allKeyed);
|
||||
assert.nonEnumerable(Promise, 'allKeyed');
|
||||
assert.true(Promise.allKeyed({}) instanceof Promise, 'returns a promise');
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, resolved with primitives', assert => {
|
||||
return Promise.allKeyed({
|
||||
a: 1,
|
||||
b: Promise.resolve(2),
|
||||
c: 3,
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
}, 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, resolved', assert => {
|
||||
return Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.resolve(2),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
}, 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, resolved with rejection', assert => {
|
||||
return Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.reject(2),
|
||||
c: Promise.resolve(3),
|
||||
}).then(() => {
|
||||
assert.avoid();
|
||||
}, error => {
|
||||
assert.same(error, 2, 'rejected with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, resolved with empty object', assert => {
|
||||
return Promise.allKeyed({}).then(it => {
|
||||
assert.deepEqual(it, {}, 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, resolved with hidden attributes', assert => {
|
||||
const obj = Object.create({ proto: Promise.resolve('hidden') });
|
||||
obj.visible = Promise.resolve(42);
|
||||
Object.defineProperty(obj, 'invisible', { value: Promise.resolve(99), enumerable: false });
|
||||
return Promise.allKeyed(obj).then(it => {
|
||||
assert.deepEqual(it, { visible: 42 }, 'ignores prototype/invisible');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, rejected on incorrect input', assert => {
|
||||
return Promise.allKeyed('string').then(() => {
|
||||
assert.avoid();
|
||||
}, error => {
|
||||
assert.true(error instanceof TypeError, 'error is TypeError');
|
||||
assert.required('rejected as expected');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, resolved with timeouts', assert => {
|
||||
return Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: new Promise(resolve => setTimeout(() => resolve(2), 10)),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
}, 'keeps correct mapping, even with delays');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, subclassing', assert => {
|
||||
const { allKeyed, resolve } = Promise;
|
||||
function SubPromise(executor) {
|
||||
executor(() => { /* empty */ }, () => { /* empty */ });
|
||||
}
|
||||
SubPromise.resolve = resolve.bind(Promise);
|
||||
assert.true(allKeyed.call(SubPromise, { a: Promise.resolve(1) }) instanceof SubPromise, 'subclassing, `this` pattern');
|
||||
|
||||
function FakePromise1() { /* empty */ }
|
||||
function FakePromise2(executor) {
|
||||
executor(null, () => { /* empty */ });
|
||||
}
|
||||
function FakePromise3(executor) {
|
||||
executor(() => { /* empty */ }, null);
|
||||
}
|
||||
FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = resolve.bind(Promise);
|
||||
assert.throws(() => {
|
||||
allKeyed.call(FakePromise1, { a: Promise.resolve(1) });
|
||||
}, 'NewPromiseCapability validations, #1');
|
||||
assert.throws(() => {
|
||||
allKeyed.call(FakePromise2, { a: Promise.resolve(1) });
|
||||
}, 'NewPromiseCapability validations, #2');
|
||||
assert.throws(() => {
|
||||
allKeyed.call(FakePromise3, { a: Promise.resolve(1) });
|
||||
}, 'NewPromiseCapability validations, #3');
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, without constructor context', assert => {
|
||||
const { allKeyed } = Promise;
|
||||
assert.throws(() => allKeyed({ a: Promise.resolve(1) }), TypeError, 'Throws if called without a constructor context');
|
||||
assert.throws(() => allKeyed.call(null, { a: Promise.resolve(1) }), TypeError, 'Throws if called with null as this');
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, result object has null prototype', assert => {
|
||||
return Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.resolve(2),
|
||||
}).then(result => {
|
||||
assert.strictEqual(
|
||||
Object.getPrototypeOf(result),
|
||||
null,
|
||||
'Result object has null prototype',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, symbol keys', assert => {
|
||||
const symA = Symbol('A');
|
||||
const symB = Symbol('B');
|
||||
return Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
[symA]: Promise.resolve(2),
|
||||
[symB]: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.same(it.a, 1, 'string key');
|
||||
assert.same(it[symA], 2, 'symbol key A');
|
||||
assert.same(it[symB], 3, 'symbol key B');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, keys order', assert => {
|
||||
return Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: new Promise(resolve => setTimeout(() => resolve(2), 10)),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
const actualKeys = Object.keys(it);
|
||||
assert.deepEqual(actualKeys, ['a', 'b', 'c'], 'correct order in the case when promises resolves in different order');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,166 @@
|
||||
QUnit.test('Promise.allSettledKeyed', assert => {
|
||||
assert.isFunction(Promise.allSettledKeyed);
|
||||
assert.arity(Promise.allSettledKeyed, 1);
|
||||
assert.looksNative(Promise.allSettledKeyed);
|
||||
assert.nonEnumerable(Promise, 'allSettledKeyed');
|
||||
assert.true(Promise.allSettledKeyed({}) instanceof Promise, 'returns a promise');
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, resolved', assert => {
|
||||
return Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.resolve(2),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, {
|
||||
a: { value: 1, status: 'fulfilled' },
|
||||
b: { value: 2, status: 'fulfilled' },
|
||||
c: { value: 3, status: 'fulfilled' },
|
||||
}, 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, resolved with primitives', assert => {
|
||||
return Promise.allSettledKeyed({
|
||||
a: 1,
|
||||
b: Promise.resolve(2),
|
||||
c: 3,
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, {
|
||||
a: { value: 1, status: 'fulfilled' },
|
||||
b: { value: 2, status: 'fulfilled' },
|
||||
c: { value: 3, status: 'fulfilled' },
|
||||
}, 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, resolved with rejection', assert => {
|
||||
return Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.reject(2),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, {
|
||||
a: { value: 1, status: 'fulfilled' },
|
||||
b: { reason: 2, status: 'rejected' },
|
||||
c: { value: 3, status: 'fulfilled' },
|
||||
}, 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, rejected', assert => {
|
||||
return Promise.allSettledKeyed().then(() => {
|
||||
assert.avoid();
|
||||
}, () => {
|
||||
assert.required('rejected as expected');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, resolved with empty object', assert => {
|
||||
return Promise.allSettledKeyed({}).then(it => {
|
||||
assert.deepEqual(it, {}, 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, resolved with hidden attributes', assert => {
|
||||
const obj = Object.create({ proto: Promise.resolve('hidden') });
|
||||
obj.visible = Promise.resolve(42);
|
||||
Object.defineProperty(obj, 'invisible', { value: Promise.resolve(99), enumerable: false });
|
||||
return Promise.allSettledKeyed(obj).then(it => {
|
||||
assert.deepEqual(it, { visible: { status: 'fulfilled', value: 42 } }, 'ignores prototype/invisible');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, rejected on incorrect input', assert => {
|
||||
return Promise.allSettledKeyed('string').then(() => {
|
||||
assert.avoid();
|
||||
}, error => {
|
||||
assert.true(error instanceof TypeError, 'error is TypeError');
|
||||
assert.required('rejected as expected');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, resolved with timeouts', assert => {
|
||||
return Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: new Promise(resolve => setTimeout(() => resolve(2), 10)),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, {
|
||||
a: { value: 1, status: 'fulfilled' },
|
||||
b: { value: 2, status: 'fulfilled' },
|
||||
c: { value: 3, status: 'fulfilled' },
|
||||
}, 'keeps correct mapping, even with delays');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, subclassing', assert => {
|
||||
const { allSettledKeyed, resolve } = Promise;
|
||||
function SubPromise(executor) {
|
||||
executor(() => { /* empty */ }, () => { /* empty */ });
|
||||
}
|
||||
SubPromise.resolve = resolve.bind(Promise);
|
||||
assert.true(allSettledKeyed.call(SubPromise, { a: 1, b: 2, c: 3 }) instanceof SubPromise, 'subclassing, `this` pattern');
|
||||
|
||||
function FakePromise1() { /* empty */ }
|
||||
function FakePromise2(executor) {
|
||||
executor(null, () => { /* empty */ });
|
||||
}
|
||||
function FakePromise3(executor) {
|
||||
executor(() => { /* empty */ }, null);
|
||||
}
|
||||
FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = resolve.bind(Promise);
|
||||
assert.throws(() => {
|
||||
allSettledKeyed.call(FakePromise1, { a: 1, b: 2, c: 3 });
|
||||
}, 'NewPromiseCapability validations, #1');
|
||||
assert.throws(() => {
|
||||
allSettledKeyed.call(FakePromise2, { a: 1, b: 2, c: 3 });
|
||||
}, 'NewPromiseCapability validations, #2');
|
||||
assert.throws(() => {
|
||||
allSettledKeyed.call(FakePromise3, { a: 1, b: 2, c: 3 });
|
||||
}, 'NewPromiseCapability validations, #3');
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, without constructor context', assert => {
|
||||
const { allSettledKeyed } = Promise;
|
||||
assert.throws(() => allSettledKeyed({ a: Promise.resolve(1) }), TypeError, 'Throws if called without a constructor context');
|
||||
assert.throws(() => allSettledKeyed.call(null, { a: Promise.resolve(1) }), TypeError, 'Throws if called with null as this');
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, result object has null prototype', assert => {
|
||||
return Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.resolve(2),
|
||||
}).then(result => {
|
||||
assert.strictEqual(
|
||||
Object.getPrototypeOf(result),
|
||||
null,
|
||||
'Result object has null prototype',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, symbol keys', assert => {
|
||||
const symA = Symbol('A');
|
||||
const symB = Symbol('B');
|
||||
return Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
[symA]: Promise.resolve(2),
|
||||
[symB]: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.deepEqual(it.a, { status: 'fulfilled', value: 1 }, 'string key');
|
||||
assert.deepEqual(it[symA], { status: 'fulfilled', value: 2 }, 'symbol key A');
|
||||
assert.deepEqual(it[symB], { status: 'fulfilled', value: 3 }, 'symbol key B');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, keys order', assert => {
|
||||
return Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: new Promise(resolve => setTimeout(() => resolve(2), 10)),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
const actualKeys = Object.keys(it);
|
||||
assert.deepEqual(actualKeys, ['a', 'b', 'c'], 'correct order in the case when promises resolves in different order');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,176 @@
|
||||
import { nullProto } from '../helpers/helpers.js';
|
||||
|
||||
import $allKeyed from 'core-js-pure/actual/promise/all-keyed';
|
||||
import Promise from 'core-js-pure/actual/promise';
|
||||
import create from 'core-js-pure/es/object/create';
|
||||
import defineProperty from 'core-js-pure/es/object/define-property';
|
||||
import getPrototypeOf from 'core-js-pure/es/object/get-prototype-of';
|
||||
import keys from 'core-js-pure/es/object/keys';
|
||||
import Symbol from 'core-js-pure/es/symbol';
|
||||
|
||||
QUnit.test('Promise.allKeyed', assert => {
|
||||
assert.isFunction(Promise.allKeyed);
|
||||
assert.arity(Promise.allKeyed, 1);
|
||||
assert.true(Promise.allKeyed({}) instanceof Promise, 'returns a promise');
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, resolved', assert => {
|
||||
return Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.resolve(2),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, nullProto({
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
}), 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, resolved with primitives', assert => {
|
||||
return Promise.allKeyed({
|
||||
a: 1,
|
||||
b: Promise.resolve(2),
|
||||
c: 3,
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, nullProto({
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
}), 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, resolved with rejection', assert => {
|
||||
return Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.reject(2),
|
||||
c: Promise.resolve(3),
|
||||
}).then(() => {
|
||||
assert.avoid();
|
||||
}, error => {
|
||||
assert.same(error, 2, 'rejected with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, resolved with empty object', assert => {
|
||||
return Promise.allKeyed({}).then(it => {
|
||||
assert.deepEqual(it, nullProto({}), 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, resolved with hidden attributes', assert => {
|
||||
const obj = create({ proto: Promise.resolve('hidden') });
|
||||
obj.visible = Promise.resolve(42);
|
||||
defineProperty(obj, 'invisible', { value: Promise.resolve(99), enumerable: false });
|
||||
return Promise.allKeyed(obj).then(it => {
|
||||
assert.deepEqual(it, nullProto({ visible: 42 }), 'ignores prototype/invisible');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, rejected on incorrect input', assert => {
|
||||
return Promise.allKeyed('string').then(() => {
|
||||
assert.avoid();
|
||||
}, error => {
|
||||
assert.true(error instanceof TypeError, 'error is TypeError');
|
||||
assert.required('rejected as expected');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, resolved with timeouts', assert => {
|
||||
return Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: new Promise(resolve => setTimeout(() => resolve(2), 10)),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, nullProto({
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
}), 'keeps correct mapping, even with delays');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, subclassing', assert => {
|
||||
const { allKeyed, resolve } = Promise;
|
||||
function SubPromise(executor) {
|
||||
executor(() => { /* empty */ }, () => { /* empty */ });
|
||||
}
|
||||
SubPromise.resolve = resolve.bind(Promise);
|
||||
assert.true(allKeyed.call(SubPromise, { a: Promise.resolve(1) }) instanceof SubPromise, 'subclassing, `this` pattern');
|
||||
|
||||
function FakePromise1() { /* empty */ }
|
||||
function FakePromise2(executor) {
|
||||
executor(null, () => { /* empty */ });
|
||||
}
|
||||
function FakePromise3(executor) {
|
||||
executor(() => { /* empty */ }, null);
|
||||
}
|
||||
FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = resolve.bind(Promise);
|
||||
assert.throws(() => {
|
||||
allKeyed.call(FakePromise1, { a: Promise.resolve(1) });
|
||||
}, 'NewPromiseCapability validations, #1');
|
||||
assert.throws(() => {
|
||||
allKeyed.call(FakePromise2, { a: Promise.resolve(1) });
|
||||
}, 'NewPromiseCapability validations, #2');
|
||||
assert.throws(() => {
|
||||
allKeyed.call(FakePromise3, { a: Promise.resolve(1) });
|
||||
}, 'NewPromiseCapability validations, #3');
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, without constructor context', assert => {
|
||||
const { allKeyed } = Promise;
|
||||
assert.throws(() => allKeyed({ a: Promise.resolve(1) }), TypeError, 'Throws if called without a constructor context');
|
||||
assert.throws(() => allKeyed.call(null, { a: Promise.resolve(1) }), TypeError, 'Throws if called with null as this');
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, method from direct entry, without constructor context', assert => {
|
||||
return $allKeyed({ a: Promise.resolve(1) }).then(it => {
|
||||
assert.deepEqual(it, nullProto({ a: 1 }), 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, method from direct entry, with null context', assert => {
|
||||
return $allKeyed.call(null, { a: Promise.resolve(1) }).then(it => {
|
||||
assert.deepEqual(it, nullProto({ a: 1 }), 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, result object has null prototype', assert => {
|
||||
return Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.resolve(2),
|
||||
}).then(result => {
|
||||
assert.strictEqual(
|
||||
getPrototypeOf(result),
|
||||
null,
|
||||
'Result object has null prototype',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, symbol keys', assert => {
|
||||
const symA = Symbol('A');
|
||||
const symB = Symbol('B');
|
||||
return Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
[symA]: Promise.resolve(2),
|
||||
[symB]: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.same(it.a, 1, 'string key');
|
||||
assert.same(it[symA], 2, 'symbol key A');
|
||||
assert.same(it[symB], 3, 'symbol key B');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allKeyed, keys order', assert => {
|
||||
return Promise.allKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: new Promise(resolve => setTimeout(() => resolve(2), 10)),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
const actualKeys = keys(it);
|
||||
assert.deepEqual(actualKeys, ['a', 'b', 'c'], 'correct order in the case when promises resolves in different order');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,186 @@
|
||||
import { nullProto } from '../helpers/helpers.js';
|
||||
|
||||
import $allSettledKeyed from 'core-js-pure/actual/promise/all-settled-keyed';
|
||||
import Promise from 'core-js-pure/actual/promise';
|
||||
import create from 'core-js-pure/es/object/create';
|
||||
import defineProperty from 'core-js-pure/es/object/define-property';
|
||||
import getPrototypeOf from 'core-js-pure/es/object/get-prototype-of';
|
||||
import keys from 'core-js-pure/es/object/keys';
|
||||
import Symbol from 'core-js-pure/es/symbol';
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed', assert => {
|
||||
const { allSettledKeyed } = Promise;
|
||||
assert.isFunction(allSettledKeyed);
|
||||
assert.arity(allSettledKeyed, 1);
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, resolved', assert => {
|
||||
return Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.resolve(2),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, nullProto({
|
||||
a: { value: 1, status: 'fulfilled' },
|
||||
b: { value: 2, status: 'fulfilled' },
|
||||
c: { value: 3, status: 'fulfilled' },
|
||||
}), 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, resolved with primitives', assert => {
|
||||
return Promise.allSettledKeyed({
|
||||
a: 1,
|
||||
b: Promise.resolve(2),
|
||||
c: 3,
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, nullProto({
|
||||
a: { value: 1, status: 'fulfilled' },
|
||||
b: { value: 2, status: 'fulfilled' },
|
||||
c: { value: 3, status: 'fulfilled' },
|
||||
}), 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, resolved with rejection', assert => {
|
||||
return Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.reject(2),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, nullProto({
|
||||
a: { value: 1, status: 'fulfilled' },
|
||||
b: { reason: 2, status: 'rejected' },
|
||||
c: { value: 3, status: 'fulfilled' },
|
||||
}), 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, rejected', assert => {
|
||||
return Promise.allSettledKeyed().then(() => {
|
||||
assert.avoid();
|
||||
}, () => {
|
||||
assert.required('rejected as expected');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, resolved with empty object', assert => {
|
||||
return Promise.allSettledKeyed({}).then(it => {
|
||||
assert.deepEqual(it, nullProto({}), 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, resolved with hidden attributes', assert => {
|
||||
const obj = create({ proto: Promise.resolve('hidden') });
|
||||
obj.visible = Promise.resolve(42);
|
||||
defineProperty(obj, 'invisible', { value: Promise.resolve(99), enumerable: false });
|
||||
return Promise.allSettledKeyed(obj).then(it => {
|
||||
assert.deepEqual(it, nullProto({ visible: { status: 'fulfilled', value: 42 } }), 'ignores prototype/invisible');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, rejected on incorrect input', assert => {
|
||||
return Promise.allSettledKeyed('string').then(() => {
|
||||
assert.avoid();
|
||||
}, error => {
|
||||
assert.true(error instanceof TypeError, 'error is TypeError');
|
||||
assert.required('rejected as expected');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, resolved with timeouts', assert => {
|
||||
return Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: new Promise(resolve => setTimeout(() => resolve(2), 10)),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.deepEqual(it, nullProto({
|
||||
a: { value: 1, status: 'fulfilled' },
|
||||
b: { value: 2, status: 'fulfilled' },
|
||||
c: { value: 3, status: 'fulfilled' },
|
||||
}), 'keeps correct mapping, even with delays');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, subclassing', assert => {
|
||||
const { allSettledKeyed, resolve } = Promise;
|
||||
function SubPromise(executor) {
|
||||
executor(() => { /* empty */ }, () => { /* empty */ });
|
||||
}
|
||||
SubPromise.resolve = resolve.bind(Promise);
|
||||
assert.true(allSettledKeyed.call(SubPromise, { a: 1, b: 2, c: 3 }) instanceof SubPromise, 'subclassing, `this` pattern');
|
||||
|
||||
function FakePromise1() { /* empty */ }
|
||||
function FakePromise2(executor) {
|
||||
executor(null, () => { /* empty */ });
|
||||
}
|
||||
function FakePromise3(executor) {
|
||||
executor(() => { /* empty */ }, null);
|
||||
}
|
||||
FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = resolve.bind(Promise);
|
||||
assert.throws(() => {
|
||||
allSettledKeyed.call(FakePromise1, { a: 1, b: 2, c: 3 });
|
||||
}, 'NewPromiseCapability validations, #1');
|
||||
assert.throws(() => {
|
||||
allSettledKeyed.call(FakePromise2, { a: 1, b: 2, c: 3 });
|
||||
}, 'NewPromiseCapability validations, #2');
|
||||
assert.throws(() => {
|
||||
allSettledKeyed.call(FakePromise3, { a: 1, b: 2, c: 3 });
|
||||
}, 'NewPromiseCapability validations, #3');
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, without constructor context', assert => {
|
||||
const { allSettledKeyed } = Promise;
|
||||
assert.throws(() => allSettledKeyed({ a: Promise.resolve(1) }), TypeError, 'Throws if called without a constructor context');
|
||||
assert.throws(() => allSettledKeyed.call(null, { a: Promise.resolve(1) }), TypeError, 'Throws if called with null as this');
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, method from direct entry, without constructor context', assert => {
|
||||
return $allSettledKeyed({ a: Promise.resolve(1) }).then(it => {
|
||||
assert.deepEqual(it, nullProto({ a: { status: 'fulfilled', value: 1 } }), 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, method from direct entry, with null context', assert => {
|
||||
return $allSettledKeyed.call(null, { a: Promise.resolve(1) }).then(it => {
|
||||
assert.deepEqual(it, nullProto({ a: { status: 'fulfilled', value: 1 } }), 'resolved with a correct value');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, result object has null prototype', assert => {
|
||||
return Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.resolve(2),
|
||||
}).then(result => {
|
||||
assert.strictEqual(
|
||||
getPrototypeOf(result),
|
||||
null,
|
||||
'Result object has null prototype',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, symbol keys', assert => {
|
||||
const symA = Symbol('A');
|
||||
const symB = Symbol('B');
|
||||
return Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
[symA]: Promise.resolve(2),
|
||||
[symB]: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
assert.deepEqual(it.a, { status: 'fulfilled', value: 1 }, 'string key');
|
||||
assert.deepEqual(it[symA], { status: 'fulfilled', value: 2 }, 'symbol key A');
|
||||
assert.deepEqual(it[symB], { status: 'fulfilled', value: 3 }, 'symbol key B');
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('Promise.allSettledKeyed, keys order', assert => {
|
||||
return Promise.allSettledKeyed({
|
||||
a: Promise.resolve(1),
|
||||
b: new Promise(resolve => setTimeout(() => resolve(2), 10)),
|
||||
c: Promise.resolve(3),
|
||||
}).then(it => {
|
||||
const actualKeys = keys(it);
|
||||
assert.deepEqual(actualKeys, ['a', 'b', 'c'], 'correct order in the case when promises resolves in different order');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user