fix(ivy): queries should register matches from top to bottom (#28319)

PR Close #28319
This commit is contained in:
Marc Laval
2019-01-23 16:58:52 +01:00
committed by Jason Aden
parent 54532dfdf1
commit fdc2b0bf77
3 changed files with 188 additions and 72 deletions

View File

@ -53,10 +53,8 @@ describe('Query API', () => {
}));
describe('querying by directive type', () => {
fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
.it('should contain all direct child directives in the light dom (constructor)', () => {
const template = `
it('should contain all direct child directives in the light dom (constructor)', () => {
const template = `
<div text="1"></div>
<needs-query text="2">
<div text="3">
@ -65,10 +63,10 @@ describe('Query API', () => {
</needs-query>
<div text="4"></div>
`;
const view = createTestCmpAndDetectChanges(MyComp0, template);
const view = createTestCmpAndDetectChanges(MyComp0, template);
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|');
});
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|');
});
it('should contain all direct child directives in the content dom', () => {
const template = '<needs-content-children #q><div text="foo"></div></needs-content-children>';
@ -97,7 +95,7 @@ describe('Query API', () => {
});
fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
'FW-982: For queries, ng-template own directives should be registered before the ones from inside the template')
.it('should contain the first content child when target is on <ng-template> with embedded view (issue #16568)',
() => {
const template =
@ -168,43 +166,37 @@ describe('Query API', () => {
expect(q.logs).toEqual([['setter', null], ['check', null]]);
});
fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
.it('should contain all directives in the light dom when descendants flag is used', () => {
const template = '<div text="1"></div>' +
'<needs-query-desc text="2"><div text="3">' +
'<div text="4"></div>' +
'</div></needs-query-desc>' +
'<div text="5"></div>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
it('should contain all directives in the light dom when descendants flag is used', () => {
const template = '<div text="1"></div>' +
'<needs-query-desc text="2"><div text="3">' +
'<div text="4"></div>' +
'</div></needs-query-desc>' +
'<div text="5"></div>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|4|');
});
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|4|');
});
fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
.it('should contain all directives in the light dom', () => {
const template = '<div text="1"></div>' +
'<needs-query text="2"><div text="3"></div></needs-query>' +
'<div text="4"></div>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
it('should contain all directives in the light dom', () => {
const template = '<div text="1"></div>' +
'<needs-query text="2"><div text="3"></div></needs-query>' +
'<div text="4"></div>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|');
});
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|');
});
fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
.it('should reflect dynamically inserted directives', () => {
const template = '<div text="1"></div>' +
'<needs-query text="2"><div *ngIf="shouldShow" [text]="\'3\'"></div></needs-query>' +
'<div text="4"></div>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
expect(asNativeElements(view.debugElement.children)).toHaveText('2|');
it('should reflect dynamically inserted directives', () => {
const template = '<div text="1"></div>' +
'<needs-query text="2"><div *ngIf="shouldShow" [text]="\'3\'"></div></needs-query>' +
'<div text="4"></div>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
expect(asNativeElements(view.debugElement.children)).toHaveText('2|');
view.componentInstance.shouldShow = true;
view.detectChanges();
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|');
});
view.componentInstance.shouldShow = true;
view.detectChanges();
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|');
});
it('should be cleanly destroyed when a query crosses view boundaries', () => {
const template = '<div text="1"></div>' +
@ -217,19 +209,17 @@ describe('Query API', () => {
view.destroy();
});
fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
.it('should reflect moved directives', () => {
const template = '<div text="1"></div>' +
'<needs-query text="2"><div *ngFor="let i of list" [text]="i"></div></needs-query>' +
'<div text="4"></div>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
expect(asNativeElements(view.debugElement.children)).toHaveText('2|1d|2d|3d|');
it('should reflect moved directives', () => {
const template = '<div text="1"></div>' +
'<needs-query text="2"><div *ngFor="let i of list" [text]="i"></div></needs-query>' +
'<div text="4"></div>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
expect(asNativeElements(view.debugElement.children)).toHaveText('2|1d|2d|3d|');
view.componentInstance.list = ['3d', '2d'];
view.detectChanges();
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3d|2d|');
});
view.componentInstance.list = ['3d', '2d'];
view.detectChanges();
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3d|2d|');
});
it('should throw with descriptive error when query selectors are not present', () => {
TestBed.configureTestingModule({declarations: [MyCompBroken0, HasNullQueryCondition]});
@ -472,25 +462,19 @@ describe('Query API', () => {
});
describe('querying in the view', () => {
fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
.it('should contain all the elements in the view with that have the given directive',
() => {
const template =
'<needs-view-query #q><div text="ignoreme"></div></needs-view-query>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
const q: NeedsViewQuery = view.debugElement.children[0].references !['q'];
expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']);
});
it('should contain all the elements in the view with that have the given directive', () => {
const template = '<needs-view-query #q><div text="ignoreme"></div></needs-view-query>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
const q: NeedsViewQuery = view.debugElement.children[0].references !['q'];
expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']);
});
fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
.it('should not include directive present on the host element', () => {
const template = '<needs-view-query #q text="self"></needs-view-query>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
const q: NeedsViewQuery = view.debugElement.children[0].references !['q'];
expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']);
});
it('should not include directive present on the host element', () => {
const template = '<needs-view-query #q text="self"></needs-view-query>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
const q: NeedsViewQuery = view.debugElement.children[0].references !['q'];
expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']);
});
it('should reflect changes in the component', () => {
const template = '<needs-view-query-if #q></needs-view-query-if>';