Skip to content

Commit b0cebdb

Browse files
committed
feat(test): allow tests to specify the platform and application providers used
With providers split into bundles, the test injector is now able to use providers for a given bundle. Suggested provider lists for tests are available in `angular2/platform/testing/<platform>`. Change the providers for a test suite using `setBaseTestProviders`. This should be done once at the start of the test suite, before any test cases run. BREAKING CHANGE: Tests are now required to use `setBaseTestProviders` to set up. Assuming your tests are run on a browser, setup would change as follows. Before: ```js // Somewhere in test setup import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter'; BrowserDomAdapter.makeCurrent ``` After: ```js // Somewhere in the test setup import {setBaseTestProviders} from 'angular2/testing'; import { TEST_BROWSER_PLATFORM_PROVIDERS, TEST_BROWSER_APPLICATION_PROVIDERS } from 'angular2/platform/testing/browser'; setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS, TEST_BROWSER_APPLICATION_PROVIDERS); ``` Closes angular#5351, Closes angular#5585 Closes angular#5975
1 parent 933a911 commit b0cebdb

File tree

19 files changed

+265
-158
lines changed

19 files changed

+265
-158
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {
2+
TEST_BROWSER_STATIC_PLATFORM_PROVIDERS,
3+
ADDITIONAL_TEST_BROWSER_PROVIDERS
4+
} from 'angular2/platform/testing/browser_static';
5+
6+
import {BROWSER_APP_PROVIDERS} from 'angular2/platform/browser';
7+
8+
9+
import {CONST_EXPR} from 'angular2/src/facade/lang';
10+
11+
/**
12+
* Default patform providers for testing.
13+
*/
14+
export const TEST_BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
15+
CONST_EXPR([TEST_BROWSER_STATIC_PLATFORM_PROVIDERS]);
16+
17+
/**
18+
* Default application providers for testing.
19+
*/
20+
export const TEST_BROWSER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
21+
CONST_EXPR([BROWSER_APP_PROVIDERS, ADDITIONAL_TEST_BROWSER_PROVIDERS]);
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import {
2+
APP_ID,
3+
DirectiveResolver,
4+
NgZone,
5+
Provider,
6+
ViewResolver,
7+
PLATFORM_COMMON_PROVIDERS,
8+
PLATFORM_INITIALIZER
9+
} from 'angular2/core';
10+
import {BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common';
11+
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
12+
13+
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
14+
import {MockAnimationBuilder} from 'angular2/src/mock/animation_builder_mock';
15+
import {MockDirectiveResolver} from 'angular2/src/mock/directive_resolver_mock';
16+
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
17+
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
18+
import {LocationStrategy} from 'angular2/src/router/location_strategy';
19+
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
20+
21+
import {XHRImpl} from "angular2/src/platform/browser/xhr_impl";
22+
import {XHR} from 'angular2/compiler';
23+
24+
import {TestComponentBuilder} from 'angular2/src/testing/test_component_builder';
25+
26+
import {BrowserDetection} from 'angular2/src/testing/utils';
27+
28+
import {ELEMENT_PROBE_PROVIDERS} from 'angular2/platform/common_dom';
29+
30+
import {CONST_EXPR} from 'angular2/src/facade/lang';
31+
32+
import {Log} from 'angular2/src/testing/utils';
33+
34+
function initBrowserTests() {
35+
BrowserDomAdapter.makeCurrent();
36+
BrowserDetection.setup();
37+
}
38+
39+
/**
40+
* Default patform providers for testing without a compiler.
41+
*/
42+
export const TEST_BROWSER_STATIC_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
43+
CONST_EXPR([
44+
PLATFORM_COMMON_PROVIDERS,
45+
new Provider(PLATFORM_INITIALIZER, {useValue: initBrowserTests, multi: true})
46+
]);
47+
48+
export const ADDITIONAL_TEST_BROWSER_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
49+
CONST_EXPR([
50+
new Provider(APP_ID, {useValue: 'a'}),
51+
ELEMENT_PROBE_PROVIDERS,
52+
new Provider(DirectiveResolver, {useClass: MockDirectiveResolver}),
53+
new Provider(ViewResolver, {useClass: MockViewResolver}),
54+
Log,
55+
TestComponentBuilder,
56+
new Provider(NgZone, {useClass: MockNgZone}),
57+
new Provider(LocationStrategy, {useClass: MockLocationStrategy}),
58+
new Provider(AnimationBuilder, {useClass: MockAnimationBuilder}),
59+
]);
60+
61+
/**
62+
* Default application providers for testing without a compiler.
63+
*/
64+
export const TEST_BROWSER_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
65+
CONST_EXPR([
66+
BROWSER_APP_COMMON_PROVIDERS,
67+
new Provider(XHR, {useClass: XHRImpl}),
68+
ADDITIONAL_TEST_BROWSER_PROVIDERS
69+
]);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// Intentionally blank, the Parse5Adapater bindings for JavaScript don't apply.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import {
2+
APP_ID,
3+
DirectiveResolver,
4+
NgZone,
5+
Provider,
6+
ViewResolver,
7+
PLATFORM_COMMON_PROVIDERS,
8+
PLATFORM_INITIALIZER,
9+
APPLICATION_COMMON_PROVIDERS,
10+
Renderer
11+
} from 'angular2/core';
12+
import {Parse5DomAdapter} from 'angular2/src/platform/server/parse5_adapter';
13+
14+
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
15+
import {MockAnimationBuilder} from 'angular2/src/mock/animation_builder_mock';
16+
import {MockDirectiveResolver} from 'angular2/src/mock/directive_resolver_mock';
17+
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
18+
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
19+
import {LocationStrategy} from 'angular2/src/router/location_strategy';
20+
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
21+
22+
import {TestComponentBuilder} from 'angular2/src/testing/test_component_builder';
23+
import {XHR} from 'angular2/src/compiler/xhr';
24+
import {BrowserDetection} from 'angular2/src/testing/utils';
25+
26+
import {COMPILER_PROVIDERS} from 'angular2/src/compiler/compiler';
27+
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
28+
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
29+
import {RootRenderer} from 'angular2/src/core/render/api';
30+
import {DomRootRenderer, DomRootRenderer_} from 'angular2/src/platform/dom/dom_renderer';
31+
import {DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
32+
33+
import {
34+
EventManager,
35+
EVENT_MANAGER_PLUGINS,
36+
ELEMENT_PROBE_PROVIDERS
37+
} from 'angular2/platform/common_dom';
38+
import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
39+
40+
import {CONST_EXPR} from 'angular2/src/facade/lang';
41+
42+
import {Log} from 'angular2/src/testing/utils';
43+
44+
function initServerTests() {
45+
Parse5DomAdapter.makeCurrent();
46+
BrowserDetection.setup();
47+
}
48+
49+
/**
50+
* Default patform providers for testing.
51+
*/
52+
export const TEST_SERVER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
53+
PLATFORM_COMMON_PROVIDERS,
54+
new Provider(PLATFORM_INITIALIZER, {useValue: initServerTests, multi: true})
55+
]);
56+
57+
function appDoc() {
58+
try {
59+
return DOM.defaultDoc();
60+
} catch (e) {
61+
return null;
62+
}
63+
}
64+
65+
/**
66+
* Default application providers for testing.
67+
*/
68+
export const TEST_SERVER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
69+
CONST_EXPR([
70+
// TODO(julie): when angular2/platform/server is available, use that instead of making our own
71+
// list here.
72+
APPLICATION_COMMON_PROVIDERS,
73+
COMPILER_PROVIDERS,
74+
new Provider(DOCUMENT, {useFactory: appDoc}),
75+
new Provider(DomRootRenderer, {useClass: DomRootRenderer_}),
76+
new Provider(RootRenderer, {useExisting: DomRootRenderer}),
77+
EventManager,
78+
new Provider(EVENT_MANAGER_PLUGINS, {useClass: DomEventsPlugin, multi: true}),
79+
new Provider(XHR, {useClass: XHR}),
80+
new Provider(APP_ID, {useValue: 'a'}),
81+
DomSharedStylesHost,
82+
ELEMENT_PROBE_PROVIDERS,
83+
new Provider(DirectiveResolver, {useClass: MockDirectiveResolver}),
84+
new Provider(ViewResolver, {useClass: MockViewResolver}),
85+
Log,
86+
TestComponentBuilder,
87+
new Provider(NgZone, {useClass: MockNgZone}),
88+
new Provider(LocationStrategy, {useClass: MockLocationStrategy}),
89+
new Provider(AnimationBuilder, {useClass: MockAnimationBuilder}),
90+
]);

