test(ivy): add ability to find already passing tests (#27449)

PR Close #27449
This commit is contained in:
Misko Hevery 2018-12-03 17:57:07 -08:00 committed by Igor Minar
parent 4b9948c1be
commit f52600e261
35 changed files with 4501 additions and 4410 deletions

View File

@ -74,8 +74,8 @@ describe('@angular/core ng_package', () => {
describe('typescript support', () => { describe('typescript support', () => {
fixmeIvy('FW-738: ngtsc doesn\'t generate flat index files') && fixmeIvy('FW-738: ngtsc doesn\'t generate flat index files')
it('should have an index d.ts file', .it('should have an index d.ts file',
() => { expect(shx.cat('core.d.ts')).toContain(`export *`); }); () => { expect(shx.cat('core.d.ts')).toContain(`export *`); });
it('should not have amd module names', it('should not have amd module names',
@ -90,8 +90,8 @@ describe('@angular/core ng_package', () => {
}); });
obsoleteInIvy('metadata files are no longer needed or produced in Ivy') && obsoleteInIvy('metadata files are no longer needed or produced in Ivy')
describe('angular metadata', () => { .describe('angular metadata', () => {
it('should have metadata.json files', it('should have metadata.json files',
() => { expect(shx.cat('core.metadata.json')).toContain(`"__symbolic":"module"`); }); () => { expect(shx.cat('core.metadata.json')).toContain(`"__symbolic":"module"`); });
@ -112,8 +112,8 @@ describe('@angular/core ng_package', () => {
.toMatch(/@license Angular v\d+\.\d+\.\d+(?!-PLACEHOLDER)/); .toMatch(/@license Angular v\d+\.\d+\.\d+(?!-PLACEHOLDER)/);
}); });
obsoleteInIvy('we no longer need to export private symbols') && obsoleteInIvy('we no longer need to export private symbols')
it('should have been built from the generated bundle index', () => { .it('should have been built from the generated bundle index', () => {
expect(shx.cat('fesm2015/core.js')).toMatch('export {.*makeParamDecorator'); expect(shx.cat('fesm2015/core.js')).toMatch('export {.*makeParamDecorator');
}); });
}); });
@ -147,8 +147,8 @@ describe('@angular/core ng_package', () => {
expect(shx.cat('fesm5/core.js')).toMatch('import {.*__extends'); expect(shx.cat('fesm5/core.js')).toMatch('import {.*__extends');
}); });
obsoleteInIvy('we no longer need to export private symbols') && obsoleteInIvy('we no longer need to export private symbols')
it('should have been built from the generated bundle index', .it('should have been built from the generated bundle index',
() => { expect(shx.cat('fesm5/core.js')).toMatch('export {.*makeParamDecorator'); }); () => { expect(shx.cat('fesm5/core.js')).toMatch('export {.*makeParamDecorator'); });
}); });
@ -228,13 +228,13 @@ describe('@angular/core ng_package', () => {
() => { expect(shx.cat(typingsFile)).toContain('export * from \'./public_api\';'); }); () => { expect(shx.cat(typingsFile)).toContain('export * from \'./public_api\';'); });
obsoleteInIvy( obsoleteInIvy(
'now that we don\'t need metadata files, we don\'t need these redirects to help resolve paths to them') && 'now that we don\'t need metadata files, we don\'t need these redirects to help resolve paths to them')
it('should have an \'redirect\' d.ts file in the parent dir', .it('should have an \'redirect\' d.ts file in the parent dir',
() => { expect(shx.cat('testing.d.ts')).toContain(`export *`); }); () => { expect(shx.cat('testing.d.ts')).toContain(`export *`); });
}); });
obsoleteInIvy('metadata files are no longer needed or produced in Ivy') && obsoleteInIvy('metadata files are no longer needed or produced in Ivy')
describe('angular metadata file', () => { .describe('angular metadata file', () => {
it('should have a \'redirect\' metadata.json file next to the d.ts file', () => { it('should have a \'redirect\' metadata.json file next to the d.ts file', () => {
expect(shx.cat('testing.metadata.json')) expect(shx.cat('testing.metadata.json'))
.toContain( .toContain(

View File

@ -17,7 +17,7 @@ describe('ngc_wrapped', () => {
// fixmeIvy placeholder to prevent jasmine from erroring out because there are no specs // fixmeIvy placeholder to prevent jasmine from erroring out because there are no specs
it('should be removed once the fixmeIvy below is resolved', () => {}); it('should be removed once the fixmeIvy below is resolved', () => {});
fixmeIvy('FW-741: ngtsc breaks tsc module resolution') && it('should work', () => { fixmeIvy('FW-741: ngtsc breaks tsc module resolution').it('should work', () => {
const {read, write, runOneBuild, writeConfig, shouldExist, basePath} = setup(); const {read, write, runOneBuild, writeConfig, shouldExist, basePath} = setup();
write('some_project/index.ts', ` write('some_project/index.ts', `

View File

@ -157,8 +157,8 @@ describe('insert/remove', () => {
expect(fixture.nativeElement).toHaveText('baz'); expect(fixture.nativeElement).toHaveText('baz');
})); }));
fixmeIvy('FW-739: destroy on NgModuleRef is not being called') && fixmeIvy('FW-739: destroy on NgModuleRef is not being called')
it('should clean up moduleRef, if supplied', async(() => { .it('should clean up moduleRef, if supplied', async(() => {
let destroyed = false; let destroyed = false;
const compiler = TestBed.get(Compiler) as Compiler; const compiler = TestBed.get(Compiler) as Compiler;
const fixture = TestBed.createComponent(TestComponent); const fixture = TestBed.createComponent(TestComponent);

View File

@ -168,8 +168,8 @@ describe('ngInjectableDef Bazel Integration', () => {
expect(TestBed.get(INJECTOR).get('foo')).toEqual('bar'); expect(TestBed.get(INJECTOR).get('foo')).toEqual('bar');
}); });
fixmeIvy('FW-646: Directive providers don\'t support primitive types') && fixmeIvy('FW-646: Directive providers don\'t support primitive types')
it('Component injector understands requests for INJECTABLE', () => { .it('Component injector understands requests for INJECTABLE', () => {
@Component({ @Component({
selector: 'test-cmp', selector: 'test-cmp',
template: 'test', template: 'test',

View File

@ -41,8 +41,8 @@ describe('Ivy NgModule', () => {
it('works', () => { createInjector(JitAppModule); }); it('works', () => { createInjector(JitAppModule); });
fixmeIvy('FW-645: jit doesn\'t support forwardRefs') && fixmeIvy('FW-645: jit doesn\'t support forwardRefs')
it('throws an error on circular module dependencies', () => { .it('throws an error on circular module dependencies', () => {
@NgModule({ @NgModule({
imports: [forwardRef(() => BModule)], imports: [forwardRef(() => BModule)],
}) })

View File

@ -60,7 +60,7 @@ describe('ngtools_api (deprecated)', () => {
}); });
} }
fixmeIvy('FW-629: ngtsc lists lazy routes') && it('should list lazy routes recursively', () => { fixmeIvy('FW-629: ngtsc lists lazy routes').it('should list lazy routes recursively', () => {
writeSomeRoutes(); writeSomeRoutes();
const {program, host, options} = createProgram(['src/main.ts']); const {program, host, options} = createProgram(['src/main.ts']);
const routes = NgTools_InternalApi_NG_2.listLazyRoutes({ const routes = NgTools_InternalApi_NG_2.listLazyRoutes({

View File

@ -35,8 +35,8 @@ ivyEnabled && describe('ApplicationRef bootstrap', () => {
class MyAppModule { class MyAppModule {
} }
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should bootstrap hello world', withBody('<hello-world></hello-world>', async() => { 'should bootstrap hello world', withBody('<hello-world></hello-world>', async() => {
const MyAppModuleFactory = new NgModuleFactory(MyAppModule); const MyAppModuleFactory = new NgModuleFactory(MyAppModule);
const moduleRef = await getTestBed().platform.bootstrapModuleFactory( const moduleRef = await getTestBed().platform.bootstrapModuleFactory(
MyAppModuleFactory, {ngZone: 'noop'}); MyAppModuleFactory, {ngZone: 'noop'});

View File

@ -74,8 +74,8 @@ class SomeComponent {
return MyModule; return MyModule;
} }
fixmeIvy('FW-776: Cannot bootstrap as there are still asynchronous initializers running') && fixmeIvy('FW-776: Cannot bootstrap as there are still asynchronous initializers running')
it('should bootstrap a component from a child module', .it('should bootstrap a component from a child module',
async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => { async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => {
@Component({ @Component({
selector: 'bootstrap-app', selector: 'bootstrap-app',
@ -103,8 +103,8 @@ class SomeComponent {
expect(component.injector.get('hello')).toEqual('component'); expect(component.injector.get('hello')).toEqual('component');
}))); })));
fixmeIvy('FW-776: Cannot bootstrap as there are still asynchronous initializers running') && fixmeIvy('FW-776: Cannot bootstrap as there are still asynchronous initializers running')
it('should bootstrap a component with a custom selector', .it('should bootstrap a component with a custom selector',
async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => { async(inject([ApplicationRef, Compiler], (app: ApplicationRef, compiler: Compiler) => {
@Component({ @Component({
selector: 'bootstrap-app', selector: 'bootstrap-app',

View File

@ -33,8 +33,8 @@ const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec'
})('foo', 'bar'); })('foo', 'bar');
}); });
fixmeIvy('unknown') && it('should work with inject()', fixmeIvy('unknown').it(
fakeAsync(inject([Parser], (parser: any /** TODO #9100 */) => { 'should work with inject()', fakeAsync(inject([Parser], (parser: any /** TODO #9100 */) => {
expect(parser).toBeAnInstanceOf(Parser); expect(parser).toBeAnInstanceOf(Parser);
}))); })));

View File

@ -15,8 +15,8 @@ import {fixmeIvy} from '@angular/private/testing';
describe('forwardRef integration', function() { describe('forwardRef integration', function() {
beforeEach(() => { TestBed.configureTestingModule({imports: [Module], declarations: [App]}); }); beforeEach(() => { TestBed.configureTestingModule({imports: [Module], declarations: [App]}); });
fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account')
it('should instantiate components which are declared using forwardRef', () => { .it('should instantiate components which are declared using forwardRef', () => {
const a = const a =
TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}).createComponent(App); TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}).createComponent(App);
a.detectChanges(); a.detectChanges();

View File

@ -69,9 +69,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(childComp.cfr.resolveComponentFactory(ChildComp) !.componentType).toBe(ChildComp); expect(childComp.cfr.resolveComponentFactory(ChildComp) !.componentType).toBe(ChildComp);
}); });
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should not be able to get components from a parent component (content hierarchy)', 'should not be able to get components from a parent component (content hierarchy)', () => {
() => {
TestBed.overrideComponent( TestBed.overrideComponent(
MainComp, {set: {template: '<child><nested></nested></child>'}}); MainComp, {set: {template: '<child><nested></nested></child>'}});
TestBed.overrideComponent(ChildComp, {set: {template: '<ng-content></ng-content>'}}); TestBed.overrideComponent(ChildComp, {set: {template: '<ng-content></ng-content>'}});

View File

@ -209,8 +209,8 @@ function declareTests(config?: {useJit: boolean}) {
.toEqual('Some other <div>HTML</div>'); .toEqual('Some other <div>HTML</div>');
}); });
modifiedInIvy('Binding to the class property directly works differently') && modifiedInIvy('Binding to the class property directly works differently')
it('should consume binding to className using class alias', () => { .it('should consume binding to className using class alias', () => {
TestBed.configureTestingModule({declarations: [MyComp]}); TestBed.configureTestingModule({declarations: [MyComp]});
const template = '<div class="initial" [class]="ctxProp"></div>'; const template = '<div class="initial" [class]="ctxProp"></div>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});
@ -238,8 +238,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(getDOM().getProperty(nativeEl, 'htmlFor')).toBe('foo'); expect(getDOM().getProperty(nativeEl, 'htmlFor')).toBe('foo');
}); });
fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') && fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work')
it('should consume directive watch expression change.', () => { .it('should consume directive watch expression change.', () => {
TestBed.configureTestingModule({declarations: [MyComp, MyDir]}); TestBed.configureTestingModule({declarations: [MyComp, MyDir]});
const template = '<span>' + const template = '<span>' +
'<div my-dir [elprop]="ctxProp"></div>' + '<div my-dir [elprop]="ctxProp"></div>' +
@ -263,8 +263,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('pipes', () => { describe('pipes', () => {
fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') && fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work')
it('should support pipes in bindings', () => { .it('should support pipes in bindings', () => {
TestBed.configureTestingModule({declarations: [MyComp, MyDir, DoublePipe]}); TestBed.configureTestingModule({declarations: [MyComp, MyDir, DoublePipe]});
const template = '<div my-dir #dir="mydir" [elprop]="ctxProp | double"></div>'; const template = '<div my-dir #dir="mydir" [elprop]="ctxProp | double"></div>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});
@ -290,8 +290,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
// GH issue 328 - https://github.com/angular/angular/issues/328 // GH issue 328 - https://github.com/angular/angular/issues/328
fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work') && fixmeIvy('FW-587: Inputs with aliases in component decorators don\'t work')
it('should support different directive types on a single node', () => { .it('should support different directive types on a single node', () => {
TestBed.configureTestingModule({declarations: [MyComp, ChildComp, MyDir]}); TestBed.configureTestingModule({declarations: [MyComp, ChildComp, MyDir]});
const template = '<child-cmp my-dir [elprop]="ctxProp"></child-cmp>'; const template = '<child-cmp my-dir [elprop]="ctxProp"></child-cmp>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});
@ -350,8 +350,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(tc.injector.get(EventDir)).not.toBeNull(); expect(tc.injector.get(EventDir)).not.toBeNull();
}); });
fixmeIvy('FW-680: Throw meaningful error for uninitialized @Output') && fixmeIvy('FW-680: Throw meaningful error for uninitialized @Output')
it('should display correct error message for uninitialized @Output', () => { .it('should display correct error message for uninitialized @Output', () => {
@Component({selector: 'my-uninitialized-output', template: '<p>It works!</p>'}) @Component({selector: 'my-uninitialized-output', template: '<p>It works!</p>'})
class UninitializedOutputComp { class UninitializedOutputComp {
@Output() customEvent !: EventEmitter<any>; @Output() customEvent !: EventEmitter<any>;
@ -374,8 +374,8 @@ function declareTests(config?: {useJit: boolean}) {
const fixture = TestBed.createComponent(MyComp); const fixture = TestBed.createComponent(MyComp);
}); });
modifiedInIvy('Comment node order changed') && modifiedInIvy('Comment node order changed')
it('should support template directives via `<ng-template>` elements.', () => { .it('should support template directives via `<ng-template>` elements.', () => {
TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]}); TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]});
const template = const template =
'<ng-template some-viewport let-greeting="someTmpl"><span>{{greeting}}</span></ng-template>'; '<ng-template some-viewport let-greeting="someTmpl"><span>{{greeting}}</span></ng-template>';
@ -403,8 +403,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
fixmeIvy( fixmeIvy(
'FW-665: Discovery util fails with "Unable to find the given context data for the given target"') && 'FW-665: Discovery util fails with "Unable to find the given context data for the given target"')
it('should not detach views in ViewContainers when the parent view is destroyed.', () => { .it('should not detach views in ViewContainers when the parent view is destroyed.', () => {
TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]}); TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]});
const template = const template =
'<div *ngIf="ctxBoolProp"><ng-template some-viewport let-greeting="someTmpl"><span>{{greeting}}</span></ng-template></div>'; '<div *ngIf="ctxBoolProp"><ng-template some-viewport let-greeting="someTmpl"><span>{{greeting}}</span></ng-template></div>';
@ -478,8 +478,8 @@ function declareTests(config?: {useJit: boolean}) {
.toBeAnInstanceOf(ExportDir); .toBeAnInstanceOf(ExportDir);
}); });
fixmeIvy('FW-708: Directives with multiple exports are not supported') && fixmeIvy('FW-708: Directives with multiple exports are not supported')
it('should assign a directive to a ref when it has multiple exportAs names', () => { .it('should assign a directive to a ref when it has multiple exportAs names', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [MyComp, DirectiveWithMultipleExportAsNames]}); {declarations: [MyComp, DirectiveWithMultipleExportAsNames]});
@ -543,8 +543,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(value.tagName.toLowerCase()).toEqual('div'); expect(value.tagName.toLowerCase()).toEqual('div');
}); });
fixmeIvy('FW-709: Context discovery does not support templates (comment nodes)') && fixmeIvy('FW-709: Context discovery does not support templates (comment nodes)')
it('should assign the TemplateRef to a user-defined variable', () => { .it('should assign the TemplateRef to a user-defined variable', () => {
const fixture = const fixture =
TestBed.configureTestingModule({declarations: [MyComp]}) TestBed.configureTestingModule({declarations: [MyComp]})
.overrideComponent( .overrideComponent(
@ -567,8 +567,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('variables', () => { describe('variables', () => {
modifiedInIvy('Comment node order changed') && modifiedInIvy('Comment node order changed')
it('should allow to use variables in a for loop', () => { .it('should allow to use variables in a for loop', () => {
const template = const template =
'<ng-template ngFor [ngForOf]="[1]" let-i><child-cmp-no-template #cmp></child-cmp-no-template>{{i}}-{{cmp.ctxProp}}</ng-template>'; '<ng-template ngFor [ngForOf]="[1]" let-i><child-cmp-no-template #cmp></child-cmp-no-template>{{i}}-{{cmp.ctxProp}}</ng-template>';
@ -586,8 +586,8 @@ function declareTests(config?: {useJit: boolean}) {
describe('OnPush components', () => { describe('OnPush components', () => {
fixmeIvy( fixmeIvy(
'FW-764: fixture.detectChanges() is not respecting OnPush flag on components in the root template') && 'FW-764: fixture.detectChanges() is not respecting OnPush flag on components in the root template')
it('should use ChangeDetectorRef to manually request a check', () => { .it('should use ChangeDetectorRef to manually request a check', () => {
TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithRef]]]}); TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithRef]]]});
const template = '<push-cmp-with-ref #cmp></push-cmp-with-ref>'; const template = '<push-cmp-with-ref #cmp></push-cmp-with-ref>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});
@ -608,8 +608,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
fixmeIvy( fixmeIvy(
'FW-764: fixture.detectChanges() is not respecting OnPush flag on components in the root template') && 'FW-764: fixture.detectChanges() is not respecting OnPush flag on components in the root template')
it('should be checked when its bindings got updated', () => { .it('should be checked when its bindings got updated', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [MyComp, PushCmp, EventCmp], imports: [CommonModule]}); {declarations: [MyComp, PushCmp, EventCmp], imports: [CommonModule]});
const template = '<push-cmp [prop]="ctxProp" #cmp></push-cmp>'; const template = '<push-cmp [prop]="ctxProp" #cmp></push-cmp>';
@ -628,11 +628,10 @@ function declareTests(config?: {useJit: boolean}) {
}); });
if (getDOM().supportsDOMEvents()) { if (getDOM().supportsDOMEvents()) {
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should allow to destroy a component from within a host event handler', 'should allow to destroy a component from within a host event handler',
fakeAsync(() => { fakeAsync(() => {
TestBed.configureTestingModule( TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithHostEvent]]]});
{declarations: [MyComp, [[PushCmpWithHostEvent]]]});
const template = '<push-cmp-with-host-event></push-cmp-with-host-event>'; const template = '<push-cmp-with-host-event></push-cmp-with-host-event>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp); const fixture = TestBed.createComponent(MyComp);
@ -648,8 +647,8 @@ function declareTests(config?: {useJit: boolean}) {
})); }));
} }
fixmeIvy('FW-758: OnPush events not marking view dirty when using renderer2') && fixmeIvy('FW-758: OnPush events not marking view dirty when using renderer2')
it('should be checked when an event is fired', () => { .it('should be checked when an event is fired', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [MyComp, PushCmp, EventCmp], imports: [CommonModule]}); {declarations: [MyComp, PushCmp, EventCmp], imports: [CommonModule]});
const template = '<push-cmp [prop]="ctxProp" #cmp></push-cmp>'; const template = '<push-cmp [prop]="ctxProp" #cmp></push-cmp>';
@ -774,8 +773,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
fixmeIvy( fixmeIvy(
'FW-763: LView tree not properly constructed / destroyed for dynamically inserted components') && 'FW-763: LView tree not properly constructed / destroyed for dynamically inserted components')
it('should support events via EventEmitter on regular elements', async(() => { .it('should support events via EventEmitter on regular elements', async(() => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent]}); {declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent]});
const template = '<div emitter listener></div>'; const template = '<div emitter listener></div>';
@ -806,8 +805,8 @@ function declareTests(config?: {useJit: boolean}) {
})); }));
fixmeIvy( fixmeIvy(
'FW-665: Discovery util fails with Unable to find the given context data for the given target') && '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(() => { .it('should support events via EventEmitter on template elements', async(() => {
const fixture = const fixture =
TestBed TestBed
.configureTestingModule({ .configureTestingModule({
@ -860,8 +859,8 @@ function declareTests(config?: {useJit: boolean}) {
})); }));
fixmeIvy( fixmeIvy(
'FW-743: Registering events on global objects (document, window, body) is not supported') && 'FW-743: Registering events on global objects (document, window, body) is not supported')
it('should support render events', () => { .it('should support render events', () => {
TestBed.configureTestingModule({declarations: [MyComp, DirectiveListeningDomEvent]}); TestBed.configureTestingModule({declarations: [MyComp, DirectiveListeningDomEvent]});
const template = '<div listener></div>'; const template = '<div listener></div>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});
@ -883,8 +882,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
fixmeIvy( fixmeIvy(
'FW-743: Registering events on global objects (document, window, body) is not supported') && 'FW-743: Registering events on global objects (document, window, body) is not supported')
it('should support render global events', () => { .it('should support render global events', () => {
TestBed.configureTestingModule({declarations: [MyComp, DirectiveListeningDomEvent]}); TestBed.configureTestingModule({declarations: [MyComp, DirectiveListeningDomEvent]});
const template = '<div listener></div>'; const template = '<div listener></div>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});
@ -947,8 +946,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(getDOM().getProperty(tc.nativeElement, 'id')).toEqual('newId'); expect(getDOM().getProperty(tc.nativeElement, 'id')).toEqual('newId');
}); });
fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') && fixmeIvy('FW-681: not possible to retrieve host property bindings from TView')
it('should not use template variables for expressions in hostProperties', () => { .it('should not use template variables for expressions in hostProperties', () => {
@Directive( @Directive(
{selector: '[host-properties]', host: {'[id]': 'id', '[title]': 'unknownProp'}}) {selector: '[host-properties]', host: {'[id]': 'id', '[title]': 'unknownProp'}})
class DirectiveWithHostProps { class DirectiveWithHostProps {
@ -968,8 +967,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(tc.properties['title']).toBe(undefined); expect(tc.properties['title']).toBe(undefined);
}); });
fixmeIvy('FW-725: Pipes in host bindings fail with a cryptic error') && fixmeIvy('FW-725: Pipes in host bindings fail with a cryptic error')
it('should not allow pipes in hostProperties', () => { .it('should not allow pipes in hostProperties', () => {
@Directive({selector: '[host-properties]', host: {'[id]': 'id | uppercase'}}) @Directive({selector: '[host-properties]', host: {'[id]': 'id | uppercase'}})
class DirectiveWithHostProps { class DirectiveWithHostProps {
} }
@ -1004,8 +1003,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(dir.receivedArgs).toEqual(['one', undefined]); expect(dir.receivedArgs).toEqual(['one', undefined]);
}); });
fixmeIvy('FW-742: Pipes in host listeners should throw a descriptive error') && fixmeIvy('FW-742: Pipes in host listeners should throw a descriptive error')
it('should not allow pipes in hostListeners', () => { .it('should not allow pipes in hostListeners', () => {
@Directive({selector: '[host-listener]', host: {'(click)': 'doIt() | somePipe'}}) @Directive({selector: '[host-listener]', host: {'(click)': 'doIt() | somePipe'}})
class DirectiveWithHostListener { class DirectiveWithHostListener {
} }
@ -1042,8 +1041,8 @@ function declareTests(config?: {useJit: boolean}) {
} }
fixmeIvy( fixmeIvy(
'FW-743: Registering events on global objects (document, window, body) is not supported') && 'FW-743: Registering events on global objects (document, window, body) is not supported')
it('should support render global events from multiple directives', () => { .it('should support render global events from multiple directives', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [MyComp, DirectiveListeningDomEvent, DirectiveListeningDomEventOther] declarations: [MyComp, DirectiveListeningDomEvent, DirectiveListeningDomEventOther]
}); });
@ -1123,8 +1122,8 @@ function declareTests(config?: {useJit: boolean}) {
.toHaveText('dynamic greet'); .toHaveText('dynamic greet');
})); }));
fixmeIvy('FW-707: TestBed: No LView in getParentInjectorLocation') && fixmeIvy('FW-707: TestBed: No LView in getParentInjectorLocation')
it('should create a component that has been freshly compiled', () => { .it('should create a component that has been freshly compiled', () => {
@Component({template: ''}) @Component({template: ''})
class RootComp { class RootComp {
constructor(public vc: ViewContainerRef) {} constructor(public vc: ViewContainerRef) {}
@ -1163,8 +1162,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(compRef.instance.someToken).toBe('someRootValue'); expect(compRef.instance.someToken).toBe('someRootValue');
}); });
fixmeIvy('FW-707: TestBed: No LView in getParentInjectorLocation') && fixmeIvy('FW-707: TestBed: No LView in getParentInjectorLocation')
it('should create a component with the passed NgModuleRef', () => { .it('should create a component with the passed NgModuleRef', () => {
@Component({template: ''}) @Component({template: ''})
class RootComp { class RootComp {
constructor(public vc: ViewContainerRef) {} constructor(public vc: ViewContainerRef) {}
@ -1204,8 +1203,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(compRef.instance.someToken).toBe('someValue'); expect(compRef.instance.someToken).toBe('someValue');
}); });
fixmeIvy('FW-707: TestBed: No LView in getParentInjectorLocation') && fixmeIvy('FW-707: TestBed: No LView in getParentInjectorLocation')
it('should create a component with the NgModuleRef of the ComponentFactoryResolver', .it('should create a component with the NgModuleRef of the ComponentFactoryResolver',
() => { () => {
@Component({template: ''}) @Component({template: ''})
class RootComp { class RootComp {
@ -1336,7 +1335,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(comp.injectable).toBeAnInstanceOf(InjectableService); expect(comp.injectable).toBeAnInstanceOf(InjectableService);
}); });
fixmeIvy('unknown') && it('should support viewProviders', () => { fixmeIvy('unknown').it('should support viewProviders', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [MyComp, DirectiveProvidingInjectableInView, DirectiveConsumingInjectable], declarations: [MyComp, DirectiveProvidingInjectableInView, DirectiveConsumingInjectable],
schemas: [NO_ERRORS_SCHEMA], schemas: [NO_ERRORS_SCHEMA],
@ -1448,8 +1447,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(getDOM().querySelectorAll(fixture.nativeElement, 'script').length).toEqual(0); expect(getDOM().querySelectorAll(fixture.nativeElement, 'script').length).toEqual(0);
}); });
fixmeIvy('FW-662: Components without selector are not supported') && fixmeIvy('FW-662: Components without selector are not supported')
it('should throw when using directives without selector', () => { .it('should throw when using directives without selector', () => {
@Directive({}) @Directive({})
class SomeDirective { class SomeDirective {
} }
@ -1496,8 +1495,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('error handling', () => { describe('error handling', () => {
fixmeIvy('FW-682: TestBed: tests assert that compilation produces specific error') && fixmeIvy('FW-682: TestBed: tests assert that compilation produces specific error')
it('should report a meaningful error when a directive is missing annotation', () => { .it('should report a meaningful error when a directive is missing annotation', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [MyComp, SomeDirectiveMissingAnnotation]}); {declarations: [MyComp, SomeDirectiveMissingAnnotation]});
@ -1506,8 +1505,9 @@ function declareTests(config?: {useJit: boolean}) {
`Unexpected value '${stringify(SomeDirectiveMissingAnnotation)}' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.`); `Unexpected value '${stringify(SomeDirectiveMissingAnnotation)}' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.`);
}); });
fixmeIvy('FW-682: TestBed: tests assert that compilation produces specific error') && fixmeIvy('FW-682: TestBed: tests assert that compilation produces specific error')
it('should report a meaningful error when a component is missing view annotation', () => { .it('should report a meaningful error when a component is missing view annotation',
() => {
TestBed.configureTestingModule({declarations: [MyComp, ComponentWithoutView]}); TestBed.configureTestingModule({declarations: [MyComp, ComponentWithoutView]});
try { try {
TestBed.createComponent(ComponentWithoutView); TestBed.createComponent(ComponentWithoutView);
@ -1518,8 +1518,8 @@ function declareTests(config?: {useJit: boolean}) {
} }
}); });
fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented') && fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented')
it('should provide an error context when an error happens in DI', () => { .it('should provide an error context when an error happens in DI', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [MyComp, DirectiveThrowingAnError], declarations: [MyComp, DirectiveThrowingAnError],
schemas: [NO_ERRORS_SCHEMA], schemas: [NO_ERRORS_SCHEMA],
@ -1537,8 +1537,8 @@ function declareTests(config?: {useJit: boolean}) {
} }
}); });
fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented') && fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented')
it('should provide an error context when an error happens in change detection', () => { .it('should provide an error context when an error happens in change detection', () => {
TestBed.configureTestingModule({declarations: [MyComp, DirectiveThrowingAnError]}); TestBed.configureTestingModule({declarations: [MyComp, DirectiveThrowingAnError]});
const template = `<input [value]="one.two.three" #local>`; const template = `<input [value]="one.two.three" #local>`;
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});
@ -1556,8 +1556,8 @@ function declareTests(config?: {useJit: boolean}) {
} }
}); });
fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented') && fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented')
it('should provide an error context when an error happens in change detection (text node)', .it('should provide an error context when an error happens in change detection (text node)',
() => { () => {
TestBed.configureTestingModule({declarations: [MyComp]}); TestBed.configureTestingModule({declarations: [MyComp]});
const template = `<div>{{one.two.three}}</div>`; const template = `<div>{{one.two.three}}</div>`;
@ -1573,8 +1573,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
if (getDOM().supportsDOMEvents()) { // this is required to use fakeAsync if (getDOM().supportsDOMEvents()) { // this is required to use fakeAsync
fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented') && fixmeIvy('FW-722: getDebugContext needs to be replaced / re-implemented')
it('should provide an error context when an error happens in an event handler', .it('should provide an error context when an error happens in an event handler',
fakeAsync(() => { fakeAsync(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent], declarations: [MyComp, DirectiveEmittingEvent, DirectiveListeningEvent],
@ -1636,8 +1636,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('Property bindings', () => { describe('Property bindings', () => {
fixmeIvy('FW-721: Bindings to unknown properties are not reported as errors') && fixmeIvy('FW-721: Bindings to unknown properties are not reported as errors')
it('should throw on bindings to unknown properties', () => { .it('should throw on bindings to unknown properties', () => {
TestBed.configureTestingModule({declarations: [MyComp]}); TestBed.configureTestingModule({declarations: [MyComp]});
const template = '<div unknown="{{ctxProp}}"></div>'; const template = '<div unknown="{{ctxProp}}"></div>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});
@ -1671,8 +1671,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(el.title).toBeFalsy(); expect(el.title).toBeFalsy();
}); });
fixmeIvy('FW-711: elementProperty instruction should not be used in host bindings') && fixmeIvy('FW-711: elementProperty instruction should not be used in host bindings')
it('should work when a directive uses hostProperty to update the DOM element', () => { .it('should work when a directive uses hostProperty to update the DOM element', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [MyComp, DirectiveWithTitleAndHostProperty]}); {declarations: [MyComp, DirectiveWithTitleAndHostProperty]});
const template = '<span [title]="ctxProp"></span>'; const template = '<span [title]="ctxProp"></span>';
@ -1688,8 +1688,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('logging property updates', () => { describe('logging property updates', () => {
fixmeIvy('FW-664: ng-reflect-* is not supported') && fixmeIvy('FW-664: ng-reflect-* is not supported')
it('should reflect property values as attributes', () => { .it('should reflect property values as attributes', () => {
TestBed.configureTestingModule({declarations: [MyComp, MyDir]}); TestBed.configureTestingModule({declarations: [MyComp, MyDir]});
const template = '<div>' + const template = '<div>' +
'<div my-dir [elprop]="ctxProp"></div>' + '<div my-dir [elprop]="ctxProp"></div>' +
@ -1712,8 +1712,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('ng-reflect-test_="hello"'); expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('ng-reflect-test_="hello"');
}); });
fixmeIvy('FW-664: ng-reflect-* is not supported') && fixmeIvy('FW-664: ng-reflect-* is not supported')
it('should reflect property values on template comments', () => { .it('should reflect property values on template comments', () => {
const fixture = const fixture =
TestBed.configureTestingModule({declarations: [MyComp]}) TestBed.configureTestingModule({declarations: [MyComp]})
.overrideComponent( .overrideComponent(
@ -1729,8 +1729,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
// also affected by FW-587: Inputs with aliases in component decorators don't work // also affected by FW-587: Inputs with aliases in component decorators don't work
fixmeIvy('FW-664: ng-reflect-* is not supported') && fixmeIvy('FW-664: ng-reflect-* is not supported')
it('should indicate when toString() throws', () => { .it('should indicate when toString() throws', () => {
TestBed.configureTestingModule({declarations: [MyComp, MyDir]}); TestBed.configureTestingModule({declarations: [MyComp, MyDir]});
const template = '<div my-dir [elprop]="toStringThrow"></div>'; const template = '<div my-dir [elprop]="toStringThrow"></div>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});

View File

@ -138,8 +138,8 @@ import {fixmeIvy} from '@angular/private/testing';
afterEach(() => { resetTestEnvironmentWithSummaries(); }); afterEach(() => { resetTestEnvironmentWithSummaries(); });
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && fixmeIvy('FW-514: ngSummary shims not generated by ngtsc')
it('should use directive metadata from summaries', () => { .it('should use directive metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries); resetTestEnvironmentWithSummaries(summaries);
@Component({template: '<div someDir></div>'}) @Component({template: '<div someDir></div>'})
@ -153,8 +153,8 @@ import {fixmeIvy} from '@angular/private/testing';
expectInstanceCreated(SomeDirective); expectInstanceCreated(SomeDirective);
}); });
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && fixmeIvy('FW-514: ngSummary shims not generated by ngtsc')
it('should use pipe metadata from summaries', () => { .it('should use pipe metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries); resetTestEnvironmentWithSummaries(summaries);
@Component({template: '{{1 | somePipe}}'}) @Component({template: '{{1 | somePipe}}'})
@ -166,8 +166,8 @@ import {fixmeIvy} from '@angular/private/testing';
expectInstanceCreated(SomePipe); expectInstanceCreated(SomePipe);
}); });
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && fixmeIvy('FW-514: ngSummary shims not generated by ngtsc')
it('should use Service metadata from summaries', () => { .it('should use Service metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries); resetTestEnvironmentWithSummaries(summaries);
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@ -177,8 +177,8 @@ import {fixmeIvy} from '@angular/private/testing';
expectInstanceCreated(SomeService); expectInstanceCreated(SomeService);
}); });
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && fixmeIvy('FW-514: ngSummary shims not generated by ngtsc')
it('should use NgModule metadata from summaries', () => { .it('should use NgModule metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries); resetTestEnvironmentWithSummaries(summaries);
TestBed TestBed
@ -192,8 +192,8 @@ import {fixmeIvy} from '@angular/private/testing';
expectInstanceCreated(SomeService); expectInstanceCreated(SomeService);
}); });
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && fixmeIvy('FW-514: ngSummary shims not generated by ngtsc')
it('should allow to create private components from imported NgModule summaries', () => { .it('should allow to create private components from imported NgModule summaries', () => {
resetTestEnvironmentWithSummaries(summaries); resetTestEnvironmentWithSummaries(summaries);
TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]}) TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
@ -201,8 +201,8 @@ import {fixmeIvy} from '@angular/private/testing';
expectInstanceCreated(SomePrivateComponent); expectInstanceCreated(SomePrivateComponent);
}); });
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && fixmeIvy('FW-514: ngSummary shims not generated by ngtsc')
it('should throw when trying to mock a type with a summary', () => { .it('should throw when trying to mock a type with a summary', () => {
resetTestEnvironmentWithSummaries(summaries); resetTestEnvironmentWithSummaries(summaries);
TestBed.resetTestingModule(); TestBed.resetTestingModule();
@ -221,8 +221,8 @@ import {fixmeIvy} from '@angular/private/testing';
.toThrowError('SomeModule was AOT compiled, so its metadata cannot be changed.'); .toThrowError('SomeModule was AOT compiled, so its metadata cannot be changed.');
}); });
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && fixmeIvy('FW-514: ngSummary shims not generated by ngtsc')
it('should return stack trace and component data on resetTestingModule when error is thrown', .it('should return stack trace and component data on resetTestingModule when error is thrown',
() => { () => {
resetTestEnvironmentWithSummaries(); resetTestEnvironmentWithSummaries();
@ -248,8 +248,8 @@ import {fixmeIvy} from '@angular/private/testing';
.toHaveBeenCalledWith('Error during cleanup of component', expectedObject); .toHaveBeenCalledWith('Error during cleanup of component', expectedObject);
}); });
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && fixmeIvy('FW-514: ngSummary shims not generated by ngtsc')
it('should allow to add summaries via configureTestingModule', () => { .it('should allow to add summaries via configureTestingModule', () => {
resetTestEnvironmentWithSummaries(); resetTestEnvironmentWithSummaries();
@Component({template: '<div someDir></div>'}) @Component({template: '<div someDir></div>'})
@ -266,8 +266,8 @@ import {fixmeIvy} from '@angular/private/testing';
expectInstanceCreated(SomeDirective); expectInstanceCreated(SomeDirective);
}); });
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && fixmeIvy('FW-514: ngSummary shims not generated by ngtsc')
it('should allow to override a provider', () => { .it('should allow to override a provider', () => {
resetTestEnvironmentWithSummaries(summaries); resetTestEnvironmentWithSummaries(summaries);
const overwrittenValue = {}; const overwrittenValue = {};
@ -280,8 +280,8 @@ import {fixmeIvy} from '@angular/private/testing';
expect(fixture.componentInstance.dep).toBe(overwrittenValue); expect(fixture.componentInstance.dep).toBe(overwrittenValue);
}); });
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && fixmeIvy('FW-514: ngSummary shims not generated by ngtsc')
it('should allow to override a template', () => { .it('should allow to override a template', () => {
resetTestEnvironmentWithSummaries(summaries); resetTestEnvironmentWithSummaries(summaries);
TestBed.overrideTemplateUsingTestingModule(SomePublicComponent, 'overwritten'); TestBed.overrideTemplateUsingTestingModule(SomePublicComponent, 'overwritten');

View File

@ -52,8 +52,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(el).toHaveText('foo'); expect(el).toHaveText('foo');
}); });
fixmeIvy('FW-678: ivy generates different DOM structure for <ng-container>') && fixmeIvy('FW-678: ivy generates different DOM structure for <ng-container>')
it('should be rendered as comment with children as siblings', () => { .it('should be rendered as comment with children as siblings', () => {
const template = '<ng-container><p></p></ng-container>'; const template = '<ng-container><p></p></ng-container>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp); const fixture = TestBed.createComponent(MyComp);
@ -67,8 +67,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(getDOM().tagName(children[1]).toUpperCase()).toEqual('P'); expect(getDOM().tagName(children[1]).toUpperCase()).toEqual('P');
}); });
fixmeIvy('FW-678: ivy generates different DOM structure for <ng-container>') && fixmeIvy('FW-678: ivy generates different DOM structure for <ng-container>')
it('should support nesting', () => { .it('should support nesting', () => {
const template = const template =
'<ng-container>1</ng-container><ng-container><ng-container>2</ng-container></ng-container>'; '<ng-container>1</ng-container><ng-container><ng-container>2</ng-container></ng-container>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});
@ -86,8 +86,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(children[4]).toHaveText('2'); expect(children[4]).toHaveText('2');
}); });
fixmeIvy('FW-678: ivy generates different DOM structure for <ng-container>') && fixmeIvy('FW-678: ivy generates different DOM structure for <ng-container>')
it('should group inner nodes', () => { .it('should group inner nodes', () => {
const template = '<ng-container *ngIf="ctxBoolProp"><p></p><b></b></ng-container>'; const template = '<ng-container *ngIf="ctxBoolProp"><p></p><b></b></ng-container>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});
const fixture = TestBed.createComponent(MyComp); const fixture = TestBed.createComponent(MyComp);
@ -136,8 +136,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(dir.text).toEqual('container'); expect(dir.text).toEqual('container');
}); });
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should contain all direct child directives in a <ng-container> (content dom)', () => { 'should contain all direct child directives in a <ng-container> (content dom)', () => {
const template = const template =
'<needs-content-children #q><ng-container><div text="foo"></div></ng-container></needs-content-children>'; '<needs-content-children #q><ng-container><div text="foo"></div></ng-container></needs-content-children>';
TestBed.overrideComponent(MyComp, {set: {template}}); TestBed.overrideComponent(MyComp, {set: {template}});

View File

@ -143,8 +143,8 @@ function declareTests(config?: {useJit: boolean}) {
} }
describe('errors', () => { describe('errors', () => {
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should error when exporting a directive that was neither declared nor imported', () => { .it('should error when exporting a directive that was neither declared nor imported', () => {
@NgModule({exports: [SomeDirective]}) @NgModule({exports: [SomeDirective]})
class SomeModule { class SomeModule {
} }
@ -154,8 +154,8 @@ function declareTests(config?: {useJit: boolean}) {
`Can't export directive ${stringify(SomeDirective)} from ${stringify(SomeModule)} as it was neither declared nor imported!`); `Can't export directive ${stringify(SomeDirective)} from ${stringify(SomeModule)} as it was neither declared nor imported!`);
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should error when exporting a pipe that was neither declared nor imported', () => { .it('should error when exporting a pipe that was neither declared nor imported', () => {
@NgModule({exports: [SomePipe]}) @NgModule({exports: [SomePipe]})
class SomeModule { class SomeModule {
} }
@ -165,8 +165,8 @@ function declareTests(config?: {useJit: boolean}) {
`Can't export pipe ${stringify(SomePipe)} from ${stringify(SomeModule)} as it was neither declared nor imported!`); `Can't export pipe ${stringify(SomePipe)} from ${stringify(SomeModule)} as it was neither declared nor imported!`);
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should error if a directive is declared in more than 1 module', () => { .it('should error if a directive is declared in more than 1 module', () => {
@NgModule({declarations: [SomeDirective]}) @NgModule({declarations: [SomeDirective]})
class Module1 { class Module1 {
} }
@ -184,8 +184,8 @@ function declareTests(config?: {useJit: boolean}) {
`You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${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)}.`);
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should error if a directive is declared in more than 1 module also if the module declaring it is imported', .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]}) @NgModule({declarations: [SomeDirective], exports: [SomeDirective]})
class Module1 { class Module1 {
@ -202,8 +202,8 @@ function declareTests(config?: {useJit: boolean}) {
`You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${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)}.`);
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should error if a pipe is declared in more than 1 module', () => { .it('should error if a pipe is declared in more than 1 module', () => {
@NgModule({declarations: [SomePipe]}) @NgModule({declarations: [SomePipe]})
class Module1 { class Module1 {
} }
@ -221,8 +221,8 @@ function declareTests(config?: {useJit: boolean}) {
`You can also create a new NgModule that exports and includes ${stringify(SomePipe)} then import that NgModule in ${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)}.`);
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should error if a pipe is declared in more than 1 module also if the module declaring it is imported', .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]}) @NgModule({declarations: [SomePipe], exports: [SomePipe]})
class Module1 { class Module1 {
@ -242,8 +242,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('schemas', () => { describe('schemas', () => {
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should error on unknown bound properties on custom elements by default', () => { .it('should error on unknown bound properties on custom elements by default', () => {
@Component({template: '<some-element [someUnknownProp]="true"></some-element>'}) @Component({template: '<some-element [someUnknownProp]="true"></some-element>'})
class ComponentUsingInvalidProperty { class ComponentUsingInvalidProperty {
} }
@ -281,16 +281,16 @@ function declareTests(config?: {useJit: boolean}) {
afterEach(() => clearModulesForTest()); afterEach(() => clearModulesForTest());
fixmeIvy('FW-740: missing global registry of NgModules by id') && fixmeIvy('FW-740: missing global registry of NgModules by id')
it('should register loaded modules', () => { .it('should register loaded modules', () => {
createModule(SomeModule); createModule(SomeModule);
const factory = getModuleFactory(token); const factory = getModuleFactory(token);
expect(factory).toBeTruthy(); expect(factory).toBeTruthy();
expect(factory.moduleType).toBe(SomeModule); expect(factory.moduleType).toBe(SomeModule);
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should throw when registering a duplicate module', () => { .it('should throw when registering a duplicate module', () => {
createModule(SomeModule); createModule(SomeModule);
expect(() => createModule(SomeOtherModule)).toThrowError(/Duplicate module registered/); expect(() => createModule(SomeOtherModule)).toThrowError(/Duplicate module registered/);
}); });
@ -311,8 +311,8 @@ function declareTests(config?: {useJit: boolean}) {
.toBe(SomeComp); .toBe(SomeComp);
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should throw if we cannot find a module associated with a module-level entryComponent', .it('should throw if we cannot find a module associated with a module-level entryComponent',
() => { () => {
@Component({template: ''}) @Component({template: ''})
class SomeCompWithEntryComponents { class SomeCompWithEntryComponents {
@ -327,8 +327,8 @@ function declareTests(config?: {useJit: boolean}) {
'Component SomeCompWithEntryComponents is not part of any NgModule or the module has not been imported into your module.'); 'Component SomeCompWithEntryComponents is not part of any NgModule or the module has not been imported into your module.');
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should throw if we cannot find a module associated with a component-level entryComponent', .it('should throw if we cannot find a module associated with a component-level entryComponent',
() => { () => {
@Component({template: '', entryComponents: [SomeComp]}) @Component({template: '', entryComponents: [SomeComp]})
class SomeCompWithEntryComponents { class SomeCompWithEntryComponents {
@ -426,8 +426,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('directives and pipes', () => { describe('directives and pipes', () => {
fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') && fixmeIvy('FW-681: not possible to retrieve host property bindings from TView')
describe('declarations', () => { .describe('declarations', () => {
it('should be supported in root modules', () => { it('should be supported in root modules', () => {
@NgModule({ @NgModule({
declarations: [CompUsingModuleDirectiveAndPipe, SomeDirective, SomePipe], declarations: [CompUsingModuleDirectiveAndPipe, SomeDirective, SomePipe],
@ -489,8 +489,8 @@ function declareTests(config?: {useJit: boolean}) {
describe('import/export', () => { describe('import/export', () => {
fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account')
it('should support exported directives and pipes', () => { .it('should support exported directives and pipes', () => {
@NgModule( @NgModule(
{declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]})
class SomeImportedModule { class SomeImportedModule {
@ -511,8 +511,8 @@ function declareTests(config?: {useJit: boolean}) {
.toBe('transformed someValue'); .toBe('transformed someValue');
}); });
fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account')
it('should support exported directives and pipes if the module is wrapped into an `ModuleWithProviders`', .it('should support exported directives and pipes if the module is wrapped into an `ModuleWithProviders`',
() => { () => {
@NgModule( @NgModule(
{declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]})
@ -534,8 +534,8 @@ function declareTests(config?: {useJit: boolean}) {
.toBe('transformed someValue'); .toBe('transformed someValue');
}); });
fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account')
it('should support reexported modules', () => { .it('should support reexported modules', () => {
@NgModule( @NgModule(
{declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]})
class SomeReexportedModule { class SomeReexportedModule {
@ -559,8 +559,8 @@ function declareTests(config?: {useJit: boolean}) {
.toBe('transformed someValue'); .toBe('transformed someValue');
}); });
fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account')
it('should support exporting individual directives of an imported module', () => { .it('should support exporting individual directives of an imported module', () => {
@NgModule( @NgModule(
{declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]})
class SomeReexportedModule { class SomeReexportedModule {
@ -584,8 +584,8 @@ function declareTests(config?: {useJit: boolean}) {
.toBe('transformed someValue'); .toBe('transformed someValue');
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should not use non exported pipes of an imported module', () => { .it('should not use non exported pipes of an imported module', () => {
@NgModule({ @NgModule({
declarations: [SomePipe], declarations: [SomePipe],
}) })
@ -604,8 +604,8 @@ function declareTests(config?: {useJit: boolean}) {
.toThrowError(/The pipe 'somePipe' could not be found/); .toThrowError(/The pipe 'somePipe' could not be found/);
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should not use non exported directives of an imported module', () => { .it('should not use non exported directives of an imported module', () => {
@NgModule({ @NgModule({
declarations: [SomeDirective], declarations: [SomeDirective],
}) })
@ -667,14 +667,14 @@ function declareTests(config?: {useJit: boolean}) {
expect(car.engine).toBeAnInstanceOf(TurboEngine); expect(car.engine).toBeAnInstanceOf(TurboEngine);
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should throw when no type and not @Inject (class case)', () => { .it('should throw when no type and not @Inject (class case)', () => {
expect(() => createInjector([NoAnnotations])) expect(() => createInjector([NoAnnotations]))
.toThrowError('Can\'t resolve all parameters for NoAnnotations: (?).'); .toThrowError('Can\'t resolve all parameters for NoAnnotations: (?).');
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should throw when no type and not @Inject (factory case)', () => { .it('should throw when no type and not @Inject (factory case)', () => {
expect(() => createInjector([{provide: 'someToken', useFactory: factoryFn}])) expect(() => createInjector([{provide: 'someToken', useFactory: factoryFn}]))
.toThrowError('Can\'t resolve all parameters for factoryFn: (?).'); .toThrowError('Can\'t resolve all parameters for factoryFn: (?).');
}); });
@ -745,8 +745,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(cars[0]).toBe(injector.get(SportsCar)); expect(cars[0]).toBe(injector.get(SportsCar));
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should throw when the aliased provider does not exist', () => { .it('should throw when the aliased provider does not exist', () => {
const injector = createInjector([{provide: 'car', useExisting: SportsCar}]); const injector = createInjector([{provide: 'car', useExisting: SportsCar}]);
const e = `NullInjectorError: No provider for ${stringify(SportsCar)}!`; const e = `NullInjectorError: No provider for ${stringify(SportsCar)}!`;
expect(() => injector.get('car')).toThrowError(e); expect(() => injector.get('car')).toThrowError(e);
@ -796,14 +796,13 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token')).toEqual('value'); expect(injector.get('token')).toEqual('value');
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling').it('should throw when given invalid providers', () => {
it('should throw when given invalid providers', () => {
expect(() => createInjector(<any>['blah'])) expect(() => createInjector(<any>['blah']))
.toThrowError( .toThrowError(
`Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?blah?]`); `Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?blah?]`);
}); });
fixmeIvy('FW-682: Compiler error handling') && it('should throw when given blank providers', () => { fixmeIvy('FW-682: Compiler error handling').it('should throw when given blank providers', () => {
expect(() => createInjector(<any>[null, {provide: 'token', useValue: 'value'}])) expect(() => createInjector(<any>[null, {provide: 'token', useValue: 'value'}]))
.toThrowError( .toThrowError(
`Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?null?, ...]`); `Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?null?, ...]`);
@ -949,8 +948,8 @@ function declareTests(config?: {useJit: boolean}) {
.toThrowError('NullInjectorError: No provider for NonExisting!'); .toThrowError('NullInjectorError: No provider for NonExisting!');
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should throw when trying to instantiate a cyclic dependency', () => { .it('should throw when trying to instantiate a cyclic dependency', () => {
expect(() => createInjector([Car, {provide: Engine, useClass: CyclicEngine}])) expect(() => createInjector([Car, {provide: Engine, useClass: CyclicEngine}]))
.toThrowError(/Cannot instantiate cyclic dependency! Car/g); .toThrowError(/Cannot instantiate cyclic dependency! Car/g);
}); });
@ -1053,8 +1052,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(created).toBe(false); expect(created).toBe(false);
}); });
fixmeIvy('FW-739: TestBed: destroy on NgModuleRef is not being called') && fixmeIvy('FW-739: TestBed: destroy on NgModuleRef is not being called')
it('should support ngOnDestroy on any provider', () => { .it('should support ngOnDestroy on any provider', () => {
let destroyed = false; let destroyed = false;
class SomeInjectable { class SomeInjectable {
@ -1073,8 +1072,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(destroyed).toBe(true); expect(destroyed).toBe(true);
}); });
fixmeIvy('FW-739: TestBed: destroy on NgModuleRef is not being called') && fixmeIvy('FW-739: TestBed: destroy on NgModuleRef is not being called')
it('should support ngOnDestroy for lazy providers', () => { .it('should support ngOnDestroy for lazy providers', () => {
let created = false; let created = false;
let destroyed = false; let destroyed = false;
@ -1318,8 +1317,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('imported2'); expect(injector.get('token1')).toBe('imported2');
}); });
fixmeIvy('FW-682: Compiler error handling') && fixmeIvy('FW-682: Compiler error handling')
it('should throw when given invalid providers in an imported ModuleWithProviders', () => { .it('should throw when given invalid providers in an imported ModuleWithProviders', () => {
@NgModule() @NgModule()
class ImportedModule1 { class ImportedModule1 {
} }
@ -1335,8 +1334,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('tree shakable providers', () => { describe('tree shakable providers', () => {
fixmeIvy('FW-794: NgModuleDefinition not exposed on NgModuleData') && fixmeIvy('FW-794: NgModuleDefinition not exposed on NgModuleData')
it('definition should not persist across NgModuleRef instances', () => { .it('definition should not persist across NgModuleRef instances', () => {
@NgModule() @NgModule()
class SomeModule { class SomeModule {
} }

View File

@ -82,8 +82,8 @@ import {fixmeIvy} from '@angular/private/testing';
expect(main.nativeElement).toHaveText(''); expect(main.nativeElement).toHaveText('');
}); });
fixmeIvy('FW-789: select attribute on <ng-content> should not be case-sensitive') && fixmeIvy('FW-789: select attribute on <ng-content> should not be case-sensitive')
it('should support multiple content tags', () => { .it('should support multiple content tags', () => {
TestBed.configureTestingModule({declarations: [MultipleContentTagsComponent]}); TestBed.configureTestingModule({declarations: [MultipleContentTagsComponent]});
TestBed.overrideComponent(MainComp, { TestBed.overrideComponent(MainComp, {
set: { set: {
@ -114,8 +114,8 @@ import {fixmeIvy} from '@angular/private/testing';
expect(main.nativeElement).toHaveText('(, BAC)'); expect(main.nativeElement).toHaveText('(, BAC)');
}); });
fixmeIvy('FW-665: Unable to find the given context data for the given target') && 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', () => { .it('should redistribute direct child viewcontainers when the light dom changes', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [MultipleContentTagsComponent, ManualViewportDirective]}); {declarations: [MultipleContentTagsComponent, ManualViewportDirective]});
TestBed.overrideComponent(MainComp, { TestBed.overrideComponent(MainComp, {
@ -158,8 +158,8 @@ import {fixmeIvy} from '@angular/private/testing';
expect(main.nativeElement).toHaveText('OUTER(SIMPLE(AB))'); expect(main.nativeElement).toHaveText('OUTER(SIMPLE(AB))');
}); });
fixmeIvy('FW-665: Unable to find the given context data for the given target') && 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', () => { .it('should support nesting with content being direct child of a nested component', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: declarations:
[InnerComponent, InnerInnerComponent, OuterComponent, ManualViewportDirective] [InnerComponent, InnerInnerComponent, OuterComponent, ManualViewportDirective]
@ -186,8 +186,8 @@ import {fixmeIvy} from '@angular/private/testing';
}); });
fixmeIvy( fixmeIvy(
'FW-745: Compiler isn\'t generating projectionDefs for <ng-content> tags inside <ng-templates>') && 'FW-745: Compiler isn\'t generating projectionDefs for <ng-content> tags inside <ng-templates>')
it('should redistribute when the shadow dom changes', () => { .it('should redistribute when the shadow dom changes', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [ConditionalContentComponent, ManualViewportDirective]}); {declarations: [ConditionalContentComponent, ManualViewportDirective]});
TestBed.overrideComponent(MainComp, { TestBed.overrideComponent(MainComp, {
@ -295,8 +295,8 @@ import {fixmeIvy} from '@angular/private/testing';
expect(main.nativeElement).toHaveText('SIMPLE()START(A)END'); expect(main.nativeElement).toHaveText('SIMPLE()START(A)END');
}); });
fixmeIvy('FW-665: Unable to find the given context data for the given target') && fixmeIvy('FW-665: Unable to find the given context data for the given target')
it('should support moving ng-content around', () => { .it('should support moving ng-content around', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: declarations:
[ConditionalContentComponent, ProjectDirective, ManualViewportDirective] [ConditionalContentComponent, ProjectDirective, ManualViewportDirective]
@ -435,8 +435,8 @@ import {fixmeIvy} from '@angular/private/testing';
}); });
} }
fixmeIvy('FW-665: Unable to find the given context data for the given target') && fixmeIvy('FW-665: Unable to find the given context data for the given target')
it('should support nested conditionals that contain ng-contents', () => { .it('should support nested conditionals that contain ng-contents', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [ConditionalTextComponent, ManualViewportDirective]}); {declarations: [ConditionalTextComponent, ManualViewportDirective]});
TestBed.overrideComponent( TestBed.overrideComponent(
@ -482,8 +482,8 @@ import {fixmeIvy} from '@angular/private/testing';
}); });
fixmeIvy( fixmeIvy(
'FW-745: Compiler isn\'t generating projectionDefs for <ng-content> tags inside <ng-templates>') && 'FW-745: Compiler isn\'t generating projectionDefs for <ng-content> tags inside <ng-templates>')
it('should project filled view containers into a view container', () => { .it('should project filled view containers into a view container', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [ConditionalContentComponent, ManualViewportDirective]}); {declarations: [ConditionalContentComponent, ManualViewportDirective]});
TestBed.overrideComponent(MainComp, { TestBed.overrideComponent(MainComp, {

View File

@ -54,8 +54,8 @@ describe('Query API', () => {
describe('querying by directive type', () => { describe('querying by directive type', () => {
fixmeIvy( fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
it('should contain all direct child directives in the light dom (constructor)', () => { .it('should contain all direct child directives in the light dom (constructor)', () => {
const template = ` const template = `
<div text="1"></div> <div text="1"></div>
<needs-query text="2"> <needs-query text="2">
@ -97,8 +97,8 @@ describe('Query API', () => {
}); });
fixmeIvy( fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
it('should contain the first content child when target is on <ng-template> with embedded view (issue #16568)', .it('should contain the first content child when target is on <ng-template> with embedded view (issue #16568)',
() => { () => {
const template = const template =
'<div directive-needs-content-child><ng-template text="foo" [ngIf]="true"><div text="bar"></div></ng-template></div>' + '<div directive-needs-content-child><ng-template text="foo" [ngIf]="true"><div text="bar"></div></ng-template></div>' +
@ -112,8 +112,8 @@ describe('Query API', () => {
expect(directive.child.text).toEqual('foo'); expect(directive.child.text).toEqual('foo');
}); });
fixmeIvy('FW-782 - View queries are executed twice in some cases') && fixmeIvy('FW-782 - View queries are executed twice in some cases')
it('should contain the first view child', () => { .it('should contain the first view child', () => {
const template = '<needs-view-child #q></needs-view-child>'; const template = '<needs-view-child #q></needs-view-child>';
const view = createTestCmpAndDetectChanges(MyComp0, template); const view = createTestCmpAndDetectChanges(MyComp0, template);
@ -128,8 +128,8 @@ describe('Query API', () => {
]); ]);
}); });
fixmeIvy('FW-782 - View queries are executed twice in some cases') && fixmeIvy('FW-782 - View queries are executed twice in some cases')
it('should set static view and content children already after the constructor call', () => { .it('should set static view and content children already after the constructor call', () => {
const template = const template =
'<needs-static-content-view-child #q><div text="contentFoo"></div></needs-static-content-view-child>'; '<needs-static-content-view-child #q><div text="contentFoo"></div></needs-static-content-view-child>';
const view = createTestCmp(MyComp0, template); const view = createTestCmp(MyComp0, template);
@ -142,8 +142,8 @@ describe('Query API', () => {
expect(q.viewChild.text).toEqual('viewFoo'); expect(q.viewChild.text).toEqual('viewFoo');
}); });
fixmeIvy('FW-782 - View queries are executed twice in some cases') && fixmeIvy('FW-782 - View queries are executed twice in some cases')
it('should contain the first view child across embedded views', () => { .it('should contain the first view child across embedded views', () => {
TestBed.overrideComponent( TestBed.overrideComponent(
MyComp0, {set: {template: '<needs-view-child #q></needs-view-child>'}}); MyComp0, {set: {template: '<needs-view-child #q></needs-view-child>'}});
TestBed.overrideComponent(NeedsViewChild, { TestBed.overrideComponent(NeedsViewChild, {
@ -172,8 +172,8 @@ describe('Query API', () => {
}); });
fixmeIvy( fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
it('should contain all directives in the light dom when descendants flag is used', () => { .it('should contain all directives in the light dom when descendants flag is used', () => {
const template = '<div text="1"></div>' + const template = '<div text="1"></div>' +
'<needs-query-desc text="2"><div text="3">' + '<needs-query-desc text="2"><div text="3">' +
'<div text="4"></div>' + '<div text="4"></div>' +
@ -185,8 +185,8 @@ describe('Query API', () => {
}); });
fixmeIvy( fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
it('should contain all directives in the light dom', () => { .it('should contain all directives in the light dom', () => {
const template = '<div text="1"></div>' + const template = '<div text="1"></div>' +
'<needs-query text="2"><div text="3"></div></needs-query>' + '<needs-query text="2"><div text="3"></div></needs-query>' +
'<div text="4"></div>'; '<div text="4"></div>';
@ -196,8 +196,8 @@ describe('Query API', () => {
}); });
fixmeIvy( fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
it('should reflect dynamically inserted directives', () => { .it('should reflect dynamically inserted directives', () => {
const template = '<div text="1"></div>' + const template = '<div text="1"></div>' +
'<needs-query text="2"><div *ngIf="shouldShow" [text]="\'3\'"></div></needs-query>' + '<needs-query text="2"><div *ngIf="shouldShow" [text]="\'3\'"></div></needs-query>' +
'<div text="4"></div>'; '<div text="4"></div>';
@ -221,8 +221,8 @@ describe('Query API', () => {
}); });
fixmeIvy( fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
it('should reflect moved directives', () => { .it('should reflect moved directives', () => {
const template = '<div text="1"></div>' + const template = '<div text="1"></div>' +
'<needs-query text="2"><div *ngFor="let i of list" [text]="i"></div></needs-query>' + '<needs-query text="2"><div *ngFor="let i of list" [text]="i"></div></needs-query>' +
'<div text="4"></div>'; '<div text="4"></div>';
@ -234,8 +234,8 @@ describe('Query API', () => {
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3d|2d|'); expect(asNativeElements(view.debugElement.children)).toHaveText('2|3d|2d|');
}); });
fixmeIvy('FW-682 - TestBed: tests assert that compilation produces specific error') && fixmeIvy('FW-682 - TestBed: tests assert that compilation produces specific error')
it('should throw with descriptive error when query selectors are not present', () => { .it('should throw with descriptive error when query selectors are not present', () => {
TestBed.configureTestingModule({declarations: [MyCompBroken0, HasNullQueryCondition]}); TestBed.configureTestingModule({declarations: [MyCompBroken0, HasNullQueryCondition]});
const template = '<has-null-query-condition></has-null-query-condition>'; const template = '<has-null-query-condition></has-null-query-condition>';
TestBed.overrideComponent(MyCompBroken0, {set: {template}}); TestBed.overrideComponent(MyCompBroken0, {set: {template}});
@ -268,8 +268,8 @@ describe('Query API', () => {
describe('read a different token', () => { describe('read a different token', () => {
modifiedInIvy( modifiedInIvy(
'Breaking change in Ivy: no longer allow multiple local refs with the same name, all local refs are now unique') && 'Breaking change in Ivy: no longer allow multiple local refs with the same name, all local refs are now unique')
it('should contain all content children', () => { .it('should contain all content children', () => {
const template = const template =
'<needs-content-children-read #q text="ca"><div #q text="cb"></div></needs-content-children-read>'; '<needs-content-children-read #q text="ca"><div #q text="cb"></div></needs-content-children-read>';
const view = createTestCmpAndDetectChanges(MyComp0, template); const view = createTestCmpAndDetectChanges(MyComp0, template);
@ -477,17 +477,19 @@ describe('Query API', () => {
describe('querying in the view', () => { describe('querying in the view', () => {
fixmeIvy( fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
it('should contain all the elements in the view with that have the given directive', () => { .it('should contain all the elements in the view with that have the given directive',
const template = '<needs-view-query #q><div text="ignoreme"></div></needs-view-query>'; () => {
const template =
'<needs-view-query #q><div text="ignoreme"></div></needs-view-query>';
const view = createTestCmpAndDetectChanges(MyComp0, template); const view = createTestCmpAndDetectChanges(MyComp0, template);
const q: NeedsViewQuery = view.debugElement.children[0].references !['q']; const q: NeedsViewQuery = view.debugElement.children[0].references !['q'];
expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']);
}); });
fixmeIvy( fixmeIvy(
'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy') && 'FW-781 - Directives invocation sequence on root and nested elements is different in Ivy')
it('should not include directive present on the host element', () => { .it('should not include directive present on the host element', () => {
const template = '<needs-view-query #q text="self"></needs-view-query>'; const template = '<needs-view-query #q text="self"></needs-view-query>';
const view = createTestCmpAndDetectChanges(MyComp0, template); const view = createTestCmpAndDetectChanges(MyComp0, template);
const q: NeedsViewQuery = view.debugElement.children[0].references !['q']; const q: NeedsViewQuery = view.debugElement.children[0].references !['q'];
@ -588,8 +590,8 @@ describe('Query API', () => {
}); });
// Note: this test is just document our current behavior, which we do for performance reasons. // Note: this test is just document our current behavior, which we do for performance reasons.
fixmeIvy('FW-782 - View queries are executed twice in some cases') && fixmeIvy('FW-782 - View queries are executed twice in some cases')
it('should not affected queries for projected templates if views are detached or moved', () => { .it('should not affected queries for projected templates if views are detached or moved', () => {
const template = const template =
'<manual-projecting #q><ng-template let-x="x"><div [text]="x"></div></ng-template></manual-projecting>'; '<manual-projecting #q><ng-template let-x="x"><div [text]="x"></div></ng-template></manual-projecting>';
const view = createTestCmpAndDetectChanges(MyComp0, template); const view = createTestCmpAndDetectChanges(MyComp0, template);
@ -615,8 +617,8 @@ describe('Query API', () => {
}); });
fixmeIvy( fixmeIvy(
'FW-763 - LView tree not properly constructed / destroyed for dynamically inserted components') && 'FW-763 - LView tree not properly constructed / destroyed for dynamically inserted components')
it('should remove manually projected templates if their parent view is destroyed', () => { .it('should remove manually projected templates if their parent view is destroyed', () => {
const template = ` const template = `
<manual-projecting #q><ng-template #tpl><div text="1"></div></ng-template></manual-projecting> <manual-projecting #q><ng-template #tpl><div text="1"></div></ng-template></manual-projecting>
<div *ngIf="shouldShow"> <div *ngIf="shouldShow">
@ -635,8 +637,8 @@ describe('Query API', () => {
expect(q.query.length).toBe(0); expect(q.query.length).toBe(0);
}); });
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should not throw if a content template is queried and created in the view during change detection', 'should not throw if a content template is queried and created in the view during change detection',
() => { () => {
@Component( @Component(
{selector: 'auto-projecting', template: '<div *ngIf="true; then: content"></div>'}) {selector: 'auto-projecting', template: '<div *ngIf="true; then: content"></div>'})

View File

@ -32,7 +32,7 @@ function declareTests(config?: {useJit: boolean}) {
describe('platform pipes', () => { describe('platform pipes', () => {
beforeEach(() => { TestBed.configureCompiler({...config}); }); beforeEach(() => { TestBed.configureCompiler({...config}); });
fixmeIvy('unknown') && it('should overwrite them by custom pipes', () => { fixmeIvy('unknown').it('should overwrite them by custom pipes', () => {
TestBed.configureTestingModule({declarations: [CustomPipe]}); TestBed.configureTestingModule({declarations: [CustomPipe]});
const template = '{{true | somePipe}}'; const template = '{{true | somePipe}}';
TestBed.overrideComponent(MyComp1, {set: {template}}); TestBed.overrideComponent(MyComp1, {set: {template}});
@ -74,8 +74,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(CountingPipe.calls).toBe(1); expect(CountingPipe.calls).toBe(1);
}); });
fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account') && fixmeIvy('FW-756: Pipes and directives from imported modules are not taken into account')
it('should only update the bound property when using asyncPipe - #15205', .it('should only update the bound property when using asyncPipe - #15205',
fakeAsync(() => { fakeAsync(() => {
@Component({template: '<div myDir [a]="p | async" [b]="2"></div>'}) @Component({template: '<div myDir [a]="p | async" [b]="2"></div>'})
class MyComp { class MyComp {
@ -333,8 +333,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(fixture.debugElement.childNodes.length).toBe(0); expect(fixture.debugElement.childNodes.length).toBe(0);
}); });
modifiedInIvy('Comment node order changed') && modifiedInIvy('Comment node order changed')
it('should allow empty embedded templates', () => { .it('should allow empty embedded templates', () => {
@Component({template: '<ng-template [ngIf]="true"></ng-template>'}) @Component({template: '<ng-template [ngIf]="true"></ng-template>'})
class MyComp { class MyComp {
} }
@ -351,9 +351,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
}); });
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should support @ContentChild and @Input on the same property for static queries', 'should support @ContentChild and @Input on the same property for static queries', () => {
() => {
@Directive({selector: 'test'}) @Directive({selector: 'test'})
class Test { class Test {
// TODO(issue/24571): remove '!'. // TODO(issue/24571): remove '!'.

View File

@ -52,8 +52,8 @@ function declareTests(config?: {useJit: boolean}) {
afterEach(() => { getDOM().log = originalLog; }); afterEach(() => { getDOM().log = originalLog; });
describe('events', () => { describe('events', () => {
fixmeIvy('FW-787: Exception in template parsing leaves TestBed in corrupted state') && fixmeIvy('FW-787: Exception in template parsing leaves TestBed in corrupted state')
it('should disallow binding to attr.on*', () => { .it('should disallow binding to attr.on*', () => {
const template = `<div [attr.onclick]="ctxProp"></div>`; const template = `<div [attr.onclick]="ctxProp"></div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});
@ -62,8 +62,8 @@ function declareTests(config?: {useJit: boolean}) {
/Binding to event attribute 'onclick' is disallowed for security reasons, please use \(click\)=.../); /Binding to event attribute 'onclick' is disallowed for security reasons, please use \(click\)=.../);
}); });
fixmeIvy('FW-787: Exception in template parsing leaves TestBed in corrupted state') && fixmeIvy('FW-787: Exception in template parsing leaves TestBed in corrupted state')
it('should disallow binding to on* with NO_ERRORS_SCHEMA', () => { .it('should disallow binding to on* with NO_ERRORS_SCHEMA', () => {
const template = `<div [onclick]="ctxProp"></div>`; const template = `<div [onclick]="ctxProp"></div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({ TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA]
@ -75,8 +75,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
fixmeIvy( fixmeIvy(
'FW-786: Element properties and directive inputs are not distinguished for sanitisation purposes') && 'FW-786: Element properties and directive inputs are not distinguished for sanitisation purposes')
it('should disallow binding to on* unless it is consumed by a directive', () => { .it('should disallow binding to on* unless it is consumed by a directive', () => {
const template = `<div [onPrefixedProp]="ctxProp" [onclick]="ctxProp"></div>`; const template = `<div [onPrefixedProp]="ctxProp" [onclick]="ctxProp"></div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({ TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA]
@ -173,8 +173,8 @@ function declareTests(config?: {useJit: boolean}) {
checkEscapeOfHrefProperty(fixture, true); checkEscapeOfHrefProperty(fixture, true);
}); });
fixmeIvy('FW-785: Host bindings are not sanitised') && fixmeIvy('FW-785: Host bindings are not sanitised')
it('should escape unsafe properties if they are used in host bindings', () => { .it('should escape unsafe properties if they are used in host bindings', () => {
@Directive({selector: '[dirHref]'}) @Directive({selector: '[dirHref]'})
class HrefDirective { class HrefDirective {
// TODO(issue/24571): remove '!'. // TODO(issue/24571): remove '!'.
@ -190,8 +190,8 @@ function declareTests(config?: {useJit: boolean}) {
checkEscapeOfHrefProperty(fixture, false); checkEscapeOfHrefProperty(fixture, false);
}); });
fixmeIvy('FW-785: Host bindings are not sanitised') && fixmeIvy('FW-785: Host bindings are not sanitised')
it('should escape unsafe attributes if they are used in host bindings', () => { .it('should escape unsafe attributes if they are used in host bindings', () => {
@Directive({selector: '[dirHref]'}) @Directive({selector: '[dirHref]'})
class HrefDirective { class HrefDirective {
// TODO(issue/24571): remove '!'. // TODO(issue/24571): remove '!'.
@ -227,8 +227,8 @@ function declareTests(config?: {useJit: boolean}) {
expect(getDOM().getStyle(e, 'background')).not.toContain('javascript'); expect(getDOM().getStyle(e, 'background')).not.toContain('javascript');
}); });
fixmeIvy('FW-787: Exception in template parsing leaves TestBed in corrupted state') && fixmeIvy('FW-787: Exception in template parsing leaves TestBed in corrupted state')
it('should escape unsafe SVG attributes', () => { .it('should escape unsafe SVG attributes', () => {
const template = `<svg:circle [xlink:href]="ctxProp">Text</svg:circle>`; const template = `<svg:circle [xlink:href]="ctxProp">Text</svg:circle>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});

View File

@ -102,29 +102,29 @@ import {fixmeIvy} from '@angular/private/testing';
function declareTests( function declareTests(
{ngUrl, templateDecorator}: {ngUrl, templateDecorator}:
{ngUrl: string, templateDecorator: (template: string) => { [key: string]: any }}) { {ngUrl: string, templateDecorator: (template: string) => { [key: string]: any }}) {
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should use the right source url in html parse errors', fakeAsync(() => { 'should use the right source url in html parse errors', fakeAsync(() => {
@Component({...templateDecorator('<div>\n </error>')}) @Component({...templateDecorator('<div>\n </error>')})
class MyComp { class MyComp {
} }
expect(() => compileAndCreateComponent(MyComp)) expect(() => compileAndCreateComponent(MyComp))
.toThrowError(new RegExp( .toThrowError(
`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:2`)); new RegExp(`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:2`));
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should use the right source url in template parse errors', fakeAsync(() => { 'should use the right source url in template parse errors', fakeAsync(() => {
@Component({...templateDecorator('<div>\n <div unknown="{{ctxProp}}"></div>')}) @Component({...templateDecorator('<div>\n <div unknown="{{ctxProp}}"></div>')})
class MyComp { class MyComp {
} }
expect(() => compileAndCreateComponent(MyComp)) expect(() => compileAndCreateComponent(MyComp))
.toThrowError(new RegExp( .toThrowError(
`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:7`)); new RegExp(`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:7`));
})); }));
fixmeIvy('unknown') && it('should create a sourceMap for templates', fakeAsync(() => { fixmeIvy('unknown').it('should create a sourceMap for templates', fakeAsync(() => {
const template = `Hello World!`; const template = `Hello World!`;
@Component({...templateDecorator(template)}) @Component({...templateDecorator(template)})
@ -142,8 +142,8 @@ import {fixmeIvy} from '@angular/private/testing';
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should report source location for di errors', fakeAsync(() => { 'should report source location for di errors', fakeAsync(() => {
const template = `<div>\n <div someDir></div></div>`; const template = `<div>\n <div someDir></div></div>`;
@Component({...templateDecorator(template)}) @Component({...templateDecorator(template)})
@ -170,8 +170,8 @@ import {fixmeIvy} from '@angular/private/testing';
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should report di errors with multiple elements and directives', fakeAsync(() => { 'should report di errors with multiple elements and directives', fakeAsync(() => {
const template = `<div someDir></div><div someDir="throw"></div>`; const template = `<div someDir></div><div someDir="throw"></div>`;
@Component({...templateDecorator(template)}) @Component({...templateDecorator(template)})
@ -202,8 +202,8 @@ import {fixmeIvy} from '@angular/private/testing';
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should report source location for binding errors', fakeAsync(() => { 'should report source location for binding errors', fakeAsync(() => {
const template = `<div>\n <span [title]="createError()"></span></div>`; const template = `<div>\n <span [title]="createError()"></span></div>`;
@Component({...templateDecorator(template)}) @Component({...templateDecorator(template)})
@ -233,8 +233,8 @@ import {fixmeIvy} from '@angular/private/testing';
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should report source location for event errors', fakeAsync(() => { 'should report source location for event errors', fakeAsync(() => {
const template = `<div>\n <span (click)="createError()"></span></div>`; const template = `<div>\n <span (click)="createError()"></span></div>`;
@Component({...templateDecorator(template)}) @Component({...templateDecorator(template)})

View File

@ -138,7 +138,7 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep instanceof Dep).toBeTruthy(); expect(instance.dep instanceof Dep).toBeTruthy();
}); });
fixmeIvy('unknown') && it('should not inject deps from sibling root elements', () => { fixmeIvy('unknown').it('should not inject deps from sibling root elements', () => {
const rootElNodes = [ const rootElNodes = [
elementDef(0, NodeFlags.None, null, null, 1, 'span'), elementDef(0, NodeFlags.None, null, null, 1, 'span'),
directiveDef(1, NodeFlags.None, null, 0, Dep, []), directiveDef(1, NodeFlags.None, null, 0, Dep, []),
@ -181,7 +181,7 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep instanceof Dep).toBeTruthy(); expect(instance.dep instanceof Dep).toBeTruthy();
}); });
fixmeIvy('unknown') && it('should throw for missing dependencies', () => { fixmeIvy('unknown').it('should throw for missing dependencies', () => {
expect(() => createAndGetRootNodes(compViewDef([ expect(() => createAndGetRootNodes(compViewDef([
elementDef(0, NodeFlags.None, null, null, 1, 'span'), elementDef(0, NodeFlags.None, null, null, 1, 'span'),
directiveDef(1, NodeFlags.None, null, 0, SomeService, ['nonExistingDep']) directiveDef(1, NodeFlags.None, null, 0, SomeService, ['nonExistingDep'])

View File

@ -160,7 +160,8 @@ function bootstrap(
afterEach(destroyPlatform); afterEach(destroyPlatform);
fixmeIvy('FW-553: TestBed is unaware of async compilation') && // TODO(misko): can't use `fixmeIvy.it` because the `it` is somehow special here.
fixmeIvy('FW-553: TestBed is unaware of async compilation').isEnabled &&
it('should throw if bootstrapped Directive is not a Component', it('should throw if bootstrapped Directive is not a Component',
inject([AsyncTestCompleter], (done: AsyncTestCompleter) => { inject([AsyncTestCompleter], (done: AsyncTestCompleter) => {
const logger = new MockConsole(); const logger = new MockConsole();
@ -188,7 +189,8 @@ function bootstrap(
}); });
})); }));
fixmeIvy('FW-553: TestBed is unaware of async compilation') && // TODO(misko): can't use `fixmeIvy.it` because the `it` is somehow special here.
fixmeIvy('FW-553: TestBed is unaware of async compilation').isEnabled &&
it('should throw if no provider', it('should throw if no provider',
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
const logger = new MockConsole(); const logger = new MockConsole();

View File

@ -251,8 +251,8 @@ class CompWithUrlTemplate {
expect(compFixture.componentInstance).toBeAnInstanceOf(CompUsingModuleDirectiveAndPipe); expect(compFixture.componentInstance).toBeAnInstanceOf(CompUsingModuleDirectiveAndPipe);
}); });
fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') && fixmeIvy('FW-681: not possible to retrieve host property bindings from TView')
it('should use set up directives and pipes', () => { .it('should use set up directives and pipes', () => {
const compFixture = TestBed.createComponent(CompUsingModuleDirectiveAndPipe); const compFixture = TestBed.createComponent(CompUsingModuleDirectiveAndPipe);
const el = compFixture.debugElement; const el = compFixture.debugElement;
@ -289,8 +289,8 @@ class CompWithUrlTemplate {
expect(service.value).toEqual('real value'); expect(service.value).toEqual('real value');
})); }));
fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') && fixmeIvy('FW-681: not possible to retrieve host property bindings from TView')
it('should use set up directives and pipes', withModule(moduleConfig, () => { .it('should use set up directives and pipes', withModule(moduleConfig, () => {
const compFixture = TestBed.createComponent(CompUsingModuleDirectiveAndPipe); const compFixture = TestBed.createComponent(CompUsingModuleDirectiveAndPipe);
const el = compFixture.debugElement; const el = compFixture.debugElement;
@ -310,8 +310,9 @@ class CompWithUrlTemplate {
TestBed.compileComponents(); TestBed.compileComponents();
})); }));
fixmeIvy('FW-553: TestBed is unaware of async compilation') && isBrowser && isBrowser &&
it('should allow to createSync components with templateUrl after explicit async compilation', fixmeIvy('FW-553: TestBed is unaware of async compilation')
.it('should allow to createSync components with templateUrl after explicit async compilation',
() => { () => {
const fixture = TestBed.createComponent(CompWithUrlTemplate); const fixture = TestBed.createComponent(CompWithUrlTemplate);
expect(fixture.nativeElement).toHaveText('from external template'); expect(fixture.nativeElement).toHaveText('from external template');
@ -371,8 +372,8 @@ class CompWithUrlTemplate {
.overrideDirective( .overrideDirective(
SomeDirective, {set: {selector: '[someDir]', host: {'[title]': 'someProp'}}}); SomeDirective, {set: {selector: '[someDir]', host: {'[title]': 'someProp'}}});
}); });
fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') && fixmeIvy('FW-681: not possible to retrieve host property bindings from TView')
it('should work', () => { .it('should work', () => {
const compFixture = TestBed.createComponent(SomeComponent); const compFixture = TestBed.createComponent(SomeComponent);
compFixture.detectChanges(); compFixture.detectChanges();
expect(compFixture.debugElement.children[0].properties['title']).toEqual('hello'); expect(compFixture.debugElement.children[0].properties['title']).toEqual('hello');
@ -387,8 +388,8 @@ class CompWithUrlTemplate {
.overridePipe(SomePipe, {set: {name: 'somePipe'}}) .overridePipe(SomePipe, {set: {name: 'somePipe'}})
.overridePipe(SomePipe, {add: {pure: false}}); .overridePipe(SomePipe, {add: {pure: false}});
}); });
fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
it('should work', () => { .it('should work', () => {
const compFixture = TestBed.createComponent(SomeComponent); const compFixture = TestBed.createComponent(SomeComponent);
compFixture.detectChanges(); compFixture.detectChanges();
expect(compFixture.nativeElement).toHaveText('transformed hello'); expect(compFixture.nativeElement).toHaveText('transformed hello');
@ -458,8 +459,8 @@ class CompWithUrlTemplate {
expect(TestBed.get('a')).toBe('mockA: depValue'); expect(TestBed.get('a')).toBe('mockA: depValue');
}); });
fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
it('should support SkipSelf', () => { .it('should support SkipSelf', () => {
@NgModule({ @NgModule({
providers: [ providers: [
{provide: 'a', useValue: 'aValue'}, {provide: 'a', useValue: 'aValue'},
@ -501,8 +502,8 @@ class CompWithUrlTemplate {
expect(someModule).toBeAnInstanceOf(SomeModule); expect(someModule).toBeAnInstanceOf(SomeModule);
}); });
obsoleteInIvy(`deprecated method, won't be reimplemented for Render3`) && obsoleteInIvy(`deprecated method, won't be reimplemented for Render3`)
it('should keep imported NgModules lazy with deprecatedOverrideProvider', () => { .it('should keep imported NgModules lazy with deprecatedOverrideProvider', () => {
let someModule: SomeModule|undefined; let someModule: SomeModule|undefined;
@NgModule() @NgModule()
@ -553,8 +554,8 @@ class CompWithUrlTemplate {
}); });
describe('in Components', () => { describe('in Components', () => {
fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
it('should support useValue', () => { .it('should support useValue', () => {
@Component({ @Component({
template: '', template: '',
providers: [ providers: [
@ -571,8 +572,8 @@ class CompWithUrlTemplate {
expect(ctx.debugElement.injector.get('a')).toBe('mockValue'); expect(ctx.debugElement.injector.get('a')).toBe('mockValue');
}); });
fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
it('should support useFactory', () => { .it('should support useFactory', () => {
@Component({ @Component({
template: '', template: '',
providers: [ providers: [
@ -591,8 +592,8 @@ class CompWithUrlTemplate {
expect(ctx.debugElement.injector.get('a')).toBe('mockA: depValue'); expect(ctx.debugElement.injector.get('a')).toBe('mockA: depValue');
}); });
fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
it('should support @Optional without matches', () => { .it('should support @Optional without matches', () => {
@Component({ @Component({
template: '', template: '',
providers: [ providers: [
@ -611,8 +612,8 @@ class CompWithUrlTemplate {
expect(ctx.debugElement.injector.get('a')).toBe('mockA: null'); expect(ctx.debugElement.injector.get('a')).toBe('mockA: null');
}); });
fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
it('should support Optional with matches', () => { .it('should support Optional with matches', () => {
@Component({ @Component({
template: '', template: '',
providers: [ providers: [
@ -632,8 +633,8 @@ class CompWithUrlTemplate {
expect(ctx.debugElement.injector.get('a')).toBe('mockA: depValue'); expect(ctx.debugElement.injector.get('a')).toBe('mockA: depValue');
}); });
fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
it('should support SkipSelf', () => { .it('should support SkipSelf', () => {
@Directive({ @Directive({
selector: '[myDir]', selector: '[myDir]',
providers: [ providers: [
@ -662,8 +663,8 @@ class CompWithUrlTemplate {
.toBe('mockA: parentDepValue'); .toBe('mockA: parentDepValue');
}); });
fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
it('should support multiple providers in a template', () => { .it('should support multiple providers in a template', () => {
@Directive({ @Directive({
selector: '[myDir1]', selector: '[myDir1]',
providers: [ providers: [
@ -708,9 +709,8 @@ class CompWithUrlTemplate {
constructor(@Inject('a') a: any, @Inject('b') b: any) {} constructor(@Inject('a') a: any, @Inject('b') b: any) {}
} }
fixmeIvy( fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
'FW-788: Support metadata override in TestBed (for AOT-compiled components)') && .it('should inject providers that were declared before it', () => {
it('should inject providers that were declared before it', () => {
TestBed.overrideProvider( TestBed.overrideProvider(
'b', {useFactory: (a: string) => `mockB: ${a}`, deps: ['a']}); 'b', {useFactory: (a: string) => `mockB: ${a}`, deps: ['a']});
const ctx = TestBed.configureTestingModule({declarations: [MyComp]}) const ctx = TestBed.configureTestingModule({declarations: [MyComp]})
@ -719,9 +719,8 @@ class CompWithUrlTemplate {
expect(ctx.debugElement.injector.get('b')).toBe('mockB: aValue'); expect(ctx.debugElement.injector.get('b')).toBe('mockB: aValue');
}); });
fixmeIvy( fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
'FW-788: Support metadata override in TestBed (for AOT-compiled components)') && .it('should inject providers that were declared after it', () => {
it('should inject providers that were declared after it', () => {
TestBed.overrideProvider( TestBed.overrideProvider(
'a', {useFactory: (b: string) => `mockA: ${b}`, deps: ['b']}); 'a', {useFactory: (b: string) => `mockA: ${b}`, deps: ['b']});
const ctx = TestBed.configureTestingModule({declarations: [MyComp]}) const ctx = TestBed.configureTestingModule({declarations: [MyComp]})
@ -741,8 +740,8 @@ class CompWithUrlTemplate {
}); });
describe('overrideTemplateUsingTestingModule', () => { describe('overrideTemplateUsingTestingModule', () => {
fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
it('should compile the template in the context of the testing module', () => { .it('should compile the template in the context of the testing module', () => {
@Component({selector: 'comp', template: 'a'}) @Component({selector: 'comp', template: 'a'})
class MyComponent { class MyComponent {
prop = 'some prop'; prop = 'some prop';
@ -770,8 +769,8 @@ class CompWithUrlTemplate {
expect(testDir !.test).toBe('some prop'); expect(testDir !.test).toBe('some prop');
}); });
fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
it('should throw if the TestBed is already created', () => { .it('should throw if the TestBed is already created', () => {
@Component({selector: 'comp', template: 'a'}) @Component({selector: 'comp', template: 'a'})
class MyComponent { class MyComponent {
} }
@ -783,8 +782,8 @@ class CompWithUrlTemplate {
/Cannot override template when the test module has already been instantiated/); /Cannot override template when the test module has already been instantiated/);
}); });
fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') && fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)')
it('should reset overrides when the testing module is resetted', () => { .it('should reset overrides when the testing module is resetted', () => {
@Component({selector: 'comp', template: 'a'}) @Component({selector: 'comp', template: 'a'})
class MyComponent { class MyComponent {
} }
@ -809,8 +808,8 @@ class CompWithUrlTemplate {
{providers: [{provide: ResourceLoader, useValue: {get: resourceLoaderGet}}]}); {providers: [{provide: ResourceLoader, useValue: {get: resourceLoaderGet}}]});
}); });
fixmeIvy('FW-553: TestBed is unaware of async compilation') && fixmeIvy('FW-553: TestBed is unaware of async compilation')
it('should use set up providers', fakeAsync(() => { .it('should use set up providers', fakeAsync(() => {
TestBed.compileComponents(); TestBed.compileComponents();
tick(); tick();
const compFixture = TestBed.createComponent(CompWithUrlTemplate); const compFixture = TestBed.createComponent(CompWithUrlTemplate);
@ -820,16 +819,16 @@ class CompWithUrlTemplate {
describe('useJit true', () => { describe('useJit true', () => {
beforeEach(() => TestBed.configureCompiler({useJit: true})); beforeEach(() => TestBed.configureCompiler({useJit: true}));
obsoleteInIvy('the Render3 compiler JiT mode is not configurable') && obsoleteInIvy('the Render3 compiler JiT mode is not configurable')
it('should set the value into CompilerConfig', .it('should set the value into CompilerConfig',
inject([CompilerConfig], (config: CompilerConfig) => { inject([CompilerConfig], (config: CompilerConfig) => {
expect(config.useJit).toBe(true); expect(config.useJit).toBe(true);
})); }));
}); });
describe('useJit false', () => { describe('useJit false', () => {
beforeEach(() => TestBed.configureCompiler({useJit: false})); beforeEach(() => TestBed.configureCompiler({useJit: false}));
obsoleteInIvy('the Render3 compiler JiT mode is not configurable') && obsoleteInIvy('the Render3 compiler JiT mode is not configurable')
it('should set the value into CompilerConfig', .it('should set the value into CompilerConfig',
inject([CompilerConfig], (config: CompilerConfig) => { inject([CompilerConfig], (config: CompilerConfig) => {
expect(config.useJit).toBe(false); expect(config.useJit).toBe(false);
})); }));
@ -921,14 +920,14 @@ class CompWithUrlTemplate {
{providers: [{provide: ResourceLoader, useValue: {get: resourceLoaderGet}}]}); {providers: [{provide: ResourceLoader, useValue: {get: resourceLoaderGet}}]});
}); });
fixmeIvy('FW-553: TestBed is unaware of async compilation') && fixmeIvy('FW-553: TestBed is unaware of async compilation')
it('should report an error for declared components with templateUrl which never call TestBed.compileComponents', .it('should report an error for declared components with templateUrl which never call TestBed.compileComponents',
() => { () => {
const itPromise = patchJasmineIt(); const itPromise = patchJasmineIt();
expect( expect(
() => () => it(
it('should fail', withModule( 'should fail', withModule(
{declarations: [CompWithUrlTemplate]}, {declarations: [CompWithUrlTemplate]},
() => TestBed.createComponent(CompWithUrlTemplate)))) () => TestBed.createComponent(CompWithUrlTemplate))))
.toThrowError( .toThrowError(
@ -941,8 +940,8 @@ class CompWithUrlTemplate {
}); });
fixmeIvy(`FW-721: Bindings to unknown properties are not reported as errors`) && fixmeIvy(`FW-721: Bindings to unknown properties are not reported as errors`)
it('should error on unknown bound properties on custom elements by default', () => { .it('should error on unknown bound properties on custom elements by default', () => {
@Component({template: '<some-element [someUnknownProp]="true"></some-element>'}) @Component({template: '<some-element [someUnknownProp]="true"></some-element>'})
class ComponentUsingInvalidProperty { class ComponentUsingInvalidProperty {
} }

View File

@ -579,8 +579,8 @@ class HiddenModule {
}); });
}))); })));
fixmeIvy('FW-672: SVG xlink:href is sanitized to :xlink:href (extra ":")') && fixmeIvy('FW-672: SVG xlink:href is sanitized to :xlink:href (extra ":")')
it('works with SVG elements', async(() => { .it('works with SVG elements', async(() => {
renderModule(SVGServerModule, {document: doc}).then(output => { renderModule(SVGServerModule, {document: doc}).then(output => {
expect(output).toBe( expect(output).toBe(
'<html><head></head><body><app ng-version="0.0.0-PLACEHOLDER">' + '<html><head></head><body><app ng-version="0.0.0-PLACEHOLDER">' +
@ -590,8 +590,8 @@ class HiddenModule {
})); }));
fixmeIvy( fixmeIvy(
`FW-643: Components with animations throw with "Failed to execute 'setAttribute' on 'Element'`) && `FW-643: Components with animations throw with "Failed to execute 'setAttribute' on 'Element'`)
it('works with animation', async(() => { .it('works with animation', async(() => {
renderModule(AnimationServerModule, {document: doc}).then(output => { renderModule(AnimationServerModule, {document: doc}).then(output => {
expect(output).toContain('Works!'); expect(output).toContain('Works!');
expect(output).toContain('ng-trigger-myAnimation'); expect(output).toContain('ng-trigger-myAnimation');

View File

@ -95,8 +95,8 @@ let lastCreatedRenderer: Renderer2;
expect(renderEl).toHaveText('Hello World!'); expect(renderEl).toHaveText('Hello World!');
}); });
fixmeIvy('#FW-750 - fixture.debugElement is null') && fixmeIvy('#FW-750 - fixture.debugElement is null')
it('should update any element property/attributes/class/style(s) independent of the compilation on the root element and other elements', .it('should update any element property/attributes/class/style(s) independent of the compilation on the root element and other elements',
() => { () => {
const fixture = const fixture =
TestBed.overrideTemplate(MyComp2, '<input [title]="y" style="position:absolute">') TestBed.overrideTemplate(MyComp2, '<input [title]="y" style="position:absolute">')
@ -131,8 +131,8 @@ let lastCreatedRenderer: Renderer2;
checkSetters(fixture.componentRef, fixture.debugElement.children[0].nativeElement); checkSetters(fixture.componentRef, fixture.debugElement.children[0].nativeElement);
}); });
fixmeIvy('#FW-664 ng-reflect-* is not supported') && fixmeIvy('#FW-664 ng-reflect-* is not supported')
it('should update any template comment property/attributes', () => { .it('should update any template comment property/attributes', () => {
const fixture = const fixture =
TestBed.overrideTemplate(MyComp2, '<ng-container *ngIf="ctxBoolProp"></ng-container>') TestBed.overrideTemplate(MyComp2, '<ng-container *ngIf="ctxBoolProp"></ng-container>')
.createComponent(MyComp2); .createComponent(MyComp2);
@ -161,7 +161,7 @@ let lastCreatedRenderer: Renderer2;
}); });
if (getDOM().supportsDOMEvents()) { if (getDOM().supportsDOMEvents()) {
fixmeIvy('#FW-750 - fixture.debugElement is null') && it('should listen to events', () => { fixmeIvy('#FW-750 - fixture.debugElement is null').it('should listen to events', () => {
const fixture = TestBed.overrideTemplate(MyComp2, '<input (change)="ctxNumProp = 1">') const fixture = TestBed.overrideTemplate(MyComp2, '<input (change)="ctxNumProp = 1">')
.createComponent(MyComp2); .createComponent(MyComp2);

View File

@ -8,6 +8,14 @@
import {bazelDefineCompileValue} from './bazel_define_compile_value'; import {bazelDefineCompileValue} from './bazel_define_compile_value';
/**
* Set this constant to `true` to run all tests and report which of the tests marked with `fixmeIvy`
* are actually already passing.
*
* This is useful for locating already passing tests. The already passing tests should have their
* `fixmeIvy` removed.
*/
const FIND_PASSING_TESTS = false;
/** /**
* A function to conditionally include a test or a block of tests only when tests run against Ivy. * A function to conditionally include a test or a block of tests only when tests run against Ivy.
@ -33,17 +41,21 @@ export const ivyEnabled = 'aot' === (bazelDefineCompileValue as string);
* when running against Ivy. * when running against Ivy.
* *
* ``` * ```
* fixmeIvy('some reason') && describe(...); * fixmeIvy('some reason').describe(...);
* ``` * ```
* *
* or * or
* *
* ``` * ```
* fixmeIvy('some reason') && it(...); * fixmeIvy('some reason').it(...);
* ``` * ```
*/ */
export function fixmeIvy(reason: string): boolean { export function fixmeIvy(reason: string): JasmineMethods {
return !ivyEnabled; if (FIND_PASSING_TESTS) {
return ivyEnabled ? PASSTHROUGH : IGNORE;
} else {
return ivyEnabled ? IGNORE : PASSTHROUGH;
}
} }
@ -54,17 +66,17 @@ export function fixmeIvy(reason: string): boolean {
* Any tests disabled using this switch should not be user-facing breaking changes. * Any tests disabled using this switch should not be user-facing breaking changes.
* *
* ``` * ```
* obsoleteInIvy('some reason') && describe(...); * obsoleteInIvy('some reason').describe(...);
* ``` * ```
* *
* or * or
* *
* ``` * ```
* obsoleteInIvy('some reason') && it(...); * obsoleteInIvy('some reason').it(...);
* ``` * ```
*/ */
export function obsoleteInIvy(reason: string): boolean { export function obsoleteInIvy(reason: string): JasmineMethods {
return !ivyEnabled; return ivyEnabled ? IGNORE : PASSTHROUGH;
} }
/** /**
@ -75,15 +87,87 @@ export function obsoleteInIvy(reason: string): boolean {
* documented as a breaking change. * documented as a breaking change.
* *
* ``` * ```
* modifiedInIvy('some reason') && describe(...); * modifiedInIvy('some reason').describe(...);
* ``` * ```
* *
* or * or
* *
* ``` * ```
* modifiedInIvy('some reason') && it(...); * modifiedInIvy('some reason').it(...);
* ``` * ```
*/ */
export function modifiedInIvy(reason: string): boolean { export function modifiedInIvy(reason: string): JasmineMethods {
return !ivyEnabled; return ivyEnabled ? IGNORE : PASSTHROUGH;
}
export interface JasmineMethods {
it: typeof it;
fit: typeof fit;
describe: typeof describe;
fdescribe: typeof fdescribe;
fixmeIvy: typeof fixmeIvy;
isEnabled: boolean;
}
const PASSTHROUGH: JasmineMethods = {
it: maybeAppendFindPassingTestsMarker(it),
fit: maybeAppendFindPassingTestsMarker(fit),
describe: maybeAppendFindPassingTestsMarker(describe),
fdescribe: maybeAppendFindPassingTestsMarker(fdescribe),
fixmeIvy: maybeAppendFindPassingTestsMarker(fixmeIvy),
isEnabled: true,
};
const FIND_PASSING_TESTS_MARKER = '__FIND_PASSING_TESTS_MARKER__';
function maybeAppendFindPassingTestsMarker<T extends Function>(fn: T): T {
return FIND_PASSING_TESTS ? function(...args: any[]) {
if (typeof args[0] == 'string') {
args[0] += FIND_PASSING_TESTS_MARKER;
}
return fn.apply(this, args);
} : fn as any;
}
function noop() {}
const IGNORE: JasmineMethods = {
it: noop,
fit: noop,
describe: noop,
fdescribe: noop,
fixmeIvy: (reason) => IGNORE,
isEnabled: false,
};
if (FIND_PASSING_TESTS) {
const env = jasmine.getEnv();
const passingTests: jasmine.CustomReporterResult[] = [];
const stillFailing: jasmine.CustomReporterResult[] = [];
let specCount = 0;
env.clearReporters();
env.addReporter({
specDone: function(result: jasmine.CustomReporterResult) {
specCount++;
if (result.fullName.indexOf(FIND_PASSING_TESTS_MARKER) != -1) {
(result.status == 'passed' ? passingTests : stillFailing).push(result);
}
},
jasmineDone: function(details: jasmine.RunDetails) {
if (passingTests.length) {
passingTests.forEach((result) => {
// tslint:disable-next-line:no-console
console.log('ALREADY PASSING', result.fullName.replace(FIND_PASSING_TESTS_MARKER, ''));
});
// tslint:disable-next-line:no-console
console.log(
`${specCount} specs,`, //
`${passingTests.length} passing specs,`, //
`${stillFailing.length} still failing specs`);
} else {
// tslint:disable-next-line:no-console
console.log('NO PASSING TESTS FOUND.');
}
}
});
} }

View File

@ -467,8 +467,8 @@ describe('Integration', () => {
expect(location.path()).toEqual('/child/simple'); expect(location.path()).toEqual('/child/simple');
}))); })));
fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick') && fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick')
it('should work when an outlet is added/removed', fakeAsync(() => { .it('should work when an outlet is added/removed', fakeAsync(() => {
@Component({ @Component({
selector: 'someRoot', selector: 'someRoot',
template: `[<div *ngIf="cond"><router-outlet></router-outlet></div>]` template: `[<div *ngIf="cond"><router-outlet></router-outlet></div>]`
@ -2595,8 +2595,8 @@ describe('Integration', () => {
expect(canceledStatus).toEqual(false); expect(canceledStatus).toEqual(false);
}))); })));
fixmeIvy('FW-766: One router test is wrong') && fixmeIvy('FW-766: One router test is wrong')
it('works with componentless routes', .it('works with componentless routes',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -3524,8 +3524,8 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('lazy-loaded-parent [lazy-loaded-child]'); expect(fixture.nativeElement).toHaveText('lazy-loaded-parent [lazy-loaded-child]');
}))); })));
fixmeIvy('FW-646: Directive providers don\'t support primitive types as DI tokens') && fixmeIvy('FW-646: Directive providers don\'t support primitive types as DI tokens')
it('should have 2 injector trees: module and element', .it('should have 2 injector trees: module and element',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
(router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => {
@ -3653,8 +3653,8 @@ describe('Integration', () => {
// https://github.com/angular/angular/issues/13870 // https://github.com/angular/angular/issues/13870
fixmeIvy( fixmeIvy(
'FW-767: Lazy loaded modules are not used when resolving dependencies in one of their components') && 'FW-767: Lazy loaded modules are not used when resolving dependencies in one of their components')
it('should create a single instance of guards for lazy-loaded modules', .it('should create a single instance of guards for lazy-loaded modules',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
(router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => {
@ -3954,8 +3954,8 @@ describe('Integration', () => {
}); });
fixmeIvy( fixmeIvy(
'FW-767: Lazy loaded modules are not used when resolving dependencies in one of their components') && 'FW-767: Lazy loaded modules are not used when resolving dependencies in one of their components')
it('should use the injector of the lazily-loaded configuration', .it('should use the injector of the lazily-loaded configuration',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
(router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => {
@ -4439,8 +4439,8 @@ describe('Integration', () => {
expect(simpleCmp1).not.toBe(simpleCmp2); expect(simpleCmp1).not.toBe(simpleCmp2);
}))); })));
fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick') && fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick')
it('should not mount the component of the previously reused route when the outlet was not instantiated at the time of route activation', .it('should not mount the component of the previously reused route when the outlet was not instantiated at the time of route activation',
fakeAsync(() => { fakeAsync(() => {
@Component({ @Component({
selector: 'root-cmp', selector: 'root-cmp',

View File

@ -62,8 +62,8 @@ describe('RouterPreloader', () => {
fixmeIvy( fixmeIvy(
'FW-765: NgModuleRef hierarchy is differently constructed when the router preloads modules') && 'FW-765: NgModuleRef hierarchy is differently constructed when the router preloads modules')
it('should work', .it('should work',
fakeAsync(inject( fakeAsync(inject(
[NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef], [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef],
(loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router, (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router,
@ -131,8 +131,8 @@ describe('RouterPreloader', () => {
}); });
fixmeIvy( fixmeIvy(
'FW-765: NgModuleRef hierarchy is differently constructed when the router preloads modules') && 'FW-765: NgModuleRef hierarchy is differently constructed when the router preloads modules')
it('should work', .it('should work',
fakeAsync(inject( fakeAsync(inject(
[NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef, Compiler], [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef, Compiler],
(loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router, (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router,

View File

@ -30,8 +30,8 @@ withEachNg1Version(() => {
describe('(basic use)', () => { describe('(basic use)', () => {
it('should have AngularJS loaded', () => expect(angular.version.major).toBe(1)); it('should have AngularJS loaded', () => expect(angular.version.major).toBe(1));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should instantiate ng2 in ng1 template and project content', async(() => { .it('should instantiate ng2 in ng1 template and project content', async(() => {
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@Component({ @Component({
@ -56,8 +56,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should instantiate ng1 in ng2 template and project content', async(() => { .it('should instantiate ng1 in ng2 template and project content', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@ -149,9 +149,8 @@ withEachNg1Version(() => {
adapter = new UpgradeAdapter(Ng2Module); adapter = new UpgradeAdapter(Ng2Module);
}); });
fixmeIvy( fixmeIvy('FW-682: JIT compilation occurs at component definition time rather than bootstrap')
'FW-682: JIT compilation occurs at component definition time rather than bootstrap') && .it('should throw an uncaught error', fakeAsync(() => {
it('should throw an uncaught error', fakeAsync(() => {
const resolveSpy = jasmine.createSpy('resolveSpy'); const resolveSpy = jasmine.createSpy('resolveSpy');
spyOn(console, 'error'); spyOn(console, 'error');
@ -162,9 +161,8 @@ withEachNg1Version(() => {
expect(resolveSpy).not.toHaveBeenCalled(); expect(resolveSpy).not.toHaveBeenCalled();
})); }));
fixmeIvy( fixmeIvy('FW-682: JIT compilation occurs at component definition time rather than bootstrap')
'FW-682: JIT compilation occurs at component definition time rather than bootstrap') && .it('should output an error message to the console and re-throw', fakeAsync(() => {
it('should output an error message to the console and re-throw', fakeAsync(() => {
const consoleErrorSpy: jasmine.Spy = spyOn(console, 'error'); const consoleErrorSpy: jasmine.Spy = spyOn(console, 'error');
expect(() => { expect(() => {
adapter.bootstrap(html('<ng2></ng2>'), ['ng1']); adapter.bootstrap(html('<ng2></ng2>'), ['ng1']);
@ -178,8 +176,8 @@ withEachNg1Version(() => {
}); });
describe('scope/component change-detection', () => { describe('scope/component change-detection', () => {
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should interleave scope and component expressions', async(() => { .it('should interleave scope and component expressions', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
const log: string[] = []; const log: string[] = [];
@ -227,8 +225,8 @@ withEachNg1Version(() => {
fixmeIvy( fixmeIvy(
'FW-712: Rendering is being run on next "animation frame" rather than "Zone.microTaskEmpty" trigger') && 'FW-712: Rendering is being run on next "animation frame" rather than "Zone.microTaskEmpty" trigger')
it('should propagate changes to a downgraded component inside the ngZone', async(() => { .it('should propagate changes to a downgraded component inside the ngZone', async(() => {
let appComponent: AppComponent; let appComponent: AppComponent;
let upgradeRef: UpgradeAdapterRef; let upgradeRef: UpgradeAdapterRef;
@ -336,8 +334,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly')
it('should bind properties, events', async(() => { .it('should bind properties, events', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []).value( const ng1Module = angular.module('ng1', []).value(
$EXCEPTION_HANDLER, (err: any) => { throw err; }); $EXCEPTION_HANDLER, (err: any) => { throw err; });
@ -460,8 +458,8 @@ withEachNg1Version(() => {
})); }));
fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly')
it('should support two-way binding and event listener', async(() => { .it('should support two-way binding and event listener', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const listenerSpy = jasmine.createSpy('$rootScope.listener'); const listenerSpy = jasmine.createSpy('$rootScope.listener');
const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => { const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => {
@ -510,8 +508,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly')
it('should initialize inputs in time for `ngOnChanges`', async(() => { .it('should initialize inputs in time for `ngOnChanges`', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
@Component({ @Component({
@ -661,8 +659,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') && fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed')
it('should properly run cleanup with multiple levels of nesting', async(() => { .it('should properly run cleanup with multiple levels of nesting', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let destroyed = false; let destroyed = false;
@ -741,8 +739,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should support multi-slot projection', async(() => { .it('should support multi-slot projection', async(() => {
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@Component({ @Component({
@ -771,8 +769,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should correctly project structural directives', async(() => { .it('should correctly project structural directives', async(() => {
@Component( @Component(
{selector: 'ng2', template: 'ng2-{{ itemId }}(<ng-content></ng-content>)'}) {selector: 'ng2', template: 'ng2-{{ itemId }}(<ng-content></ng-content>)'})
class Ng2Component { class Ng2Component {
@ -835,8 +833,8 @@ withEachNg1Version(() => {
}); });
describe('upgrade ng1 component', () => { describe('upgrade ng1 component', () => {
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should support `@` bindings', fakeAsync(() => { .it('should support `@` bindings', fakeAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng2ComponentInstance: Ng2Component; let ng2ComponentInstance: Ng2Component;
@ -862,7 +860,8 @@ withEachNg1Version(() => {
} }
// Define `ng1Module` // Define `ng1Module`
const ng1Module = angular.module('ng1Module', []) const ng1Module =
angular.module('ng1Module', [])
.component('ng1', ng1Component) .component('ng1', ng1Component)
.directive('ng2', adapter.downgradeNg2Component(Ng2Component)); .directive('ng2', adapter.downgradeNg2Component(Ng2Component));
@ -902,8 +901,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should support `<` bindings', fakeAsync(() => { .it('should support `<` bindings', fakeAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng2ComponentInstance: Ng2Component; let ng2ComponentInstance: Ng2Component;
@ -929,7 +928,8 @@ withEachNg1Version(() => {
} }
// Define `ng1Module` // Define `ng1Module`
const ng1Module = angular.module('ng1Module', []) const ng1Module =
angular.module('ng1Module', [])
.component('ng1', ng1Component) .component('ng1', ng1Component)
.directive('ng2', adapter.downgradeNg2Component(Ng2Component)); .directive('ng2', adapter.downgradeNg2Component(Ng2Component));
@ -969,8 +969,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should support `=` bindings', fakeAsync(() => { .it('should support `=` bindings', fakeAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng2ComponentInstance: Ng2Component; let ng2ComponentInstance: Ng2Component;
@ -996,7 +996,8 @@ withEachNg1Version(() => {
} }
// Define `ng1Module` // Define `ng1Module`
const ng1Module = angular.module('ng1Module', []) const ng1Module =
angular.module('ng1Module', [])
.component('ng1', ng1Component) .component('ng1', ng1Component)
.directive('ng2', adapter.downgradeNg2Component(Ng2Component)); .directive('ng2', adapter.downgradeNg2Component(Ng2Component));
@ -1036,8 +1037,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should support `&` bindings', fakeAsync(() => { .it('should support `&` bindings', fakeAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
// Define `ng1Component` // Define `ng1Component`
@ -1060,7 +1061,8 @@ withEachNg1Version(() => {
} }
// Define `ng1Module` // Define `ng1Module`
const ng1Module = angular.module('ng1Module', []) const ng1Module =
angular.module('ng1Module', [])
.component('ng1', ng1Component) .component('ng1', ng1Component)
.directive('ng2', adapter.downgradeNg2Component(Ng2Component)); .directive('ng2', adapter.downgradeNg2Component(Ng2Component));
@ -1091,16 +1093,21 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should bind properties, events', async(() => { .it('should bind properties, events', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
const ng1 = () => { const ng1 = () => {
return { return {
template: 'Hello {{fullName}}; A: {{modelA}}; B: {{modelB}}; C: {{modelC}}; | ', template: 'Hello {{fullName}}; A: {{modelA}}; B: {{modelB}}; C: {{modelC}}; | ',
scope: scope: {
{fullName: '@', modelA: '=dataA', modelB: '=dataB', modelC: '=', event: '&'}, fullName: '@',
modelA: '=dataA',
modelB: '=dataB',
modelC: '=',
event: '&'
},
link: function(scope: any) { link: function(scope: any) {
scope.$watch('modelB', (v: string) => { scope.$watch('modelB', (v: string) => {
if (v == 'Savkin') { if (v == 'Savkin') {
@ -1151,8 +1158,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should bind optional properties', async(() => { .it('should bind optional properties', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@ -1196,8 +1203,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should bind properties, events in controller when bindToController is not used', .it('should bind properties, events in controller when bindToController is not used',
async(() => { async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@ -1244,8 +1251,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should bind properties, events in link function', async(() => { .it('should bind properties, events in link function', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@ -1289,8 +1296,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should support templateUrl fetched from $httpBackend', async(() => { .it('should support templateUrl fetched from $httpBackend', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
ng1Module.value( ng1Module.value(
@ -1319,8 +1326,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should support templateUrl as a function', async(() => { .it('should support templateUrl as a function', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
ng1Module.value( ng1Module.value(
@ -1401,8 +1408,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should support templateUrl fetched from $templateCache', async(() => { .it('should support templateUrl fetched from $templateCache', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
ng1Module.run(($templateCache: any) => $templateCache.put('url.html', 'WORKS')); ng1Module.run(($templateCache: any) => $templateCache.put('url.html', 'WORKS'));
@ -1429,8 +1436,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should support controller with controllerAs', async(() => { .it('should support controller with controllerAs', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@ -1477,8 +1484,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should support bindToController', async(() => { .it('should support bindToController', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@ -1512,8 +1519,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should support bindToController with bindings', async(() => { .it('should support bindToController with bindings', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@ -1547,8 +1554,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should support single require in linking fn', async(() => { .it('should support single require in linking fn', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@ -1589,8 +1596,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-724: upgraded ng1 components are not being rendered') && fixmeIvy('FW-724: upgraded ng1 components are not being rendered')
it('should support array require in linking fn', async(() => { .it('should support array require in linking fn', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@ -1635,8 +1642,8 @@ withEachNg1Version(() => {
})); }));
describe('with lifecycle hooks', () => { describe('with lifecycle hooks', () => {
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should call `$onInit()` on controller', async(() => { 'should call `$onInit()` on controller', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const $onInitSpyA = jasmine.createSpy('$onInitA'); const $onInitSpyA = jasmine.createSpy('$onInitA');
const $onInitSpyB = jasmine.createSpy('$onInitB'); const $onInitSpyB = jasmine.createSpy('$onInitB');
@ -1727,8 +1734,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should call `$doCheck()` on controller', async(() => { 'should call `$doCheck()` on controller', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const $doCheckSpyA = jasmine.createSpy('$doCheckA'); const $doCheckSpyA = jasmine.createSpy('$doCheckA');
const $doCheckSpyB = jasmine.createSpy('$doCheckB'); const $doCheckSpyB = jasmine.createSpy('$doCheckB');
@ -1837,8 +1844,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should call `$postLink()` on controller', async(() => { 'should call `$postLink()` on controller', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const $postLinkSpyA = jasmine.createSpy('$postLinkA'); const $postLinkSpyA = jasmine.createSpy('$postLinkA');
const $postLinkSpyB = jasmine.createSpy('$postLinkB'); const $postLinkSpyB = jasmine.createSpy('$postLinkB');
@ -1929,8 +1936,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should call `$onChanges()` on binding destination', fakeAsync(() => { 'should call `$onChanges()` on binding destination', fakeAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const $onChangesControllerSpyA = jasmine.createSpy('$onChangesControllerA'); const $onChangesControllerSpyA = jasmine.createSpy('$onChangesControllerA');
const $onChangesControllerSpyB = jasmine.createSpy('$onChangesControllerB'); const $onChangesControllerSpyB = jasmine.createSpy('$onChangesControllerB');
@ -1955,15 +1962,15 @@ withEachNg1Version(() => {
this.$onChanges = $onChangesControllerSpyA; this.$onChanges = $onChangesControllerSpyA;
} }
})) }))
.directive('ng1B', () => ({ .directive(
'ng1B',
() => ({
template: '', template: '',
scope: {valB: '<'}, scope: {valB: '<'},
bindToController: false, bindToController: false,
controllerAs: '$ctrl', controllerAs: '$ctrl',
controller: class { controller: class {
$onChanges(changes: SimpleChanges) { $onChanges(changes: SimpleChanges) { $onChangesControllerSpyB(changes); }
$onChangesControllerSpyB(changes);
}
} }
})) }))
.directive('ng2', adapter.downgradeNg2Component(Ng2Component)) .directive('ng2', adapter.downgradeNg2Component(Ng2Component))
@ -2024,8 +2031,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should call `$onDestroy()` on controller', fakeAsync(() => { 'should call `$onDestroy()` on controller', fakeAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const $onDestroySpyA = jasmine.createSpy('$onDestroyA'); const $onDestroySpyA = jasmine.createSpy('$onDestroyA');
const $onDestroySpyB = jasmine.createSpy('$onDestroyB'); const $onDestroySpyB = jasmine.createSpy('$onDestroyB');
@ -2057,8 +2064,7 @@ withEachNg1Version(() => {
controllerAs: '$ctrl', controllerAs: '$ctrl',
controller: class {$onDestroy() { $onDestroySpyA(); }} controller: class {$onDestroy() { $onDestroySpyA(); }}
})) }))
.directive( .directive('ng1B', () => ({
'ng1B', () => ({
template: '', template: '',
scope: {}, scope: {},
bindToController: false, bindToController: false,
@ -2116,8 +2122,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should not call `$onDestroy()` on scope', fakeAsync(() => { 'should not call `$onDestroy()` on scope', fakeAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const $onDestroySpy = jasmine.createSpy('$onDestroy'); const $onDestroySpy = jasmine.createSpy('$onDestroy');
let ng2ComponentInstance: Ng2Component; let ng2ComponentInstance: Ng2Component;
@ -2147,8 +2153,7 @@ withEachNg1Version(() => {
bindToController: true, bindToController: true,
controllerAs: '$ctrl', controllerAs: '$ctrl',
controller: function($scope: angular.IScope) { controller: function($scope: angular.IScope) {
Object.getPrototypeOf($scope).$onDestroy = Object.getPrototypeOf($scope).$onDestroy = $onDestroySpy;
$onDestroySpy;
} }
})) }))
.directive('ng1B', () => ({ .directive('ng1B', () => ({
@ -2200,8 +2205,8 @@ withEachNg1Version(() => {
}); });
describe('destroying the upgraded component', () => { describe('destroying the upgraded component', () => {
fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') && fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed')
it('should destroy `componentScope`', fakeAsync(() => { .it('should destroy `componentScope`', fakeAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const scopeDestroyListener = jasmine.createSpy('scopeDestroyListener'); const scopeDestroyListener = jasmine.createSpy('scopeDestroyListener');
let ng2ComponentInstance: Ng2Component; let ng2ComponentInstance: Ng2Component;
@ -2247,8 +2252,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') && fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed')
it('should emit `$destroy` on `$element` and descendants', fakeAsync(() => { .it('should emit `$destroy` on `$element` and descendants', fakeAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const elementDestroyListener = jasmine.createSpy('elementDestroyListener'); const elementDestroyListener = jasmine.createSpy('elementDestroyListener');
const descendantDestroyListener = jasmine.createSpy('descendantDestroyListener'); const descendantDestroyListener = jasmine.createSpy('descendantDestroyListener');
@ -2303,8 +2308,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') && fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed')
it('should clear data on `$element` and descendants', fakeAsync(() => { .it('should clear data on `$element` and descendants', fakeAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng1ComponentElement: angular.IAugmentedJQuery; let ng1ComponentElement: angular.IAugmentedJQuery;
let ng2ComponentAInstance: Ng2ComponentA; let ng2ComponentAInstance: Ng2ComponentA;
@ -2341,7 +2346,8 @@ withEachNg1Version(() => {
// Define `Ng2Module` // Define `Ng2Module`
@NgModule({ @NgModule({
declarations: [adapter.upgradeNg1Component('ng1'), Ng2ComponentA, Ng2ComponentB], declarations:
[adapter.upgradeNg1Component('ng1'), Ng2ComponentA, Ng2ComponentB],
entryComponents: [Ng2ComponentA], entryComponents: [Ng2ComponentA],
imports: [BrowserModule] imports: [BrowserModule]
}) })
@ -2368,8 +2374,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') && fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed')
it('should clear dom listeners on `$element` and descendants`', fakeAsync(() => { .it('should clear dom listeners on `$element` and descendants`', fakeAsync(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const elementClickListener = jasmine.createSpy('elementClickListener'); const elementClickListener = jasmine.createSpy('elementClickListener');
const descendantClickListener = jasmine.createSpy('descendantClickListener'); const descendantClickListener = jasmine.createSpy('descendantClickListener');
@ -2408,7 +2414,8 @@ withEachNg1Version(() => {
// Define `Ng2Module` // Define `Ng2Module`
@NgModule({ @NgModule({
declarations: [adapter.upgradeNg1Component('ng1'), Ng2ComponentA, Ng2ComponentB], declarations:
[adapter.upgradeNg1Component('ng1'), Ng2ComponentA, Ng2ComponentB],
entryComponents: [Ng2ComponentA], entryComponents: [Ng2ComponentA],
imports: [BrowserModule] imports: [BrowserModule]
}) })
@ -2439,8 +2446,8 @@ withEachNg1Version(() => {
}); });
describe('linking', () => { describe('linking', () => {
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should run the pre-linking after instantiating the controller', async(() => { 'should run the pre-linking after instantiating the controller', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const log: string[] = []; const log: string[] = [];
@ -2457,8 +2464,7 @@ withEachNg1Version(() => {
} }
// Define `ng1Module` // Define `ng1Module`
const ng1Module = const ng1Module = angular.module('ng1', [])
angular.module('ng1', [])
.directive('ng1', () => ng1Directive) .directive('ng1', () => ng1Directive)
.directive('ng2', adapter.downgradeNg2Component(Ng2Component)); .directive('ng2', adapter.downgradeNg2Component(Ng2Component));
@ -2478,8 +2484,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should run the pre-linking function before linking', async(() => { 'should run the pre-linking function before linking', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const log: string[] = []; const log: string[] = [];
@ -2497,8 +2503,7 @@ withEachNg1Version(() => {
} }
// Define `ng1Module` // Define `ng1Module`
const ng1Module = const ng1Module = angular.module('ng1', [])
angular.module('ng1', [])
.directive('ng1A', () => ng1DirectiveA) .directive('ng1A', () => ng1DirectiveA)
.directive('ng1B', () => ng1DirectiveB) .directive('ng1B', () => ng1DirectiveB)
.directive('ng2', adapter.downgradeNg2Component(Ng2Component)); .directive('ng2', adapter.downgradeNg2Component(Ng2Component));
@ -2520,8 +2525,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should run the post-linking function after linking (link: object)', async(() => { 'should run the post-linking function after linking (link: object)', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const log: string[] = []; const log: string[] = [];
@ -2539,8 +2544,7 @@ withEachNg1Version(() => {
} }
// Define `ng1Module` // Define `ng1Module`
const ng1Module = const ng1Module = angular.module('ng1', [])
angular.module('ng1', [])
.directive('ng1A', () => ng1DirectiveA) .directive('ng1A', () => ng1DirectiveA)
.directive('ng1B', () => ng1DirectiveB) .directive('ng1B', () => ng1DirectiveB)
.directive('ng2', adapter.downgradeNg2Component(Ng2Component)); .directive('ng2', adapter.downgradeNg2Component(Ng2Component));
@ -2562,8 +2566,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should run the post-linking function after linking (link: function)', async(() => { 'should run the post-linking function after linking (link: function)', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const log: string[] = []; const log: string[] = [];
@ -2581,8 +2585,7 @@ withEachNg1Version(() => {
} }
// Define `ng1Module` // Define `ng1Module`
const ng1Module = const ng1Module = angular.module('ng1', [])
angular.module('ng1', [])
.directive('ng1A', () => ng1DirectiveA) .directive('ng1A', () => ng1DirectiveA)
.directive('ng1B', () => ng1DirectiveB) .directive('ng1B', () => ng1DirectiveB)
.directive('ng2', adapter.downgradeNg2Component(Ng2Component)); .directive('ng2', adapter.downgradeNg2Component(Ng2Component));
@ -2604,8 +2607,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should run the post-linking function before `$postLink`', async(() => { 'should run the post-linking function before `$postLink`', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const log: string[] = []; const log: string[] = [];
@ -2622,8 +2625,7 @@ withEachNg1Version(() => {
} }
// Define `ng1Module` // Define `ng1Module`
const ng1Module = const ng1Module = angular.module('ng1', [])
angular.module('ng1', [])
.directive('ng1', () => ng1Directive) .directive('ng1', () => ng1Directive)
.directive('ng2', adapter.downgradeNg2Component(Ng2Component)); .directive('ng2', adapter.downgradeNg2Component(Ng2Component));
@ -2645,8 +2647,8 @@ withEachNg1Version(() => {
}); });
describe('transclusion', () => { describe('transclusion', () => {
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should support single-slot transclusion', async(() => { .it('should support single-slot transclusion', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng2ComponentAInstance: Ng2ComponentA; let ng2ComponentAInstance: Ng2ComponentA;
let ng2ComponentBInstance: Ng2ComponentB; let ng2ComponentBInstance: Ng2ComponentB;
@ -2708,8 +2710,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should support single-slot transclusion with fallback content', async(() => { .it('should support single-slot transclusion with fallback content', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng1ControllerInstances: any[] = []; let ng1ControllerInstances: any[] = [];
let ng2ComponentInstance: Ng2Component; let ng2ComponentInstance: Ng2Component;
@ -2771,8 +2773,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should support multi-slot transclusion', async(() => { .it('should support multi-slot transclusion', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng2ComponentInstance: Ng2Component; let ng2ComponentInstance: Ng2Component;
@ -2833,18 +2835,20 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should support default slot (with fallback content)', async(() => { .it('should support default slot (with fallback content)', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng1ControllerInstances: any[] = []; let ng1ControllerInstances: any[] = [];
let ng2ComponentInstance: Ng2Component; let ng2ComponentInstance: Ng2Component;
// Define `ng1Component` // Define `ng1Component`
const ng1Component: angular.IComponent = { const ng1Component: angular.IComponent = {
template: 'ng1(default(<div ng-transclude="">fallback-{{ $ctrl.value }}</div>))', template:
'ng1(default(<div ng-transclude="">fallback-{{ $ctrl.value }}</div>))',
transclude: {slotX: 'contentX', slotY: 'contentY'}, transclude: {slotX: 'contentX', slotY: 'contentY'},
controller: controller: class {
class {value = 'ng1'; constructor() { ng1ControllerInstances.push(this); }} value = 'ng1'; constructor() { ng1ControllerInstances.push(this); }
}
}; };
// Define `Ng2Component` // Define `Ng2Component`
@ -2912,8 +2916,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should support optional transclusion slots (with fallback content)', async(() => { .it('should support optional transclusion slots (with fallback content)', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng1ControllerInstances: any[] = []; let ng1ControllerInstances: any[] = [];
let ng2ComponentInstance: Ng2Component; let ng2ComponentInstance: Ng2Component;
@ -2981,8 +2985,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should throw if a non-optional slot is not filled', async(() => { .it('should throw if a non-optional slot is not filled', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let errorMessage: string; let errorMessage: string;
@ -3021,8 +3025,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should support structural directives in transcluded content', async(() => { .it('should support structural directives in transcluded content', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
let ng2ComponentInstance: Ng2Component; let ng2ComponentInstance: Ng2Component;
@ -3092,15 +3096,14 @@ withEachNg1Version(() => {
})); }));
}); });
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should bind input properties (<) of components', async(() => { 'should bind input properties (<) of components', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
const ng1 = { const ng1 = {
bindings: {personProfile: '<'}, bindings: {personProfile: '<'},
template: template: 'Hello {{$ctrl.personProfile.firstName}} {{$ctrl.personProfile.lastName}}',
'Hello {{$ctrl.personProfile.firstName}} {{$ctrl.personProfile.lastName}}',
controller: class {} controller: class {}
}; };
ng1Module.component('ng1', ng1); ng1Module.component('ng1', ng1);
@ -3126,8 +3129,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('unknown') && fixmeIvy('unknown').it(
it('should support ng2 > ng1 > ng2', async(() => { 'should support ng2 > ng1 > ng2', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@ -3199,8 +3202,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should respect hierarchical dependency injection for ng2', async(() => { .it('should respect hierarchical dependency injection for ng2', async(() => {
const ng1Module = angular.module('ng1', []); const ng1Module = angular.module('ng1', []);
@Component( @Component(
@ -3302,8 +3305,8 @@ withEachNg1Version(() => {
}); });
describe('examples', () => { describe('examples', () => {
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should verify UpgradeAdapter example', async(() => { .it('should verify UpgradeAdapter example', async(() => {
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module)); const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
const module = angular.module('myExample', []); const module = angular.module('myExample', []);

View File

@ -77,8 +77,8 @@ withEachNg1Version(() => {
})); }));
fixmeIvy( fixmeIvy(
'FW-712: Rendering is being run on next "animation frame" rather than "Zone.microTaskEmpty" trigger') && 'FW-712: Rendering is being run on next "animation frame" rather than "Zone.microTaskEmpty" trigger')
it('should propagate changes to a downgraded component inside the ngZone', async(() => { .it('should propagate changes to a downgraded component inside the ngZone', async(() => {
const element = html('<my-app></my-app>'); const element = html('<my-app></my-app>');
let appComponent: AppComponent; let appComponent: AppComponent;

View File

@ -22,8 +22,8 @@ withEachNg1Version(() => {
beforeEach(() => destroyPlatform()); beforeEach(() => destroyPlatform());
afterEach(() => destroyPlatform()); afterEach(() => destroyPlatform());
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should instantiate ng2 in ng1 template and project content', async(() => { .it('should instantiate ng2 in ng1 template and project content', async(() => {
// the ng2 component that will be used in ng1 (downgraded) // the ng2 component that will be used in ng1 (downgraded)
@Component({selector: 'ng2', template: `{{ prop }}(<ng-content></ng-content>)`}) @Component({selector: 'ng2', template: `{{ prop }}(<ng-content></ng-content>)`})
@ -60,8 +60,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should correctly project structural directives', async(() => { .it('should correctly project structural directives', async(() => {
@Component({selector: 'ng2', template: 'ng2-{{ itemId }}(<ng-content></ng-content>)'}) @Component({selector: 'ng2', template: 'ng2-{{ itemId }}(<ng-content></ng-content>)'})
class Ng2Component { class Ng2Component {
// TODO(issue/24571): remove '!'. // TODO(issue/24571): remove '!'.
@ -145,8 +145,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should support multi-slot projection', async(() => { .it('should support multi-slot projection', async(() => {
@Component({ @Component({
selector: 'ng2', selector: 'ng2',

View File

@ -22,8 +22,8 @@ withEachNg1Version(() => {
beforeEach(() => destroyPlatform()); beforeEach(() => destroyPlatform());
afterEach(() => destroyPlatform()); afterEach(() => destroyPlatform());
fixmeIvy('FW-716: Error: [$rootScope:inprog] $digest already in progress') && fixmeIvy('FW-716: Error: [$rootScope:inprog] $digest already in progress')
it('should bind properties, events', async(() => { .it('should bind properties, events', async(() => {
const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => { const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => {
$rootScope['name'] = 'world'; $rootScope['name'] = 'world';
$rootScope['dataA'] = 'A'; $rootScope['dataA'] = 'A';
@ -189,8 +189,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly')
it('should support two-way binding and event listener', async(() => { .it('should support two-way binding and event listener', async(() => {
const listenerSpy = jasmine.createSpy('$rootScope.listener'); const listenerSpy = jasmine.createSpy('$rootScope.listener');
const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => { const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => {
$rootScope['value'] = 'world'; $rootScope['value'] = 'world';
@ -404,8 +404,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly')
it('should initialize inputs in time for `ngOnChanges`', async(() => { .it('should initialize inputs in time for `ngOnChanges`', async(() => {
@Component({ @Component({
selector: 'ng2', selector: 'ng2',
template: ` template: `
@ -709,8 +709,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should respect hierarchical dependency injection for ng2', async(() => { .it('should respect hierarchical dependency injection for ng2', async(() => {
@Component({selector: 'parent', template: 'parent(<ng-content></ng-content>)'}) @Component({selector: 'parent', template: 'parent(<ng-content></ng-content>)'})
class ParentComponent { class ParentComponent {
} }
@ -742,8 +742,8 @@ withEachNg1Version(() => {
})); }));
fixmeIvy( fixmeIvy(
'FW-717: Injector on lazy loaded components are not the same as their NgModule\'s injector') && 'FW-717: Injector on lazy loaded components are not the same as their NgModule\'s injector')
it('should work with ng2 lazy loaded components', async(() => { .it('should work with ng2 lazy loaded components', async(() => {
let componentInjector: Injector; let componentInjector: Injector;
@Component({selector: 'ng2', template: ''}) @Component({selector: 'ng2', template: ''})
@ -783,8 +783,8 @@ withEachNg1Version(() => {
const compiler = modInjector.get(Compiler); const compiler = modInjector.get(Compiler);
const modFactory = compiler.compileModuleSync(LazyLoadedModule); const modFactory = compiler.compileModuleSync(LazyLoadedModule);
const childMod = modFactory.create(modInjector); const childMod = modFactory.create(modInjector);
const cmpFactory = const cmpFactory = childMod.componentFactoryResolver.resolveComponentFactory(
childMod.componentFactoryResolver.resolveComponentFactory(LazyLoadedComponent) !; LazyLoadedComponent) !;
const lazyCmp = cmpFactory.create(componentInjector); const lazyCmp = cmpFactory.create(componentInjector);
expect(lazyCmp.instance.module.injector === childMod.injector).toBe(true); expect(lazyCmp.instance.module.injector === childMod.injector).toBe(true);

View File

@ -132,8 +132,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-718: upgraded service not being initialized correctly on the injector') && fixmeIvy('FW-718: upgraded service not being initialized correctly on the injector')
it('should support using an upgraded service', async(() => { .it('should support using an upgraded service', async(() => {
class Ng2Service { class Ng2Service {
constructor(@Inject('ng1Value') private ng1Value: string) {} constructor(@Inject('ng1Value') private ng1Value: string) {}
getValue = () => `${this.ng1Value}-bar`; getValue = () => `${this.ng1Value}-bar`;
@ -261,8 +261,8 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly')
it('should propagate input changes inside the Angular zone', async(() => { .it('should propagate input changes inside the Angular zone', async(() => {
let ng2Component: Ng2Component; let ng2Component: Ng2Component;
@Component({selector: 'ng2', template: ''}) @Component({selector: 'ng2', template: ''})
@ -364,9 +364,9 @@ withEachNg1Version(() => {
}); });
})); }));
fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') && fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly')
fixmeIvy('FW-714: ng1 projected content is not being rendered') && .fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should run the lifecycle hooks in the correct order', async(() => { .it('should run the lifecycle hooks in the correct order', async(() => {
const logs: string[] = []; const logs: string[] = [];
let rootScope: angular.IRootScopeService; let rootScope: angular.IRootScopeService;
@ -379,8 +379,8 @@ withEachNg1Version(() => {
` `
}) })
class Ng2Component implements AfterContentChecked, class Ng2Component implements AfterContentChecked,
AfterContentInit, AfterViewChecked, AfterViewInit, DoCheck, OnChanges, OnDestroy, AfterContentInit, AfterViewChecked, AfterViewInit, DoCheck, OnChanges,
OnInit { OnDestroy, OnInit {
@Input() value = 'foo'; @Input() value = 'foo';
ngAfterContentChecked() { this.log('AfterContentChecked'); } ngAfterContentChecked() { this.log('AfterContentChecked'); }
@ -427,7 +427,8 @@ withEachNg1Version(() => {
// Once initialized. // Once initialized.
expect(multiTrim(element.textContent)).toBe('bar Content'); expect(multiTrim(element.textContent)).toBe('bar Content');
expect(logs).toEqual([ expect(logs).toEqual([
// `ngOnChanges()` call triggered directly through the `inputChanges` $watcher. // `ngOnChanges()` call triggered directly through the `inputChanges`
// $watcher.
'OnChanges(bar)', 'OnChanges(bar)',
// Initial CD triggered directly through the `detectChanges()` or // Initial CD triggered directly through the `detectChanges()` or
// `inputChanges` // `inputChanges`
@ -458,7 +459,8 @@ withEachNg1Version(() => {
rootScope.$apply('value = "baz"'); rootScope.$apply('value = "baz"');
expect(multiTrim(element.textContent)).toBe('baz Content'); expect(multiTrim(element.textContent)).toBe('baz Content');
expect(logs).toEqual([ expect(logs).toEqual([
// `ngOnChanges()` call triggered directly through the `inputChanges` $watcher. // `ngOnChanges()` call triggered directly through the `inputChanges`
// $watcher.
'OnChanges(baz)', 'OnChanges(baz)',
// `propagateDigest: true` (3 CD runs): // `propagateDigest: true` (3 CD runs):
// - CD triggered due to entering/leaving the NgZone (in `inputChanges` // - CD triggered due to entering/leaving the NgZone (in `inputChanges`

View File

@ -24,8 +24,8 @@ withEachNg1Version(() => {
it('should have AngularJS loaded', () => expect(angular.version.major).toBe(1)); it('should have AngularJS loaded', () => expect(angular.version.major).toBe(1));
fixmeIvy('FW-714: ng1 projected content is not being rendered') && fixmeIvy('FW-714: ng1 projected content is not being rendered')
it('should verify UpgradeAdapter example', async(() => { .it('should verify UpgradeAdapter example', async(() => {
// This is wrapping (upgrading) an AngularJS component to be used in an Angular // This is wrapping (upgrading) an AngularJS component to be used in an Angular
// component // component

View File

@ -2135,8 +2135,8 @@ withEachNg1Version(() => {
describe('transclusion', () => { describe('transclusion', () => {
fixmeIvy( fixmeIvy(
`Error: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.`) && `Error: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.`)
it('should support single-slot transclusion', async(() => { .it('should support single-slot transclusion', async(() => {
let ng2ComponentAInstance: Ng2ComponentA; let ng2ComponentAInstance: Ng2ComponentA;
let ng2ComponentBInstance: Ng2ComponentB; let ng2ComponentBInstance: Ng2ComponentB;
@ -2532,8 +2532,8 @@ withEachNg1Version(() => {
})); }));
fixmeIvy( fixmeIvy(
`Error: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.`) && `Error: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.`)
it('should support structural directives in transcluded content', async(() => { .it('should support structural directives in transcluded content', async(() => {
let ng2ComponentInstance: Ng2Component; let ng2ComponentInstance: Ng2Component;
// Define `ng1Component` // Define `ng1Component`
@ -3336,8 +3336,8 @@ withEachNg1Version(() => {
})); }));
fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') && fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed')
it('should call `$onDestroy()` on controller', async(() => { .it('should call `$onDestroy()` on controller', async(() => {
const controllerOnDestroyA = jasmine.createSpy('controllerOnDestroyA'); const controllerOnDestroyA = jasmine.createSpy('controllerOnDestroyA');
const controllerOnDestroyB = jasmine.createSpy('controllerOnDestroyB'); const controllerOnDestroyB = jasmine.createSpy('controllerOnDestroyB');
@ -3355,8 +3355,9 @@ withEachNg1Version(() => {
scope: {}, scope: {},
bindToController: true, bindToController: true,
controllerAs: '$ctrl', controllerAs: '$ctrl',
controller: controller: class {
class {constructor() { (this as any)['$onDestroy'] = controllerOnDestroyB; }} constructor() { (this as any)['$onDestroy'] = controllerOnDestroyB; }
}
}; };
// Define `Ng1ComponentFacade` // Define `Ng1ComponentFacade`
@ -3402,7 +3403,8 @@ withEachNg1Version(() => {
} }
// Bootstrap // Bootstrap
const element = html('<ng2 [show]="!destroyFromNg2" ng-if="!destroyFromNg1"></ng2>'); const element =
html('<ng2 [show]="!destroyFromNg2" ng-if="!destroyFromNg1"></ng2>');
bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(adapter => { bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(adapter => {
const $rootScope = const $rootScope =