Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port tests from Promise.all to Promise.allSettled #2124

Merged
merged 6 commits into from Apr 17, 2019
Merged
Changes from 4 commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -18,3 +18,57 @@ function checkSequence(arr, message) {

return true;
}

function checkSettledPromises(settleds, expected, message) {
const prefix = message ? `${message}: ` : '';

assert.sameValue(Array.isArray(settleds), true, `${prefix}Settled values is an array`);

assert.sameValue(
settleds.length,
expected.length,
`${prefix}The settled values has a different length than expected`
);

settleds.forEach((settled, i) => {
assert.sameValue(
Object.prototype.hasOwnProperty.call(settled, 'status'),
true,
`${prefix}The settled value has a property status`
);

assert.sameValue(settled.status, expected[i].status, `${prefix}status for item ${i}`);

if (settled.status === 'fulfilled') {
assert.sameValue(
Object.prototype.hasOwnProperty.call(settled, 'value'),
true,
`${prefix}The fulfilled promise has a property named value`
);

assert.sameValue(
Object.prototype.hasOwnProperty.call(settled, 'reason'),
false,
`${prefix}The fulfilled promise has no property named reason`
);

assert.sameValue(settled.value, expected[i].value, `${prefix}value for item ${i}`);
} else {
assert.sameValue(settled.status, 'rejected', `${prefix}Valid statuses are only fulfilled or rejected`);

assert.sameValue(
Object.prototype.hasOwnProperty.call(settled, 'value'),
false,
`${prefix}The fulfilled promise has no property named value`
);

assert.sameValue(
Object.prototype.hasOwnProperty.call(settled, 'reason'),
true,
`${prefix}The fulfilled promise has a property named reason`
);

assert.sameValue(settled.reason, expected[i].reason, `${prefix}Reason value for item ${i}`);
}
});
}
@@ -0,0 +1,54 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-promise.allsettled-resolve-element-functions
description: >
Cannot change result value of resolved Promise.allSettled element after Promise.allSettled() returned.
info: |
Promise.allSettled Resolve Element Functions
1. Let F be the active function object.
2. Let alreadyCalled be F.[[AlreadyCalled]].
3. If alreadyCalled.[[Value]] is true, return undefined.
4. Set alreadyCalled.[[Value]] to true.
...
includes: [promiseHelper.js]
This conversation was marked as resolved by rwaldron

This comment has been minimized.

Copy link
@rwaldron

rwaldron Apr 17, 2019

Contributor

Missing features:

This comment has been minimized.

Copy link
@leobalter

leobalter Apr 17, 2019

Author Member

Not anymore 2b4d328

---*/

var callCount = 0;
var valuesArray;
var expected = [{ status: 'fulfilled', value: 'expectedValue' }];

function Constructor(executor) {
function resolve(values) {
callCount += 1;
valuesArray = values;
checkSettledPromises(values, expected, 'values');
}
executor(resolve, $ERROR);
}
Constructor.resolve = function(v) {
return v;
};

var p1OnFulfilled;

var p1 = {
then(onFulfilled, onRejected) {
p1OnFulfilled = onFulfilled;
onFulfilled("expectedValue");
}
};

assert.sameValue(callCount, 0, "callCount before call to all()");

Promise.allSettled.call(Constructor, [p1]);

assert.sameValue(callCount, 1, "callCount after call to all()");
checkSettledPromises(valuesArray, expected, 'valuesArray after call to all()');

p1OnFulfilled("unexpectedValue");

assert.sameValue(callCount, 1, "callCount after call to onFulfilled()");
checkSettledPromises(valuesArray, expected, 'valuesArray after call to onFulfilled()');
@@ -0,0 +1,58 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-promise.allsettled-resolve-element-functions
description: >
Cannot change result value of resolved Promise.allSettled elements.
info: |
Promise.allSettled Resolve Element Functions
1. Let F be the active function object.
2. Let alreadyCalled be F.[[AlreadyCalled]].
3. If alreadyCalled.[[Value]] is true, return undefined.
4. Set alreadyCalled.[[Value]] to true.
...
includes: [promiseHelper.js]
---*/

var callCount = 0;

function Constructor(executor) {
function resolve(values) {
callCount += 1;
checkSettledPromises(values, [
{
status: 'fulfilled',
value: 'expectedValue-p1'
},
{
status: 'fulfilled',
value: 'expectedValue-p2'
}
], 'values');
}
executor(resolve, $ERROR);
}
Constructor.resolve = function(v) {
return v;
};

var p1 = {
then(onFulfilled, onRejected) {
onFulfilled("expectedValue-p1");
onFulfilled("unexpectedValue-p1");
}
};
var p2 = {
then(onFulfilled, onRejected) {
onFulfilled("expectedValue-p2");
onFulfilled("unexpectedValue-p2");
}
};

