test(ivy): content projection canonical example (#21674)

PR Close #21674
This commit is contained in:
Miško Hevery 2018-01-18 13:27:01 -08:00
parent acf381bcb7
commit 1e9cd95f5c
4 changed files with 93 additions and 27 deletions

View File

@ -87,3 +87,4 @@ export {
defineDirective, defineDirective,
}; };
export {createComponentRef, detectChanges, getHostElement, markDirty, renderComponent}; export {createComponentRef, detectChanges, getHostElement, markDirty, renderComponent};
export {CssSelector} from './interfaces/projection';

View File

@ -243,7 +243,7 @@ export function createLNode(
} }
if (index != null) { if (index != null) {
// We are Element or Container // We are Element or Container
ngDevMode && assertEqual(data.length, index, 'data.length not in sequence'); ngDevMode && assertDataNext(index);
data[index] = node; data[index] = node;
// Every node adds a value to the static data array to avoid a sparse array // Every node adds a value to the static data array to avoid a sparse array
@ -1264,7 +1264,7 @@ export const componentRefresh:
* *
* @param selectors * @param selectors
*/ */
export function projectionDef(selectors?: CssSelector[]): LNode[][] { export function projectionDef(index: number, selectors?: CssSelector[]): void {
const noOfNodeBuckets = selectors ? selectors.length + 1 : 1; const noOfNodeBuckets = selectors ? selectors.length + 1 : 1;
const distributedNodes = new Array<LNode[]>(noOfNodeBuckets); const distributedNodes = new Array<LNode[]>(noOfNodeBuckets);
for (let i = 0; i < noOfNodeBuckets; i++) { for (let i = 0; i < noOfNodeBuckets; i++) {
@ -1305,7 +1305,8 @@ export function projectionDef(selectors?: CssSelector[]): LNode[][] {
componentChild = componentChild.next; componentChild = componentChild.next;
} }
return distributedNodes; ngDevMode && assertDataNext(index);
data[index] = distributedNodes;
} }
/** /**
@ -1891,3 +1892,7 @@ function assertDataInRange(index: number, arr?: any[]) {
if (arr == null) arr = data; if (arr == null) arr = data;
assertLessThan(index, arr ? arr.length : 0, 'data.length'); assertLessThan(index, arr ? arr.length : 0, 'data.length');
} }
function assertDataNext(index: number) {
assertEqual(data.length, index, 'data.length not in sequence');
}

View File

@ -164,6 +164,69 @@ describe('compiler specification', () => {
expect(renderComp(MyComponent)).toEqual('<child some-directive="">child-view</child>!'); expect(renderComp(MyComponent)).toEqual('<child some-directive="">child-view</child>!');
expect(log).toEqual(['ChildComponent', 'SomeDirective']); expect(log).toEqual(['ChildComponent', 'SomeDirective']);
}); });
it('should support content projection', () => {
@Component({selector: 'simple', template: `<div><ng-content></ng-content></div>`})
class SimpleComponent {
static ngComponentDef = r3.defineComponent({
tag: 'simple',
factory: () => new SimpleComponent(),
template: function(ctx: SimpleComponent, cm: boolean) {
if (cm) {
r3.pD(0);
r3.E(0, 'div');
r3.P(2, 0);
r3.e();
}
}
});
}
@Component({
selector: 'complex',
template: `
<div id="first"><ng-content select="span[title=toFirst]"></ng-content></div>
<div id="second"><ng-content select="span[title=toSecond]"></ng-content></div>`
})
class ComplexComponent {
static ngComponentDef = r3.defineComponent({
tag: 'complex',
factory: () => new ComplexComponent(),
template: function(ctx: ComplexComponent, cm: boolean) {
if (cm) {
r3.pD(0, pD_0);
r3.E(1, 'div', ['id', 'first']);
r3.P(2, 0, 1);
r3.e();
r3.E(3, 'div', ['id', 'second']);
r3.P(4, 0, 2);
r3.e();
}
}
});
}
const pD_0: r3.CssSelector[] =
[[[['span', 'title', 'toFirst'], null]], [[['span', 'title', 'toSecond'], null]]];
@Component({
selector: 'my-app',
template: `<simple>content</simple>
<complex></complex>`
})
class MyApp {
static ngComponentDef = r3.defineComponent({
tag: 'my-app',
factory: () => new MyApp(),
template: function(ctx: MyApp, cm: boolean) {
if (cm) {
r3.E(0, SimpleComponent);
r3.T(2, 'content');
r3.e();
}
}
});
}
});
}); });
describe('local references', () => { describe('local references', () => {
@ -424,7 +487,7 @@ xdescribe('NgModule', () => {
factory: () => new MyModule(inject(Toast)), factory: () => new MyModule(inject(Toast)),
provider: [ provider: [
{provide: Toast, deps: [String]}, // If Toast has metadata generate this line {provide: Toast, deps: [String]}, // If Toast has metadata generate this line
Toast, // If toast has not metadata generate this line. Toast, // If Toast has no metadata generate this line.
{provide: String, useValue: 'Hello'} {provide: String, useValue: 'Hello'}
], ],
imports: [CommonModule] imports: [CommonModule]

View File

@ -18,7 +18,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD()); pD(0);
E(1, 'div'); E(1, 'div');
{ P(2, 0); } { P(2, 0); }
e(); e();
@ -44,7 +44,7 @@ describe('content projection', () => {
it('should project content when root.', () => { it('should project content when root.', () => {
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD()); pD(0);
P(1, 0); P(1, 0);
} }
}); });
@ -64,7 +64,7 @@ describe('content projection', () => {
it('should re-project content when root.', () => { it('should re-project content when root.', () => {
const GrandChild = createComponent('grand-child', function(ctx: any, cm: boolean) { const GrandChild = createComponent('grand-child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD()); pD(0);
E(1, 'div'); E(1, 'div');
{ P(2, 0); } { P(2, 0); }
e(); e();
@ -72,7 +72,7 @@ describe('content projection', () => {
}); });
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD()); pD(0);
E(1, GrandChild); E(1, GrandChild);
{ P(3, 0); } { P(3, 0); }
e(); e();
@ -102,7 +102,7 @@ describe('content projection', () => {
it('should project content with container.', () => { it('should project content with container.', () => {
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD()); pD(0);
E(1, 'div'); E(1, 'div');
{ P(2, 0); } { P(2, 0); }
e(); e();
@ -144,7 +144,7 @@ describe('content projection', () => {
it('should project content with container into root', () => { it('should project content with container into root', () => {
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD()); pD(0);
P(1, 0); P(1, 0);
} }
}); });
@ -182,7 +182,7 @@ describe('content projection', () => {
it('should project content with container and if-else.', () => { it('should project content with container and if-else.', () => {
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD()); pD(0);
E(1, 'div'); E(1, 'div');
{ P(2, 0); } { P(2, 0); }
e(); e();
@ -240,7 +240,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD()); pD(0);
E(1, 'div'); E(1, 'div');
{ C(2); } { C(2); }
e(); e();
@ -295,7 +295,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD()); pD(0);
E(1, 'div'); E(1, 'div');
{ C(2); } { C(2); }
e(); e();
@ -342,7 +342,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD()); pD(0);
E(1, 'div'); E(1, 'div');
{ P(2, 0); } { P(2, 0); }
e(); e();
@ -389,7 +389,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD()); pD(0);
P(1, 0); P(1, 0);
E(2, 'div'); E(2, 'div');
{ C(3); } { C(3); }
@ -439,8 +439,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD(0, [[[['span', 'title', 'toFirst'], null]], [[['span', 'title', 'toSecond'], null]]]);
pD([[[['span', 'title', 'toFirst'], null]], [[['span', 'title', 'toSecond'], null]]]));
E(1, 'div', ['id', 'first']); E(1, 'div', ['id', 'first']);
{ P(2, 0, 1); } { P(2, 0, 1); }
e(); e();
@ -486,8 +485,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD(0, [[[['span', 'class', 'toFirst'], null]], [[['span', 'class', 'toSecond'], null]]]);
pD([[[['span', 'class', 'toFirst'], null]], [[['span', 'class', 'toSecond'], null]]]));
E(1, 'div', ['id', 'first']); E(1, 'div', ['id', 'first']);
{ P(2, 0, 1); } { P(2, 0, 1); }
e(); e();
@ -533,8 +531,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD(0, [[[['span', 'class', 'toFirst'], null]], [[['span', 'class', 'toSecond'], null]]]);
pD([[[['span', 'class', 'toFirst'], null]], [[['span', 'class', 'toSecond'], null]]]));
E(1, 'div', ['id', 'first']); E(1, 'div', ['id', 'first']);
{ P(2, 0, 1); } { P(2, 0, 1); }
e(); e();
@ -580,7 +577,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD([[[['span'], null]], [[['span', 'class', 'toSecond'], null]]])); pD(0, [[[['span'], null]], [[['span', 'class', 'toSecond'], null]]]);
E(1, 'div', ['id', 'first']); E(1, 'div', ['id', 'first']);
{ P(2, 0, 1); } { P(2, 0, 1); }
e(); e();
@ -626,7 +623,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD([[[['span', 'class', 'toFirst'], null]]])); pD(0, [[[['span', 'class', 'toFirst'], null]]]);
E(1, 'div', ['id', 'first']); E(1, 'div', ['id', 'first']);
{ P(2, 0, 1); } { P(2, 0, 1); }
e(); e();
@ -673,7 +670,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD([[[['span', 'class', 'toSecond'], null]]])); pD(0, [[[['span', 'class', 'toSecond'], null]]]);
E(1, 'div', ['id', 'first']); E(1, 'div', ['id', 'first']);
{ P(2, 0); } { P(2, 0); }
e(); e();
@ -727,7 +724,7 @@ describe('content projection', () => {
*/ */
const GrandChild = createComponent('grand-child', function(ctx: any, cm: boolean) { const GrandChild = createComponent('grand-child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD([[[['span'], null]]])); pD(0, [[[['span'], null]]]);
P(1, 0, 1); P(1, 0, 1);
E(2, 'hr'); E(2, 'hr');
e(); e();
@ -743,7 +740,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD()); pD(0);
E(1, GrandChild); E(1, GrandChild);
{ {
P(3, 0); P(3, 0);
@ -793,7 +790,7 @@ describe('content projection', () => {
*/ */
const Child = createComponent('child', function(ctx: any, cm: boolean) { const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) { if (cm) {
m(0, pD([[[['div'], null]]])); pD(0, [[[['div'], null]]]);
E(1, 'span'); E(1, 'span');
{ P(2, 0, 1); } { P(2, 0, 1); }
e(); e();