test(core): make tests more resilient to header offset changes (#41883)

Updates some tests where values related to the `HEADER_OFFSET` are hardcoded, causing them to break when the offset is updated. This comes up once in a while during refactorings and these changes should save us some time in the future.

PR Close #41883
This commit is contained in:
Kristiyan Kostadinov 2021-04-29 18:22:59 +02:00 committed by Misko Hevery
parent 77d920e461
commit 36c7bebe40
5 changed files with 313 additions and 260 deletions

View File

@ -652,12 +652,15 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
const lViewDebug = lView.debug!; const lViewDebug = lView.debug!;
fixture.detectChanges(); fixture.detectChanges();
expect((fixture.nativeElement as Element).textContent).toEqual('just now'); expect((fixture.nativeElement as Element).textContent).toEqual('just now');
expect(lViewDebug.nodes.map(toTypeContent)).toEqual(['IcuContainer(<!--ICU 21:0-->)']); expect(lViewDebug.nodes.map(toTypeContent)).toEqual([
`IcuContainer(<!--ICU ${HEADER_OFFSET + 0}:0-->)`
]);
// We want to ensure that the ICU container does not have any content! // We want to ensure that the ICU container does not have any content!
// This is because the content is instance dependent and therefore can't be shared // This is because the content is instance dependent and therefore can't be shared
// across `TNode`s. // across `TNode`s.
expect(lViewDebug.nodes[0].children.map(toTypeContent)).toEqual([]); expect(lViewDebug.nodes[0].children.map(toTypeContent)).toEqual([]);
expect(fixture.nativeElement.innerHTML).toEqual('just now<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML)
.toEqual(`just now<!--ICU ${HEADER_OFFSET + 0}:0-->`);
}); });
it('should support multiple ICUs', () => { it('should support multiple ICUs', () => {
@ -674,15 +677,16 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
`); `);
const lView = getComponentLView(fixture.componentInstance); const lView = getComponentLView(fixture.componentInstance);
expect(lView.debug!.nodes.map(toTypeContent)).toEqual([ expect(lView.debug!.nodes.map(toTypeContent)).toEqual([
'IcuContainer(<!--ICU 21:0-->)', `IcuContainer(<!--ICU ${HEADER_OFFSET + 0}:0-->)`,
'IcuContainer(<!--ICU 22:0-->)', `IcuContainer(<!--ICU ${HEADER_OFFSET + 1}:0-->)`,
]); ]);
// We want to ensure that the ICU container does not have any content! // We want to ensure that the ICU container does not have any content!
// This is because the content is instance dependent and therefore can't be shared // This is because the content is instance dependent and therefore can't be shared
// across `TNode`s. // across `TNode`s.
expect(lView.debug!.nodes[0].children.map(toTypeContent)).toEqual([]); expect(lView.debug!.nodes[0].children.map(toTypeContent)).toEqual([]);
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual('just now<!--ICU 21:0-->Mr. Angular<!--ICU 22:0-->'); .toEqual(`just now<!--ICU ${HEADER_OFFSET + 0}:0-->Mr. Angular<!--ICU ${
HEADER_OFFSET + 1}:0-->`);
}); });
}); });
}); });
@ -778,19 +782,21 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
other {({{name}})} other {({{name}})}
}</div>`); }</div>`);
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual(`<div>aucun <b>email</b>!<!--ICU 22:0--> - (Angular)<!--ICU 22:3--></div>`); .toEqual(`<div>aucun <b>email</b>!<!--ICU ${HEADER_OFFSET + 1}:0--> - (Angular)<!--ICU ${
HEADER_OFFSET + 1}:3--></div>`);
fixture.componentRef.instance.count = 4; fixture.componentRef.instance.count = 4;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual( .toEqual(`<div>4 <span title="Angular">emails</span><!--ICU ${
`<div>4 <span title="Angular">emails</span><!--ICU 22:0--> - (Angular)<!--ICU 22:3--></div>`); HEADER_OFFSET + 1}:0--> - (Angular)<!--ICU ${HEADER_OFFSET + 1}:3--></div>`);
fixture.componentRef.instance.count = 0; fixture.componentRef.instance.count = 0;
fixture.componentRef.instance.name = 'John'; fixture.componentRef.instance.name = 'John';
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual(`<div>aucun <b>email</b>!<!--ICU 22:0--> - (John)<!--ICU 22:3--></div>`); .toEqual(`<div>aucun <b>email</b>!<!--ICU ${HEADER_OFFSET + 1}:0--> - (John)<!--ICU ${
HEADER_OFFSET + 1}:3--></div>`);
}); });
it('with custom interpolation config', () => { it('with custom interpolation config', () => {
@ -829,9 +835,9 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual( .toEqual(
`<div>` + `<div>` +
`<span>aucun <b>email</b>!<!--ICU 22:0--></span>` + `<span>aucun <b>email</b>!<!--ICU ${HEADER_OFFSET + 1}:0--></span>` +
` - ` + ` - ` +
`<span>(Angular)<!--ICU 22:3--></span>` + `<span>(Angular)<!--ICU ${HEADER_OFFSET + 1}:3--></span>` +
`</div>`); `</div>`);
fixture.componentRef.instance.count = 4; fixture.componentRef.instance.count = 4;
@ -839,9 +845,10 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual( .toEqual(
`<div>` + `<div>` +
`<span>4 <span title="Angular">emails</span><!--ICU 22:0--></span>` + `<span>4 <span title="Angular">emails</span><!--ICU ${
HEADER_OFFSET + 1}:0--></span>` +
` - ` + ` - ` +
`<span>(Angular)<!--ICU 22:3--></span>` + `<span>(Angular)<!--ICU ${HEADER_OFFSET + 1}:3--></span>` +
`</div>`); `</div>`);
fixture.componentRef.instance.count = 0; fixture.componentRef.instance.count = 0;
@ -850,9 +857,9 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual( .toEqual(
`<div>` + `<div>` +
`<span>aucun <b>email</b>!<!--ICU 22:0--></span>` + `<span>aucun <b>email</b>!<!--ICU ${HEADER_OFFSET + 1}:0--></span>` +
` - ` + ` - ` +
`<span>(John)<!--ICU 22:3--></span>` + `<span>(John)<!--ICU ${HEADER_OFFSET + 1}:3--></span>` +
`</div>`); `</div>`);
}); });
@ -867,7 +874,7 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
other {({{name}})} other {({{name}})}
}</span></div>`); }</span></div>`);
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual(`<div><span>(Angular)<!--ICU 21:0--></span><!--bindings={ .toEqual(`<div><span>(Angular)<!--ICU ${HEADER_OFFSET + 0}:0--></span><!--bindings={
"ng-reflect-ng-if": "true" "ng-reflect-ng-if": "true"
}--></div>`); }--></div>`);
@ -887,7 +894,7 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
other {({{name}})} other {({{name}})}
}</ng-container>`); }</ng-container>`);
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual(`(Angular)<!--ICU 22:0--><!--ng-container-->`); .toEqual(`(Angular)<!--ICU ${HEADER_OFFSET + 1}:0--><!--ng-container-->`);
}); });
it('inside <ng-template>', () => { it('inside <ng-template>', () => {
@ -922,12 +929,13 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
other {animals} other {animals}
}!} }!}
}</div>`); }</div>`);
expect(fixture.nativeElement.innerHTML).toEqual(`<div>zero<!--ICU 22:1--></div>`); expect(fixture.nativeElement.innerHTML)
.toEqual(`<div>zero<!--ICU ${HEADER_OFFSET + 1}:1--></div>`);
fixture.componentRef.instance.count = 4; fixture.componentRef.instance.count = 4;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual(`<div>4 animaux<!--nested ICU 0-->!<!--ICU 22:1--></div>`); .toEqual(`<div>4 animaux<!--nested ICU 0-->!<!--ICU ${HEADER_OFFSET + 1}:1--></div>`);
}); });
it('nested with interpolations in "other" blocks', () => { it('nested with interpolations in "other" blocks', () => {
@ -947,16 +955,18 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
}!} }!}
other {other - {{count}}} other {other - {{count}}}
}</div>`); }</div>`);
expect(fixture.nativeElement.innerHTML).toEqual(`<div>zero<!--ICU 22:1--></div>`); expect(fixture.nativeElement.innerHTML)
.toEqual(`<div>zero<!--ICU ${HEADER_OFFSET + 1}:1--></div>`);
fixture.componentRef.instance.count = 2; fixture.componentRef.instance.count = 2;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual(`<div>2 animaux<!--nested ICU 0-->!<!--ICU 22:1--></div>`); .toEqual(`<div>2 animaux<!--nested ICU 0-->!<!--ICU ${HEADER_OFFSET + 1}:1--></div>`);
fixture.componentRef.instance.count = 4; fixture.componentRef.instance.count = 4;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual(`<div>autre - 4<!--ICU 22:1--></div>`); expect(fixture.nativeElement.innerHTML)
.toEqual(`<div>autre - 4<!--ICU ${HEADER_OFFSET + 1}:1--></div>`);
}); });
it('should return the correct plural form for ICU expressions when using "ro" locale', () => { it('should return the correct plural form for ICU expressions when using "ro" locale', () => {
@ -989,31 +999,34 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
=other {lots of emails} =other {lots of emails}
}`); }`);
expect(fixture.nativeElement.innerHTML).toEqual('no email<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML).toEqual(`no email<!--ICU ${HEADER_OFFSET + 0}:0-->`);
// Change detection cycle, no model changes // Change detection cycle, no model changes
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('no email<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML).toEqual(`no email<!--ICU ${HEADER_OFFSET + 0}:0-->`);
fixture.componentInstance.count = 3; fixture.componentInstance.count = 3;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('a few emails<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML)
.toEqual(`a few emails<!--ICU ${HEADER_OFFSET + 0}:0-->`);
fixture.componentInstance.count = 1; fixture.componentInstance.count = 1;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('one email<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML).toEqual(`one email<!--ICU ${HEADER_OFFSET + 0}:0-->`);
fixture.componentInstance.count = 10; fixture.componentInstance.count = 10;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('a few emails<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML)
.toEqual(`a few emails<!--ICU ${HEADER_OFFSET + 0}:0-->`);
fixture.componentInstance.count = 20; fixture.componentInstance.count = 20;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('lots of emails<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML)
.toEqual(`lots of emails<!--ICU ${HEADER_OFFSET + 0}:0-->`);
fixture.componentInstance.count = 0; fixture.componentInstance.count = 0;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('no email<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML).toEqual(`no email<!--ICU ${HEADER_OFFSET + 0}:0-->`);
}); });
it(`should return the correct plural form for ICU expressions when using "es" locale`, () => { it(`should return the correct plural form for ICU expressions when using "es" locale`, () => {
@ -1040,31 +1053,34 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
=other {lots of emails} =other {lots of emails}
}`); }`);
expect(fixture.nativeElement.innerHTML).toEqual('no email<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML).toEqual(`no email<!--ICU ${HEADER_OFFSET + 0}:0-->`);
// Change detection cycle, no model changes // Change detection cycle, no model changes
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('no email<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML).toEqual(`no email<!--ICU ${HEADER_OFFSET + 0}:0-->`);
fixture.componentInstance.count = 3; fixture.componentInstance.count = 3;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('lots of emails<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML)
.toEqual(`lots of emails<!--ICU ${HEADER_OFFSET + 0}:0-->`);
fixture.componentInstance.count = 1; fixture.componentInstance.count = 1;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('one email<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML).toEqual(`one email<!--ICU ${HEADER_OFFSET + 0}:0-->`);
fixture.componentInstance.count = 10; fixture.componentInstance.count = 10;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('lots of emails<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML)
.toEqual(`lots of emails<!--ICU ${HEADER_OFFSET + 0}:0-->`);
fixture.componentInstance.count = 20; fixture.componentInstance.count = 20;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('lots of emails<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML)
.toEqual(`lots of emails<!--ICU ${HEADER_OFFSET + 0}:0-->`);
fixture.componentInstance.count = 0; fixture.componentInstance.count = 0;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('no email<!--ICU 21:0-->'); expect(fixture.nativeElement.innerHTML).toEqual(`no email<!--ICU ${HEADER_OFFSET + 0}:0-->`);
}); });
it('projection', () => { it('projection', () => {
@ -1159,12 +1175,14 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
const fixture = TestBed.createComponent(App); const fixture = TestBed.createComponent(App);
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.debugElement.nativeElement.innerHTML) expect(fixture.debugElement.nativeElement.innerHTML)
.toContain('<my-cmp><div>ONE<!--ICU 22:0--></div><!--container--></my-cmp>'); .toContain(
`<my-cmp><div>ONE<!--ICU ${HEADER_OFFSET + 1}:0--></div><!--container--></my-cmp>`);
fixture.componentRef.instance.count = 2; fixture.componentRef.instance.count = 2;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.debugElement.nativeElement.innerHTML) expect(fixture.debugElement.nativeElement.innerHTML)
.toContain('<my-cmp><div>OTHER<!--ICU 22:0--></div><!--container--></my-cmp>'); .toContain(
`<my-cmp><div>OTHER<!--ICU ${HEADER_OFFSET + 1}:0--></div><!--container--></my-cmp>`);
// destroy component // destroy component
fixture.componentInstance.condition = false; fixture.componentInstance.condition = false;
@ -1176,7 +1194,8 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
fixture.componentInstance.count = 1; fixture.componentInstance.count = 1;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.debugElement.nativeElement.innerHTML) expect(fixture.debugElement.nativeElement.innerHTML)
.toContain('<my-cmp><div>ONE<!--ICU 22:0--></div><!--container--></my-cmp>'); .toContain(
`<my-cmp><div>ONE<!--ICU ${HEADER_OFFSET + 1}:0--></div><!--container--></my-cmp>`);
}); });
it('with nested ICU expression and inside a container when creating a view via vcr.createEmbeddedView', it('with nested ICU expression and inside a container when creating a view via vcr.createEmbeddedView',
@ -1247,13 +1266,14 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
dir!.attachEmbeddedView(); dir!.attachEmbeddedView();
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.debugElement.nativeElement.innerHTML) expect(fixture.debugElement.nativeElement.innerHTML)
.toBe( .toBe(`<my-cmp><div>2 animals<!--nested ICU 0-->!<!--ICU ${
'<my-cmp><div>2 animals<!--nested ICU 0-->!<!--ICU 22:1--></div><!--container--></my-cmp>'); HEADER_OFFSET + 1}:1--></div><!--container--></my-cmp>`);
fixture.componentRef.instance.count = 1; fixture.componentRef.instance.count = 1;
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.debugElement.nativeElement.innerHTML) expect(fixture.debugElement.nativeElement.innerHTML)
.toBe('<my-cmp><div>ONE<!--ICU 22:1--></div><!--container--></my-cmp>'); .toBe(`<my-cmp><div>ONE<!--ICU ${
HEADER_OFFSET + 1}:1--></div><!--container--></my-cmp>`);
}); });
it('with nested containers', () => { it('with nested containers', () => {
@ -2356,14 +2376,14 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
const fixture = TestBed.createComponent(Parent); const fixture = TestBed.createComponent(Parent);
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual( .toEqual(`<child><div>Contenu enfant et projection depuis Parent<!--ICU ${
`<child><div>Contenu enfant et projection depuis Parent<!--ICU 22:0--></div></child>`); HEADER_OFFSET + 1}:0--></div></child>`);
fixture.componentRef.instance.name = 'angular'; fixture.componentRef.instance.name = 'angular';
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.nativeElement.innerHTML) expect(fixture.nativeElement.innerHTML)
.toEqual( .toEqual(`<child><div>Contenu enfant et projection depuis Angular<!--ICU ${
`<child><div>Contenu enfant et projection depuis Angular<!--ICU 22:0--></div></child>`); HEADER_OFFSET + 1}:0--></div></child>`);
}); });
it(`shouldn't project deleted projections in i18n blocks`, () => { it(`shouldn't project deleted projections in i18n blocks`, () => {

View File

@ -9,6 +9,7 @@
import {addTNodeAndUpdateInsertBeforeIndex} from '@angular/core/src/render3/i18n/i18n_insert_before_index'; import {addTNodeAndUpdateInsertBeforeIndex} from '@angular/core/src/render3/i18n/i18n_insert_before_index';
import {createTNode} from '@angular/core/src/render3/instructions/shared'; import {createTNode} from '@angular/core/src/render3/instructions/shared';
import {TNode, TNodeType} from '@angular/core/src/render3/interfaces/node'; import {TNode, TNodeType} from '@angular/core/src/render3/interfaces/node';
import {HEADER_OFFSET} from '@angular/core/src/render3/interfaces/view';
import {matchTNode} from '../matchers'; import {matchTNode} from '../matchers';
@ -29,9 +30,9 @@ describe('addTNodeAndUpdateInsertBeforeIndex', () => {
it('should add first node', () => { it('should add first node', () => {
const previousTNodes: TNode[] = []; const previousTNodes: TNode[] = [];
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tPlaceholderElementNode(21)); addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tPlaceholderElementNode(HEADER_OFFSET + 0));
expect(previousTNodes).toEqual([ expect(previousTNodes).toEqual([
matchTNode({index: 21, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 0, insertBeforeIndex: null}),
]); ]);
}); });
@ -39,14 +40,15 @@ describe('addTNodeAndUpdateInsertBeforeIndex', () => {
describe('whose index is greater than those already there', () => { describe('whose index is greater than those already there', () => {
it('should not update the `insertBeforeIndex` values', () => { it('should not update the `insertBeforeIndex` values', () => {
const previousTNodes: TNode[] = [ const previousTNodes: TNode[] = [
tPlaceholderElementNode(21), tPlaceholderElementNode(HEADER_OFFSET + 0),
tPlaceholderElementNode(22), tPlaceholderElementNode(HEADER_OFFSET + 1),
]; ];
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tPlaceholderElementNode(23)); addTNodeAndUpdateInsertBeforeIndex(
previousTNodes, tPlaceholderElementNode(HEADER_OFFSET + 2));
expect(previousTNodes).toEqual([ expect(previousTNodes).toEqual([
matchTNode({index: 21, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 0, insertBeforeIndex: null}),
matchTNode({index: 22, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 1, insertBeforeIndex: null}),
matchTNode({index: 23, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 2, insertBeforeIndex: null}),
]); ]);
}); });
}); });
@ -54,44 +56,47 @@ describe('addTNodeAndUpdateInsertBeforeIndex', () => {
describe('whose index is smaller than current nodes', () => { describe('whose index is smaller than current nodes', () => {
it('should update the previous insertBeforeIndex', () => { it('should update the previous insertBeforeIndex', () => {
const previousTNodes: TNode[] = [ const previousTNodes: TNode[] = [
tPlaceholderElementNode(22), tPlaceholderElementNode(HEADER_OFFSET + 1),
tPlaceholderElementNode(23), tPlaceholderElementNode(HEADER_OFFSET + 2),
]; ];
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tPlaceholderElementNode(21)); addTNodeAndUpdateInsertBeforeIndex(
previousTNodes, tPlaceholderElementNode(HEADER_OFFSET + 0));
expect(previousTNodes).toEqual([ expect(previousTNodes).toEqual([
matchTNode({index: 22, insertBeforeIndex: 21}), matchTNode({index: HEADER_OFFSET + 1, insertBeforeIndex: HEADER_OFFSET + 0}),
matchTNode({index: 23, insertBeforeIndex: 21}), matchTNode({index: HEADER_OFFSET + 2, insertBeforeIndex: HEADER_OFFSET + 0}),
matchTNode({index: 21, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 0, insertBeforeIndex: null}),
]); ]);
}); });
it('should not update the previous insertBeforeIndex if it is already set', () => { it('should not update the previous insertBeforeIndex if it is already set', () => {
const previousTNodes: TNode[] = [ const previousTNodes: TNode[] = [
tPlaceholderElementNode(23, 22), tPlaceholderElementNode(HEADER_OFFSET + 2, HEADER_OFFSET + 1),
tPlaceholderElementNode(24, 22), tPlaceholderElementNode(HEADER_OFFSET + 3, HEADER_OFFSET + 1),
tPlaceholderElementNode(22), tPlaceholderElementNode(HEADER_OFFSET + 1),
]; ];
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tPlaceholderElementNode(21)); addTNodeAndUpdateInsertBeforeIndex(
previousTNodes, tPlaceholderElementNode(HEADER_OFFSET + 0));
expect(previousTNodes).toEqual([ expect(previousTNodes).toEqual([
matchTNode({index: 23, insertBeforeIndex: 22}), matchTNode({index: HEADER_OFFSET + 2, insertBeforeIndex: HEADER_OFFSET + 1}),
matchTNode({index: 24, insertBeforeIndex: 22}), matchTNode({index: HEADER_OFFSET + 3, insertBeforeIndex: HEADER_OFFSET + 1}),
matchTNode({index: 22, insertBeforeIndex: 21}), matchTNode({index: HEADER_OFFSET + 1, insertBeforeIndex: HEADER_OFFSET + 0}),
matchTNode({index: 21, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 0, insertBeforeIndex: null}),
]); ]);
}); });
it('should not update the previous insertBeforeIndex if it is created after', () => { it('should not update the previous insertBeforeIndex if it is created after', () => {
const previousTNodes: TNode[] = [ const previousTNodes: TNode[] = [
tPlaceholderElementNode(26, 21), tPlaceholderElementNode(HEADER_OFFSET + 5, HEADER_OFFSET + 0),
tPlaceholderElementNode(27, 21), tPlaceholderElementNode(HEADER_OFFSET + 6, HEADER_OFFSET + 0),
tPlaceholderElementNode(21), tPlaceholderElementNode(HEADER_OFFSET + 0),
]; ];
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tPlaceholderElementNode(24)); addTNodeAndUpdateInsertBeforeIndex(
previousTNodes, tPlaceholderElementNode(HEADER_OFFSET + 3));
expect(previousTNodes).toEqual([ expect(previousTNodes).toEqual([
matchTNode({index: 26, insertBeforeIndex: 21}), matchTNode({index: HEADER_OFFSET + 5, insertBeforeIndex: HEADER_OFFSET + 0}),
matchTNode({index: 27, insertBeforeIndex: 21}), matchTNode({index: HEADER_OFFSET + 6, insertBeforeIndex: HEADER_OFFSET + 0}),
matchTNode({index: 21, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 0, insertBeforeIndex: null}),
matchTNode({index: 24, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 3, insertBeforeIndex: null}),
]); ]);
}); });
}); });
@ -101,14 +106,14 @@ describe('addTNodeAndUpdateInsertBeforeIndex', () => {
describe('whose index is greater than those already there', () => { describe('whose index is greater than those already there', () => {
it('should not update the `insertBeforeIndex` values', () => { it('should not update the `insertBeforeIndex` values', () => {
const previousTNodes: TNode[] = [ const previousTNodes: TNode[] = [
tPlaceholderElementNode(21), tPlaceholderElementNode(HEADER_OFFSET + 0),
tPlaceholderElementNode(22), tPlaceholderElementNode(HEADER_OFFSET + 1),
]; ];
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tI18NTextNode(23)); addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tI18NTextNode(HEADER_OFFSET + 2));
expect(previousTNodes).toEqual([ expect(previousTNodes).toEqual([
matchTNode({index: 21, insertBeforeIndex: 23}), matchTNode({index: HEADER_OFFSET + 0, insertBeforeIndex: HEADER_OFFSET + 2}),
matchTNode({index: 22, insertBeforeIndex: 23}), matchTNode({index: HEADER_OFFSET + 1, insertBeforeIndex: HEADER_OFFSET + 2}),
matchTNode({index: 23, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 2, insertBeforeIndex: null}),
]); ]);
}); });
}); });
@ -116,44 +121,44 @@ describe('addTNodeAndUpdateInsertBeforeIndex', () => {
describe('whose index is smaller than current nodes', () => { describe('whose index is smaller than current nodes', () => {
it('should update the previous insertBeforeIndex', () => { it('should update the previous insertBeforeIndex', () => {
const previousTNodes: TNode[] = [ const previousTNodes: TNode[] = [
tPlaceholderElementNode(22), tPlaceholderElementNode(HEADER_OFFSET + 1),
tPlaceholderElementNode(23), tPlaceholderElementNode(HEADER_OFFSET + 2),
]; ];
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tI18NTextNode(21)); addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tI18NTextNode(HEADER_OFFSET + 0));
expect(previousTNodes).toEqual([ expect(previousTNodes).toEqual([
matchTNode({index: 22, insertBeforeIndex: 21}), matchTNode({index: HEADER_OFFSET + 1, insertBeforeIndex: HEADER_OFFSET + 0}),
matchTNode({index: 23, insertBeforeIndex: 21}), matchTNode({index: HEADER_OFFSET + 2, insertBeforeIndex: HEADER_OFFSET + 0}),
matchTNode({index: 21, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 0, insertBeforeIndex: null}),
]); ]);
}); });
it('should not update the previous insertBeforeIndex if it is already set', () => { it('should not update the previous insertBeforeIndex if it is already set', () => {
const previousTNodes: TNode[] = [ const previousTNodes: TNode[] = [
tPlaceholderElementNode(23, 22), tPlaceholderElementNode(HEADER_OFFSET + 2, HEADER_OFFSET + 1),
tPlaceholderElementNode(24, 22), tPlaceholderElementNode(HEADER_OFFSET + 3, HEADER_OFFSET + 1),
tPlaceholderElementNode(22), tPlaceholderElementNode(HEADER_OFFSET + 1),
]; ];
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tI18NTextNode(21)); addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tI18NTextNode(HEADER_OFFSET + 0));
expect(previousTNodes).toEqual([ expect(previousTNodes).toEqual([
matchTNode({index: 23, insertBeforeIndex: 22}), matchTNode({index: HEADER_OFFSET + 2, insertBeforeIndex: HEADER_OFFSET + 1}),
matchTNode({index: 24, insertBeforeIndex: 22}), matchTNode({index: HEADER_OFFSET + 3, insertBeforeIndex: HEADER_OFFSET + 1}),
matchTNode({index: 22, insertBeforeIndex: 21}), matchTNode({index: HEADER_OFFSET + 1, insertBeforeIndex: HEADER_OFFSET + 0}),
matchTNode({index: 21, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 0, insertBeforeIndex: null}),
]); ]);
}); });
it('should not update the previous insertBeforeIndex if it is created after', () => { it('should not update the previous insertBeforeIndex if it is created after', () => {
const previousTNodes: TNode[] = [ const previousTNodes: TNode[] = [
tPlaceholderElementNode(26, 21), tPlaceholderElementNode(HEADER_OFFSET + 5, HEADER_OFFSET + 0),
tPlaceholderElementNode(27, 21), tPlaceholderElementNode(HEADER_OFFSET + 6, HEADER_OFFSET + 0),
tPlaceholderElementNode(21), tPlaceholderElementNode(HEADER_OFFSET + 0),
]; ];
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tI18NTextNode(24)); addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tI18NTextNode(HEADER_OFFSET + 3));
expect(previousTNodes).toEqual([ expect(previousTNodes).toEqual([
matchTNode({index: 26, insertBeforeIndex: 21}), matchTNode({index: HEADER_OFFSET + 5, insertBeforeIndex: HEADER_OFFSET + 0}),
matchTNode({index: 27, insertBeforeIndex: 21}), matchTNode({index: HEADER_OFFSET + 6, insertBeforeIndex: HEADER_OFFSET + 0}),
matchTNode({index: 21, insertBeforeIndex: 24}), matchTNode({index: HEADER_OFFSET + 0, insertBeforeIndex: HEADER_OFFSET + 3}),
matchTNode({index: 24, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 3, insertBeforeIndex: null}),
]); ]);
}); });
}); });
@ -162,21 +167,27 @@ describe('addTNodeAndUpdateInsertBeforeIndex', () => {
describe('scenario', () => { describe('scenario', () => {
it('should rearrange the nodes', () => { it('should rearrange the nodes', () => {
const previousTNodes: TNode[] = []; const previousTNodes: TNode[] = [];
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tPlaceholderElementNode(23)); addTNodeAndUpdateInsertBeforeIndex(
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tPlaceholderElementNode(29)); previousTNodes, tPlaceholderElementNode(HEADER_OFFSET + 2));
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tPlaceholderElementNode(25)); addTNodeAndUpdateInsertBeforeIndex(
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tPlaceholderElementNode(26)); previousTNodes, tPlaceholderElementNode(HEADER_OFFSET + 8));
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tI18NTextNode(30)); addTNodeAndUpdateInsertBeforeIndex(
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tPlaceholderElementNode(24)); previousTNodes, tPlaceholderElementNode(HEADER_OFFSET + 4));
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tPlaceholderElementNode(28)); addTNodeAndUpdateInsertBeforeIndex(
previousTNodes, tPlaceholderElementNode(HEADER_OFFSET + 5));
addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tI18NTextNode(HEADER_OFFSET + 9));
addTNodeAndUpdateInsertBeforeIndex(
previousTNodes, tPlaceholderElementNode(HEADER_OFFSET + 3));
addTNodeAndUpdateInsertBeforeIndex(
previousTNodes, tPlaceholderElementNode(HEADER_OFFSET + 7));
expect(previousTNodes).toEqual([ expect(previousTNodes).toEqual([
matchTNode({index: 23, insertBeforeIndex: 30}), matchTNode({index: HEADER_OFFSET + 2, insertBeforeIndex: HEADER_OFFSET + 9}),
matchTNode({index: 29, insertBeforeIndex: 25}), matchTNode({index: HEADER_OFFSET + 8, insertBeforeIndex: HEADER_OFFSET + 4}),
matchTNode({index: 25, insertBeforeIndex: 30}), matchTNode({index: HEADER_OFFSET + 4, insertBeforeIndex: HEADER_OFFSET + 9}),
matchTNode({index: 26, insertBeforeIndex: 30}), matchTNode({index: HEADER_OFFSET + 5, insertBeforeIndex: HEADER_OFFSET + 9}),
matchTNode({index: 30, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 9, insertBeforeIndex: null}),
matchTNode({index: 24, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 3, insertBeforeIndex: null}),
matchTNode({index: 28, insertBeforeIndex: null}), matchTNode({index: HEADER_OFFSET + 7, insertBeforeIndex: null}),
]); ]);
}); });
}); });

