From 221531eed0a0e05658e4ae5b33035231ad806e68 Mon Sep 17 00:00:00 2001 From: why520crazy Date: Wed, 9 Oct 2019 21:16:09 +0800 Subject: [PATCH] test(planet): add some test cases for planet service and module --- packages/planet/src/module.spec.ts | 71 ++++++++++++++ packages/planet/src/module.ts | 7 +- packages/planet/src/planet.class.ts | 6 +- packages/planet/src/planet.spec.ts | 146 ++++++++++++++++++++++++++++ packages/planet/src/planet.ts | 23 +++-- 5 files changed, 242 insertions(+), 11 deletions(-) create mode 100644 packages/planet/src/module.spec.ts create mode 100644 packages/planet/src/planet.spec.ts diff --git a/packages/planet/src/module.spec.ts b/packages/planet/src/module.spec.ts new file mode 100644 index 0000000..0013089 --- /dev/null +++ b/packages/planet/src/module.spec.ts @@ -0,0 +1,71 @@ +import { TestBed } from '@angular/core/testing'; +import { NgxPlanetModule } from './module'; +import { NgModule } from '@angular/core'; +import { PlanetApplicationService } from './application/planet-application.service'; +import { Planet } from './planet'; +import { RouterModule } from '@angular/router'; + +const app1 = { + name: 'app1', + host: '.host-selector', + selector: 'app1-root-container', + routerPathPrefix: '/app1', + hostClass: 'app1-host', + preload: false, + resourcePathPrefix: '/static/app1/', + styles: ['styles/main.css'], + scripts: ['vendor.js', 'main.js'], + loadSerial: false, + manifest: '', + extra: { + appName: '应用1' + } +}; + +@NgModule({ + imports: [NgxPlanetModule, RouterModule.forRoot([])] +}) +class AppModule {} + +@NgModule({ + imports: [NgxPlanetModule.forRoot([app1]), RouterModule.forRoot([])] +}) +class AppModuleWithApps {} + +describe('NgxPlanetModule', () => { + describe('basic', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [AppModule] + }); + }); + + it('should get NgxPlanetModule', () => { + expect(TestBed.get(NgxPlanetModule)).toBeTruthy(); + }); + + it('should get planet', () => { + const planet: Planet = TestBed.get(Planet); + expect(planet).toBeTruthy(); + expect(planet.getApps()).toEqual([]); + }); + }); + + describe('forRoot', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [AppModuleWithApps] + }); + }); + + it('should get NgxPlanetModule', () => { + expect(TestBed.get(NgxPlanetModule)).toBeTruthy(); + }); + + it('should register app1 when use forRoot', () => { + const planet: Planet = TestBed.get(Planet); + expect(planet).toBeTruthy(); + expect(planet.getApps()).toEqual([app1]); + }); + }); +}); diff --git a/packages/planet/src/module.ts b/packages/planet/src/module.ts index dbb75d9..c67aa5b 100644 --- a/packages/planet/src/module.ts +++ b/packages/planet/src/module.ts @@ -1,16 +1,15 @@ import { NgModule, InjectionToken, ModuleWithProviders } from '@angular/core'; import { GlobalEventDispatcher } from './global-event-dispatcher'; -import { PlanetApplication } from './planet.class'; +import { PlanetApplication, PLANET_APPLICATIONS } from './planet.class'; import { HttpClientModule } from '@angular/common/http'; import { EmptyComponent } from './empty/empty.component'; - -const PLANET_APPLICATIONS = new InjectionToken('PLANET_APPLICATIONS'); +import { RouterModule } from '@angular/router'; @NgModule({ declarations: [EmptyComponent], entryComponents: [EmptyComponent], imports: [HttpClientModule], - providers: [GlobalEventDispatcher], + providers: [], exports: [HttpClientModule, EmptyComponent] }) export class NgxPlanetModule { diff --git a/packages/planet/src/planet.class.ts b/packages/planet/src/planet.class.ts index 4c7e4a1..a3acf4d 100644 --- a/packages/planet/src/planet.class.ts +++ b/packages/planet/src/planet.class.ts @@ -1,4 +1,4 @@ -import { NgZone } from '@angular/core'; +import { NgZone, InjectionToken } from '@angular/core'; import { Router } from '@angular/router'; import { PlanetPortalApplication } from './application/portal-application'; @@ -45,3 +45,7 @@ export enum SwitchModes { export interface PlanetRouterEvent { url: string; } + +const PLANET_APPLICATIONS = new InjectionToken('PLANET_APPLICATIONS'); + +export { PLANET_APPLICATIONS }; diff --git a/packages/planet/src/planet.spec.ts b/packages/planet/src/planet.spec.ts new file mode 100644 index 0000000..1004daf --- /dev/null +++ b/packages/planet/src/planet.spec.ts @@ -0,0 +1,146 @@ +import { TestBed, async, tick, fakeAsync } from '@angular/core/testing'; +import { Planet } from './planet'; +import { NgxPlanetModule } from './module'; +import { RouterModule, Router } from '@angular/router'; +import { SwitchModes } from './planet.class'; +import { PlanetApplicationService } from './application/planet-application.service'; +import { PlanetApplicationLoader } from './application/planet-application-loader'; +import { EmptyComponent } from './empty/empty.component'; +import { NgZone } from '@angular/core'; + +const app1 = { + name: 'app1', + host: '.host-selector', + selector: 'app1-root-container', + routerPathPrefix: '/app1', + hostClass: 'app1-host', + preload: false, + switchMode: SwitchModes.default, + resourcePathPrefix: '/static/app1/', + styles: ['styles/main.css'], + scripts: ['vendor.js', 'main.js'], + loadSerial: false, + manifest: '', + extra: { + appName: '应用1' + } +}; + +const app2 = { + name: 'app2', + host: '.host-selector', + selector: 'app2-root-container', + routerPathPrefix: '/app2', + hostClass: 'app2-host', + preload: false, + switchMode: SwitchModes.coexist, + resourcePathPrefix: '/static/app2', + styles: ['styles/main.css'], + scripts: ['vendor.js', 'main.js'], + loadSerial: false, + extra: { + appName: '应用2' + } +}; + +describe('Planet', () => { + let planet: Planet; + let planetApplicationService: PlanetApplicationService; + let planetApplicationLoader: PlanetApplicationLoader; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + NgxPlanetModule, + RouterModule.forRoot([ + { + path: '**', + component: EmptyComponent + } + ]) + ] + }); + planet = TestBed.get(Planet); + planetApplicationService = TestBed.get(PlanetApplicationService); + planetApplicationLoader = TestBed.get(PlanetApplicationLoader); + }); + + it('should create planet', () => { + expect(planet).toBeTruthy(); + }); + + it('should register app1', () => { + const registerSpy = spyOn(planetApplicationService, 'register'); + expect(registerSpy).not.toHaveBeenCalled(); + planet.registerApp(app1); + expect(registerSpy).toHaveBeenCalled(); + expect(registerSpy).toHaveBeenCalledWith(app1); + }); + + it('should register multiple apps', () => { + const registerSpy = spyOn(planetApplicationService, 'register'); + expect(registerSpy).not.toHaveBeenCalled(); + planet.registerApps([app1, app2]); + expect(registerSpy).toHaveBeenCalled(); + expect(registerSpy).toHaveBeenCalledWith([app1, app2]); + }); + + it('should unregister app', () => { + const unregisterSpy = spyOn(planetApplicationService, 'unregister'); + expect(unregisterSpy).not.toHaveBeenCalled(); + planet.unregisterApp('app1'); + expect(unregisterSpy).toHaveBeenCalled(); + expect(unregisterSpy).toHaveBeenCalledWith('app1'); + }); + + it('should get apps', () => { + const getAppsSpy = spyOn(planetApplicationService, 'getApps'); + getAppsSpy.and.returnValue([app1, app2]); + expect(getAppsSpy).not.toHaveBeenCalled(); + const apps = planet.getApps(); + expect(getAppsSpy).toHaveBeenCalled(); + expect(apps).toEqual([app1, app2]); + }); + + it('should set options success', () => { + const setOptionsSpy = spyOn(planetApplicationLoader, 'setOptions'); + expect(setOptionsSpy).not.toHaveBeenCalled(); + const options = { + switchMode: SwitchModes.coexist, + errorHandler: () => {} + }; + planet.setOptions(options); + expect(setOptionsSpy).toHaveBeenCalled(); + expect(setOptionsSpy).toHaveBeenCalledWith(options); + }); + + it('should reroute when navigateByUrl', fakeAsync(() => { + const router: Router = TestBed.get(Router); + const ngZone: NgZone = TestBed.get(NgZone); + const rerouteSpy = spyOn(planetApplicationLoader, 'reroute'); + expect(rerouteSpy).not.toHaveBeenCalled(); + planet.start(); + expect(rerouteSpy).not.toHaveBeenCalled(); + + ngZone.run(() => { + router.navigateByUrl('/app1/dashboard'); + }); + + tick(); + + expect(rerouteSpy).toHaveBeenCalledTimes(1); + expect(rerouteSpy).toHaveBeenCalledWith({ + url: '/app1/dashboard' + }); + + ngZone.run(() => { + router.navigateByUrl('/app1/users'); + }); + tick(); + + expect(rerouteSpy).toHaveBeenCalledTimes(2); + expect(rerouteSpy).toHaveBeenCalledWith({ + url: '/app1/users' + }); + })); +}); diff --git a/packages/planet/src/planet.ts b/packages/planet/src/planet.ts index 569a2fb..955cb96 100644 --- a/packages/planet/src/planet.ts +++ b/packages/planet/src/planet.ts @@ -1,16 +1,14 @@ -import { Injectable } from '@angular/core'; +import { Injectable, Inject, Optional } from '@angular/core'; import { NavigationEnd, RouterEvent, Router } from '@angular/router'; -import { PlanetOptions, PlanetApplication } from './planet.class'; +import { PlanetOptions, PlanetApplication, PLANET_APPLICATIONS } from './planet.class'; import { PlanetApplicationService } from './application/planet-application.service'; import { setPortalApplicationData } from './application/planet-application-ref'; import { PlanetApplicationLoader, - ApplicationStatus, AppsLoadingStartEvent, AppStatusChangeEvent } from './application/planet-application-loader'; import { Observable } from 'rxjs'; -import { EmptyComponent } from './empty/empty.component'; @Injectable({ providedIn: 'root' @@ -31,8 +29,13 @@ export class Planet { constructor( private planetApplicationLoader: PlanetApplicationLoader, private router: Router, - private planetApplicationService: PlanetApplicationService - ) {} + private planetApplicationService: PlanetApplicationService, + @Inject(PLANET_APPLICATIONS) @Optional() planetApplications: PlanetApplication[] + ) { + if (planetApplications) { + this.registerApps(planetApplications); + } + } setOptions(options: Partial) { this.planetApplicationLoader.setOptions(options); @@ -50,6 +53,14 @@ export class Planet { this.planetApplicationService.register(apps); } + unregisterApp(name: string) { + this.planetApplicationService.unregister(name); + } + + getApps() { + return this.planetApplicationService.getApps(); + } + start() { this.router.events.subscribe((event: RouterEvent) => { if (event instanceof NavigationEnd) {