assert.sameValue(callCount, 0, "callCount before call to all()");

Promise.allSettled.call(Constructor, [p1, p2]);

assert.sameValue(callCount, 1, "callCount after call to all()");
@@ -0,0 +1,48 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-promise.allsettled-resolve-element-functions
description: >
Cannot change result value of resolved Promise.allSettled element.
info: |
Promise.allSettled Resolve Element Functions
1. Let F be the active function object.
2. Let alreadyCalled be F.[[AlreadyCalled]].
3. If alreadyCalled.[[Value]] is true, return undefined.
4. Set alreadyCalled.[[Value]] to true.
...
includes: [promiseHelper.js]
---*/

var callCount = 0;

function Constructor(executor) {
function resolve(values) {
callCount += 1;
checkSettledPromises(values, [
{
status: 'fulfilled',
value: 'expectedValue'
}
], 'values');
}
executor(resolve, $ERROR);
}
Constructor.resolve = function(v) {
return v;
};

var p1 = {
then(onFulfilled, onRejected) {
onFulfilled("expectedValue");
onFulfilled("unexpectedValue");
}
};

assert.sameValue(callCount, 0, "callCount before call to all()");

Promise.allSettled.call(Constructor, [p1]);

assert.sameValue(callCount, 1, "callCount after call to all()");
@@ -0,0 +1,79 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-promise.allsettled
description: >
Throws a TypeError if capabilities executor already called with non-undefined values.
info: |
Promise.allSettled ( iterable )
...
3. Let promiseCapability be ? NewPromiseCapability(C).
...
GetCapabilitiesExecutor Functions
...
4. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
5. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
6. Set promiseCapability.[[Resolve]] to resolve.
7. Set promiseCapability.[[Reject]] to reject.
...
---*/

var checkPoint = "";
Promise.allSettled.call(function(executor) {
checkPoint += "a";
executor();
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}, []);
assert.sameValue(checkPoint, "abc", "executor initially called with no arguments");

var checkPoint = "";
Promise.allSettled.call(function(executor) {
checkPoint += "a";
executor(undefined, undefined);
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}, []);
assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)");

var checkPoint = "";
assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) {
checkPoint += "a";
executor(undefined, function() {});
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}, []);
}, "executor initially called with (undefined, function)");
assert.sameValue(checkPoint, "ab", "executor initially called with (undefined, function)");

var checkPoint = "";
assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) {
checkPoint += "a";
executor(function() {}, undefined);
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}, []);
}, "executor initially called with (function, undefined)");
assert.sameValue(checkPoint, "ab", "executor initially called with (function, undefined)");

var checkPoint = "";
assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) {
checkPoint += "a";
executor("invalid value", 123);
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}, []);
}, "executor initially called with (String, Number)");
assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)");
@@ -0,0 +1,82 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-promise.allsettled
description: >
Throws a TypeError if either resolve or reject capability is not callable.
info: |
Promise.allSettled ( iterable )
...
3. Let promiseCapability be ? NewPromiseCapability(C).
...
NewPromiseCapability ( C )
...
5. Let executor be CreateBuiltinFunction(steps, « [[Capability]] »).
6. Set executor.[[Capability]] to promiseCapability.
7. Let promise be ? Construct(C, « executor »).
8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
9. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
...
---*/

var checkPoint = "";
assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) {
checkPoint += "a";
}, []);
}, "executor not called at all");
assert.sameValue(checkPoint, "a", "executor not called at all");

var checkPoint = "";
assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) {
checkPoint += "a";
executor();
checkPoint += "b";
}, []);
}, "executor called with no arguments");
assert.sameValue(checkPoint, "ab", "executor called with no arguments");

var checkPoint = "";
assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) {
checkPoint += "a";
executor(undefined, undefined);
checkPoint += "b";
}, []);
}, "executor called with (undefined, undefined)");
assert.sameValue(checkPoint, "ab", "executor called with (undefined, undefined)");

var checkPoint = "";
assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) {
checkPoint += "a";
executor(undefined, function() {});
checkPoint += "b";
}, []);
}, "executor called with (undefined, function)");
assert.sameValue(checkPoint, "ab", "executor called with (undefined, function)");

var checkPoint = "";
assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) {
checkPoint += "a";
executor(function() {}, undefined);
checkPoint += "b";
}, []);
}, "executor called with (function, undefined)");
assert.sameValue(checkPoint, "ab", "executor called with (function, undefined)");

var checkPoint = "";
assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) {
checkPoint += "a";
executor(123, "invalid value");
checkPoint += "b";
}, []);
}, "executor called with (Number, String)");
assert.sameValue(checkPoint, "ab", "executor called with (Number, String)");
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.