test(ivy): run router tests with ivy on CI (#27195)

PR Close #27195
This commit is contained in:
Marc Laval 2018-11-20 17:02:35 +01:00 committed by Miško Hevery
parent 573fb783e1
commit 8ce59a583b
9 changed files with 2108 additions and 1993 deletions

View File

@ -51,6 +51,7 @@ System.config({
'@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'}, '@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser-dynamic/testing': {main: 'index.js', defaultExtension: 'js'}, '@angular/platform-browser-dynamic/testing': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser-dynamic': {main: 'index.js', defaultExtension: 'js'}, '@angular/platform-browser-dynamic': {main: 'index.js', defaultExtension: 'js'},
'@angular/private/testing': {main: 'index.js', defaultExtension: 'js'},
'@angular/upgrade/static': {main: 'index.js', defaultExtension: 'js'}, '@angular/upgrade/static': {main: 'index.js', defaultExtension: 'js'},
'@angular/router/upgrade': {main: 'index.js', defaultExtension: 'js'}, '@angular/router/upgrade': {main: 'index.js', defaultExtension: 'js'},
'@angular/router/testing': {main: 'index.js', defaultExtension: 'js'}, '@angular/router/testing': {main: 'index.js', defaultExtension: 'js'},

View File

@ -76,6 +76,8 @@ module.exports = function(config) {
watched: false watched: false
}, },
{pattern: 'dist/all/@angular/private/testing/**/*.js', included: false, watched: false},
{pattern: 'dist/all/@angular/upgrade/static/*.js', included: false, watched: false}, {pattern: 'dist/all/@angular/upgrade/static/*.js', included: false, watched: false},
{pattern: 'dist/all/@angular/upgrade/static/src/**/*.js', included: false, watched: false}, {pattern: 'dist/all/@angular/upgrade/static/src/**/*.js', included: false, watched: false},

View File

@ -12,6 +12,7 @@ ts_library(
"//packages/platform-browser", "//packages/platform-browser",
"//packages/platform-browser-dynamic", "//packages/platform-browser-dynamic",
"//packages/platform-browser/testing", "//packages/platform-browser/testing",
"//packages/private/testing",
"//packages/router", "//packages/router",
"//packages/router/testing", "//packages/router/testing",
"@rxjs", "@rxjs",
@ -23,9 +24,6 @@ ts_library(
jasmine_node_test( jasmine_node_test(
name = "test", name = "test",
bootstrap = ["angular/tools/testing/init_node_spec.js"], bootstrap = ["angular/tools/testing/init_node_spec.js"],
tags = [
"fixme-ivy-aot",
],
deps = [ deps = [
":test_lib", ":test_lib",
"//tools/testing:node", "//tools/testing:node",
@ -34,9 +32,6 @@ jasmine_node_test(
ts_web_test_suite( ts_web_test_suite(
name = "test_web", name = "test_web",
tags = [
"fixme-ivy-aot",
],
deps = [ deps = [
":test_lib", ":test_lib",
], ],

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,7 @@
import {TestBed} from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import {RouterTestingModule} from '@angular/router/testing';
import {Observable, Observer, of } from 'rxjs'; import {Observable, Observer, of } from 'rxjs';
import {every, mergeMap} from 'rxjs/operators'; import {every, mergeMap} from 'rxjs/operators';
import {TestScheduler} from 'rxjs/testing'; import {TestScheduler} from 'rxjs/testing';
@ -15,7 +16,6 @@ import {TestScheduler} from 'rxjs/testing';
import {prioritizedGuardValue} from '../../src/operators/prioritized_guard_value'; import {prioritizedGuardValue} from '../../src/operators/prioritized_guard_value';
import {Router} from '../../src/router'; import {Router} from '../../src/router';
import {UrlTree} from '../../src/url_tree'; import {UrlTree} from '../../src/url_tree';
import {RouterTestingModule} from '../../testing/src/router_testing_module';
describe('prioritizedGuardValue operator', () => { describe('prioritizedGuardValue operator', () => {

View File

@ -9,21 +9,22 @@
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {Component, ContentChild, NgModule, TemplateRef, Type, ViewChild, ViewContainerRef} from '@angular/core'; import {Component, ContentChild, NgModule, TemplateRef, Type, ViewChild, ViewContainerRef} from '@angular/core';
import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing'; import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {fixmeIvy} from '@angular/private/testing';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {RouterTestingModule} from '@angular/router/testing'; import {RouterTestingModule} from '@angular/router/testing';
describe('Integration', () => { describe('Integration', () => {
describe('routerLinkActive', () => { describe('routerLinkActive', () => {
it('should not cause infinite loops in the change detection - #15825', fakeAsync(() => { fixmeIvy('FW-662: Components without selector are not supported') &&
@Component({selector: 'simple', template: 'simple'}) it('should not cause infinite loops in the change detection - #15825', fakeAsync(() => {
class SimpleCmp { @Component({selector: 'simple', template: 'simple'})
} class SimpleCmp {
}
@Component({ @Component({
selector: 'some-root', selector: 'some-root',
template: ` template: `
<div *ngIf="show"> <div *ngIf="show">
<ng-container *ngTemplateOutlet="tpl"></ng-container> <ng-container *ngTemplateOutlet="tpl"></ng-container>
</div> </div>
@ -31,36 +32,37 @@ describe('Integration', () => {
<ng-template #tpl> <ng-template #tpl>
<a routerLink="/simple" routerLinkActive="active"></a> <a routerLink="/simple" routerLinkActive="active"></a>
</ng-template>` </ng-template>`
}) })
class MyCmp { class MyCmp {
show: boolean = false; show: boolean = false;
} }
@NgModule({ @NgModule({
imports: [CommonModule, RouterTestingModule], imports: [CommonModule, RouterTestingModule],
declarations: [MyCmp, SimpleCmp], declarations: [MyCmp, SimpleCmp],
entryComponents: [SimpleCmp], entryComponents: [SimpleCmp],
}) })
class MyModule { class MyModule {
} }
TestBed.configureTestingModule({imports: [MyModule]}); TestBed.configureTestingModule({imports: [MyModule]});
const router: Router = TestBed.get(Router); const router: Router = TestBed.get(Router);
const fixture = createRoot(router, MyCmp); const fixture = createRoot(router, MyCmp);
router.resetConfig([{path: 'simple', component: SimpleCmp}]); router.resetConfig([{path: 'simple', component: SimpleCmp}]);
router.navigateByUrl('/simple'); router.navigateByUrl('/simple');
advance(fixture); advance(fixture);
const instance = fixture.componentInstance; const instance = fixture.componentInstance;
instance.show = true; instance.show = true;
expect(() => advance(fixture)).not.toThrow(); expect(() => advance(fixture)).not.toThrow();
})); }));
it('should set isActive right after looking at its children -- #18983', fakeAsync(() => { fixmeIvy('FW-662: Components without selector are not supported') &&
@Component({ it('should set isActive right after looking at its children -- #18983', fakeAsync(() => {
template: ` @Component({
template: `
<div #rla="routerLinkActive" routerLinkActive> <div #rla="routerLinkActive" routerLinkActive>
isActive: {{rla.isActive}} isActive: {{rla.isActive}}
@ -71,43 +73,43 @@ describe('Integration', () => {
<ng-container #container></ng-container> <ng-container #container></ng-container>
</div> </div>
` `
}) })
class ComponentWithRouterLink { class ComponentWithRouterLink {
// TODO(issue/24571): remove '!'. // TODO(issue/24571): remove '!'.
@ViewChild(TemplateRef) templateRef !: TemplateRef<any>; @ViewChild(TemplateRef) templateRef !: TemplateRef<any>;
// TODO(issue/24571): remove '!'. // TODO(issue/24571): remove '!'.
@ViewChild('container', {read: ViewContainerRef}) container !: ViewContainerRef; @ViewChild('container', {read: ViewContainerRef}) container !: ViewContainerRef;
addLink() { addLink() {
this.container.createEmbeddedView(this.templateRef, {$implicit: '/simple'}); this.container.createEmbeddedView(this.templateRef, {$implicit: '/simple'});
} }
removeLink() { this.container.clear(); } removeLink() { this.container.clear(); }
} }
@Component({template: 'simple'}) @Component({template: 'simple'})
class SimpleCmp { class SimpleCmp {
} }
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes([{path: 'simple', component: SimpleCmp}])], imports: [RouterTestingModule.withRoutes([{path: 'simple', component: SimpleCmp}])],
declarations: [ComponentWithRouterLink, SimpleCmp] declarations: [ComponentWithRouterLink, SimpleCmp]
}); });
const router: Router = TestBed.get(Router); const router: Router = TestBed.get(Router);
const fixture = createRoot(router, ComponentWithRouterLink); const fixture = createRoot(router, ComponentWithRouterLink);
router.navigateByUrl('/simple'); router.navigateByUrl('/simple');
advance(fixture); advance(fixture);
fixture.componentInstance.addLink(); fixture.componentInstance.addLink();
fixture.detectChanges(); fixture.detectChanges();
fixture.componentInstance.removeLink(); fixture.componentInstance.removeLink();
advance(fixture); advance(fixture);
advance(fixture); advance(fixture);
expect(fixture.nativeElement.innerHTML).toContain('isActive: false'); expect(fixture.nativeElement.innerHTML).toContain('isActive: false');
})); }));
}); });

View File

@ -8,6 +8,7 @@
import {Location} from '@angular/common'; import {Location} from '@angular/common';
import {TestBed, inject} from '@angular/core/testing'; import {TestBed, inject} from '@angular/core/testing';
import {RouterTestingModule} from '@angular/router/testing';
import {of } from 'rxjs'; import {of } from 'rxjs';
import {Routes} from '../src/config'; import {Routes} from '../src/config';
@ -20,7 +21,6 @@ import {RouterStateSnapshot, createEmptyStateSnapshot} from '../src/router_state
import {DefaultUrlSerializer, UrlTree} from '../src/url_tree'; import {DefaultUrlSerializer, UrlTree} from '../src/url_tree';
import {getAllRouteGuards} from '../src/utils/preactivation'; import {getAllRouteGuards} from '../src/utils/preactivation';
import {TreeNode} from '../src/utils/tree'; import {TreeNode} from '../src/utils/tree';
import {RouterTestingModule} from '../testing/src/router_testing_module';
import {Logger, createActivatedRouteSnapshot, provideTokenLogger} from './helpers'; import {Logger, createActivatedRouteSnapshot, provideTokenLogger} from './helpers';

View File

@ -8,10 +8,11 @@
import {Compiler, Component, NgModule, NgModuleFactoryLoader, NgModuleRef} from '@angular/core'; import {Compiler, Component, NgModule, NgModuleFactoryLoader, NgModuleRef} from '@angular/core';
import {TestBed, fakeAsync, inject, tick} from '@angular/core/testing'; import {TestBed, fakeAsync, inject, tick} from '@angular/core/testing';
import {fixmeIvy} from '@angular/private/testing';
import {PreloadAllModules, PreloadingStrategy, RouterPreloader} from '@angular/router';
import {Route, RouteConfigLoadEnd, RouteConfigLoadStart, Router, RouterModule} from '../index'; import {Route, RouteConfigLoadEnd, RouteConfigLoadStart, Router, RouterModule} from '../index';
import {LoadedRouterConfig} from '../src/config'; import {LoadedRouterConfig} from '../src/config';
import {PreloadAllModules, PreloadingStrategy, RouterPreloader} from '../src/router_preloader';
import {RouterTestingModule, SpyNgModuleFactoryLoader} from '../testing'; import {RouterTestingModule, SpyNgModuleFactoryLoader} from '../testing';
describe('RouterPreloader', () => { describe('RouterPreloader', () => {
@ -35,19 +36,20 @@ describe('RouterPreloader', () => {
}); });
}); });
it('should work', fixmeIvy('FW-561: Runtime compiler is not loaded') &&
fakeAsync(inject( it('should work',
[NgModuleFactoryLoader, RouterPreloader, Router], fakeAsync(inject(
(loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router) => { [NgModuleFactoryLoader, RouterPreloader, Router],
loader.stubbedModules = {expected: LoadedModule}; (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router) => {
loader.stubbedModules = {expected: LoadedModule};
preloader.preload().subscribe(() => {}); preloader.preload().subscribe(() => {});
tick(); tick();
const c = router.config; const c = router.config;
expect((c[0] as any)._loadedConfig).not.toBeDefined(); expect((c[0] as any)._loadedConfig).not.toBeDefined();
}))); })));
}); });
describe('should preload configurations', () => { describe('should preload configurations', () => {
@ -58,63 +60,64 @@ describe('RouterPreloader', () => {
}); });
}); });
it('should work', fixmeIvy('FW-561: Runtime compiler is not loaded') &&
fakeAsync(inject( it('should work',
[NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef], fakeAsync(inject(
(loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router, [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef],
testModule: NgModuleRef<any>) => { (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router,
const events: Array<RouteConfigLoadStart|RouteConfigLoadEnd> = []; testModule: NgModuleRef<any>) => {
@NgModule({ const events: Array<RouteConfigLoadStart|RouteConfigLoadEnd> = [];
declarations: [LazyLoadedCmp], @NgModule({
imports: declarations: [LazyLoadedCmp],
[RouterModule.forChild([{path: 'LoadedModule2', component: LazyLoadedCmp}])] imports: [RouterModule.forChild(
}) [{path: 'LoadedModule2', component: LazyLoadedCmp}])]
class LoadedModule2 { })
} class LoadedModule2 {
}
@NgModule({ @NgModule({
imports: imports: [RouterModule.forChild(
[RouterModule.forChild([{path: 'LoadedModule1', loadChildren: 'expected2'}])] [{path: 'LoadedModule1', loadChildren: 'expected2'}])]
}) })
class LoadedModule1 { class LoadedModule1 {
} }
router.events.subscribe(e => { router.events.subscribe(e => {
if (e instanceof RouteConfigLoadEnd || e instanceof RouteConfigLoadStart) { if (e instanceof RouteConfigLoadEnd || e instanceof RouteConfigLoadStart) {
events.push(e); events.push(e);
} }
}); });
loader.stubbedModules = { loader.stubbedModules = {
expected: LoadedModule1, expected: LoadedModule1,
expected2: LoadedModule2, expected2: LoadedModule2,
}; };
preloader.preload().subscribe(() => {}); preloader.preload().subscribe(() => {});
tick(); tick();
const c = router.config; const c = router.config;
expect(c[0].loadChildren).toEqual('expected'); expect(c[0].loadChildren).toEqual('expected');
const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !; const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !;
const module: any = loadedConfig.module; const module: any = loadedConfig.module;
expect(loadedConfig.routes[0].path).toEqual('LoadedModule1'); expect(loadedConfig.routes[0].path).toEqual('LoadedModule1');
expect(module._parent).toBe(testModule); expect(module._parent).toBe(testModule);
const loadedConfig2: LoadedRouterConfig = const loadedConfig2: LoadedRouterConfig =
(loadedConfig.routes[0] as any)._loadedConfig !; (loadedConfig.routes[0] as any)._loadedConfig !;
const module2: any = loadedConfig2.module; const module2: any = loadedConfig2.module;
expect(loadedConfig2.routes[0].path).toEqual('LoadedModule2'); expect(loadedConfig2.routes[0].path).toEqual('LoadedModule2');
expect(module2._parent).toBe(module); expect(module2._parent).toBe(module);
expect(events.map(e => e.toString())).toEqual([ expect(events.map(e => e.toString())).toEqual([
'RouteConfigLoadStart(path: lazy)', 'RouteConfigLoadStart(path: lazy)',
'RouteConfigLoadEnd(path: lazy)', 'RouteConfigLoadEnd(path: lazy)',
'RouteConfigLoadStart(path: LoadedModule1)', 'RouteConfigLoadStart(path: LoadedModule1)',
'RouteConfigLoadEnd(path: LoadedModule1)', 'RouteConfigLoadEnd(path: LoadedModule1)',
]); ]);
}))); })));
}); });
describe('should support modules that have already been loaded', () => { describe('should support modules that have already been loaded', () => {
@ -125,57 +128,59 @@ describe('RouterPreloader', () => {
}); });
}); });
it('should work', fakeAsync(inject( fixmeIvy('FW-???: Cannot read property \'declarations\' of undefined') &&
[NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef, Compiler], it('should work',
(loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, fakeAsync(inject(
router: Router, testModule: NgModuleRef<any>, compiler: Compiler) => { [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef, Compiler],
@NgModule() (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router,
class LoadedModule2 { testModule: NgModuleRef<any>, compiler: Compiler) => {
} @NgModule()
class LoadedModule2 {
}
const module2 = compiler.compileModuleSync(LoadedModule2).create(null); const module2 = compiler.compileModuleSync(LoadedModule2).create(null);
@NgModule({ @NgModule({
imports: [RouterModule.forChild([ imports: [RouterModule.forChild([
<Route>{ <Route>{
path: 'LoadedModule2', path: 'LoadedModule2',
loadChildren: 'no', loadChildren: 'no',
_loadedConfig: { _loadedConfig: {
routes: [{path: 'LoadedModule3', loadChildren: 'expected3'}], routes: [{path: 'LoadedModule3', loadChildren: 'expected3'}],
module: module2, module: module2,
} }
}, },
])] ])]
}) })
class LoadedModule1 { class LoadedModule1 {
} }
@NgModule({imports: [RouterModule.forChild([])]}) @NgModule({imports: [RouterModule.forChild([])]})
class LoadedModule3 { class LoadedModule3 {
} }
loader.stubbedModules = { loader.stubbedModules = {
expected: LoadedModule1, expected: LoadedModule1,
expected3: LoadedModule3, expected3: LoadedModule3,
}; };
preloader.preload().subscribe(() => {}); preloader.preload().subscribe(() => {});
tick(); tick();
const c = router.config; const c = router.config;
const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !; const loadedConfig: LoadedRouterConfig = (c[0] as any)._loadedConfig !;
const module: any = loadedConfig.module; const module: any = loadedConfig.module;
expect(module._parent).toBe(testModule); expect(module._parent).toBe(testModule);
const loadedConfig2: LoadedRouterConfig = const loadedConfig2: LoadedRouterConfig =
(loadedConfig.routes[0] as any)._loadedConfig !; (loadedConfig.routes[0] as any)._loadedConfig !;
const loadedConfig3: LoadedRouterConfig = const loadedConfig3: LoadedRouterConfig =
(loadedConfig2.routes[0] as any)._loadedConfig !; (loadedConfig2.routes[0] as any)._loadedConfig !;
const module3: any = loadedConfig3.module; const module3: any = loadedConfig3.module;
expect(module3._parent).toBe(module2); expect(module3._parent).toBe(module2);
}))); })));
}); });
describe('should ignore errors', () => { describe('should ignore errors', () => {
@ -195,20 +200,21 @@ describe('RouterPreloader', () => {
}); });
}); });
it('should work', fixmeIvy('FW-561: Runtime compiler is not loaded') &&
fakeAsync(inject( it('should work',
[NgModuleFactoryLoader, RouterPreloader, Router], fakeAsync(inject(
(loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router) => { [NgModuleFactoryLoader, RouterPreloader, Router],
loader.stubbedModules = {expected2: LoadedModule}; (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router) => {
loader.stubbedModules = {expected2: LoadedModule};
preloader.preload().subscribe(() => {}); preloader.preload().subscribe(() => {});
tick(); tick();
const c = router.config; const c = router.config;
expect((c[0] as any)._loadedConfig).not.toBeDefined(); expect((c[0] as any)._loadedConfig).not.toBeDefined();
expect((c[1] as any)._loadedConfig).toBeDefined(); expect((c[1] as any)._loadedConfig).toBeDefined();
}))); })));
}); });
describe('should copy loaded configs', () => { describe('should copy loaded configs', () => {
@ -224,21 +230,22 @@ describe('RouterPreloader', () => {
}); });
}); });
it('should work', fixmeIvy('FW-561: Runtime compiler is not loaded') &&
fakeAsync(inject( it('should work',
[NgModuleFactoryLoader, RouterPreloader, Router], fakeAsync(inject(
(loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router) => { [NgModuleFactoryLoader, RouterPreloader, Router],
loader.stubbedModules = {expected: LoadedModule}; (loader: SpyNgModuleFactoryLoader, preloader: RouterPreloader, router: Router) => {
loader.stubbedModules = {expected: LoadedModule};
preloader.preload().subscribe(() => {}); preloader.preload().subscribe(() => {});
tick(); tick();
const c = router.config as{_loadedConfig: LoadedRouterConfig}[]; const c = router.config as{_loadedConfig: LoadedRouterConfig}[];
expect(c[0]._loadedConfig).toBeDefined(); expect(c[0]._loadedConfig).toBeDefined();
expect(c[0]._loadedConfig !.routes).not.toBe(configs); expect(c[0]._loadedConfig !.routes).not.toBe(configs);
expect(c[0]._loadedConfig !.routes[0]).not.toBe(configs[0]); expect(c[0]._loadedConfig !.routes[0]).not.toBe(configs[0]);
expect(c[0]._loadedConfig !.routes[0].component).toBe(configs[0].component); expect(c[0]._loadedConfig !.routes[0].component).toBe(configs[0].component);
}))); })));
}); });
}); });

View File

@ -7,7 +7,7 @@
*/ */
import {fakeAsync, tick} from '@angular/core/testing'; import {fakeAsync, tick} from '@angular/core/testing';
import {SpyNgModuleFactoryLoader} from '../testing/src/router_testing_module'; import {SpyNgModuleFactoryLoader} from '@angular/router/testing';
describe('SpyNgModuleFactoryLoader', () => { describe('SpyNgModuleFactoryLoader', () => {
it('should invoke the compiler when the setter is called', () => { it('should invoke the compiler when the setter is called', () => {