View File

@ -11,7 +11,7 @@ import {applyCreateOpCodes} from '@angular/core/src/render3/i18n/i18n_apply';
import {i18nStartFirstCreatePass} from '@angular/core/src/render3/i18n/i18n_parse'; import {i18nStartFirstCreatePass} from '@angular/core/src/render3/i18n/i18n_parse';
import {getTIcu} from '@angular/core/src/render3/i18n/i18n_util'; import {getTIcu} from '@angular/core/src/render3/i18n/i18n_util';
import {I18nUpdateOpCodes, IcuType, TI18n} from '@angular/core/src/render3/interfaces/i18n'; import {I18nUpdateOpCodes, IcuType, TI18n} from '@angular/core/src/render3/interfaces/i18n';
import {HEADER_OFFSET} from '@angular/core/src/render3/interfaces/view'; import {HEADER_OFFSET, HOST} from '@angular/core/src/render3/interfaces/view';
import {expect} from '@angular/core/testing/src/testing_internal'; import {expect} from '@angular/core/testing/src/testing_internal';
import {matchTI18n, matchTIcu} from '../matchers'; import {matchTI18n, matchTIcu} from '../matchers';
import {matchDebug} from '../utils'; import {matchDebug} from '../utils';
@ -26,8 +26,8 @@ describe('i18n_parse', () => {
const tI18n = toT18n('some text'); const tI18n = toT18n('some text');
expect(tI18n).toEqual(matchTI18n({ expect(tI18n).toEqual(matchTI18n({
create: matchDebug([ create: matchDebug([
'lView[23] = document.createText("some text");', `lView[${HEADER_OFFSET + 2}] = document.createText("some text");`,
'parent.appendChild(lView[23]);', `parent.appendChild(lView[${HEADER_OFFSET + 2}]);`,
]), ]),
update: [] as unknown as I18nUpdateOpCodes, update: [] as unknown as I18nUpdateOpCodes,
})); }));
@ -57,30 +57,30 @@ describe('i18n_parse', () => {
}|after`); }|after`);
expect(tI18n).toEqual(matchTI18n({ expect(tI18n).toEqual(matchTI18n({
create: matchDebug([ create: matchDebug([
'lView[23] = document.createText("before|");', `lView[${HEADER_OFFSET + 2}] = document.createText("before|");`,
'parent.appendChild(lView[23]);', `parent.appendChild(lView[${HEADER_OFFSET + 2}]);`,
'lView[24] = document.createComment("ICU 21:0");', `lView[${HEADER_OFFSET + 3}] = document.createComment("ICU ${HEADER_OFFSET + 0}:0");`,
'parent.appendChild(lView[24]);', `parent.appendChild(lView[${HEADER_OFFSET + 3}]);`,
'lView[28] = document.createText("|after");', `lView[${HEADER_OFFSET + 7}] = document.createText("|after");`,
'parent.appendChild(lView[28]);', `parent.appendChild(lView[${HEADER_OFFSET + 7}]);`,
]), ]),
update: matchDebug([ update: matchDebug([
'if (mask & 0b1) { icuSwitchCase(24, `${lView[i-1]}`); }', `if (mask & 0b1) { icuSwitchCase(${HEADER_OFFSET + 3}, \`\${lView[i-1]}\`); }`,
]) ])
})); }));
expect(getTIcu(fixture.tView, 24)).toEqual(matchTIcu({ expect(getTIcu(fixture.tView, HEADER_OFFSET + 3)).toEqual(matchTIcu({
type: IcuType.select, type: IcuType.select,
anchorIdx: 24, anchorIdx: HEADER_OFFSET + 3,
currentCaseLViewIndex: 25, currentCaseLViewIndex: HEADER_OFFSET + 4,
cases: ['A', 'other'], cases: ['A', 'other'],
create: [ create: [
matchDebug([ matchDebug([
'lView[26] = document.createTextNode("caseA")', `lView[${HEADER_OFFSET + 5}] = document.createTextNode("caseA")`,
'(lView[0] as Element).appendChild(lView[26])' `(lView[${HOST}] as Element).appendChild(lView[${HEADER_OFFSET + 5}])`
]), ]),
matchDebug([ matchDebug([
'lView[27] = document.createTextNode("otherCase")', `lView[${HEADER_OFFSET + 6}] = document.createTextNode("otherCase")`,
'(lView[0] as Element).appendChild(lView[27])', `(lView[${HOST}] as Element).appendChild(lView[${HEADER_OFFSET + 6}])`,
]) ])
], ],
update: [ update: [
@ -88,29 +88,32 @@ describe('i18n_parse', () => {
matchDebug([]), matchDebug([]),
], ],
remove: [ remove: [
matchDebug(['remove(lView[26])']), matchDebug([`remove(lView[${HEADER_OFFSET + 5}])`]),
matchDebug(['remove(lView[27])']), matchDebug([`remove(lView[${HEADER_OFFSET + 6}])`]),
], ],
})); }));
fixture.apply(() => { fixture.apply(() => {
applyCreateOpCodes(fixture.lView, tI18n.create, fixture.host, null); applyCreateOpCodes(fixture.lView, tI18n.create, fixture.host, null);
expect(fixture.host.innerHTML).toEqual('before|<!--ICU 21:0-->|after'); expect(fixture.host.innerHTML).toEqual(`before|<!--ICU ${HEADER_OFFSET + 0}:0-->|after`);
}); });
fixture.apply(() => { fixture.apply(() => {
ɵɵi18nExp('A'); ɵɵi18nExp('A');
ɵɵi18nApply(0); // index 0 + HEADER_OFFSET = 20; ɵɵi18nApply(0);
expect(fixture.host.innerHTML).toEqual('before|caseA<!--ICU 21:0-->|after'); expect(fixture.host.innerHTML)
.toEqual(`before|caseA<!--ICU ${HEADER_OFFSET + 0}:0-->|after`);
}); });
fixture.apply(() => { fixture.apply(() => {
ɵɵi18nExp('x'); ɵɵi18nExp('x');
ɵɵi18nApply(0); // index 0 + HEADER_OFFSET = 20; ɵɵi18nApply(0);
expect(fixture.host.innerHTML).toEqual('before|otherCase<!--ICU 21:0-->|after'); expect(fixture.host.innerHTML)
.toEqual(`before|otherCase<!--ICU ${HEADER_OFFSET + 0}:0-->|after`);
}); });
fixture.apply(() => { fixture.apply(() => {
ɵɵi18nExp('A'); ɵɵi18nExp('A');
ɵɵi18nApply(0); // index 0 + HEADER_OFFSET = 20; ɵɵi18nApply(0);
expect(fixture.host.innerHTML).toEqual('before|caseA<!--ICU 21:0-->|after'); expect(fixture.host.innerHTML)
.toEqual(`before|caseA<!--ICU ${HEADER_OFFSET + 0}:0-->|after`);
}); });
}); });
@ -122,23 +125,25 @@ describe('i18n_parse', () => {
}`); }`);
fixture.apply(() => { fixture.apply(() => {
applyCreateOpCodes(fixture.lView, tI18n.create, fixture.host, null); applyCreateOpCodes(fixture.lView, tI18n.create, fixture.host, null);
expect(fixture.host.innerHTML).toEqual('<!--ICU 21:0-->'); expect(fixture.host.innerHTML).toEqual(`<!--ICU ${HEADER_OFFSET + 0}:0-->`);
}); });
fixture.apply(() => { fixture.apply(() => {
ɵɵi18nExp('A'); ɵɵi18nExp('A');
ɵɵi18nApply(0); // index 0 + HEADER_OFFSET = 20; ɵɵi18nApply(0);
expect(fixture.host.innerHTML).toEqual('Hello <b>world<i>!</i></b><!--ICU 21:0-->'); expect(fixture.host.innerHTML)
.toEqual(`Hello <b>world<i>!</i></b><!--ICU ${HEADER_OFFSET + 0}:0-->`);
}); });
fixture.apply(() => { fixture.apply(() => {
ɵɵi18nExp('x'); ɵɵi18nExp('x');
ɵɵi18nApply(0); // index 0 + HEADER_OFFSET = 20; ɵɵi18nApply(0);
expect(fixture.host.innerHTML) expect(fixture.host.innerHTML)
.toEqual('<div>nestedOther<!--nested ICU 0--></div><!--ICU 21:0-->'); .toEqual(`<div>nestedOther<!--nested ICU 0--></div><!--ICU ${HEADER_OFFSET + 0}:0-->`);
}); });
fixture.apply(() => { fixture.apply(() => {
ɵɵi18nExp('A'); ɵɵi18nExp('A');
ɵɵi18nApply(0); // index 0 + HEADER_OFFSET = 20; ɵɵi18nApply(0);
expect(fixture.host.innerHTML).toEqual('Hello <b>world<i>!</i></b><!--ICU 21:0-->'); expect(fixture.host.innerHTML)
.toEqual(`Hello <b>world<i>!</i></b><!--ICU ${HEADER_OFFSET + 0}:0-->`);
}); });
}); });
@ -170,32 +175,32 @@ describe('i18n_parse', () => {
}`); }`);
expect(tI18n).toEqual(matchTI18n({ expect(tI18n).toEqual(matchTI18n({
create: matchDebug([ create: matchDebug([
'lView[25] = document.createComment("ICU 21:0");', `lView[${HEADER_OFFSET + 4}] = document.createComment("ICU ${HEADER_OFFSET + 0}:0");`,
'parent.appendChild(lView[25]);', `parent.appendChild(lView[${HEADER_OFFSET + 4}]);`,
]), ]),
update: matchDebug([ update: matchDebug([
'if (mask & 0b1) { icuSwitchCase(25, `${lView[i-1]}`); }', `if (mask & 0b1) { icuSwitchCase(${HEADER_OFFSET + 4}, \`\${lView[i-1]}\`); }`,
'if (mask & 0b10) { icuSwitchCase(28, `${lView[i-2]}`); }', `if (mask & 0b10) { icuSwitchCase(${HEADER_OFFSET + 7}, \`\${lView[i-2]}\`); }`,
'if (mask & 0b100) { icuUpdateCase(28); }', `if (mask & 0b100) { icuUpdateCase(${HEADER_OFFSET + 7}); }`,
]), ]),
})); }));
expect(getTIcu(fixture.tView, 25)).toEqual(matchTIcu({ expect(getTIcu(fixture.tView, HEADER_OFFSET + 4)).toEqual(matchTIcu({
type: IcuType.select, type: IcuType.select,
anchorIdx: 25, anchorIdx: HEADER_OFFSET + 4,
currentCaseLViewIndex: 26, currentCaseLViewIndex: HEADER_OFFSET + 5,
cases: ['A', 'other'], cases: ['A', 'other'],
create: [ create: [
matchDebug([ matchDebug([
'lView[27] = document.createTextNode("parentA ")', `lView[${HEADER_OFFSET + 6}] = document.createTextNode("parentA ")`,
'(lView[0] as Element).appendChild(lView[27])', `(lView[${HOST}] as Element).appendChild(lView[${HEADER_OFFSET + 6}])`,
'lView[28] = document.createComment("nested ICU 0")', `lView[${HEADER_OFFSET + 7}] = document.createComment("nested ICU 0")`,
'(lView[0] as Element).appendChild(lView[28])', `(lView[${HOST}] as Element).appendChild(lView[${HEADER_OFFSET + 7}])`,
'lView[32] = document.createTextNode("!")', `lView[${HEADER_OFFSET + 11}] = document.createTextNode("!")`,
'(lView[0] as Element).appendChild(lView[32])', `(lView[${HOST}] as Element).appendChild(lView[${HEADER_OFFSET + 11}])`,
]), ]),
matchDebug([ matchDebug([
'lView[33] = document.createTextNode("parentOther")', `lView[${HEADER_OFFSET + 12}] = document.createTextNode("parentOther")`,
'(lView[0] as Element).appendChild(lView[33])', `(lView[${HOST}] as Element).appendChild(lView[${HEADER_OFFSET + 12}])`,
]) ])
], ],
update: [ update: [
@ -204,76 +209,79 @@ describe('i18n_parse', () => {
], ],
remove: [ remove: [
matchDebug([ matchDebug([
'remove(lView[27])', `remove(lView[${HEADER_OFFSET + 6}])`,
'removeNestedICU(28)', `removeNestedICU(${HEADER_OFFSET + 7})`,
'remove(lView[28])', `remove(lView[${HEADER_OFFSET + 7}])`,
'remove(lView[32])', `remove(lView[${HEADER_OFFSET + 11}])`,
]), ]),
matchDebug([ matchDebug([
'remove(lView[33])', `remove(lView[${HEADER_OFFSET + 12}])`,
]) ])
], ],
})); }));
expect(getTIcu(fixture.tView, 28)).toEqual(matchTIcu({ expect(getTIcu(fixture.tView, HEADER_OFFSET + 7)).toEqual(matchTIcu({
type: IcuType.select, type: IcuType.select,
anchorIdx: 28, anchorIdx: HEADER_OFFSET + 7,
currentCaseLViewIndex: 29, currentCaseLViewIndex: HEADER_OFFSET + 8,
cases: ['0', 'other'], cases: ['0', 'other'],
create: [ create: [
matchDebug([ matchDebug([
'lView[30] = document.createTextNode("nested0")', `lView[${HEADER_OFFSET + 9}] = document.createTextNode("nested0")`,
'(lView[0] as Element).appendChild(lView[30])' `(lView[${HOST}] as Element).appendChild(lView[${HEADER_OFFSET + 9}])`
]), ]),
matchDebug([ matchDebug([
'lView[31] = document.createTextNode("")', `lView[${HEADER_OFFSET + 10}] = document.createTextNode("")`,
'(lView[0] as Element).appendChild(lView[31])', `(lView[${HOST}] as Element).appendChild(lView[${HEADER_OFFSET + 10}])`,
]) ])
], ],
update: [ update: [
matchDebug([]), matchDebug([]),
matchDebug([ matchDebug([
'if (mask & 0b100) { (lView[31] as Text).textContent = `${lView[i-3]}`; }', `if (mask & 0b100) { (lView[${
HEADER_OFFSET + 10}] as Text).textContent = \`\${lView[i-3]}\`; }`,
]), ]),
], ],
remove: [ remove: [
matchDebug(['remove(lView[30])']), matchDebug([`remove(lView[${HEADER_OFFSET + 9}])`]),
matchDebug(['remove(lView[31])']), matchDebug([`remove(lView[${HEADER_OFFSET + 10}])`]),
], ],
})); }));
fixture.apply(() => { fixture.apply(() => {
applyCreateOpCodes(fixture.lView, tI18n.create, fixture.host, null); applyCreateOpCodes(fixture.lView, tI18n.create, fixture.host, null);
expect(fixture.host.innerHTML).toEqual('<!--ICU 21:0-->'); expect(fixture.host.innerHTML).toEqual(`<!--ICU ${HEADER_OFFSET + 0}:0-->`);
}); });
fixture.apply(() => { fixture.apply(() => {
ɵɵi18nExp('A'); ɵɵi18nExp('A');
ɵɵi18nExp('0'); ɵɵi18nExp('0');
ɵɵi18nExp('value1'); ɵɵi18nExp('value1');
ɵɵi18nApply(0); // index 0 + HEADER_OFFSET = 20; ɵɵi18nApply(0);
expect(fixture.host.innerHTML) expect(fixture.host.innerHTML)
.toEqual('parentA nested0<!--nested ICU 0-->!<!--ICU 21:0-->'); .toEqual(`parentA nested0<!--nested ICU 0-->!<!--ICU ${HEADER_OFFSET + 0}:0-->`);
}); });
fixture.apply(() => { fixture.apply(() => {
ɵɵi18nExp('A'); ɵɵi18nExp('A');
ɵɵi18nExp('x'); ɵɵi18nExp('x');
ɵɵi18nExp('value1'); ɵɵi18nExp('value1');
ɵɵi18nApply(0); // index 0 + HEADER_OFFSET = 20; ɵɵi18nApply(0);
expect(fixture.host.innerHTML).toEqual('parentA value1<!--nested ICU 0-->!<!--ICU 21:0-->'); expect(fixture.host.innerHTML)
.toEqual(`parentA value1<!--nested ICU 0-->!<!--ICU ${HEADER_OFFSET + 0}:0-->`);
}); });
fixture.apply(() => { fixture.apply(() => {
ɵɵi18nExp('x'); ɵɵi18nExp('x');
ɵɵi18nExp('x'); ɵɵi18nExp('x');
ɵɵi18nExp('value2'); ɵɵi18nExp('value2');
ɵɵi18nApply(0); // index 0 + HEADER_OFFSET = 20; ɵɵi18nApply(0);
expect(fixture.host.innerHTML).toEqual('parentOther<!--ICU 21:0-->'); expect(fixture.host.innerHTML).toEqual(`parentOther<!--ICU ${HEADER_OFFSET + 0}:0-->`);
}); });
fixture.apply(() => { fixture.apply(() => {
ɵɵi18nExp('A'); ɵɵi18nExp('A');
ɵɵi18nExp('A'); ɵɵi18nExp('A');
ɵɵi18nExp('value2'); ɵɵi18nExp('value2');
ɵɵi18nApply(0); // index 0 + HEADER_OFFSET = 20; ɵɵi18nApply(0);
expect(fixture.host.innerHTML).toEqual('parentA value2<!--nested ICU 0-->!<!--ICU 21:0-->'); expect(fixture.host.innerHTML)
.toEqual(`parentA value2<!--nested ICU 0-->!<!--ICU ${HEADER_OFFSET + 0}:0-->`);
}); });
}); });
}); });

