Merge pull request #2131 from leobalter/resolve-lookup

Add tests for Promise.all|race resolve lookup
This commit is contained in:
Leo Balter 2019-04-25 13:31:39 -04:00 committed by GitHub
commit 1e4c5ae01e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 509 additions and 179 deletions

View File

@ -2,7 +2,7 @@
// This code is governed by the BSD license found in the LICENSE file. // This code is governed by the BSD license found in the LICENSE file.
/*--- /*---
es6id: 25.4.4.1 esid: sec-promise.all
description: > description: >
Throws a TypeError if capabilities executor already called with non-undefined values. Throws a TypeError if capabilities executor already called with non-undefined values.
info: | info: |
@ -13,67 +13,90 @@ info: |
7. ReturnIfAbrupt(promiseCapability). 7. ReturnIfAbrupt(promiseCapability).
... ...
25.4.1.5.1 GetCapabilitiesExecutor Functions GetCapabilitiesExecutor Functions
... ...
3. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception. 3. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
4. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception. 4. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
5. Set promiseCapability.[[Resolve]] to resolve. 5. Set promiseCapability.[[Resolve]] to resolve.
6. Set promiseCapability.[[Reject]] to reject. 6. Set promiseCapability.[[Reject]] to reject.
... ...
PerformPromiseAll ( iteratorRecord, constructor, resultCapability )
...
1. Let promiseResolve be ? Get(constructor, `"resolve"`).
1. If IsCallable(promiseResolve) is *false*, throw a *TypeError* exception.
...
---*/ ---*/
var checkPoint = ""; var checkPoint = "";
Promise.all.call(function(executor) { function fn1(executor) {
checkPoint += "a"; checkPoint += "a";
executor(); executor();
checkPoint += "b"; checkPoint += "b";
executor(function() {}, function() {}); executor(function() {}, function() {});
checkPoint += "c"; checkPoint += "c";
}, []); }
fn1.resolve = function() {};
Promise.all.call(fn1, []);
assert.sameValue(checkPoint, "abc", "executor initially called with no arguments"); assert.sameValue(checkPoint, "abc", "executor initially called with no arguments");
var checkPoint = ""; checkPoint = "";
Promise.all.call(function(executor) { function fn2(executor) {
checkPoint += "a"; checkPoint += "a";
executor(undefined, undefined); executor(undefined, undefined);
checkPoint += "b"; checkPoint += "b";
executor(function() {}, function() {}); executor(function() {}, function() {});
checkPoint += "c"; checkPoint += "c";
}, []); }
fn2.resolve = function() {};
Promise.all.call(fn2, []);
assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)"); assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)");
var checkPoint = ""; checkPoint = "";
function fn3(executor) {
checkPoint += "a";
executor(undefined, function() {});
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}
Object.defineProperty(fn3, 'resolve', {
get() { throw new Test262Error; }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.all.call(function(executor) { Promise.all.call(fn3, []);
checkPoint += "a";
executor(undefined, function() {});
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}, []);
}, "executor initially called with (undefined, function)"); }, "executor initially called with (undefined, function)");
assert.sameValue(checkPoint, "ab", "executor initially called with (undefined, function)"); assert.sameValue(checkPoint, "ab", "executor initially called with (undefined, function)");
var checkPoint = ""; checkPoint = "";
function fn4(executor) {
checkPoint += "a";
executor(function() {}, undefined);
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}
Object.defineProperty(fn4, 'resolve', {
get() { throw new Test262Error; }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.all.call(function(executor) { Promise.all.call(fn4, []);
checkPoint += "a";
executor(function() {}, undefined);
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}, []);
}, "executor initially called with (function, undefined)"); }, "executor initially called with (function, undefined)");
assert.sameValue(checkPoint, "ab", "executor initially called with (function, undefined)"); assert.sameValue(checkPoint, "ab", "executor initially called with (function, undefined)");
var checkPoint = ""; checkPoint = "";
function fn5(executor) {
checkPoint += "a";
executor("invalid value", 123);
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}
Object.defineProperty(fn5, 'resolve', {
get() { throw new Test262Error; }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.all.call(function(executor) { Promise.all.call(fn5, []);
checkPoint += "a";
executor("invalid value", 123);
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}, []);
}, "executor initially called with (String, Number)"); }, "executor initially called with (String, Number)");
assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)"); assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)");

