Revert "refactor(testing): move common testing logic into test_injector"
This reverts commit b88a6d983f
.
This commit is contained in:
parent
3191fd1440
commit
2aaef81b1b
|
@ -23,7 +23,7 @@ import {
|
|||
defaultKeyValueDiffers,
|
||||
ChangeDetectorGenConfig
|
||||
} from 'angular2/src/core/change_detection/change_detection';
|
||||
import {BaseException, ExceptionHandler} from 'angular2/src/facade/exceptions';
|
||||
import {ExceptionHandler} from 'angular2/src/facade/exceptions';
|
||||
import {PipeResolver} from 'angular2/src/core/linker/pipe_resolver';
|
||||
import {XHR} from 'angular2/src/compiler/xhr';
|
||||
|
||||
|
@ -131,56 +131,14 @@ function _runtimeCompilerBindings() {
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures an injector suitable for testing.
|
||||
*/
|
||||
export class TestInjector {
|
||||
private _instantiated: boolean = false;
|
||||
|
||||
private _injector: Injector = null;
|
||||
|
||||
private _providers: Array<Type | Provider | any[]> = [];
|
||||
|
||||
reset() {
|
||||
this._injector = null;
|
||||
this._providers = [];
|
||||
this._instantiated = false;
|
||||
}
|
||||
|
||||
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 = Injector.resolveAndCreate(_getRootProviders());
|
||||
this._injector = rootInjector.resolveAndCreateChild(ListWrapper.concat(
|
||||
ListWrapper.concat(_getAppBindings(), _runtimeCompilerBindings()), this._providers));
|
||||
this._instantiated = true;
|
||||
return this._injector;
|
||||
}
|
||||
|
||||
execute(fn: FunctionWithParamTokens): any {
|
||||
if (!this._instantiated) {
|
||||
this.createInjector();
|
||||
}
|
||||
return fn.execute(this._injector);
|
||||
}
|
||||
export function createTestInjector(providers: Array<Type | Provider | any[]>): Injector {
|
||||
var rootInjector = Injector.resolveAndCreate(_getRootProviders());
|
||||
return rootInjector.resolveAndCreateChild(ListWrapper.concat(_getAppBindings(), providers));
|
||||
}
|
||||
|
||||
var _testInjector: TestInjector = null;
|
||||
|
||||
/**
|
||||
* Retrieve the {@link TestInjector}, possibly creating one if it doesn't
|
||||
* exist yet.
|
||||
*/
|
||||
export function getTestInjector() {
|
||||
if (_testInjector == null) {
|
||||
_testInjector = new TestInjector();
|
||||
}
|
||||
return _testInjector;
|
||||
export function createTestInjectorWithRuntimeCompiler(
|
||||
providers: Array<Type | Provider | any[]>): Injector {
|
||||
return createTestInjector(ListWrapper.concat(_runtimeCompilerBindings(), providers));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -216,17 +174,12 @@ export function inject(tokens: any[], fn: Function): FunctionWithParamTokens {
|
|||
}
|
||||
|
||||
/**
|
||||
* Use {@link inject} instead, which now supports both synchronous and asynchronous tests.
|
||||
*
|
||||
* @deprecated
|
||||
* @deprecated Use inject instead, which now supports both synchronous and asynchronous tests.
|
||||
*/
|
||||
export function injectAsync(tokens: any[], fn: Function): FunctionWithParamTokens {
|
||||
return new FunctionWithParamTokens(tokens, fn, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* A testing function with parameters which will be injected. See {@link inject} for details.
|
||||
*/
|
||||
export class FunctionWithParamTokens {
|
||||
constructor(private _tokens: any[], private _fn: Function, public isAsync: boolean) {}
|
||||
|
||||
|
|
|
@ -7,11 +7,10 @@ import {ListWrapper} from 'angular2/src/facade/collection';
|
|||
import {bind} from 'angular2/core';
|
||||
|
||||
import {
|
||||
createTestInjectorWithRuntimeCompiler,
|
||||
FunctionWithParamTokens,
|
||||
inject,
|
||||
injectAsync,
|
||||
TestInjector,
|
||||
getTestInjector
|
||||
injectAsync
|
||||
} from './test_injector';
|
||||
|
||||
export {inject, injectAsync} from './test_injector';
|
||||
|
@ -93,10 +92,14 @@ var jsmIt = _global.it;
|
|||
var jsmIIt = _global.fit;
|
||||
var jsmXIt = _global.xit;
|
||||
|
||||
var testInjector: TestInjector = getTestInjector();
|
||||
var testProviders;
|
||||
var injector;
|
||||
|
||||
// Reset the test providers before each test.
|
||||
jsmBeforeEach(() => { testInjector.reset(); });
|
||||
jsmBeforeEach(() => {
|
||||
testProviders = [];
|
||||
injector = null;
|
||||
});
|
||||
|
||||
/**
|
||||
* Allows overriding default providers of the test injector,
|
||||
|
@ -112,9 +115,8 @@ export function beforeEachProviders(fn): void {
|
|||
jsmBeforeEach(() => {
|
||||
var providers = fn();
|
||||
if (!providers) return;
|
||||
try {
|
||||
testInjector.addProviders(providers);
|
||||
} catch (e) {
|
||||
testProviders = [...testProviders, ...providers];
|
||||
if (injector !== null) {
|
||||
throw new Error('beforeEachProviders was called after the injector had ' +
|
||||
'been used in a beforeEach or it block. This invalidates the ' +
|
||||
'test injector');
|
||||
|
@ -186,7 +188,11 @@ function _it(jsmFn: Function, name: string, testFn: FunctionWithParamTokens | An
|
|||
|
||||
if (testFn instanceof FunctionWithParamTokens) {
|
||||
jsmFn(name, (done) => {
|
||||
var returnedTestValue = runInTestZone(() => testInjector.execute(testFn), done, done.fail);
|
||||
if (!injector) {
|
||||
injector = createTestInjectorWithRuntimeCompiler(testProviders);
|
||||
}
|
||||
|
||||
var returnedTestValue = runInTestZone(() => testFn.execute(injector), done, done.fail);
|
||||
if (_isPromiseLike(returnedTestValue)) {
|
||||
(<Promise<any>>returnedTestValue).then(null, (err) => { done.fail(err); });
|
||||
}
|
||||
|
@ -215,7 +221,13 @@ export function beforeEach(fn: FunctionWithParamTokens | AnyTestFn): void {
|
|||
// The test case uses inject(). ie `beforeEach(inject([ClassA], (a) => { ...
|
||||
// }));`
|
||||
|
||||
jsmBeforeEach((done) => { runInTestZone(() => testInjector.execute(fn), done, done.fail); });
|
||||
jsmBeforeEach((done) => {
|
||||
if (!injector) {
|
||||
injector = createTestInjectorWithRuntimeCompiler(testProviders);
|
||||
}
|
||||
|
||||
runInTestZone(() => fn.execute(injector), done, done.fail);
|
||||
});
|
||||
} else {
|
||||
// The test case doesn't use inject(). ie `beforeEach((done) => { ... }));`
|
||||
if ((<any>fn).length === 0) {
|
||||
|
|
|
@ -21,23 +21,20 @@ import 'package:angular2/src/core/reflection/reflection.dart';
|
|||
import 'package:angular2/src/core/reflection/reflection_capabilities.dart';
|
||||
|
||||
import 'package:angular2/src/core/di/provider.dart' show bind;
|
||||
import 'package:angular2/src/core/di/injector.dart' show Injector;
|
||||
import 'package:angular2/src/facade/collection.dart' show StringMapWrapper;
|
||||
|
||||
import 'test_injector.dart';
|
||||
export 'test_injector.dart' show inject;
|
||||
|
||||
TestInjector _testInjector = getTestInjector();
|
||||
List _testBindings = [];
|
||||
Injector _injector;
|
||||
bool _isCurrentTestAsync;
|
||||
Future _currentTestFuture;
|
||||
bool _inIt = false;
|
||||
|
||||
class AsyncTestCompleter {
|
||||
final _completer = new Completer();
|
||||
|
||||
AsyncTestCompleter() {
|
||||
_currentTestFuture = this.future;
|
||||
}
|
||||
|
||||
void done() {
|
||||
_completer.complete();
|
||||
}
|
||||
|
@ -53,11 +50,10 @@ void testSetup() {
|
|||
// - Priority 1: create the test injector to be used in beforeEach() and it()
|
||||
|
||||
gns.beforeEach(() {
|
||||
_testInjector.reset();
|
||||
_currentTestFuture = null;
|
||||
_testBindings.clear();
|
||||
}, priority: 3);
|
||||
|
||||
var completerProvider = bind(AsyncTestCompleter).toFactory(() {
|
||||
var completerBinding = bind(AsyncTestCompleter).toFactory(() {
|
||||
// Mark the test as async when an AsyncTestCompleter is injected in an it(),
|
||||
if (!_inIt) throw 'AsyncTestCompleter can only be injected in an "it()"';
|
||||
_isCurrentTestAsync = true;
|
||||
|
@ -66,14 +62,15 @@ void testSetup() {
|
|||
|
||||
gns.beforeEach(() {
|
||||
_isCurrentTestAsync = false;
|
||||
_testInjector.addProviders([completerProvider]);
|
||||
_testBindings.add(completerBinding);
|
||||
_injector = createTestInjectorWithRuntimeCompiler(_testBindings);
|
||||
}, priority: 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows overriding default providers defined in test_injector.js.
|
||||
* Allows overriding default bindings defined in test_injector.js.
|
||||
*
|
||||
* The given function must return a list of DI providers.
|
||||
* The given function must return a list of DI bindings.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
|
@ -84,8 +81,8 @@ void testSetup() {
|
|||
*/
|
||||
void beforeEachProviders(Function fn) {
|
||||
gns.beforeEach(() {
|
||||
var providers = fn();
|
||||
if (providers != null) _testInjector.addProviders(providers);
|
||||
var bindings = fn();
|
||||
if (bindings != null) _testBindings.addAll(bindings);
|
||||
}, priority: 2);
|
||||
}
|
||||
|
||||
|
@ -98,7 +95,7 @@ void beforeEach(fn) {
|
|||
if (fn is! FunctionWithParamTokens) fn =
|
||||
new FunctionWithParamTokens([], fn, false);
|
||||
gns.beforeEach(() {
|
||||
_testInjector.execute(fn);
|
||||
fn.execute(_injector);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -107,9 +104,9 @@ void _it(gnsFn, name, fn) {
|
|||
new FunctionWithParamTokens([], fn, false);
|
||||
gnsFn(name, () {
|
||||
_inIt = true;
|
||||
_testInjector.execute(fn);
|
||||
fn.execute(_injector);
|
||||
_inIt = false;
|
||||
if (_isCurrentTestAsync) return _currentTestFuture;
|
||||
if (_isCurrentTestAsync) return _injector.get(AsyncTestCompleter).future;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,11 @@ import {NgZoneZone} from 'angular2/src/core/zone/ng_zone';
|
|||
|
||||
import {provide} from 'angular2/core';
|
||||
|
||||
import {TestInjector, getTestInjector, FunctionWithParamTokens, inject} from './test_injector';
|
||||
import {
|
||||
createTestInjectorWithRuntimeCompiler,
|
||||
FunctionWithParamTokens,
|
||||
inject
|
||||
} from './test_injector';
|
||||
import {browserDetection} from './utils';
|
||||
|
||||
export {inject} from './test_injector';
|
||||
|
@ -44,7 +48,7 @@ var inIt = false;
|
|||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 500;
|
||||
var globalTimeOut = browserDetection.isSlow ? 3000 : jasmine.DEFAULT_TIMEOUT_INTERVAL;
|
||||
|
||||
var testInjector = getTestInjector();
|
||||
var testProviders;
|
||||
|
||||
/**
|
||||
* Mechanism to run `beforeEach()` functions of Angular tests.
|
||||
|
@ -58,17 +62,16 @@ class BeforeEachRunner {
|
|||
|
||||
beforeEach(fn: FunctionWithParamTokens | SyncTestFn): void { this._fns.push(fn); }
|
||||
|
||||
run(): void {
|
||||
if (this._parent) this._parent.run();
|
||||
run(injector): void {
|
||||
if (this._parent) this._parent.run(injector);
|
||||
this._fns.forEach((fn) => {
|
||||
return isFunction(fn) ? (<SyncTestFn>fn)() :
|
||||
(testInjector.execute(<FunctionWithParamTokens>fn));
|
||||
return isFunction(fn) ? (<SyncTestFn>fn)() : (<FunctionWithParamTokens>fn).execute(injector);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the test providers before each test
|
||||
jsmBeforeEach(() => { testInjector.reset(); });
|
||||
jsmBeforeEach(() => { testProviders = []; });
|
||||
|
||||
function _describe(jsmFn, ...args) {
|
||||
var parentRunner = runnerStack.length === 0 ? null : runnerStack[runnerStack.length - 1];
|
||||
|
@ -117,7 +120,7 @@ export function beforeEachProviders(fn): void {
|
|||
jsmBeforeEach(() => {
|
||||
var providers = fn();
|
||||
if (!providers) return;
|
||||
testInjector.addProviders(providers);
|
||||
testProviders = [...testProviders, ...providers];
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -147,17 +150,18 @@ function _it(jsmFn: Function, name: string, testFn: FunctionWithParamTokens | An
|
|||
}
|
||||
});
|
||||
|
||||
testInjector.addProviders([completerProvider]);
|
||||
runner.run();
|
||||
var injector = createTestInjectorWithRuntimeCompiler([...testProviders, completerProvider]);
|
||||
runner.run(injector);
|
||||
|
||||
inIt = true;
|
||||
testInjector.execute(testFn);
|
||||
testFn.execute(injector);
|
||||
inIt = false;
|
||||
}, timeOut);
|
||||
} else {
|
||||
jsmFn(name, () => {
|
||||
runner.run();
|
||||
testInjector.execute(testFn);
|
||||
var injector = createTestInjectorWithRuntimeCompiler(testProviders);
|
||||
runner.run(injector);
|
||||
testFn.execute(injector);
|
||||
}, timeOut);
|
||||
}
|
||||
|
||||
|
@ -166,12 +170,14 @@ function _it(jsmFn: Function, name: string, testFn: FunctionWithParamTokens | An
|
|||
|
||||
if ((<any>testFn).length === 0) {
|
||||
jsmFn(name, () => {
|
||||
runner.run();
|
||||
var injector = createTestInjectorWithRuntimeCompiler(testProviders);
|
||||
runner.run(injector);
|
||||
(<SyncTestFn>testFn)();
|
||||
}, timeOut);
|
||||
} else {
|
||||
jsmFn(name, (done) => {
|
||||
runner.run();
|
||||
var injector = createTestInjectorWithRuntimeCompiler(testProviders);
|
||||
runner.run(injector);
|
||||
(<AsyncTestFn>testFn)(done);
|
||||
}, timeOut);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import "package:angular2/testing_internal.dart"
|
|||
iit,
|
||||
expect,
|
||||
beforeEach,
|
||||
createTestInjector,
|
||||
beforeEachProviders,
|
||||
SpyObject,
|
||||
proxy;
|
||||
|
|
|
@ -10,6 +10,7 @@ import "package:angular2/testing_internal.dart"
|
|||
it,
|
||||
expect,
|
||||
beforeEach,
|
||||
createTestInjector,
|
||||
beforeEachProviders,
|
||||
SpyObject,
|
||||
proxy;
|
||||
|
|
|
@ -8,6 +8,7 @@ import "package:angular2/testing_internal.dart"
|
|||
it,
|
||||
expect,
|
||||
beforeEach,
|
||||
createTestInjector,
|
||||
beforeEachProviders,
|
||||
SpyObject,
|
||||
proxy;
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
it,
|
||||
expect,
|
||||
beforeEach,
|
||||
createTestInjectorWithRuntimeCompiler,
|
||||
beforeEachProviders,
|
||||
SpyObject,
|
||||
proxy
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
it,
|
||||
expect,
|
||||
beforeEach,
|
||||
createTestInjectorWithRuntimeCompiler,
|
||||
beforeEachProviders,
|
||||
SpyObject,
|
||||
proxy
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
it,
|
||||
expect,
|
||||
beforeEach,
|
||||
createTestInjectorWithRuntimeCompiler,
|
||||
beforeEachProviders,
|
||||
SpyObject,
|
||||
proxy
|
||||
|
|
|
@ -7,8 +7,8 @@ import {
|
|||
iit,
|
||||
expect,
|
||||
beforeEach,
|
||||
createTestInjectorWithRuntimeCompiler,
|
||||
beforeEachProviders,
|
||||
TestInjector,
|
||||
TestComponentBuilder
|
||||
} from "angular2/testing_internal";
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
|
@ -102,14 +102,12 @@ export function main() {
|
|||
beforeEachProviders(() => {
|
||||
var uiRenderProtoViewStore = new RenderProtoViewRefStore(false);
|
||||
uiRenderViewStore = new RenderViewWithFragmentsStore(false);
|
||||
var testInjector = new TestInjector();
|
||||
testInjector.addProviders([
|
||||
uiInjector = createTestInjectorWithRuntimeCompiler([
|
||||
provide(RenderProtoViewRefStore, {useValue: uiRenderProtoViewStore}),
|
||||
provide(RenderViewWithFragmentsStore, {useValue: uiRenderViewStore}),
|
||||
provide(DomRenderer, {useClass: DomRenderer_}),
|
||||
provide(Renderer, {useExisting: DomRenderer})
|
||||
]);
|
||||
uiInjector = testInjector.createInjector();
|
||||
var uiSerializer = uiInjector.get(Serializer);
|
||||
var domRenderer = uiInjector.get(DomRenderer);
|
||||
var workerRenderProtoViewStore = new RenderProtoViewRefStore(true);
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
it,
|
||||
expect,
|
||||
beforeEach,
|
||||
createTestInjectorWithRuntimeCompiler,
|
||||
beforeEachProviders
|
||||
} from 'angular2/testing_internal';
|
||||
import {SpyMessageBroker} from './spies';
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
library angular2_testing.angular2_testing;
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test/src/backend/invoker.dart';
|
||||
import 'package:test/src/backend/live_test.dart';
|
||||
|
||||
import 'package:angular2/angular2.dart';
|
||||
import 'package:angular2/src/core/di/injector.dart' show Injector;
|
||||
import 'package:angular2/src/core/di/metadata.dart' show InjectMetadata;
|
||||
import 'package:angular2/src/core/di/exceptions.dart' show NoAnnotationError;
|
||||
import 'package:angular2/platform/browser_static.dart' show BrowserDomAdapter;
|
||||
|
@ -28,13 +31,6 @@ void initAngularTests() {
|
|||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||
}
|
||||
|
||||
void _addTestInjectorTearDown() {
|
||||
// Multiple resets are harmless.
|
||||
tearDown(() {
|
||||
_testInjector.reset();
|
||||
});
|
||||
}
|
||||
|
||||
/// Allows overriding default bindings defined in test_injector.dart.
|
||||
///
|
||||
/// The given function must return a list of DI providers.
|
||||
|
@ -49,17 +45,13 @@ void _addTestInjectorTearDown() {
|
|||
/// ```
|
||||
void setUpProviders(Iterable<Provider> providerFactory()) {
|
||||
setUp(() {
|
||||
try {
|
||||
_testInjector.addProviders(providerFactory());
|
||||
} catch(e) {
|
||||
if (_currentInjector != null) {
|
||||
throw 'setUpProviders was called after the injector had '
|
||||
'been used in a setUp or test block. This invalidates the '
|
||||
'test injector';
|
||||
}
|
||||
|
||||
_currentTestProviders.addAll(providerFactory());
|
||||
});
|
||||
|
||||
_addTestInjectorTearDown();
|
||||
}
|
||||
|
||||
dynamic _runInjectableFunction(Function fn) {
|
||||
|
@ -80,8 +72,11 @@ dynamic _runInjectableFunction(Function fn) {
|
|||
tokens.add(token);
|
||||
}
|
||||
|
||||
if (_currentInjector == null) {
|
||||
_currentInjector = createTestInjectorWithRuntimeCompiler(_currentTestProviders);
|
||||
}
|
||||
var injectFn = new FunctionWithParamTokens(tokens, fn, false);
|
||||
return _testInjector.execute(injectFn);
|
||||
return injectFn.execute(_currentInjector);
|
||||
}
|
||||
|
||||
/// Use the test injector to get bindings and run a function.
|
||||
|
@ -97,8 +92,6 @@ void ngSetUp(Function fn) {
|
|||
setUp(() async {
|
||||
await _runInjectableFunction(fn);
|
||||
});
|
||||
|
||||
_addTestInjectorTearDown();
|
||||
}
|
||||
|
||||
/// Add a test which can use the test injector.
|
||||
|
@ -115,8 +108,25 @@ void ngTest(String description, Function fn,
|
|||
test(description, () async {
|
||||
await _runInjectableFunction(fn);
|
||||
}, testOn: testOn, timeout: timeout, skip: skip, onPlatform: onPlatform);
|
||||
|
||||
_addTestInjectorTearDown();
|
||||
}
|
||||
|
||||
final TestInjector _testInjector = getTestInjector();
|
||||
final _providersExpando =
|
||||
new Expando<List<Provider>>('Providers for the current test');
|
||||
final _injectorExpando =
|
||||
new Expando<Injector>('Angular Injector for the current test');
|
||||
|
||||
List get _currentTestProviders {
|
||||
if (_providersExpando[_currentTest] == null) {
|
||||
return _providersExpando[_currentTest] = [];
|
||||
}
|
||||
return _providersExpando[_currentTest];
|
||||
}
|
||||
|
||||
Injector get _currentInjector => _injectorExpando[_currentTest];
|
||||
void set _currentInjector(Injector newInjector) {
|
||||
_injectorExpando[_currentTest] = newInjector;
|
||||
}
|
||||
|
||||
// TODO: warning, the Invoker.current.liveTest is not a settled API and is
|
||||
// subject to change in future versions of package:test.
|
||||
LiveTest get _currentTest => Invoker.current.liveTest;
|
||||
|
|
Loading…
Reference in New Issue