text: import { StringMapWrapper } from 'angular2/src/facade/collection';
  import { global, isFunction, Math } from 'angular2/src/facade/lang';
  import { provide } from 'angular2/src/core/di';
  import { createTestInjector, FunctionWithParamTokens } from './test_injector';
  import { browserDetection } from './utils';
  export { inject } from './test_injector';
  export { expect } from './matchers';
  export var proxy = (t) => t;
  var _global = (typeof window === 'undefined' ? global : window);
  export var afterEach = _global.afterEach;
  export class AsyncTestCompleter {
      constructor(_done) {
          this._done = _done;
      }
      done() { this._done(); }
  }
  var jsmBeforeEach = _global.beforeEach;
  var jsmDescribe = _global.describe;
  var jsmDDescribe = _global.fdescribe;
  var jsmXDescribe = _global.xdescribe;
  var jsmIt = _global.it;
  var jsmIIt = _global.fit;
  var jsmXIt = _global.xit;
  var runnerStack = [];
  var inIt = false;
  jasmine.DEFAULT_TIMEOUT_INTERVAL = 500;
  var globalTimeOut = browserDetection.isSlow ? 3000 : jasmine.DEFAULT_TIMEOUT_INTERVAL;
  var testProviders;
  /**
   * Mechanism to run `beforeEach()` functions of Angular tests.
   *
   * Note: Jasmine own `beforeEach` is used by this library to handle DI providers.
   */
  class BeforeEachRunner {
      constructor(_parent) {
          this._parent = _parent;
          this._fns = [];
      }
      beforeEach(fn) { this._fns.push(fn); }
      run(injector) {
          if (this._parent)
              this._parent.run(injector);
          this._fns.forEach((fn) => {
              return isFunction(fn) ? fn() : fn.execute(injector);
          });
      }
  }
  // Reset the test providers before each test
  jsmBeforeEach(() => { testProviders = []; });
  function _describe(jsmFn, ...args) {
      var parentRunner = runnerStack.length === 0 ? null : runnerStack[runnerStack.length - 1];
      var runner = new BeforeEachRunner(parentRunner);
      runnerStack.push(runner);
      var suite = jsmFn(...args);
      runnerStack.pop();
      return suite;
  }
  export function describe(...args) {
      return _describe(jsmDescribe, ...args);
  }
  export function ddescribe(...args) {
      return _describe(jsmDDescribe, ...args);
  }
  export function xdescribe(...args) {
      return _describe(jsmXDescribe, ...args);
  }
  export function beforeEach(fn) {
      if (runnerStack.length > 0) {
          // Inside a describe block, beforeEach() uses a BeforeEachRunner
          runnerStack[runnerStack.length - 1].beforeEach(fn);
      }
      else {
          // Top level beforeEach() are delegated to jasmine
          jsmBeforeEach(fn);
      }
  }
  /**
   * Allows overriding default providers defined in test_injector.js.
   *
   * The given function must return a list of DI providers.
   *
   * Example:
   *
   *   beforeEachBindings(() => [
   *     provide(Compiler, {useClass: MockCompiler}),
   *     provide(SomeToken, {useValue: myValue}),
   *   ]);
   */
  export function beforeEachProviders(fn) {
      jsmBeforeEach(() => {
          var bindings = fn();
          if (!bindings)
              return;
          testProviders = [...testProviders, ...bindings];
      });
  }
  /**
   * @deprecated
   */
  export function beforeEachBindings(fn) {
      beforeEachProviders(fn);
  }
  function _it(jsmFn, name, testFn, testTimeOut) {
      var runner = runnerStack[runnerStack.length - 1];
      var timeOut = Math.max(globalTimeOut, testTimeOut);
      if (testFn instanceof FunctionWithParamTokens) {
          // The test case uses inject(). ie `it('test', inject([AsyncTestCompleter], (async) => { ...
          // }));`
          if (testFn.hasToken(AsyncTestCompleter)) {
              jsmFn(name, (done) => {
                  var completerProvider = provide(AsyncTestCompleter, {
                      useFactory: () => {
                          // Mark the test as async when an AsyncTestCompleter is injected in an it()
                          if (!inIt)
                              throw new Error('AsyncTestCompleter can only be injected in an "it()"');
                          return new AsyncTestCompleter(done);
                      }
                  });
                  var injector = createTestInjector([...testProviders, completerProvider]);
                  runner.run(injector);
                  inIt = true;
                  testFn.execute(injector);
                  inIt = false;
              }, timeOut);
          }
          else {
              jsmFn(name, () => {
                  var injector = createTestInjector(testProviders);
                  runner.run(injector);
                  testFn.execute(injector);
              }, timeOut);
          }
      }
      else {
          // The test case doesn't use inject(). ie `it('test', (done) => { ... }));`
          if (testFn.length === 0) {
              jsmFn(name, () => {
                  var injector = createTestInjector(testProviders);
                  runner.run(injector);
                  testFn();
              }, timeOut);
          }
          else {
              jsmFn(name, (done) => {
                  var injector = createTestInjector(testProviders);
                  runner.run(injector);
                  testFn(done);
              }, timeOut);
          }
      }
  }
  export function it(name, fn, timeOut = null) {
      return _it(jsmIt, name, fn, timeOut);
  }
  export function xit(name, fn, timeOut = null) {
      return _it(jsmXIt, name, fn, timeOut);
  }
  export function iit(name, fn, timeOut = null) {
      return _it(jsmIIt, name, fn, timeOut);
  }
  export class SpyObject {
      constructor(type = null) {
          if (type) {
              for (var prop in type.prototype) {
                  var m = null;
                  try {
                      m = type.prototype[prop];
                  }
                  catch (e) {
                  }
                  if (typeof m === 'function') {
                      this.spy(prop);
                  }
              }
          }
      }
      // Noop so that SpyObject has the same interface as in Dart
      noSuchMethod(args) { }
      spy(name) {
          if (!this[name]) {
              this[name] = this._createGuinnessCompatibleSpy(name);
          }
          return this[name];
      }
      prop(name, value) { this[name] = value; }
      static stub(object = null, config = null, overrides = null) {
          if (!(object instanceof SpyObject)) {
              overrides = config;
              config = object;
              object = new SpyObject();
          }
          var m = StringMapWrapper.merge(config, overrides);
          StringMapWrapper.forEach(m, (value, key) => { object.spy(key).andReturn(value); });
          return object;
      }
      /** @internal */
      _createGuinnessCompatibleSpy(name) {
          var newSpy = jasmine.createSpy(name);
          newSpy.andCallFake = newSpy.and.callFake;
          newSpy.andReturn = newSpy.and.returnValue;
          newSpy.reset = newSpy.calls.reset;
          // revisit return null here (previously needed for rtts_assert).
          newSpy.and.returnValue(null);
          return newSpy;
      }
  }
  export function isInInnerZone() {
      return global.zone._innerZone === true;
  }
  //# sourceMappingURL=testing_internal.js.map