View File

@ -25,59 +25,83 @@ info: |
---*/ ---*/
var checkPoint = ""; var checkPoint = "";
function fn1(executor) {
checkPoint += "a";
}
Object.defineProperty(fn1, 'resolve', {
get() { throw new Test262Error; }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.all.call(function(executor) { Promise.all.call(fn1, []);
checkPoint += "a";
}, []);
}, "executor not called at all"); }, "executor not called at all");
assert.sameValue(checkPoint, "a", "executor not called at all"); assert.sameValue(checkPoint, "a", "executor not called at all");
var checkPoint = ""; checkPoint = "";
function fn2(executor) {
checkPoint += "a";
executor();
checkPoint += "b";
}
Object.defineProperty(fn2, 'resolve', {
get() { throw new Test262Error; }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.all.call(function(executor) { Promise.all.call(fn2, []);
checkPoint += "a";
executor();
checkPoint += "b";
}, []);
}, "executor called with no arguments"); }, "executor called with no arguments");
assert.sameValue(checkPoint, "ab", "executor called with no arguments"); assert.sameValue(checkPoint, "ab", "executor called with no arguments");
var checkPoint = ""; checkPoint = "";
function fn3(executor) {
checkPoint += "a";
executor(undefined, undefined);
checkPoint += "b";
}
Object.defineProperty(fn3, 'resolve', {
get() { throw new Test262Error; }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.all.call(function(executor) { Promise.all.call(fn3, []);
checkPoint += "a";
executor(undefined, undefined);
checkPoint += "b";
}, []);
}, "executor called with (undefined, undefined)"); }, "executor called with (undefined, undefined)");
assert.sameValue(checkPoint, "ab", "executor called with (undefined, undefined)"); assert.sameValue(checkPoint, "ab", "executor called with (undefined, undefined)");
var checkPoint = ""; checkPoint = "";
function fn4(executor) {
checkPoint += "a";
executor(undefined, function() {});
checkPoint += "b";
}
Object.defineProperty(fn4, 'resolve', {
get() { throw new Test262Error; }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.all.call(function(executor) { Promise.all.call(fn4, []);
checkPoint += "a";
executor(undefined, function() {});
checkPoint += "b";
}, []);
}, "executor called with (undefined, function)"); }, "executor called with (undefined, function)");
assert.sameValue(checkPoint, "ab", "executor called with (undefined, function)"); assert.sameValue(checkPoint, "ab", "executor called with (undefined, function)");
var checkPoint = ""; checkPoint = "";
function fn5(executor) {
checkPoint += "a";
executor(function() {}, undefined);
checkPoint += "b";
}
Object.defineProperty(fn5, 'resolve', {
get() { throw new Test262Error; }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.all.call(function(executor) { Promise.all.call(fn5, []);
checkPoint += "a";
executor(function() {}, undefined);
checkPoint += "b";
}, []);
}, "executor called with (function, undefined)"); }, "executor called with (function, undefined)");
assert.sameValue(checkPoint, "ab", "executor called with (function, undefined)"); assert.sameValue(checkPoint, "ab", "executor called with (function, undefined)");
var checkPoint = ""; checkPoint = "";
function fn6(executor) {
checkPoint += "a";
executor(123, "invalid value");
checkPoint += "b";
}
Object.defineProperty(fn6, 'resolve', {
get() { throw new Test262Error; }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.all.call(function(executor) { Promise.all.call(fn6, []);
checkPoint += "a";
executor(123, "invalid value");
checkPoint += "b";
}, []);
}, "executor called with (Number, String)"); }, "executor called with (Number, String)");
assert.sameValue(checkPoint, "ab", "executor called with (Number, String)"); assert.sameValue(checkPoint, "ab", "executor called with (Number, String)");

View File

