angular/modules/angular2/src/test_lib/test_injector.js
Tobias Bosch bfa381b35a refactor(view): introduce AppViewManager to consolidate logic
AppViewManager is the single entry point to changing the view hierarchy.
It is split between the manager itself which does coordination and
helper methods, so both are easily testable in isolation.

Also, ViewContainer is now only a pure reference to a bound element
with the previous functionality but does not contain the list of views
any more.

Part of #1477
2015-04-24 20:26:18 -07:00

175 lines
5.9 KiB
JavaScript

import {bind} from 'angular2/di';
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
import {Reflector, reflector} from 'angular2/src/reflection/reflection';
import {Parser, Lexer, ChangeDetection, DynamicChangeDetection,
PipeRegistry, defaultPipeRegistry} from 'angular2/change_detection';
import {ExceptionHandler} from 'angular2/src/core/exception_handler';
import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
import {ShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/shadow_dom_strategy';
import {EmulatedUnscopedShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
import {XHR} from 'angular2/src/services/xhr';
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
import {UrlResolver} from 'angular2/src/services/url_resolver';
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
import {DOM} from 'angular2/src/dom/dom_adapter';
import {appDocumentToken} from 'angular2/src/core/application_tokens';
import {EventManager, DomEventsPlugin} from 'angular2/src/render/dom/events/event_manager';
import {MockTemplateResolver} from 'angular2/src/mock/template_resolver_mock';
import {MockXHR} from 'angular2/src/mock/xhr_mock';
import {MockVmTurnZone} from 'angular2/src/mock/vm_turn_zone_mock';
import {TestBed} from './test_bed';
import {Injector} from 'angular2/di';
import {List, ListWrapper} from 'angular2/src/facade/collection';
import {FunctionWrapper} from 'angular2/src/facade/lang';
import {AppViewPool, APP_VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_pool';
import {AppViewManager} from 'angular2/src/core/compiler/view_manager';
import {AppViewManagerUtils} from 'angular2/src/core/compiler/view_manager_utils';
import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
import {Renderer} from 'angular2/src/render/api';
import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
import * as rc from 'angular2/src/render/dom/compiler/compiler';
import * as rvf from 'angular2/src/render/dom/view/view_factory';
import * as rvh from 'angular2/src/render/dom/view/view_hydrator';
/**
* Returns the root injector bindings.
*
* This must be kept in sync with the _rootBindings in application.js
*
* @returns {any[]}
*/
function _getRootBindings() {
return [
bind(Reflector).toValue(reflector),
];
}
/**
* Returns the application injector bindings.
*
* This must be kept in sync with _injectorBindings() in application.js
*
* @returns {any[]}
*/
function _getAppBindings() {
var appDoc;
// The document is only available in browser environment
try {
appDoc = DOM.defaultDoc();
} catch(e) {
appDoc = null;
}
return [
bind(appDocumentToken).toValue(appDoc),
bind(ShadowDomStrategy).toFactory(
(styleUrlResolver, doc) => new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, doc.head),
[StyleUrlResolver, appDocumentToken]),
bind(DirectDomRenderer).toClass(DirectDomRenderer),
bind(Renderer).toClass(DirectDomRenderer),
bind(rc.Compiler).toClass(rc.DefaultCompiler),
rvf.ViewFactory,
rvh.RenderViewHydrator,
bind(rvf.VIEW_POOL_CAPACITY).toValue(500),
ProtoViewFactory,
AppViewPool,
AppViewManager,
AppViewManagerUtils,
bind(APP_VIEW_POOL_CAPACITY).toValue(500),
Compiler,
CompilerCache,
bind(TemplateResolver).toClass(MockTemplateResolver),
bind(PipeRegistry).toValue(defaultPipeRegistry),
bind(ChangeDetection).toClass(DynamicChangeDetection),
TemplateLoader,
DynamicComponentLoader,
DirectiveMetadataReader,
Parser,
Lexer,
ExceptionHandler,
bind(XHR).toClass(MockXHR),
ComponentUrlMapper,
UrlResolver,
StyleUrlResolver,
StyleInliner,
TestBed,
bind(VmTurnZone).toClass(MockVmTurnZone),
bind(EventManager).toFactory((zone) => {
var plugins = [
new DomEventsPlugin(),
];
return new EventManager(plugins, zone);
}, [VmTurnZone]),
];
}
export function createTestInjector(bindings: List) {
var rootInjector = Injector.resolveAndCreate(_getRootBindings());
return rootInjector.resolveAndCreateChild(ListWrapper.concat(_getAppBindings(), bindings));
}
/**
* Allows injecting dependencies in `beforeEach()` and `it()`.
*
* Example:
*
* ```
* beforeEach(inject([Dependency, AClass], (dep, object) => {
* // some code that uses `dep` and `object`
* // ...
* }));
*
* it('...', inject([AClass, AsyncTestCompleter], (object, async) => {
* object.doSomething().then(() => {
* expect(...);
* async.done();
* });
* })
* ```
*
* Notes:
* - injecting an `AsyncTestCompleter` allow completing async tests - this is the equivalent of
* adding a `done` parameter in Jasmine,
* - 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 {FunctionWithParamTokens}
* @exportedAs angular2/test
*/
export function inject(tokens: List, fn: Function) {
return new FunctionWithParamTokens(tokens, fn);
}
export class FunctionWithParamTokens {
_tokens: List;
_fn: Function;
constructor(tokens: List, fn: Function) {
this._tokens = tokens;
this._fn = fn;
}
execute(injector: Injector) {
var params = ListWrapper.map(this._tokens, (t) => injector.get(t));
FunctionWrapper.apply(this._fn, params);
}
}