test(ivy): update root causes for @angular/core TestBed failures (#27321)

PR Close #27321
This commit is contained in:
Pawel Kozlowski 2018-11-28 12:18:44 +01:00 committed by Jason Aden
parent 0340ba47df
commit 7076773360
2 changed files with 162 additions and 171 deletions

View File

@ -28,16 +28,13 @@ import {stringify} from '../../src/util';
const ANCHOR_ELEMENT = new InjectionToken('AnchorElement'); const ANCHOR_ELEMENT = new InjectionToken('AnchorElement');
{ if (ivyEnabled) {
if (ivyEnabled) { describe('ivy', () => { declareTests(); });
describe('ivy', () => { declareTests(); }); } else {
} else { describe('jit', () => { declareTests({useJit: true}); });
describe('jit', () => { declareTests({useJit: true}); }); describe('no jit', () => { declareTests({useJit: false}); });
describe('no jit', () => { declareTests({useJit: false}); });
}
} }
function declareTests(config?: {useJit: boolean}) { function declareTests(config?: {useJit: boolean}) {
describe('integration tests', function() { describe('integration tests', function() {
@ -227,19 +224,18 @@ function declareTests(config?: {useJit: boolean}) {
expect(nativeEl).not.toHaveCssClass('initial'); expect(nativeEl).not.toHaveCssClass('initial');
}); });
fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') && it('should consume binding to htmlFor using for alias', () => {
it('should consume binding to htmlFor using for alias', () => { const template = '<label [for]="ctxProp"></label>';
const template = '<label [for]="ctxProp"></label>'; const fixture = TestBed.configureTestingModule({declarations: [MyComp]})
const fixture = TestBed.configureTestingModule({declarations: [MyComp]}) .overrideComponent(MyComp, {set: {template}})
.overrideComponent(MyComp, {set: {template}}) .createComponent(MyComp);
.createComponent(MyComp);
const nativeEl = fixture.debugElement.children[0].nativeElement; const nativeEl = fixture.debugElement.children[0].nativeElement;
fixture.debugElement.componentInstance.ctxProp = 'foo'; fixture.debugElement.componentInstance.ctxProp = 'foo';
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getProperty(nativeEl, 'htmlFor')).toBe('foo'); expect(getDOM().getProperty(nativeEl, 'htmlFor')).toBe('foo');
}); });
fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') && fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') &&
it('should consume directive watch expression change.', () => { it('should consume directive watch expression change.', () => {
@ -856,48 +852,52 @@ function declareTests(config?: {useJit: boolean}) {
dir.triggerChange('two'); dir.triggerChange('two');
})); }));
fixmeIvy('unknown') && it('should support render events', () => { fixmeIvy(
TestBed.configureTestingModule({declarations: [MyComp, DirectiveListeningDomEvent]}); 'FW-743: Registering events on global objects (document, window, body) is not supported') &&
const template = '<div listener></div>'; it('should support render events', () => {
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.configureTestingModule({declarations: [MyComp, DirectiveListeningDomEvent]});
const fixture = TestBed.createComponent(MyComp); const template = '<div listener></div>';
TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp);
const tc = fixture.debugElement.children[0]; const tc = fixture.debugElement.children[0];
const listener = tc.injector.get(DirectiveListeningDomEvent); const listener = tc.injector.get(DirectiveListeningDomEvent);
dispatchEvent(tc.nativeElement, 'domEvent'); dispatchEvent(tc.nativeElement, 'domEvent');
expect(listener.eventTypes).toEqual([ expect(listener.eventTypes).toEqual([
'domEvent', 'body_domEvent', 'document_domEvent', 'window_domEvent' 'domEvent', 'body_domEvent', 'document_domEvent', 'window_domEvent'
]); ]);
fixture.destroy(); fixture.destroy();
listener.eventTypes = []; listener.eventTypes = [];
dispatchEvent(tc.nativeElement, 'domEvent'); dispatchEvent(tc.nativeElement, 'domEvent');
expect(listener.eventTypes).toEqual([]); expect(listener.eventTypes).toEqual([]);
}); });
fixmeIvy('unknown') && it('should support render global events', () => { fixmeIvy(
TestBed.configureTestingModule({declarations: [MyComp, DirectiveListeningDomEvent]}); 'FW-743: Registering events on global objects (document, window, body) is not supported') &&
const template = '<div listener></div>'; it('should support render global events', () => {
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.configureTestingModule({declarations: [MyComp, DirectiveListeningDomEvent]});
const fixture = TestBed.createComponent(MyComp); const template = '<div listener></div>';
const doc = TestBed.get(DOCUMENT); TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp);
const doc = TestBed.get(DOCUMENT);
const tc = fixture.debugElement.children[0]; const tc = fixture.debugElement.children[0];
const listener = tc.injector.get(DirectiveListeningDomEvent); const listener = tc.injector.get(DirectiveListeningDomEvent);
dispatchEvent(getDOM().getGlobalEventTarget(doc, 'window'), 'domEvent'); dispatchEvent(getDOM().getGlobalEventTarget(doc, 'window'), 'domEvent');
expect(listener.eventTypes).toEqual(['window_domEvent']); expect(listener.eventTypes).toEqual(['window_domEvent']);
listener.eventTypes = []; listener.eventTypes = [];
dispatchEvent(getDOM().getGlobalEventTarget(doc, 'document'), 'domEvent'); dispatchEvent(getDOM().getGlobalEventTarget(doc, 'document'), 'domEvent');
expect(listener.eventTypes).toEqual(['document_domEvent', 'window_domEvent']); expect(listener.eventTypes).toEqual(['document_domEvent', 'window_domEvent']);
fixture.destroy(); fixture.destroy();
listener.eventTypes = []; listener.eventTypes = [];
dispatchEvent(getDOM().getGlobalEventTarget(doc, 'body'), 'domEvent'); dispatchEvent(getDOM().getGlobalEventTarget(doc, 'body'), 'domEvent');
expect(listener.eventTypes).toEqual([]); expect(listener.eventTypes).toEqual([]);
}); });
it('should support updating host element via hostAttributes on root elements', () => { it('should support updating host element via hostAttributes on root elements', () => {
@Component({host: {'role': 'button'}, template: ''}) @Component({host: {'role': 'button'}, template: ''})
@ -1034,7 +1034,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
} }
fixmeIvy('unknown') && fixmeIvy(
'FW-743: Registering events on global objects (document, window, body) is not supported') &&
it('should support render global events from multiple directives', () => { it('should support render global events from multiple directives', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [MyComp, DirectiveListeningDomEvent, DirectiveListeningDomEventOther] declarations: [MyComp, DirectiveListeningDomEvent, DirectiveListeningDomEventOther]
@ -1457,37 +1458,35 @@ function declareTests(config?: {useJit: boolean}) {
`Directive ${stringify(SomeDirective)} has no selector, please add it!`); `Directive ${stringify(SomeDirective)} has no selector, please add it!`);
}); });
fixmeIvy('FW-662: Components without selector are not supported') && it('should use a default element name for components without selectors', () => {
it('should use a default element name for components without selectors', () => { let noSelectorComponentFactory: ComponentFactory<SomeComponent> = undefined !;
let noSelectorComponentFactory: ComponentFactory<SomeComponent> = undefined !;
@Component({template: '----'}) @Component({template: '----'})
class NoSelectorComponent { class NoSelectorComponent {
} }
@Component( @Component({selector: 'some-comp', template: '', entryComponents: [NoSelectorComponent]})
{selector: 'some-comp', template: '', entryComponents: [NoSelectorComponent]}) class SomeComponent {
class SomeComponent { constructor(componentFactoryResolver: ComponentFactoryResolver) {
constructor(componentFactoryResolver: ComponentFactoryResolver) { // grab its own component factory
// grab its own component factory noSelectorComponentFactory =
noSelectorComponentFactory = componentFactoryResolver.resolveComponentFactory(NoSelectorComponent) !;
componentFactoryResolver.resolveComponentFactory(NoSelectorComponent) !; }
} }
}
TestBed.configureTestingModule({declarations: [SomeComponent, NoSelectorComponent]}); TestBed.configureTestingModule({declarations: [SomeComponent, NoSelectorComponent]});
// get the factory // get the factory
TestBed.createComponent(SomeComponent); TestBed.createComponent(SomeComponent);
expect(noSelectorComponentFactory.selector).toBe('ng-component'); expect(noSelectorComponentFactory.selector).toBe('ng-component');
expect(getDOM() expect(
.nodeName( getDOM()
noSelectorComponentFactory.create(Injector.NULL).location.nativeElement) .nodeName(noSelectorComponentFactory.create(Injector.NULL).location.nativeElement)
.toLowerCase()) .toLowerCase())
.toEqual('ng-component'); .toEqual('ng-component');
}); });
}); });
describe('error handling', () => { describe('error handling', () => {
@ -1699,15 +1698,13 @@ function declareTests(config?: {useJit: boolean}) {
.toContain('ng-reflect-dir-prop="hello"'); .toContain('ng-reflect-dir-prop="hello"');
}); });
fixmeIvy('FW-664: ng-reflect-* is not supported') && it(`should work with prop names containing '$'`, () => {
it(`should work with prop names containing '$'`, () => { TestBed.configureTestingModule({declarations: [ParentCmp, SomeCmpWithInput]});
TestBed.configureTestingModule({declarations: [ParentCmp, SomeCmpWithInput]}); const fixture = TestBed.createComponent(ParentCmp);
const fixture = TestBed.createComponent(ParentCmp); fixture.detectChanges();
fixture.detectChanges();
expect(getDOM().getInnerHTML(fixture.nativeElement)) expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('ng-reflect-test_="hello"');
.toContain('ng-reflect-test_="hello"'); });
});
fixmeIvy('FW-664: ng-reflect-* is not supported') && fixmeIvy('FW-664: ng-reflect-* is not supported') &&
it('should reflect property values on template comments', () => { it('should reflect property values on template comments', () => {
@ -1725,16 +1722,15 @@ function declareTests(config?: {useJit: boolean}) {
.toContain('"ng\-reflect\-ng\-if"\: "true"'); .toContain('"ng\-reflect\-ng\-if"\: "true"');
}); });
fixmeIvy('FW-664: ng-reflect-* is not supported') && fixmeIvy('unknown') && it('should indicate when toString() throws', () => {
it('should indicate when toString() throws', () => { TestBed.configureTestingModule({declarations: [MyComp, MyDir]});
TestBed.configureTestingModule({declarations: [MyComp, MyDir]}); const template = '<div my-dir [elprop]="toStringThrow"></div>';
const template = '<div my-dir [elprop]="toStringThrow"></div>'; TestBed.overrideComponent(MyComp, {set: {template}});
TestBed.overrideComponent(MyComp, {set: {template}}); const fixture = TestBed.createComponent(MyComp);
const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('[ERROR]'); expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('[ERROR]');
}); });
}); });
describe('property decorators', () => { describe('property decorators', () => {

View File

@ -239,38 +239,37 @@ import {fixmeIvy} from '@angular/private/testing';
expect(main.nativeElement).toHaveText('P,text'); expect(main.nativeElement).toHaveText('P,text');
}); });
fixmeIvy('FW-665: Unable to find the given context data for the given target') && it('should support moving non projected light dom around', () => {
it('should support moving non projected light dom around', () => { let sourceDirective: ManualViewportDirective = undefined !;
let sourceDirective: ManualViewportDirective = undefined !;
@Directive({selector: '[manual]'}) @Directive({selector: '[manual]'})
class ManualViewportDirective { class ManualViewportDirective {
constructor(public templateRef: TemplateRef<Object>) { sourceDirective = this; } constructor(public templateRef: TemplateRef<Object>) { sourceDirective = this; }
} }
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [Empty, ProjectDirective, ManualViewportDirective]}); {declarations: [Empty, ProjectDirective, ManualViewportDirective]});
TestBed.overrideComponent(MainComp, { TestBed.overrideComponent(MainComp, {
set: { set: {
template: '<empty>' + template: '<empty>' +
' <ng-template manual><div>A</div></ng-template>' + ' <ng-template manual><div>A</div></ng-template>' +
'</empty>' + '</empty>' +
'START(<div project></div>)END' 'START(<div project></div>)END'
} }
}); });
const main = TestBed.createComponent(MainComp); const main = TestBed.createComponent(MainComp);
const projectDirective: ProjectDirective = const projectDirective: ProjectDirective =
main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].injector.get( main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].injector.get(
ProjectDirective); ProjectDirective);
expect(main.nativeElement).toHaveText('START()END'); expect(main.nativeElement).toHaveText('START()END');
projectDirective.show(sourceDirective.templateRef); projectDirective.show(sourceDirective.templateRef);
expect(main.nativeElement).toHaveText('START(A)END'); expect(main.nativeElement).toHaveText('START(A)END');
}); });
fixmeIvy('unknown') && it('should support moving projected light dom around', () => { it('should support moving projected light dom around', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [Empty, ProjectDirective, ManualViewportDirective]}); {declarations: [Empty, ProjectDirective, ManualViewportDirective]});
TestBed.overrideComponent(MainComp, { TestBed.overrideComponent(MainComp, {
@ -330,52 +329,49 @@ import {fixmeIvy} from '@angular/private/testing';
// Note: This does not use a ng-content element, but // Note: This does not use a ng-content element, but
// is still important as we are merging proto views independent of // is still important as we are merging proto views independent of
// the presence of ng-content elements! // the presence of ng-content elements!
fixmeIvy('FW-665: Unable to find the given context data for the given target') && it('should still allow to implement a recursive trees', () => {
it('should still allow to implement a recursive trees', () => { TestBed.configureTestingModule({declarations: [Tree, ManualViewportDirective]});
TestBed.configureTestingModule({declarations: [Tree, ManualViewportDirective]}); TestBed.overrideComponent(MainComp, {set: {template: '<tree></tree>'}});
TestBed.overrideComponent(MainComp, {set: {template: '<tree></tree>'}}); const main = TestBed.createComponent(MainComp);
const main = TestBed.createComponent(MainComp);
main.detectChanges(); main.detectChanges();
const manualDirective: ManualViewportDirective = const manualDirective: ManualViewportDirective =
main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0] main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get(
.injector.get(ManualViewportDirective); ManualViewportDirective);
expect(main.nativeElement).toHaveText('TREE(0:)'); expect(main.nativeElement).toHaveText('TREE(0:)');
manualDirective.show(); manualDirective.show();
main.detectChanges(); main.detectChanges();
expect(main.nativeElement).toHaveText('TREE(0:TREE(1:))'); expect(main.nativeElement).toHaveText('TREE(0:TREE(1:))');
}); });
// Note: This does not use a ng-content element, but // Note: This does not use a ng-content element, but
// is still important as we are merging proto views independent of // is still important as we are merging proto views independent of
// the presence of ng-content elements! // the presence of ng-content elements!
fixmeIvy('FW-665: Unable to find the given context data for the given target') && it('should still allow to implement a recursive trees via multiple components', () => {
it('should still allow to implement a recursive trees via multiple components', () => { TestBed.configureTestingModule({declarations: [Tree, Tree2, ManualViewportDirective]});
TestBed.configureTestingModule({declarations: [Tree, Tree2, ManualViewportDirective]}); TestBed.overrideComponent(MainComp, {set: {template: '<tree></tree>'}});
TestBed.overrideComponent(MainComp, {set: {template: '<tree></tree>'}}); TestBed.overrideComponent(
TestBed.overrideComponent( Tree, {set: {template: 'TREE({{depth}}:<tree2 *manual [depth]="depth+1"></tree2>)'}});
Tree, {set: {template: 'TREE({{depth}}:<tree2 *manual [depth]="depth+1"></tree2>)'}}); const main = TestBed.createComponent(MainComp);
const main = TestBed.createComponent(MainComp);
main.detectChanges(); main.detectChanges();
expect(main.nativeElement).toHaveText('TREE(0:)'); expect(main.nativeElement).toHaveText('TREE(0:)');
const tree = main.debugElement.query(By.directive(Tree)); const tree = main.debugElement.query(By.directive(Tree));
let manualDirective: ManualViewportDirective = tree.queryAllNodes(By.directive( let manualDirective: ManualViewportDirective = tree.queryAllNodes(By.directive(
ManualViewportDirective))[0].injector.get(ManualViewportDirective); ManualViewportDirective))[0].injector.get(ManualViewportDirective);
manualDirective.show(); manualDirective.show();
main.detectChanges(); main.detectChanges();
expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:))'); expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:))');
const tree2 = main.debugElement.query(By.directive(Tree2)); const tree2 = main.debugElement.query(By.directive(Tree2));
manualDirective = manualDirective = tree2.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get(
tree2.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get( ManualViewportDirective);
ManualViewportDirective); manualDirective.show();
manualDirective.show(); main.detectChanges();
main.detectChanges(); expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:TREE(2:)))');
expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:TREE(2:)))'); });
});
if (getDOM().supportsNativeShadowDOM()) { if (getDOM().supportsNativeShadowDOM()) {
it('should support native content projection and isolate styles per component', () => { it('should support native content projection and isolate styles per component', () => {
@ -457,20 +453,19 @@ import {fixmeIvy} from '@angular/private/testing';
expect(main.nativeElement).toHaveText('MAIN(FIRST(SECOND(a)))'); expect(main.nativeElement).toHaveText('MAIN(FIRST(SECOND(a)))');
}); });
fixmeIvy('unknown') && it('should allow to switch the order of nested components via ng-content', () => {
it('should allow to switch the order of nested components via ng-content', () => { TestBed.configureTestingModule({declarations: [CmpA, CmpB, CmpD, CmpC]});
TestBed.configureTestingModule({declarations: [CmpA, CmpB, CmpD, CmpC]}); TestBed.overrideComponent(MainComp, {set: {template: `<cmp-a><cmp-b></cmp-b></cmp-a>`}});
TestBed.overrideComponent(MainComp, {set: {template: `<cmp-a><cmp-b></cmp-b></cmp-a>`}}); const main = TestBed.createComponent(MainComp);
const main = TestBed.createComponent(MainComp);
main.detectChanges(); main.detectChanges();
expect(getDOM().getInnerHTML(main.nativeElement)) expect(getDOM().getInnerHTML(main.nativeElement))
.toEqual( .toEqual(
'<cmp-a><cmp-b><cmp-d><i>cmp-d</i></cmp-d></cmp-b>' + '<cmp-a><cmp-b><cmp-d><i>cmp-d</i></cmp-d></cmp-b>' +
'<cmp-c><b>cmp-c</b></cmp-c></cmp-a>'); '<cmp-c><b>cmp-c</b></cmp-c></cmp-a>');
}); });
fixmeIvy('unknown') && it('should create nested components in the right order', () => { it('should create nested components in the right order', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [CmpA1, CmpA2, CmpB11, CmpB12, CmpB21, CmpB22]}); {declarations: [CmpA1, CmpA2, CmpB11, CmpB12, CmpB21, CmpB22]});
TestBed.overrideComponent(MainComp, {set: {template: `<cmp-a1></cmp-a1><cmp-a2></cmp-a2>`}}); TestBed.overrideComponent(MainComp, {set: {template: `<cmp-a1></cmp-a1><cmp-a2></cmp-a2>`}});