parent
a433baf99a
commit
8042140742
|
@ -308,7 +308,7 @@ export function getOrCreateInjectable<T>(
|
||||||
try {
|
try {
|
||||||
const value = bloomHash();
|
const value = bloomHash();
|
||||||
if (value == null && !(flags & InjectFlags.Optional)) {
|
if (value == null && !(flags & InjectFlags.Optional)) {
|
||||||
throw new Error(`No provider for ${stringify(token)}`);
|
throw new Error(`No provider for ${stringify(token)}!`);
|
||||||
} else {
|
} else {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ export function stringify(value: any): string {
|
||||||
if (typeof value == 'function') return value.name || value;
|
if (typeof value == 'function') return value.name || value;
|
||||||
if (typeof value == 'string') return value;
|
if (typeof value == 'string') return value;
|
||||||
if (value == null) return '';
|
if (value == null) return '';
|
||||||
|
if (typeof value == 'object' && typeof value.type == 'function')
|
||||||
|
return value.type.name || value.type;
|
||||||
return '' + value;
|
return '' + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, Compon
|
||||||
import {ComponentFixture, TestBed, fakeAsync} from '@angular/core/testing';
|
import {ComponentFixture, TestBed, fakeAsync} from '@angular/core/testing';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
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]'})
|
@Directive({selector: '[simpleDirective]'})
|
||||||
class SimpleDirective {
|
class SimpleDirective {
|
||||||
|
@ -598,57 +598,109 @@ class TestComp {
|
||||||
expect(el.children[0].injector.get(NeedsAppService).service).toEqual('appService');
|
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')
|
||||||
TestBed.configureTestingModule({declarations: [CycleDirective]});
|
.it('should not instantiate a directive with cyclic dependencies', () => {
|
||||||
expect(() => createComponent('<div cycleDirective></div>'))
|
TestBed.configureTestingModule({declarations: [CycleDirective]});
|
||||||
.toThrowError(
|
expect(() => createComponent('<div cycleDirective></div>'))
|
||||||
/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>'))
|
|
||||||
.toThrowError(
|
.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(
|
onlyInIvy('This error is generated by the runtime of Ivy')
|
||||||
'should not instantiate a directive in a view that has a host dependency on providers' +
|
.it('should not instantiate a directive with cyclic dependencies', () => {
|
||||||
' of a decorator directive',
|
TestBed.configureTestingModule({declarations: [CycleDirective]});
|
||||||
() => {
|
expect(() => createComponent('<div cycleDirective></div>'))
|
||||||
TestBed.configureTestingModule(
|
.toThrowError('Circular dep for CycleDirective');
|
||||||
{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/);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy('unknown').it(
|
obsoleteInIvy('This error is no longer generated by the compiler')
|
||||||
'should not instantiate a directive in a view that has a self dependency on a parent directive',
|
.it('should not instantiate a directive in a view that has a host dependency on providers' +
|
||||||
() => {
|
' of the component',
|
||||||
TestBed.configureTestingModule(
|
() => {
|
||||||
{declarations: [SimpleDirective, NeedsDirectiveFromSelf]});
|
TestBed.configureTestingModule(
|
||||||
expect(
|
{declarations: [SimpleComponent, NeedsServiceFromHost]});
|
||||||
() => createComponent(
|
TestBed.overrideComponent(
|
||||||
'<div simpleDirective><div needsDirectiveFromSelf></div></div>'))
|
SimpleComponent,
|
||||||
.toThrowError(
|
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
|
||||||
/Template parse errors:\nNo provider for SimpleDirective \("<div simpleDirective>\[ERROR ->\]<div needsDirectiveFromSelf><\/div><\/div>"\): .*TestComp.html@0:21/);
|
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(() => {
|
it('should instantiate directives that depend on other directives', fakeAsync(() => {
|
||||||
TestBed.configureTestingModule({declarations: [SimpleDirective, NeedsDirective]});
|
TestBed.configureTestingModule({declarations: [SimpleDirective, NeedsDirective]});
|
||||||
|
@ -691,17 +743,28 @@ class TestComp {
|
||||||
expect(el.componentInstance.service).toEqual('appService');
|
expect(el.componentInstance.service).toEqual('appService');
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy('unknown').it(
|
obsoleteInIvy('This error is no longer generated by the compiler')
|
||||||
'should not instantiate directives that depend on other directives on the host element',
|
.it('should not instantiate directives that depend on other directives on the host element',
|
||||||
() => {
|
() => {
|
||||||
TestBed.configureTestingModule(
|
TestBed.configureTestingModule(
|
||||||
{declarations: [SimpleComponent, SimpleDirective, NeedsDirectiveFromHost]});
|
{declarations: [SimpleComponent, SimpleDirective, NeedsDirectiveFromHost]});
|
||||||
TestBed.overrideComponent(
|
TestBed.overrideComponent(
|
||||||
SimpleComponent, {set: {template: '<div needsDirectiveFromHost></div>'}});
|
SimpleComponent, {set: {template: '<div needsDirectiveFromHost></div>'}});
|
||||||
expect(() => createComponent('<div simpleComponent simpleDirective></div>'))
|
expect(() => createComponent('<div simpleComponent simpleDirective></div>'))
|
||||||
.toThrowError(
|
.toThrowError(
|
||||||
/Template parse errors:\nNo provider for SimpleDirective \("\[ERROR ->\]<div needsDirectiveFromHost><\/div>"\): .*SimpleComponent.html@0:0/);
|
/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(
|
fixmeIvy('unknown').it(
|
||||||
'should allow to use the NgModule injector from a root ViewContainerRef.parentInjector',
|
'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);
|
.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]});
|
TestBed.configureTestingModule({declarations: [NeedsTemplateRef]});
|
||||||
expect(() => createComponent('<div needsTemplateRef></div>'))
|
expect(() => createComponent('<div needsTemplateRef></div>'))
|
||||||
.toThrowError(/No provider for TemplateRef!/);
|
.toThrowError(/No provider for TemplateRef!/);
|
||||||
|
|
|
@ -79,6 +79,24 @@ export function obsoleteInIvy(reason: string): JasmineMethods {
|
||||||
return ivyEnabled ? IGNORE : PASSTHROUGH;
|
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
|
* A function to conditionally skip the execution of tests that have intentionally
|
||||||
* been broken when running against Ivy.
|
* been broken when running against Ivy.
|
||||||
|
|
Loading…
Reference in New Issue