test(ivy): enable more @angular/core tests (#27654)

PR Close #27654
This commit is contained in:
Marc Laval 2018-12-13 18:16:03 +01:00 committed by Miško Hevery
parent a433baf99a
commit 8042140742
4 changed files with 143 additions and 60 deletions

View File

@ -308,7 +308,7 @@ export function getOrCreateInjectable<T>(
try {
const value = bloomHash();
if (value == null && !(flags & InjectFlags.Optional)) {
throw new Error(`No provider for ${stringify(token)}`);
throw new Error(`No provider for ${stringify(token)}!`);
} else {
return value;
}

View File

@ -35,6 +35,8 @@ export function stringify(value: any): string {
if (typeof value == 'function') return value.name || value;
if (typeof value == 'string') return value;
if (value == null) return '';
if (typeof value == 'object' && typeof value.type == 'function')
return value.type.name || value.type;
return '' + value;
}

View File

@ -10,7 +10,7 @@ import {Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, Compon
import {ComponentFixture, TestBed, fakeAsync} from '@angular/core/testing';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {fixmeIvy} from '@angular/private/testing';
import {fixmeIvy, obsoleteInIvy, onlyInIvy} from '@angular/private/testing';
@Directive({selector: '[simpleDirective]'})
class SimpleDirective {
@ -598,57 +598,109 @@ class TestComp {
expect(el.children[0].injector.get(NeedsAppService).service).toEqual('appService');
});
fixmeIvy('unknown').it('should not instantiate a directive with cyclic dependencies', () => {
TestBed.configureTestingModule({declarations: [CycleDirective]});
expect(() => createComponent('<div cycleDirective></div>'))
.toThrowError(
/Template parse errors:\nCannot instantiate cyclic dependency! CycleDirective \("\[ERROR ->\]<div cycleDirective><\/div>"\): .*TestComp.html@0:0/);
});
fixmeIvy('unknown').it(
'should not instantiate a directive in a view that has a host dependency on providers' +
' of the component',
() => {
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsServiceFromHost]});
TestBed.overrideComponent(
SimpleComponent,
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsServiceFromHost><div>'}});
expect(() => createComponent('<div simpleComponent></div>'))
obsoleteInIvy('This error is no longer generated by the compiler')
.it('should not instantiate a directive with cyclic dependencies', () => {
TestBed.configureTestingModule({declarations: [CycleDirective]});
expect(() => createComponent('<div cycleDirective></div>'))
.toThrowError(
/Template parse errors:\nNo provider for service \("\[ERROR ->\]<div needsServiceFromHost><div>"\): .*SimpleComponent.html@0:0/);
/Template parse errors:\nCannot instantiate cyclic dependency! CycleDirective \("\[ERROR ->\]<div cycleDirective><\/div>"\): .*TestComp.html@0:0/);
});
fixmeIvy('unknown').it(
'should not instantiate a directive in a view that has a host dependency on providers' +
' of a decorator directive',
() => {
TestBed.configureTestingModule(
{declarations: [SimpleComponent, SomeOtherDirective, NeedsServiceFromHost]});
TestBed.overrideComponent(
SimpleComponent,
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsServiceFromHost><div>'}});
expect(() => createComponent('<div simpleComponent someOtherDirective></div>'))
.toThrowError(
/Template parse errors:\nNo provider for service \("\[ERROR ->\]<div needsServiceFromHost><div>"\): .*SimpleComponent.html@0:0/);
onlyInIvy('This error is generated by the runtime of Ivy')
.it('should not instantiate a directive with cyclic dependencies', () => {
TestBed.configureTestingModule({declarations: [CycleDirective]});
expect(() => createComponent('<div cycleDirective></div>'))
.toThrowError('Circular dep for CycleDirective');
});
fixmeIvy('unknown').it(
'should not instantiate a directive in a view that has a self dependency on a parent directive',
() => {
TestBed.configureTestingModule(
{declarations: [SimpleDirective, NeedsDirectiveFromSelf]});
expect(
() => createComponent(
'<div simpleDirective><div needsDirectiveFromSelf></div></div>'))
.toThrowError(
/Template parse errors:\nNo provider for SimpleDirective \("<div simpleDirective>\[ERROR ->\]<div needsDirectiveFromSelf><\/div><\/div>"\): .*TestComp.html@0:21/);
});
obsoleteInIvy('This error is no longer generated by the compiler')
.it('should not instantiate a directive in a view that has a host dependency on providers' +
' of the component',
() => {
TestBed.configureTestingModule(
{declarations: [SimpleComponent, NeedsServiceFromHost]});
TestBed.overrideComponent(
SimpleComponent,
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsServiceFromHost><div>'}});
expect(() => createComponent('<div simpleComponent></div>'))
.toThrowError(
/Template parse errors:\nNo provider for service \("\[ERROR ->\]<div needsServiceFromHost><div>"\): .*SimpleComponent.html@0:0/);
});
onlyInIvy('This error is generated by the runtime of Ivy')
.it('should not instantiate a directive in a view that has a host dependency on providers' +
' of the component',
() => {
TestBed.configureTestingModule(
{declarations: [SimpleComponent, NeedsServiceFromHost]});
TestBed.overrideComponent(
SimpleComponent,
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsServiceFromHost><div>'}});
expect(() => createComponent('<div simpleComponent></div>'))
.toThrowError('NodeInjector: NOT_FOUND [service]');
});
obsoleteInIvy('This error is no longer generated by the compiler')
.it('should not instantiate a directive in a view that has a host dependency on providers' +
' of a decorator directive',
() => {
TestBed.configureTestingModule(
{declarations: [SimpleComponent, SomeOtherDirective, NeedsServiceFromHost]});
TestBed.overrideComponent(
SimpleComponent,
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsServiceFromHost><div>'}});
expect(() => createComponent('<div simpleComponent someOtherDirective></div>'))
.toThrowError(
/Template parse errors:\nNo provider for service \("\[ERROR ->\]<div needsServiceFromHost><div>"\): .*SimpleComponent.html@0:0/);
});
onlyInIvy('This error is generated by the runtime of Ivy')
.it('should not instantiate a directive in a view that has a host dependency on providers' +
' of a decorator directive',
() => {
TestBed.configureTestingModule(
{declarations: [SimpleComponent, SomeOtherDirective, NeedsServiceFromHost]});
TestBed.overrideComponent(
SimpleComponent,
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsServiceFromHost><div>'}});
expect(() => createComponent('<div simpleComponent someOtherDirective></div>'))
.toThrowError('NodeInjector: NOT_FOUND [service]');
});
obsoleteInIvy('This error is no longer generated by the compiler')
.it('should not instantiate a directive in a view that has a self dependency on a parent directive',
() => {
TestBed.configureTestingModule(
{declarations: [SimpleDirective, NeedsDirectiveFromSelf]});
expect(
() => createComponent(
'<div simpleDirective><div needsDirectiveFromSelf></div></div>'))
.toThrowError(
/Template parse errors:\nNo provider for SimpleDirective \("<div simpleDirective>\[ERROR ->\]<div needsDirectiveFromSelf><\/div><\/div>"\): .*TestComp.html@0:21/);
});
onlyInIvy('This error is generated by the runtime of Ivy')
.it('should not instantiate a directive in a view that has a self dependency on a parent directive',
() => {
TestBed.configureTestingModule(
{declarations: [SimpleDirective, NeedsDirectiveFromSelf]});
expect(
() => createComponent(
'<div simpleDirective><div needsDirectiveFromSelf></div></div>'))
.toThrowError('NodeInjector: NOT_FOUND [SimpleDirective]');
});
it('should instantiate directives that depend on other directives', fakeAsync(() => {
TestBed.configureTestingModule({declarations: [SimpleDirective, NeedsDirective]});
@ -691,17 +743,28 @@ class TestComp {
expect(el.componentInstance.service).toEqual('appService');
});
fixmeIvy('unknown').it(
'should not instantiate directives that depend on other directives on the host element',
() => {
TestBed.configureTestingModule(
{declarations: [SimpleComponent, SimpleDirective, NeedsDirectiveFromHost]});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsDirectiveFromHost></div>'}});
expect(() => createComponent('<div simpleComponent simpleDirective></div>'))
.toThrowError(
/Template parse errors:\nNo provider for SimpleDirective \("\[ERROR ->\]<div needsDirectiveFromHost><\/div>"\): .*SimpleComponent.html@0:0/);
});
obsoleteInIvy('This error is no longer generated by the compiler')
.it('should not instantiate directives that depend on other directives on the host element',
() => {
TestBed.configureTestingModule(
{declarations: [SimpleComponent, SimpleDirective, NeedsDirectiveFromHost]});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsDirectiveFromHost></div>'}});
expect(() => createComponent('<div simpleComponent simpleDirective></div>'))
.toThrowError(
/Template parse errors:\nNo provider for SimpleDirective \("\[ERROR ->\]<div needsDirectiveFromHost><\/div>"\): .*SimpleComponent.html@0:0/);
});
onlyInIvy('This error is generated by the runtime of Ivy')
.it('should not instantiate directives that depend on other directives on the host element',
() => {
TestBed.configureTestingModule(
{declarations: [SimpleComponent, SimpleDirective, NeedsDirectiveFromHost]});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsDirectiveFromHost></div>'}});
expect(() => createComponent('<div simpleComponent simpleDirective></div>'))
.toThrowError('NodeInjector: NOT_FOUND [SimpleDirective]');
});
fixmeIvy('unknown').it(
'should allow to use the NgModule injector from a root ViewContainerRef.parentInjector',
@ -884,7 +947,7 @@ class TestComp {
.toEqual(el.childNodes[0].injector.get(NeedsViewContainerRef).viewContainer.element);
});
fixmeIvy('unknown').it('should throw if there is no TemplateRef', () => {
it('should throw if there is no TemplateRef', () => {
TestBed.configureTestingModule({declarations: [NeedsTemplateRef]});
expect(() => createComponent('<div needsTemplateRef></div>'))
.toThrowError(/No provider for TemplateRef!/);

View File

@ -79,6 +79,24 @@ export function obsoleteInIvy(reason: string): JasmineMethods {
return ivyEnabled ? IGNORE : PASSTHROUGH;
}
/**
* A function to conditionally skip the execution of tests that are not relevant when
* not running against Ivy.
*
* ```
* onlyInIvy('some reason').describe(...);
* ```
*
* or
*
* ```
* onlyInIvy('some reason').it(...);
* ```
*/
export function onlyInIvy(reason: string): JasmineMethods {
return ivyEnabled ? PASSTHROUGH : IGNORE;
}
/**
* A function to conditionally skip the execution of tests that have intentionally
* been broken when running against Ivy.