|  | // 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_(); | 
|  | } | 
|  | })(); |