@ -45,11 +45,13 @@ info: |
features: [Symbol.iterator] features: [Symbol.iterator]
---*/ ---*/
var nextCount = 0;
var returnCount = 0; var returnCount = 0;
var iter = {}; var iter = {};
iter[Symbol.iterator] = function() { iter[Symbol.iterator] = function() {
return { return {
next: function() { next: function() {
nextCount += 1;
return { return {
done: true done: true
}; };
@ -68,6 +70,9 @@ var P = function(executor) {
}); });
}; };
P.resolve = Promise.resolve;
Promise.all.call(P, iter); Promise.all.call(P, iter);
assert.sameValue(nextCount, 1);
assert.sameValue(returnCount, 0); assert.sameValue(returnCount, 0);

View File

@ -54,6 +54,8 @@ var P = function(executor) {
}); });
}; };
P.resolve = Promise.resolve;
Promise.all.call(P, []) Promise.all.call(P, [])
.then(function() { .then(function() {
$DONE('Promise incorrectly fulfilled.'); $DONE('Promise incorrectly fulfilled.');

View File

@ -42,7 +42,7 @@ iterDoneSpy[Symbol.iterator] = function() {
}; };
Promise.resolve = function() { Promise.resolve = function() {
throw new Error(); throw new Test262Error();
}; };
Promise.all(iterDoneSpy); Promise.all(iterDoneSpy);

View File

@ -3,9 +3,8 @@
/*--- /*---
description: > description: >
Error retrieving the constructor's `resolve` method (closing iterator) Error retrieving the constructor's `resolve` method before iterator being used.
esid: sec-performpromiseall esid: sec-performpromiseall
es6id: 25.4.4.1
info: | info: |
11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability). 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
12. If result is an abrupt completion, 12. If result is an abrupt completion,
@ -13,23 +12,29 @@ info: |
IteratorClose(iterator, result). IteratorClose(iterator, result).
b. IfAbruptRejectPromise(result, promiseCapability). b. IfAbruptRejectPromise(result, promiseCapability).
[...] ...
25.4.4.1.1 Runtime Semantics: PerformPromiseAll Runtime Semantics: PerformPromiseAll
[...] ...
6. Repeat 1. Let promiseResolve be ? Get(constructor, `"resolve"`).
[...] ...
i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»). 1. Repeat,
j. ReturnIfAbrupt(nextPromise ). 1. Let next be IteratorStep(iteratorRecord).
...
1. Let nextPromise be ? Call(promiseResolve, constructor, < nextValue >).
features: [Symbol.iterator] features: [Symbol.iterator]
---*/ ---*/
var iter = {}; var iter = {};
var returnCount = 0; var returnCount = 0;
var nextCount = 0;
iter[Symbol.iterator] = function() { iter[Symbol.iterator] = function() {
return { return {
next: function() { next: function() {
nextCount += 1;
return { return {
done: false done: false
}; };
@ -41,11 +46,12 @@ iter[Symbol.iterator] = function() {
}; };
}; };
Object.defineProperty(Promise, 'resolve', { Object.defineProperty(Promise, 'resolve', {
get: function() { get() {
throw new Test262Error(); throw new Test262Error();
} }
}); });
Promise.all(iter); Promise.all(iter);
assert.sameValue(returnCount, 1); assert.sameValue(nextCount, 0);
assert.sameValue(returnCount, 0);

View File

@ -15,13 +15,15 @@ info: |
[...] [...]
25.4.4.1.1 Runtime Semantics: PerformPromiseAll Runtime Semantics: PerformPromiseAll
[...] ...
6. Repeat 1. Let promiseResolve be ? Get(constructor, `"resolve"`).
[...] ...
i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»). 1. Repeat,
j. ReturnIfAbrupt(nextPromise ). 1. Let next be IteratorStep(iteratorRecord).
...
1. Let nextPromise be ? Call(promiseResolve, constructor, < nextValue >).
flags: [async] flags: [async]
---*/ ---*/

View File

@ -0,0 +1,45 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Gets constructor's `resolve` method once from zero to many invocations.
esid: sec-promise.all
info: |
Runtime Semantics: PerformPromiseAll
1. Let promiseResolve be ? Get(constructor, `"resolve"`).
1. If IsCallable(promiseResolve) is false, throw a TypeError exception.
...
1. Repeat,
...
1. Let nextPromise be ? Call(promiseResolve, constructor, &laquo; nextValue &raquo;).
---*/
var p1 = Promise.resolve(1);
var p2 = Promise.resolve(1);
var p3 = Promise.reject(1);
var p4 = Promise.resolve(1);
var resolve = Promise.resolve;
var getCount = 0;
var callCount = 0;
Object.defineProperty(Promise, 'resolve', {
configurable: true,
get() {
getCount += 1;
return function() {
callCount += 1;
return resolve.apply(Promise, arguments);
};
}
});
Promise.all([p1, p2, p3, p4]);
assert.sameValue(
getCount, 1, 'Got `resolve` only once for each iterated value'
);
assert.sameValue(
callCount, 4, '`resolve` invoked once for each iterated value'
);

View File

@ -0,0 +1,42 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Gets constructor's `resolve` method once from zero to many invocations.
esid: sec-promise.allsettled
info: |
Runtime Semantics: PerformPromiseAll
1. Let promiseResolve be ? Get(constructor, `"resolve"`).
1. If IsCallable(promiseResolve) is false, throw a TypeError exception.
...
1. Repeat,
...
1. Let nextPromise be ? Call(promiseResolve, constructor, &laquo; nextValue &raquo;).
features: [Promise.allSettled]
---*/
var resolve = Promise.resolve;
var getCount = 0;
var callCount = 0;
Object.defineProperty(Promise, 'resolve', {
configurable: true,
get() {
getCount += 1;
return function() {
callCount += 1;
return resolve.apply(Promise, arguments);
};
}
});
Promise.all([]);
assert.sameValue(
getCount, 1, 'Got `resolve` only once for each iterated value'
);
assert.sameValue(
callCount, 0, '`resolve` not called for empty iterator'
);

View File

@ -16,6 +16,8 @@ features: [Symbol.species]
function C(executor) { function C(executor) {
executor(function() {}, function() {}); executor(function() {}, function() {});
} }
C.resolve = function() {};
Object.defineProperty(C, Symbol.species, { Object.defineProperty(C, Symbol.species, {
get: function() { get: function() {
$ERROR("Getter for Symbol.species called"); $ERROR("Getter for Symbol.species called");

View File

@ -24,57 +24,83 @@ features: [Promise.allSettled]
---*/ ---*/
var checkPoint = ''; var checkPoint = '';
Promise.allSettled.call(function(executor) { function fn1(executor) {
checkPoint += 'a'; checkPoint += 'a';
executor(); executor();
checkPoint += 'b'; checkPoint += 'b';
executor(function() {}, function() {}); executor(function() {}, function() {});
checkPoint += 'c'; checkPoint += 'c';
}, []); }
fn1.resolve = function() {
throw new Test262Error();
};
Promise.allSettled.call(fn1, []);
assert.sameValue(checkPoint, 'abc', 'executor initially called with no arguments'); assert.sameValue(checkPoint, 'abc', 'executor initially called with no arguments');
var checkPoint = ''; checkPoint = '';
Promise.allSettled.call(function(executor) { function fn2(executor) {
checkPoint += 'a'; checkPoint += 'a';
executor(undefined, undefined); executor(undefined, undefined);
checkPoint += 'b'; checkPoint += 'b';
executor(function() {}, function() {}); executor(function() {}, function() {});
checkPoint += 'c'; checkPoint += 'c';
}, []); }
fn2.resolve = function() {
throw new Test262Error();
};
Promise.allSettled.call(fn2, []);
assert.sameValue(checkPoint, 'abc', 'executor initially called with (undefined, undefined)'); assert.sameValue(checkPoint, 'abc', 'executor initially called with (undefined, undefined)');
var checkPoint = ''; checkPoint = '';
function fn3(executor) {
checkPoint += 'a';
executor(undefined, function() {});
checkPoint += 'b';
executor(function() {}, function() {});
checkPoint += 'c';
}
Object.defineProperty(fn3, 'resolve', {
get() {
throw new Test262Error();
}
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) { Promise.allSettled.call(fn3, []);
checkPoint += 'a';
executor(undefined, function() {});
checkPoint += 'b';
executor(function() {}, function() {});
checkPoint += 'c';
}, []);
}, 'executor initially called with (undefined, function)'); }, 'executor initially called with (undefined, function)');
assert.sameValue(checkPoint, 'ab', 'executor initially called with (undefined, function)'); assert.sameValue(checkPoint, 'ab', 'executor initially called with (undefined, function)');
var checkPoint = ''; checkPoint = '';
function fn4(executor) {
checkPoint += 'a';
executor(function() {}, undefined);
checkPoint += 'b';
executor(function() {}, function() {});
checkPoint += 'c';
}
Object.defineProperty(fn4, 'resolve', {
get() {
throw new Test262Error();
}
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) { Promise.allSettled.call(fn4, []);
checkPoint += 'a';
executor(function() {}, undefined);
checkPoint += 'b';
executor(function() {}, function() {});
checkPoint += 'c';
}, []);
}, 'executor initially called with (function, undefined)'); }, 'executor initially called with (function, undefined)');
assert.sameValue(checkPoint, 'ab', 'executor initially called with (function, undefined)'); assert.sameValue(checkPoint, 'ab', 'executor initially called with (function, undefined)');
var checkPoint = ''; checkPoint = '';
function fn5(executor) {
checkPoint += 'a';
executor('invalid value', 123);
checkPoint += 'b';
executor(function() {}, function() {});
checkPoint += 'c';
}
Object.defineProperty(fn5, 'resolve', {
get() {
throw new Test262Error();
}
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) { Promise.allSettled.call(fn5, []);
checkPoint += 'a';
executor('invalid value', 123);
checkPoint += 'b';
executor(function() {}, function() {});
checkPoint += 'c';
}, []);
}, 'executor initially called with (String, Number)'); }, 'executor initially called with (String, Number)');
assert.sameValue(checkPoint, 'ab', 'executor initially called with (String, Number)'); assert.sameValue(checkPoint, 'ab', 'executor initially called with (String, Number)');

