test(ivy): add more test for content projection with ngIf / ngFor (#27705)
PR Close #27705
This commit is contained in:
parent
94f17e9038
commit
d132baede3
|
@ -9,10 +9,10 @@
|
|||
import {SelectorFlags} from '@angular/core/src/render3/interfaces/projection';
|
||||
|
||||
import {AttributeMarker, detectChanges} from '../../src/render3/index';
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, projection, projectionDef, template, text} from '../../src/render3/instructions';
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, projection, projectionDef, template, text, textBinding, interpolation1} from '../../src/render3/instructions';
|
||||
import {RenderFlags} from '../../src/render3/interfaces/definition';
|
||||
|
||||
import {NgIf} from './common_with_def';
|
||||
import {NgIf, NgForOf} from './common_with_def';
|
||||
import {ComponentFixture, createComponent, getDirectiveOnNode, renderComponent, toHtml} from './render_util';
|
||||
|
||||
describe('content projection', () => {
|
||||
|
@ -45,7 +45,7 @@ describe('content projection', () => {
|
|||
expect(toHtml(parent)).toEqual('<child><div>content</div></child>');
|
||||
});
|
||||
|
||||
it('should project content when root.', () => {
|
||||
it('should project content when <ng-content> is at a template root', () => {
|
||||
/** <ng-content></ng-content> */
|
||||
const Child = createComponent('child', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
|
@ -231,7 +231,7 @@ describe('content projection', () => {
|
|||
});
|
||||
|
||||
it('should project containers', () => {
|
||||
/** <div> <ng-content></ng-content></div> */
|
||||
/** <div><ng-content></ng-content></div> */
|
||||
const Child = createComponent('child', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
projectionDef();
|
||||
|
@ -824,7 +824,6 @@ describe('content projection', () => {
|
|||
|
||||
function IfTemplate(rf1: RenderFlags, ctx: any) {
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
projectionDef();
|
||||
projection(0);
|
||||
}
|
||||
}
|
||||
|
@ -889,7 +888,6 @@ describe('content projection', () => {
|
|||
|
||||
function IfTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
projectionDef();
|
||||
projection(0);
|
||||
}
|
||||
}
|
||||
|
@ -931,6 +929,74 @@ describe('content projection', () => {
|
|||
expect(fixture.html).toEqual('<child>Before-<div>A</div>Some text-After</child>');
|
||||
});
|
||||
|
||||
it('should project into dynamic views with specific selectors', () => {
|
||||
/**
|
||||
* <ng-content></ng-content>
|
||||
* Before-
|
||||
* <ng-template [ngIf]="showing">
|
||||
* <ng-content select="div"></ng-content>
|
||||
* </ng-template>
|
||||
* -After
|
||||
*/
|
||||
const Child = createComponent('child', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
projectionDef([[['div']]], ['div']);
|
||||
projection(0);
|
||||
text(1, 'Before-');
|
||||
template(2, IfTemplate, 1, 0, '', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
text(3, '-After');
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(2, 'ngIf', bind(ctx.showing));
|
||||
}
|
||||
|
||||
}, 4, 1, [NgIf]);
|
||||
|
||||
function IfTemplate(rf1: RenderFlags) {
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
projection(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
let child: {showing: boolean};
|
||||
/**
|
||||
* <child>
|
||||
* <div>A</div>
|
||||
* <span>B</span>
|
||||
* </child>
|
||||
*/
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'child');
|
||||
{
|
||||
elementStart(1, 'div');
|
||||
{ text(2, 'A'); }
|
||||
elementEnd();
|
||||
elementStart(3, 'span');
|
||||
{ text(4, 'B'); }
|
||||
elementEnd();
|
||||
}
|
||||
elementEnd();
|
||||
|
||||
// testing
|
||||
child = getDirectiveOnNode(0);
|
||||
}
|
||||
}, 5, 0, [Child]);
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
child !.showing = true;
|
||||
fixture.update();
|
||||
expect(fixture.html).toEqual('<child><span>B</span>Before-<div>A</div>-After</child>');
|
||||
|
||||
child !.showing = false;
|
||||
fixture.update();
|
||||
expect(fixture.html).toEqual('<child><span>B</span>Before--After</child>');
|
||||
|
||||
child !.showing = true;
|
||||
fixture.update();
|
||||
expect(fixture.html).toEqual('<child><span>B</span>Before-<div>A</div>-After</child>');
|
||||
});
|
||||
|
||||
it('should project nodes into the last ng-content', () => {
|
||||
/**
|
||||
* <div><ng-content></ng-content></div>
|
||||
|
@ -1027,6 +1093,52 @@ describe('content projection', () => {
|
|||
expect(toHtml(parent)).toEqual('<child><div>content</div></child>');
|
||||
});
|
||||
|
||||
// https://stackblitz.com/edit/angular-ceqmnw?file=src%2Fapp%2Fapp.component.ts
|
||||
it('should project nodes into the last ng-content unrolled by ngFor', () => {
|
||||
const items = [1, 2];
|
||||
|
||||
/**
|
||||
<div *ngFor="let item of [1, 2]; let index = index">
|
||||
({{index}}): <ng-content></ng-content>
|
||||
</div>
|
||||
*/
|
||||
const Child = createComponent('child', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
projectionDef();
|
||||
{ template(0, ForTemplate, 3, 1, undefined, ['ngForOf', '']); }
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngForOf', bind(items));
|
||||
}
|
||||
}, 1, 1, [NgForOf]);
|
||||
|
||||
function ForTemplate(rf1: RenderFlags, ctx: {index: number}) {
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
elementStart(0, 'div');
|
||||
text(1);
|
||||
projection(2);
|
||||
elementEnd();
|
||||
}
|
||||
if (rf1 & RenderFlags.Update) {
|
||||
textBinding(1, interpolation1('(', ctx.index, '):'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <child>content</child>
|
||||
*/
|
||||
const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'child');
|
||||
{ text(1, 'content'); }
|
||||
elementEnd();
|
||||
}
|
||||
}, 2, 0, [Child]);
|
||||
|
||||
const parent = renderComponent(Parent);
|
||||
expect(toHtml(parent)).toEqual('<child><div>(0):</div><div>(1):content</div></child>');
|
||||
});
|
||||
|
||||
it('should project with multiple instances of a component with projection', () => {
|
||||
const ProjectionComp = createComponent('projection-comp', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
|
|
Loading…
Reference in New Issue