modules/angular2/src/platform/dom/dom_adapter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export abstract class DomAdapter {
2323
abstract logGroup(error);
2424
abstract logGroupEnd();
2525

26+
/** @deprecated */
2627
abstract getXHR(): Type;
2728

2829
/**

modules/angular2/src/testing/test_injector.ts

Lines changed: 38 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,7 @@
1-
import {
2-
APP_ID,
3-
APPLICATION_COMMON_PROVIDERS,
4-
AppViewManager,
5-
DirectiveResolver,
6-
DynamicComponentLoader,
7-
Injector,
8-
NgZone,
9-
Renderer,
10-
Provider,
11-
ViewResolver,
12-
provide
13-
} from 'angular2/core';
14-
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
15-
import {MockAnimationBuilder} from 'angular2/src/mock/animation_builder_mock';
16-
17-
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
18-
import {Reflector, reflector} from 'angular2/src/core/reflection/reflection';
19-
import {
20-
IterableDiffers,
21-
defaultIterableDiffers,
22-
KeyValueDiffers,
23-
defaultKeyValueDiffers,
24-
ChangeDetectorGenConfig
25-
} from 'angular2/src/core/change_detection/change_detection';
1+
import {Injector, Provider, PLATFORM_INITIALIZER} from 'angular2/core';
262
import {BaseException, ExceptionHandler} from 'angular2/src/facade/exceptions';
27-
import {PipeResolver} from 'angular2/src/core/linker/pipe_resolver';
28-
import {XHR} from 'angular2/src/compiler/xhr';
29-
30-
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
31-
32-
import {MockDirectiveResolver} from 'angular2/src/mock/directive_resolver_mock';
33-
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
34-
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
35-
import {LocationStrategy} from 'angular2/src/router/location_strategy';
36-
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
37-
38-
import {TestComponentBuilder} from './test_component_builder';
39-
40-
import {
41-
EventManager,
42-
EVENT_MANAGER_PLUGINS,
43-
ELEMENT_PROBE_PROVIDERS
44-
} from 'angular2/platform/common_dom';
45-
463
import {ListWrapper} from 'angular2/src/facade/collection';
47-
import {FunctionWrapper, Type} from 'angular2/src/facade/lang';
48-
49-
import {RootRenderer} from 'angular2/src/core/render/api';
50-
51-
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
52-
import {DomRootRenderer, DomRootRenderer_} from 'angular2/src/platform/dom/dom_renderer';
53-
import {DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
54-
import {SharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
55-
import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
56-
57-
import {Serializer} from "angular2/src/web_workers/shared/serializer";
58-
import {Log} from './utils';
59-
import {COMPILER_PROVIDERS} from 'angular2/src/compiler/compiler';
60-
import {DynamicComponentLoader_} from "angular2/src/core/linker/dynamic_component_loader";
61-
import {AppViewManager_} from "angular2/src/core/linker/view_manager";
62-
63-
/**
64-
* Returns the root injector providers.
65-
*
66-
* This must be kept in sync with the _rootBindings in application.js
67-
*
68-
* @returns {any[]}
69-
*/
70-
function _getRootProviders() {
71-
return [provide(Reflector, {useValue: reflector})];
72-
}
73-
74-
/**
75-
* Returns the application injector providers.
76-
*
77-
* This must be kept in sync with _injectorBindings() in application.js
78-
*
79-
* @returns {any[]}
80-
*/
81-
function _getAppBindings() {
82-
var appDoc;
83-
84-
// The document is only available in browser environment
85-
try {
86-
appDoc = DOM.defaultDoc();
87-
} catch (e) {
88-
appDoc = null;
89-
}
90-
91-
return [
92-
APPLICATION_COMMON_PROVIDERS,
93-
provide(ChangeDetectorGenConfig, {useValue: new ChangeDetectorGenConfig(true, false, false)}),
94-
provide(DOCUMENT, {useValue: appDoc}),
95-
provide(DomRootRenderer, {useClass: DomRootRenderer_}),
96-
provide(RootRenderer, {useExisting: DomRootRenderer}),
97-
provide(APP_ID, {useValue: 'a'}),
98-
DomSharedStylesHost,
99-
provide(SharedStylesHost, {useExisting: DomSharedStylesHost}),
100-
provide(AppViewManager, {useClass: AppViewManager_}),
101-
Serializer,
102-
ELEMENT_PROBE_PROVIDERS,
103-
ResolvedMetadataCache,
104-
provide(DirectiveResolver, {useClass: MockDirectiveResolver}),
105-
provide(ViewResolver, {useClass: MockViewResolver}),
106-
provide(IterableDiffers, {useValue: defaultIterableDiffers}),
107-
provide(KeyValueDiffers, {useValue: defaultKeyValueDiffers}),
108-
Log,
109-
provide(DynamicComponentLoader, {useClass: DynamicComponentLoader_}),
110-
PipeResolver,
111-
provide(ExceptionHandler, {useValue: new ExceptionHandler(DOM)}),
112-
provide(LocationStrategy, {useClass: MockLocationStrategy}),
113-
provide(XHR, {useClass: DOM.getXHR()}),
114-
TestComponentBuilder,
115-
provide(NgZone, {useClass: MockNgZone}),
116-
provide(AnimationBuilder, {useClass: MockAnimationBuilder}),
117-
EventManager,
118-
new Provider(EVENT_MANAGER_PLUGINS, {useClass: DomEventsPlugin, multi: true})
119-
];
120-
}
121-
122-
function _runtimeCompilerBindings() {
123-
return [
124-
provide(XHR, {useClass: DOM.getXHR()}),
125-
COMPILER_PROVIDERS,
126-
];
127-
}
4+
import {FunctionWrapper, isPresent, Type} from 'angular2/src/facade/lang';
1285

1296
export class TestInjector {
1307
private _instantiated: boolean = false;
@@ -139,6 +16,10 @@ export class TestInjector {
13916
this._instantiated = false;
14017
}
14118

19+
platformProviders: Array<Type | Provider | any[]> = [];
20+
21+
applicationProviders: Array<Type | Provider | any[]> = [];
22+
14223
addProviders(providers: Array<Type | Provider | any[]>) {
14324
if (this._instantiated) {
14425
throw new BaseException('Cannot add providers after test injector is instantiated');
@@ -147,9 +28,9 @@ export class TestInjector {
14728
}
14829

14930
createInjector() {
150-
var rootInjector = Injector.resolveAndCreate(_getRootProviders());
151-
this._injector = rootInjector.resolveAndCreateChild(ListWrapper.concat(
152-
ListWrapper.concat(_getAppBindings(), _runtimeCompilerBindings()), this._providers));
31+
var rootInjector = Injector.resolveAndCreate(this.platformProviders);
32+
this._injector = rootInjector.resolveAndCreateChild(
33+
ListWrapper.concat(this.applicationProviders, this._providers));
15334
this._instantiated = true;
15435
return this._injector;
15536
}
@@ -172,19 +53,40 @@ export function getTestInjector() {
17253
}
17354

17455
/**
175-
* @deprecated Use TestInjector#createInjector() instead.
56+
* Set the providers that the test injector should use. These should be providers
57+
* common to every test in the suite.
58+
*
59+
* This may only be called once, to set up the common providers for the current test
60+
* suite on teh current platform. If you absolutely need to change the providers,
61+
* first use `resetBaseTestProviders`.
62+
*
63+
* Test Providers for individual platforms are available from
64+
* 'angular2/platform/testing/<platform_name>'.
17665
*/
177-
export function createTestInjector(providers: Array<Type | Provider | any[]>): Injector {
178-
var rootInjector = Injector.resolveAndCreate(_getRootProviders());
179-
return rootInjector.resolveAndCreateChild(ListWrapper.concat(_getAppBindings(), providers));
66+
export function setBaseTestProviders(platformProviders: Array<Type | Provider | any[]>,
67+
applicationProviders: Array<Type | Provider | any[]>) {
68+
var testInjector = getTestInjector();
69+
if (testInjector.platformProviders.length > 0 || testInjector.applicationProviders.length > 0) {
70+
throw new BaseException('Cannot set base providers because it has already been called');
71+
}
72+
testInjector.platformProviders = platformProviders;
73+
testInjector.applicationProviders = applicationProviders;
74+
var injector = testInjector.createInjector();
75+
let inits: Function[] = injector.getOptional(PLATFORM_INITIALIZER);
76+
if (isPresent(inits)) {
77+
inits.forEach(init => init());
78+
}
79+
testInjector.reset();
18080
}
18181

18282
/**
183-
* @deprecated Use TestInjector#createInjector() instead.
83+
* Reset the providers for the test injector.
18484
*/
185-
export function createTestInjectorWithRuntimeCompiler(
186-
providers: Array<Type | Provider | any[]>): Injector {
187-
return createTestInjector(ListWrapper.concat(_runtimeCompilerBindings(), providers));
85+
export function resetBaseTestProviders() {
86+
var testInjector = getTestInjector();
87+
testInjector.platformProviders = [];
88+
testInjector.applicationProviders = [];
89+
testInjector.reset();
18890
}
18991

19092
/**

0 commit comments

Comments
 (0)