View File

@ -25,59 +25,83 @@ features: [Promise.allSettled]
---*/ ---*/
var checkPoint = ''; var checkPoint = '';
function fn1(executor) {
checkPoint += 'a';
}
Object.defineProperty(fn1, 'resolve', {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) { Promise.allSettled.call(fn1, []);
checkPoint += 'a';
}, []);
}, 'executor not called at all'); }, 'executor not called at all');
assert.sameValue(checkPoint, 'a', 'executor not called at all'); assert.sameValue(checkPoint, 'a', 'executor not called at all');
var checkPoint = ''; checkPoint = '';
function fn2(executor) {
checkPoint += 'a';
executor();
checkPoint += 'b';
}
Object.defineProperty(fn2, 'resolve', {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) { Promise.allSettled.call(fn2, []);
checkPoint += 'a';
executor();
checkPoint += 'b';
}, []);
}, 'executor called with no arguments'); }, 'executor called with no arguments');
assert.sameValue(checkPoint, 'ab', 'executor called with no arguments'); assert.sameValue(checkPoint, 'ab', 'executor called with no arguments');
var checkPoint = ''; checkPoint = '';
function fn3(executor) {
checkPoint += 'a';
executor(undefined, undefined);
checkPoint += 'b';
}
Object.defineProperty(fn3, 'resolve', {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) { Promise.allSettled.call(fn3, []);
checkPoint += 'a';
executor(undefined, undefined);
checkPoint += 'b';
}, []);
}, 'executor called with (undefined, undefined)'); }, 'executor called with (undefined, undefined)');
assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, undefined)'); assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, undefined)');
var checkPoint = ''; checkPoint = '';
function fn4(executor) {
checkPoint += 'a';
executor(undefined, function() {});
checkPoint += 'b';
}
Object.defineProperty(fn4, 'resolve', {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) { Promise.allSettled.call(fn4, []);
checkPoint += 'a';
executor(undefined, function() {});
checkPoint += 'b';
}, []);
}, 'executor called with (undefined, function)'); }, 'executor called with (undefined, function)');
assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, function)'); assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, function)');
var checkPoint = ''; checkPoint = '';
function fn5(executor) {
checkPoint += 'a';
executor(function() {}, undefined);
checkPoint += 'b';
}
Object.defineProperty(fn5, 'resolve', {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) { Promise.allSettled.call(fn5, []);
checkPoint += 'a';
executor(function() {}, undefined);
checkPoint += 'b';
}, []);
}, 'executor called with (function, undefined)'); }, 'executor called with (function, undefined)');
assert.sameValue(checkPoint, 'ab', 'executor called with (function, undefined)'); assert.sameValue(checkPoint, 'ab', 'executor called with (function, undefined)');
var checkPoint = ''; checkPoint = '';
function fn6(executor) {
checkPoint += 'a';
executor(123, 'invalid value');
checkPoint += 'b';
}
Object.defineProperty(fn6, 'resolve', {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.allSettled.call(function(executor) { Promise.allSettled.call(fn6, []);
checkPoint += 'a';
executor(123, 'invalid value');
checkPoint += 'b';
}, []);
}, 'executor called with (Number, String)'); }, 'executor called with (Number, String)');
assert.sameValue(checkPoint, 'ab', 'executor called with (Number, String)'); assert.sameValue(checkPoint, 'ab', 'executor called with (Number, String)');

