v8/test/mjsunit/es6/promise-all.js
Andreas Haas 8c3c1b6c0f [mjsunit] Move the implementation of testAsync into a separate file
The original implementation of 'testAsync' in mjsunit.js required to
put the call to '%AbortJS' into an 'eval' statement. The reason is that
this call requires the flag --allow-natives-syntax to be set, but the
flag is not set in all mjsunit tests. With the use of 'eval'
compilation errors can be avoided.

The problem with this approach was that the fuzzer started to produce
test cases which include the line 'eval("%AbortJS(message)");', and
this line crashes intentionally. Different to the line
'%Abort(message)', however, the 'eval' statement cannot be filtered
so easily in the fuzzer. Therefore I pulled the implementation of
'testAsync' into a separate file to avoid the 'eval'.

Additional changes: I use '===' now instead of 'deepEquals' in
AsyncAssertion.equals because 'deepEquals' is not available outside
mjsunit.js. Using '===' seems more appropriate anyways because for
all tests but one it is sufficient, and it is more precise than
deepEquals.

R=gsathya@chromium.org

Bug: chromium:774841
Change-Id: I47270aa63ff5a1d6aa76a771f9276eaaf579c5ac
Reviewed-on: https://chromium-review.googlesource.com/1156598
Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54833}
2018-08-01 08:46:24 +00:00

87 lines
2.2 KiB
JavaScript

// Copyright 2018 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
load('test/mjsunit/test-async.js');
// We store the index in the hash code field of the Promise.all resolve
// element closures, so make sure we properly handle the cases where this
// magical field turns into a PropertyArray later.
(function() {
class MyPromise extends Promise {
then(resolve, reject) {
this.resolve = resolve;
}
};
const myPromise = new MyPromise(() => {});
MyPromise.all([myPromise]);
myPromise.resolve.x = 1;
myPromise.resolve(1);
})();
// Same test as above, but for PropertyDictionary.
(function() {
class MyPromise extends Promise {
then(resolve, reject) {
this.resolve = resolve;
}
};
const myPromise = new MyPromise(() => {});
MyPromise.all([myPromise]);
for (let i = 0; i < 1025; ++i) {
myPromise.resolve[`x${i}`] = i;
}
myPromise.resolve(1);
})();
// Test that we return a proper array even if (custom) "then" invokes the
// resolve callbacks right away.
(function() {
class MyPromise extends Promise {
constructor(executor, id) {
super(executor);
this.id = id;
}
then(resolve, reject) {
if (this.id) return resolve(this.id);
return super.then(resolve, reject)
}
};
const a = new MyPromise(() => {}, 'a');
const b = new MyPromise(() => {}, 'b');
testAsync(assert => {
assert.plan(1);
MyPromise.all([a, b]).then(
v => assert.equals(['a', 'b'], v),
assert.unexpectedRejection());
});
})();
// Test that we properly handle holes introduced into the resulting array
// by resolving some late elements immediately.
(function() {
class MyPromise extends Promise {
then(resolve, reject) {
if (this.immediately) {
resolve(42);
} else {
super.then(resolve, reject);
}
}
};
const a = new Array(1024);
a.fill(MyPromise.resolve(1));
const p = MyPromise.resolve(0);
p.immediately = true;
a.push(p);
testAsync(assert => {
assert.plan(1);
MyPromise.all(a).then(
b => assert.equals(42, b[1024]),
assert.unexpectedRejection());
});
})();