test(ivy): add tests for component factory projectable node corner cases (#27791)

In some cases ivy expects projectable nodes to be passed in a different order
to ViewEngine. Specifically, ivy expects the catch-all ("*") to be at index
0, whereas ViewEngine expects it to be at its position at which it was parsed
in the template.

This commit adds one test that breaks under ivy and others that just describe
more accurately what happens in corner cases.

PR Close #27791
This commit is contained in:
Pete Bacon Darwin 2018-12-21 10:05:31 +00:00 committed by Misko Hevery
parent c34c223122
commit 6feef368f6
2 changed files with 44 additions and 5 deletions

View File

@ -422,7 +422,12 @@ describe('compiler (unbundled Angular)', () => {
@Component({
selector: 'my-comp',
template: '<ng-content></ng-content><ng-content select="child"></ng-content>'
template:
'<ng-content select="child1"></ng-content>' +
'<ng-content></ng-content>' +
'<ng-template><ng-content select="child2"></ng-content></ng-template>' +
'<ng-content select="child3"></ng-content>' +
'<ng-content select="child1"></ng-content>'
})
export class MyComp {
@Input('aInputName')
@ -449,8 +454,8 @@ describe('compiler (unbundled Angular)', () => {
expect(createComponentFactoryCall).toContain(`{aInputProp:'aInputName'}`);
// outputs
expect(createComponentFactoryCall).toContain(`{aOutputProp:'aOutputName'}`);
// ngContentSelectors
expect(createComponentFactoryCall).toContain(`['*','child']`);
// ngContentSelectors - note that the catch-all doesn't have to appear at the start
expect(createComponentFactoryCall).toContain(`['child1','*','child2','child3','child1']`);
});
});

View File

@ -6,12 +6,12 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Component, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, Injector, Input, NgModule, OnInit, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation} from '@angular/core';
import {Component, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, Injector, Input, NO_ERRORS_SCHEMA, NgModule, OnInit, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation} from '@angular/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {fixmeIvy} from '@angular/private/testing';
import {fixmeIvy, modifiedInIvy} from '@angular/private/testing';
describe('projection', () => {
beforeEach(() => TestBed.configureTestingModule({declarations: [MainComp, OtherComp, Simple]}));
@ -111,6 +111,40 @@ describe('projection', () => {
expect(main.nativeElement).toHaveText('(A, BC)');
});
modifiedInIvy(
'FW-886: `projectableNodes` passed to a componentFactory should be in the order of declaration')
.it('should support passing projectable nodes via factory function', () => {
@Component({
selector: 'multiple-content-tags',
template: '(<ng-content SELECT="h1"></ng-content>, <ng-content></ng-content>)',
})
class MultipleContentTagsComponent {
}
@NgModule({
declarations: [MultipleContentTagsComponent],
entryComponents: [MultipleContentTagsComponent],
schemas: [NO_ERRORS_SCHEMA],
})
class MyModule {
}
TestBed.configureTestingModule({imports: [MyModule]});
const injector: Injector = TestBed.get(Injector);
const componentFactoryResolver: ComponentFactoryResolver =
injector.get(ComponentFactoryResolver);
const componentFactory =
componentFactoryResolver.resolveComponentFactory(MultipleContentTagsComponent);
expect(componentFactory.ngContentSelectors).toEqual(['h1', '*']);
const nodeOne = getDOM().createTextNode('one');
const nodeTwo = getDOM().createTextNode('two');
const component = componentFactory.create(injector, [[nodeOne], [nodeTwo]]);
expect(component.location.nativeElement).toHaveText('(one, two)');
});
it('should redistribute only direct children', () => {
TestBed.configureTestingModule({declarations: [MultipleContentTagsComponent]});
TestBed.overrideComponent(MainComp, {