View File

@ -55,6 +55,10 @@ var P = function(executor) {
}); });
}; };
P.resolve = function() {
throw new Test262Error();
};
Promise.allSettled.call(P, iter); Promise.allSettled.call(P, iter);
assert.sameValue(returnCount, 0); assert.sameValue(returnCount, 0);

View File

@ -43,6 +43,10 @@ var P = function(executor) {
}); });
}; };
P.resolve = function() {
throw new Test262Error();
};
Promise.allSettled.call(P, []) Promise.allSettled.call(P, [])
.then(function() { .then(function() {
$DONE('Promise incorrectly fulfilled.'); $DONE('Promise incorrectly fulfilled.');

View File

@ -3,7 +3,7 @@
/*--- /*---
description: > description: >
Error retrieving the constructor's `resolve` method (closing iterator) Error retrieving the constructor's `resolve` method not opening iterator
esid: sec-promise.allsettled esid: sec-promise.allsettled
info: | info: |
6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability). 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
@ -21,9 +21,11 @@ features: [Promise.allSettled, Symbol.iterator]
var iter = {}; var iter = {};
var returnCount = 0; var returnCount = 0;
var nextCount = 0;
iter[Symbol.iterator] = function() { iter[Symbol.iterator] = function() {
return { return {
next() { next() {
nextCount += 1;
return { return {
done: false done: false
}; };
@ -42,4 +44,5 @@ Object.defineProperty(Promise, 'resolve', {
Promise.allSettled(iter); Promise.allSettled(iter);
assert.sameValue(returnCount, 1); assert.sameValue(nextCount, 0);
assert.sameValue(returnCount, 0);

View File

@ -22,4 +22,8 @@ Object.defineProperty(C, Symbol.species, {
} }
}); });
C.resolve = function() {
throw new Test262Error();
};
Promise.allSettled.call(C, []); Promise.allSettled.call(C, []);

View File

@ -23,57 +23,77 @@ info: |
---*/ ---*/
var checkPoint = ""; var checkPoint = "";
Promise.race.call(function(executor) { function fn1(executor) {
checkPoint += "a"; checkPoint += "a";
executor(); executor();
checkPoint += "b"; checkPoint += "b";
executor(function() {}, function() {}); executor(function() {}, function() {});
checkPoint += "c"; checkPoint += "c";
}, []); }
fn1.resolve = function() {
throw new Test262Error();
};
Promise.race.call(fn1 , []);
assert.sameValue(checkPoint, "abc", "executor initially called with no arguments"); assert.sameValue(checkPoint, "abc", "executor initially called with no arguments");
var checkPoint = ""; checkPoint = "";
Promise.race.call(function(executor) { function fn2(executor) {
checkPoint += "a"; checkPoint += "a";
executor(undefined, undefined); executor(undefined, undefined);
checkPoint += "b"; checkPoint += "b";
executor(function() {}, function() {}); executor(function() {}, function() {});
checkPoint += "c"; checkPoint += "c";
}, []); }
fn2.resolve = function() {
throw new Test262Error();
};
Promise.race.call(fn2 , []);
assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)"); assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)");
var checkPoint = ""; checkPoint = "";
function fn3(executor) {
checkPoint += "a";
executor(undefined, function() {});
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}
Object.defineProperty(fn3, "resolve", {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.race.call(function(executor) { Promise.race.call(fn3 , []);
checkPoint += "a";
executor(undefined, function() {});
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}, []);
}, "executor initially called with (undefined, function)"); }, "executor initially called with (undefined, function)");
assert.sameValue(checkPoint, "ab", "executor initially called with (undefined, function)"); assert.sameValue(checkPoint, "ab", "executor initially called with (undefined, function)");
var checkPoint = ""; checkPoint = "";
function fn4(executor) {
checkPoint += "a";
executor(function() {}, undefined);
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}
Object.defineProperty(fn4, "resolve", {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.race.call(function(executor) { Promise.race.call(fn4 , []);
checkPoint += "a";
executor(function() {}, undefined);
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}, []);
}, "executor initially called with (function, undefined)"); }, "executor initially called with (function, undefined)");
assert.sameValue(checkPoint, "ab", "executor initially called with (function, undefined)"); assert.sameValue(checkPoint, "ab", "executor initially called with (function, undefined)");
var checkPoint = ""; checkPoint = "";
function fn5(executor) {
checkPoint += "a";
executor("invalid value", 123);
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}
Object.defineProperty(fn5, "resolve", {
get() { throw new Test262Error(); }
});
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Promise.race.call(function(executor) { Promise.race.call(fn5 , []);
checkPoint += "a";
executor("invalid value", 123);
checkPoint += "b";
executor(function() {}, function() {});
checkPoint += "c";
}, []);
}, "executor initially called with (String, Number)"); }, "executor initially called with (String, Number)");
assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)"); assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)");

