diff --git a/packages/core/test/linker/entry_components_integration_spec.ts b/packages/core/test/linker/entry_components_integration_spec.ts index df69314406..da6520d04b 100644 --- a/packages/core/test/linker/entry_components_integration_spec.ts +++ b/packages/core/test/linker/entry_components_integration_spec.ts @@ -15,10 +15,10 @@ import {fixmeIvy} from '@angular/private/testing'; { if (ivyEnabled) { - fixmeIvy('unknown') && describe('ivy', () => { declareTests(); }); + describe('ivy', () => { declareTests(); }); } else { - fixmeIvy('unknown') && describe('jit', () => { declareTests({useJit: true}); }); - fixmeIvy('unknown') && describe('no jit', () => { declareTests({useJit: false}); }); + describe('jit', () => { declareTests({useJit: true}); }); + describe('no jit', () => { declareTests({useJit: false}); }); } } @@ -71,18 +71,21 @@ function declareTests(config?: {useJit: boolean}) { expect(childComp.cfr.resolveComponentFactory(ChildComp) !.componentType).toBe(ChildComp); }); - it('should not be able to get components from a parent component (content hierarchy)', () => { - TestBed.overrideComponent(MainComp, {set: {template: ''}}); - TestBed.overrideComponent(ChildComp, {set: {template: ''}}); + fixmeIvy('unknown') && + it('should not be able to get components from a parent component (content hierarchy)', + () => { + TestBed.overrideComponent( + MainComp, {set: {template: ''}}); + TestBed.overrideComponent(ChildComp, {set: {template: ''}}); - const compFixture = TestBed.createComponent(MainComp); - const nestedChildCompEl = compFixture.debugElement.children[0].children[0]; - const nestedChildComp: NestedChildComp = nestedChildCompEl.componentInstance; - expect(nestedChildComp.cfr.resolveComponentFactory(ChildComp) !.componentType) - .toBe(ChildComp); - expect(() => nestedChildComp.cfr.resolveComponentFactory(NestedChildComp)) - .toThrow(noComponentFactoryError(NestedChildComp)); - }); + const compFixture = TestBed.createComponent(MainComp); + const nestedChildCompEl = compFixture.debugElement.children[0].children[0]; + const nestedChildComp: NestedChildComp = nestedChildCompEl.componentInstance; + expect(nestedChildComp.cfr.resolveComponentFactory(ChildComp) !.componentType) + .toBe(ChildComp); + expect(() => nestedChildComp.cfr.resolveComponentFactory(NestedChildComp)) + .toThrow(noComponentFactoryError(NestedChildComp)); + }); }); } diff --git a/packages/core/test/linker/integration_spec.ts b/packages/core/test/linker/integration_spec.ts index a086919dc5..ae727978f1 100644 --- a/packages/core/test/linker/integration_spec.ts +++ b/packages/core/test/linker/integration_spec.ts @@ -7,7 +7,6 @@ */ import {CommonModule} from '@angular/common'; -import {CompilerConfig} from '@angular/compiler'; import {Compiler, ComponentFactory, ComponentRef, ErrorHandler, EventEmitter, Host, Inject, Injectable, InjectionToken, Injector, NO_ERRORS_SCHEMA, NgModule, NgModuleRef, OnDestroy, SkipSelf, ViewRef, ɵivyEnabled as ivyEnabled} from '@angular/core'; import {ChangeDetectionStrategy, ChangeDetectorRef, PipeTransform} from '@angular/core/src/change_detection/change_detection'; import {getDebugContext} from '@angular/core/src/errors'; @@ -31,10 +30,10 @@ const ANCHOR_ELEMENT = new InjectionToken('AnchorElement'); { if (ivyEnabled) { - fixmeIvy('unknown') && describe('ivy', () => { declareTests(); }); + describe('ivy', () => { declareTests(); }); } else { - fixmeIvy('unknown') && describe('jit', () => { declareTests({useJit: true}); }); - fixmeIvy('unknown') && describe('no jit', () => { declareTests({useJit: false}); }); + describe('jit', () => { declareTests({useJit: true}); }); + describe('no jit', () => { declareTests({useJit: false}); }); } } @@ -213,7 +212,7 @@ function declareTests(config?: {useJit: boolean}) { .toEqual('Some other
HTML
'); }); - it('should consume binding to className using class alias', () => { + fixmeIvy('unknown') && it('should consume binding to className using class alias', () => { TestBed.configureTestingModule({declarations: [MyComp]}); const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -228,20 +227,21 @@ function declareTests(config?: {useJit: boolean}) { expect(nativeEl).not.toHaveCssClass('initial'); }); - it('should consume binding to htmlFor using for alias', () => { - const template = ''; - const fixture = TestBed.configureTestingModule({declarations: [MyComp]}) - .overrideComponent(MyComp, {set: {template}}) - .createComponent(MyComp); + fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') && + it('should consume binding to htmlFor using for alias', () => { + const template = ''; + const fixture = TestBed.configureTestingModule({declarations: [MyComp]}) + .overrideComponent(MyComp, {set: {template}}) + .createComponent(MyComp); - const nativeEl = fixture.debugElement.children[0].nativeElement; - fixture.debugElement.componentInstance.ctxProp = 'foo'; - fixture.detectChanges(); + const nativeEl = fixture.debugElement.children[0].nativeElement; + fixture.debugElement.componentInstance.ctxProp = 'foo'; + fixture.detectChanges(); - expect(getDOM().getProperty(nativeEl, 'htmlFor')).toBe('foo'); - }); + expect(getDOM().getProperty(nativeEl, 'htmlFor')).toBe('foo'); + }); - it('should consume directive watch expression change.', () => { + fixmeIvy('unknown') && it('should consume directive watch expression change.', () => { TestBed.configureTestingModule({declarations: [MyComp, MyDir]}); const template = '' + '
' + @@ -265,7 +265,7 @@ function declareTests(config?: {useJit: boolean}) { }); describe('pipes', () => { - it('should support pipes in bindings', () => { + fixmeIvy('unknown') && it('should support pipes in bindings', () => { TestBed.configureTestingModule({declarations: [MyComp, MyDir, DoublePipe]}); const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -291,7 +291,7 @@ function declareTests(config?: {useJit: boolean}) { }); // GH issue 328 - https://github.com/angular/angular/issues/328 - it('should support different directive types on a single node', () => { + fixmeIvy('unknown') && it('should support different directive types on a single node', () => { TestBed.configureTestingModule({declarations: [MyComp, ChildComp, MyDir]}); const template = ''; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -350,20 +350,22 @@ function declareTests(config?: {useJit: boolean}) { expect(tc.injector.get(EventDir)).not.toBeNull(); }); - it('should display correct error message for uninitialized @Output', () => { - @Component({selector: 'my-uninitialized-output', template: '

It works!

'}) - class UninitializedOutputComp { - @Output() customEvent !: EventEmitter; - } + fixmeIvy('unknown') && + it('should display correct error message for uninitialized @Output', () => { + @Component({selector: 'my-uninitialized-output', template: '

It works!

'}) + class UninitializedOutputComp { + @Output() customEvent !: EventEmitter; + } - const template = - ''; - TestBed.overrideComponent(MyComp, {set: {template}}); + const template = + ''; + TestBed.overrideComponent(MyComp, {set: {template}}); - TestBed.configureTestingModule({declarations: [MyComp, UninitializedOutputComp]}); - expect(() => TestBed.createComponent(MyComp)) - .toThrowError('@Output customEvent not initialized in \'UninitializedOutputComp\'.'); - }); + TestBed.configureTestingModule({declarations: [MyComp, UninitializedOutputComp]}); + expect(() => TestBed.createComponent(MyComp)) + .toThrowError( + '@Output customEvent not initialized in \'UninitializedOutputComp\'.'); + }); it('should read directives metadata from their binding token', () => { TestBed.configureTestingModule({declarations: [MyComp, PrivateImpl, NeedsPublicApi]}); @@ -372,21 +374,22 @@ function declareTests(config?: {useJit: boolean}) { const fixture = TestBed.createComponent(MyComp); }); - it('should support template directives via `` elements.', () => { - TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]}); - const template = - '{{greeting}}'; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('unknown') && + it('should support template directives via `` elements.', () => { + TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]}); + const template = + '{{greeting}}'; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); + fixture.detectChanges(); - const childNodesOfWrapper = getDOM().childNodes(fixture.nativeElement); - // 1 template + 2 copies. - expect(childNodesOfWrapper.length).toBe(3); - expect(childNodesOfWrapper[1]).toHaveText('hello'); - expect(childNodesOfWrapper[2]).toHaveText('again'); - }); + const childNodesOfWrapper = getDOM().childNodes(fixture.nativeElement); + // 1 template + 2 copies. + expect(childNodesOfWrapper.length).toBe(3); + expect(childNodesOfWrapper[1]).toHaveText('hello'); + expect(childNodesOfWrapper[2]).toHaveText('again'); + }); it('should not share empty context for template directives - issue #10045', () => { TestBed.configureTestingModule({declarations: [MyComp, PollutedContext, NoContext]}); @@ -399,27 +402,28 @@ function declareTests(config?: {useJit: boolean}) { expect(fixture.nativeElement).toHaveText('baz'); }); - it('should not detach views in ViewContainers when the parent view is destroyed.', () => { - TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]}); - const template = - '
{{greeting}}
'; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('unknown') && + it('should not detach views in ViewContainers when the parent view is destroyed.', () => { + TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]}); + const template = + '
{{greeting}}
'; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - fixture.componentInstance.ctxBoolProp = true; - fixture.detectChanges(); + fixture.componentInstance.ctxBoolProp = true; + fixture.detectChanges(); - const ngIfEl = fixture.debugElement.children[0]; - const someViewport: SomeViewport = ngIfEl.childNodes[0].injector.get(SomeViewport); - expect(someViewport.container.length).toBe(2); - expect(ngIfEl.children.length).toBe(2); + const ngIfEl = fixture.debugElement.children[0]; + const someViewport: SomeViewport = ngIfEl.childNodes[0].injector.get(SomeViewport); + expect(someViewport.container.length).toBe(2); + expect(ngIfEl.children.length).toBe(2); - fixture.componentInstance.ctxBoolProp = false; - fixture.detectChanges(); + fixture.componentInstance.ctxBoolProp = false; + fixture.detectChanges(); - expect(someViewport.container.length).toBe(2); - expect(fixture.debugElement.children.length).toBe(0); - }); + expect(someViewport.container.length).toBe(2); + expect(fixture.debugElement.children.length).toBe(0); + }); it('should use a comment while stamping out `` elements.', () => { const fixture = @@ -473,19 +477,20 @@ function declareTests(config?: {useJit: boolean}) { .toBeAnInstanceOf(ExportDir); }); - it('should assign a directive to a ref when it has multiple exportAs names', () => { - TestBed.configureTestingModule( - {declarations: [MyComp, DirectiveWithMultipleExportAsNames]}); + fixmeIvy('unknown') && + it('should assign a directive to a ref when it has multiple exportAs names', () => { + TestBed.configureTestingModule( + {declarations: [MyComp, DirectiveWithMultipleExportAsNames]}); - const template = '
'; - TestBed.overrideComponent(MyComp, {set: {template}}); + const template = '
'; + TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); - expect(fixture.debugElement.children[0].references !['x']) - .toBeAnInstanceOf(DirectiveWithMultipleExportAsNames); - expect(fixture.debugElement.children[0].references !['y']) - .toBeAnInstanceOf(DirectiveWithMultipleExportAsNames); - }); + const fixture = TestBed.createComponent(MyComp); + expect(fixture.debugElement.children[0].references !['x']) + .toBeAnInstanceOf(DirectiveWithMultipleExportAsNames); + expect(fixture.debugElement.children[0].references !['y']) + .toBeAnInstanceOf(DirectiveWithMultipleExportAsNames); + }); it('should make the assigned component accessible in property bindings, even if they were declared before the component', () => { @@ -537,16 +542,17 @@ function declareTests(config?: {useJit: boolean}) { expect(value.tagName.toLowerCase()).toEqual('div'); }); - it('should assign the TemplateRef to a user-defined variable', () => { - const fixture = - TestBed.configureTestingModule({declarations: [MyComp]}) - .overrideComponent( - MyComp, {set: {template: ''}}) - .createComponent(MyComp); + fixmeIvy('unknown') && + it('should assign the TemplateRef to a user-defined variable', () => { + const fixture = + TestBed.configureTestingModule({declarations: [MyComp]}) + .overrideComponent( + MyComp, {set: {template: ''}}) + .createComponent(MyComp); - const value = fixture.debugElement.childNodes[0].references !['alice']; - expect(value.createEmbeddedView).toBeTruthy(); - }); + const value = fixture.debugElement.childNodes[0].references !['alice']; + expect(value.createEmbeddedView).toBeTruthy(); + }); it('should preserve case', () => { TestBed.configureTestingModule({declarations: [MyComp, ChildComp]}); @@ -560,7 +566,7 @@ function declareTests(config?: {useJit: boolean}) { }); describe('variables', () => { - it('should allow to use variables in a for loop', () => { + fixmeIvy('unknown') && it('should allow to use variables in a for loop', () => { const template = '{{i}}-{{cmp.ctxProp}}'; @@ -577,27 +583,28 @@ function declareTests(config?: {useJit: boolean}) { describe('OnPush components', () => { - it('should use ChangeDetectorRef to manually request a check', () => { - TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithRef]]]}); - const template = ''; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('unknown') && + it('should use ChangeDetectorRef to manually request a check', () => { + TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithRef]]]}); + const template = ''; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - const cmp = fixture.debugElement.children[0].references !['cmp']; + const cmp = fixture.debugElement.children[0].references !['cmp']; - fixture.detectChanges(); - expect(cmp.numberOfChecks).toEqual(1); + fixture.detectChanges(); + expect(cmp.numberOfChecks).toEqual(1); - fixture.detectChanges(); - expect(cmp.numberOfChecks).toEqual(1); + fixture.detectChanges(); + expect(cmp.numberOfChecks).toEqual(1); - cmp.propagate(); + cmp.propagate(); - fixture.detectChanges(); - expect(cmp.numberOfChecks).toEqual(2); - }); + fixture.detectChanges(); + expect(cmp.numberOfChecks).toEqual(2); + }); - it('should be checked when its bindings got updated', () => { + fixmeIvy('unknown') && it('should be checked when its bindings got updated', () => { TestBed.configureTestingModule( {declarations: [MyComp, PushCmp, EventCmp], imports: [CommonModule]}); const template = ''; @@ -616,25 +623,27 @@ function declareTests(config?: {useJit: boolean}) { }); if (getDOM().supportsDOMEvents()) { - it('should allow to destroy a component from within a host event handler', - fakeAsync(() => { - TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithHostEvent]]]}); - const template = ''; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('unknown') && + it('should allow to destroy a component from within a host event handler', + fakeAsync(() => { + TestBed.configureTestingModule( + {declarations: [MyComp, [[PushCmpWithHostEvent]]]}); + const template = ''; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - tick(); - fixture.detectChanges(); + tick(); + fixture.detectChanges(); - const cmpEl = fixture.debugElement.children[0]; - const cmp: PushCmpWithHostEvent = cmpEl.injector.get(PushCmpWithHostEvent); - cmp.ctxCallback = (_: any) => fixture.destroy(); + const cmpEl = fixture.debugElement.children[0]; + const cmp: PushCmpWithHostEvent = cmpEl.injector.get(PushCmpWithHostEvent); + cmp.ctxCallback = (_: any) => fixture.destroy(); - expect(() => cmpEl.triggerEventHandler('click', {})).not.toThrow(); - })); + expect(() => cmpEl.triggerEventHandler('click', {})).not.toThrow(); + })); } - it('should be checked when an event is fired', () => { + fixmeIvy('unknown') && it('should be checked when an event is fired', () => { TestBed.configureTestingModule( {declarations: [MyComp, PushCmp, EventCmp], imports: [CommonModule]}); const template = ''; @@ -758,67 +767,71 @@ function declareTests(config?: {useJit: boolean}) { expect(childComponent.myHost).toBeAnInstanceOf(SomeDirective); }); - it('should support events via EventEmitter on regular elements', async(() => { - TestBed.configureTestingModule( - {declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent]}); - const template = '
'; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('unknown') && + it('should support events via EventEmitter on regular elements', async(() => { + TestBed.configureTestingModule( + {declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent]}); + const template = '
'; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - const tc = fixture.debugElement.children[0]; - const emitter = tc.injector.get(DirectiveEmittingEvent); - const listener = tc.injector.get(DirectiveListeningEvent); + const tc = fixture.debugElement.children[0]; + const emitter = tc.injector.get(DirectiveEmittingEvent); + const listener = tc.injector.get(DirectiveListeningEvent); - expect(listener.msg).toEqual(''); - let eventCount = 0; + expect(listener.msg).toEqual(''); + let eventCount = 0; - emitter.event.subscribe({ - next: () => { - eventCount++; - if (eventCount === 1) { - expect(listener.msg).toEqual('fired !'); - fixture.destroy(); - emitter.fireEvent('fired again !'); - } else { - expect(listener.msg).toEqual('fired !'); - } - } - }); + emitter.event.subscribe({ + next: () => { + eventCount++; + if (eventCount === 1) { + expect(listener.msg).toEqual('fired !'); + fixture.destroy(); + emitter.fireEvent('fired again !'); + } else { + expect(listener.msg).toEqual('fired !'); + } + } + }); - emitter.fireEvent('fired !'); - })); + emitter.fireEvent('fired !'); + })); - it('should support events via EventEmitter on template elements', async(() => { - const fixture = - TestBed - .configureTestingModule( - {declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent]}) - .overrideComponent(MyComp, { - set: { - template: - '' - } - }) - .createComponent(MyComp); + fixmeIvy( + 'FW-665: Discovery util fails with Unable to find the given context data for the given target') && + it('should support events via EventEmitter on template elements', async(() => { + const fixture = + TestBed + .configureTestingModule({ + declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent] + }) + .overrideComponent(MyComp, { + set: { + template: + '' + } + }) + .createComponent(MyComp); - const tc = fixture.debugElement.childNodes[0]; + const tc = fixture.debugElement.childNodes[0]; - const emitter = tc.injector.get(DirectiveEmittingEvent); - const myComp = fixture.debugElement.injector.get(MyComp); - const listener = tc.injector.get(DirectiveListeningEvent); + const emitter = tc.injector.get(DirectiveEmittingEvent); + const myComp = fixture.debugElement.injector.get(MyComp); + const listener = tc.injector.get(DirectiveListeningEvent); - myComp.ctxProp = ''; - expect(listener.msg).toEqual(''); + myComp.ctxProp = ''; + expect(listener.msg).toEqual(''); - emitter.event.subscribe({ - next: () => { - expect(listener.msg).toEqual('fired !'); - expect(myComp.ctxProp).toEqual('fired !'); - } - }); + emitter.event.subscribe({ + next: () => { + expect(listener.msg).toEqual('fired !'); + expect(myComp.ctxProp).toEqual('fired !'); + } + }); - emitter.fireEvent('fired !'); - })); + emitter.fireEvent('fired !'); + })); it('should support [()] syntax', async(() => { TestBed.configureTestingModule({declarations: [MyComp, DirectiveWithTwoWayBinding]}); @@ -839,7 +852,7 @@ function declareTests(config?: {useJit: boolean}) { dir.triggerChange('two'); })); - it('should support render events', () => { + fixmeIvy('unknown') && it('should support render events', () => { TestBed.configureTestingModule({declarations: [MyComp, DirectiveListeningDomEvent]}); const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -860,7 +873,7 @@ function declareTests(config?: {useJit: boolean}) { expect(listener.eventTypes).toEqual([]); }); - it('should support render global events', () => { + fixmeIvy('unknown') && it('should support render global events', () => { TestBed.configureTestingModule({declarations: [MyComp, DirectiveListeningDomEvent]}); const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -907,7 +920,7 @@ function declareTests(config?: {useJit: boolean}) { .toEqual('button'); }); - it('should support updating host element via hostProperties', () => { + fixmeIvy('unknown') && it('should support updating host element via hostProperties', () => { TestBed.configureTestingModule({declarations: [MyComp, DirectiveUpdatingHostProperties]}); const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -942,7 +955,7 @@ function declareTests(config?: {useJit: boolean}) { expect(tc.properties['title']).toBe(undefined); }); - it('should not allow pipes in hostProperties', () => { + fixmeIvy('unknown') && it('should not allow pipes in hostProperties', () => { @Directive({selector: '[host-properties]', host: {'[id]': 'id | uppercase'}}) class DirectiveWithHostProps { } @@ -977,7 +990,7 @@ function declareTests(config?: {useJit: boolean}) { expect(dir.receivedArgs).toEqual(['one', undefined]); }); - it('should not allow pipes in hostListeners', () => { + fixmeIvy('unknown') && it('should not allow pipes in hostListeners', () => { @Directive({selector: '[host-listener]', host: {'(click)': 'doIt() | somePipe'}}) class DirectiveWithHostListener { } @@ -1013,41 +1026,43 @@ function declareTests(config?: {useJit: boolean}) { }); } - it('should support render global events from multiple directives', () => { - TestBed.configureTestingModule( - {declarations: [MyComp, DirectiveListeningDomEvent, DirectiveListeningDomEventOther]}); - const template = '
'; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); - const doc = TestBed.get(DOCUMENT); + fixmeIvy('unknown') && + it('should support render global events from multiple directives', () => { + TestBed.configureTestingModule({ + declarations: [MyComp, DirectiveListeningDomEvent, DirectiveListeningDomEventOther] + }); + const template = '
'; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); + const doc = TestBed.get(DOCUMENT); - globalCounter = 0; - fixture.componentInstance.ctxBoolProp = true; - fixture.detectChanges(); + globalCounter = 0; + fixture.componentInstance.ctxBoolProp = true; + fixture.detectChanges(); - const tc = fixture.debugElement.children[0]; + const tc = fixture.debugElement.children[0]; - const listener = tc.injector.get(DirectiveListeningDomEvent); - const listenerother = tc.injector.get(DirectiveListeningDomEventOther); - dispatchEvent(getDOM().getGlobalEventTarget(doc, 'window'), 'domEvent'); - expect(listener.eventTypes).toEqual(['window_domEvent']); - expect(listenerother.eventType).toEqual('other_domEvent'); - expect(globalCounter).toEqual(1); + const listener = tc.injector.get(DirectiveListeningDomEvent); + const listenerother = tc.injector.get(DirectiveListeningDomEventOther); + dispatchEvent(getDOM().getGlobalEventTarget(doc, 'window'), 'domEvent'); + expect(listener.eventTypes).toEqual(['window_domEvent']); + expect(listenerother.eventType).toEqual('other_domEvent'); + expect(globalCounter).toEqual(1); - fixture.componentInstance.ctxBoolProp = false; - fixture.detectChanges(); - dispatchEvent(getDOM().getGlobalEventTarget(doc, 'window'), 'domEvent'); - expect(globalCounter).toEqual(1); + fixture.componentInstance.ctxBoolProp = false; + fixture.detectChanges(); + dispatchEvent(getDOM().getGlobalEventTarget(doc, 'window'), 'domEvent'); + expect(globalCounter).toEqual(1); - fixture.componentInstance.ctxBoolProp = true; - fixture.detectChanges(); - dispatchEvent(getDOM().getGlobalEventTarget(doc, 'window'), 'domEvent'); - expect(globalCounter).toEqual(2); + fixture.componentInstance.ctxBoolProp = true; + fixture.detectChanges(); + dispatchEvent(getDOM().getGlobalEventTarget(doc, 'window'), 'domEvent'); + expect(globalCounter).toEqual(2); - // need to destroy to release all remaining global event listeners - fixture.destroy(); - }); + // need to destroy to release all remaining global event listeners + fixture.destroy(); + }); describe('ViewContainerRef', () => { beforeEach(() => { @@ -1092,161 +1107,168 @@ function declareTests(config?: {useJit: boolean}) { .toHaveText('dynamic greet'); })); - it('should create a component that has been freshly compiled', () => { - @Component({template: ''}) - class RootComp { - constructor(public vc: ViewContainerRef) {} - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should create a component that has been freshly compiled', () => { + @Component({template: ''}) + class RootComp { + constructor(public vc: ViewContainerRef) {} + } - @NgModule({ - declarations: [RootComp], - providers: [{provide: 'someToken', useValue: 'someRootValue'}], - }) - class RootModule { - } + @NgModule({ + declarations: [RootComp], + providers: [{provide: 'someToken', useValue: 'someRootValue'}], + }) + class RootModule { + } - @Component({template: ''}) - class MyComp { - constructor(@Inject('someToken') public someToken: string) {} - } + @Component({template: ''}) + class MyComp { + constructor(@Inject('someToken') public someToken: string) {} + } - @NgModule({ - declarations: [MyComp], - providers: [{provide: 'someToken', useValue: 'someValue'}], - }) - class MyModule { - } + @NgModule({ + declarations: [MyComp], + providers: [{provide: 'someToken', useValue: 'someValue'}], + }) + class MyModule { + } - const compFixture = - TestBed.configureTestingModule({imports: [RootModule]}).createComponent(RootComp); - const compiler = TestBed.get(Compiler); - const myCompFactory = - >compiler.compileModuleAndAllComponentsSync(MyModule) - .componentFactories[0]; + const compFixture = TestBed.configureTestingModule({imports: [RootModule]}) + .createComponent(RootComp); + const compiler = TestBed.get(Compiler); + const myCompFactory = + >compiler.compileModuleAndAllComponentsSync(MyModule) + .componentFactories[0]; - // Note: the ComponentFactory was created directly via the compiler, i.e. it - // does not have an association to an NgModuleRef. - // -> expect the providers of the module that the view container belongs to. - const compRef = compFixture.componentInstance.vc.createComponent(myCompFactory); - expect(compRef.instance.someToken).toBe('someRootValue'); - }); + // Note: the ComponentFactory was created directly via the compiler, i.e. it + // does not have an association to an NgModuleRef. + // -> expect the providers of the module that the view container belongs to. + const compRef = compFixture.componentInstance.vc.createComponent(myCompFactory); + expect(compRef.instance.someToken).toBe('someRootValue'); + }); - it('should create a component with the passed NgModuleRef', () => { - @Component({template: ''}) - class RootComp { - constructor(public vc: ViewContainerRef) {} - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should create a component with the passed NgModuleRef', () => { + @Component({template: ''}) + class RootComp { + constructor(public vc: ViewContainerRef) {} + } - @Component({template: ''}) - class MyComp { - constructor(@Inject('someToken') public someToken: string) {} - } + @Component({template: ''}) + class MyComp { + constructor(@Inject('someToken') public someToken: string) {} + } - @NgModule({ - declarations: [RootComp, MyComp], - entryComponents: [MyComp], - providers: [{provide: 'someToken', useValue: 'someRootValue'}], - }) - class RootModule { - } + @NgModule({ + declarations: [RootComp, MyComp], + entryComponents: [MyComp], + providers: [{provide: 'someToken', useValue: 'someRootValue'}], + }) + class RootModule { + } - @NgModule({providers: [{provide: 'someToken', useValue: 'someValue'}]}) - class MyModule { - } + @NgModule({providers: [{provide: 'someToken', useValue: 'someValue'}]}) + class MyModule { + } - const compFixture = - TestBed.configureTestingModule({imports: [RootModule]}).createComponent(RootComp); - const compiler = TestBed.get(Compiler); - const myModule = compiler.compileModuleSync(MyModule).create(TestBed.get(NgModuleRef)); - const myCompFactory = (TestBed.get(ComponentFactoryResolver)) - .resolveComponentFactory(MyComp); + const compFixture = TestBed.configureTestingModule({imports: [RootModule]}) + .createComponent(RootComp); + const compiler = TestBed.get(Compiler); + const myModule = + compiler.compileModuleSync(MyModule).create(TestBed.get(NgModuleRef)); + const myCompFactory = + (TestBed.get(ComponentFactoryResolver)) + .resolveComponentFactory(MyComp); - // Note: MyComp was declared as entryComponent in the RootModule, - // but we pass MyModule to the createComponent call. - // -> expect the providers of MyModule! - const compRef = compFixture.componentInstance.vc.createComponent( - myCompFactory, undefined, undefined, undefined, myModule); - expect(compRef.instance.someToken).toBe('someValue'); - }); + // Note: MyComp was declared as entryComponent in the RootModule, + // but we pass MyModule to the createComponent call. + // -> expect the providers of MyModule! + const compRef = compFixture.componentInstance.vc.createComponent( + myCompFactory, undefined, undefined, undefined, myModule); + expect(compRef.instance.someToken).toBe('someValue'); + }); - it('should create a component with the NgModuleRef of the ComponentFactoryResolver', - () => { - @Component({template: ''}) - class RootComp { - constructor(public vc: ViewContainerRef) {} - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should create a component with the NgModuleRef of the ComponentFactoryResolver', + () => { + @Component({template: ''}) + class RootComp { + constructor(public vc: ViewContainerRef) {} + } - @NgModule({ - declarations: [RootComp], - providers: [{provide: 'someToken', useValue: 'someRootValue'}], - }) - class RootModule { - } + @NgModule({ + declarations: [RootComp], + providers: [{provide: 'someToken', useValue: 'someRootValue'}], + }) + class RootModule { + } - @Component({template: ''}) - class MyComp { - constructor(@Inject('someToken') public someToken: string) {} - } + @Component({template: ''}) + class MyComp { + constructor(@Inject('someToken') public someToken: string) {} + } - @NgModule({ - declarations: [MyComp], - entryComponents: [MyComp], - providers: [{provide: 'someToken', useValue: 'someValue'}], - }) - class MyModule { - } + @NgModule({ + declarations: [MyComp], + entryComponents: [MyComp], + providers: [{provide: 'someToken', useValue: 'someValue'}], + }) + class MyModule { + } - const compFixture = TestBed.configureTestingModule({imports: [RootModule]}) - .createComponent(RootComp); - const compiler = TestBed.get(Compiler); - const myModule = - compiler.compileModuleSync(MyModule).create(TestBed.get(NgModuleRef)); - const myCompFactory = - myModule.componentFactoryResolver.resolveComponentFactory(MyComp); + const compFixture = TestBed.configureTestingModule({imports: [RootModule]}) + .createComponent(RootComp); + const compiler = TestBed.get(Compiler); + const myModule = + compiler.compileModuleSync(MyModule).create(TestBed.get(NgModuleRef)); + const myCompFactory = + myModule.componentFactoryResolver.resolveComponentFactory(MyComp); - // Note: MyComp was declared as entryComponent in MyModule, - // and we don't pass an explicit ModuleRef to the createComponent call. - // -> expect the providers of MyModule! - const compRef = compFixture.componentInstance.vc.createComponent(myCompFactory); - expect(compRef.instance.someToken).toBe('someValue'); - }); + // Note: MyComp was declared as entryComponent in MyModule, + // and we don't pass an explicit ModuleRef to the createComponent call. + // -> expect the providers of MyModule! + const compRef = compFixture.componentInstance.vc.createComponent(myCompFactory); + expect(compRef.instance.someToken).toBe('someValue'); + }); }); describe('.insert', () => { - it('should throw with destroyed views', async(() => { - const fixture = TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}) - .createComponent(MyComp); - const tc = fixture.debugElement.children[0].children[0]; - const dynamicVp: DynamicViewport = tc.injector.get(DynamicViewport); - const ref = dynamicVp.create(); - fixture.detectChanges(); + fixmeIvy('unknown') && + it('should throw with destroyed views', async(() => { + const fixture = TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}) + .createComponent(MyComp); + const tc = fixture.debugElement.children[0].children[0]; + const dynamicVp: DynamicViewport = tc.injector.get(DynamicViewport); + const ref = dynamicVp.create(); + fixture.detectChanges(); - ref.destroy(); - expect(() => { - dynamicVp.insert(ref.hostView); - }).toThrowError('Cannot insert a destroyed View in a ViewContainer!'); - })); + ref.destroy(); + expect(() => { + dynamicVp.insert(ref.hostView); + }).toThrowError('Cannot insert a destroyed View in a ViewContainer!'); + })); }); describe('.move', () => { - it('should throw with destroyed views', async(() => { - const fixture = TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}) - .createComponent(MyComp); - const tc = fixture.debugElement.children[0].children[0]; - const dynamicVp: DynamicViewport = tc.injector.get(DynamicViewport); - const ref = dynamicVp.create(); - fixture.detectChanges(); + fixmeIvy('unknown') && + it('should throw with destroyed views', async(() => { + const fixture = TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}) + .createComponent(MyComp); + const tc = fixture.debugElement.children[0].children[0]; + const dynamicVp: DynamicViewport = tc.injector.get(DynamicViewport); + const ref = dynamicVp.create(); + fixture.detectChanges(); - ref.destroy(); - expect(() => { - dynamicVp.move(ref.hostView, 1); - }).toThrowError('Cannot move a destroyed View in a ViewContainer!'); - })); + ref.destroy(); + expect(() => { + dynamicVp.move(ref.hostView, 1); + }).toThrowError('Cannot move a destroyed View in a ViewContainer!'); + })); }); }); - it('should support static attributes', () => { + fixmeIvy('unknown') && it('should support static attributes', () => { TestBed.configureTestingModule({declarations: [MyComp, NeedsAttribute]}); const template = ''; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -1259,7 +1281,7 @@ function declareTests(config?: {useJit: boolean}) { expect(needsAttribute.fooAttribute).toBeNull(); }); - it('should support custom interpolation', () => { + fixmeIvy('unknown') && it('should support custom interpolation', () => { TestBed.configureTestingModule({ declarations: [ MyComp, ComponentWithCustomInterpolationA, ComponentWithCustomInterpolationB, @@ -1300,7 +1322,7 @@ function declareTests(config?: {useJit: boolean}) { expect(comp.injectable).toBeAnInstanceOf(InjectableService); }); - it('should support viewProviders', () => { + fixmeIvy('unknown') && it('should support viewProviders', () => { TestBed.configureTestingModule({ declarations: [MyComp, DirectiveProvidingInjectableInView, DirectiveConsumingInjectable], schemas: [NO_ERRORS_SCHEMA], @@ -1412,121 +1434,131 @@ function declareTests(config?: {useJit: boolean}) { expect(getDOM().querySelectorAll(fixture.nativeElement, 'script').length).toEqual(0); }); - it('should throw when using directives without selector', () => { - @Directive({}) - class SomeDirective { - } + fixmeIvy('FW-662: Components without selector are not supported') && + it('should throw when using directives without selector', () => { + @Directive({}) + class SomeDirective { + } - @Component({selector: 'comp', template: ''}) - class SomeComponent { - } + @Component({selector: 'comp', template: ''}) + class SomeComponent { + } - TestBed.configureTestingModule({declarations: [MyComp, SomeDirective, SomeComponent]}); - expect(() => TestBed.createComponent(MyComp)) - .toThrowError(`Directive ${stringify(SomeDirective)} has no selector, please add it!`); - }); + TestBed.configureTestingModule({declarations: [MyComp, SomeDirective, SomeComponent]}); + expect(() => TestBed.createComponent(MyComp)) + .toThrowError( + `Directive ${stringify(SomeDirective)} has no selector, please add it!`); + }); - it('should use a default element name for components without selectors', () => { - let noSelectorComponentFactory: ComponentFactory = undefined !; + fixmeIvy('FW-662: Components without selector are not supported') && + it('should use a default element name for components without selectors', () => { + let noSelectorComponentFactory: ComponentFactory = undefined !; - @Component({template: '----'}) - class NoSelectorComponent { - } + @Component({template: '----'}) + class NoSelectorComponent { + } - @Component({selector: 'some-comp', template: '', entryComponents: [NoSelectorComponent]}) - class SomeComponent { - constructor(componentFactoryResolver: ComponentFactoryResolver) { - // grab its own component factory - noSelectorComponentFactory = - componentFactoryResolver.resolveComponentFactory(NoSelectorComponent) !; - } - } + @Component( + {selector: 'some-comp', template: '', entryComponents: [NoSelectorComponent]}) + class SomeComponent { + constructor(componentFactoryResolver: ComponentFactoryResolver) { + // grab its own component factory + noSelectorComponentFactory = + componentFactoryResolver.resolveComponentFactory(NoSelectorComponent) !; + } + } - TestBed.configureTestingModule({declarations: [SomeComponent, NoSelectorComponent]}); + TestBed.configureTestingModule({declarations: [SomeComponent, NoSelectorComponent]}); - // get the factory - TestBed.createComponent(SomeComponent); + // get the factory + TestBed.createComponent(SomeComponent); - expect(noSelectorComponentFactory.selector).toBe('ng-component'); + expect(noSelectorComponentFactory.selector).toBe('ng-component'); - expect( - getDOM() - .nodeName(noSelectorComponentFactory.create(Injector.NULL).location.nativeElement) - .toLowerCase()) - .toEqual('ng-component'); - }); + expect(getDOM() + .nodeName( + noSelectorComponentFactory.create(Injector.NULL).location.nativeElement) + .toLowerCase()) + .toEqual('ng-component'); + }); }); describe('error handling', () => { - it('should report a meaningful error when a directive is missing annotation', () => { - TestBed.configureTestingModule({declarations: [MyComp, SomeDirectiveMissingAnnotation]}); + fixmeIvy('unknown') && + it('should report a meaningful error when a directive is missing annotation', () => { + TestBed.configureTestingModule( + {declarations: [MyComp, SomeDirectiveMissingAnnotation]}); - expect(() => TestBed.createComponent(MyComp)) - .toThrowError( - `Unexpected value '${stringify(SomeDirectiveMissingAnnotation)}' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.`); - }); + expect(() => TestBed.createComponent(MyComp)) + .toThrowError( + `Unexpected value '${stringify(SomeDirectiveMissingAnnotation)}' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.`); + }); - it('should report a meaningful error when a component is missing view annotation', () => { - TestBed.configureTestingModule({declarations: [MyComp, ComponentWithoutView]}); - try { - TestBed.createComponent(ComponentWithoutView); - expect(true).toBe(false); - } catch (e) { - expect(e.message).toContain( - `No template specified for component ${stringify(ComponentWithoutView)}`); - } - }); + fixmeIvy('unknown') && + it('should report a meaningful error when a component is missing view annotation', () => { + TestBed.configureTestingModule({declarations: [MyComp, ComponentWithoutView]}); + try { + TestBed.createComponent(ComponentWithoutView); + expect(true).toBe(false); + } catch (e) { + expect(e.message).toContain( + `No template specified for component ${stringify(ComponentWithoutView)}`); + } + }); - it('should provide an error context when an error happens in DI', () => { - TestBed.configureTestingModule({ - declarations: [MyComp, DirectiveThrowingAnError], - schemas: [NO_ERRORS_SCHEMA], - }); - const template = ``; - TestBed.overrideComponent(MyComp, {set: {template}}); + fixmeIvy('unknown') && + it('should provide an error context when an error happens in DI', () => { + TestBed.configureTestingModule({ + declarations: [MyComp, DirectiveThrowingAnError], + schemas: [NO_ERRORS_SCHEMA], + }); + const template = ``; + TestBed.overrideComponent(MyComp, {set: {template}}); - try { - TestBed.createComponent(MyComp); - throw 'Should throw'; - } catch (e) { - const c = getDebugContext(e); - expect(getDOM().nodeName(c.componentRenderElement).toUpperCase()).toEqual('DIV'); - expect((c.injector).get).toBeTruthy(); - } - }); + try { + TestBed.createComponent(MyComp); + throw 'Should throw'; + } catch (e) { + const c = getDebugContext(e); + expect(getDOM().nodeName(c.componentRenderElement).toUpperCase()).toEqual('DIV'); + expect((c.injector).get).toBeTruthy(); + } + }); - it('should provide an error context when an error happens in change detection', () => { - TestBed.configureTestingModule({declarations: [MyComp, DirectiveThrowingAnError]}); - const template = ``; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); - try { - fixture.detectChanges(); - throw 'Should throw'; - } catch (e) { - const c = getDebugContext(e); - expect(getDOM().nodeName(c.renderNode).toUpperCase()).toEqual('INPUT'); - expect(getDOM().nodeName(c.componentRenderElement).toUpperCase()).toEqual('DIV'); - expect((c.injector).get).toBeTruthy(); - expect(c.context).toBe(fixture.componentInstance); - expect(c.references['local']).toBeDefined(); - } - }); + fixmeIvy('unknown') && + it('should provide an error context when an error happens in change detection', () => { + TestBed.configureTestingModule({declarations: [MyComp, DirectiveThrowingAnError]}); + const template = ``; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); + try { + fixture.detectChanges(); + throw 'Should throw'; + } catch (e) { + const c = getDebugContext(e); + expect(getDOM().nodeName(c.renderNode).toUpperCase()).toEqual('INPUT'); + expect(getDOM().nodeName(c.componentRenderElement).toUpperCase()).toEqual('DIV'); + expect((c.injector).get).toBeTruthy(); + expect(c.context).toBe(fixture.componentInstance); + expect(c.references['local']).toBeDefined(); + } + }); - it('should provide an error context when an error happens in change detection (text node)', - () => { - TestBed.configureTestingModule({declarations: [MyComp]}); - const template = `
{{one.two.three}}
`; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); - try { - fixture.detectChanges(); - throw 'Should throw'; - } catch (e) { - const c = getDebugContext(e); - expect(c.renderNode).toBeTruthy(); - } - }); + fixmeIvy('unknown') && + it('should provide an error context when an error happens in change detection (text node)', + () => { + TestBed.configureTestingModule({declarations: [MyComp]}); + const template = `
{{one.two.three}}
`; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); + try { + fixture.detectChanges(); + throw 'Should throw'; + } catch (e) { + const c = getDebugContext(e); + expect(c.renderNode).toBeTruthy(); + } + }); if (getDOM().supportsDOMEvents()) { // this is required to use fakeAsync it('should provide an error context when an error happens in an event handler', @@ -1591,7 +1623,7 @@ function declareTests(config?: {useJit: boolean}) { }); describe('Property bindings', () => { - it('should throw on bindings to unknown properties', () => { + fixmeIvy('unknown') && it('should throw on bindings to unknown properties', () => { TestBed.configureTestingModule({declarations: [MyComp]}); const template = '
'; TestBed.overrideComponent(MyComp, {set: {template}}); @@ -1625,67 +1657,75 @@ function declareTests(config?: {useJit: boolean}) { expect(el.title).toBeFalsy(); }); - it('should work when a directive uses hostProperty to update the DOM element', () => { - TestBed.configureTestingModule({declarations: [MyComp, DirectiveWithTitleAndHostProperty]}); - const template = ''; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('unknown') && + it('should work when a directive uses hostProperty to update the DOM element', () => { + TestBed.configureTestingModule( + {declarations: [MyComp, DirectiveWithTitleAndHostProperty]}); + const template = ''; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - fixture.componentInstance.ctxProp = 'TITLE'; - fixture.detectChanges(); + fixture.componentInstance.ctxProp = 'TITLE'; + fixture.detectChanges(); - const el = getDOM().querySelector(fixture.nativeElement, 'span'); - expect(getDOM().getProperty(el, 'title')).toEqual('TITLE'); - }); + const el = getDOM().querySelector(fixture.nativeElement, 'span'); + expect(getDOM().getProperty(el, 'title')).toEqual('TITLE'); + }); }); describe('logging property updates', () => { - it('should reflect property values as attributes', () => { - TestBed.configureTestingModule({declarations: [MyComp, MyDir]}); - const template = '
' + - '
' + - '
'; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('FW-664: ng-reflect-* is not supported') && + it('should reflect property values as attributes', () => { + TestBed.configureTestingModule({declarations: [MyComp, MyDir]}); + const template = '
' + + '
' + + '
'; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - fixture.componentInstance.ctxProp = 'hello'; - fixture.detectChanges(); + fixture.componentInstance.ctxProp = 'hello'; + fixture.detectChanges(); - expect(getDOM().getInnerHTML(fixture.nativeElement)) - .toContain('ng-reflect-dir-prop="hello"'); - }); + expect(getDOM().getInnerHTML(fixture.nativeElement)) + .toContain('ng-reflect-dir-prop="hello"'); + }); - it(`should work with prop names containing '$'`, () => { - TestBed.configureTestingModule({declarations: [ParentCmp, SomeCmpWithInput]}); - const fixture = TestBed.createComponent(ParentCmp); - fixture.detectChanges(); + fixmeIvy('FW-664: ng-reflect-* is not supported') && + it(`should work with prop names containing '$'`, () => { + TestBed.configureTestingModule({declarations: [ParentCmp, SomeCmpWithInput]}); + const fixture = TestBed.createComponent(ParentCmp); + fixture.detectChanges(); - expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('ng-reflect-test_="hello"'); - }); + expect(getDOM().getInnerHTML(fixture.nativeElement)) + .toContain('ng-reflect-test_="hello"'); + }); - it('should reflect property values on template comments', () => { - const fixture = - TestBed.configureTestingModule({declarations: [MyComp]}) - .overrideComponent( - MyComp, {set: {template: ''}}) - .createComponent(MyComp); + fixmeIvy('FW-664: ng-reflect-* is not supported') && + it('should reflect property values on template comments', () => { + const fixture = + TestBed.configureTestingModule({declarations: [MyComp]}) + .overrideComponent( + MyComp, + {set: {template: ''}}) + .createComponent(MyComp); - fixture.componentInstance.ctxBoolProp = true; - fixture.detectChanges(); + fixture.componentInstance.ctxBoolProp = true; + fixture.detectChanges(); - expect(getDOM().getInnerHTML(fixture.nativeElement)) - .toContain('"ng\-reflect\-ng\-if"\: "true"'); - }); + expect(getDOM().getInnerHTML(fixture.nativeElement)) + .toContain('"ng\-reflect\-ng\-if"\: "true"'); + }); - it('should indicate when toString() throws', () => { - TestBed.configureTestingModule({declarations: [MyComp, MyDir]}); - const template = '
'; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('FW-664: ng-reflect-* is not supported') && + it('should indicate when toString() throws', () => { + TestBed.configureTestingModule({declarations: [MyComp, MyDir]}); + const template = '
'; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); - expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('[ERROR]'); - }); + fixture.detectChanges(); + expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('[ERROR]'); + }); }); describe('property decorators', () => { diff --git a/packages/core/test/linker/jit_summaries_integration_spec.ts b/packages/core/test/linker/jit_summaries_integration_spec.ts index e052d5f46a..bebe685ff7 100644 --- a/packages/core/test/linker/jit_summaries_integration_spec.ts +++ b/packages/core/test/linker/jit_summaries_integration_spec.ts @@ -15,7 +15,8 @@ import {expect} from '@angular/platform-browser/testing/src/matchers'; import {fixmeIvy} from '@angular/private/testing'; { - fixmeIvy('unknown') && describe('Jit Summaries', () => { + // ivy fix in https://github.com/angular/angular/pull/26871 + fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && describe('Jit Summaries', () => { let instances: Map; let summaries: () => any[]; diff --git a/packages/core/test/linker/ng_container_integration_spec.ts b/packages/core/test/linker/ng_container_integration_spec.ts index 3149bb2eea..890a63e7ff 100644 --- a/packages/core/test/linker/ng_container_integration_spec.ts +++ b/packages/core/test/linker/ng_container_integration_spec.ts @@ -15,10 +15,10 @@ import {fixmeIvy} from '@angular/private/testing'; { if (ivyEnabled) { - fixmeIvy('unknown') && describe('ivy', () => { declareTests(); }); + describe('ivy', () => { declareTests(); }); } else { - fixmeIvy('unknown') && describe('jit', () => { declareTests({useJit: true}); }); - fixmeIvy('unknown') && describe('no jit', () => { declareTests({useJit: false}); }); + describe('jit', () => { declareTests({useJit: true}); }); + describe('no jit', () => { declareTests({useJit: false}); }); } } @@ -38,74 +38,78 @@ function declareTests(config?: {useJit: boolean}) { }); }); - it('should support the "i18n" attribute', () => { - const template = 'foo'; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('FW-663: ReferenceError: goog is not defined') && + it('should support the "i18n" attribute', () => { + const template = 'foo'; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); + fixture.detectChanges(); - const el = fixture.nativeElement; - expect(el).toHaveText('foo'); - }); + const el = fixture.nativeElement; + expect(el).toHaveText('foo'); + }); - it('should be rendered as comment with children as siblings', () => { - const template = '

'; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('FW-678: ivy generates different DOM structure for ') && + it('should be rendered as comment with children as siblings', () => { + const template = '

'; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); + fixture.detectChanges(); - const el = fixture.nativeElement; - const children = getDOM().childNodes(el); - expect(children.length).toBe(2); - expect(getDOM().isCommentNode(children[0])).toBe(true); - expect(getDOM().tagName(children[1]).toUpperCase()).toEqual('P'); - }); + const el = fixture.nativeElement; + const children = getDOM().childNodes(el); + expect(children.length).toBe(2); + expect(getDOM().isCommentNode(children[0])).toBe(true); + expect(getDOM().tagName(children[1]).toUpperCase()).toEqual('P'); + }); - it('should support nesting', () => { - const template = - '12'; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('FW-678: ivy generates different DOM structure for ') && + it('should support nesting', () => { + const template = + '12'; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); + fixture.detectChanges(); - const el = fixture.nativeElement; - const children = getDOM().childNodes(el); - expect(children.length).toBe(5); - expect(getDOM().isCommentNode(children[0])).toBe(true); - expect(children[1]).toHaveText('1'); - expect(getDOM().isCommentNode(children[2])).toBe(true); - expect(getDOM().isCommentNode(children[3])).toBe(true); - expect(children[4]).toHaveText('2'); - }); + const el = fixture.nativeElement; + const children = getDOM().childNodes(el); + expect(children.length).toBe(5); + expect(getDOM().isCommentNode(children[0])).toBe(true); + expect(children[1]).toHaveText('1'); + expect(getDOM().isCommentNode(children[2])).toBe(true); + expect(getDOM().isCommentNode(children[3])).toBe(true); + expect(children[4]).toHaveText('2'); + }); - it('should group inner nodes', () => { - const template = '

'; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('FW-678: ivy generates different DOM structure for ') && + it('should group inner nodes', () => { + const template = '

'; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - fixture.componentInstance.ctxBoolProp = true; - fixture.detectChanges(); + fixture.componentInstance.ctxBoolProp = true; + fixture.detectChanges(); - const el = fixture.nativeElement; - const children = getDOM().childNodes(el); + const el = fixture.nativeElement; + const children = getDOM().childNodes(el); - expect(children.length).toBe(4); - // ngIf anchor - expect(getDOM().isCommentNode(children[0])).toBe(true); - // ng-container anchor - expect(getDOM().isCommentNode(children[1])).toBe(true); - expect(getDOM().tagName(children[2]).toUpperCase()).toEqual('P'); - expect(getDOM().tagName(children[3]).toUpperCase()).toEqual('B'); + expect(children.length).toBe(4); + // ngIf anchor + expect(getDOM().isCommentNode(children[0])).toBe(true); + // ng-container anchor + expect(getDOM().isCommentNode(children[1])).toBe(true); + expect(getDOM().tagName(children[2]).toUpperCase()).toEqual('P'); + expect(getDOM().tagName(children[3]).toUpperCase()).toEqual('B'); - fixture.componentInstance.ctxBoolProp = false; - fixture.detectChanges(); + fixture.componentInstance.ctxBoolProp = false; + fixture.detectChanges(); - expect(children.length).toBe(1); - expect(getDOM().isCommentNode(children[0])).toBe(true); - }); + expect(children.length).toBe(1); + expect(getDOM().isCommentNode(children[0])).toBe(true); + }); it('should work with static content projection', () => { const template = `

1

2

`; @@ -130,19 +134,20 @@ function declareTests(config?: {useJit: boolean}) { expect(dir.text).toEqual('container'); }); - it('should contain all direct child directives in a (content dom)', () => { - const template = - '
'; - TestBed.overrideComponent(MyComp, {set: {template}}); - const fixture = TestBed.createComponent(MyComp); + fixmeIvy('unknown') && + it('should contain all direct child directives in a (content dom)', () => { + const template = + '
'; + TestBed.overrideComponent(MyComp, {set: {template}}); + const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); - const q = fixture.debugElement.children[0].references !['q']; - fixture.detectChanges(); + fixture.detectChanges(); + const q = fixture.debugElement.children[0].references !['q']; + fixture.detectChanges(); - expect(q.textDirChildren.length).toEqual(1); - expect(q.numberOfChildrenAfterContentInit).toEqual(1); - }); + expect(q.textDirChildren.length).toEqual(1); + expect(q.numberOfChildrenAfterContentInit).toEqual(1); + }); it('should contain all child directives in a (view dom)', () => { const template = ''; diff --git a/packages/core/test/linker/ng_module_integration_spec.ts b/packages/core/test/linker/ng_module_integration_spec.ts index 46cfdba52d..4ae6555c26 100644 --- a/packages/core/test/linker/ng_module_integration_spec.ts +++ b/packages/core/test/linker/ng_module_integration_spec.ts @@ -100,11 +100,10 @@ class DummyConsole implements Console { { if (ivyEnabled) { - fixmeIvy('unknown') && describe('ivy', () => { declareTests(); }); + describe('ivy', () => { declareTests(); }); } else { - fixmeIvy('unknown') && describe('jit', () => { declareTests({useJit: true}); }); - - fixmeIvy('unknown') && describe('no jit', () => { declareTests({useJit: false}); }); + describe('jit', () => { declareTests({useJit: true}); }); + describe('no jit', () => { declareTests({useJit: false}); }); } } @@ -144,124 +143,134 @@ function declareTests(config?: {useJit: boolean}) { } describe('errors', () => { - it('should error when exporting a directive that was neither declared nor imported', () => { - @NgModule({exports: [SomeDirective]}) - class SomeModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should error when exporting a directive that was neither declared nor imported', () => { + @NgModule({exports: [SomeDirective]}) + class SomeModule { + } - expect(() => createModule(SomeModule)) - .toThrowError( - `Can't export directive ${stringify(SomeDirective)} from ${stringify(SomeModule)} as it was neither declared nor imported!`); - }); + expect(() => createModule(SomeModule)) + .toThrowError( + `Can't export directive ${stringify(SomeDirective)} from ${stringify(SomeModule)} as it was neither declared nor imported!`); + }); - it('should error when exporting a pipe that was neither declared nor imported', () => { - @NgModule({exports: [SomePipe]}) - class SomeModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should error when exporting a pipe that was neither declared nor imported', () => { + @NgModule({exports: [SomePipe]}) + class SomeModule { + } - expect(() => createModule(SomeModule)) - .toThrowError( - `Can't export pipe ${stringify(SomePipe)} from ${stringify(SomeModule)} as it was neither declared nor imported!`); - }); + expect(() => createModule(SomeModule)) + .toThrowError( + `Can't export pipe ${stringify(SomePipe)} from ${stringify(SomeModule)} as it was neither declared nor imported!`); + }); - it('should error if a directive is declared in more than 1 module', () => { - @NgModule({declarations: [SomeDirective]}) - class Module1 { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should error if a directive is declared in more than 1 module', () => { + @NgModule({declarations: [SomeDirective]}) + class Module1 { + } - @NgModule({declarations: [SomeDirective]}) - class Module2 { - } + @NgModule({declarations: [SomeDirective]}) + class Module2 { + } - createModule(Module1); + createModule(Module1); - expect(() => createModule(Module2)) - .toThrowError( - `Type ${stringify(SomeDirective)} is part of the declarations of 2 modules: ${stringify(Module1)} and ${stringify(Module2)}! ` + - `Please consider moving ${stringify(SomeDirective)} to a higher module that imports ${stringify(Module1)} and ${stringify(Module2)}. ` + - `You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`); - }); + expect(() => createModule(Module2)) + .toThrowError( + `Type ${stringify(SomeDirective)} is part of the declarations of 2 modules: ${stringify(Module1)} and ${stringify(Module2)}! ` + + `Please consider moving ${stringify(SomeDirective)} to a higher module that imports ${stringify(Module1)} and ${stringify(Module2)}. ` + + `You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`); + }); - it('should error if a directive is declared in more than 1 module also if the module declaring it is imported', - () => { - @NgModule({declarations: [SomeDirective], exports: [SomeDirective]}) - class Module1 { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should error if a directive is declared in more than 1 module also if the module declaring it is imported', + () => { + @NgModule({declarations: [SomeDirective], exports: [SomeDirective]}) + class Module1 { + } - @NgModule({declarations: [SomeDirective], imports: [Module1]}) - class Module2 { - } + @NgModule({declarations: [SomeDirective], imports: [Module1]}) + class Module2 { + } - expect(() => createModule(Module2)) - .toThrowError( - `Type ${stringify(SomeDirective)} is part of the declarations of 2 modules: ${stringify(Module1)} and ${stringify(Module2)}! ` + - `Please consider moving ${stringify(SomeDirective)} to a higher module that imports ${stringify(Module1)} and ${stringify(Module2)}. ` + - `You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`); - }); + expect(() => createModule(Module2)) + .toThrowError( + `Type ${stringify(SomeDirective)} is part of the declarations of 2 modules: ${stringify(Module1)} and ${stringify(Module2)}! ` + + `Please consider moving ${stringify(SomeDirective)} to a higher module that imports ${stringify(Module1)} and ${stringify(Module2)}. ` + + `You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`); + }); - it('should error if a pipe is declared in more than 1 module', () => { - @NgModule({declarations: [SomePipe]}) - class Module1 { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should error if a pipe is declared in more than 1 module', () => { + @NgModule({declarations: [SomePipe]}) + class Module1 { + } - @NgModule({declarations: [SomePipe]}) - class Module2 { - } + @NgModule({declarations: [SomePipe]}) + class Module2 { + } - createModule(Module1); + createModule(Module1); - expect(() => createModule(Module2)) - .toThrowError( - `Type ${stringify(SomePipe)} is part of the declarations of 2 modules: ${stringify(Module1)} and ${stringify(Module2)}! ` + - `Please consider moving ${stringify(SomePipe)} to a higher module that imports ${stringify(Module1)} and ${stringify(Module2)}. ` + - `You can also create a new NgModule that exports and includes ${stringify(SomePipe)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`); - }); + expect(() => createModule(Module2)) + .toThrowError( + `Type ${stringify(SomePipe)} is part of the declarations of 2 modules: ${stringify(Module1)} and ${stringify(Module2)}! ` + + `Please consider moving ${stringify(SomePipe)} to a higher module that imports ${stringify(Module1)} and ${stringify(Module2)}. ` + + `You can also create a new NgModule that exports and includes ${stringify(SomePipe)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`); + }); - it('should error if a pipe is declared in more than 1 module also if the module declaring it is imported', - () => { - @NgModule({declarations: [SomePipe], exports: [SomePipe]}) - class Module1 { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should error if a pipe is declared in more than 1 module also if the module declaring it is imported', + () => { + @NgModule({declarations: [SomePipe], exports: [SomePipe]}) + class Module1 { + } - @NgModule({declarations: [SomePipe], imports: [Module1]}) - class Module2 { - } + @NgModule({declarations: [SomePipe], imports: [Module1]}) + class Module2 { + } - expect(() => createModule(Module2)) - .toThrowError( - `Type ${stringify(SomePipe)} is part of the declarations of 2 modules: ${stringify(Module1)} and ${stringify(Module2)}! ` + - `Please consider moving ${stringify(SomePipe)} to a higher module that imports ${stringify(Module1)} and ${stringify(Module2)}. ` + - `You can also create a new NgModule that exports and includes ${stringify(SomePipe)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`); - }); + expect(() => createModule(Module2)) + .toThrowError( + `Type ${stringify(SomePipe)} is part of the declarations of 2 modules: ${stringify(Module1)} and ${stringify(Module2)}! ` + + `Please consider moving ${stringify(SomePipe)} to a higher module that imports ${stringify(Module1)} and ${stringify(Module2)}. ` + + `You can also create a new NgModule that exports and includes ${stringify(SomePipe)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`); + }); }); describe('schemas', () => { - it('should error on unknown bound properties on custom elements by default', () => { - @Component({template: ''}) - class ComponentUsingInvalidProperty { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should error on unknown bound properties on custom elements by default', () => { + @Component({template: ''}) + class ComponentUsingInvalidProperty { + } - @NgModule({declarations: [ComponentUsingInvalidProperty]}) - class SomeModule { - } + @NgModule({declarations: [ComponentUsingInvalidProperty]}) + class SomeModule { + } - expect(() => createModule(SomeModule)).toThrowError(/Can't bind to 'someUnknownProp'/); - }); + expect(() => createModule(SomeModule)).toThrowError(/Can't bind to 'someUnknownProp'/); + }); - it('should not error on unknown bound properties on custom elements when using the CUSTOM_ELEMENTS_SCHEMA', - () => { - @Component({template: ''}) - class ComponentUsingInvalidProperty { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should not error on unknown bound properties on custom elements when using the CUSTOM_ELEMENTS_SCHEMA', + () => { + @Component({template: ''}) + class ComponentUsingInvalidProperty { + } - @NgModule( - {schemas: [CUSTOM_ELEMENTS_SCHEMA], declarations: [ComponentUsingInvalidProperty]}) - class SomeModule { - } + @NgModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [ComponentUsingInvalidProperty] + }) + class SomeModule { + } - expect(() => createModule(SomeModule)).not.toThrow(); - }); + expect(() => createModule(SomeModule)).not.toThrow(); + }); }); describe('id', () => { @@ -275,332 +284,361 @@ function declareTests(config?: {useJit: boolean}) { afterEach(() => clearModulesForTest()); - it('should register loaded modules', () => { - createModule(SomeModule); - const factory = getModuleFactory(token); - expect(factory).toBeTruthy(); - expect(factory.moduleType).toBe(SomeModule); - }); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should register loaded modules', () => { + createModule(SomeModule); + const factory = getModuleFactory(token); + expect(factory).toBeTruthy(); + expect(factory.moduleType).toBe(SomeModule); + }); - it('should throw when registering a duplicate module', () => { - createModule(SomeModule); - expect(() => createModule(SomeOtherModule)).toThrowError(/Duplicate module registered/); - }); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should throw when registering a duplicate module', () => { + createModule(SomeModule); + expect(() => createModule(SomeOtherModule)).toThrowError(/Duplicate module registered/); + }); }); describe('entryComponents', () => { - it('should create ComponentFactories in root modules', () => { - @NgModule({declarations: [SomeComp], entryComponents: [SomeComp]}) - class SomeModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should create ComponentFactories in root modules', () => { + @NgModule({declarations: [SomeComp], entryComponents: [SomeComp]}) + class SomeModule { + } - const ngModule = createModule(SomeModule); - expect(ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType) - .toBe(SomeComp); - expect(ngModule.injector.get(ComponentFactoryResolver) - .resolveComponentFactory(SomeComp) - .componentType) - .toBe(SomeComp); - }); + const ngModule = createModule(SomeModule); + expect( + ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType) + .toBe(SomeComp); + expect(ngModule.injector.get(ComponentFactoryResolver) + .resolveComponentFactory(SomeComp) + .componentType) + .toBe(SomeComp); + }); - it('should throw if we cannot find a module associated with a module-level entryComponent', () => { - @Component({template: ''}) - class SomeCompWithEntryComponents { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should throw if we cannot find a module associated with a module-level entryComponent', + () => { + @Component({template: ''}) + class SomeCompWithEntryComponents { + } - @NgModule({declarations: [], entryComponents: [SomeCompWithEntryComponents]}) - class SomeModule { - } + @NgModule({declarations: [], entryComponents: [SomeCompWithEntryComponents]}) + class SomeModule { + } - expect(() => createModule(SomeModule)) - .toThrowError( - 'Component SomeCompWithEntryComponents is not part of any NgModule or the module has not been imported into your module.'); - }); + expect(() => createModule(SomeModule)) + .toThrowError( + 'Component SomeCompWithEntryComponents is not part of any NgModule or the module has not been imported into your module.'); + }); - it('should throw if we cannot find a module associated with a component-level entryComponent', - () => { - @Component({template: '', entryComponents: [SomeComp]}) - class SomeCompWithEntryComponents { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should throw if we cannot find a module associated with a component-level entryComponent', + () => { + @Component({template: '', entryComponents: [SomeComp]}) + class SomeCompWithEntryComponents { + } - @NgModule({declarations: [SomeCompWithEntryComponents]}) - class SomeModule { - } + @NgModule({declarations: [SomeCompWithEntryComponents]}) + class SomeModule { + } - expect(() => createModule(SomeModule)) - .toThrowError( - 'Component SomeComp is not part of any NgModule or the module has not been imported into your module.'); - }); + expect(() => createModule(SomeModule)) + .toThrowError( + 'Component SomeComp is not part of any NgModule or the module has not been imported into your module.'); + }); - it('should create ComponentFactories via ANALYZE_FOR_ENTRY_COMPONENTS', () => { - @NgModule({ - declarations: [SomeComp], - providers: [{ - provide: ANALYZE_FOR_ENTRY_COMPONENTS, - multi: true, - useValue: [{a: 'b', component: SomeComp}] - }] - }) - class SomeModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should create ComponentFactories via ANALYZE_FOR_ENTRY_COMPONENTS', () => { + @NgModule({ + declarations: [SomeComp], + providers: [{ + provide: ANALYZE_FOR_ENTRY_COMPONENTS, + multi: true, + useValue: [{a: 'b', component: SomeComp}] + }] + }) + class SomeModule { + } - const ngModule = createModule(SomeModule); - expect(ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType) - .toBe(SomeComp); - expect(ngModule.injector.get(ComponentFactoryResolver) - .resolveComponentFactory(SomeComp) - .componentType) - .toBe(SomeComp); - }); + const ngModule = createModule(SomeModule); + expect( + ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType) + .toBe(SomeComp); + expect(ngModule.injector.get(ComponentFactoryResolver) + .resolveComponentFactory(SomeComp) + .componentType) + .toBe(SomeComp); + }); - it('should create ComponentFactories in imported modules', () => { - @NgModule({declarations: [SomeComp], entryComponents: [SomeComp]}) - class SomeImportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should create ComponentFactories in imported modules', () => { + @NgModule({declarations: [SomeComp], entryComponents: [SomeComp]}) + class SomeImportedModule { + } - @NgModule({imports: [SomeImportedModule]}) - class SomeModule { - } + @NgModule({imports: [SomeImportedModule]}) + class SomeModule { + } - const ngModule = createModule(SomeModule); - expect(ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType) - .toBe(SomeComp); - expect(ngModule.injector.get(ComponentFactoryResolver) - .resolveComponentFactory(SomeComp) - .componentType) - .toBe(SomeComp); - }); + const ngModule = createModule(SomeModule); + expect( + ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType) + .toBe(SomeComp); + expect(ngModule.injector.get(ComponentFactoryResolver) + .resolveComponentFactory(SomeComp) + .componentType) + .toBe(SomeComp); + }); - it('should create ComponentFactories if the component was imported', () => { - @NgModule({declarations: [SomeComp], exports: [SomeComp]}) - class SomeImportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should create ComponentFactories if the component was imported', () => { + @NgModule({declarations: [SomeComp], exports: [SomeComp]}) + class SomeImportedModule { + } - @NgModule({imports: [SomeImportedModule], entryComponents: [SomeComp]}) - class SomeModule { - } + @NgModule({imports: [SomeImportedModule], entryComponents: [SomeComp]}) + class SomeModule { + } - const ngModule = createModule(SomeModule); - expect(ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType) - .toBe(SomeComp); - expect(ngModule.injector.get(ComponentFactoryResolver) - .resolveComponentFactory(SomeComp) - .componentType) - .toBe(SomeComp); - }); + const ngModule = createModule(SomeModule); + expect( + ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType) + .toBe(SomeComp); + expect(ngModule.injector.get(ComponentFactoryResolver) + .resolveComponentFactory(SomeComp) + .componentType) + .toBe(SomeComp); + }); }); describe('bootstrap components', () => { - it('should create ComponentFactories', () => { - @NgModule({declarations: [SomeComp], bootstrap: [SomeComp]}) - class SomeModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should create ComponentFactories', () => { + @NgModule({declarations: [SomeComp], bootstrap: [SomeComp]}) + class SomeModule { + } - const ngModule = createModule(SomeModule); - expect(ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType) - .toBe(SomeComp); - }); + const ngModule = createModule(SomeModule); + expect( + ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType) + .toBe(SomeComp); + }); - it('should store the ComponentFactories in the NgModuleInjector', () => { - @NgModule({declarations: [SomeComp], bootstrap: [SomeComp]}) - class SomeModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should store the ComponentFactories in the NgModuleInjector', () => { + @NgModule({declarations: [SomeComp], bootstrap: [SomeComp]}) + class SomeModule { + } - const ngModule = >createModule(SomeModule); - expect(ngModule._bootstrapComponents.length).toBe(1); - expect(ngModule._bootstrapComponents[0]).toBe(SomeComp); - }); + const ngModule = >createModule(SomeModule); + expect(ngModule._bootstrapComponents.length).toBe(1); + expect(ngModule._bootstrapComponents[0]).toBe(SomeComp); + }); }); describe('directives and pipes', () => { describe('declarations', () => { - it('should be supported in root modules', () => { - @NgModule({ - declarations: [CompUsingModuleDirectiveAndPipe, SomeDirective, SomePipe], - entryComponents: [CompUsingModuleDirectiveAndPipe] - }) - class SomeModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should be supported in root modules', () => { + @NgModule({ + declarations: [CompUsingModuleDirectiveAndPipe, SomeDirective, SomePipe], + entryComponents: [CompUsingModuleDirectiveAndPipe] + }) + class SomeModule { + } - const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); + const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); - compFixture.detectChanges(); - expect(compFixture.debugElement.children[0].properties['title']) - .toBe('transformed someValue'); - }); + compFixture.detectChanges(); + expect(compFixture.debugElement.children[0].properties['title']) + .toBe('transformed someValue'); + }); - it('should be supported in imported modules', () => { - @NgModule({ - declarations: [CompUsingModuleDirectiveAndPipe, SomeDirective, SomePipe], - entryComponents: [CompUsingModuleDirectiveAndPipe] - }) - class SomeImportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should be supported in imported modules', () => { + @NgModule({ + declarations: [CompUsingModuleDirectiveAndPipe, SomeDirective, SomePipe], + entryComponents: [CompUsingModuleDirectiveAndPipe] + }) + class SomeImportedModule { + } - @NgModule({imports: [SomeImportedModule]}) - class SomeModule { - } + @NgModule({imports: [SomeImportedModule]}) + class SomeModule { + } - const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); - compFixture.detectChanges(); - expect(compFixture.debugElement.children[0].properties['title']) - .toBe('transformed someValue'); - }); + const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); + compFixture.detectChanges(); + expect(compFixture.debugElement.children[0].properties['title']) + .toBe('transformed someValue'); + }); - it('should be supported in nested components', () => { - @Component({ - selector: 'parent', - template: '', - }) - class ParentCompUsingModuleDirectiveAndPipe { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should be supported in nested components', () => { + @Component({ + selector: 'parent', + template: '', + }) + class ParentCompUsingModuleDirectiveAndPipe { + } - @NgModule({ - declarations: [ - ParentCompUsingModuleDirectiveAndPipe, CompUsingModuleDirectiveAndPipe, SomeDirective, - SomePipe - ], - entryComponents: [ParentCompUsingModuleDirectiveAndPipe] - }) - class SomeModule { - } + @NgModule({ + declarations: [ + ParentCompUsingModuleDirectiveAndPipe, CompUsingModuleDirectiveAndPipe, + SomeDirective, SomePipe + ], + entryComponents: [ParentCompUsingModuleDirectiveAndPipe] + }) + class SomeModule { + } - const compFixture = createComp(ParentCompUsingModuleDirectiveAndPipe, SomeModule); - compFixture.detectChanges(); - expect(compFixture.debugElement.children[0].children[0].properties['title']) - .toBe('transformed someValue'); - }); + const compFixture = createComp(ParentCompUsingModuleDirectiveAndPipe, SomeModule); + compFixture.detectChanges(); + expect(compFixture.debugElement.children[0].children[0].properties['title']) + .toBe('transformed someValue'); + }); }); describe('import/export', () => { - it('should support exported directives and pipes', () => { - @NgModule({declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) - class SomeImportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should support exported directives and pipes', () => { + @NgModule( + {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) + class SomeImportedModule { + } - @NgModule({ - declarations: [CompUsingModuleDirectiveAndPipe], - imports: [SomeImportedModule], - entryComponents: [CompUsingModuleDirectiveAndPipe] - }) - class SomeModule { - } + @NgModule({ + declarations: [CompUsingModuleDirectiveAndPipe], + imports: [SomeImportedModule], + entryComponents: [CompUsingModuleDirectiveAndPipe] + }) + class SomeModule { + } - const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); - compFixture.detectChanges(); - expect(compFixture.debugElement.children[0].properties['title']) - .toBe('transformed someValue'); - }); + const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); + compFixture.detectChanges(); + expect(compFixture.debugElement.children[0].properties['title']) + .toBe('transformed someValue'); + }); - it('should support exported directives and pipes if the module is wrapped into an `ModuleWithProviders`', - () => { - @NgModule( - {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) - class SomeImportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should support exported directives and pipes if the module is wrapped into an `ModuleWithProviders`', + () => { + @NgModule( + {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) + class SomeImportedModule { + } - @NgModule({ - declarations: [CompUsingModuleDirectiveAndPipe], - imports: [{ngModule: SomeImportedModule}], - entryComponents: [CompUsingModuleDirectiveAndPipe] - }) - class SomeModule { - } + @NgModule({ + declarations: [CompUsingModuleDirectiveAndPipe], + imports: [{ngModule: SomeImportedModule}], + entryComponents: [CompUsingModuleDirectiveAndPipe] + }) + class SomeModule { + } - const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); - compFixture.detectChanges(); - expect(compFixture.debugElement.children[0].properties['title']) - .toBe('transformed someValue'); - }); + const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); + compFixture.detectChanges(); + expect(compFixture.debugElement.children[0].properties['title']) + .toBe('transformed someValue'); + }); - it('should support reexported modules', () => { - @NgModule({declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) - class SomeReexportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should support reexported modules', () => { + @NgModule( + {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) + class SomeReexportedModule { + } - @NgModule({exports: [SomeReexportedModule]}) - class SomeImportedModule { - } + @NgModule({exports: [SomeReexportedModule]}) + class SomeImportedModule { + } - @NgModule({ - declarations: [CompUsingModuleDirectiveAndPipe], - imports: [SomeImportedModule], - entryComponents: [CompUsingModuleDirectiveAndPipe] - }) - class SomeModule { - } + @NgModule({ + declarations: [CompUsingModuleDirectiveAndPipe], + imports: [SomeImportedModule], + entryComponents: [CompUsingModuleDirectiveAndPipe] + }) + class SomeModule { + } - const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); - compFixture.detectChanges(); - expect(compFixture.debugElement.children[0].properties['title']) - .toBe('transformed someValue'); - }); + const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); + compFixture.detectChanges(); + expect(compFixture.debugElement.children[0].properties['title']) + .toBe('transformed someValue'); + }); - it('should support exporting individual directives of an imported module', () => { - @NgModule({declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) - class SomeReexportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should support exporting individual directives of an imported module', () => { + @NgModule( + {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) + class SomeReexportedModule { + } - @NgModule({imports: [SomeReexportedModule], exports: [SomeDirective, SomePipe]}) - class SomeImportedModule { - } + @NgModule({imports: [SomeReexportedModule], exports: [SomeDirective, SomePipe]}) + class SomeImportedModule { + } - @NgModule({ - declarations: [CompUsingModuleDirectiveAndPipe], - imports: [SomeImportedModule], - entryComponents: [CompUsingModuleDirectiveAndPipe] - }) - class SomeModule { - } + @NgModule({ + declarations: [CompUsingModuleDirectiveAndPipe], + imports: [SomeImportedModule], + entryComponents: [CompUsingModuleDirectiveAndPipe] + }) + class SomeModule { + } - const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); - compFixture.detectChanges(); - expect(compFixture.debugElement.children[0].properties['title']) - .toBe('transformed someValue'); - }); + const compFixture = createComp(CompUsingModuleDirectiveAndPipe, SomeModule); + compFixture.detectChanges(); + expect(compFixture.debugElement.children[0].properties['title']) + .toBe('transformed someValue'); + }); - it('should not use non exported pipes of an imported module', () => { - @NgModule({ - declarations: [SomePipe], - }) - class SomeImportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should not use non exported pipes of an imported module', () => { + @NgModule({ + declarations: [SomePipe], + }) + class SomeImportedModule { + } - @NgModule({ - declarations: [CompUsingModuleDirectiveAndPipe], - imports: [SomeImportedModule], - entryComponents: [CompUsingModuleDirectiveAndPipe] - }) - class SomeModule { - } + @NgModule({ + declarations: [CompUsingModuleDirectiveAndPipe], + imports: [SomeImportedModule], + entryComponents: [CompUsingModuleDirectiveAndPipe] + }) + class SomeModule { + } - expect(() => createComp(SomeComp, SomeModule)) - .toThrowError(/The pipe 'somePipe' could not be found/); - }); + expect(() => createComp(SomeComp, SomeModule)) + .toThrowError(/The pipe 'somePipe' could not be found/); + }); - it('should not use non exported directives of an imported module', () => { - @NgModule({ - declarations: [SomeDirective], - }) - class SomeImportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should not use non exported directives of an imported module', () => { + @NgModule({ + declarations: [SomeDirective], + }) + class SomeImportedModule { + } - @NgModule({ - declarations: [CompUsingModuleDirectiveAndPipe, SomePipe], - imports: [SomeImportedModule], - entryComponents: [CompUsingModuleDirectiveAndPipe] - }) - class SomeModule { - } + @NgModule({ + declarations: [CompUsingModuleDirectiveAndPipe, SomePipe], + imports: [SomeImportedModule], + entryComponents: [CompUsingModuleDirectiveAndPipe] + }) + class SomeModule { + } - expect(() => createComp(SomeComp, SomeModule)).toThrowError(/Can't bind to 'someDir'/); - }); + expect(() => createComp(SomeComp, SomeModule)) + .toThrowError(/Can't bind to 'someDir'/); + }); }); }); @@ -619,43 +657,49 @@ function declareTests(config?: {useJit: boolean}) { return createModule(SomeModule, parent).injector; } - it('should provide the module', - () => { expect(createInjector([]).get(moduleType)).toBeAnInstanceOf(moduleType); }); - - it('should instantiate a class without dependencies', () => { - const injector = createInjector([Engine]); - const engine = injector.get(Engine); - - expect(engine).toBeAnInstanceOf(Engine); + fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should provide the module', () => { + expect(createInjector([]).get(moduleType)).toBeAnInstanceOf(moduleType); }); - it('should resolve dependencies based on type information', () => { - const injector = createInjector([Engine, Car]); - const car = injector.get(Car); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should instantiate a class without dependencies', () => { + const injector = createInjector([Engine]); + const engine = injector.get(Engine); - expect(car).toBeAnInstanceOf(Car); - expect(car.engine).toBeAnInstanceOf(Engine); - }); + expect(engine).toBeAnInstanceOf(Engine); + }); - it('should resolve dependencies based on @Inject annotation', () => { - const injector = createInjector([TurboEngine, Engine, CarWithInject]); - const car = injector.get(CarWithInject); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should resolve dependencies based on type information', () => { + const injector = createInjector([Engine, Car]); + const car = injector.get(Car); - expect(car).toBeAnInstanceOf(CarWithInject); - expect(car.engine).toBeAnInstanceOf(TurboEngine); - }); + expect(car).toBeAnInstanceOf(Car); + expect(car.engine).toBeAnInstanceOf(Engine); + }); - it('should throw when no type and not @Inject (class case)', () => { - expect(() => createInjector([NoAnnotations])) - .toThrowError('Can\'t resolve all parameters for NoAnnotations: (?).'); - }); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should resolve dependencies based on @Inject annotation', () => { + const injector = createInjector([TurboEngine, Engine, CarWithInject]); + const car = injector.get(CarWithInject); - it('should throw when no type and not @Inject (factory case)', () => { - expect(() => createInjector([{provide: 'someToken', useFactory: factoryFn}])) - .toThrowError('Can\'t resolve all parameters for factoryFn: (?).'); - }); + expect(car).toBeAnInstanceOf(CarWithInject); + expect(car.engine).toBeAnInstanceOf(TurboEngine); + }); - it('should cache instances', () => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should throw when no type and not @Inject (class case)', () => { + expect(() => createInjector([NoAnnotations])) + .toThrowError('Can\'t resolve all parameters for NoAnnotations: (?).'); + }); + + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should throw when no type and not @Inject (factory case)', () => { + expect(() => createInjector([{provide: 'someToken', useFactory: factoryFn}])) + .toThrowError('Can\'t resolve all parameters for factoryFn: (?).'); + }); + + fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should cache instances', () => { const injector = createInjector([Engine]); const e1 = injector.get(Engine); @@ -664,31 +708,33 @@ function declareTests(config?: {useJit: boolean}) { expect(e1).toBe(e2); }); - it('should provide to a value', () => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should provide to a value', () => { const injector = createInjector([{provide: Engine, useValue: 'fake engine'}]); const engine = injector.get(Engine); expect(engine).toEqual('fake engine'); }); - it('should provide to a factory', () => { - function sportsCarFactory(e: Engine) { return new SportsCar(e); } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should provide to a factory', () => { + function sportsCarFactory(e: Engine) { return new SportsCar(e); } - const injector = - createInjector([Engine, {provide: Car, useFactory: sportsCarFactory, deps: [Engine]}]); + const injector = createInjector( + [Engine, {provide: Car, useFactory: sportsCarFactory, deps: [Engine]}]); - const car = injector.get(Car); - expect(car).toBeAnInstanceOf(SportsCar); - expect(car.engine).toBeAnInstanceOf(Engine); - }); + const car = injector.get(Car); + expect(car).toBeAnInstanceOf(SportsCar); + expect(car.engine).toBeAnInstanceOf(Engine); + }); - it('should supporting provider to null', () => { - const injector = createInjector([{provide: Engine, useValue: null}]); - const engine = injector.get(Engine); - expect(engine).toBeNull(); - }); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should supporting provider to null', () => { + const injector = createInjector([{provide: Engine, useValue: null}]); + const engine = injector.get(Engine); + expect(engine).toBeNull(); + }); - it('should provide to an alias', () => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should provide to an alias', () => { const injector = createInjector([ Engine, {provide: SportsCar, useClass: SportsCar}, {provide: Car, useExisting: SportsCar} @@ -700,97 +746,109 @@ function declareTests(config?: {useJit: boolean}) { expect(car).toBe(sportsCar); }); - it('should support multiProviders', () => { - const injector = createInjector([ - Engine, {provide: CARS, useClass: SportsCar, multi: true}, - {provide: CARS, useClass: CarWithOptionalEngine, multi: true} - ]); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should support multiProviders', () => { + const injector = createInjector([ + Engine, {provide: CARS, useClass: SportsCar, multi: true}, + {provide: CARS, useClass: CarWithOptionalEngine, multi: true} + ]); - const cars = injector.get(CARS); - expect(cars.length).toEqual(2); - expect(cars[0]).toBeAnInstanceOf(SportsCar); - expect(cars[1]).toBeAnInstanceOf(CarWithOptionalEngine); - }); + const cars = injector.get(CARS); + expect(cars.length).toEqual(2); + expect(cars[0]).toBeAnInstanceOf(SportsCar); + expect(cars[1]).toBeAnInstanceOf(CarWithOptionalEngine); + }); - it('should support multiProviders that are created using useExisting', () => { - const injector = createInjector( - [Engine, SportsCar, {provide: CARS, useExisting: SportsCar, multi: true}]); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should support multiProviders that are created using useExisting', () => { + const injector = createInjector( + [Engine, SportsCar, {provide: CARS, useExisting: SportsCar, multi: true}]); - const cars = injector.get(CARS); - expect(cars.length).toEqual(1); - expect(cars[0]).toBe(injector.get(SportsCar)); - }); + const cars = injector.get(CARS); + expect(cars.length).toEqual(1); + expect(cars[0]).toBe(injector.get(SportsCar)); + }); - it('should throw when the aliased provider does not exist', () => { - const injector = createInjector([{provide: 'car', useExisting: SportsCar}]); - const e = `NullInjectorError: No provider for ${stringify(SportsCar)}!`; - expect(() => injector.get('car')).toThrowError(e); - }); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should throw when the aliased provider does not exist', () => { + const injector = createInjector([{provide: 'car', useExisting: SportsCar}]); + const e = `NullInjectorError: No provider for ${stringify(SportsCar)}!`; + expect(() => injector.get('car')).toThrowError(e); + }); - it('should handle forwardRef in useExisting', () => { - const injector = createInjector([ - {provide: 'originalEngine', useClass: forwardRef(() => Engine)}, - {provide: 'aliasedEngine', useExisting: forwardRef(() => 'originalEngine')} - ]); - expect(injector.get('aliasedEngine')).toBeAnInstanceOf(Engine); - }); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should handle forwardRef in useExisting', () => { + const injector = createInjector([ + {provide: 'originalEngine', useClass: forwardRef(() => Engine)}, + {provide: 'aliasedEngine', useExisting: forwardRef(() => 'originalEngine')} + ]); + expect(injector.get('aliasedEngine')).toBeAnInstanceOf(Engine); + }); - it('should support overriding factory dependencies', () => { - const injector = createInjector( - [Engine, {provide: Car, useFactory: (e: Engine) => new SportsCar(e), deps: [Engine]}]); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should support overriding factory dependencies', () => { + const injector = createInjector([ + Engine, {provide: Car, useFactory: (e: Engine) => new SportsCar(e), deps: [Engine]} + ]); - const car = injector.get(Car); - expect(car).toBeAnInstanceOf(SportsCar); - expect(car.engine).toBeAnInstanceOf(Engine); - }); + const car = injector.get(Car); + expect(car).toBeAnInstanceOf(SportsCar); + expect(car.engine).toBeAnInstanceOf(Engine); + }); - it('should support optional dependencies', () => { - const injector = createInjector([CarWithOptionalEngine]); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should support optional dependencies', () => { + const injector = createInjector([CarWithOptionalEngine]); - const car = injector.get(CarWithOptionalEngine); - expect(car.engine).toBeNull(); - }); + const car = injector.get(CarWithOptionalEngine); + expect(car.engine).toBeNull(); + }); - it('should flatten passed-in providers', () => { - const injector = createInjector([[[Engine, Car]]]); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should flatten passed-in providers', () => { + const injector = createInjector([[[Engine, Car]]]); - const car = injector.get(Car); - expect(car).toBeAnInstanceOf(Car); - }); + const car = injector.get(Car); + expect(car).toBeAnInstanceOf(Car); + }); - it('should use the last provider when there are multiple providers for same token', () => { - const injector = createInjector( - [{provide: Engine, useClass: Engine}, {provide: Engine, useClass: TurboEngine}]); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should use the last provider when there are multiple providers for same token', + () => { + const injector = createInjector( + [{provide: Engine, useClass: Engine}, {provide: Engine, useClass: TurboEngine}]); - expect(injector.get(Engine)).toBeAnInstanceOf(TurboEngine); - }); + expect(injector.get(Engine)).toBeAnInstanceOf(TurboEngine); + }); - it('should use non-type tokens', () => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should use non-type tokens', () => { const injector = createInjector([{provide: 'token', useValue: 'value'}]); expect(injector.get('token')).toEqual('value'); }); - it('should throw when given invalid providers', () => { - expect(() => createInjector(['blah'])) - .toThrowError( - `Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?blah?]`); - }); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should throw when given invalid providers', () => { + expect(() => createInjector(['blah'])) + .toThrowError( + `Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?blah?]`); + }); - it('should throw when given blank providers', () => { - expect(() => createInjector([null, {provide: 'token', useValue: 'value'}])) - .toThrowError( - `Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?null?, ...]`); - }); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should throw when given blank providers', () => { + expect(() => createInjector([null, {provide: 'token', useValue: 'value'}])) + .toThrowError( + `Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?null?, ...]`); + }); - it('should provide itself', () => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should provide itself', () => { const parent = createInjector([]); const child = createInjector([], parent); expect(child.get(Injector)).toBe(child); }); - it('should provide undefined', () => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should provide undefined', () => { let factoryCounter = 0; const injector = createInjector([{ @@ -808,179 +866,193 @@ function declareTests(config?: {useJit: boolean}) { describe('injecting lazy providers into an eager provider via Injector.get', () => { - it('should inject providers that were declared before it', () => { - @NgModule({ - providers: [ - {provide: 'lazy', useFactory: () => 'lazyValue'}, - { - provide: 'eager', - useFactory: (i: Injector) => `eagerValue: ${i.get('lazy')}`, - deps: [Injector] - }, - ] - }) - class MyModule { - // NgModule is eager, which makes all of its deps eager - constructor(@Inject('eager') eager: any) {} - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should inject providers that were declared before it', () => { + @NgModule({ + providers: [ + {provide: 'lazy', useFactory: () => 'lazyValue'}, + { + provide: 'eager', + useFactory: (i: Injector) => `eagerValue: ${i.get('lazy')}`, + deps: [Injector] + }, + ] + }) + class MyModule { + // NgModule is eager, which makes all of its deps eager + constructor(@Inject('eager') eager: any) {} + } - expect(createModule(MyModule).injector.get('eager')).toBe('eagerValue: lazyValue'); - }); + expect(createModule(MyModule).injector.get('eager')).toBe('eagerValue: lazyValue'); + }); - it('should inject providers that were declared after it', () => { - @NgModule({ - providers: [ - { - provide: 'eager', - useFactory: (i: Injector) => `eagerValue: ${i.get('lazy')}`, - deps: [Injector] - }, - {provide: 'lazy', useFactory: () => 'lazyValue'}, - ] - }) - class MyModule { - // NgModule is eager, which makes all of its deps eager - constructor(@Inject('eager') eager: any) {} - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should inject providers that were declared after it', () => { + @NgModule({ + providers: [ + { + provide: 'eager', + useFactory: (i: Injector) => `eagerValue: ${i.get('lazy')}`, + deps: [Injector] + }, + {provide: 'lazy', useFactory: () => 'lazyValue'}, + ] + }) + class MyModule { + // NgModule is eager, which makes all of its deps eager + constructor(@Inject('eager') eager: any) {} + } - expect(createModule(MyModule).injector.get('eager')).toBe('eagerValue: lazyValue'); - }); + expect(createModule(MyModule).injector.get('eager')).toBe('eagerValue: lazyValue'); + }); }); describe('injecting eager providers into an eager provider via Injector.get', () => { - it('should inject providers that were declared before it', () => { - @NgModule({ - providers: [ - {provide: 'eager1', useFactory: () => 'v1'}, - { - provide: 'eager2', - useFactory: (i: Injector) => `v2: ${i.get('eager1')}`, - deps: [Injector] - }, - ] - }) - class MyModule { - // NgModule is eager, which makes all of its deps eager - constructor(@Inject('eager1') eager1: any, @Inject('eager2') eager2: any) {} - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should inject providers that were declared before it', () => { + @NgModule({ + providers: [ + {provide: 'eager1', useFactory: () => 'v1'}, + { + provide: 'eager2', + useFactory: (i: Injector) => `v2: ${i.get('eager1')}`, + deps: [Injector] + }, + ] + }) + class MyModule { + // NgModule is eager, which makes all of its deps eager + constructor(@Inject('eager1') eager1: any, @Inject('eager2') eager2: any) {} + } - expect(createModule(MyModule).injector.get('eager2')).toBe('v2: v1'); - }); + expect(createModule(MyModule).injector.get('eager2')).toBe('v2: v1'); + }); - it('should inject providers that were declared after it', () => { - @NgModule({ - providers: [ - { - provide: 'eager1', - useFactory: (i: Injector) => `v1: ${i.get('eager2')}`, - deps: [Injector] - }, - {provide: 'eager2', useFactory: () => 'v2'}, - ] - }) - class MyModule { - // NgModule is eager, which makes all of its deps eager - constructor(@Inject('eager1') eager1: any, @Inject('eager2') eager2: any) {} - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should inject providers that were declared after it', () => { + @NgModule({ + providers: [ + { + provide: 'eager1', + useFactory: (i: Injector) => `v1: ${i.get('eager2')}`, + deps: [Injector] + }, + {provide: 'eager2', useFactory: () => 'v2'}, + ] + }) + class MyModule { + // NgModule is eager, which makes all of its deps eager + constructor(@Inject('eager1') eager1: any, @Inject('eager2') eager2: any) {} + } - expect(createModule(MyModule).injector.get('eager1')).toBe('v1: v2'); - }); + expect(createModule(MyModule).injector.get('eager1')).toBe('v1: v2'); + }); - it('eager providers should get initialized only once', () => { - @Injectable() - class MyService1 { - public innerService: MyService2; - constructor(injector: Injector) { - // Create MyService2 before it it's initialized by TestModule. - this.innerService = injector.get(MyService2); - } - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('eager providers should get initialized only once', () => { + @Injectable() + class MyService1 { + public innerService: MyService2; + constructor(injector: Injector) { + // Create MyService2 before it it's initialized by TestModule. + this.innerService = injector.get(MyService2); + } + } - @Injectable() - class MyService2 { - constructor() {} - } + @Injectable() + class MyService2 { + constructor() {} + } - @NgModule({ - providers: [MyService1, MyService2], - }) - class TestModule { - constructor(public service1: MyService1, public service2: MyService2) {} - } + @NgModule({ + providers: [MyService1, MyService2], + }) + class TestModule { + constructor(public service1: MyService1, public service2: MyService2) {} + } - const moduleRef = createModule(TestModule, injector); - const module = moduleRef.instance; + const moduleRef = createModule(TestModule, injector); + const module = moduleRef.instance; - // MyService2 should not get initialized twice. - expect(module.service1.innerService).toBe(module.service2); - }); + // MyService2 should not get initialized twice. + expect(module.service1.innerService).toBe(module.service2); + }); }); - it('should throw when no provider defined', () => { - const injector = createInjector([]); - expect(() => injector.get('NonExisting')) - .toThrowError('NullInjectorError: No provider for NonExisting!'); - }); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should throw when no provider defined', () => { + const injector = createInjector([]); + expect(() => injector.get('NonExisting')) + .toThrowError('NullInjectorError: No provider for NonExisting!'); + }); - it('should throw when trying to instantiate a cyclic dependency', () => { - expect(() => createInjector([Car, {provide: Engine, useClass: CyclicEngine}])) - .toThrowError(/Cannot instantiate cyclic dependency! Car/g); - }); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should throw when trying to instantiate a cyclic dependency', () => { + expect(() => createInjector([Car, {provide: Engine, useClass: CyclicEngine}])) + .toThrowError(/Cannot instantiate cyclic dependency! Car/g); + }); - it('should support null values', () => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should support null values', () => { const injector = createInjector([{provide: 'null', useValue: null}]); expect(injector.get('null')).toBe(null); }); describe('child', () => { - it('should load instances from parent injector', () => { - const parent = createInjector([Engine]); - const child = createInjector([], parent); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should load instances from parent injector', () => { + const parent = createInjector([Engine]); + const child = createInjector([], parent); - const engineFromParent = parent.get(Engine); - const engineFromChild = child.get(Engine); + const engineFromParent = parent.get(Engine); + const engineFromChild = child.get(Engine); - expect(engineFromChild).toBe(engineFromParent); - }); + expect(engineFromChild).toBe(engineFromParent); + }); - it('should not use the child providers when resolving the dependencies of a parent provider', - () => { - const parent = createInjector([Car, Engine]); - const child = createInjector([{provide: Engine, useClass: TurboEngine}], parent); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should not use the child providers when resolving the dependencies of a parent provider', + () => { + const parent = createInjector([Car, Engine]); + const child = createInjector([{provide: Engine, useClass: TurboEngine}], parent); - const carFromChild = child.get(Car); - expect(carFromChild.engine).toBeAnInstanceOf(Engine); - }); + const carFromChild = child.get(Car); + expect(carFromChild.engine).toBeAnInstanceOf(Engine); + }); - it('should create new instance in a child injector', () => { - const parent = createInjector([Engine]); - const child = createInjector([{provide: Engine, useClass: TurboEngine}], parent); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should create new instance in a child injector', () => { + const parent = createInjector([Engine]); + const child = createInjector([{provide: Engine, useClass: TurboEngine}], parent); - const engineFromParent = parent.get(Engine); - const engineFromChild = child.get(Engine); + const engineFromParent = parent.get(Engine); + const engineFromChild = child.get(Engine); - expect(engineFromParent).not.toBe(engineFromChild); - expect(engineFromChild).toBeAnInstanceOf(TurboEngine); - }); + expect(engineFromParent).not.toBe(engineFromChild); + expect(engineFromChild).toBeAnInstanceOf(TurboEngine); + }); }); describe('depedency resolution', () => { describe('@Self()', () => { - it('should return a dependency from self', () => { - const inj = createInjector([ - Engine, - {provide: Car, useFactory: (e: Engine) => new Car(e), deps: [[Engine, new Self()]]} - ]); + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should return a dependency from self', () => { + const inj = createInjector([ + Engine, { + provide: Car, + useFactory: (e: Engine) => new Car(e), + deps: [[Engine, new Self()]] + } + ]); - expect(inj.get(Car)).toBeAnInstanceOf(Car); - }); + expect(inj.get(Car)).toBeAnInstanceOf(Car); + }); }); describe('default', () => { - it('should not skip self', () => { + fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should not skip self', () => { const parent = createInjector([Engine]); const child = createInjector( [ @@ -995,7 +1067,7 @@ function declareTests(config?: {useJit: boolean}) { }); describe('lifecycle', () => { - it('should instantiate modules eagerly', () => { + fixmeIvy('unknown') && it('should instantiate modules eagerly', () => { let created = false; @NgModule() @@ -1012,325 +1084,347 @@ function declareTests(config?: {useJit: boolean}) { expect(created).toBe(true); }); - it('should instantiate providers that are not used by a module lazily', () => { - let created = false; + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should instantiate providers that are not used by a module lazily', () => { + let created = false; - createInjector([{ - provide: 'someToken', - useFactory: () => { - created = true; - return true; - } - }]); + createInjector([{ + provide: 'someToken', + useFactory: () => { + created = true; + return true; + } + }]); - expect(created).toBe(false); - }); + expect(created).toBe(false); + }); - it('should support ngOnDestroy on any provider', () => { - let destroyed = false; + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should support ngOnDestroy on any provider', () => { + let destroyed = false; - class SomeInjectable { - ngOnDestroy() { destroyed = true; } - } + class SomeInjectable { + ngOnDestroy() { destroyed = true; } + } - @NgModule({providers: [SomeInjectable]}) - class SomeModule { - // Inject SomeInjectable to make it eager... - constructor(i: SomeInjectable) {} - } + @NgModule({providers: [SomeInjectable]}) + class SomeModule { + // Inject SomeInjectable to make it eager... + constructor(i: SomeInjectable) {} + } - const moduleRef = createModule(SomeModule); - expect(destroyed).toBe(false); - moduleRef.destroy(); - expect(destroyed).toBe(true); - }); + const moduleRef = createModule(SomeModule); + expect(destroyed).toBe(false); + moduleRef.destroy(); + expect(destroyed).toBe(true); + }); - it('should support ngOnDestroy for lazy providers', () => { - let created = false; - let destroyed = false; + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should support ngOnDestroy for lazy providers', () => { + let created = false; + let destroyed = false; - class SomeInjectable { - constructor() { created = true; } - ngOnDestroy() { destroyed = true; } - } + class SomeInjectable { + constructor() { created = true; } + ngOnDestroy() { destroyed = true; } + } - @NgModule({providers: [SomeInjectable]}) - class SomeModule { - } + @NgModule({providers: [SomeInjectable]}) + class SomeModule { + } - let moduleRef = createModule(SomeModule); - expect(created).toBe(false); - expect(destroyed).toBe(false); + let moduleRef = createModule(SomeModule); + expect(created).toBe(false); + expect(destroyed).toBe(false); - // no error if the provider was not yet created - moduleRef.destroy(); - expect(created).toBe(false); - expect(destroyed).toBe(false); + // no error if the provider was not yet created + moduleRef.destroy(); + expect(created).toBe(false); + expect(destroyed).toBe(false); - moduleRef = createModule(SomeModule); - moduleRef.injector.get(SomeInjectable); - expect(created).toBe(true); - moduleRef.destroy(); - expect(destroyed).toBe(true); - }); + moduleRef = createModule(SomeModule); + moduleRef.injector.get(SomeInjectable); + expect(created).toBe(true); + moduleRef.destroy(); + expect(destroyed).toBe(true); + }); }); describe('imported and exported modules', () => { - it('should add the providers of imported modules', () => { - @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) - class ImportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should add the providers of imported modules', () => { + @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) + class ImportedModule { + } - @NgModule({imports: [ImportedModule]}) - class SomeModule { - } + @NgModule({imports: [ImportedModule]}) + class SomeModule { + } - const injector = createModule(SomeModule).injector; + const injector = createModule(SomeModule).injector; - expect(injector.get(SomeModule)).toBeAnInstanceOf(SomeModule); - expect(injector.get(ImportedModule)).toBeAnInstanceOf(ImportedModule); - expect(injector.get('token1')).toBe('imported'); - }); + expect(injector.get(SomeModule)).toBeAnInstanceOf(SomeModule); + expect(injector.get(ImportedModule)).toBeAnInstanceOf(ImportedModule); + expect(injector.get('token1')).toBe('imported'); + }); - it('should add the providers of imported ModuleWithProviders', () => { - @NgModule() - class ImportedModule { - } + fixmeIvy('unknown') && + it('should add the providers of imported ModuleWithProviders', () => { + @NgModule() + class ImportedModule { + } - @NgModule({ - imports: [ - {ngModule: ImportedModule, providers: [{provide: 'token1', useValue: 'imported'}]} - ] - }) - class SomeModule { - } + @NgModule({ + imports: [{ + ngModule: ImportedModule, + providers: [{provide: 'token1', useValue: 'imported'}] + }] + }) + class SomeModule { + } - const injector = createModule(SomeModule).injector; + const injector = createModule(SomeModule).injector; - expect(injector.get(SomeModule)).toBeAnInstanceOf(SomeModule); - expect(injector.get(ImportedModule)).toBeAnInstanceOf(ImportedModule); - expect(injector.get('token1')).toBe('imported'); - }); + expect(injector.get(SomeModule)).toBeAnInstanceOf(SomeModule); + expect(injector.get(ImportedModule)).toBeAnInstanceOf(ImportedModule); + expect(injector.get('token1')).toBe('imported'); + }); - it('should overwrite the providers of imported modules', () => { - @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) - class ImportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should overwrite the providers of imported modules', () => { + @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) + class ImportedModule { + } - @NgModule( - {providers: [{provide: 'token1', useValue: 'direct'}], imports: [ImportedModule]}) - class SomeModule { - } + @NgModule( + {providers: [{provide: 'token1', useValue: 'direct'}], imports: [ImportedModule]}) + class SomeModule { + } - const injector = createModule(SomeModule).injector; - expect(injector.get('token1')).toBe('direct'); - }); + const injector = createModule(SomeModule).injector; + expect(injector.get('token1')).toBe('direct'); + }); - it('should overwrite the providers of imported ModuleWithProviders', () => { - @NgModule() - class ImportedModule { - } + fixmeIvy('unknown') && + it('should overwrite the providers of imported ModuleWithProviders', () => { + @NgModule() + class ImportedModule { + } - @NgModule({ - providers: [{provide: 'token1', useValue: 'direct'}], - imports: [ - {ngModule: ImportedModule, providers: [{provide: 'token1', useValue: 'imported'}]} - ] - }) - class SomeModule { - } + @NgModule({ + providers: [{provide: 'token1', useValue: 'direct'}], + imports: [{ + ngModule: ImportedModule, + providers: [{provide: 'token1', useValue: 'imported'}] + }] + }) + class SomeModule { + } - const injector = createModule(SomeModule).injector; - expect(injector.get('token1')).toBe('direct'); - }); + const injector = createModule(SomeModule).injector; + expect(injector.get('token1')).toBe('direct'); + }); - it('should overwrite the providers of imported modules on the second import level', () => { - @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) - class ImportedModuleLevel2 { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should overwrite the providers of imported modules on the second import level', + () => { + @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) + class ImportedModuleLevel2 { + } - @NgModule({ - providers: [{provide: 'token1', useValue: 'direct'}], - imports: [ImportedModuleLevel2] - }) - class ImportedModuleLevel1 { - } + @NgModule({ + providers: [{provide: 'token1', useValue: 'direct'}], + imports: [ImportedModuleLevel2] + }) + class ImportedModuleLevel1 { + } - @NgModule({imports: [ImportedModuleLevel1]}) - class SomeModule { - } + @NgModule({imports: [ImportedModuleLevel1]}) + class SomeModule { + } - const injector = createModule(SomeModule).injector; - expect(injector.get('token1')).toBe('direct'); - }); + const injector = createModule(SomeModule).injector; + expect(injector.get('token1')).toBe('direct'); + }); - it('should add the providers of exported modules', () => { - @NgModule({providers: [{provide: 'token1', useValue: 'exported'}]}) - class ExportedValue { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should add the providers of exported modules', () => { + @NgModule({providers: [{provide: 'token1', useValue: 'exported'}]}) + class ExportedValue { + } - @NgModule({exports: [ExportedValue]}) - class SomeModule { - } + @NgModule({exports: [ExportedValue]}) + class SomeModule { + } - const injector = createModule(SomeModule).injector; + const injector = createModule(SomeModule).injector; - expect(injector.get(SomeModule)).toBeAnInstanceOf(SomeModule); - expect(injector.get(ExportedValue)).toBeAnInstanceOf(ExportedValue); - expect(injector.get('token1')).toBe('exported'); - }); + expect(injector.get(SomeModule)).toBeAnInstanceOf(SomeModule); + expect(injector.get(ExportedValue)).toBeAnInstanceOf(ExportedValue); + expect(injector.get('token1')).toBe('exported'); + }); - it('should overwrite the providers of exported modules', () => { - @NgModule({providers: [{provide: 'token1', useValue: 'exported'}]}) - class ExportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should overwrite the providers of exported modules', () => { + @NgModule({providers: [{provide: 'token1', useValue: 'exported'}]}) + class ExportedModule { + } - @NgModule( - {providers: [{provide: 'token1', useValue: 'direct'}], exports: [ExportedModule]}) - class SomeModule { - } + @NgModule( + {providers: [{provide: 'token1', useValue: 'direct'}], exports: [ExportedModule]}) + class SomeModule { + } - const injector = createModule(SomeModule).injector; - expect(injector.get('token1')).toBe('direct'); - }); + const injector = createModule(SomeModule).injector; + expect(injector.get('token1')).toBe('direct'); + }); - it('should overwrite the providers of imported modules by following imported modules', - () => { - @NgModule({providers: [{provide: 'token1', useValue: 'imported1'}]}) - class ImportedModule1 { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should overwrite the providers of imported modules by following imported modules', + () => { + @NgModule({providers: [{provide: 'token1', useValue: 'imported1'}]}) + class ImportedModule1 { + } - @NgModule({providers: [{provide: 'token1', useValue: 'imported2'}]}) - class ImportedModule2 { - } + @NgModule({providers: [{provide: 'token1', useValue: 'imported2'}]}) + class ImportedModule2 { + } - @NgModule({imports: [ImportedModule1, ImportedModule2]}) - class SomeModule { - } + @NgModule({imports: [ImportedModule1, ImportedModule2]}) + class SomeModule { + } - const injector = createModule(SomeModule).injector; - expect(injector.get('token1')).toBe('imported2'); - }); + const injector = createModule(SomeModule).injector; + expect(injector.get('token1')).toBe('imported2'); + }); - it('should overwrite the providers of exported modules by following exported modules', - () => { - @NgModule({providers: [{provide: 'token1', useValue: 'exported1'}]}) - class ExportedModule1 { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should overwrite the providers of exported modules by following exported modules', + () => { + @NgModule({providers: [{provide: 'token1', useValue: 'exported1'}]}) + class ExportedModule1 { + } - @NgModule({providers: [{provide: 'token1', useValue: 'exported2'}]}) - class ExportedModule2 { - } + @NgModule({providers: [{provide: 'token1', useValue: 'exported2'}]}) + class ExportedModule2 { + } - @NgModule({exports: [ExportedModule1, ExportedModule2]}) - class SomeModule { - } + @NgModule({exports: [ExportedModule1, ExportedModule2]}) + class SomeModule { + } - const injector = createModule(SomeModule).injector; - expect(injector.get('token1')).toBe('exported2'); - }); + const injector = createModule(SomeModule).injector; + expect(injector.get('token1')).toBe('exported2'); + }); - it('should overwrite the providers of imported modules by exported modules', () => { - @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) - class ImportedModule { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should overwrite the providers of imported modules by exported modules', () => { + @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) + class ImportedModule { + } - @NgModule({providers: [{provide: 'token1', useValue: 'exported'}]}) - class ExportedModule { - } + @NgModule({providers: [{provide: 'token1', useValue: 'exported'}]}) + class ExportedModule { + } - @NgModule({imports: [ImportedModule], exports: [ExportedModule]}) - class SomeModule { - } + @NgModule({imports: [ImportedModule], exports: [ExportedModule]}) + class SomeModule { + } - const injector = createModule(SomeModule).injector; - expect(injector.get('token1')).toBe('exported'); - }); + const injector = createModule(SomeModule).injector; + expect(injector.get('token1')).toBe('exported'); + }); - it('should not overwrite the providers if a module was already used on the same level', - () => { - @NgModule({providers: [{provide: 'token1', useValue: 'imported1'}]}) - class ImportedModule1 { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should not overwrite the providers if a module was already used on the same level', + () => { + @NgModule({providers: [{provide: 'token1', useValue: 'imported1'}]}) + class ImportedModule1 { + } - @NgModule({providers: [{provide: 'token1', useValue: 'imported2'}]}) - class ImportedModule2 { - } + @NgModule({providers: [{provide: 'token1', useValue: 'imported2'}]}) + class ImportedModule2 { + } - @NgModule({imports: [ImportedModule1, ImportedModule2, ImportedModule1]}) - class SomeModule { - } + @NgModule({imports: [ImportedModule1, ImportedModule2, ImportedModule1]}) + class SomeModule { + } - const injector = createModule(SomeModule).injector; - expect(injector.get('token1')).toBe('imported2'); - }); + const injector = createModule(SomeModule).injector; + expect(injector.get('token1')).toBe('imported2'); + }); - it('should not overwrite the providers if a module was already used on a child level', - () => { - @NgModule({providers: [{provide: 'token1', useValue: 'imported1'}]}) - class ImportedModule1 { - } + fixmeIvy('FW-561: Runtime compiler is not loaded') && + it('should not overwrite the providers if a module was already used on a child level', + () => { + @NgModule({providers: [{provide: 'token1', useValue: 'imported1'}]}) + class ImportedModule1 { + } - @NgModule({imports: [ImportedModule1]}) - class ImportedModule3 { - } + @NgModule({imports: [ImportedModule1]}) + class ImportedModule3 { + } - @NgModule({providers: [{provide: 'token1', useValue: 'imported2'}]}) - class ImportedModule2 { - } + @NgModule({providers: [{provide: 'token1', useValue: 'imported2'}]}) + class ImportedModule2 { + } - @NgModule({imports: [ImportedModule3, ImportedModule2, ImportedModule1]}) - class SomeModule { - } + @NgModule({imports: [ImportedModule3, ImportedModule2, ImportedModule1]}) + class SomeModule { + } - const injector = createModule(SomeModule).injector; - expect(injector.get('token1')).toBe('imported2'); - }); + const injector = createModule(SomeModule).injector; + expect(injector.get('token1')).toBe('imported2'); + }); - it('should throw when given invalid providers in an imported ModuleWithProviders', () => { - @NgModule() - class ImportedModule1 { - } + fixmeIvy('unknown') && + it('should throw when given invalid providers in an imported ModuleWithProviders', () => { + @NgModule() + class ImportedModule1 { + } - @NgModule({imports: [{ngModule: ImportedModule1, providers: ['broken']}]}) - class SomeModule { - } + @NgModule({imports: [{ngModule: ImportedModule1, providers: ['broken']}]}) + class SomeModule { + } - expect(() => createModule(SomeModule).injector) - .toThrowError( - `Invalid provider for the NgModule 'ImportedModule1' - only instances of Provider and Type are allowed, got: [?broken?]`); - }); + expect(() => createModule(SomeModule).injector) + .toThrowError( + `Invalid provider for the NgModule 'ImportedModule1' - only instances of Provider and Type are allowed, got: [?broken?]`); + }); }); describe('tree shakable providers', () => { - it('definition should not persist across NgModuleRef instances', () => { - @NgModule() - class SomeModule { - } + fixmeIvy('unknown') && + it('definition should not persist across NgModuleRef instances', () => { + @NgModule() + class SomeModule { + } - class Bar { - static ngInjectableDef: InjectableDef = defineInjectable({ - factory: () => new Bar(), - providedIn: SomeModule, + class Bar { + static ngInjectableDef: InjectableDef = defineInjectable({ + factory: () => new Bar(), + providedIn: SomeModule, + }); + } + + const factory = createModuleFactory(SomeModule); + const ngModuleRef1 = factory.create(null); + + // Inject a tree shakeable provider token. + ngModuleRef1.injector.get(Bar); + + // Tree Shakeable provider definition should get added to the NgModule data. + const providerDef1 = + (ngModuleRef1 as NgModuleData)._def.providersByKey[tokenKey(Bar)]; + expect(providerDef1).not.toBeUndefined(); + + // Instantiate the same module. The tree shakeable provider + // definition should not already be present. + const ngModuleRef2 = factory.create(null); + const providerDef2 = + (ngModuleRef2 as NgModuleData)._def.providersByKey[tokenKey(Bar)]; + expect(providerDef2).toBeUndefined(); }); - } - - const factory = createModuleFactory(SomeModule); - const ngModuleRef1 = factory.create(null); - - // Inject a tree shakeable provider token. - ngModuleRef1.injector.get(Bar); - - // Tree Shakeable provider definition should get added to the NgModule data. - const providerDef1 = (ngModuleRef1 as NgModuleData)._def.providersByKey[tokenKey(Bar)]; - expect(providerDef1).not.toBeUndefined(); - - // Instantiate the same module. The tree shakeable provider - // definition should not already be present. - const ngModuleRef2 = factory.create(null); - const providerDef2 = (ngModuleRef2 as NgModuleData)._def.providersByKey[tokenKey(Bar)]; - expect(providerDef2).toBeUndefined(); - }); }); }); }); diff --git a/packages/core/test/linker/projection_integration_spec.ts b/packages/core/test/linker/projection_integration_spec.ts index 2cb04d34ff..f7a58249b4 100644 --- a/packages/core/test/linker/projection_integration_spec.ts +++ b/packages/core/test/linker/projection_integration_spec.ts @@ -14,7 +14,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers'; import {fixmeIvy} from '@angular/private/testing'; { - fixmeIvy('unknown') && describe('projection', () => { + describe('projection', () => { beforeEach(() => TestBed.configureTestingModule({declarations: [MainComp, OtherComp, Simple]})); it('should support simple components', () => { @@ -82,7 +82,7 @@ import {fixmeIvy} from '@angular/private/testing'; expect(main.nativeElement).toHaveText(''); }); - it('should support multiple content tags', () => { + fixmeIvy('unknown') && it('should support multiple content tags', () => { TestBed.configureTestingModule({declarations: [MultipleContentTagsComponent]}); TestBed.overrideComponent(MainComp, { set: { @@ -113,33 +113,34 @@ import {fixmeIvy} from '@angular/private/testing'; expect(main.nativeElement).toHaveText('(, BAC)'); }); - it('should redistribute direct child viewcontainers when the light dom changes', () => { - TestBed.configureTestingModule( - {declarations: [MultipleContentTagsComponent, ManualViewportDirective]}); - TestBed.overrideComponent(MainComp, { - set: { - template: '' + - '
A1
' + - '
B
' + - '
' - } - }); - const main = TestBed.createComponent(MainComp); + fixmeIvy('FW-665: Unable to find the given context data for the given target') && + it('should redistribute direct child viewcontainers when the light dom changes', () => { + TestBed.configureTestingModule( + {declarations: [MultipleContentTagsComponent, ManualViewportDirective]}); + TestBed.overrideComponent(MainComp, { + set: { + template: '' + + '
A1
' + + '
B
' + + '
' + } + }); + const main = TestBed.createComponent(MainComp); - const viewportDirectives = main.debugElement.children[0] - .childNodes.filter(By.directive(ManualViewportDirective)) - .map(de => de.injector.get(ManualViewportDirective)); + const viewportDirectives = main.debugElement.children[0] + .childNodes.filter(By.directive(ManualViewportDirective)) + .map(de => de.injector.get(ManualViewportDirective)); - expect(main.nativeElement).toHaveText('(, B)'); + expect(main.nativeElement).toHaveText('(, B)'); - viewportDirectives.forEach(d => d.show()); - main.detectChanges(); - expect(main.nativeElement).toHaveText('(A1, B)'); + viewportDirectives.forEach(d => d.show()); + main.detectChanges(); + expect(main.nativeElement).toHaveText('(A1, B)'); - viewportDirectives.forEach(d => d.hide()); - main.detectChanges(); - expect(main.nativeElement).toHaveText('(, B)'); - }); + viewportDirectives.forEach(d => d.hide()); + main.detectChanges(); + expect(main.nativeElement).toHaveText('(, B)'); + }); it('should support nested components', () => { TestBed.configureTestingModule({declarations: [OuterWithIndirectNestedComponent]}); @@ -156,33 +157,34 @@ import {fixmeIvy} from '@angular/private/testing'; expect(main.nativeElement).toHaveText('OUTER(SIMPLE(AB))'); }); - it('should support nesting with content being direct child of a nested component', () => { - TestBed.configureTestingModule({ - declarations: - [InnerComponent, InnerInnerComponent, OuterComponent, ManualViewportDirective] - }); - TestBed.overrideComponent(MainComp, { - set: { - template: '' + - '
A
' + - '
B
' + - '
C
' + - '
' - } - }); - const main = TestBed.createComponent(MainComp); + fixmeIvy('FW-665: Unable to find the given context data for the given target') && + it('should support nesting with content being direct child of a nested component', () => { + TestBed.configureTestingModule({ + declarations: + [InnerComponent, InnerInnerComponent, OuterComponent, ManualViewportDirective] + }); + TestBed.overrideComponent(MainComp, { + set: { + template: '' + + '
A
' + + '
B
' + + '
C
' + + '
' + } + }); + const main = TestBed.createComponent(MainComp); - const viewportDirective = - main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get( - ManualViewportDirective); + const viewportDirective = + main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0] + .injector.get(ManualViewportDirective); - expect(main.nativeElement).toHaveText('OUTER(INNER(INNERINNER(,BC)))'); - viewportDirective.show(); + expect(main.nativeElement).toHaveText('OUTER(INNER(INNERINNER(,BC)))'); + viewportDirective.show(); - expect(main.nativeElement).toHaveText('OUTER(INNER(INNERINNER(A,BC)))'); - }); + expect(main.nativeElement).toHaveText('OUTER(INNER(INNERINNER(A,BC)))'); + }); - it('should redistribute when the shadow dom changes', () => { + fixmeIvy('unknown') && it('should redistribute when the shadow dom changes', () => { TestBed.configureTestingModule( {declarations: [ConditionalContentComponent, ManualViewportDirective]}); TestBed.overrideComponent(MainComp, { @@ -237,37 +239,38 @@ import {fixmeIvy} from '@angular/private/testing'; expect(main.nativeElement).toHaveText('P,text'); }); - it('should support moving non projected light dom around', () => { - let sourceDirective: ManualViewportDirective = undefined !; + fixmeIvy('FW-665: Unable to find the given context data for the given target') && + it('should support moving non projected light dom around', () => { + let sourceDirective: ManualViewportDirective = undefined !; - @Directive({selector: '[manual]'}) - class ManualViewportDirective { - constructor(public templateRef: TemplateRef) { sourceDirective = this; } - } + @Directive({selector: '[manual]'}) + class ManualViewportDirective { + constructor(public templateRef: TemplateRef) { sourceDirective = this; } + } - TestBed.configureTestingModule( - {declarations: [Empty, ProjectDirective, ManualViewportDirective]}); - TestBed.overrideComponent(MainComp, { - set: { - template: '' + - '
A
' + - '
' + - 'START(
)END' - } - }); - const main = TestBed.createComponent(MainComp); + TestBed.configureTestingModule( + {declarations: [Empty, ProjectDirective, ManualViewportDirective]}); + TestBed.overrideComponent(MainComp, { + set: { + template: '' + + '
A
' + + '
' + + 'START(
)END' + } + }); + const main = TestBed.createComponent(MainComp); - const projectDirective: ProjectDirective = - main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].injector.get( - ProjectDirective); + const projectDirective: ProjectDirective = + main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].injector.get( + ProjectDirective); - expect(main.nativeElement).toHaveText('START()END'); + expect(main.nativeElement).toHaveText('START()END'); - projectDirective.show(sourceDirective.templateRef); - expect(main.nativeElement).toHaveText('START(A)END'); - }); + projectDirective.show(sourceDirective.templateRef); + expect(main.nativeElement).toHaveText('START(A)END'); + }); - it('should support moving projected light dom around', () => { + fixmeIvy('unknown') && it('should support moving projected light dom around', () => { TestBed.configureTestingModule( {declarations: [Empty, ProjectDirective, ManualViewportDirective]}); TestBed.overrideComponent(MainComp, { @@ -290,83 +293,89 @@ import {fixmeIvy} from '@angular/private/testing'; expect(main.nativeElement).toHaveText('SIMPLE()START(A)END'); }); - it('should support moving ng-content around', () => { - TestBed.configureTestingModule( - {declarations: [ConditionalContentComponent, ProjectDirective, ManualViewportDirective]}); - TestBed.overrideComponent(MainComp, { - set: { - template: '' + - '
A
' + - '
B
' + - '
' + - 'START(
)END' - } - }); - const main = TestBed.createComponent(MainComp); + fixmeIvy('FW-665: Unable to find the given context data for the given target') && + it('should support moving ng-content around', () => { + TestBed.configureTestingModule({ + declarations: + [ConditionalContentComponent, ProjectDirective, ManualViewportDirective] + }); + TestBed.overrideComponent(MainComp, { + set: { + template: '' + + '
A
' + + '
B
' + + '
' + + 'START(
)END' + } + }); + const main = TestBed.createComponent(MainComp); - const sourceDirective: ManualViewportDirective = - main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get( - ManualViewportDirective); - const projectDirective: ProjectDirective = - main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].injector.get( - ProjectDirective); - expect(main.nativeElement).toHaveText('(, B)START()END'); + const sourceDirective: ManualViewportDirective = + main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0] + .injector.get(ManualViewportDirective); + const projectDirective: ProjectDirective = + main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].injector.get( + ProjectDirective); + expect(main.nativeElement).toHaveText('(, B)START()END'); - projectDirective.show(sourceDirective.templateRef); - expect(main.nativeElement).toHaveText('(, B)START(A)END'); + projectDirective.show(sourceDirective.templateRef); + expect(main.nativeElement).toHaveText('(, B)START(A)END'); - // Stamping ng-content multiple times should not produce the content multiple - // times... - projectDirective.show(sourceDirective.templateRef); - expect(main.nativeElement).toHaveText('(, B)START(A)END'); - }); + // Stamping ng-content multiple times should not produce the content multiple + // times... + projectDirective.show(sourceDirective.templateRef); + expect(main.nativeElement).toHaveText('(, B)START(A)END'); + }); // Note: This does not use a ng-content element, but // is still important as we are merging proto views independent of // the presence of ng-content elements! - it('should still allow to implement a recursive trees', () => { - TestBed.configureTestingModule({declarations: [Tree, ManualViewportDirective]}); - TestBed.overrideComponent(MainComp, {set: {template: ''}}); - const main = TestBed.createComponent(MainComp); + fixmeIvy('FW-665: Unable to find the given context data for the given target') && + it('should still allow to implement a recursive trees', () => { + TestBed.configureTestingModule({declarations: [Tree, ManualViewportDirective]}); + TestBed.overrideComponent(MainComp, {set: {template: ''}}); + const main = TestBed.createComponent(MainComp); - main.detectChanges(); - const manualDirective: ManualViewportDirective = - main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get( - ManualViewportDirective); - expect(main.nativeElement).toHaveText('TREE(0:)'); - manualDirective.show(); - main.detectChanges(); - expect(main.nativeElement).toHaveText('TREE(0:TREE(1:))'); - }); + main.detectChanges(); + const manualDirective: ManualViewportDirective = + main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0] + .injector.get(ManualViewportDirective); + expect(main.nativeElement).toHaveText('TREE(0:)'); + manualDirective.show(); + main.detectChanges(); + expect(main.nativeElement).toHaveText('TREE(0:TREE(1:))'); + }); // Note: This does not use a ng-content element, but // is still important as we are merging proto views independent of // the presence of ng-content elements! - it('should still allow to implement a recursive trees via multiple components', () => { - TestBed.configureTestingModule({declarations: [Tree, Tree2, ManualViewportDirective]}); - TestBed.overrideComponent(MainComp, {set: {template: ''}}); - TestBed.overrideComponent( - Tree, {set: {template: 'TREE({{depth}}:)'}}); - const main = TestBed.createComponent(MainComp); + 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', () => { + TestBed.configureTestingModule({declarations: [Tree, Tree2, ManualViewportDirective]}); + TestBed.overrideComponent(MainComp, {set: {template: ''}}); + TestBed.overrideComponent( + Tree, {set: {template: 'TREE({{depth}}:)'}}); + 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)); - let manualDirective: ManualViewportDirective = tree.queryAllNodes(By.directive( - ManualViewportDirective))[0].injector.get(ManualViewportDirective); - manualDirective.show(); - main.detectChanges(); - expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:))'); + const tree = main.debugElement.query(By.directive(Tree)); + let manualDirective: ManualViewportDirective = tree.queryAllNodes(By.directive( + ManualViewportDirective))[0].injector.get(ManualViewportDirective); + manualDirective.show(); + main.detectChanges(); + expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:))'); - const tree2 = main.debugElement.query(By.directive(Tree2)); - manualDirective = tree2.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get( - ManualViewportDirective); - manualDirective.show(); - main.detectChanges(); - expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:TREE(2:)))'); - }); + const tree2 = main.debugElement.query(By.directive(Tree2)); + manualDirective = + tree2.queryAllNodes(By.directive(ManualViewportDirective))[0].injector.get( + ManualViewportDirective); + manualDirective.show(); + main.detectChanges(); + expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:TREE(2:)))'); + }); if (getDOM().supportsNativeShadowDOM()) { it('should support native content projection and isolate styles per component', () => { @@ -427,38 +436,41 @@ import {fixmeIvy} from '@angular/private/testing'; }); } - it('should support nested conditionals that contain ng-contents', () => { - TestBed.configureTestingModule( - {declarations: [ConditionalTextComponent, ManualViewportDirective]}); - TestBed.overrideComponent( - MainComp, {set: {template: `a`}}); - const main = TestBed.createComponent(MainComp); + fixmeIvy('FW-665: Unable to find the given context data for the given target') && + it('should support nested conditionals that contain ng-contents', () => { + TestBed.configureTestingModule( + {declarations: [ConditionalTextComponent, ManualViewportDirective]}); + TestBed.overrideComponent( + MainComp, {set: {template: `a`}}); + const main = TestBed.createComponent(MainComp); - expect(main.nativeElement).toHaveText('MAIN()'); + expect(main.nativeElement).toHaveText('MAIN()'); - let viewportElement = - main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0]; - viewportElement.injector.get(ManualViewportDirective).show(); - expect(main.nativeElement).toHaveText('MAIN(FIRST())'); + let viewportElement = + main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0]; + viewportElement.injector.get(ManualViewportDirective).show(); + expect(main.nativeElement).toHaveText('MAIN(FIRST())'); - viewportElement = main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[1]; - viewportElement.injector.get(ManualViewportDirective).show(); - expect(main.nativeElement).toHaveText('MAIN(FIRST(SECOND(a)))'); - }); + viewportElement = + main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[1]; + viewportElement.injector.get(ManualViewportDirective).show(); + expect(main.nativeElement).toHaveText('MAIN(FIRST(SECOND(a)))'); + }); - it('should allow to switch the order of nested components via ng-content', () => { - TestBed.configureTestingModule({declarations: [CmpA, CmpB, CmpD, CmpC]}); - TestBed.overrideComponent(MainComp, {set: {template: ``}}); - const main = TestBed.createComponent(MainComp); + fixmeIvy('unknown') && + it('should allow to switch the order of nested components via ng-content', () => { + TestBed.configureTestingModule({declarations: [CmpA, CmpB, CmpD, CmpC]}); + TestBed.overrideComponent(MainComp, {set: {template: ``}}); + const main = TestBed.createComponent(MainComp); - main.detectChanges(); - expect(getDOM().getInnerHTML(main.nativeElement)) - .toEqual( - 'cmp-d' + - 'cmp-c'); - }); + main.detectChanges(); + expect(getDOM().getInnerHTML(main.nativeElement)) + .toEqual( + 'cmp-d' + + 'cmp-c'); + }); - it('should create nested components in the right order', () => { + fixmeIvy('unknown') && it('should create nested components in the right order', () => { TestBed.configureTestingModule( {declarations: [CmpA1, CmpA2, CmpB11, CmpB12, CmpB21, CmpB22]}); TestBed.overrideComponent(MainComp, {set: {template: ``}}); @@ -471,7 +483,7 @@ import {fixmeIvy} from '@angular/private/testing'; 'a2b21b22'); }); - it('should project filled view containers into a view container', () => { + fixmeIvy('unknown') && it('should project filled view containers into a view container', () => { TestBed.configureTestingModule( {declarations: [ConditionalContentComponent, ManualViewportDirective]}); TestBed.overrideComponent(MainComp, { diff --git a/packages/core/test/linker/query_integration_spec.ts b/packages/core/test/linker/query_integration_spec.ts index f4dc6ebdd8..17ba44ff88 100644 --- a/packages/core/test/linker/query_integration_spec.ts +++ b/packages/core/test/linker/query_integration_spec.ts @@ -14,629 +14,671 @@ import {Subject} from 'rxjs'; import {stringify} from '../../src/util'; -{ - fixmeIvy('unknown') && describe('Query API', () => { +// FW-670: Internal Error: The name q is already defined in scope +fixmeIvy('FW-670') && describe('Query API', () => { - beforeEach(() => TestBed.configureTestingModule({ - declarations: [ - MyComp0, - NeedsQuery, - NeedsQueryDesc, - NeedsQueryByLabel, - NeedsQueryByTwoLabels, - NeedsQueryAndProject, - NeedsViewQuery, - NeedsViewQueryIf, - NeedsViewQueryNestedIf, - NeedsViewQueryOrder, - NeedsViewQueryByLabel, - NeedsViewQueryOrderWithParent, - NeedsContentChildren, - NeedsViewChildren, - NeedsViewChild, - NeedsStaticContentAndViewChild, - NeedsContentChild, - DirectiveNeedsContentChild, - NeedsTpl, - NeedsNamedTpl, - TextDirective, - InertDirective, - NeedsFourQueries, - NeedsContentChildrenWithRead, - NeedsContentChildWithRead, - NeedsViewChildrenWithRead, - NeedsViewChildWithRead, - NeedsContentChildTemplateRef, - NeedsContentChildTemplateRefApp, - NeedsViewContainerWithRead, - ManualProjecting - ] - })); + beforeEach(() => TestBed.configureTestingModule({ + declarations: [ + MyComp0, + NeedsQuery, + NeedsQueryDesc, + NeedsQueryByLabel, + NeedsQueryByTwoLabels, + NeedsQueryAndProject, + NeedsViewQuery, + NeedsViewQueryIf, + NeedsViewQueryNestedIf, + NeedsViewQueryOrder, + NeedsViewQueryByLabel, + NeedsViewQueryOrderWithParent, + NeedsContentChildren, + NeedsViewChildren, + NeedsViewChild, + NeedsStaticContentAndViewChild, + NeedsContentChild, + DirectiveNeedsContentChild, + NeedsTpl, + NeedsNamedTpl, + TextDirective, + InertDirective, + NeedsFourQueries, + NeedsContentChildrenWithRead, + NeedsContentChildWithRead, + NeedsViewChildrenWithRead, + NeedsViewChildWithRead, + NeedsContentChildTemplateRef, + NeedsContentChildTemplateRefApp, + NeedsViewContainerWithRead, + ManualProjecting + ] + })); - describe('querying by directive type', () => { - it('should contain all direct child directives in the light dom (constructor)', () => { - const template = '
' + - '
' + - '
' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); + describe('querying by directive type', () => { + it('should contain all direct child directives in the light dom (constructor)', () => { + const template = '
' + + '
' + + '
' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); - expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|'); - }); - - it('should contain all direct child directives in the content dom', () => { - const template = - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - const q = view.debugElement.children[0].references !['q']; - view.detectChanges(); - expect(q.textDirChildren.length).toEqual(1); - expect(q.numberOfChildrenAfterContentInit).toEqual(1); - }); - - it('should contain the first content child', () => { - const template = - '
'; - const view = createTestCmp(MyComp0, template); - view.componentInstance.shouldShow = true; - view.detectChanges(); - const q: NeedsContentChild = view.debugElement.children[0].references !['q']; - expect(q.logs).toEqual([['setter', 'foo'], ['init', 'foo'], ['check', 'foo']]); - - view.componentInstance.shouldShow = false; - view.detectChanges(); - expect(q.logs).toEqual([ - ['setter', 'foo'], ['init', 'foo'], ['check', 'foo'], ['setter', null], ['check', null] - ]); - }); - - it('should contain the first content child when target is on with embedded view (issue #16568)', - () => { - const template = - '
' + - '
'; - const view = createTestCmp(MyComp0, template); - view.detectChanges(); - const q: NeedsContentChild = view.debugElement.children[1].references !['q']; - expect(q.child.text).toEqual('foo'); - const directive: DirectiveNeedsContentChild = - view.debugElement.children[0].injector.get(DirectiveNeedsContentChild); - expect(directive.child.text).toEqual('foo'); - }); - - it('should contain the first view child', () => { - const template = ''; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - const q: NeedsViewChild = view.debugElement.children[0].references !['q']; - expect(q.logs).toEqual([['setter', 'foo'], ['init', 'foo'], ['check', 'foo']]); - - q.shouldShow = false; - view.detectChanges(); - expect(q.logs).toEqual([ - ['setter', 'foo'], ['init', 'foo'], ['check', 'foo'], ['setter', null], ['check', null] - ]); - }); - - it('should set static view and content children already after the constructor call', () => { - const template = - '
'; - const view = createTestCmp(MyComp0, template); - const q: NeedsStaticContentAndViewChild = view.debugElement.children[0].references !['q']; - expect(q.contentChild.text).toBeFalsy(); - expect(q.viewChild.text).toBeFalsy(); - - view.detectChanges(); - expect(q.contentChild.text).toEqual('contentFoo'); - expect(q.viewChild.text).toEqual('viewFoo'); - }); - - it('should contain the first view child across embedded views', () => { - TestBed.overrideComponent( - MyComp0, {set: {template: ''}}); - TestBed.overrideComponent(NeedsViewChild, { - set: { - template: - '
' - } - }); - const view = TestBed.createComponent(MyComp0); - - view.detectChanges(); - const q: NeedsViewChild = view.debugElement.children[0].references !['q']; - expect(q.logs).toEqual([['setter', 'foo'], ['init', 'foo'], ['check', 'foo']]); - - q.shouldShow = false; - q.shouldShow2 = true; - q.logs = []; - view.detectChanges(); - expect(q.logs).toEqual([['setter', 'bar'], ['check', 'bar']]); - - q.shouldShow = false; - q.shouldShow2 = false; - q.logs = []; - view.detectChanges(); - expect(q.logs).toEqual([['setter', null], ['check', null]]); - }); - - it('should contain all directives in the light dom when descendants flag is used', () => { - const template = '
' + - '
' + - '
' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|4|'); - }); - - it('should contain all directives in the light dom', () => { - const template = '
' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|'); - }); - - it('should reflect dynamically inserted directives', () => { - const template = '
' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - expect(asNativeElements(view.debugElement.children)).toHaveText('2|'); - - view.componentInstance.shouldShow = true; - view.detectChanges(); - expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|'); - }); - - it('should be cleanly destroyed when a query crosses view boundaries', () => { - const template = '
' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - view.componentInstance.shouldShow = true; - view.detectChanges(); - view.destroy(); - }); - - it('should reflect moved directives', () => { - const template = '
' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - expect(asNativeElements(view.debugElement.children)).toHaveText('2|1d|2d|3d|'); - - view.componentInstance.list = ['3d', '2d']; - view.detectChanges(); - expect(asNativeElements(view.debugElement.children)).toHaveText('2|3d|2d|'); - }); - - it('should throw with descriptive error when query selectors are not present', () => { - TestBed.configureTestingModule({declarations: [MyCompBroken0, HasNullQueryCondition]}); - const template = ''; - TestBed.overrideComponent(MyCompBroken0, {set: {template}}); - expect(() => TestBed.createComponent(MyCompBroken0)) - .toThrowError( - `Can't construct a query for the property "errorTrigger" of "${stringify(HasNullQueryCondition)}" since the query selector wasn't defined.`); - }); + expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|'); }); - describe('query for TemplateRef', () => { - it('should find TemplateRefs in the light and shadow dom', () => { - const template = '
light
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const needsTpl: NeedsTpl = view.debugElement.children[0].injector.get(NeedsTpl); + it('should contain all direct child directives in the content dom', () => { + const template = '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); - expect(needsTpl.vc.createEmbeddedView(needsTpl.query.first).rootNodes[0]) - .toHaveText('light'); - expect(needsTpl.vc.createEmbeddedView(needsTpl.viewQuery.first).rootNodes[0]) - .toHaveText('shadow'); - }); - - it('should find named TemplateRefs', () => { - const template = - '
light
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const needsTpl: NeedsNamedTpl = view.debugElement.children[0].injector.get(NeedsNamedTpl); - expect(needsTpl.vc.createEmbeddedView(needsTpl.contentTpl).rootNodes[0]) - .toHaveText('light'); - expect(needsTpl.vc.createEmbeddedView(needsTpl.viewTpl).rootNodes[0]).toHaveText('shadow'); - }); + const q = view.debugElement.children[0].references !['q']; + view.detectChanges(); + expect(q.textDirChildren.length).toEqual(1); + expect(q.numberOfChildrenAfterContentInit).toEqual(1); }); - describe('read a different token', () => { - it('should contain all content children', () => { - const template = - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); + it('should contain the first content child', () => { + const template = + '
'; + const view = createTestCmp(MyComp0, template); + view.componentInstance.shouldShow = true; + view.detectChanges(); + const q: NeedsContentChild = view.debugElement.children[0].references !['q']; + expect(q.logs).toEqual([['setter', 'foo'], ['init', 'foo'], ['check', 'foo']]); - const comp: NeedsContentChildrenWithRead = - view.debugElement.children[0].injector.get(NeedsContentChildrenWithRead); - expect(comp.textDirChildren.map(textDirective => textDirective.text)).toEqual(['ca', 'cb']); - }); - - it('should contain the first content child', () => { - const template = - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - const comp: NeedsContentChildWithRead = - view.debugElement.children[0].injector.get(NeedsContentChildWithRead); - expect(comp.textDirChild.text).toEqual('ca'); - }); - - it('should contain the first descendant content child', () => { - const template = '' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - const comp: NeedsContentChildWithRead = - view.debugElement.children[0].injector.get(NeedsContentChildWithRead); - expect(comp.textDirChild.text).toEqual('ca'); - }); - - it('should contain the first descendant content child templateRef', () => { - const template = '' + - ''; - const view = createTestCmp(MyComp0, template); - - // can't execute checkNoChanges as our view modifies our content children (via a query). - view.detectChanges(false); - expect(view.nativeElement).toHaveText('OUTER'); - }); - - it('should contain the first view child', () => { - const template = ''; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - const comp: NeedsViewChildWithRead = - view.debugElement.children[0].injector.get(NeedsViewChildWithRead); - expect(comp.textDirChild.text).toEqual('va'); - }); - - it('should contain all child directives in the view', () => { - const template = ''; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - const comp: NeedsViewChildrenWithRead = - view.debugElement.children[0].injector.get(NeedsViewChildrenWithRead); - expect(comp.textDirChildren.map(textDirective => textDirective.text)).toEqual(['va', 'vb']); - }); - - it('should support reading a ViewContainer', () => { - const template = - 'hello'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - const comp: NeedsViewContainerWithRead = - view.debugElement.children[0].injector.get(NeedsViewContainerWithRead); - comp.createView(); - expect(view.debugElement.children[0].nativeElement).toHaveText('hello'); - }); + view.componentInstance.shouldShow = false; + view.detectChanges(); + expect(q.logs).toEqual([ + ['setter', 'foo'], ['init', 'foo'], ['check', 'foo'], ['setter', null], ['check', null] + ]); }); - describe('changes', () => { - it('should notify query on change', async(() => { - const template = '' + - '
' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); + it('should contain the first content child when target is on with embedded view (issue #16568)', + () => { + const template = + '
' + + '
'; + const view = createTestCmp(MyComp0, template); + view.detectChanges(); + const q: NeedsContentChild = view.debugElement.children[1].references !['q']; + expect(q.child.text).toEqual('foo'); + const directive: DirectiveNeedsContentChild = + view.debugElement.children[0].injector.get(DirectiveNeedsContentChild); + expect(directive.child.text).toEqual('foo'); + }); - const q = view.debugElement.children[0].references !['q']; + it('should contain the first view child', () => { + const template = ''; + const view = createTestCmpAndDetectChanges(MyComp0, template); - q.query.changes.subscribe({ - next: () => { - expect(q.query.first.text).toEqual('1'); - expect(q.query.last.text).toEqual('2'); - } - }); + const q: NeedsViewChild = view.debugElement.children[0].references !['q']; + expect(q.logs).toEqual([['setter', 'foo'], ['init', 'foo'], ['check', 'foo']]); - view.componentInstance.shouldShow = true; - view.detectChanges(); - })); - - it('should correctly clean-up when destroyed together with the directives it is querying', - () => { - const template = - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - view.componentInstance.shouldShow = true; - view.detectChanges(); - - let isQueryListCompleted = false; - - const q: NeedsQuery = view.debugElement.children[0].references !['q']; - const changes = >q.query.changes; - expect(q.query.length).toEqual(1); - expect(changes.closed).toBeFalsy(); - changes.subscribe(() => {}, () => {}, () => { isQueryListCompleted = true; }); - - view.componentInstance.shouldShow = false; - view.detectChanges(); - expect(changes.closed).toBeTruthy(); - expect(isQueryListCompleted).toBeTruthy(); - - view.componentInstance.shouldShow = true; - view.detectChanges(); - const q2: NeedsQuery = view.debugElement.children[0].references !['q']; - - expect(q2.query.length).toEqual(1); - expect(changes.closed).toBeTruthy(); - expect((>q2.query.changes).closed).toBeFalsy(); - }); + q.shouldShow = false; + view.detectChanges(); + expect(q.logs).toEqual([ + ['setter', 'foo'], ['init', 'foo'], ['check', 'foo'], ['setter', null], ['check', null] + ]); }); - describe('querying by var binding', () => { - it('should contain all the child directives in the light dom with the given var binding', - () => { - const template = '' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q = view.debugElement.children[0].references !['q']; + it('should set static view and content children already after the constructor call', () => { + const template = + '
'; + const view = createTestCmp(MyComp0, template); + const q: NeedsStaticContentAndViewChild = view.debugElement.children[0].references !['q']; + expect(q.contentChild.text).toBeFalsy(); + expect(q.viewChild.text).toBeFalsy(); - view.componentInstance.list = ['1d', '2d']; - view.detectChanges(); - expect(q.query.first.text).toEqual('1d'); - expect(q.query.last.text).toEqual('2d'); - }); - - it('should support querying by multiple var bindings', () => { - const template = '' + - '
' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q = view.debugElement.children[0].references !['q']; - - expect(q.query.first.text).toEqual('one'); - expect(q.query.last.text).toEqual('two'); - }); - - it('should support dynamically inserted directives', () => { - const template = '' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q = view.debugElement.children[0].references !['q']; - - view.componentInstance.list = ['1d', '2d']; - view.detectChanges(); - view.componentInstance.list = ['2d', '1d']; - view.detectChanges(); - expect(q.query.last.text).toEqual('1d'); - }); - - it('should contain all the elements in the light dom with the given var binding', () => { - const template = '' + - '
' + - '
{{item}}
' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q = view.debugElement.children[0].references !['q']; - - view.componentInstance.list = ['1d', '2d']; - view.detectChanges(); - expect(q.query.first.nativeElement).toHaveText('1d'); - expect(q.query.last.nativeElement).toHaveText('2d'); - }); - - it('should contain all the elements in the light dom even if they get projected', () => { - const template = '' + - '
' + - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - expect(asNativeElements(view.debugElement.children)).toHaveText('hello|world|'); - }); - - it('should support querying the view by using a view query', () => { - const template = ''; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - const q: NeedsViewQueryByLabel = view.debugElement.children[0].references !['q']; - expect(q.query.first.nativeElement).toHaveText('text'); - }); - - it('should contain all child directives in the view dom', () => { - const template = ''; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q = view.debugElement.children[0].references !['q']; - expect(q.textDirChildren.length).toEqual(1); - expect(q.numberOfChildrenAfterViewInit).toEqual(1); - }); + view.detectChanges(); + expect(q.contentChild.text).toEqual('contentFoo'); + expect(q.viewChild.text).toEqual('viewFoo'); }); - describe('querying in the view', () => { - it('should contain all the elements in the view with that have the given directive', () => { - const template = '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q: NeedsViewQuery = view.debugElement.children[0].references !['q']; - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); - }); - - it('should not include directive present on the host element', () => { - const template = ''; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q: NeedsViewQuery = view.debugElement.children[0].references !['q']; - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); - }); - - it('should reflect changes in the component', () => { - const template = ''; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q: NeedsViewQueryIf = view.debugElement.children[0].references !['q']; - expect(q.query.length).toBe(0); - - q.show = true; - view.detectChanges(); - expect(q.query.length).toBe(1); - expect(q.query.first.text).toEqual('1'); - }); - - it('should not be affected by other changes in the component', () => { - const template = ''; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q: NeedsViewQueryNestedIf = view.debugElement.children[0].references !['q']; - - expect(q.query.length).toEqual(1); - expect(q.query.first.text).toEqual('1'); - - q.show = false; - view.detectChanges(); - expect(q.query.length).toEqual(1); - expect(q.query.first.text).toEqual('1'); - }); - - it('should maintain directives in pre-order depth-first DOM order after dynamic insertion', - () => { - const template = ''; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q: NeedsViewQueryOrder = view.debugElement.children[0].references !['q']; - - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); - - q.list = ['-3', '2']; - view.detectChanges(); - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '-3', '2', '4']); - }); - - it('should maintain directives in pre-order depth-first DOM order after dynamic insertion', - () => { - const template = ''; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q: NeedsViewQueryOrderWithParent = view.debugElement.children[0].references !['q']; - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); - - q.list = ['-3', '2']; - view.detectChanges(); - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '-3', '2', '4']); - }); - - it('should handle long ngFor cycles', () => { - const template = ''; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q: NeedsViewQueryOrder = view.debugElement.children[0].references !['q']; - - // no significance to 50, just a reasonably large cycle. - for (let i = 0; i < 50; i++) { - const newString = i.toString(); - q.list = [newString]; - view.detectChanges(); - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', newString, '4']); + it('should contain the first view child across embedded views', () => { + TestBed.overrideComponent( + MyComp0, {set: {template: ''}}); + TestBed.overrideComponent(NeedsViewChild, { + set: { + template: + '
' } }); + const view = TestBed.createComponent(MyComp0); - it('should support more than three queries', () => { - const template = '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q = view.debugElement.children[0].references !['q']; - expect(q.query1).toBeDefined(); - expect(q.query2).toBeDefined(); - expect(q.query3).toBeDefined(); - expect(q.query4).toBeDefined(); - }); + view.detectChanges(); + const q: NeedsViewChild = view.debugElement.children[0].references !['q']; + expect(q.logs).toEqual([['setter', 'foo'], ['init', 'foo'], ['check', 'foo']]); + + q.shouldShow = false; + q.shouldShow2 = true; + q.logs = []; + view.detectChanges(); + expect(q.logs).toEqual([['setter', 'bar'], ['check', 'bar']]); + + q.shouldShow = false; + q.shouldShow2 = false; + q.logs = []; + view.detectChanges(); + expect(q.logs).toEqual([['setter', null], ['check', null]]); }); - describe('query over moved templates', () => { - it('should include manually projected templates in queries', () => { - const template = - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q = view.debugElement.children[0].references !['q']; - expect(q.query.length).toBe(0); + it('should contain all directives in the light dom when descendants flag is used', () => { + const template = '
' + + '
' + + '
' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); - q.create(); + expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|4|'); + }); + + it('should contain all directives in the light dom', () => { + const template = '
' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|'); + }); + + it('should reflect dynamically inserted directives', () => { + const template = '
' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + expect(asNativeElements(view.debugElement.children)).toHaveText('2|'); + + view.componentInstance.shouldShow = true; + view.detectChanges(); + expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|'); + }); + + it('should be cleanly destroyed when a query crosses view boundaries', () => { + const template = '
' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + view.componentInstance.shouldShow = true; + view.detectChanges(); + view.destroy(); + }); + + it('should reflect moved directives', () => { + const template = '
' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + expect(asNativeElements(view.debugElement.children)).toHaveText('2|1d|2d|3d|'); + + view.componentInstance.list = ['3d', '2d']; + view.detectChanges(); + expect(asNativeElements(view.debugElement.children)).toHaveText('2|3d|2d|'); + }); + + it('should throw with descriptive error when query selectors are not present', () => { + TestBed.configureTestingModule({declarations: [MyCompBroken0, HasNullQueryCondition]}); + const template = ''; + TestBed.overrideComponent(MyCompBroken0, {set: {template}}); + expect(() => TestBed.createComponent(MyCompBroken0)) + .toThrowError( + `Can't construct a query for the property "errorTrigger" of "${stringify(HasNullQueryCondition)}" since the query selector wasn't defined.`); + }); + }); + + describe('query for TemplateRef', () => { + it('should find TemplateRefs in the light and shadow dom', () => { + const template = '
light
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const needsTpl: NeedsTpl = view.debugElement.children[0].injector.get(NeedsTpl); + + expect(needsTpl.vc.createEmbeddedView(needsTpl.query.first).rootNodes[0]).toHaveText('light'); + expect(needsTpl.vc.createEmbeddedView(needsTpl.viewQuery.first).rootNodes[0]) + .toHaveText('shadow'); + }); + + it('should find named TemplateRefs', () => { + const template = + '
light
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const needsTpl: NeedsNamedTpl = view.debugElement.children[0].injector.get(NeedsNamedTpl); + expect(needsTpl.vc.createEmbeddedView(needsTpl.contentTpl).rootNodes[0]).toHaveText('light'); + expect(needsTpl.vc.createEmbeddedView(needsTpl.viewTpl).rootNodes[0]).toHaveText('shadow'); + }); + }); + + describe('read a different token', () => { + it('should contain all content children', () => { + const template = + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + const comp: NeedsContentChildrenWithRead = + view.debugElement.children[0].injector.get(NeedsContentChildrenWithRead); + expect(comp.textDirChildren.map(textDirective => textDirective.text)).toEqual(['ca', 'cb']); + }); + + it('should contain the first content child', () => { + const template = + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + const comp: NeedsContentChildWithRead = + view.debugElement.children[0].injector.get(NeedsContentChildWithRead); + expect(comp.textDirChild.text).toEqual('ca'); + }); + + it('should contain the first descendant content child', () => { + const template = '' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + const comp: NeedsContentChildWithRead = + view.debugElement.children[0].injector.get(NeedsContentChildWithRead); + expect(comp.textDirChild.text).toEqual('ca'); + }); + + it('should contain the first descendant content child templateRef', () => { + const template = '' + + ''; + const view = createTestCmp(MyComp0, template); + + // can't + // execute + // checkNoChanges + // as + // our + // view + // modifies + // our + // content + // children + // (via + // a + // query). + view.detectChanges(false); + expect(view.nativeElement).toHaveText('OUTER'); + }); + + it('should contain the first view child', () => { + const template = ''; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + const comp: NeedsViewChildWithRead = + view.debugElement.children[0].injector.get(NeedsViewChildWithRead); + expect(comp.textDirChild.text).toEqual('va'); + }); + + it('should contain all child directives in the view', () => { + const template = ''; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + const comp: NeedsViewChildrenWithRead = + view.debugElement.children[0].injector.get(NeedsViewChildrenWithRead); + expect(comp.textDirChildren.map(textDirective => textDirective.text)).toEqual(['va', 'vb']); + }); + + it('should support reading a ViewContainer', () => { + const template = + 'hello'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + const comp: NeedsViewContainerWithRead = + view.debugElement.children[0].injector.get(NeedsViewContainerWithRead); + comp.createView(); + expect(view.debugElement.children[0].nativeElement).toHaveText('hello'); + }); + }); + + describe('changes', () => { + it('should notify query on change', async(() => { + const template = '' + + '
' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + const q = view.debugElement.children[0].references !['q']; + + q.query.changes.subscribe({ + next: () => { + expect(q.query.first.text).toEqual('1'); + expect(q.query.last.text).toEqual('2'); + } + }); + + view.componentInstance.shouldShow = true; + view.detectChanges(); + })); + + it('should correctly clean-up when destroyed together with the directives it is querying', + () => { + const template = '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + view.componentInstance.shouldShow = true; + view.detectChanges(); + + let isQueryListCompleted = false; + + const q: NeedsQuery = view.debugElement.children[0].references !['q']; + const changes = >q.query.changes; + expect(q.query.length).toEqual(1); + expect(changes.closed).toBeFalsy(); + changes.subscribe(() => {}, () => {}, () => { isQueryListCompleted = true; }); + + view.componentInstance.shouldShow = false; + view.detectChanges(); + expect(changes.closed).toBeTruthy(); + expect(isQueryListCompleted).toBeTruthy(); + + view.componentInstance.shouldShow = true; + view.detectChanges(); + const q2: NeedsQuery = view.debugElement.children[0].references !['q']; + + expect(q2.query.length).toEqual(1); + expect(changes.closed).toBeTruthy(); + expect((>q2.query.changes).closed).toBeFalsy(); + }); + }); + + describe('querying by var binding', () => { + it('should contain all the child directives in the light dom with the given var binding', + () => { + const template = '' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references !['q']; + + view.componentInstance.list = ['1d', '2d']; + view.detectChanges(); + expect(q.query.first.text).toEqual('1d'); + expect(q.query.last.text).toEqual('2d'); + }); + + it('should support querying by multiple var bindings', () => { + const template = '' + + '
' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references !['q']; + + expect(q.query.first.text).toEqual('one'); + expect(q.query.last.text).toEqual('two'); + }); + + it('should support dynamically inserted directives', () => { + const template = '' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references !['q']; + + view.componentInstance.list = ['1d', '2d']; + view.detectChanges(); + view.componentInstance.list = ['2d', '1d']; + view.detectChanges(); + expect(q.query.last.text).toEqual('1d'); + }); + + it('should contain all the elements in the light dom with the given var binding', () => { + const template = '' + + '
' + + '
{{item}}
' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references !['q']; + + view.componentInstance.list = ['1d', '2d']; + view.detectChanges(); + expect(q.query.first.nativeElement).toHaveText('1d'); + expect(q.query.last.nativeElement).toHaveText('2d'); + }); + + it('should contain all the elements in the light dom even if they get projected', () => { + const template = '' + + '
' + + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + expect(asNativeElements(view.debugElement.children)).toHaveText('hello|world|'); + }); + + it('should support querying the view by using a view query', () => { + const template = ''; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + const q: NeedsViewQueryByLabel = view.debugElement.children[0].references !['q']; + expect(q.query.first.nativeElement).toHaveText('text'); + }); + + it('should contain all child directives in the view dom', () => { + const template = ''; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references !['q']; + expect(q.textDirChildren.length).toEqual(1); + expect(q.numberOfChildrenAfterViewInit).toEqual(1); + }); + }); + + describe('querying in the view', () => { + it('should contain all the elements in the view with that have the given directive', () => { + const template = '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQuery = view.debugElement.children[0].references !['q']; + expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); + }); + + it('should not include directive present on the host element', () => { + const template = ''; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQuery = view.debugElement.children[0].references !['q']; + expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); + }); + + it('should reflect changes in the component', () => { + const template = ''; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQueryIf = view.debugElement.children[0].references !['q']; + expect(q.query.length).toBe(0); + + q.show = true; + view.detectChanges(); + expect(q.query.length).toBe(1); + expect(q.query.first.text).toEqual('1'); + }); + + it('should not be affected by other changes in the component', () => { + const template = ''; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQueryNestedIf = view.debugElement.children[0].references !['q']; + + expect(q.query.length).toEqual(1); + expect(q.query.first.text).toEqual('1'); + + q.show = false; + view.detectChanges(); + expect(q.query.length).toEqual(1); + expect(q.query.first.text).toEqual('1'); + }); + + it('should maintain directives in pre-order depth-first DOM order after dynamic insertion', + () => { + const template = ''; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQueryOrder = view.debugElement.children[0].references !['q']; + + expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); + + q.list = ['-3', '2']; + view.detectChanges(); + expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '-3', '2', '4']); + }); + + it('should maintain directives in pre-order depth-first DOM order after dynamic insertion', + () => { + const template = ''; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQueryOrderWithParent = view.debugElement.children[0].references !['q']; + expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); + + q.list = ['-3', '2']; + view.detectChanges(); + expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '-3', '2', '4']); + }); + + it('should handle long ngFor cycles', () => { + const template = ''; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQueryOrder = view.debugElement.children[0].references !['q']; + + // no + // significance + // to + // 50, + // just + // a + // reasonably + // large + // cycle. + for (let i = 0; i < 50; i++) { + const newString = i.toString(); + q.list = [newString]; view.detectChanges(); - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1']); + expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', newString, '4']); + } + }); - q.destroy(); - view.detectChanges(); - expect(q.query.length).toBe(0); - }); + it('should support more than three queries', () => { + const template = '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references !['q']; + expect(q.query1).toBeDefined(); + expect(q.query2).toBeDefined(); + expect(q.query3).toBeDefined(); + expect(q.query4).toBeDefined(); + }); + }); - // Note: This tests is just document our current behavior, which we do - // for performance reasons. - it('should not affected queries for projected templates if views are detached or moved', () => { - const template = - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - const q = view.debugElement.children[0].references !['q'] as ManualProjecting; - expect(q.query.length).toBe(0); + describe('query over moved templates', () => { + it('should include manually projected templates in queries', () => { + const template = + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references !['q']; + expect(q.query.length).toBe(0); - const view1 = q.vc.createEmbeddedView(q.template, {'x': '1'}); - const view2 = q.vc.createEmbeddedView(q.template, {'x': '2'}); - view.detectChanges(); - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2']); + q.create(); + view.detectChanges(); + expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1']); - q.vc.detach(1); - q.vc.detach(0); + q.destroy(); + view.detectChanges(); + expect(q.query.length).toBe(0); + }); - view.detectChanges(); - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2']); + // Note: + // This + // tests + // is + // just + // document + // our + // current + // behavior, + // which + // we + // do + // for + // performance + // reasons. + it('should not affected queries for projected templates if views are detached or moved', () => { + const template = + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references !['q'] as ManualProjecting; + expect(q.query.length).toBe(0); - q.vc.insert(view2); - q.vc.insert(view1); + const view1 = q.vc.createEmbeddedView(q.template, {'x': '1'}); + const view2 = q.vc.createEmbeddedView(q.template, {'x': '2'}); + view.detectChanges(); + expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2']); - view.detectChanges(); - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2']); - }); + q.vc.detach(1); + q.vc.detach(0); - it('should remove manually projected templates if their parent view is destroyed', () => { - const template = ` + view.detectChanges(); + expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2']); + + q.vc.insert(view2); + q.vc.insert(view1); + + view.detectChanges(); + expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2']); + }); + + it('should remove manually projected templates if their parent view is destroyed', () => { + const template = `
`; - const view = createTestCmp(MyComp0, template); - const q = view.debugElement.children[0].references !['q']; - view.componentInstance.shouldShow = true; - view.detectChanges(); + const view = createTestCmp(MyComp0, template); + const q = view.debugElement.children[0].references !['q']; + view.componentInstance.shouldShow = true; + view.detectChanges(); - expect(q.query.length).toBe(1); - - view.componentInstance.shouldShow = false; - view.detectChanges(); - expect(q.query.length).toBe(0); - }); - - it('should not throw if a content template is queried and created in the view during change detection', - () => { - @Component( - {selector: 'auto-projecting', template: '
'}) - class AutoProjecting { - // TODO(issue/24571): remove '!'. - @ContentChild(TemplateRef) - content !: TemplateRef; - - // TODO(issue/24571): remove '!'. - @ContentChildren(TextDirective) - query !: QueryList; - } - - TestBed.configureTestingModule({declarations: [AutoProjecting]}); - const template = - '
'; - const view = createTestCmpAndDetectChanges(MyComp0, template); - - const q = view.debugElement.children[0].references !['q']; - // This should be 1, but due to - // https://github.com/angular/angular/issues/15117 this is 0. - expect(q.query.length).toBe(0); - }); + expect(q.query.length).toBe(1); + view.componentInstance.shouldShow = false; + view.detectChanges(); + expect(q.query.length).toBe(0); }); + + it('should not throw if a content template is queried and created in the view during change detection', + () => { + @Component( + {selector: 'auto-projecting', template: '
'}) + class AutoProjecting { + // TODO(issue/24571): + // remove + // '!'. + @ContentChild(TemplateRef) + content !: TemplateRef; + + // TODO(issue/24571): + // remove + // '!'. + @ContentChildren(TextDirective) + query !: QueryList; + } + + TestBed.configureTestingModule({declarations: [AutoProjecting]}); + const template = + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + const q = view.debugElement.children[0].references !['q']; + // This + // should + // be + // 1, + // but + // due + // to + // https://github.com/angular/angular/issues/15117 + // this + // is + // 0. + expect(q.query.length).toBe(0); + }); + }); -} +}); + @Directive({selector: '[text]', inputs: ['text'], exportAs: 'textDir'}) class TextDirective { diff --git a/packages/core/test/linker/regression_integration_spec.ts b/packages/core/test/linker/regression_integration_spec.ts index d0e5c79cb8..646e95e67a 100644 --- a/packages/core/test/linker/regression_integration_spec.ts +++ b/packages/core/test/linker/regression_integration_spec.ts @@ -7,7 +7,7 @@ */ import {ANALYZE_FOR_ENTRY_COMPONENTS, ApplicationRef, Component, ComponentRef, ContentChild, Directive, ErrorHandler, EventEmitter, HostListener, InjectionToken, Injector, Input, NgModule, NgModuleRef, NgZone, Output, Pipe, PipeTransform, Provider, QueryList, Renderer2, SimpleChanges, TemplateRef, ViewChildren, ViewContainerRef, destroyPlatform, ɵivyEnabled as ivyEnabled} from '@angular/core'; -import {TestBed, async, fakeAsync, inject, tick} from '@angular/core/testing'; +import {TestBed, fakeAsync, inject, tick} from '@angular/core/testing'; import {BrowserModule, By, DOCUMENT} from '@angular/platform-browser'; import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; @@ -16,11 +16,10 @@ import {fixmeIvy} from '@angular/private/testing'; { if (ivyEnabled) { - fixmeIvy('unknown') && describe('ivy', () => { declareTests(); }); + describe('ivy', () => { declareTests(); }); } else { - fixmeIvy('unknown') && describe('jit', () => { declareTests({useJit: true}); }); - - fixmeIvy('unknown') && describe('no jit', () => { declareTests({useJit: false}); }); + describe('jit', () => { declareTests({useJit: true}); }); + describe('no jit', () => { declareTests({useJit: false}); }); } declareTestsUsingBootstrap(); @@ -35,7 +34,7 @@ function declareTests(config?: {useJit: boolean}) { describe('platform pipes', () => { beforeEach(() => { TestBed.configureCompiler({...config}); }); - it('should overwrite them by custom pipes', () => { + fixmeIvy('unknown') && it('should overwrite them by custom pipes', () => { TestBed.configureTestingModule({declarations: [CustomPipe]}); const template = '{{true | somePipe}}'; TestBed.overrideComponent(MyComp1, {set: {template}}); @@ -77,43 +76,46 @@ function declareTests(config?: {useJit: boolean}) { expect(CountingPipe.calls).toBe(1); }); - it('should only update the bound property when using asyncPipe - #15205', fakeAsync(() => { - @Component({template: '
'}) - class MyComp { - p = Promise.resolve(1); - } + fixmeIvy('unknown') && + it('should only update the bound property when using asyncPipe - #15205', + fakeAsync(() => { + @Component({template: '
'}) + class MyComp { + p = Promise.resolve(1); + } - @Directive({selector: '[myDir]'}) - class MyDir { - setterCalls: {[key: string]: any} = {}; - // TODO(issue/24571): remove '!'. - changes !: SimpleChanges; + @Directive({selector: '[myDir]'}) + class MyDir { + setterCalls: {[key: string]: any} = {}; + // TODO(issue/24571): remove '!'. + changes !: SimpleChanges; - @Input() - set a(v: number) { this.setterCalls['a'] = v; } - @Input() - set b(v: number) { this.setterCalls['b'] = v; } + @Input() + set a(v: number) { this.setterCalls['a'] = v; } + @Input() + set b(v: number) { this.setterCalls['b'] = v; } - ngOnChanges(changes: SimpleChanges) { this.changes = changes; } - } + ngOnChanges(changes: SimpleChanges) { this.changes = changes; } + } - TestBed.configureTestingModule({declarations: [MyDir, MyComp]}); - const fixture = TestBed.createComponent(MyComp); - const dir = fixture.debugElement.query(By.directive(MyDir)).injector.get(MyDir) as MyDir; + TestBed.configureTestingModule({declarations: [MyDir, MyComp]}); + const fixture = TestBed.createComponent(MyComp); + const dir = + fixture.debugElement.query(By.directive(MyDir)).injector.get(MyDir) as MyDir; - fixture.detectChanges(); - expect(dir.setterCalls).toEqual({'a': null, 'b': 2}); - expect(Object.keys(dir.changes)).toEqual(['a', 'b']); + fixture.detectChanges(); + expect(dir.setterCalls).toEqual({'a': null, 'b': 2}); + expect(Object.keys(dir.changes)).toEqual(['a', 'b']); - dir.setterCalls = {}; - dir.changes = {}; + dir.setterCalls = {}; + dir.changes = {}; - tick(); - fixture.detectChanges(); + tick(); + fixture.detectChanges(); - expect(dir.setterCalls).toEqual({'a': 1}); - expect(Object.keys(dir.changes)).toEqual(['a']); - })); + expect(dir.setterCalls).toEqual({'a': 1}); + expect(Object.keys(dir.changes)).toEqual(['a']); + })); it('should only evaluate methods once - #10639', () => { TestBed.configureTestingModule({declarations: [MyCountingComp]}); @@ -160,13 +162,14 @@ function declareTests(config?: {useJit: boolean}) { expect(injector.get(token)).toEqual(tokenValue); }); - it('should support providers with string token with a `.` in it', () => { - const token = 'a.b'; - const tokenValue = 1; - const injector = createInjector([{provide: token, useValue: tokenValue}]); + fixmeIvy('FW-646: Directive providers don\'t support primitive types as DI tokens') && + it('should support providers with string token with a `.` in it', () => { + const token = 'a.b'; + const tokenValue = 1; + const injector = createInjector([{provide: token, useValue: tokenValue}]); - expect(injector.get(token)).toEqual(tokenValue); - }); + expect(injector.get(token)).toEqual(tokenValue); + }); it('should support providers with an anonymous function as token', () => { const token = () => true; @@ -188,14 +191,15 @@ function declareTests(config?: {useJit: boolean}) { expect(injector.get(token2)).toEqual(tokenValue2); }); - it('should support providers that have a `name` property with a number value', () => { - class TestClass { - constructor(public name: number) {} - } - const data = [new TestClass(1), new TestClass(2)]; - const injector = createInjector([{provide: 'someToken', useValue: data}]); - expect(injector.get('someToken')).toEqual(data); - }); + fixmeIvy('FW-646: Directive providers don\'t support primitive types as DI tokens') && + it('should support providers that have a `name` property with a number value', () => { + class TestClass { + constructor(public name: number) {} + } + const data = [new TestClass(1), new TestClass(2)]; + const injector = createInjector([{provide: 'someToken', useValue: data}]); + expect(injector.get('someToken')).toEqual(data); + }); describe('ANALYZE_FOR_ENTRY_COMPONENTS providers', () => { @@ -333,7 +337,7 @@ function declareTests(config?: {useJit: boolean}) { expect(fixture.debugElement.childNodes.length).toBe(0); }); - it('should allow empty embedded templates', () => { + fixmeIvy('unknown') && it('should allow empty embedded templates', () => { @Component({template: ''}) class MyComp { } @@ -350,35 +354,37 @@ function declareTests(config?: {useJit: boolean}) { }); }); - it('should support @ContentChild and @Input on the same property for static queries', () => { - @Directive({selector: 'test'}) - class Test { - // TODO(issue/24571): remove '!'. - @Input() @ContentChild(TemplateRef) tpl !: TemplateRef; - } + fixmeIvy('unknown') && + it('should support @ContentChild and @Input on the same property for static queries', + () => { + @Directive({selector: 'test'}) + class Test { + // TODO(issue/24571): remove '!'. + @Input() @ContentChild(TemplateRef) tpl !: TemplateRef; + } - @Component({ - selector: 'my-app', - template: ` + @Component({ + selector: 'my-app', + template: `
Custom as a child
Custom as a binding
` - }) - class App { - } + }) + class App { + } - const fixture = - TestBed.configureTestingModule({declarations: [App, Test]}).createComponent(App); - fixture.detectChanges(); + const fixture = + TestBed.configureTestingModule({declarations: [App, Test]}).createComponent(App); + fixture.detectChanges(); - const testDirs = - fixture.debugElement.queryAll(By.directive(Test)).map(el => el.injector.get(Test)); - expect(testDirs[0].tpl).toBeUndefined(); - expect(testDirs[1].tpl).toBeDefined(); - expect(testDirs[2].tpl).toBeDefined(); - }); + const testDirs = + fixture.debugElement.queryAll(By.directive(Test)).map(el => el.injector.get(Test)); + expect(testDirs[0].tpl).toBeUndefined(); + expect(testDirs[1].tpl).toBeDefined(); + expect(testDirs[2].tpl).toBeDefined(); + }); it('should not add ng-version for dynamically created components', () => { @Component({template: ''}) diff --git a/packages/core/test/linker/security_integration_spec.ts b/packages/core/test/linker/security_integration_spec.ts index a74b7aee71..0f179283f9 100644 --- a/packages/core/test/linker/security_integration_spec.ts +++ b/packages/core/test/linker/security_integration_spec.ts @@ -16,9 +16,8 @@ import {fixmeIvy} from '@angular/private/testing'; if (ivyEnabled) { fixmeIvy('unknown') && describe('ivy', () => { declareTests(); }); } else { - fixmeIvy('unknown') && describe('jit', () => { declareTests({useJit: true}); }); - - fixmeIvy('unknown') && describe('no jit', () => { declareTests({useJit: false}); }); + describe('jit', () => { declareTests({useJit: true}); }); + describe('no jit', () => { declareTests({useJit: false}); }); } }