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,
};
export {createComponentRef, detectChanges, getHostElement, markDirty, renderComponent};
export {CssSelector} from './interfaces/projection';

View File

@ -243,7 +243,7 @@ export function createLNode(
}
if (index != null) {
// We are Element or Container
ngDevMode && assertEqual(data.length, index, 'data.length not in sequence');
ngDevMode && assertDataNext(index);
data[index] = node;
// Every node adds a value to the static data array to avoid a sparse array
@ -1264,7 +1264,7 @@ export const componentRefresh:
*
* @param selectors
*/
export function projectionDef(selectors?: CssSelector[]): LNode[][] {
export function projectionDef(index: number, selectors?: CssSelector[]): void {
const noOfNodeBuckets = selectors ? selectors.length + 1 : 1;
const distributedNodes = new Array<LNode[]>(noOfNodeBuckets);
for (let i = 0; i < noOfNodeBuckets; i++) {
@ -1305,7 +1305,8 @@ export function projectionDef(selectors?: CssSelector[]): LNode[][] {
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;
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(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', () => {
@ -424,7 +487,7 @@ xdescribe('NgModule', () => {
factory: () => new MyModule(inject(Toast)),
provider: [
{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'}
],
imports: [CommonModule]

View File

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