test(ivy): add root causes for router TestBed failures (#28014)

PR Close #28014
This commit is contained in:
Marc Laval 2019-01-09 15:45:55 +01:00 committed by Andrew Kushnir
parent 29e3144269
commit 5609764886

View File

@ -451,7 +451,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]');
}))); })));
fixmeIvy('unknown/maybe FW-918') fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick')
.it('should work when an outlet is in an ngIf', .it('should work when an outlet is in an ngIf',
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);
@ -468,40 +468,38 @@ describe('Integration', () => {
expect(location.path()).toEqual('/child/simple'); expect(location.path()).toEqual('/child/simple');
}))); })));
it('should work when an outlet is added/removed', fakeAsync(() => { fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick')
@Component({ .it('should work when an outlet is added/removed', fakeAsync(() => {
selector: 'someRoot', @Component({
template: `[<div *ngIf="cond"><router-outlet></router-outlet></div>]` selector: 'someRoot',
}) template: `[<div *ngIf="cond"><router-outlet></router-outlet></div>]`
class RootCmpWithLink { })
cond: boolean = true; class RootCmpWithLink {
} cond: boolean = true;
TestBed.configureTestingModule({declarations: [RootCmpWithLink]}); }
TestBed.configureTestingModule({declarations: [RootCmpWithLink]});
const router: Router = TestBed.get(Router); const router: Router = TestBed.get(Router);
const fixture = createRoot(router, RootCmpWithLink); const fixture = createRoot(router, RootCmpWithLink);
router.resetConfig([ router.resetConfig([
{path: 'simple', component: SimpleCmp}, {path: 'simple', component: SimpleCmp},
{path: 'blank', component: BlankCmp}, {path: 'blank', component: BlankCmp},
]); ]);
router.navigateByUrl('/simple'); router.navigateByUrl('/simple');
advance(fixture); advance(fixture);
expect(fixture.nativeElement).toHaveText('[simple]'); expect(fixture.nativeElement).toHaveText('[simple]');
fixture.componentInstance.cond = false; fixture.componentInstance.cond = false;
advance(fixture); advance(fixture);
expect(fixture.nativeElement).toHaveText('[]'); expect(fixture.nativeElement).toHaveText('[]');
fixture.componentInstance.cond = true; fixture.componentInstance.cond = true;
advance(fixture); advance(fixture);
expect(fixture.nativeElement).toHaveText('[simple]'); expect(fixture.nativeElement).toHaveText('[simple]');
}));
// TODO: remove extra tick for Ivy?
tick();
}));
it('should update location when navigating', fakeAsync(() => { it('should update location when navigating', fakeAsync(() => {
@Component({template: `record`}) @Component({template: `record`})
@ -635,7 +633,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]'); expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]');
}))); })));
fixmeIvy('unknown/maybe FW-918') fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick')
.it('should navigate back and forward', .it('should navigate back and forward',
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);
@ -1008,7 +1006,7 @@ describe('Integration', () => {
]); ]);
}))); })));
fixmeIvy('unknown/maybe FW-918') fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick')
.it('should handle failed navigations gracefully', .it('should handle failed navigations gracefully',
fakeAsync(inject([Router], (router: Router) => { fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -2033,7 +2031,7 @@ describe('Integration', () => {
}); });
}); });
fixmeIvy('unknown/maybe FW-918') fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick')
.it('works', .it('works',
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);
@ -2056,7 +2054,7 @@ describe('Integration', () => {
beforeEach(() => { TestBed.configureTestingModule({providers: [AlwaysTrue]}); }); beforeEach(() => { TestBed.configureTestingModule({providers: [AlwaysTrue]}); });
fixmeIvy('unknown/maybe FW-918') fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick')
.it('works', .it('works',
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);
@ -3357,7 +3355,7 @@ describe('Integration', () => {
}); });
describe('route events', () => { describe('route events', () => {
fixmeIvy('unknown/maybe FW-918') fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick')
.it('should fire matching (Child)ActivationStart/End events', .it('should fire matching (Child)ActivationStart/End events',
fakeAsync(inject([Router], (router: Router) => { fakeAsync(inject([Router], (router: Router) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -4530,84 +4528,82 @@ describe('Integration', () => {
expect(simpleCmp1).not.toBe(simpleCmp2); expect(simpleCmp1).not.toBe(simpleCmp2);
}))); })));
it('should not mount the component of the previously reused route when the outlet was not instantiated at the time of route activation', fixmeIvy('FW-768: markViewDirty instruction is scheduling a tick')
fakeAsync(() => { .it('should not mount the component of the previously reused route when the outlet was not instantiated at the time of route activation',
@Component({ fakeAsync(() => {
selector: 'root-cmp', @Component({
template: selector: 'root-cmp',
'<div *ngIf="isToolpanelShowing"><router-outlet name="toolpanel"></router-outlet></div>' template:
}) '<div *ngIf="isToolpanelShowing"><router-outlet name="toolpanel"></router-outlet></div>'
class RootCmpWithCondOutlet implements OnDestroy { })
private subscription: Subscription; class RootCmpWithCondOutlet implements OnDestroy {
public isToolpanelShowing: boolean = false; private subscription: Subscription;
public isToolpanelShowing: boolean = false;
constructor(router: Router) { constructor(router: Router) {
this.subscription = this.subscription =
router.events.pipe(filter(event => event instanceof NavigationEnd)) router.events.pipe(filter(event => event instanceof NavigationEnd))
.subscribe( .subscribe(
() => this.isToolpanelShowing = () => this.isToolpanelShowing =
!!router.parseUrl(router.url).root.children['toolpanel']); !!router.parseUrl(router.url).root.children['toolpanel']);
} }
public ngOnDestroy(): void { this.subscription.unsubscribe(); } public ngOnDestroy(): void { this.subscription.unsubscribe(); }
} }
@Component({selector: 'tool-1-cmp', template: 'Tool 1 showing'}) @Component({selector: 'tool-1-cmp', template: 'Tool 1 showing'})
class Tool1Component { class Tool1Component {
} }
@Component({selector: 'tool-2-cmp', template: 'Tool 2 showing'}) @Component({selector: 'tool-2-cmp', template: 'Tool 2 showing'})
class Tool2Component { class Tool2Component {
} }
@NgModule({ @NgModule({
declarations: [RootCmpWithCondOutlet, Tool1Component, Tool2Component], declarations: [RootCmpWithCondOutlet, Tool1Component, Tool2Component],
imports: [ imports: [
CommonModule, CommonModule,
RouterTestingModule.withRoutes([ RouterTestingModule.withRoutes([
{path: 'a', outlet: 'toolpanel', component: Tool1Component}, {path: 'a', outlet: 'toolpanel', component: Tool1Component},
{path: 'b', outlet: 'toolpanel', component: Tool2Component}, {path: 'b', outlet: 'toolpanel', component: Tool2Component},
]), ]),
], ],
}) })
class TestModule { class TestModule {
} }
TestBed.configureTestingModule({imports: [TestModule]}); TestBed.configureTestingModule({imports: [TestModule]});
const router: Router = TestBed.get(Router); const router: Router = TestBed.get(Router);
router.routeReuseStrategy = new AttachDetachReuseStrategy(); router.routeReuseStrategy = new AttachDetachReuseStrategy();
const fixture = createRoot(router, RootCmpWithCondOutlet); const fixture = createRoot(router, RootCmpWithCondOutlet);
// Activate 'tool-1' // Activate 'tool-1'
router.navigate([{outlets: {toolpanel: 'a'}}]); router.navigate([{outlets: {toolpanel: 'a'}}]);
advance(fixture); advance(fixture);
expect(fixture).toContainComponent(Tool1Component, '(a)'); expect(fixture).toContainComponent(Tool1Component, '(a)');
// Deactivate 'tool-1' // Deactivate 'tool-1'
router.navigate([{outlets: {toolpanel: null}}]); router.navigate([{outlets: {toolpanel: null}}]);
advance(fixture); advance(fixture);
expect(fixture).not.toContainComponent(Tool1Component, '(b)'); expect(fixture).not.toContainComponent(Tool1Component, '(b)');
// Activate 'tool-1' // Activate 'tool-1'
router.navigate([{outlets: {toolpanel: 'a'}}]); router.navigate([{outlets: {toolpanel: 'a'}}]);
advance(fixture); advance(fixture);
expect(fixture).toContainComponent(Tool1Component, '(c)'); expect(fixture).toContainComponent(Tool1Component, '(c)');
// Deactivate 'tool-1' // Deactivate 'tool-1'
router.navigate([{outlets: {toolpanel: null}}]); router.navigate([{outlets: {toolpanel: null}}]);
advance(fixture); advance(fixture);
expect(fixture).not.toContainComponent(Tool1Component, '(d)'); expect(fixture).not.toContainComponent(Tool1Component, '(d)');
// Activate 'tool-2' // Activate 'tool-2'
router.navigate([{outlets: {toolpanel: 'b'}}]); router.navigate([{outlets: {toolpanel: 'b'}}]);
advance(fixture); advance(fixture);
expect(fixture).toContainComponent(Tool2Component, '(e)'); expect(fixture).toContainComponent(Tool2Component, '(e)');
}));
// TODO: remove extra tick for Ivy?
tick();
}));
}); });
}); });