// 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() { %RunMicrotasks(); } 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); %RunMicrotasks(); assert.done_(); } })();