text: /**
  * @license
  * Copyright Google Inc. All Rights Reserved.
  *
  * Use of this source code is governed by an MIT-style license that can be
  * found in the LICENSE file at https://angular.io/license
  */
  (function (global, factory) {
      typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
      typeof define === 'function' && define.amd ? define(factory) :
      (factory());
  }(this, (function () { 'use strict';
  
  /**
   * @license
   * Copyright Google Inc. All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  var AsyncTestZoneSpec = (function () {
      function AsyncTestZoneSpec(finishCallback, failCallback, namePrefix) {
          this._pendingMicroTasks = false;
          this._pendingMacroTasks = false;
          this._alreadyErrored = false;
          this.runZone = Zone.current;
          this._finishCallback = finishCallback;
          this._failCallback = failCallback;
          this.name = 'asyncTestZone for ' + namePrefix;
      }
      AsyncTestZoneSpec.prototype._finishCallbackIfDone = function () {
          var _this = this;
          if (!(this._pendingMicroTasks || this._pendingMacroTasks)) {
              // We do this because we would like to catch unhandled rejected promises.
              this.runZone.run(function () {
                  setTimeout(function () {
                      if (!_this._alreadyErrored && !(_this._pendingMicroTasks || _this._pendingMacroTasks)) {
                          _this._finishCallback();
                      }
                  }, 0);
              });
          }
      };
      // Note - we need to use onInvoke at the moment to call finish when a test is
      // fully synchronous. TODO(juliemr): remove this when the logic for
      // onHasTask changes and it calls whenever the task queues are dirty.
      AsyncTestZoneSpec.prototype.onInvoke = function (parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) {
          try {
              return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source);
          }
          finally {
              this._finishCallbackIfDone();
          }
      };
      AsyncTestZoneSpec.prototype.onHandleError = function (parentZoneDelegate, currentZone, targetZone, error) {
          // Let the parent try to handle the error.
          var result = parentZoneDelegate.handleError(targetZone, error);
          if (result) {
              this._failCallback(error);
              this._alreadyErrored = true;
          }
          return false;
      };
      AsyncTestZoneSpec.prototype.onScheduleTask = function (delegate, currentZone, targetZone, task) {
          if (task.type == 'macroTask' && task.source == 'setInterval') {
              this._failCallback('Cannot use setInterval from within an async zone test.');
              return;
          }
          return delegate.scheduleTask(targetZone, task);
      };
      AsyncTestZoneSpec.prototype.onHasTask = function (delegate, current, target, hasTaskState) {
          delegate.hasTask(target, hasTaskState);
          if (hasTaskState.change == 'microTask') {
              this._pendingMicroTasks = hasTaskState.microTask;
              this._finishCallbackIfDone();
          }
          else if (hasTaskState.change == 'macroTask') {
              this._pendingMacroTasks = hasTaskState.macroTask;
              this._finishCallbackIfDone();
          }
      };
      return AsyncTestZoneSpec;
  }());
  // Export the class so that new instances can be created with proper
  // constructor params.
  Zone['AsyncTestZoneSpec'] = AsyncTestZoneSpec;
  
  })));
  