feat(compiler): support sync runtime compile

Adds new abstraction `Compiler` with methods
`compileComponentAsync` and `compileComponentSync`.
This is in preparation of deprecating `ComponentResolver`.

`compileComponentSync` is able to compile components
synchronously given all components either have an inline
template or they have been compiled before.

Also changes `TestComponentBuilder.createSync` to
take a `Type` and use the new `compileComponentSync` method.

Also supports overriding the component metadata even if
the component has already been compiled.

Also fixes #7084 in a better way.

BREAKING CHANGE:
`TestComponentBuilder.createSync` now takes a component type
and throws if not all templates are either inlined
are compiled before via `createAsync`.

Closes #9594
This commit is contained in:
Tobias Bosch
2016-06-24 08:46:43 -07:00
parent 24eb8389d2
commit bf598d6b8b
35 changed files with 1093 additions and 700 deletions

View File

@ -6,18 +6,19 @@
* found in the LICENSE file at https://angular.io/license
*/
import {beforeEach, ddescribe, describe, expect, iit, it,} from '@angular/core/testing/testing_internal';
import {beforeEach, ddescribe, describe, expect, iit, it, inject,} from '@angular/core/testing/testing_internal';
import {stringify} from '../src/facade/lang';
import {MockViewResolver} from '../testing';
import {Component, ViewMetadata} from '@angular/core';
import {Component, ViewMetadata, Injector} from '@angular/core';
import {isBlank} from '../src/facade/lang';
export function main() {
describe('MockViewResolver', () => {
var viewResolver: MockViewResolver;
beforeEach(() => { viewResolver = new MockViewResolver(); });
beforeEach(inject(
[Injector], (injector: Injector) => { viewResolver = new MockViewResolver(injector); }));
describe('View overriding', () => {
it('should fallback to the default ViewResolver when templates are not overridden', () => {
@ -33,13 +34,12 @@ export function main() {
expect(isBlank(view.directives)).toBe(true);
});
it('should not allow overriding a view after it has been resolved', () => {
it('should allow overriding a view after it has been resolved', () => {
viewResolver.resolve(SomeComponent);
expect(() => {
viewResolver.setView(SomeComponent, new ViewMetadata({template: 'overridden template'}));
})
.toThrowError(
`The component ${stringify(SomeComponent)} has already been compiled, its configuration can not be changed`);
viewResolver.setView(SomeComponent, new ViewMetadata({template: 'overridden template'}));
var view = viewResolver.resolve(SomeComponent);
expect(view.template).toEqual('overridden template');
expect(isBlank(view.directives)).toBe(true);
});
});
@ -58,11 +58,11 @@ export function main() {
expect(view.template).toEqual('overridden template x 2');
});
it('should not allow overriding a view after it has been resolved', () => {
it('should allow overriding a view after it has been resolved', () => {
viewResolver.resolve(SomeComponent);
expect(() => { viewResolver.setInlineTemplate(SomeComponent, 'overridden template'); })
.toThrowError(
`The component ${stringify(SomeComponent)} has already been compiled, its configuration can not be changed`);
viewResolver.setInlineTemplate(SomeComponent, 'overridden template');
var view = viewResolver.resolve(SomeComponent);
expect(view.template).toEqual('overridden template');
});
});
@ -90,13 +90,12 @@ export function main() {
`Overriden directive ${stringify(SomeOtherDirective)} not found in the template of ${stringify(SomeComponent)}`);
});
it('should not allow overriding a directive after its view has been resolved', () => {
it('should allow overriding a directive after its view has been resolved', () => {
viewResolver.resolve(SomeComponent);
expect(() => {
viewResolver.overrideViewDirective(SomeComponent, SomeDirective, SomeOtherDirective);
})
.toThrowError(
`The component ${stringify(SomeComponent)} has already been compiled, its configuration can not be changed`);
viewResolver.overrideViewDirective(SomeComponent, SomeDirective, SomeOtherDirective);
var view = viewResolver.resolve(SomeComponent);
expect(view.directives.length).toEqual(1);
expect(view.directives[0]).toBe(SomeOtherDirective);
});
});
});