test(core): add JIRA references for root-casuse ivy TestBed failures (#27196)

PR Close #27196
This commit is contained in:
Pawel Kozlowski 2018-11-20 17:00:41 +01:00 committed by Miško Hevery
parent a72250bace
commit d666370e16
9 changed files with 2416 additions and 2214 deletions

View File

@ -15,10 +15,10 @@ import {fixmeIvy} from '@angular/private/testing';
{ {
if (ivyEnabled) { if (ivyEnabled) {
fixmeIvy('unknown') && describe('ivy', () => { declareTests(); }); describe('ivy', () => { declareTests(); });
} else { } else {
fixmeIvy('unknown') && describe('jit', () => { declareTests({useJit: true}); }); describe('jit', () => { declareTests({useJit: true}); });
fixmeIvy('unknown') && describe('no jit', () => { declareTests({useJit: false}); }); describe('no jit', () => { declareTests({useJit: false}); });
} }
} }
@ -71,18 +71,21 @@ function declareTests(config?: {useJit: boolean}) {
expect(childComp.cfr.resolveComponentFactory(ChildComp) !.componentType).toBe(ChildComp); expect(childComp.cfr.resolveComponentFactory(ChildComp) !.componentType).toBe(ChildComp);
}); });
it('should not be able to get components from a parent component (content hierarchy)', () => { fixmeIvy('unknown') &&
TestBed.overrideComponent(MainComp, {set: {template: '<child><nested></nested></child>'}}); it('should not be able to get components from a parent component (content hierarchy)',
TestBed.overrideComponent(ChildComp, {set: {template: '<ng-content></ng-content>'}}); () => {
TestBed.overrideComponent(
MainComp, {set: {template: '<child><nested></nested></child>'}});
TestBed.overrideComponent(ChildComp, {set: {template: '<ng-content></ng-content>'}});
const compFixture = TestBed.createComponent(MainComp); const compFixture = TestBed.createComponent(MainComp);
const nestedChildCompEl = compFixture.debugElement.children[0].children[0]; const nestedChildCompEl = compFixture.debugElement.children[0].children[0];
const nestedChildComp: NestedChildComp = nestedChildCompEl.componentInstance; const nestedChildComp: NestedChildComp = nestedChildCompEl.componentInstance;
expect(nestedChildComp.cfr.resolveComponentFactory(ChildComp) !.componentType) expect(nestedChildComp.cfr.resolveComponentFactory(ChildComp) !.componentType)
.toBe(ChildComp); .toBe(ChildComp);
expect(() => nestedChildComp.cfr.resolveComponentFactory(NestedChildComp)) expect(() => nestedChildComp.cfr.resolveComponentFactory(NestedChildComp))
.toThrow(noComponentFactoryError(NestedChildComp)); .toThrow(noComponentFactoryError(NestedChildComp));
}); });
}); });
} }

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,8 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
import {fixmeIvy} from '@angular/private/testing'; import {fixmeIvy} from '@angular/private/testing';
{ {
fixmeIvy('unknown') && describe('Jit Summaries', () => { // ivy fix in https://github.com/angular/angular/pull/26871
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && describe('Jit Summaries', () => {
let instances: Map<any, Base>; let instances: Map<any, Base>;
let summaries: () => any[]; let summaries: () => any[];

View File

@ -15,10 +15,10 @@ import {fixmeIvy} from '@angular/private/testing';
{ {
if (ivyEnabled) { if (ivyEnabled) {
fixmeIvy('unknown') && describe('ivy', () => { declareTests(); }); describe('ivy', () => { declareTests(); });
} else { } else {
fixmeIvy('unknown') && describe('jit', () => { declareTests({useJit: true}); }); describe('jit', () => { declareTests({useJit: true}); });
fixmeIvy('unknown') && describe('no jit', () => { declareTests({useJit: false}); }); describe('no jit', () => { declareTests({useJit: false}); });
} }
} }
@ -38,74 +38,78 @@ function declareTests(config?: {useJit: boolean}) {
}); });
}); });
it('should support the "i18n" attribute', () => { fixmeIvy('FW-663: ReferenceError: goog is not defined') &&
const template = '<ng-container i18n>foo</ng-container>'; it('should support the "i18n" attribute', () => {
TestBed.overrideComponent(MyComp, {set: {template}}); const template = '<ng-container i18n>foo</ng-container>';
const fixture = TestBed.createComponent(MyComp); TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges(); fixture.detectChanges();
const el = fixture.nativeElement; const el = fixture.nativeElement;
expect(el).toHaveText('foo'); expect(el).toHaveText('foo');
}); });
it('should be rendered as comment with children as siblings', () => { fixmeIvy('FW-678: ivy generates different DOM structure for <ng-container>') &&
const template = '<ng-container><p></p></ng-container>'; it('should be rendered as comment with children as siblings', () => {
TestBed.overrideComponent(MyComp, {set: {template}}); const template = '<ng-container><p></p></ng-container>';
const fixture = TestBed.createComponent(MyComp); TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges(); fixture.detectChanges();
const el = fixture.nativeElement; const el = fixture.nativeElement;
const children = getDOM().childNodes(el); const children = getDOM().childNodes(el);
expect(children.length).toBe(2); expect(children.length).toBe(2);
expect(getDOM().isCommentNode(children[0])).toBe(true); expect(getDOM().isCommentNode(children[0])).toBe(true);
expect(getDOM().tagName(children[1]).toUpperCase()).toEqual('P'); expect(getDOM().tagName(children[1]).toUpperCase()).toEqual('P');
}); });
it('should support nesting', () => { fixmeIvy('FW-678: ivy generates different DOM structure for <ng-container>') &&
const template = it('should support nesting', () => {
'<ng-container>1</ng-container><ng-container><ng-container>2</ng-container></ng-container>'; const template =
TestBed.overrideComponent(MyComp, {set: {template}}); '<ng-container>1</ng-container><ng-container><ng-container>2</ng-container></ng-container>';
const fixture = TestBed.createComponent(MyComp); TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges(); fixture.detectChanges();
const el = fixture.nativeElement; const el = fixture.nativeElement;
const children = getDOM().childNodes(el); const children = getDOM().childNodes(el);
expect(children.length).toBe(5); expect(children.length).toBe(5);
expect(getDOM().isCommentNode(children[0])).toBe(true); expect(getDOM().isCommentNode(children[0])).toBe(true);
expect(children[1]).toHaveText('1'); expect(children[1]).toHaveText('1');
expect(getDOM().isCommentNode(children[2])).toBe(true); expect(getDOM().isCommentNode(children[2])).toBe(true);
expect(getDOM().isCommentNode(children[3])).toBe(true); expect(getDOM().isCommentNode(children[3])).toBe(true);
expect(children[4]).toHaveText('2'); expect(children[4]).toHaveText('2');
}); });
it('should group inner nodes', () => { fixmeIvy('FW-678: ivy generates different DOM structure for <ng-container>') &&
const template = '<ng-container *ngIf="ctxBoolProp"><p></p><b></b></ng-container>'; it('should group inner nodes', () => {
TestBed.overrideComponent(MyComp, {set: {template}}); const template = '<ng-container *ngIf="ctxBoolProp"><p></p><b></b></ng-container>';
const fixture = TestBed.createComponent(MyComp); TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp);
fixture.componentInstance.ctxBoolProp = true; fixture.componentInstance.ctxBoolProp = true;
fixture.detectChanges(); fixture.detectChanges();
const el = fixture.nativeElement; const el = fixture.nativeElement;
const children = getDOM().childNodes(el); const children = getDOM().childNodes(el);
expect(children.length).toBe(4); expect(children.length).toBe(4);
// ngIf anchor // ngIf anchor
expect(getDOM().isCommentNode(children[0])).toBe(true); expect(getDOM().isCommentNode(children[0])).toBe(true);
// ng-container anchor // ng-container anchor
expect(getDOM().isCommentNode(children[1])).toBe(true); expect(getDOM().isCommentNode(children[1])).toBe(true);
expect(getDOM().tagName(children[2]).toUpperCase()).toEqual('P'); expect(getDOM().tagName(children[2]).toUpperCase()).toEqual('P');
expect(getDOM().tagName(children[3]).toUpperCase()).toEqual('B'); expect(getDOM().tagName(children[3]).toUpperCase()).toEqual('B');
fixture.componentInstance.ctxBoolProp = false; fixture.componentInstance.ctxBoolProp = false;
fixture.detectChanges(); fixture.detectChanges();
expect(children.length).toBe(1); expect(children.length).toBe(1);
expect(getDOM().isCommentNode(children[0])).toBe(true); expect(getDOM().isCommentNode(children[0])).toBe(true);
}); });
it('should work with static content projection', () => { it('should work with static content projection', () => {
const template = `<simple><ng-container><p>1</p><p>2</p></ng-container></simple>`; const template = `<simple><ng-container><p>1</p><p>2</p></ng-container></simple>`;
@ -130,19 +134,20 @@ function declareTests(config?: {useJit: boolean}) {
expect(dir.text).toEqual('container'); expect(dir.text).toEqual('container');
}); });
it('should contain all direct child directives in a <ng-container> (content dom)', () => { fixmeIvy('unknown') &&
const template = it('should contain all direct child directives in a <ng-container> (content dom)', () => {
'<needs-content-children #q><ng-container><div text="foo"></div></ng-container></needs-content-children>'; const template =
TestBed.overrideComponent(MyComp, {set: {template}}); '<needs-content-children #q><ng-container><div text="foo"></div></ng-container></needs-content-children>';
const fixture = TestBed.createComponent(MyComp); TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges(); fixture.detectChanges();
const q = fixture.debugElement.children[0].references !['q']; const q = fixture.debugElement.children[0].references !['q'];
fixture.detectChanges(); fixture.detectChanges();
expect(q.textDirChildren.length).toEqual(1); expect(q.textDirChildren.length).toEqual(1);
expect(q.numberOfChildrenAfterContentInit).toEqual(1); expect(q.numberOfChildrenAfterContentInit).toEqual(1);
}); });
it('should contain all child directives in a <ng-container> (view dom)', () => { it('should contain all child directives in a <ng-container> (view dom)', () => {
const template = '<needs-view-children #q></needs-view-children>'; const template = '<needs-view-children #q></needs-view-children>';

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
import {fixmeIvy} from '@angular/private/testing'; import {fixmeIvy} from '@angular/private/testing';
{ {
fixmeIvy('unknown') && describe('projection', () => { describe('projection', () => {
beforeEach(() => TestBed.configureTestingModule({declarations: [MainComp, OtherComp, Simple]})); beforeEach(() => TestBed.configureTestingModule({declarations: [MainComp, OtherComp, Simple]}));
it('should support simple components', () => { it('should support simple components', () => {
@ -82,7 +82,7 @@ import {fixmeIvy} from '@angular/private/testing';
expect(main.nativeElement).toHaveText(''); expect(main.nativeElement).toHaveText('');
}); });
it('should support multiple content tags', () => { fixmeIvy('unknown') && it('should support multiple content tags', () => {
TestBed.configureTestingModule({declarations: [MultipleContentTagsComponent]}); TestBed.configureTestingModule({declarations: [MultipleContentTagsComponent]});
TestBed.overrideComponent(MainComp, { TestBed.overrideComponent(MainComp, {
set: { set: {
@ -113,33 +113,34 @@ import {fixmeIvy} from '@angular/private/testing';
expect(main.nativeElement).toHaveText('(, BAC)'); expect(main.nativeElement).toHaveText('(, BAC)');
}); });
it('should redistribute direct child viewcontainers when the light dom changes', () => { fixmeIvy('FW-665: Unable to find the given context data for the given target') &&
TestBed.configureTestingModule( it('should redistribute direct child viewcontainers when the light dom changes', () => {
{declarations: [MultipleContentTagsComponent, ManualViewportDirective]}); TestBed.configureTestingModule(
TestBed.overrideComponent(MainComp, { {declarations: [MultipleContentTagsComponent, ManualViewportDirective]});
set: { TestBed.overrideComponent(MainComp, {
template: '<multiple-content-tags>' + set: {
'<ng-template manual class="left"><div>A1</div></ng-template>' + template: '<multiple-content-tags>' +
'<div>B</div>' + '<ng-template manual class="left"><div>A1</div></ng-template>' +
'</multiple-content-tags>' '<div>B</div>' +
} '</multiple-content-tags>'
}); }
const main = TestBed.createComponent(MainComp); });
const main = TestBed.createComponent(MainComp);
const viewportDirectives = main.debugElement.children[0] const viewportDirectives = main.debugElement.children[0]
.childNodes.filter(By.directive(ManualViewportDirective)) .childNodes.filter(By.directive(ManualViewportDirective))
.map(de => de.injector.get(ManualViewportDirective)); .map(de => de.injector.get(ManualViewportDirective));
expect(main.nativeElement).toHaveText('(, B)'); expect(main.nativeElement).toHaveText('(, B)');
viewportDirectives.forEach(d => d.show()); viewportDirectives.forEach(d => d.show());
main.detectChanges(); main.detectChanges();
expect(main.nativeElement).toHaveText('(A1, B)'); expect(main.nativeElement).toHaveText('(A1, B)');
viewportDirectives.forEach(d => d.hide()); viewportDirectives.forEach(d => d.hide());
main.detectChanges(); main.detectChanges();
expect(main.nativeElement).toHaveText('(, B)'); expect(main.nativeElement).toHaveText('(, B)');
}); });
it('should support nested components', () => { it('should support nested components', () => {
TestBed.configureTestingModule({declarations: [OuterWithIndirectNestedComponent]}); TestBed.configureTestingModule({declarations: [OuterWithIndirectNestedComponent]});
@ -156,33 +157,34 @@ import {fixmeIvy} from '@angular/private/testing';
expect(main.nativeElement).toHaveText('OUTER(SIMPLE(AB))'); expect(main.nativeElement).toHaveText('OUTER(SIMPLE(AB))');
}); });
it('should support nesting with content being direct child of a nested component', () => { fixmeIvy('FW-665: Unable to find the given context data for the given target') &&
TestBed.configureTestingModule({ it('should support nesting with content being direct child of a nested component', () => {
declarations: TestBed.configureTestingModule({
[InnerComponent, InnerInnerComponent, OuterComponent, ManualViewportDirective] declarations:
}); [InnerComponent, InnerInnerComponent, OuterComponent, ManualViewportDirective]
TestBed.overrideComponent(MainComp, { });
set: { TestBed.overrideComponent(MainComp, {
template: '<outer>' + set: {
'<ng-template manual class="left"><div>A</div></ng-template>' + template: '<outer>' +
'<div>B</div>' + '<ng-template manual class="left"><div>A</div></ng-template>' +
'<div>C</div>' + '<div>B</div>' +
'</outer>' '<div>C</div>' +
} '</outer>'
}); }
const main = TestBed.createComponent(MainComp); });
const main = TestBed.createComponent(MainComp);
const viewportDirective = const viewportDirective =
main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get( main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0]
ManualViewportDirective); .injector.get(ManualViewportDirective);
expect(main.nativeElement).toHaveText('OUTER(INNER(INNERINNER(,BC)))'); expect(main.nativeElement).toHaveText('OUTER(INNER(INNERINNER(,BC)))');
viewportDirective.show(); viewportDirective.show();
expect(main.nativeElement).toHaveText('OUTER(INNER(INNERINNER(A,BC)))'); expect(main.nativeElement).toHaveText('OUTER(INNER(INNERINNER(A,BC)))');
}); });
it('should redistribute when the shadow dom changes', () => { fixmeIvy('unknown') && it('should redistribute when the shadow dom changes', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [ConditionalContentComponent, ManualViewportDirective]}); {declarations: [ConditionalContentComponent, ManualViewportDirective]});
TestBed.overrideComponent(MainComp, { TestBed.overrideComponent(MainComp, {
@ -237,37 +239,38 @@ import {fixmeIvy} from '@angular/private/testing';
expect(main.nativeElement).toHaveText('P,text'); expect(main.nativeElement).toHaveText('P,text');
}); });
it('should support moving non projected light dom around', () => { fixmeIvy('FW-665: Unable to find the given context data for the given target') &&
let sourceDirective: ManualViewportDirective = undefined !; it('should support moving non projected light dom around', () => {
let sourceDirective: ManualViewportDirective = undefined !;
@Directive({selector: '[manual]'}) @Directive({selector: '[manual]'})
class ManualViewportDirective { class ManualViewportDirective {
constructor(public templateRef: TemplateRef<Object>) { sourceDirective = this; } constructor(public templateRef: TemplateRef<Object>) { sourceDirective = this; }
} }
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [Empty, ProjectDirective, ManualViewportDirective]}); {declarations: [Empty, ProjectDirective, ManualViewportDirective]});
TestBed.overrideComponent(MainComp, { TestBed.overrideComponent(MainComp, {
set: { set: {
template: '<empty>' + template: '<empty>' +
' <ng-template manual><div>A</div></ng-template>' + ' <ng-template manual><div>A</div></ng-template>' +
'</empty>' + '</empty>' +
'START(<div project></div>)END' 'START(<div project></div>)END'
} }
}); });
const main = TestBed.createComponent(MainComp); const main = TestBed.createComponent(MainComp);
const projectDirective: ProjectDirective = const projectDirective: ProjectDirective =
main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].injector.get( main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].injector.get(
ProjectDirective); ProjectDirective);
expect(main.nativeElement).toHaveText('START()END'); expect(main.nativeElement).toHaveText('START()END');
projectDirective.show(sourceDirective.templateRef); projectDirective.show(sourceDirective.templateRef);
expect(main.nativeElement).toHaveText('START(A)END'); expect(main.nativeElement).toHaveText('START(A)END');
}); });
it('should support moving projected light dom around', () => { fixmeIvy('unknown') && it('should support moving projected light dom around', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [Empty, ProjectDirective, ManualViewportDirective]}); {declarations: [Empty, ProjectDirective, ManualViewportDirective]});
TestBed.overrideComponent(MainComp, { TestBed.overrideComponent(MainComp, {
@ -290,83 +293,89 @@ import {fixmeIvy} from '@angular/private/testing';
expect(main.nativeElement).toHaveText('SIMPLE()START(A)END'); expect(main.nativeElement).toHaveText('SIMPLE()START(A)END');
}); });
it('should support moving ng-content around', () => { fixmeIvy('FW-665: Unable to find the given context data for the given target') &&
TestBed.configureTestingModule( it('should support moving ng-content around', () => {
{declarations: [ConditionalContentComponent, ProjectDirective, ManualViewportDirective]}); TestBed.configureTestingModule({
TestBed.overrideComponent(MainComp, { declarations:
set: { [ConditionalContentComponent, ProjectDirective, ManualViewportDirective]
template: '<conditional-content>' + });
'<div class="left">A</div>' + TestBed.overrideComponent(MainComp, {
'<div>B</div>' + set: {
'</conditional-content>' + template: '<conditional-content>' +
'START(<div project></div>)END' '<div class="left">A</div>' +
} '<div>B</div>' +
}); '</conditional-content>' +
const main = TestBed.createComponent(MainComp); 'START(<div project></div>)END'
}
});
const main = TestBed.createComponent(MainComp);
const sourceDirective: ManualViewportDirective = const sourceDirective: ManualViewportDirective =
main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get( main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0]
ManualViewportDirective); .injector.get(ManualViewportDirective);
const projectDirective: ProjectDirective = const projectDirective: ProjectDirective =
main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].injector.get( main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].injector.get(
ProjectDirective); ProjectDirective);
expect(main.nativeElement).toHaveText('(, B)START()END'); expect(main.nativeElement).toHaveText('(, B)START()END');
projectDirective.show(sourceDirective.templateRef); projectDirective.show(sourceDirective.templateRef);
expect(main.nativeElement).toHaveText('(, B)START(A)END'); expect(main.nativeElement).toHaveText('(, B)START(A)END');
// Stamping ng-content multiple times should not produce the content multiple // Stamping ng-content multiple times should not produce the content multiple
// times... // times...
projectDirective.show(sourceDirective.templateRef); projectDirective.show(sourceDirective.templateRef);
expect(main.nativeElement).toHaveText('(, B)START(A)END'); expect(main.nativeElement).toHaveText('(, B)START(A)END');
}); });
// Note: This does not use a ng-content element, but // Note: This does not use a ng-content element, but
// is still important as we are merging proto views independent of // is still important as we are merging proto views independent of
// the presence of ng-content elements! // the presence of ng-content elements!
it('should still allow to implement a recursive trees', () => { fixmeIvy('FW-665: Unable to find the given context data for the given target') &&
TestBed.configureTestingModule({declarations: [Tree, ManualViewportDirective]}); it('should still allow to implement a recursive trees', () => {
TestBed.overrideComponent(MainComp, {set: {template: '<tree></tree>'}}); TestBed.configureTestingModule({declarations: [Tree, ManualViewportDirective]});
const main = TestBed.createComponent(MainComp); TestBed.overrideComponent(MainComp, {set: {template: '<tree></tree>'}});
const main = TestBed.createComponent(MainComp);
main.detectChanges(); main.detectChanges();
const manualDirective: ManualViewportDirective = const manualDirective: ManualViewportDirective =
main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get( main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0]
ManualViewportDirective); .injector.get(ManualViewportDirective);
expect(main.nativeElement).toHaveText('TREE(0:)'); expect(main.nativeElement).toHaveText('TREE(0:)');
manualDirective.show(); manualDirective.show();
main.detectChanges(); main.detectChanges();
expect(main.nativeElement).toHaveText('TREE(0:TREE(1:))'); expect(main.nativeElement).toHaveText('TREE(0:TREE(1:))');
}); });
// Note: This does not use a ng-content element, but // Note: This does not use a ng-content element, but
// is still important as we are merging proto views independent of // is still important as we are merging proto views independent of
// the presence of ng-content elements! // the presence of ng-content elements!
it('should still allow to implement a recursive trees via multiple components', () => { fixmeIvy('FW-665: Unable to find the given context data for the given target') &&
TestBed.configureTestingModule({declarations: [Tree, Tree2, ManualViewportDirective]}); it('should still allow to implement a recursive trees via multiple components', () => {
TestBed.overrideComponent(MainComp, {set: {template: '<tree></tree>'}}); TestBed.configureTestingModule({declarations: [Tree, Tree2, ManualViewportDirective]});
TestBed.overrideComponent( TestBed.overrideComponent(MainComp, {set: {template: '<tree></tree>'}});
Tree, {set: {template: 'TREE({{depth}}:<tree2 *manual [depth]="depth+1"></tree2>)'}}); TestBed.overrideComponent(
const main = TestBed.createComponent(MainComp); Tree, {set: {template: 'TREE({{depth}}:<tree2 *manual [depth]="depth+1"></tree2>)'}});
const main = TestBed.createComponent(MainComp);
main.detectChanges(); main.detectChanges();
expect(main.nativeElement).toHaveText('TREE(0:)'); expect(main.nativeElement).toHaveText('TREE(0:)');
const tree = main.debugElement.query(By.directive(Tree)); const tree = main.debugElement.query(By.directive(Tree));
let manualDirective: ManualViewportDirective = tree.queryAllNodes(By.directive( let manualDirective: ManualViewportDirective = tree.queryAllNodes(By.directive(
ManualViewportDirective))[0].injector.get(ManualViewportDirective); ManualViewportDirective))[0].injector.get(ManualViewportDirective);
manualDirective.show(); manualDirective.show();
main.detectChanges(); main.detectChanges();
expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:))'); expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:))');
const tree2 = main.debugElement.query(By.directive(Tree2)); const tree2 = main.debugElement.query(By.directive(Tree2));
manualDirective = tree2.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get( manualDirective =
ManualViewportDirective); tree2.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get(
manualDirective.show(); ManualViewportDirective);
main.detectChanges(); manualDirective.show();
expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:TREE(2:)))'); main.detectChanges();
}); expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:TREE(2:)))');
});
if (getDOM().supportsNativeShadowDOM()) { if (getDOM().supportsNativeShadowDOM()) {
it('should support native content projection and isolate styles per component', () => { it('should support native content projection and isolate styles per component', () => {
@ -427,38 +436,41 @@ import {fixmeIvy} from '@angular/private/testing';
}); });
} }
it('should support nested conditionals that contain ng-contents', () => { fixmeIvy('FW-665: Unable to find the given context data for the given target') &&
TestBed.configureTestingModule( it('should support nested conditionals that contain ng-contents', () => {
{declarations: [ConditionalTextComponent, ManualViewportDirective]}); TestBed.configureTestingModule(
TestBed.overrideComponent( {declarations: [ConditionalTextComponent, ManualViewportDirective]});
MainComp, {set: {template: `<conditional-text>a</conditional-text>`}}); TestBed.overrideComponent(
const main = TestBed.createComponent(MainComp); MainComp, {set: {template: `<conditional-text>a</conditional-text>`}});
const main = TestBed.createComponent(MainComp);
expect(main.nativeElement).toHaveText('MAIN()'); expect(main.nativeElement).toHaveText('MAIN()');
let viewportElement = let viewportElement =
main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0]; main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0];
viewportElement.injector.get(ManualViewportDirective).show(); viewportElement.injector.get(ManualViewportDirective).show();
expect(main.nativeElement).toHaveText('MAIN(FIRST())'); expect(main.nativeElement).toHaveText('MAIN(FIRST())');
viewportElement = main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[1]; viewportElement =
viewportElement.injector.get(ManualViewportDirective).show(); main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[1];
expect(main.nativeElement).toHaveText('MAIN(FIRST(SECOND(a)))'); viewportElement.injector.get(ManualViewportDirective).show();
}); expect(main.nativeElement).toHaveText('MAIN(FIRST(SECOND(a)))');
});
it('should allow to switch the order of nested components via ng-content', () => { fixmeIvy('unknown') &&
TestBed.configureTestingModule({declarations: [CmpA, CmpB, CmpD, CmpC]}); it('should allow to switch the order of nested components via ng-content', () => {
TestBed.overrideComponent(MainComp, {set: {template: `<cmp-a><cmp-b></cmp-b></cmp-a>`}}); TestBed.configureTestingModule({declarations: [CmpA, CmpB, CmpD, CmpC]});
const main = TestBed.createComponent(MainComp); TestBed.overrideComponent(MainComp, {set: {template: `<cmp-a><cmp-b></cmp-b></cmp-a>`}});
const main = TestBed.createComponent(MainComp);
main.detectChanges(); main.detectChanges();
expect(getDOM().getInnerHTML(main.nativeElement)) expect(getDOM().getInnerHTML(main.nativeElement))
.toEqual( .toEqual(
'<cmp-a><cmp-b><cmp-d><i>cmp-d</i></cmp-d></cmp-b>' + '<cmp-a><cmp-b><cmp-d><i>cmp-d</i></cmp-d></cmp-b>' +
'<cmp-c><b>cmp-c</b></cmp-c></cmp-a>'); '<cmp-c><b>cmp-c</b></cmp-c></cmp-a>');
}); });
it('should create nested components in the right order', () => { fixmeIvy('unknown') && it('should create nested components in the right order', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [CmpA1, CmpA2, CmpB11, CmpB12, CmpB21, CmpB22]}); {declarations: [CmpA1, CmpA2, CmpB11, CmpB12, CmpB21, CmpB22]});
TestBed.overrideComponent(MainComp, {set: {template: `<cmp-a1></cmp-a1><cmp-a2></cmp-a2>`}}); TestBed.overrideComponent(MainComp, {set: {template: `<cmp-a1></cmp-a1><cmp-a2></cmp-a2>`}});
@ -471,7 +483,7 @@ import {fixmeIvy} from '@angular/private/testing';
'<cmp-a2>a2<cmp-b21>b21</cmp-b21><cmp-b22>b22</cmp-b22></cmp-a2>'); '<cmp-a2>a2<cmp-b21>b21</cmp-b21><cmp-b22>b22</cmp-b22></cmp-a2>');
}); });
it('should project filled view containers into a view container', () => { fixmeIvy('unknown') && it('should project filled view containers into a view container', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [ConditionalContentComponent, ManualViewportDirective]}); {declarations: [ConditionalContentComponent, ManualViewportDirective]});
TestBed.overrideComponent(MainComp, { TestBed.overrideComponent(MainComp, {

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
*/ */
import {ANALYZE_FOR_ENTRY_COMPONENTS, ApplicationRef, Component, ComponentRef, ContentChild, Directive, ErrorHandler, EventEmitter, HostListener, InjectionToken, Injector, Input, NgModule, NgModuleRef, NgZone, Output, Pipe, PipeTransform, Provider, QueryList, Renderer2, SimpleChanges, TemplateRef, ViewChildren, ViewContainerRef, destroyPlatform, ɵivyEnabled as ivyEnabled} from '@angular/core'; import {ANALYZE_FOR_ENTRY_COMPONENTS, ApplicationRef, Component, ComponentRef, ContentChild, Directive, ErrorHandler, EventEmitter, HostListener, InjectionToken, Injector, Input, NgModule, NgModuleRef, NgZone, Output, Pipe, PipeTransform, Provider, QueryList, Renderer2, SimpleChanges, TemplateRef, ViewChildren, ViewContainerRef, destroyPlatform, ɵivyEnabled as ivyEnabled} from '@angular/core';
import {TestBed, async, fakeAsync, inject, tick} from '@angular/core/testing'; import {TestBed, fakeAsync, inject, tick} from '@angular/core/testing';
import {BrowserModule, By, DOCUMENT} from '@angular/platform-browser'; import {BrowserModule, By, DOCUMENT} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
@ -16,11 +16,10 @@ import {fixmeIvy} from '@angular/private/testing';
{ {
if (ivyEnabled) { if (ivyEnabled) {
fixmeIvy('unknown') && describe('ivy', () => { declareTests(); }); describe('ivy', () => { declareTests(); });
} else { } else {
fixmeIvy('unknown') && describe('jit', () => { declareTests({useJit: true}); }); describe('jit', () => { declareTests({useJit: true}); });
describe('no jit', () => { declareTests({useJit: false}); });
fixmeIvy('unknown') && describe('no jit', () => { declareTests({useJit: false}); });
} }
declareTestsUsingBootstrap(); declareTestsUsingBootstrap();
@ -35,7 +34,7 @@ function declareTests(config?: {useJit: boolean}) {
describe('platform pipes', () => { describe('platform pipes', () => {
beforeEach(() => { TestBed.configureCompiler({...config}); }); beforeEach(() => { TestBed.configureCompiler({...config}); });
it('should overwrite them by custom pipes', () => { fixmeIvy('unknown') && it('should overwrite them by custom pipes', () => {
TestBed.configureTestingModule({declarations: [CustomPipe]}); TestBed.configureTestingModule({declarations: [CustomPipe]});
const template = '{{true | somePipe}}'; const template = '{{true | somePipe}}';
TestBed.overrideComponent(MyComp1, {set: {template}}); TestBed.overrideComponent(MyComp1, {set: {template}});
@ -77,43 +76,46 @@ function declareTests(config?: {useJit: boolean}) {
expect(CountingPipe.calls).toBe(1); expect(CountingPipe.calls).toBe(1);
}); });
it('should only update the bound property when using asyncPipe - #15205', fakeAsync(() => { fixmeIvy('unknown') &&
@Component({template: '<div myDir [a]="p | async" [b]="2"></div>'}) it('should only update the bound property when using asyncPipe - #15205',
class MyComp { fakeAsync(() => {
p = Promise.resolve(1); @Component({template: '<div myDir [a]="p | async" [b]="2"></div>'})
} class MyComp {
p = Promise.resolve(1);
}
@Directive({selector: '[myDir]'}) @Directive({selector: '[myDir]'})
class MyDir { class MyDir {
setterCalls: {[key: string]: any} = {}; setterCalls: {[key: string]: any} = {};
// TODO(issue/24571): remove '!'. // TODO(issue/24571): remove '!'.
changes !: SimpleChanges; changes !: SimpleChanges;
@Input() @Input()
set a(v: number) { this.setterCalls['a'] = v; } set a(v: number) { this.setterCalls['a'] = v; }
@Input() @Input()
set b(v: number) { this.setterCalls['b'] = v; } set b(v: number) { this.setterCalls['b'] = v; }
ngOnChanges(changes: SimpleChanges) { this.changes = changes; } ngOnChanges(changes: SimpleChanges) { this.changes = changes; }
} }
TestBed.configureTestingModule({declarations: [MyDir, MyComp]}); TestBed.configureTestingModule({declarations: [MyDir, MyComp]});
const fixture = TestBed.createComponent(MyComp); const fixture = TestBed.createComponent(MyComp);
const dir = fixture.debugElement.query(By.directive(MyDir)).injector.get(MyDir) as MyDir; const dir =
fixture.debugElement.query(By.directive(MyDir)).injector.get(MyDir) as MyDir;
fixture.detectChanges(); fixture.detectChanges();
expect(dir.setterCalls).toEqual({'a': null, 'b': 2}); expect(dir.setterCalls).toEqual({'a': null, 'b': 2});
expect(Object.keys(dir.changes)).toEqual(['a', 'b']); expect(Object.keys(dir.changes)).toEqual(['a', 'b']);
dir.setterCalls = {}; dir.setterCalls = {};
dir.changes = {}; dir.changes = {};
tick(); tick();
fixture.detectChanges(); fixture.detectChanges();
expect(dir.setterCalls).toEqual({'a': 1}); expect(dir.setterCalls).toEqual({'a': 1});
expect(Object.keys(dir.changes)).toEqual(['a']); expect(Object.keys(dir.changes)).toEqual(['a']);
})); }));
it('should only evaluate methods once - #10639', () => { it('should only evaluate methods once - #10639', () => {
TestBed.configureTestingModule({declarations: [MyCountingComp]}); TestBed.configureTestingModule({declarations: [MyCountingComp]});
@ -160,13 +162,14 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get(token)).toEqual(tokenValue); expect(injector.get(token)).toEqual(tokenValue);
}); });
it('should support providers with string token with a `.` in it', () => { fixmeIvy('FW-646: Directive providers don\'t support primitive types as DI tokens') &&
const token = 'a.b'; it('should support providers with string token with a `.` in it', () => {
const tokenValue = 1; const token = 'a.b';
const injector = createInjector([{provide: token, useValue: tokenValue}]); const tokenValue = 1;
const injector = createInjector([{provide: token, useValue: tokenValue}]);
expect(injector.get(token)).toEqual(tokenValue); expect(injector.get(token)).toEqual(tokenValue);
}); });
it('should support providers with an anonymous function as token', () => { it('should support providers with an anonymous function as token', () => {
const token = () => true; const token = () => true;
@ -188,14 +191,15 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get(token2)).toEqual(tokenValue2); expect(injector.get(token2)).toEqual(tokenValue2);
}); });
it('should support providers that have a `name` property with a number value', () => { fixmeIvy('FW-646: Directive providers don\'t support primitive types as DI tokens') &&
class TestClass { it('should support providers that have a `name` property with a number value', () => {
constructor(public name: number) {} class TestClass {
} constructor(public name: number) {}
const data = [new TestClass(1), new TestClass(2)]; }
const injector = createInjector([{provide: 'someToken', useValue: data}]); const data = [new TestClass(1), new TestClass(2)];
expect(injector.get('someToken')).toEqual(data); const injector = createInjector([{provide: 'someToken', useValue: data}]);
}); expect(injector.get('someToken')).toEqual(data);
});
describe('ANALYZE_FOR_ENTRY_COMPONENTS providers', () => { describe('ANALYZE_FOR_ENTRY_COMPONENTS providers', () => {
@ -333,7 +337,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(fixture.debugElement.childNodes.length).toBe(0); expect(fixture.debugElement.childNodes.length).toBe(0);
}); });
it('should allow empty embedded templates', () => { fixmeIvy('unknown') && it('should allow empty embedded templates', () => {
@Component({template: '<ng-template [ngIf]="true"></ng-template>'}) @Component({template: '<ng-template [ngIf]="true"></ng-template>'})
class MyComp { class MyComp {
} }
@ -350,35 +354,37 @@ function declareTests(config?: {useJit: boolean}) {
}); });
}); });
it('should support @ContentChild and @Input on the same property for static queries', () => { fixmeIvy('unknown') &&
@Directive({selector: 'test'}) it('should support @ContentChild and @Input on the same property for static queries',
class Test { () => {
// TODO(issue/24571): remove '!'. @Directive({selector: 'test'})
@Input() @ContentChild(TemplateRef) tpl !: TemplateRef<any>; class Test {
} // TODO(issue/24571): remove '!'.
@Input() @ContentChild(TemplateRef) tpl !: TemplateRef<any>;
}
@Component({ @Component({
selector: 'my-app', selector: 'my-app',
template: ` template: `
<test></test><br> <test></test><br>
<test><ng-template>Custom as a child</ng-template></test><br> <test><ng-template>Custom as a child</ng-template></test><br>
<ng-template #custom>Custom as a binding</ng-template> <ng-template #custom>Custom as a binding</ng-template>
<test [tpl]="custom"></test><br> <test [tpl]="custom"></test><br>
` `
}) })
class App { class App {
} }
const fixture = const fixture =
TestBed.configureTestingModule({declarations: [App, Test]}).createComponent(App); TestBed.configureTestingModule({declarations: [App, Test]}).createComponent(App);
fixture.detectChanges(); fixture.detectChanges();
const testDirs = const testDirs =
fixture.debugElement.queryAll(By.directive(Test)).map(el => el.injector.get(Test)); fixture.debugElement.queryAll(By.directive(Test)).map(el => el.injector.get(Test));
expect(testDirs[0].tpl).toBeUndefined(); expect(testDirs[0].tpl).toBeUndefined();
expect(testDirs[1].tpl).toBeDefined(); expect(testDirs[1].tpl).toBeDefined();
expect(testDirs[2].tpl).toBeDefined(); expect(testDirs[2].tpl).toBeDefined();
}); });
it('should not add ng-version for dynamically created components', () => { it('should not add ng-version for dynamically created components', () => {
@Component({template: ''}) @Component({template: ''})

View File

@ -16,9 +16,8 @@ import {fixmeIvy} from '@angular/private/testing';
if (ivyEnabled) { if (ivyEnabled) {
fixmeIvy('unknown') && describe('ivy', () => { declareTests(); }); fixmeIvy('unknown') && describe('ivy', () => { declareTests(); });
} else { } else {
fixmeIvy('unknown') && describe('jit', () => { declareTests({useJit: true}); }); describe('jit', () => { declareTests({useJit: true}); });
describe('no jit', () => { declareTests({useJit: false}); });
fixmeIvy('unknown') && describe('no jit', () => { declareTests({useJit: false}); });
} }
} }