feat(testing): add implicit test module
Every test now has an implicit module. It can be configured via `configureModule` (from @angular/core/testing)
to add providers, directives, pipes, ...
The compiler now has to be configured separately via `configureCompiler` (from @angular/core/testing)
to add providers or define whether to use jit.
BREAKING CHANGE:
- Application providers can no longer inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead. This reflects the
changes to `bootstrap` for module support (3f55aa609f
).
- Compiler providers can no longer be added via `addProviders` / `withProviders`.
Use the new method `configureCompiler` instead.
- Platform directives / pipes need to be provided via
`configureModule` and can no longer be provided via the
`PLATFORM_PIPES` / `PLATFORM_DIRECTIVES` tokens.
- `setBaseTestProviders()` was renamed into `initTestEnvironment` and
now takes a `PlatformRef` and a factory for a
`Compiler`.
- E.g. for the browser platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from ‘@angular/platform-browser-dynamic/testing’;
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
```
AFTER:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {browserTestCompiler, browserDynamicTestPlatform,
BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
browserTestCompiler,
browserDynamicTestPlatform(),
BrowserDynamicTestModule);
```
- E.g. for the server platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS} from ‘@angular/platform-server/testing/server’;
setBaseTestProviders(TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS);
```
AFTER:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {serverTestCompiler, serverTestPlatform,
ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
serverTestCompiler,
serverTestPlatform(),
ServerTestModule);
```
Related to #9726
Closes #9846
This commit is contained in:
@ -6,11 +6,14 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {addProviders, inject, fakeAsync, async, withProviders, tick,} from '@angular/core/testing';
|
||||
import {TestComponentBuilder} from '@angular/compiler/testing';
|
||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||
import {Injectable, provide, Component, ViewMetadata} from '@angular/core';
|
||||
import {NgIf} from '@angular/common';
|
||||
import {CompilerConfig, XHR} from '@angular/compiler';
|
||||
import {TestComponentBuilder} from '@angular/compiler/testing';
|
||||
import {AppModule, Component, ComponentFactoryResolver, Directive, Injectable, Input, Pipe, ViewMetadata, provide} from '@angular/core';
|
||||
import {addProviders, async, configureCompiler, configureModule, fakeAsync, inject, tick, withModule, withProviders} from '@angular/core/testing';
|
||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||
|
||||
import {stringify} from '../../http/src/facade/lang';
|
||||
import {PromiseWrapper} from '../../http/src/facade/promise';
|
||||
|
||||
// Services, and components for the tests.
|
||||
@ -98,6 +101,29 @@ class TestViewProvidersComp {
|
||||
constructor(private fancyService: FancyService) {}
|
||||
}
|
||||
|
||||
@Directive({selector: '[someDir]', host: {'[title]': 'someDir'}})
|
||||
class SomeDirective {
|
||||
@Input()
|
||||
someDir: string;
|
||||
}
|
||||
|
||||
@Pipe({name: 'somePipe'})
|
||||
class SomePipe {
|
||||
transform(value: string): any { return `transformed ${value}`; }
|
||||
}
|
||||
|
||||
@Component({selector: 'comp', template: `<div [someDir]="'someValue' | somePipe"></div>`})
|
||||
class CompUsingModuleDirectiveAndPipe {
|
||||
}
|
||||
|
||||
@AppModule({})
|
||||
class SomeNestedModule {
|
||||
}
|
||||
|
||||
@Component({selector: 'comp', templateUrl: 'someTemplate.html'})
|
||||
class CompWithUrlTemplate {
|
||||
}
|
||||
|
||||
export function main() {
|
||||
describe('using the async helper', () => {
|
||||
var actuallyDone: boolean;
|
||||
@ -203,6 +229,133 @@ export function main() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('using the test injector with modules', () => {
|
||||
let moduleConfig: any;
|
||||
beforeEach(() => {
|
||||
moduleConfig = {
|
||||
providers: [FancyService],
|
||||
directives: [SomeDirective],
|
||||
pipes: [SomePipe],
|
||||
precompile: [CompUsingModuleDirectiveAndPipe],
|
||||
modules: [SomeNestedModule]
|
||||
};
|
||||
});
|
||||
|
||||
describe('setting up a module', () => {
|
||||
beforeEach(() => configureModule(moduleConfig));
|
||||
|
||||
it('should use set up providers', inject([FancyService], (service: FancyService) => {
|
||||
expect(service.value).toEqual('real value');
|
||||
}));
|
||||
|
||||
it('should use set up directives and pipes',
|
||||
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
let compFixture = tcb.createSync(CompUsingModuleDirectiveAndPipe);
|
||||
let el = compFixture.debugElement;
|
||||
|
||||
compFixture.detectChanges();
|
||||
expect(el.children[0].properties['title']).toBe('transformed someValue');
|
||||
}));
|
||||
|
||||
it('should use set up nested modules',
|
||||
inject([SomeNestedModule], (nestedModule: SomeNestedModule) => {
|
||||
expect(nestedModule).toBeAnInstanceOf(SomeNestedModule);
|
||||
}));
|
||||
|
||||
it('should use set up precompile components',
|
||||
inject([ComponentFactoryResolver], (resolver: ComponentFactoryResolver) => {
|
||||
expect(resolver.resolveComponentFactory(CompUsingModuleDirectiveAndPipe).componentType)
|
||||
.toBe(CompUsingModuleDirectiveAndPipe);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('per test modules', () => {
|
||||
it('should use set up providers',
|
||||
withModule(() => moduleConfig).inject([FancyService], (service: FancyService) => {
|
||||
expect(service.value).toEqual('real value');
|
||||
}));
|
||||
|
||||
it('should use set up directives and pipes',
|
||||
withModule(() => moduleConfig)
|
||||
.inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
let compFixture = tcb.createSync(CompUsingModuleDirectiveAndPipe);
|
||||
let el = compFixture.debugElement;
|
||||
|
||||
compFixture.detectChanges();
|
||||
expect(el.children[0].properties['title']).toBe('transformed someValue');
|
||||
}));
|
||||
|
||||
it('should use set up nested modules',
|
||||
withModule(() => moduleConfig)
|
||||
.inject([SomeNestedModule], (nestedModule: SomeNestedModule) => {
|
||||
expect(nestedModule).toBeAnInstanceOf(SomeNestedModule);
|
||||
}));
|
||||
|
||||
it('should use set up precompile components',
|
||||
withModule(() => moduleConfig)
|
||||
.inject([ComponentFactoryResolver], (resolver: ComponentFactoryResolver) => {
|
||||
expect(
|
||||
resolver.resolveComponentFactory(CompUsingModuleDirectiveAndPipe).componentType)
|
||||
.toBe(CompUsingModuleDirectiveAndPipe);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('precompile components with template url', () => {
|
||||
let xhrGet: jasmine.Spy;
|
||||
beforeEach(() => {
|
||||
xhrGet = jasmine.createSpy('xhrGet').and.returnValue(Promise.resolve('Hello world!'));
|
||||
configureCompiler({providers: [{provide: XHR, useValue: {get: xhrGet}}]});
|
||||
});
|
||||
|
||||
it('should allow to precompile components with templateUrl using the async helper',
|
||||
async(withModule(() => {
|
||||
return {precompile: [CompWithUrlTemplate]};
|
||||
}).inject([ComponentFactoryResolver], (resolver: ComponentFactoryResolver) => {
|
||||
expect(resolver.resolveComponentFactory(CompWithUrlTemplate).componentType)
|
||||
.toBe(CompWithUrlTemplate);
|
||||
})));
|
||||
|
||||
it('should allow to precompile components with templateUrl using the fakeAsync helper',
|
||||
fakeAsync(withModule(() => {
|
||||
return {precompile: [CompWithUrlTemplate]};
|
||||
}).inject([ComponentFactoryResolver], (resolver: ComponentFactoryResolver) => {
|
||||
expect(resolver.resolveComponentFactory(CompWithUrlTemplate).componentType)
|
||||
.toBe(CompWithUrlTemplate);
|
||||
})));
|
||||
});
|
||||
|
||||
describe('setting up the compiler', () => {
|
||||
|
||||
describe('providers', () => {
|
||||
beforeEach(() => {
|
||||
let xhrGet = jasmine.createSpy('xhrGet').and.returnValue(Promise.resolve('Hello world!'));
|
||||
configureCompiler({providers: [{provide: XHR, useValue: {get: xhrGet}}]});
|
||||
});
|
||||
|
||||
it('should use set up providers',
|
||||
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
let compFixture = tcb.createFakeAsync(CompWithUrlTemplate);
|
||||
expect(compFixture.nativeElement).toHaveText('Hello world!');
|
||||
})));
|
||||
});
|
||||
|
||||
describe('useJit true', () => {
|
||||
beforeEach(() => { configureCompiler({useJit: true}); });
|
||||
it('should set the value into CompilerConfig',
|
||||
inject([CompilerConfig], (config: CompilerConfig) => {
|
||||
expect(config.useJit).toBe(true);
|
||||
}));
|
||||
});
|
||||
describe('useJit false', () => {
|
||||
beforeEach(() => { configureCompiler({useJit: false}); });
|
||||
it('should set the value into CompilerConfig',
|
||||
inject([CompilerConfig], (config: CompilerConfig) => {
|
||||
expect(config.useJit).toBe(false);
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('errors', () => {
|
||||
var originalJasmineIt: any;
|
||||
var originalJasmineBeforeEach: any;
|
||||
@ -294,6 +447,36 @@ export function main() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('precompile', () => {
|
||||
let xhrGet: jasmine.Spy;
|
||||
beforeEach(() => {
|
||||
xhrGet = jasmine.createSpy('xhrGet').and.returnValue(Promise.resolve('Hello world!'));
|
||||
configureCompiler({providers: [{provide: XHR, useValue: {get: xhrGet}}]});
|
||||
});
|
||||
|
||||
it('should report an error for precompile components with templateUrl and sync tests', () => {
|
||||
var itPromise = patchJasmineIt();
|
||||
|
||||
expect(
|
||||
() => it(
|
||||
'should fail',
|
||||
withModule(() => { return {precompile: [CompWithUrlTemplate]}; })
|
||||
.inject(
|
||||
[ComponentFactoryResolver],
|
||||
(resolver: ComponentFactoryResolver) => {
|
||||
expect(
|
||||
resolver.resolveComponentFactory(CompWithUrlTemplate).componentType)
|
||||
.toBe(CompWithUrlTemplate);
|
||||
})))
|
||||
.toThrowError(
|
||||
`This test module precompiles the component ${stringify(CompWithUrlTemplate)} which is using a "templateUrl", but the test is synchronous. ` +
|
||||
'Please use the "async(...)" or "fakeAsync(...)" helper functions to make the test asynchronous.');
|
||||
|
||||
restoreJasmineIt();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('test component builder', function() {
|
||||
|
Reference in New Issue
Block a user