repackaging: all the file moves
This commit is contained in:
4
modules/@angular/core/testing/async.dart
Normal file
4
modules/@angular/core/testing/async.dart
Normal file
@ -0,0 +1,4 @@
|
||||
// This symbol is not used on the Dart side. This exists just as a stub.
|
||||
async(Function fn) {
|
||||
throw 'async() test wrapper not available for Dart.';
|
||||
}
|
25
modules/@angular/core/testing/async.ts
Normal file
25
modules/@angular/core/testing/async.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Wraps a test function in an asynchronous test zone. The test will automatically
|
||||
* complete when all asynchronous calls within this zone are done. Can be used
|
||||
* to wrap an {@link inject} call.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
* it('...', async(inject([AClass], (object) => {
|
||||
* object.doSomething.then(() => {
|
||||
* expect(...);
|
||||
* })
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function async(fn: Function): Function {
|
||||
return () => {
|
||||
return new Promise<void>((finishCallback, failCallback) => {
|
||||
var AsyncTestZoneSpec = Zone['AsyncTestZoneSpec'];
|
||||
var testZoneSpec = new AsyncTestZoneSpec(finishCallback, failCallback, 'test');
|
||||
var testZone = Zone.current.fork(testZoneSpec);
|
||||
return testZone.run(fn);
|
||||
});
|
||||
}
|
||||
}
|
13
modules/@angular/core/testing/async_test_completer.ts
Normal file
13
modules/@angular/core/testing/async_test_completer.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import {PromiseCompleter} from 'angular2/src/facade/promise';
|
||||
|
||||
/**
|
||||
* Injectable completer that allows signaling completion of an asynchronous test. Used internally.
|
||||
*/
|
||||
export class AsyncTestCompleter {
|
||||
private _completer = new PromiseCompleter<any>();
|
||||
done(value?: any) { this._completer.resolve(value); }
|
||||
|
||||
fail(error?: any, stackTrace?: string) { this._completer.reject(error, stackTrace); }
|
||||
|
||||
get promise(): Promise<any> { return this._completer.promise; }
|
||||
}
|
103
modules/@angular/core/testing/fake_async.dart
Normal file
103
modules/@angular/core/testing/fake_async.dart
Normal file
@ -0,0 +1,103 @@
|
||||
library testing.fake_async;
|
||||
|
||||
import 'dart:async' show runZoned, ZoneSpecification;
|
||||
import 'package:quiver/testing/async.dart' as quiver;
|
||||
import 'package:angular2/src/facade/exceptions.dart' show BaseException;
|
||||
|
||||
const _u = const Object();
|
||||
|
||||
quiver.FakeAsync _fakeAsync = null;
|
||||
|
||||
/**
|
||||
* Wraps the [fn] to be executed in the fakeAsync zone:
|
||||
* - microtasks are manually executed by calling [flushMicrotasks],
|
||||
* - timers are synchronous, [tick] simulates the asynchronous passage of time.
|
||||
*
|
||||
* If there are any pending timers at the end of the function, an exception
|
||||
* will be thrown.
|
||||
*
|
||||
* Can be used to wrap inject() calls.
|
||||
*
|
||||
* Returns a `Function` that wraps [fn].
|
||||
*/
|
||||
Function fakeAsync(Function fn) {
|
||||
if (_fakeAsync != null) {
|
||||
throw 'fakeAsync() calls can not be nested';
|
||||
}
|
||||
|
||||
return ([a0 = _u,
|
||||
a1 = _u,
|
||||
a2 = _u,
|
||||
a3 = _u,
|
||||
a4 = _u,
|
||||
a5 = _u,
|
||||
a6 = _u,
|
||||
a7 = _u,
|
||||
a8 = _u,
|
||||
a9 = _u]) {
|
||||
// runZoned() to install a custom exception handler that re-throws
|
||||
return runZoned(() {
|
||||
return new quiver.FakeAsync().run((quiver.FakeAsync async) {
|
||||
try {
|
||||
_fakeAsync = async;
|
||||
List args = [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]
|
||||
.takeWhile((a) => a != _u)
|
||||
.toList();
|
||||
var res = Function.apply(fn, args);
|
||||
_fakeAsync.flushMicrotasks();
|
||||
|
||||
if (async.periodicTimerCount > 0) {
|
||||
throw new BaseException('${async.periodicTimerCount} periodic '
|
||||
'timer(s) still in the queue.');
|
||||
}
|
||||
|
||||
if (async.nonPeriodicTimerCount > 0) {
|
||||
throw new BaseException('${async.nonPeriodicTimerCount} timer(s) '
|
||||
'still in the queue.');
|
||||
}
|
||||
|
||||
return res;
|
||||
} finally {
|
||||
_fakeAsync = null;
|
||||
}
|
||||
});
|
||||
},
|
||||
zoneSpecification: new ZoneSpecification(
|
||||
handleUncaughtError: (self, parent, zone, error, stackTrace) =>
|
||||
throw error));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates the asynchronous passage of [millis] milliseconds for the timers
|
||||
* in the fakeAsync zone.
|
||||
*
|
||||
* The microtasks queue is drained at the very start of this function and after
|
||||
* any timer callback has been executed.
|
||||
*/
|
||||
void tick([int millis = 0]) {
|
||||
_assertInFakeAsyncZone();
|
||||
var duration = new Duration(milliseconds: millis);
|
||||
_fakeAsync.elapse(duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is not needed in Dart. Because quiver correctly removes a timer when
|
||||
* it throws an exception.
|
||||
*/
|
||||
void clearPendingTimers() {}
|
||||
|
||||
/**
|
||||
* Flush any pending microtasks.
|
||||
*/
|
||||
void flushMicrotasks() {
|
||||
_assertInFakeAsyncZone();
|
||||
_fakeAsync.flushMicrotasks();
|
||||
}
|
||||
|
||||
void _assertInFakeAsyncZone() {
|
||||
if (_fakeAsync == null) {
|
||||
throw new BaseException('The code should be running in the fakeAsync zone '
|
||||
'to call this function');
|
||||
}
|
||||
}
|
89
modules/@angular/core/testing/fake_async.ts
Normal file
89
modules/@angular/core/testing/fake_async.ts
Normal file
@ -0,0 +1,89 @@
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
import {getTestInjector} from './test_injector';
|
||||
|
||||
let _FakeAsyncTestZoneSpecType = Zone['FakeAsyncTestZoneSpec'];
|
||||
|
||||
/**
|
||||
* Wraps a function to be executed in the fakeAsync zone:
|
||||
* - microtasks are manually executed by calling `flushMicrotasks()`,
|
||||
* - timers are synchronous, `tick()` simulates the asynchronous passage of time.
|
||||
*
|
||||
* If there are any pending timers at the end of the function, an exception will be thrown.
|
||||
*
|
||||
* Can be used to wrap inject() calls.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example testing/ts/fake_async.ts region='basic'}
|
||||
*
|
||||
* @param fn
|
||||
* @returns {Function} The function wrapped to be executed in the fakeAsync zone
|
||||
*/
|
||||
export function fakeAsync(fn: Function): Function {
|
||||
if (Zone.current.get('FakeAsyncTestZoneSpec') != null) {
|
||||
throw new BaseException('fakeAsync() calls can not be nested');
|
||||
}
|
||||
|
||||
let fakeAsyncTestZoneSpec = new _FakeAsyncTestZoneSpecType();
|
||||
let fakeAsyncZone = Zone.current.fork(fakeAsyncTestZoneSpec);
|
||||
|
||||
return function(...args) {
|
||||
let res = fakeAsyncZone.run(() => {
|
||||
let res = fn(...args);
|
||||
flushMicrotasks();
|
||||
return res;
|
||||
});
|
||||
|
||||
if (fakeAsyncTestZoneSpec.pendingPeriodicTimers.length > 0) {
|
||||
throw new BaseException(`${fakeAsyncTestZoneSpec.pendingPeriodicTimers.length} ` +
|
||||
`periodic timer(s) still in the queue.`);
|
||||
}
|
||||
|
||||
if (fakeAsyncTestZoneSpec.pendingTimers.length > 0) {
|
||||
throw new BaseException(
|
||||
`${fakeAsyncTestZoneSpec.pendingTimers.length} timer(s) still in the queue.`);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
function _getFakeAsyncZoneSpec(): any {
|
||||
let zoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
|
||||
if (zoneSpec == null) {
|
||||
throw new Error('The code should be running in the fakeAsync zone to call this function');
|
||||
}
|
||||
return zoneSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the queue of pending timers and microtasks.
|
||||
* Tests no longer need to call this explicitly.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export function clearPendingTimers(): void {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates the asynchronous passage of time for the timers in the fakeAsync zone.
|
||||
*
|
||||
* The microtasks queue is drained at the very start of this function and after any timer callback
|
||||
* has been executed.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example testing/ts/fake_async.ts region='basic'}
|
||||
*
|
||||
* @param {number} millis Number of millisecond, defaults to 0
|
||||
*/
|
||||
export function tick(millis: number = 0): void {
|
||||
_getFakeAsyncZoneSpec().tick(millis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush any pending microtasks.
|
||||
*/
|
||||
export function flushMicrotasks(): void {
|
||||
_getFakeAsyncZoneSpec().flushMicrotasks();
|
||||
}
|
10
modules/@angular/core/testing/lang_utils.dart
Normal file
10
modules/@angular/core/testing/lang_utils.dart
Normal file
@ -0,0 +1,10 @@
|
||||
library testing.lang_utils;
|
||||
|
||||
import 'dart:mirrors';
|
||||
|
||||
Type getTypeOf(instance) => instance.runtimeType;
|
||||
|
||||
dynamic instantiateType(Type type, [List params = const []]) {
|
||||
var cm = reflectClass(type);
|
||||
return cm.newInstance(new Symbol(''), params).reflectee;
|
||||
}
|
9
modules/@angular/core/testing/lang_utils.ts
Normal file
9
modules/@angular/core/testing/lang_utils.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export function getTypeOf(instance) {
|
||||
return instance.constructor;
|
||||
}
|
||||
|
||||
export function instantiateType(type: Function, params: any[] = []) {
|
||||
var instance = Object.create(type.prototype);
|
||||
instance.constructor.apply(instance, params);
|
||||
return instance;
|
||||
}
|
31
modules/@angular/core/testing/mock_application_ref.ts
Normal file
31
modules/@angular/core/testing/mock_application_ref.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import {ApplicationRef} from 'angular2/src/core/application_ref';
|
||||
import {Injectable, Injector} from 'angular2/src/core/di';
|
||||
import {Type} from 'angular2/src/facade/lang';
|
||||
import {ComponentRef, ComponentFactory} from 'angular2/src/core/linker/component_factory';
|
||||
import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
||||
|
||||
/**
|
||||
* A no-op implementation of {@link ApplicationRef}, useful for testing.
|
||||
*/
|
||||
@Injectable()
|
||||
export class MockApplicationRef extends ApplicationRef {
|
||||
registerBootstrapListener(listener: (ref: ComponentRef<any>) => void): void {}
|
||||
|
||||
registerDisposeListener(dispose: () => void): void {}
|
||||
|
||||
bootstrap<C>(componentFactory: ComponentFactory<C>): ComponentRef<C> { return null; }
|
||||
|
||||
get injector(): Injector { return null; };
|
||||
|
||||
get zone(): NgZone { return null; };
|
||||
|
||||
run(callback: Function): any { return null; }
|
||||
|
||||
waitForAsyncInitializers(): Promise<any> { return null; }
|
||||
|
||||
dispose(): void {}
|
||||
|
||||
tick(): void {}
|
||||
|
||||
get componentTypes(): Type[] { return null; };
|
||||
}
|
22
modules/@angular/core/testing/ng_zone_mock.ts
Normal file
22
modules/@angular/core/testing/ng_zone_mock.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import {Injectable} from 'angular2/src/core/di';
|
||||
import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
||||
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||
|
||||
/**
|
||||
* A mock implementation of {@link NgZone}.
|
||||
*/
|
||||
@Injectable()
|
||||
export class MockNgZone extends NgZone {
|
||||
/** @internal */
|
||||
private _mockOnStable: EventEmitter<any> = new EventEmitter(false);
|
||||
|
||||
constructor() { super({enableLongStackTrace: false}); }
|
||||
|
||||
get onStable() { return this._mockOnStable; }
|
||||
|
||||
run(fn: Function): any { return fn(); }
|
||||
|
||||
runOutsideAngular(fn: Function): any { return fn(); }
|
||||
|
||||
simulateZoneExit(): void { ObservableWrapper.callNext(this.onStable, null); }
|
||||
}
|
204
modules/@angular/core/testing/test_injector.ts
Normal file
204
modules/@angular/core/testing/test_injector.ts
Normal file
@ -0,0 +1,204 @@
|
||||
import {ReflectiveInjector, Provider, PLATFORM_INITIALIZER} from 'angular2/core';
|
||||
import {BaseException, ExceptionHandler} from 'angular2/src/facade/exceptions';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {FunctionWrapper, isPresent, Type} from 'angular2/src/facade/lang';
|
||||
|
||||
import {async} from './async';
|
||||
import {AsyncTestCompleter} from './async_test_completer';
|
||||
|
||||
export {async} from './async';
|
||||
|
||||
export class TestInjector {
|
||||
private _instantiated: boolean = false;
|
||||
|
||||
private _injector: ReflectiveInjector = null;
|
||||
|
||||
private _providers: Array<Type | Provider | any[]> = [];
|
||||
|
||||
reset() {
|
||||
this._injector = null;
|
||||
this._providers = [];
|
||||
this._instantiated = false;
|
||||
}
|
||||
|
||||
platformProviders: Array<Type | Provider | any[]> = [];
|
||||
|
||||
applicationProviders: Array<Type | Provider | any[]> = [];
|
||||
|
||||
addProviders(providers: Array<Type | Provider | any[]>) {
|
||||
if (this._instantiated) {
|
||||
throw new BaseException('Cannot add providers after test injector is instantiated');
|
||||
}
|
||||
this._providers = ListWrapper.concat(this._providers, providers);
|
||||
}
|
||||
|
||||
createInjector() {
|
||||
var rootInjector = ReflectiveInjector.resolveAndCreate(this.platformProviders);
|
||||
this._injector = rootInjector.resolveAndCreateChild(
|
||||
ListWrapper.concat(this.applicationProviders, this._providers));
|
||||
this._instantiated = true;
|
||||
return this._injector;
|
||||
}
|
||||
|
||||
get(token: any) {
|
||||
if (!this._instantiated) {
|
||||
this.createInjector();
|
||||
}
|
||||
return this._injector.get(token);
|
||||
}
|
||||
|
||||
execute(tokens: any[], fn: Function): any {
|
||||
if (!this._instantiated) {
|
||||
this.createInjector();
|
||||
}
|
||||
var params = tokens.map(t => this._injector.get(t));
|
||||
return FunctionWrapper.apply(fn, params);
|
||||
}
|
||||
}
|
||||
|
||||
var _testInjector: TestInjector = null;
|
||||
|
||||
export function getTestInjector() {
|
||||
if (_testInjector == null) {
|
||||
_testInjector = new TestInjector();
|
||||
}
|
||||
return _testInjector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the providers that the test injector should use. These should be providers
|
||||
* common to every test in the suite.
|
||||
*
|
||||
* This may only be called once, to set up the common providers for the current test
|
||||
* suite on teh current platform. If you absolutely need to change the providers,
|
||||
* first use `resetBaseTestProviders`.
|
||||
*
|
||||
* Test Providers for individual platforms are available from
|
||||
* 'angular2/platform/testing/<platform_name>'.
|
||||
*/
|
||||
export function setBaseTestProviders(platformProviders: Array<Type | Provider | any[]>,
|
||||
applicationProviders: Array<Type | Provider | any[]>) {
|
||||
var testInjector = getTestInjector();
|
||||
if (testInjector.platformProviders.length > 0 || testInjector.applicationProviders.length > 0) {
|
||||
throw new BaseException('Cannot set base providers because it has already been called');
|
||||
}
|
||||
testInjector.platformProviders = platformProviders;
|
||||
testInjector.applicationProviders = applicationProviders;
|
||||
var injector = testInjector.createInjector();
|
||||
let inits: Function[] = injector.get(PLATFORM_INITIALIZER, null);
|
||||
if (isPresent(inits)) {
|
||||
inits.forEach(init => init());
|
||||
}
|
||||
testInjector.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the providers for the test injector.
|
||||
*/
|
||||
export function resetBaseTestProviders() {
|
||||
var testInjector = getTestInjector();
|
||||
testInjector.platformProviders = [];
|
||||
testInjector.applicationProviders = [];
|
||||
testInjector.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows injecting dependencies in `beforeEach()` and `it()`.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
* beforeEach(inject([Dependency, AClass], (dep, object) => {
|
||||
* // some code that uses `dep` and `object`
|
||||
* // ...
|
||||
* }));
|
||||
*
|
||||
* it('...', inject([AClass], (object) => {
|
||||
* object.doSomething();
|
||||
* expect(...);
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* Notes:
|
||||
* - inject is currently a function because of some Traceur limitation the syntax should
|
||||
* eventually
|
||||
* becomes `it('...', @Inject (object: AClass, async: AsyncTestCompleter) => { ... });`
|
||||
*
|
||||
* @param {Array} tokens
|
||||
* @param {Function} fn
|
||||
* @return {Function}
|
||||
*/
|
||||
export function inject(tokens: any[], fn: Function): Function {
|
||||
let testInjector = getTestInjector();
|
||||
if (tokens.indexOf(AsyncTestCompleter) >= 0) {
|
||||
// Return an async test method that returns a Promise if AsyncTestCompleter is one of the
|
||||
// injected tokens.
|
||||
return () => {
|
||||
let completer: AsyncTestCompleter = testInjector.get(AsyncTestCompleter);
|
||||
testInjector.execute(tokens, fn);
|
||||
return completer.promise;
|
||||
}
|
||||
} else {
|
||||
// Return a synchronous test method with the injected tokens.
|
||||
return () => { return getTestInjector().execute(tokens, fn); };
|
||||
}
|
||||
}
|
||||
|
||||
export class InjectSetupWrapper {
|
||||
constructor(private _providers: () => any) {}
|
||||
|
||||
private _addProviders() {
|
||||
var additionalProviders = this._providers();
|
||||
if (additionalProviders.length > 0) {
|
||||
getTestInjector().addProviders(additionalProviders);
|
||||
}
|
||||
}
|
||||
|
||||
inject(tokens: any[], fn: Function): Function {
|
||||
return () => {
|
||||
this._addProviders();
|
||||
return inject_impl(tokens, fn)();
|
||||
}
|
||||
}
|
||||
|
||||
/** @Deprecated {use async(withProviders().inject())} */
|
||||
injectAsync(tokens: any[], fn: Function): Function {
|
||||
return () => {
|
||||
this._addProviders();
|
||||
return injectAsync_impl(tokens, fn)();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function withProviders(providers: () => any) {
|
||||
return new InjectSetupWrapper(providers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Deprecated {use async(inject())}
|
||||
*
|
||||
* Allows injecting dependencies in `beforeEach()` and `it()`. The test must return
|
||||
* a promise which will resolve when all asynchronous activity is complete.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
* it('...', injectAsync([AClass], (object) => {
|
||||
* return object.doSomething().then(() => {
|
||||
* expect(...);
|
||||
* });
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @param {Array} tokens
|
||||
* @param {Function} fn
|
||||
* @return {Function}
|
||||
*/
|
||||
export function injectAsync(tokens: any[], fn: Function): Function {
|
||||
return async(inject(tokens, fn));
|
||||
}
|
||||
|
||||
// This is to ensure inject(Async) within InjectSetupWrapper doesn't call itself
|
||||
// when transpiled to Dart.
|
||||
var inject_impl = inject;
|
||||
var injectAsync_impl = injectAsync;
|
3
modules/@angular/core/testing/testing.dart
Normal file
3
modules/@angular/core/testing/testing.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library angular2.src.testing.testing;
|
||||
|
||||
// empty as this file is for external TS/js users and should not be transpiled to dart
|
189
modules/@angular/core/testing/testing.ts
Normal file
189
modules/@angular/core/testing/testing.ts
Normal file
@ -0,0 +1,189 @@
|
||||
/**
|
||||
* Public Test Library for unit testing Angular2 Applications. Uses the
|
||||
* Jasmine framework.
|
||||
*/
|
||||
import {global, isPromise} from 'angular2/src/facade/lang';
|
||||
|
||||
import {inject, async, injectAsync, TestInjector, getTestInjector} from './test_injector';
|
||||
|
||||
export {inject, async, injectAsync} from './test_injector';
|
||||
|
||||
export {expect, NgMatchers} from './matchers';
|
||||
|
||||
var _global = <any>(typeof window === 'undefined' ? global : window);
|
||||
|
||||
/**
|
||||
* Run a function (with an optional asynchronous callback) after each test case.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='afterEach'}
|
||||
*/
|
||||
export var afterEach: Function = _global.afterEach;
|
||||
|
||||
/**
|
||||
* Group test cases together under a common description prefix.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='describeIt'}
|
||||
*/
|
||||
export var describe: Function = _global.describe;
|
||||
|
||||
/**
|
||||
* See {@link fdescribe}.
|
||||
*/
|
||||
export var ddescribe: Function = _global.fdescribe;
|
||||
|
||||
/**
|
||||
* Like {@link describe}, but instructs the test runner to only run
|
||||
* the test cases in this group. This is useful for debugging.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='fdescribe'}
|
||||
*/
|
||||
export var fdescribe: Function = _global.fdescribe;
|
||||
|
||||
/**
|
||||
* Like {@link describe}, but instructs the test runner to exclude
|
||||
* this group of test cases from execution. This is useful for
|
||||
* debugging, or for excluding broken tests until they can be fixed.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='xdescribe'}
|
||||
*/
|
||||
export var xdescribe: Function = _global.xdescribe;
|
||||
|
||||
var jsmBeforeEach = _global.beforeEach;
|
||||
var jsmIt = _global.it;
|
||||
var jsmIIt = _global.fit;
|
||||
var jsmXIt = _global.xit;
|
||||
|
||||
var testInjector: TestInjector = getTestInjector();
|
||||
|
||||
// Reset the test providers before each test.
|
||||
jsmBeforeEach(() => { testInjector.reset(); });
|
||||
|
||||
/**
|
||||
* Allows overriding default providers of the test injector,
|
||||
* which are defined in test_injector.js.
|
||||
*
|
||||
* The given function must return a list of DI providers.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='beforeEachProviders'}
|
||||
*/
|
||||
export function beforeEachProviders(fn): void {
|
||||
jsmBeforeEach(() => {
|
||||
var providers = fn();
|
||||
if (!providers) return;
|
||||
try {
|
||||
testInjector.addProviders(providers);
|
||||
} catch (e) {
|
||||
throw new Error('beforeEachProviders was called after the injector had ' +
|
||||
'been used in a beforeEach or it block. This invalidates the ' +
|
||||
'test injector');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _wrapTestFn(fn: Function) {
|
||||
// Wraps a test or beforeEach function to handle synchronous and asynchronous execution.
|
||||
return (done: any) => {
|
||||
if (fn.length === 0) {
|
||||
let retVal = fn();
|
||||
if (isPromise(retVal)) {
|
||||
// Asynchronous test function - wait for completion.
|
||||
(<Promise<any>>retVal).then(done, done.fail);
|
||||
} else {
|
||||
// Synchronous test function - complete immediately.
|
||||
done();
|
||||
}
|
||||
} else {
|
||||
// Asynchronous test function that takes "done" as parameter.
|
||||
fn(done);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function _it(jsmFn: Function, name: string, testFn: Function, testTimeOut: number): void {
|
||||
jsmFn(name, _wrapTestFn(testFn), testTimeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around Jasmine beforeEach function.
|
||||
*
|
||||
* beforeEach may be used with the `inject` function to fetch dependencies.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='beforeEach'}
|
||||
*/
|
||||
export function beforeEach(fn: Function): void {
|
||||
jsmBeforeEach(_wrapTestFn(fn));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a single test case with the given test name and execution function.
|
||||
*
|
||||
* The test function can be either a synchronous function, the result of {@link async},
|
||||
* or an injected function created via {@link inject}.
|
||||
*
|
||||
* Wrapper around Jasmine it function. See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='describeIt'}
|
||||
*/
|
||||
export function it(name: string, fn: Function, timeOut: number = null): void {
|
||||
return _it(jsmIt, name, fn, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link it}, but instructs the test runner to exclude this test
|
||||
* entirely. Useful for debugging or for excluding broken tests until
|
||||
* they can be fixed.
|
||||
*
|
||||
* Wrapper around Jasmine xit function. See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='xit'}
|
||||
*/
|
||||
export function xit(name: string, fn: Function, timeOut: number = null): void {
|
||||
return _it(jsmXIt, name, fn, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link fit}.
|
||||
*/
|
||||
export function iit(name: string, fn: Function, timeOut: number = null): void {
|
||||
return _it(jsmIIt, name, fn, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link it}, but instructs the test runner to only run this test.
|
||||
* Useful for debugging.
|
||||
*
|
||||
* Wrapper around Jasmine fit function. See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='fit'}
|
||||
*/
|
||||
export function fit(name: string, fn: Function, timeOut: number = null): void {
|
||||
return _it(jsmIIt, name, fn, timeOut);
|
||||
}
|
69
modules/@angular/core/testing/testing_internal.dart
Normal file
69
modules/@angular/core/testing/testing_internal.dart
Normal file
@ -0,0 +1,69 @@
|
||||
library angular2.src.testing.testing_internal;
|
||||
|
||||
import 'testing_internal_core.dart' as core;
|
||||
export 'testing_internal_core.dart'
|
||||
hide
|
||||
beforeEachProviders,
|
||||
beforeEachBindings,
|
||||
beforeEach,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
testSetup,
|
||||
describe,
|
||||
ddescribe,
|
||||
xdescribe;
|
||||
|
||||
import 'package:angular2/platform/testing/browser.dart';
|
||||
import 'package:angular2/src/facade/collection.dart' show StringMapWrapper;
|
||||
import "package:angular2/src/core/zone/ng_zone.dart" show NgZone;
|
||||
|
||||
export 'test_injector.dart' show inject;
|
||||
|
||||
void testSetup() {
|
||||
core.setDartBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS, TEST_BROWSER_APPLICATION_PROVIDERS);
|
||||
}
|
||||
|
||||
void beforeEachProviders(Function fn) {
|
||||
testSetup();
|
||||
core.beforeEachProviders(fn);
|
||||
}
|
||||
|
||||
@Deprecated('using beforeEachProviders instead')
|
||||
void beforeEachBindings(Function fn) {
|
||||
beforeEachProviders(fn);
|
||||
}
|
||||
|
||||
void beforeEach(fn) {
|
||||
testSetup();
|
||||
core.beforeEach(fn);
|
||||
}
|
||||
|
||||
void it(name, fn, [timeOut = null]) {
|
||||
core.it(name, fn, timeOut);
|
||||
}
|
||||
|
||||
void iit(name, fn, [timeOut = null]) {
|
||||
core.iit(name, fn, timeOut);
|
||||
}
|
||||
|
||||
void xit(name, fn, [timeOut = null]) {
|
||||
core.xit(name, fn, timeOut);
|
||||
}
|
||||
|
||||
void describe(name, fn) {
|
||||
testSetup();
|
||||
core.describe(name, fn);
|
||||
}
|
||||
|
||||
void ddescribe(name, fn) {
|
||||
testSetup();
|
||||
core.ddescribe(name, fn);
|
||||
}
|
||||
|
||||
void xdescribe(name, fn) {
|
||||
testSetup();
|
||||
core.xdescribe(name, fn);
|
||||
}
|
||||
|
||||
bool isInInnerZone() => NgZone.isInAngularZone();
|
224
modules/@angular/core/testing/testing_internal.ts
Normal file
224
modules/@angular/core/testing/testing_internal.ts
Normal file
@ -0,0 +1,224 @@
|
||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {global, isPromise, Math} from 'angular2/src/facade/lang';
|
||||
|
||||
import {provide} from 'angular2/core';
|
||||
|
||||
import {AsyncTestCompleter} from './async_test_completer';
|
||||
import {getTestInjector, inject} from './test_injector';
|
||||
import {browserDetection} from './utils';
|
||||
|
||||
export {AsyncTestCompleter} from './async_test_completer';
|
||||
export {inject} from './test_injector';
|
||||
|
||||
export {expect, NgMatchers} from './matchers';
|
||||
|
||||
export var proxy: ClassDecorator = (t) => t;
|
||||
|
||||
var _global = <any>(typeof window === 'undefined' ? global : window);
|
||||
|
||||
export var afterEach: Function = _global.afterEach;
|
||||
|
||||
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 testInjector = getTestInjector();
|
||||
|
||||
/**
|
||||
* Mechanism to run `beforeEach()` functions of Angular tests.
|
||||
*
|
||||
* Note: Jasmine own `beforeEach` is used by this library to handle DI providers.
|
||||
*/
|
||||
class BeforeEachRunner {
|
||||
private _fns: Array<Function> = [];
|
||||
|
||||
constructor(private _parent: BeforeEachRunner) {}
|
||||
|
||||
beforeEach(fn: Function): void { this._fns.push(fn); }
|
||||
|
||||
run(): void {
|
||||
if (this._parent) this._parent.run();
|
||||
this._fns.forEach((fn) => { fn(); });
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the test providers before each test
|
||||
jsmBeforeEach(() => { testInjector.reset(); });
|
||||
|
||||
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): void {
|
||||
return _describe(jsmDescribe, ...args);
|
||||
}
|
||||
|
||||
export function ddescribe(...args): void {
|
||||
return _describe(jsmDDescribe, ...args);
|
||||
}
|
||||
|
||||
export function xdescribe(...args): void {
|
||||
return _describe(jsmXDescribe, ...args);
|
||||
}
|
||||
|
||||
export function beforeEach(fn: Function): void {
|
||||
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:
|
||||
*
|
||||
* beforeEachProviders(() => [
|
||||
* provide(Compiler, {useClass: MockCompiler}),
|
||||
* provide(SomeToken, {useValue: myValue}),
|
||||
* ]);
|
||||
*/
|
||||
export function beforeEachProviders(fn): void {
|
||||
jsmBeforeEach(() => {
|
||||
var providers = fn();
|
||||
if (!providers) return;
|
||||
testInjector.addProviders(providers);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export function beforeEachBindings(fn): void {
|
||||
beforeEachProviders(fn);
|
||||
}
|
||||
|
||||
function _it(jsmFn: Function, name: string, testFn: Function, testTimeOut: number): void {
|
||||
var runner = runnerStack[runnerStack.length - 1];
|
||||
var timeOut = Math.max(globalTimeOut, testTimeOut);
|
||||
|
||||
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();
|
||||
}
|
||||
});
|
||||
testInjector.addProviders([completerProvider]);
|
||||
runner.run();
|
||||
|
||||
inIt = true;
|
||||
if (testFn.length == 0) {
|
||||
let retVal = testFn();
|
||||
if (isPromise(retVal)) {
|
||||
// Asynchronous test function that returns a Promise - wait for completion.
|
||||
(<Promise<any>>retVal).then(done, done.fail);
|
||||
} else {
|
||||
// Synchronous test function - complete immediately.
|
||||
done();
|
||||
}
|
||||
} else {
|
||||
// Asynchronous test function that takes in 'done' parameter.
|
||||
testFn(done);
|
||||
}
|
||||
inIt = false;
|
||||
}, timeOut);
|
||||
}
|
||||
|
||||
export function it(name, fn, timeOut = null): void {
|
||||
return _it(jsmIt, name, fn, timeOut);
|
||||
}
|
||||
|
||||
export function xit(name, fn, timeOut = null): void {
|
||||
return _it(jsmXIt, name, fn, timeOut);
|
||||
}
|
||||
|
||||
export function iit(name, fn, timeOut = null): void {
|
||||
return _it(jsmIIt, name, fn, timeOut);
|
||||
}
|
||||
|
||||
export interface GuinessCompatibleSpy extends jasmine.Spy {
|
||||
/** By chaining the spy with and.returnValue, all calls to the function will return a specific
|
||||
* value. */
|
||||
andReturn(val: any): void;
|
||||
/** By chaining the spy with and.callFake, all calls to the spy will delegate to the supplied
|
||||
* function. */
|
||||
andCallFake(fn: Function): GuinessCompatibleSpy;
|
||||
/** removes all recorded calls */
|
||||
reset();
|
||||
}
|
||||
|
||||
export class SpyObject {
|
||||
constructor(type = null) {
|
||||
if (type) {
|
||||
for (var prop in type.prototype) {
|
||||
var m = null;
|
||||
try {
|
||||
m = type.prototype[prop];
|
||||
} catch (e) {
|
||||
// As we are creating spys for abstract classes,
|
||||
// these classes might have getters that throw when they are accessed.
|
||||
// As we are only auto creating spys for methods, this
|
||||
// should not matter.
|
||||
}
|
||||
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): GuinessCompatibleSpy {
|
||||
var newSpy: GuinessCompatibleSpy = <any>jasmine.createSpy(name);
|
||||
newSpy.andCallFake = <any>newSpy.and.callFake;
|
||||
newSpy.andReturn = <any>newSpy.and.returnValue;
|
||||
newSpy.reset = <any>newSpy.calls.reset;
|
||||
// revisit return null here (previously needed for rtts_assert).
|
||||
newSpy.and.returnValue(null);
|
||||
return newSpy;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user