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,18 +598,27 @@ class TestComp {
expect(el.children[0].injector.get(NeedsAppService).service).toEqual('appService');
});
fixmeIvy('unknown').it('should not instantiate a directive with cyclic dependencies', () => {
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:\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' +
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');
});
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.configureTestingModule(
{declarations: [SimpleComponent, NeedsServiceFromHost]});
TestBed.overrideComponent(
SimpleComponent,
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
@ -621,8 +630,24 @@ class TestComp {
/Template parse errors:\nNo provider for service \("\[ERROR ->\]<div needsServiceFromHost><div>"\): .*SimpleComponent.html@0:0/);
});
fixmeIvy('unknown').it(
'should not instantiate a directive in a view that has a host dependency on providers' +
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(
@ -638,8 +663,24 @@ class TestComp {
/Template parse errors:\nNo provider for service \("\[ERROR ->\]<div needsServiceFromHost><div>"\): .*SimpleComponent.html@0:0/);
});
fixmeIvy('unknown').it(
'should not instantiate a directive in a view that has a self dependency on a parent directive',
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]});
@ -650,6 +691,17 @@ class TestComp {
/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]});
const el = createComponent('<div simpleDirective><div needsDirective></div></div>');
@ -691,8 +743,8 @@ class TestComp {
expect(el.componentInstance.service).toEqual('appService');
});
fixmeIvy('unknown').it(
'should not instantiate directives that depend on other directives on the host element',
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]});
@ -703,6 +755,17 @@ class TestComp {
/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.