test(ivy): run browser-specific @angular/core tests on CI (#27545)

PR Close #27545
This commit is contained in:
Pawel Kozlowski
2018-12-07 14:05:03 +01:00
committed by Alex Rickabaugh
parent aa48810d80
commit 5657126d86
12 changed files with 2751 additions and 2645 deletions

View File

@ -13,6 +13,7 @@ import {ComponentFixture, TestBed, fakeAsync} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by';
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';
export function createUrlResolverWithoutPackagePrefix(): UrlResolver {
return new UrlResolver();
@ -445,13 +446,14 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
}));
it('should ignore empty bindings', fakeAsync(() => {
const ctx = _bindSimpleProp('[someProp]', TestData);
ctx.componentInstance.a = 'value';
ctx.detectChanges(false);
fixmeIvy('FW-814: Bindings with an empty value should be ignored in the compiler')
.it('should ignore empty bindings', fakeAsync(() => {
const ctx = _bindSimpleProp('[someProp]', TestData);
ctx.componentInstance.a = 'value';
ctx.detectChanges(false);
expect(renderLog.log).toEqual([]);
}));
expect(renderLog.log).toEqual([]);
}));
it('should support interpolation', fakeAsync(() => {
const ctx = _bindSimpleProp('someProp="B{{a}}A"', TestData);
@ -537,27 +539,28 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
expect(renderLog.log).toEqual(['someProp=Megatron']);
}));
it('should record unwrapped values via ngOnChanges', fakeAsync(() => {
const ctx = createCompFixture(
'<div [testDirective]="\'aName\' | wrappedPipe" [a]="1" [b]="2 | wrappedPipe"></div>');
const dir: TestDirective = queryDirs(ctx.debugElement, TestDirective)[0];
ctx.detectChanges(false);
dir.changes = {};
ctx.detectChanges(false);
fixmeIvy('unknown').it(
'should record unwrapped values via ngOnChanges', fakeAsync(() => {
const ctx = createCompFixture(
'<div [testDirective]="\'aName\' | wrappedPipe" [a]="1" [b]="2 | wrappedPipe"></div>');
const dir: TestDirective = queryDirs(ctx.debugElement, TestDirective)[0];
ctx.detectChanges(false);
dir.changes = {};
ctx.detectChanges(false);
// Note: the binding for `b` did not change and has no ValueWrapper,
// and should therefore stay unchanged.
expect(dir.changes).toEqual({
'name': new SimpleChange('aName', 'aName', false),
'b': new SimpleChange(2, 2, false)
});
// Note: the binding for `b` did not change and has no ValueWrapper,
// and should therefore stay unchanged.
expect(dir.changes).toEqual({
'name': new SimpleChange('aName', 'aName', false),
'b': new SimpleChange(2, 2, false)
});
ctx.detectChanges(false);
expect(dir.changes).toEqual({
'name': new SimpleChange('aName', 'aName', false),
'b': new SimpleChange(2, 2, false)
});
}));
ctx.detectChanges(false);
expect(dir.changes).toEqual({
'name': new SimpleChange('aName', 'aName', false),
'b': new SimpleChange(2, 2, false)
});
}));
it('should call pure pipes only if the arguments change', fakeAsync(() => {
const ctx = _bindSimpleValue('name | countingPipe', Person);
@ -588,29 +591,30 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
}));
it('should call pure pipes that are used multiple times only when the arguments change',
fakeAsync(() => {
const ctx = createCompFixture(
`<div [someProp]="name | countingPipe"></div><div [someProp]="age | countingPipe"></div>` +
'<div *ngFor="let x of [1,2]" [someProp]="address.city | countingPipe"></div>',
Person);
ctx.componentInstance.name = 'a';
ctx.componentInstance.age = 10;
ctx.componentInstance.address = new Address('mtv');
ctx.detectChanges(false);
expect(renderLog.loggedValues).toEqual([
'mtv state:0', 'mtv state:1', 'a state:2', '10 state:3'
]);
ctx.detectChanges(false);
expect(renderLog.loggedValues).toEqual([
'mtv state:0', 'mtv state:1', 'a state:2', '10 state:3'
]);
ctx.componentInstance.age = 11;
ctx.detectChanges(false);
expect(renderLog.loggedValues).toEqual([
'mtv state:0', 'mtv state:1', 'a state:2', '10 state:3', '11 state:4'
]);
}));
fixmeIvy('unknown').it(
'should call pure pipes that are used multiple times only when the arguments change',
fakeAsync(() => {
const ctx = createCompFixture(
`<div [someProp]="name | countingPipe"></div><div [someProp]="age | countingPipe"></div>` +
'<div *ngFor="let x of [1,2]" [someProp]="address.city | countingPipe"></div>',
Person);
ctx.componentInstance.name = 'a';
ctx.componentInstance.age = 10;
ctx.componentInstance.address = new Address('mtv');
ctx.detectChanges(false);
expect(renderLog.loggedValues).toEqual([
'mtv state:0', 'mtv state:1', 'a state:2', '10 state:3'
]);
ctx.detectChanges(false);
expect(renderLog.loggedValues).toEqual([
'mtv state:0', 'mtv state:1', 'a state:2', '10 state:3'
]);
ctx.componentInstance.age = 11;
ctx.detectChanges(false);
expect(renderLog.loggedValues).toEqual([
'mtv state:0', 'mtv state:1', 'a state:2', '10 state:3', '11 state:4'
]);
}));
it('should call impure pipes on each change detection run', fakeAsync(() => {
const ctx = _bindSimpleValue('name | countingImpurePipe', Person);
@ -994,31 +998,32 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual([]);
}));
it('should not call ngAfterViewInit again if it throws', fakeAsync(() => {
const ctx =
createCompFixture('<div testDirective="dir" throwOn="ngAfterViewInit"></div>');
fixmeIvy('unknown').it(
'should not call ngAfterViewInit again if it throws', fakeAsync(() => {
const ctx =
createCompFixture('<div testDirective="dir" throwOn="ngAfterViewInit"></div>');
let errored = false;
// First pass fails, but ngAfterViewInit should be called.
try {
ctx.detectChanges(false);
} catch (e) {
errored = true;
}
expect(errored).toBe(true);
let errored = false;
// First pass fails, but ngAfterViewInit should be called.
try {
ctx.detectChanges(false);
} catch (e) {
errored = true;
}
expect(errored).toBe(true);
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual(['dir.ngAfterViewInit']);
directiveLog.clear();
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual(['dir.ngAfterViewInit']);
directiveLog.clear();
// Second change detection also fails, but this time ngAfterViewInit should not be
// called.
try {
ctx.detectChanges(false);
} catch (e) {
throw new Error('Second detectChanges() should not have run detection.');
}
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual([]);
}));
// Second change detection also fails, but this time ngAfterViewInit should not be
// called.
try {
ctx.detectChanges(false);
} catch (e) {
throw new Error('Second detectChanges() should not have run detection.');
}
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual([]);
}));
});
describe('ngAfterViewChecked', () => {
@ -1073,111 +1078,119 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
});
describe('ngOnDestroy', () => {
it('should be called on view destruction', fakeAsync(() => {
const ctx = createCompFixture('<div testDirective="dir"></div>');
ctx.detectChanges(false);
fixmeIvy('unknown').it(
'should be called on view destruction', fakeAsync(() => {
const ctx = createCompFixture('<div testDirective="dir"></div>');
ctx.detectChanges(false);
ctx.destroy();
ctx.destroy();
expect(directiveLog.filter(['ngOnDestroy'])).toEqual(['dir.ngOnDestroy']);
}));
expect(directiveLog.filter(['ngOnDestroy'])).toEqual(['dir.ngOnDestroy']);
}));
it('should be called after processing the content and view children', fakeAsync(() => {
TestBed.overrideComponent(AnotherComponent, {
set: new Component(
{selector: 'other-cmp', template: '<div testDirective="viewChild"></div>'})
});
fixmeIvy('unknown').it(
'should be called after processing the content and view children', fakeAsync(() => {
TestBed.overrideComponent(AnotherComponent, {
set: new Component(
{selector: 'other-cmp', template: '<div testDirective="viewChild"></div>'})
});
const ctx = createCompFixture(
'<div testDirective="parent"><div *ngFor="let x of [0,1]" testDirective="contentChild{{x}}"></div>' +
'<other-cmp></other-cmp></div>',
TestComponent);
const ctx = createCompFixture(
'<div testDirective="parent"><div *ngFor="let x of [0,1]" testDirective="contentChild{{x}}"></div>' +
'<other-cmp></other-cmp></div>',
TestComponent);
ctx.detectChanges(false);
ctx.destroy();
ctx.detectChanges(false);
ctx.destroy();
expect(directiveLog.filter(['ngOnDestroy'])).toEqual([
'contentChild0.ngOnDestroy', 'contentChild1.ngOnDestroy', 'viewChild.ngOnDestroy',
'parent.ngOnDestroy'
]);
}));
expect(directiveLog.filter(['ngOnDestroy'])).toEqual([
'contentChild0.ngOnDestroy', 'contentChild1.ngOnDestroy', 'viewChild.ngOnDestroy',
'parent.ngOnDestroy'
]);
}));
it('should be called in reverse order so the child is always notified before the parent',
fakeAsync(() => {
const ctx = createCompFixture(
'<div testDirective="parent"><div testDirective="child"></div></div><div testDirective="sibling"></div>');
fixmeIvy('unknown').it(
'should be called in reverse order so the child is always notified before the parent',
fakeAsync(() => {
const ctx = createCompFixture(
'<div testDirective="parent"><div testDirective="child"></div></div><div testDirective="sibling"></div>');
ctx.detectChanges(false);
ctx.destroy();
ctx.detectChanges(false);
ctx.destroy();
expect(directiveLog.filter(['ngOnDestroy'])).toEqual([
'child.ngOnDestroy', 'parent.ngOnDestroy', 'sibling.ngOnDestroy'
]);
}));
expect(directiveLog.filter(['ngOnDestroy'])).toEqual([
'child.ngOnDestroy', 'parent.ngOnDestroy', 'sibling.ngOnDestroy'
]);
}));
it('should deliver synchronous events to parent', fakeAsync(() => {
const ctx = createCompFixture('<div (destroy)="a=$event" onDestroyDirective></div>');
fixmeIvy('unknown').it(
'should deliver synchronous events to parent', fakeAsync(() => {
const ctx = createCompFixture('<div (destroy)="a=$event" onDestroyDirective></div>');
ctx.detectChanges(false);
ctx.destroy();
ctx.detectChanges(false);
ctx.destroy();
expect(ctx.componentInstance.a).toEqual('destroyed');
}));
expect(ctx.componentInstance.a).toEqual('destroyed');
}));
it('should call ngOnDestroy on pipes', fakeAsync(() => {
const ctx = createCompFixture('{{true | pipeWithOnDestroy }}');
fixmeIvy('unknown').it('should call ngOnDestroy on pipes', fakeAsync(() => {
const ctx = createCompFixture('{{true | pipeWithOnDestroy }}');
ctx.detectChanges(false);
ctx.destroy();
ctx.detectChanges(false);
ctx.destroy();
expect(directiveLog.filter(['ngOnDestroy'])).toEqual([
'pipeWithOnDestroy.ngOnDestroy'
]);
}));
expect(directiveLog.filter(['ngOnDestroy'])).toEqual([
'pipeWithOnDestroy.ngOnDestroy'
]);
}));
it('should call ngOnDestroy on an injectable class', fakeAsync(() => {
TestBed.overrideDirective(
TestDirective, {set: {providers: [InjectableWithLifecycle]}});
fixmeIvy('unknown').it('should call ngOnDestroy on an injectable class', fakeAsync(() => {
TestBed.overrideDirective(
TestDirective, {set: {providers: [InjectableWithLifecycle]}});
const ctx = createCompFixture('<div testDirective="dir"></div>', TestComponent);
const ctx = createCompFixture(
'<div testDirective="dir"></div>', TestComponent);
ctx.debugElement.children[0].injector.get(InjectableWithLifecycle);
ctx.detectChanges(false);
ctx.debugElement.children[0].injector.get(InjectableWithLifecycle);
ctx.detectChanges(false);
ctx.destroy();
ctx.destroy();
// We don't care about the exact order in this test.
expect(directiveLog.filter(['ngOnDestroy']).sort()).toEqual([
'dir.ngOnDestroy', 'injectable.ngOnDestroy'
]);
}));
// We don't care about the exact order in this test.
expect(directiveLog.filter(['ngOnDestroy']).sort()).toEqual([
'dir.ngOnDestroy', 'injectable.ngOnDestroy'
]);
}));
});
});
describe('enforce no new changes', () => {
it('should throw when a record gets changed after it has been checked', fakeAsync(() => {
@Directive({selector: '[changed]'})
class ChangingDirective {
@Input() changed: any;
}
fixmeIvy('unknown').it(
'should throw when a record gets changed after it has been checked', fakeAsync(() => {
@Directive({selector: '[changed]'})
class ChangingDirective {
@Input() changed: any;
}
TestBed.configureTestingModule({declarations: [ChangingDirective]});
TestBed.configureTestingModule({declarations: [ChangingDirective]});
const ctx = createCompFixture('<div [someProp]="a" [changed]="b"></div>', TestData);
const ctx = createCompFixture('<div [someProp]="a" [changed]="b"></div>', TestData);
ctx.componentInstance.b = 1;
ctx.componentInstance.b = 1;
expect(() => ctx.checkNoChanges())
.toThrowError(/Previous value: 'changed: undefined'\. Current value: 'changed: 1'/g);
}));
expect(() => ctx.checkNoChanges())
.toThrowError(
/Previous value: 'changed: undefined'\. Current value: 'changed: 1'/g);
}));
it('should warn when the view has been created in a cd hook', fakeAsync(() => {
const ctx = createCompFixture('<div *gh9882>{{ a }}</div>', TestData);
ctx.componentInstance.a = 1;
expect(() => ctx.detectChanges())
.toThrowError(
/It seems like the view has been created after its parent and its children have been dirty checked/);
}));
fixmeIvy('unknown').it(
'should warn when the view has been created in a cd hook', fakeAsync(() => {
const ctx = createCompFixture('<div *gh9882>{{ a }}</div>', TestData);
ctx.componentInstance.a = 1;
expect(() => ctx.detectChanges())
.toThrowError(
/It seems like the view has been created after its parent and its children have been dirty checked/);
}));
it('should not throw when two arrays are structurally the same', fakeAsync(() => {
const ctx = _bindSimpleValue('a', TestData);
@ -1187,27 +1200,27 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
expect(() => ctx.checkNoChanges()).not.toThrow();
}));
it('should not break the next run', fakeAsync(() => {
const ctx = _bindSimpleValue('a', TestData);
ctx.componentInstance.a = 'value';
expect(() => ctx.checkNoChanges()).toThrow();
fixmeIvy('unknown').it('should not break the next run', fakeAsync(() => {
const ctx = _bindSimpleValue('a', TestData);
ctx.componentInstance.a = 'value';
expect(() => ctx.checkNoChanges()).toThrow();
ctx.detectChanges();
expect(renderLog.loggedValues).toEqual(['value']);
}));
ctx.detectChanges();
expect(renderLog.loggedValues).toEqual(['value']);
}));
});
describe('mode', () => {
it('Detached', fakeAsync(() => {
const ctx = createCompFixture('<comp-with-ref></comp-with-ref>');
const cmp: CompWithRef = queryDirs(ctx.debugElement, CompWithRef)[0];
cmp.value = 'hello';
cmp.changeDetectorRef.detach();
fixmeIvy('unknown').it('Detached', fakeAsync(() => {
const ctx = createCompFixture('<comp-with-ref></comp-with-ref>');
const cmp: CompWithRef = queryDirs(ctx.debugElement, CompWithRef)[0];
cmp.value = 'hello';
cmp.changeDetectorRef.detach();
ctx.detectChanges();
ctx.detectChanges();
expect(renderLog.log).toEqual([]);
}));
expect(renderLog.log).toEqual([]);
}));
it('Detached should disable OnPush', fakeAsync(() => {
const ctx = createCompFixture('<push-cmp [value]="value"></push-cmp>');
@ -1260,34 +1273,36 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
}));
it('Reattaches in the original cd mode', fakeAsync(() => {
const ctx = createCompFixture('<push-cmp></push-cmp>');
const cmp: PushComp = queryDirs(ctx.debugElement, PushComp)[0];
cmp.changeDetectorRef.detach();
cmp.changeDetectorRef.reattach();
fixmeIvy('unknown').it('Reattaches in the original cd mode', fakeAsync(() => {
const ctx = createCompFixture('<push-cmp></push-cmp>');
const cmp: PushComp = queryDirs(ctx.debugElement, PushComp)[0];
cmp.changeDetectorRef.detach();
cmp.changeDetectorRef.reattach();
// renderCount should NOT be incremented with each CD as CD mode should be resetted to
// on-push
ctx.detectChanges();
expect(cmp.renderCount).toBeGreaterThan(0);
const count = cmp.renderCount;
// renderCount should NOT be incremented with each CD as CD mode
// should be resetted to
// on-push
ctx.detectChanges();
expect(cmp.renderCount).toBeGreaterThan(0);
const count = cmp.renderCount;
ctx.detectChanges();
expect(cmp.renderCount).toBe(count);
}));
ctx.detectChanges();
expect(cmp.renderCount).toBe(count);
}));
});
describe('multi directive order', () => {
it('should follow the DI order for the same element', fakeAsync(() => {
const ctx =
createCompFixture('<div orderCheck2="2" orderCheck0="0" orderCheck1="1"></div>');
fixmeIvy('unknown').it(
'should follow the DI order for the same element', fakeAsync(() => {
const ctx =
createCompFixture('<div orderCheck2="2" orderCheck0="0" orderCheck1="1"></div>');
ctx.detectChanges(false);
ctx.destroy();
ctx.detectChanges(false);
ctx.destroy();
expect(directiveLog.filter(['set'])).toEqual(['0.set', '1.set', '2.set']);
}));
expect(directiveLog.filter(['set'])).toEqual(['0.set', '1.set', '2.set']);
}));
});
describe('nested view recursion', () => {
@ -1424,25 +1439,26 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
expect(log).toEqual(['inner-start', 'main-tpl', 'outer-tpl']);
});
it('should dirty check projected views if the declaration place is dirty checked', () => {
ctx.detectChanges(false);
log = [];
innerComp.cdRef.detach();
mainComp.cdRef.detectChanges();
fixmeIvy('unknown').it(
'should dirty check projected views if the declaration place is dirty checked', () => {
ctx.detectChanges(false);
log = [];
innerComp.cdRef.detach();
mainComp.cdRef.detectChanges();
expect(log).toEqual(['main-start', 'outer-start', 'main-tpl', 'outer-tpl']);
expect(log).toEqual(['main-start', 'outer-start', 'main-tpl', 'outer-tpl']);
log = [];
outerComp.cdRef.detectChanges();
log = [];
outerComp.cdRef.detectChanges();
expect(log).toEqual(['outer-start', 'outer-tpl']);
expect(log).toEqual(['outer-start', 'outer-tpl']);
log = [];
outerComp.cdRef.detach();
mainComp.cdRef.detectChanges();
log = [];
outerComp.cdRef.detach();
mainComp.cdRef.detectChanges();
expect(log).toEqual(['main-start', 'main-tpl']);
});
expect(log).toEqual(['main-start', 'main-tpl']);
});
});
});
@ -1516,7 +1532,7 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
childThrows: LifetimeMethods;
}
describe('calling init', () => {
fixmeIvy('unknown').describe('calling init', () => {
function initialize(options: Options) {
@Component({selector: 'my-child', template: ''})
class MyChild {

View File

@ -700,30 +700,31 @@ function declareTests(config?: {useJit: boolean}) {
});
if (getDOM().supportsDOMEvents()) {
it('should be checked when an async pipe requests a check', fakeAsync(() => {
TestBed.configureTestingModule(
{declarations: [MyComp, PushCmpWithAsyncPipe], imports: [CommonModule]});
const template = '<push-cmp-with-async #cmp></push-cmp-with-async>';
TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp);
fixmeIvy('unknown').it(
'should be checked when an async pipe requests a check', fakeAsync(() => {
TestBed.configureTestingModule(
{declarations: [MyComp, PushCmpWithAsyncPipe], imports: [CommonModule]});
const template = '<push-cmp-with-async #cmp></push-cmp-with-async>';
TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp);
tick();
tick();
const cmp: PushCmpWithAsyncPipe =
fixture.debugElement.children[0].references !['cmp'];
fixture.detectChanges();
expect(cmp.numberOfChecks).toEqual(1);
const cmp: PushCmpWithAsyncPipe =
fixture.debugElement.children[0].references !['cmp'];
fixture.detectChanges();
expect(cmp.numberOfChecks).toEqual(1);
fixture.detectChanges();
fixture.detectChanges();
expect(cmp.numberOfChecks).toEqual(1);
fixture.detectChanges();
fixture.detectChanges();
expect(cmp.numberOfChecks).toEqual(1);
cmp.resolve(2);
tick();
cmp.resolve(2);
tick();
fixture.detectChanges();
expect(cmp.numberOfChecks).toEqual(2);
}));
fixture.detectChanges();
expect(cmp.numberOfChecks).toEqual(2);
}));
}
});
@ -1872,7 +1873,7 @@ function declareTests(config?: {useJit: boolean}) {
if (getDOM().supportsDOMEvents()) {
describe('svg', () => {
it('should support svg elements', () => {
fixmeIvy('unknown').it('should support svg elements', () => {
TestBed.configureTestingModule({declarations: [MyComp]});
const template = '<svg><use xlink:href="Port" /></svg>';
TestBed.overrideComponent(MyComp, {set: {template}});
@ -1891,7 +1892,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(firstAttribute.namespaceURI).toEqual('http://www.w3.org/1999/xlink');
});
it('should support foreignObjects with document fragments', () => {
fixmeIvy('unknown').it('should support foreignObjects with document fragments', () => {
TestBed.configureTestingModule({declarations: [MyComp]});
const template =
'<svg><foreignObject><xhtml:div><p>Test</p></xhtml:div></foreignObject></svg>';
@ -1913,7 +1914,7 @@ function declareTests(config?: {useJit: boolean}) {
describe('attributes', () => {
it('should support attributes with namespace', () => {
fixmeIvy('unknown').it('should support attributes with namespace', () => {
TestBed.configureTestingModule({declarations: [MyComp, SomeCmp]});
const template = '<svg:use xlink:href="#id" />';
TestBed.overrideComponent(SomeCmp, {set: {template}});
@ -1924,7 +1925,7 @@ function declareTests(config?: {useJit: boolean}) {
.toEqual('#id');
});
it('should support binding to attributes with namespace', () => {
fixmeIvy('unknown').it('should support binding to attributes with namespace', () => {
TestBed.configureTestingModule({declarations: [MyComp, SomeCmp]});
const template = '<svg:use [attr.xlink:href]="value" />';
TestBed.overrideComponent(SomeCmp, {set: {template}});

View File

@ -370,21 +370,22 @@ describe('projection', () => {
});
if (getDOM().supportsNativeShadowDOM()) {
it('should support native content projection and isolate styles per component', () => {
TestBed.configureTestingModule({declarations: [SimpleNative1, SimpleNative2]});
TestBed.overrideComponent(MainComp, {
set: {
template: '<simple-native1><div>A</div></simple-native1>' +
'<simple-native2><div>B</div></simple-native2>'
}
});
const main = TestBed.createComponent(MainComp);
fixmeIvy('unknown').it(
'should support native content projection and isolate styles per component', () => {
TestBed.configureTestingModule({declarations: [SimpleNative1, SimpleNative2]});
TestBed.overrideComponent(MainComp, {
set: {
template: '<simple-native1><div>A</div></simple-native1>' +
'<simple-native2><div>B</div></simple-native2>'
}
});
const main = TestBed.createComponent(MainComp);
const childNodes = getDOM().childNodes(main.nativeElement);
expect(childNodes[0]).toHaveText('div {color: red}SIMPLE1(A)');
expect(childNodes[1]).toHaveText('div {color: blue}SIMPLE2(B)');
main.destroy();
});
const childNodes = getDOM().childNodes(main.nativeElement);
expect(childNodes[0]).toHaveText('div {color: red}SIMPLE1(A)');
expect(childNodes[1]).toHaveText('div {color: blue}SIMPLE2(B)');
main.destroy();
});
}
if (getDOM().supportsDOMEvents()) {

View File

@ -428,7 +428,7 @@ function declareTestsUsingBootstrap() {
if (getDOM().supportsDOMEvents()) {
// This test needs a real DOM....
it('should keep change detecting if there was an error', (done) => {
fixmeIvy('unknown').it('should keep change detecting if there was an error', (done) => {
@Component({
selector: COMP_SELECTOR,
template:

View File

@ -10,6 +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';
@Directive({selector: '[simpleDirective]'})
class SimpleDirective {
@ -291,7 +292,7 @@ class TestComp {
expect(el.children[0].injector.get('injectable2')).toEqual('injectable1-injectable2');
});
it('should instantiate viewProviders that have dependencies', () => {
fixmeIvy('unknown').it('should instantiate viewProviders that have dependencies', () => {
TestBed.configureTestingModule({declarations: [SimpleComponent]});
const viewProviders = [
{provide: 'injectable1', useValue: 'injectable1'}, {
@ -428,7 +429,7 @@ class TestComp {
expect(ctx.debugElement.injector.get('eager2')).toBe('v2: v1');
});
it('should inject providers that were declared after it', () => {
fixmeIvy('unknown').it('should inject providers that were declared after it', () => {
@Component({
template: '',
providers: [
@ -464,7 +465,7 @@ class TestComp {
expect(comp.componentInstance.a).toBe('aValue');
});
it('should support ngOnDestroy for lazy providers', () => {
fixmeIvy('unknown').it('should support ngOnDestroy for lazy providers', () => {
let created = false;
let destroyed = false;
@ -496,7 +497,7 @@ class TestComp {
expect(destroyed).toBe(true);
});
it('should instantiate view providers lazily', () => {
fixmeIvy('unknown').it('should instantiate view providers lazily', () => {
let created = false;
TestBed.configureTestingModule({declarations: [SimpleComponent]});
TestBed.overrideComponent(
@ -551,38 +552,45 @@ class TestComp {
.toEqual('parentService');
});
it('should instantiate directives that depend on providers of a component', () => {
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsService]});
TestBed.overrideComponent(
SimpleComponent, {set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
TestBed.overrideComponent(SimpleComponent, {set: {template: '<div needsService></div>'}});
const el = createComponent('<div simpleComponent></div>');
expect(el.children[0].children[0].injector.get(NeedsService).service)
.toEqual('hostService');
});
fixmeIvy('unknown').it(
'should instantiate directives that depend on providers of a component', () => {
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsService]});
TestBed.overrideComponent(
SimpleComponent,
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsService></div>'}});
const el = createComponent('<div simpleComponent></div>');
expect(el.children[0].children[0].injector.get(NeedsService).service)
.toEqual('hostService');
});
it('should instantiate directives that depend on view providers of a component', () => {
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsService]});
TestBed.overrideComponent(
SimpleComponent, {set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
TestBed.overrideComponent(SimpleComponent, {set: {template: '<div needsService></div>'}});
const el = createComponent('<div simpleComponent></div>');
expect(el.children[0].children[0].injector.get(NeedsService).service)
.toEqual('hostService');
});
fixmeIvy('unknown').it(
'should instantiate directives that depend on view providers of a component', () => {
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsService]});
TestBed.overrideComponent(
SimpleComponent,
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsService></div>'}});
const el = createComponent('<div simpleComponent></div>');
expect(el.children[0].children[0].injector.get(NeedsService).service)
.toEqual('hostService');
});
it('should instantiate directives in a root embedded view that depend on view providers of a component',
() => {
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsService]});
TestBed.overrideComponent(
SimpleComponent,
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div *ngIf="true" needsService></div>'}});
const el = createComponent('<div simpleComponent></div>');
expect(el.children[0].children[0].injector.get(NeedsService).service)
.toEqual('hostService');
});
fixmeIvy('unknown').it(
'should instantiate directives in a root embedded view that depend on view providers of a component',
() => {
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsService]});
TestBed.overrideComponent(
SimpleComponent,
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div *ngIf="true" needsService></div>'}});
const el = createComponent('<div simpleComponent></div>');
expect(el.children[0].children[0].injector.get(NeedsService).service)
.toEqual('hostService');
});
it('should instantiate directives that depend on instances in the app injector', () => {
TestBed.configureTestingModule({declarations: [NeedsAppService]});
@ -590,54 +598,57 @@ class TestComp {
expect(el.children[0].injector.get(NeedsAppService).service).toEqual('appService');
});
it('should not instantiate a directive with cyclic dependencies', () => {
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/);
});
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>'}});
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(
/Template parse errors:\nNo provider for service \("\[ERROR ->\]<div needsServiceFromHost><div>"\): .*SimpleComponent.html@0:0/);
});
expect(() => createComponent('<div simpleComponent></div>'))
.toThrowError(
/Template parse errors:\nNo provider for service \("\[ERROR ->\]<div needsServiceFromHost><div>"\): .*SimpleComponent.html@0:0/);
});
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>'}});
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/);
});
expect(() => createComponent('<div simpleComponent someOtherDirective></div>'))
.toThrowError(
/Template parse errors:\nNo provider for service \("\[ERROR ->\]<div needsServiceFromHost><div>"\): .*SimpleComponent.html@0:0/);
});
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/);
});
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/);
});
it('should instantiate directives that depend on other directives', fakeAsync(() => {
TestBed.configureTestingModule({declarations: [SimpleDirective, NeedsDirective]});
@ -662,48 +673,54 @@ class TestComp {
expect(d.dependency).toBeNull();
});
it('should instantiate directives that depends on the host component', () => {
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsComponentFromHost]});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsComponentFromHost></div>'}});
const el = createComponent('<div simpleComponent></div>');
const d = el.children[0].children[0].injector.get(NeedsComponentFromHost);
expect(d.dependency).toBeAnInstanceOf(SimpleComponent);
});
fixmeIvy('unknown').it(
'should instantiate directives that depends on the host component', () => {
TestBed.configureTestingModule(
{declarations: [SimpleComponent, NeedsComponentFromHost]});
TestBed.overrideComponent(
SimpleComponent, {set: {template: '<div needsComponentFromHost></div>'}});
const el = createComponent('<div simpleComponent></div>');
const d = el.children[0].children[0].injector.get(NeedsComponentFromHost);
expect(d.dependency).toBeAnInstanceOf(SimpleComponent);
});
it('should instantiate host views for components that have a @Host dependency ', () => {
TestBed.configureTestingModule({declarations: [NeedsHostAppService]});
const el = createComponent('', [], NeedsHostAppService);
expect(el.componentInstance.service).toEqual('appService');
});
fixmeIvy('unknown').it(
'should instantiate host views for components that have a @Host dependency ', () => {
TestBed.configureTestingModule({declarations: [NeedsHostAppService]});
const el = createComponent('', [], NeedsHostAppService);
expect(el.componentInstance.service).toEqual('appService');
});
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/);
});
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/);
});
it('should allow to use the NgModule injector from a root ViewContainerRef.parentInjector',
() => {
@Component({template: ''})
class MyComp {
constructor(public vc: ViewContainerRef) {}
}
fixmeIvy('unknown').it(
'should allow to use the NgModule injector from a root ViewContainerRef.parentInjector',
() => {
@Component({template: ''})
class MyComp {
constructor(public vc: ViewContainerRef) {}
}
const compFixture = TestBed
.configureTestingModule({
declarations: [MyComp],
providers: [{provide: 'someToken', useValue: 'someValue'}]
})
.createComponent(MyComp);
const compFixture = TestBed
.configureTestingModule({
declarations: [MyComp],
providers: [{provide: 'someToken', useValue: 'someValue'}]
})
.createComponent(MyComp);
expect(compFixture.componentInstance.vc.parentInjector.get('someToken'))
.toBe('someValue');
});
expect(compFixture.componentInstance.vc.parentInjector.get('someToken'))
.toBe('someValue');
});
});
describe('static attributes', () => {
@ -734,85 +751,97 @@ class TestComp {
.toBe(el.children[0].nativeElement);
});
it('should inject ChangeDetectorRef of the component\'s view into the component', () => {
TestBed.configureTestingModule({declarations: [PushComponentNeedsChangeDetectorRef]});
const cf = createComponentFixture('<div componentNeedsChangeDetectorRef></div>');
cf.detectChanges();
const compEl = cf.debugElement.children[0];
const comp = compEl.injector.get(PushComponentNeedsChangeDetectorRef);
comp.counter = 1;
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('0');
comp.changeDetectorRef.markForCheck();
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('1');
});
fixmeIvy('unknown').it(
'should inject ChangeDetectorRef of the component\'s view into the component', () => {
TestBed.configureTestingModule({declarations: [PushComponentNeedsChangeDetectorRef]});
const cf = createComponentFixture('<div componentNeedsChangeDetectorRef></div>');
cf.detectChanges();
const compEl = cf.debugElement.children[0];
const comp = compEl.injector.get(PushComponentNeedsChangeDetectorRef);
comp.counter = 1;
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('0');
comp.changeDetectorRef.markForCheck();
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('1');
});
it('should inject ChangeDetectorRef of the containing component into directives', () => {
TestBed.configureTestingModule(
{declarations: [PushComponentNeedsChangeDetectorRef, DirectiveNeedsChangeDetectorRef]});
TestBed.overrideComponent(PushComponentNeedsChangeDetectorRef, {
set: {
template:
'{{counter}}<div directiveNeedsChangeDetectorRef></div><div *ngIf="true" directiveNeedsChangeDetectorRef></div>'
}
});
const cf = createComponentFixture('<div componentNeedsChangeDetectorRef></div>');
cf.detectChanges();
const compEl = cf.debugElement.children[0];
const comp: PushComponentNeedsChangeDetectorRef =
compEl.injector.get(PushComponentNeedsChangeDetectorRef);
comp.counter = 1;
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('0');
expect(compEl.children[0].injector.get(DirectiveNeedsChangeDetectorRef).changeDetectorRef)
.toEqual(comp.changeDetectorRef);
expect(compEl.children[1].injector.get(DirectiveNeedsChangeDetectorRef).changeDetectorRef)
.toEqual(comp.changeDetectorRef);
comp.changeDetectorRef.markForCheck();
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('1');
});
fixmeIvy('unknown').it(
'should inject ChangeDetectorRef of the containing component into directives', () => {
TestBed.configureTestingModule({
declarations:
[PushComponentNeedsChangeDetectorRef, DirectiveNeedsChangeDetectorRef]
});
TestBed.overrideComponent(PushComponentNeedsChangeDetectorRef, {
set: {
template:
'{{counter}}<div directiveNeedsChangeDetectorRef></div><div *ngIf="true" directiveNeedsChangeDetectorRef></div>'
}
});
const cf = createComponentFixture('<div componentNeedsChangeDetectorRef></div>');
cf.detectChanges();
const compEl = cf.debugElement.children[0];
const comp: PushComponentNeedsChangeDetectorRef =
compEl.injector.get(PushComponentNeedsChangeDetectorRef);
comp.counter = 1;
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('0');
expect(
compEl.children[0].injector.get(DirectiveNeedsChangeDetectorRef).changeDetectorRef)
.toEqual(comp.changeDetectorRef);
expect(
compEl.children[1].injector.get(DirectiveNeedsChangeDetectorRef).changeDetectorRef)
.toEqual(comp.changeDetectorRef);
comp.changeDetectorRef.markForCheck();
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('1');
});
it('should inject ChangeDetectorRef of a same element component into a directive', () => {
TestBed.configureTestingModule(
{declarations: [PushComponentNeedsChangeDetectorRef, DirectiveNeedsChangeDetectorRef]});
const cf = createComponentFixture(
'<div componentNeedsChangeDetectorRef directiveNeedsChangeDetectorRef></div>');
cf.detectChanges();
const compEl = cf.debugElement.children[0];
const comp = compEl.injector.get(PushComponentNeedsChangeDetectorRef);
const dir = compEl.injector.get(DirectiveNeedsChangeDetectorRef);
comp.counter = 1;
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('0');
dir.changeDetectorRef.markForCheck();
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('1');
});
fixmeIvy('unknown').it(
'should inject ChangeDetectorRef of a same element component into a directive', () => {
TestBed.configureTestingModule({
declarations:
[PushComponentNeedsChangeDetectorRef, DirectiveNeedsChangeDetectorRef]
});
const cf = createComponentFixture(
'<div componentNeedsChangeDetectorRef directiveNeedsChangeDetectorRef></div>');
cf.detectChanges();
const compEl = cf.debugElement.children[0];
const comp = compEl.injector.get(PushComponentNeedsChangeDetectorRef);
const dir = compEl.injector.get(DirectiveNeedsChangeDetectorRef);
comp.counter = 1;
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('0');
dir.changeDetectorRef.markForCheck();
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('1');
});
it(`should not inject ChangeDetectorRef of a parent element's component into a directive`, () => {
TestBed
.configureTestingModule({
declarations: [PushComponentNeedsChangeDetectorRef, DirectiveNeedsChangeDetectorRef]
})
.overrideComponent(
PushComponentNeedsChangeDetectorRef,
{set: {template: '<ng-content></ng-content>{{counter}}'}});
const cf = createComponentFixture(
'<div componentNeedsChangeDetectorRef><div directiveNeedsChangeDetectorRef></div></div>');
cf.detectChanges();
const compEl = cf.debugElement.children[0];
const comp = compEl.injector.get(PushComponentNeedsChangeDetectorRef);
const dirEl = compEl.children[0];
const dir = dirEl.injector.get(DirectiveNeedsChangeDetectorRef);
comp.counter = 1;
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('0');
dir.changeDetectorRef.markForCheck();
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('0');
});
fixmeIvy('unknown').it(
`should not inject ChangeDetectorRef of a parent element's component into a directive`,
() => {
TestBed
.configureTestingModule({
declarations:
[PushComponentNeedsChangeDetectorRef, DirectiveNeedsChangeDetectorRef]
})
.overrideComponent(
PushComponentNeedsChangeDetectorRef,
{set: {template: '<ng-content></ng-content>{{counter}}'}});
const cf = createComponentFixture(
'<div componentNeedsChangeDetectorRef><div directiveNeedsChangeDetectorRef></div></div>');
cf.detectChanges();
const compEl = cf.debugElement.children[0];
const comp = compEl.injector.get(PushComponentNeedsChangeDetectorRef);
const dirEl = compEl.children[0];
const dir = dirEl.injector.get(DirectiveNeedsChangeDetectorRef);
comp.counter = 1;
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('0');
dir.changeDetectorRef.markForCheck();
cf.detectChanges();
expect(compEl.nativeElement).toHaveText('0');
});
it('should inject ViewContainerRef', () => {
TestBed.configureTestingModule({declarations: [NeedsViewContainerRef]});
@ -822,7 +851,7 @@ class TestComp {
.toBe(el.children[0].nativeElement);
});
it('should inject ViewContainerRef', () => {
fixmeIvy('unknown').it('should inject ViewContainerRef', () => {
@Component({template: ''})
class TestComp {
constructor(public vcr: ViewContainerRef) {}
@ -847,7 +876,7 @@ class TestComp {
expect(component.instance.vcr.parentInjector.get('someToken')).toBe('someNewValue');
});
it('should inject TemplateRef', () => {
fixmeIvy('unknown').it('should inject TemplateRef', () => {
TestBed.configureTestingModule({declarations: [NeedsViewContainerRef, NeedsTemplateRef]});
const el =
createComponent('<ng-template needsViewContainerRef needsTemplateRef></ng-template>');
@ -855,7 +884,7 @@ class TestComp {
.toEqual(el.childNodes[0].injector.get(NeedsViewContainerRef).viewContainer.element);
});
it('should throw if there is no TemplateRef', () => {
fixmeIvy('unknown').it('should throw if there is no TemplateRef', () => {
TestBed.configureTestingModule({declarations: [NeedsTemplateRef]});
expect(() => createComponent('<div needsTemplateRef></div>'))
.toThrowError(/No provider for TemplateRef!/);
@ -870,7 +899,7 @@ class TestComp {
});
describe('pipes', () => {
it('should instantiate pipes that have dependencies', () => {
fixmeIvy('unknown').it('should instantiate pipes that have dependencies', () => {
TestBed.configureTestingModule({declarations: [SimpleDirective, PipeNeedsService]});
const el = createComponent(
@ -879,7 +908,7 @@ class TestComp {
expect(el.children[0].injector.get(SimpleDirective).value.service).toEqual('pipeService');
});
it('should overwrite pipes with later entry in the pipes array', () => {
fixmeIvy('unknown').it('should overwrite pipes with later entry in the pipes array', () => {
TestBed.configureTestingModule(
{declarations: [SimpleDirective, DuplicatePipe1, DuplicatePipe2]});
const el = createComponent('<div [simpleDirective]="true | duplicatePipe"></div>');
@ -898,7 +927,7 @@ class TestComp {
expect(el.children[0].injector.get(SimpleDirective).value.changeDetectorRef).toEqual(cdRef);
});
it('should cache pure pipes', () => {
fixmeIvy('unknown').it('should cache pure pipes', () => {
TestBed.configureTestingModule({declarations: [SimpleDirective, PurePipe]});
const el = createComponent(
'<div [simpleDirective]="true | purePipe"></div><div [simpleDirective]="true | purePipe"></div>' +