View File

@ -127,9 +127,8 @@ describe('Runtime i18n', () => {
ɵɵelementEnd(); ɵɵelementEnd();
}, undefined, nbConsts, HEADER_OFFSET + index); }, undefined, nbConsts, HEADER_OFFSET + index);
expect((opCodes as any).update.debug).toEqual([ expect((opCodes as any).update.debug).toEqual([`if (mask & 0b1) { (lView[${
'if (mask & 0b1) { (lView[23] as Text).textContent = `Hello ${lView[i-1]}!`; }' HEADER_OFFSET + 2}] as Text).textContent = \`Hello \${lView[i-1]}!\`; }`]);
]);
expect(opCodes).toEqual({ expect(opCodes).toEqual({
create: matchDebug([ create: matchDebug([
@ -137,7 +136,8 @@ describe('Runtime i18n', () => {
`parent.appendChild(lView[${HEADER_OFFSET + 2}]);`, `parent.appendChild(lView[${HEADER_OFFSET + 2}]);`,
]), ]),
update: matchDebug([ update: matchDebug([
'if (mask & 0b1) { (lView[23] as Text).textContent = `Hello ${lView[i-1]}!`; }', `if (mask & 0b1) { (lView[${
HEADER_OFFSET + 2}] as Text).textContent = \`Hello \${lView[i-1]}!\`; }`,
]), ]),
}); });
}); });
@ -158,7 +158,9 @@ describe('Runtime i18n', () => {
`parent.appendChild(lView[${HEADER_OFFSET + 2}]);`, `parent.appendChild(lView[${HEADER_OFFSET + 2}]);`,
]), ]),
update: matchDebug([ update: matchDebug([
'if (mask & 0b11) { (lView[23] as Text).textContent = `Hello ${lView[i-1]} and ${lView[i-2]}, again ${lView[i-1]}!`; }', `if (mask & 0b11) { (lView[${
HEADER_OFFSET +
2}] as Text).textContent = \`Hello \${lView[i-1]} and \${lView[i-2]}, again \${lView[i-1]}!\`; }`,
]), ]),
}); });
}); });
@ -193,7 +195,8 @@ describe('Runtime i18n', () => {
`parent.appendChild(lView[${HEADER_OFFSET + 4}]);`, `parent.appendChild(lView[${HEADER_OFFSET + 4}]);`,
]), ]),
update: matchDebug([ update: matchDebug([
'if (mask & 0b1) { (lView[24] as Text).textContent = `${lView[i-1]} is rendered as: `; }', `if (mask & 0b1) { (lView[${
HEADER_OFFSET + 3}] as Text).textContent = \`\${lView[i-1]} is rendered as: \`; }`,
]), ]),
}); });
@ -249,26 +252,26 @@ describe('Runtime i18n', () => {
expect(opCodes).toEqual({ expect(opCodes).toEqual({
create: matchDebug([ create: matchDebug([
`lView[${HEADER_OFFSET + 2}] = document.createComment("ICU 22:0");`, `lView[${HEADER_OFFSET + 2}] = document.createComment("ICU ${HEADER_OFFSET + 1}:0");`,
`parent.appendChild(lView[${HEADER_OFFSET + 2}]);`, `parent.appendChild(lView[${HEADER_OFFSET + 2}]);`,
]), ]),
update: matchDebug([ update: matchDebug([
'if (mask & 0b1) { icuSwitchCase(23, `${lView[i-1]}`); }', `if (mask & 0b1) { icuSwitchCase(${HEADER_OFFSET + 2}, \`\${lView[i-1]}\`); }`,
'if (mask & 0b1) { icuUpdateCase(23); }', `if (mask & 0b1) { icuUpdateCase(${HEADER_OFFSET + 2}); }`,
]), ]),
}); });
expect(getTIcu(tView, 23)).toEqual(<TIcu>{ expect(getTIcu(tView, HEADER_OFFSET + 2)).toEqual(<TIcu>{
type: 1, type: 1,
currentCaseLViewIndex: 24, currentCaseLViewIndex: HEADER_OFFSET + 3,
anchorIdx: 23, anchorIdx: HEADER_OFFSET + 2,
cases: ['0', '1', 'other'], cases: ['0', '1', 'other'],
create: [ create: [
matchDebug([ matchDebug([
`lView[${HEADER_OFFSET + 4}] = document.createTextNode("no ")`, `lView[${HEADER_OFFSET + 4}] = document.createTextNode("no ")`,
`(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 4}])`, `(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 4}])`,
'lView[26] = document.createElement("b")', `lView[${HEADER_OFFSET + 5}] = document.createElement("b")`,
`(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 5}])`, `(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 5}])`,
'(lView[26] as Element).setAttribute("title", "none")', `(lView[${HEADER_OFFSET + 5}] as Element).setAttribute("title", "none")`,
`lView[${HEADER_OFFSET + 6}] = document.createTextNode("emails")`, `lView[${HEADER_OFFSET + 6}] = document.createTextNode("emails")`,
`(lView[${HEADER_OFFSET + 5}] as Element).appendChild(lView[${HEADER_OFFSET + 6}])`, `(lView[${HEADER_OFFSET + 5}] as Element).appendChild(lView[${HEADER_OFFSET + 6}])`,
`lView[${HEADER_OFFSET + 7}] = document.createTextNode("!")`, `lView[${HEADER_OFFSET + 7}] = document.createTextNode("!")`,
@ -277,41 +280,43 @@ describe('Runtime i18n', () => {
matchDebug([ matchDebug([
`lView[${HEADER_OFFSET + 8}] = document.createTextNode("one ")`, `lView[${HEADER_OFFSET + 8}] = document.createTextNode("one ")`,
`(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 8}])`, `(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 8}])`,
'lView[30] = document.createElement("i")', `lView[${HEADER_OFFSET + 9}] = document.createElement("i")`,
`(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 9}])`, `(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 9}])`,
'lView[31] = document.createTextNode("email")', `lView[${HEADER_OFFSET + 10}] = document.createTextNode("email")`,
'(lView[30] as Element).appendChild(lView[31])', `(lView[${HEADER_OFFSET + 9}] as Element).appendChild(lView[${HEADER_OFFSET + 10}])`,
]), ]),
matchDebug([ matchDebug([
'lView[32] = document.createTextNode("")', `lView[${HEADER_OFFSET + 11}] = document.createTextNode("")`,
'(lView[21] as Element).appendChild(lView[32])', `(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 11}])`,
'lView[33] = document.createElement("span")', `lView[${HEADER_OFFSET + 12}] = document.createElement("span")`,
'(lView[21] as Element).appendChild(lView[33])', `(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 12}])`,
'lView[34] = document.createTextNode("emails")', `lView[${HEADER_OFFSET + 13}] = document.createTextNode("emails")`,
'(lView[33] as Element).appendChild(lView[34])', `(lView[${HEADER_OFFSET + 12}] as Element).appendChild(lView[${HEADER_OFFSET + 13}])`,
]), ]),
], ],
remove: [ remove: [
matchDebug([ matchDebug([
'remove(lView[25])', `remove(lView[${HEADER_OFFSET + 4}])`,
'remove(lView[26])', `remove(lView[${HEADER_OFFSET + 5}])`,
'remove(lView[28])', `remove(lView[${HEADER_OFFSET + 7}])`,
]), ]),
matchDebug([ matchDebug([
'remove(lView[29])', `remove(lView[${HEADER_OFFSET + 8}])`,
'remove(lView[30])', `remove(lView[${HEADER_OFFSET + 9}])`,
]), ]),
matchDebug([ matchDebug([
'remove(lView[32])', `remove(lView[${HEADER_OFFSET + 11}])`,
'remove(lView[33])', `remove(lView[${HEADER_OFFSET + 12}])`,
]), ]),
], ],
update: [ update: [
matchDebug([]), matchDebug([]),
matchDebug([]), matchDebug([]),
matchDebug([ matchDebug([
'if (mask & 0b1) { (lView[32] as Text).textContent = `${lView[i-1]} `; }', `if (mask & 0b1) { (lView[${
'if (mask & 0b10) { (lView[33] as Element).setAttribute(\'title\', `${lView[i-2]}`); }', HEADER_OFFSET + 11}] as Text).textContent = \`\${lView[i-1]} \`; }`,
`if (mask & 0b10) { (lView[${
HEADER_OFFSET + 12}] as Element).setAttribute('title', \`\${lView[i-2]}\`); }`,
]), ]),
] ]
}); });
@ -336,19 +341,19 @@ describe('Runtime i18n', () => {
expect(opCodes).toEqual({ expect(opCodes).toEqual({
create: matchDebug([ create: matchDebug([
`lView[${HEADER_OFFSET + 2}] = document.createComment("ICU 22:0");`, `lView[${HEADER_OFFSET + 2}] = document.createComment("ICU ${HEADER_OFFSET + 1}:0");`,
`parent.appendChild(lView[${HEADER_OFFSET + 2}]);`, `parent.appendChild(lView[${HEADER_OFFSET + 2}]);`,
]), ]),
update: matchDebug([ update: matchDebug([
'if (mask & 0b1) { icuSwitchCase(23, `${lView[i-1]}`); }', `if (mask & 0b1) { icuSwitchCase(${HEADER_OFFSET + 2}, \`\${lView[i-1]}\`); }`,
'if (mask & 0b10) { icuSwitchCase(27, `${lView[i-2]}`); }', `if (mask & 0b10) { icuSwitchCase(${HEADER_OFFSET + 6}, \`\${lView[i-2]}\`); }`,
'if (mask & 0b1) { icuUpdateCase(23); }', `if (mask & 0b1) { icuUpdateCase(${HEADER_OFFSET + 2}); }`,
]), ]),
}); });
expect(getTIcu(tView, 23)).toEqual({ expect(getTIcu(tView, HEADER_OFFSET + 2)).toEqual({
type: 1, type: 1,
anchorIdx: 23, anchorIdx: HEADER_OFFSET + 2,
currentCaseLViewIndex: 24, currentCaseLViewIndex: HEADER_OFFSET + 3,
cases: ['0', 'other'], cases: ['0', 'other'],
create: [ create: [
matchDebug([ matchDebug([
@ -358,34 +363,35 @@ describe('Runtime i18n', () => {
matchDebug([ matchDebug([
`lView[${HEADER_OFFSET + 5}] = document.createTextNode("")`, `lView[${HEADER_OFFSET + 5}] = document.createTextNode("")`,
`(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 5}])`, `(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 5}])`,
'lView[27] = document.createComment("nested ICU 0")', `lView[${HEADER_OFFSET + 6}] = document.createComment("nested ICU 0")`,
`(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 6}])`, `(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 6}])`,
'lView[32] = document.createTextNode("!")', `lView[${HEADER_OFFSET + 11}] = document.createTextNode("!")`,
'(lView[21] as Element).appendChild(lView[32])', `(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 11}])`,
]), ]),
], ],
update: [ update: [
matchDebug([]), matchDebug([]),
matchDebug([ matchDebug([
'if (mask & 0b1) { (lView[26] as Text).textContent = `${lView[i-1]} `; }', `if (mask & 0b1) { (lView[${
HEADER_OFFSET + 5}] as Text).textContent = \`\${lView[i-1]} \`; }`,
]), ]),
], ],
remove: [ remove: [
matchDebug([ matchDebug([
'remove(lView[25])', `remove(lView[${HEADER_OFFSET + 4}])`,
]), ]),
matchDebug([ matchDebug([
'remove(lView[26])', `remove(lView[${HEADER_OFFSET + 5}])`,
'removeNestedICU(27)', `removeNestedICU(${HEADER_OFFSET + 6})`,
'remove(lView[27])', `remove(lView[${HEADER_OFFSET + 6}])`,
'remove(lView[32])', `remove(lView[${HEADER_OFFSET + 11}])`,
]), ]),
], ],
}); });
expect(tView.data[27]).toEqual({ expect(tView.data[HEADER_OFFSET + 6]).toEqual({
type: 0, type: 0,
anchorIdx: 27, anchorIdx: HEADER_OFFSET + 6,
currentCaseLViewIndex: 28, currentCaseLViewIndex: HEADER_OFFSET + 7,
cases: ['cat', 'dog', 'other'], cases: ['cat', 'dog', 'other'],
create: [ create: [
matchDebug([ matchDebug([
@ -397,8 +403,8 @@ describe('Runtime i18n', () => {
`(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 9}])`, `(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 9}])`,
]), ]),
matchDebug([ matchDebug([
'lView[31] = document.createTextNode("animals")', `lView[${HEADER_OFFSET + 10}] = document.createTextNode("animals")`,
'(lView[21] as Element).appendChild(lView[31])', `(lView[${HEADER_OFFSET + 0}] as Element).appendChild(lView[${HEADER_OFFSET + 10}])`,
]), ]),
], ],
update: [ update: [
@ -407,9 +413,9 @@ describe('Runtime i18n', () => {
matchDebug([]), matchDebug([]),
], ],
remove: [ remove: [
matchDebug(['remove(lView[29])']), matchDebug([`remove(lView[${HEADER_OFFSET + 8}])`]),
matchDebug(['remove(lView[30])']), matchDebug([`remove(lView[${HEADER_OFFSET + 9}])`]),
matchDebug(['remove(lView[31])']), matchDebug([`remove(lView[${HEADER_OFFSET + 10}])`]),
], ],
}); });
}); });
@ -428,7 +434,8 @@ describe('Runtime i18n', () => {
}, undefined, nbConsts, HEADER_OFFSET + index); }, undefined, nbConsts, HEADER_OFFSET + index);
expect(opCodes).toEqual(matchDebug([ expect(opCodes).toEqual(matchDebug([
'if (mask & 0b1) { (lView[21] as Element).setAttribute(\'title\', `Hello ${lView[i-1]}!`); }', `if (mask & 0b1) { (lView[${
HEADER_OFFSET + 0}] as Element).setAttribute('title', \`Hello \$\{lView[i-1]}!\`); }`,
])); ]));
}); });
@ -444,7 +451,9 @@ describe('Runtime i18n', () => {
}, undefined, nbConsts, HEADER_OFFSET + index); }, undefined, nbConsts, HEADER_OFFSET + index);
expect(opCodes).toEqual(matchDebug([ expect(opCodes).toEqual(matchDebug([
'if (mask & 0b11) { (lView[21] as Element).setAttribute(\'title\', `Hello ${lView[i-1]} and ${lView[i-2]}, again ${lView[i-1]}!`); }', `if (mask & 0b11) { (lView[${
HEADER_OFFSET +
0}] as Element).setAttribute('title', \`Hello \$\{lView[i-1]} and \$\{lView[i-2]}, again \$\{lView[i-1]}!\`); }`,
])); ]));
}); });
@ -460,8 +469,11 @@ describe('Runtime i18n', () => {
}, undefined, nbConsts, HEADER_OFFSET + index); }, undefined, nbConsts, HEADER_OFFSET + index);
expect(opCodes).toEqual(matchDebug([ expect(opCodes).toEqual(matchDebug([
'if (mask & 0b1) { (lView[21] as Element).setAttribute(\'title\', `Hello ${lView[i-1]}!`); }', `if (mask & 0b1) { (lView[${
'if (mask & 0b1) { (lView[21] as Element).setAttribute(\'aria-label\', `Hello ${lView[i-1]}!`); }', HEADER_OFFSET + 0}] as Element).setAttribute('title', \`Hello \$\{lView[i-1]}!\`); }`,
`if (mask & 0b1) { (lView[${
HEADER_OFFSET +
0}] as Element).setAttribute('aria-label', \`Hello \$\{lView[i-1]}!\`); }`,
])); ]));
}); });
}); });
@ -702,8 +714,10 @@ describe('Runtime i18n', () => {
], ],
})); }));
expect(ti18n.update).toEqual(matchDebug([ expect(ti18n.update).toEqual(matchDebug([
'if (mask & 0b1) { (lView[51] as Text).textContent = `${lView[i-1]} `; }', `if (mask & 0b1) { (lView[${
'if (mask & 0b10) { (lView[52] as Text).textContent = `${lView[i-2]}`; }' HEADER_OFFSET + 30}] as Text).textContent = \`\${lView[i-1]} \`; }`,
`if (mask & 0b10) { (lView[${
HEADER_OFFSET + 31}] as Text).textContent = \`\${lView[i-2]}\`; }`
])); ]));
const lViewDebug = fixture.lView.debug!; const lViewDebug = fixture.lView.debug!;
expect(lViewDebug.template).toEqual('<div>{{?}}<Placeholder>{{?}}</Placeholder>!</div>'); expect(lViewDebug.template).toEqual('<div>{{?}}<Placeholder>{{?}}</Placeholder>!</div>');
@ -714,16 +728,16 @@ describe('Runtime i18n', () => {
fixture.tView, 0, fixture.lView, HEADER_OFFSET + 1, 'Hello <20>*2:1<>World<6C>/*2:1<>!', -1); fixture.tView, 0, fixture.lView, HEADER_OFFSET + 1, 'Hello <20>*2:1<>World<6C>/*2:1<>!', -1);
const ti18n = fixture.tView.data[HEADER_OFFSET + 1] as TI18n; const ti18n = fixture.tView.data[HEADER_OFFSET + 1] as TI18n;
expect(ti18n.create.debug).toEqual([ expect(ti18n.create.debug).toEqual([
'lView[51] = document.createText("Hello ");', `lView[${HEADER_OFFSET + 30}] = document.createText("Hello ");`,
'parent.appendChild(lView[51]);', `parent.appendChild(lView[${HEADER_OFFSET + 30}]);`,
'lView[52] = document.createText("!");', `lView[${HEADER_OFFSET + 31}] = document.createText("!");`,
'parent.appendChild(lView[52]);', `parent.appendChild(lView[${HEADER_OFFSET + 31}]);`,
]); ]);
// Leave behind `Placeholder` to be picked up by `TNode` creation. // Leave behind `Placeholder` to be picked up by `TNode` creation.
// It should insert itself in front of "!" // It should insert itself in front of "!"
expect(fixture.tView.data[HEADER_OFFSET + 2]).toEqual(matchTNode({ expect(fixture.tView.data[HEADER_OFFSET + 2]).toEqual(matchTNode({
type: TNodeType.Placeholder, type: TNodeType.Placeholder,
insertBeforeIndex: 52, insertBeforeIndex: HEADER_OFFSET + 31,
})); }));
}); });
}); });