View File

@ -25,10 +25,14 @@ features: [Symbol.iterator]
---*/ ---*/
var iter = {}; var iter = {};
var returnCount = 0; var returnCount = 0;
var nextCount = 0;
iter[Symbol.iterator] = function() { iter[Symbol.iterator] = function() {
return { return {
next: function() { next: function() {
nextCount += 1;
return { return {
done: false done: false
}; };
@ -40,11 +44,12 @@ iter[Symbol.iterator] = function() {
}; };
}; };
Object.defineProperty(Promise, 'resolve', { Object.defineProperty(Promise, 'resolve', {
get: function() { get() {
throw new Test262Error(); throw new Test262Error();
} }
}); });
Promise.race(iter); Promise.race(iter);
assert.sameValue(returnCount, 1); assert.sameValue(nextCount, 0);
assert.sameValue(returnCount, 0);

View File

@ -0,0 +1,45 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Gets constructor's `resolve` method once from zero to many invocations.
esid: sec-promise.race
info: |
Runtime Semantics: PerformPromiseRace
1. Let promiseResolve be ? Get(constructor, `"resolve"`).
1. If IsCallable(promiseResolve) is false, throw a TypeError exception.
...
1. Repeat,
...
1. Let nextPromise be ? Call(promiseResolve, constructor, &laquo; nextValue &raquo;).
---*/
var p1 = Promise.resolve(1);
var p2 = Promise.resolve(1);
var p3 = Promise.reject(1);
var p4 = Promise.resolve(1);
var resolve = Promise.resolve;
var getCount = 0;
var callCount = 0;
Object.defineProperty(Promise, 'resolve', {
configurable: true,
get() {
getCount += 1;
return function() {
callCount += 1;
return resolve.apply(Promise, arguments);
};
}
});
Promise.race([p1, p2, p3, p4]);
assert.sameValue(
getCount, 1, 'Got `resolve` only once for each iterated value'
);
assert.sameValue(
callCount, 4, '`resolve` invoked once for each iterated value'
);

View File

@ -0,0 +1,41 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Gets constructor's `resolve` method once from zero to many invocations.
esid: sec-promise.race
info: |
Runtime Semantics: PerformPromiseRace
1. Let promiseResolve be ? Get(constructor, `"resolve"`).
1. If IsCallable(promiseResolve) is false, throw a TypeError exception.
...
1. Repeat,
...
1. Let nextPromise be ? Call(promiseResolve, constructor, &laquo; nextValue &raquo;).
---*/
var resolve = Promise.resolve;
var getCount = 0;
var callCount = 0;
Object.defineProperty(Promise, 'resolve', {
configurable: true,
get() {
getCount += 1;
return function() {
callCount += 1;
return resolve.apply(Promise, arguments);
};
}
});
Promise.race([]);
assert.sameValue(
getCount, 1, 'Got `resolve` only once for each iterated value'
);
assert.sameValue(
callCount, 0, '`resolve` not called for empty iterator'
);

View File

@ -17,9 +17,12 @@ function C(executor) {
executor(function() {}, function() {}); executor(function() {}, function() {});
} }
Object.defineProperty(C, Symbol.species, { Object.defineProperty(C, Symbol.species, {
get: function() { get() {
$ERROR("Getter for Symbol.species called"); throw new Test262Error("Getter for Symbol.species called");
} }
}); });
C.resolve = function() {
throw new Test262Error();
};
Promise.race.call(C, []); Promise.race.call(C, []);