angular2
Version:
Angular 2 - a web framework for modern web apps
210 lines • 7.15 kB
JavaScript
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