View File

@ -13,7 +13,7 @@ import {ɵɵelement, ɵɵelementEnd, ɵɵelementStart} from '@angular/core/src/r
import {TNodeDebug} from '@angular/core/src/render3/instructions/lview_debug'; import {TNodeDebug} from '@angular/core/src/render3/instructions/lview_debug';
import {createTNode, createTView} from '@angular/core/src/render3/instructions/shared'; import {createTNode, createTView} from '@angular/core/src/render3/instructions/shared';
import {TNodeType} from '@angular/core/src/render3/interfaces/node'; import {TNodeType} from '@angular/core/src/render3/interfaces/node';
import {LView, LViewDebug, TView, TViewType} from '@angular/core/src/render3/interfaces/view'; import {HEADER_OFFSET, LView, LViewDebug, TView, TViewType} from '@angular/core/src/render3/interfaces/view';
import {enterView, leaveView} from '@angular/core/src/render3/state'; import {enterView, leaveView} from '@angular/core/src/render3/state';
import {insertTStylingBinding} from '@angular/core/src/render3/styling/style_binding_list'; import {insertTStylingBinding} from '@angular/core/src/render3/styling/style_binding_list';
import {getComponentLView} from '@angular/core/src/render3/util/discovery_utils'; import {getComponentLView} from '@angular/core/src/render3/util/discovery_utils';
@ -242,7 +242,7 @@ describe('lView_debug', () => {
cumulativeBloom: jasmine.anything(), cumulativeBloom: jasmine.anything(),
providers: [MyChild.ɵdir], providers: [MyChild.ɵdir],
viewProviders: [], viewProviders: [],
parentInjectorIndex: 23, parentInjectorIndex: HEADER_OFFSET + 2,
}); });
}); });
}); });