07011cc4f0
This replaces Runtime_RunMicrotasks with Runtime_PerformMicrotaskCheckpoint. RunMicrotasks forcibly runs Microtasks even when the microtasks are suppressed, and may causes nested Microtasks in a problematic way. E.g. that confuses v8::MicrotasksScope::IsRunningMicrotasks() and GetEnteredOrMicrotaskContext(). OTOH, PerformMicrotaskCheckpoint() doesn't run cause the failure as it respects the microtask suppressions. As all existing tests don't call RunMicrotasks() in the suppressed situation (like Promise.resolve().then(()=>{%RunMicrotasks();})), this change should not affect to these tests. Change-Id: Ib043a0cc8e482e022d375084d65ea98a6f54ef3d Reviewed-on: https://chromium-review.googlesource.com/c/1360095 Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Taiju Tsuiki <tzik@chromium.org> Cr-Commit-Position: refs/heads/master@{#58068}
118 lines
3.4 KiB
JavaScript
118 lines
3.4 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
|
|
|
|
// Used for async tests. See definition below for more documentation.
|
|
var testAsync;
|
|
|
|
(function () { // Scope for utility functions.
|
|
/**
|
|
* This is to be used through the testAsync helper function defined
|
|
* below.
|
|
*
|
|
* This requires the --allow-natives-syntax flag to allow calling
|
|
* runtime functions.
|
|
*
|
|
* There must be at least one assertion in an async test. A test
|
|
* with no assertions will fail.
|
|
*
|
|
* @example
|
|
* testAsync(assert => {
|
|
* assert.plan(1) // There should be one assertion in this test.
|
|
* Promise.resolve(1)
|
|
* .then(val => assert.equals(1, val),
|
|
* assert.unreachable);
|
|
* })
|
|
*/
|
|
class AsyncAssertion {
|
|
constructor(test, name) {
|
|
this.expectedAsserts_ = -1;
|
|
this.actualAsserts_ = 0;
|
|
this.test_ = test;
|
|
this.name_ = name || '';
|
|
}
|
|
|
|
/**
|
|
* Sets the number of expected asserts in the test. The test fails
|
|
* if the number of asserts computed after running the test is not
|
|
* equal to this specified value.
|
|
* @param {number} expectedAsserts
|
|
*/
|
|
plan(expectedAsserts) {
|
|
this.expectedAsserts_ = expectedAsserts;
|
|
}
|
|
|
|
fail(expectedText, found) {
|
|
let message = formatFailureText(expectedText, found);
|
|
message += "\nin test:" + this.name_
|
|
message += "\n" + Function.prototype.toString.apply(this.test_);
|
|
%AbortJS(message);
|
|
}
|
|
|
|
equals(expected, found, name_opt) {
|
|
this.actualAsserts_++;
|
|
if (!deepEquals(expected, found)) {
|
|
this.fail(prettyPrinted(expected), found, name_opt);
|
|
}
|
|
}
|
|
|
|
unreachable() {
|
|
let message = "Failure: unreachable in test: " + this.name_;
|
|
message += "\n" + Function.prototype.toString.apply(this.test_);
|
|
%AbortJS(message);
|
|
}
|
|
|
|
unexpectedRejection(details) {
|
|
return (error) => {
|
|
let message =
|
|
"Failure: unexpected Promise rejection in test: " + this.name_;
|
|
if (details) message += "\n @" + details;
|
|
if (error instanceof Error) {
|
|
message += "\n" + String(error.stack);
|
|
} else {
|
|
message += "\n" + String(error);
|
|
}
|
|
message += "\n\n" + Function.prototype.toString.apply(this.test_);
|
|
%AbortJS(message);
|
|
};
|
|
}
|
|
|
|
drainMicrotasks() {
|
|
%PerformMicrotaskCheckpoint();
|
|
}
|
|
|
|
done_() {
|
|
if (this.expectedAsserts_ === -1) {
|
|
let message = "Please call t.plan(count) to initialize test harness " +
|
|
"with correct assert count (Note: count > 0)";
|
|
%AbortJS(message);
|
|
}
|
|
|
|
if (this.expectedAsserts_ !== this.actualAsserts_) {
|
|
let message = "Expected asserts: " + this.expectedAsserts_;
|
|
message += ", Actual asserts: " + this.actualAsserts_;
|
|
message += "\nin test: " + this.name_;
|
|
message += "\n" + Function.prototype.toString.apply(this.test_);
|
|
%AbortJS(message);
|
|
}
|
|
}
|
|
}
|
|
|
|
/** This is used to test async functions and promises.
|
|
* @param {testCallback} test - test function
|
|
* @param {string} [name] - optional name of the test
|
|
*
|
|
*
|
|
* @callback testCallback
|
|
* @param {AsyncAssertion} assert
|
|
*/
|
|
testAsync = function(test, name) {
|
|
let assert = new AsyncAssertion(test, name);
|
|
test(assert);
|
|
%PerformMicrotaskCheckpoint();
|
|
assert.done_();
|
|
}
|
|
})();
|