Skip to content

Commit

Permalink
refactor(loader): extract load app logic to app loader service, add test
Browse files Browse the repository at this point in the history
  • Loading branch information
why520crazy committed Sep 15, 2019
1 parent 19bbf8a commit 62eed19
Show file tree
Hide file tree
Showing 16 changed files with 849 additions and 349 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ npm i @worktile/planet --save

## Demo

![ngx-planet-micro-front-end.gif](https://github.com/worktile/ngx-planet/blob/master/src/assets/ngx-planet-micro-front-end.gif?raw=true)
![ngx-planet-micro-front-end.gif](https://github.com/worktile/ngx-planet/blob/master/examples/portal/src/assets/ngx-planet-micro-front-end.gif?raw=true)

## Usage

Expand Down
4 changes: 2 additions & 2 deletions examples/portal/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class AppComponent implements OnInit {
routerPathPrefix: /\/app1|app4/, // '/app1',
selector: 'app1-root-container',
resourcePathPrefix: 'app1/static/',
preload: true,
preload: false,
loadSerial: true,
// prettier-ignore
scripts: [
Expand All @@ -71,7 +71,7 @@ export class AppComponent implements OnInit {
hostClass: appHostContainerClass,
routerPathPrefix: '/app2',
selector: 'app2-root-container',
preload: true,
preload: false,
// prettier-ignore
scripts: [
'/app2/static/main.js'
Expand Down
2 changes: 1 addition & 1 deletion examples/portal/src/tslint.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": "../tslint.json",
"extends": "../../../tslint.json",
"rules": {
"directive-selector": [true, "attribute", "app", "camelCase"],
"component-selector": [true, "element", "app", "kebab-case"]
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"build:app2": "ng build app2",
"build": "ng build planet",
"test": "ng test planet",
"lint": "ng lint",
"lint": "ng lint planet",
"e2e": "ng e2e",
"pub-only": "cd dist/planet && npm publish --access=public",
"pub": "npm run build && npm run pub-only"
Expand Down
2 changes: 1 addition & 1 deletion packages/planet/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@worktile/planet",
"name": "@worktile/ngx-planet",
"version": "0.0.11",
"private": false,
"peerDependencies": {
Expand Down
134 changes: 134 additions & 0 deletions packages/planet/src/application/planet-application-loader.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { Subject } from 'rxjs';
import { RouterModule } from '@angular/router';
import { TestBed, fakeAsync, flush, tick } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { PlanetApplicationLoader, ApplicationStatus } from './planet-application-loader';
import { AssetsLoader } from '../assets-loader';

import { SwitchModes } from '../planet.class';
import { PlanetApplicationService } from './planet-application.service';
import { CommonModule } from '@angular/common';
import { NgZone } from '@angular/core';
import { PlanetApplicationRef } from './planet-application-ref';

const app1 = {
name: 'app1',
host: '.host-selector',
selector: 'app1-root-container',
routerPathPrefix: '/app1',
hostClass: 'app1-host',
preload: false,
switchMode: SwitchModes.coexist,
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'
}
};

function mockApplicationRef(appName: string) {
const planetAppRef = new PlanetApplicationRef(appName, null);
(window as any).planet.apps[appName] = planetAppRef;
return planetAppRef;
}

describe('PlanetApplicationLoader', () => {
let planetApplicationLoader: PlanetApplicationLoader;
let planetApplicationService: PlanetApplicationService;
let assetsLoader: AssetsLoader;
let ngZone: NgZone;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, RouterModule.forRoot([])]
});
planetApplicationLoader = TestBed.get(PlanetApplicationLoader);
planetApplicationService = TestBed.get(PlanetApplicationService);
assetsLoader = TestBed.get(AssetsLoader);
ngZone = TestBed.get(NgZone);

planetApplicationService.register(app1);
planetApplicationService.register(app2);
});

afterEach(() => {
(window as any).planet.apps = {};
});

it(`should load and bootstrap app`, fakeAsync(() => {
const loadScriptsAndStyles$ = new Subject();
const assetsLoaderSpy = spyOn(assetsLoader, 'loadScriptsAndStyles');
assetsLoaderSpy.and.returnValue(loadScriptsAndStyles$);

const planetAppRef = mockApplicationRef(app1.name);
const bootstrapSpy = spyOn(planetAppRef, 'bootstrap');

const appStatusChangeSpy = jasmine.createSpy('app status change spy');
planetApplicationLoader.appStatusChange.subscribe(appStatusChangeSpy);
expect(appStatusChangeSpy).not.toHaveBeenCalled();

planetApplicationLoader.reroute({ url: '/app1/dashboard' });

expect(appStatusChangeSpy).toHaveBeenCalled();
expect(appStatusChangeSpy).toHaveBeenCalledWith({ app: app1, status: ApplicationStatus.assetsLoading });

loadScriptsAndStyles$.next();
loadScriptsAndStyles$.complete();

expect(appStatusChangeSpy).toHaveBeenCalledTimes(2);
expect(appStatusChangeSpy).toHaveBeenCalledWith({ app: app1, status: ApplicationStatus.assetsLoaded });

expect(bootstrapSpy).not.toHaveBeenCalled();
ngZone.onStable.next();
expect(bootstrapSpy).toHaveBeenCalled();

expect(appStatusChangeSpy).toHaveBeenCalledTimes(4);
expect(appStatusChangeSpy).toHaveBeenCalledWith({ app: app1, status: ApplicationStatus.bootstrapped });

tick();
}));

// it(`should cancel load app1 which not returned and start load app2`, fakeAsync(() => {
// const loadScriptsAndStylesApp1$ = new Subject();
// const loadScriptsAndStylesApp2$ = new Subject();
// const assetsLoaderSpy = spyOn(assetsLoader, 'loadScriptsAndStyles');
// assetsLoaderSpy.and.returnValues(loadScriptsAndStylesApp1$, loadScriptsAndStylesApp2$);
// const appStatusChangeSpy = jasmine.createSpy('app status change spy');
// planetApplicationLoader.appStatusChange.subscribe(appStatusChangeSpy);
// expect(appStatusChangeSpy).not.toHaveBeenCalled();
// planetApplicationLoader.reroute({ url: '/app1' });
// expect(appStatusChangeSpy).toHaveBeenCalled();
// expect(appStatusChangeSpy).toHaveBeenCalledWith({ app: app1, status: ApplicationStatus.assetsLoading });
// planetApplicationLoader.reroute({ url: '/app2' });
// expect(appStatusChangeSpy).toHaveBeenCalledTimes(2);
// expect(appStatusChangeSpy).toHaveBeenCalledWith({ app: app2, status: ApplicationStatus.assetsLoading });
// loadScriptsAndStylesApp1$.next();
// loadScriptsAndStylesApp1$.complete();
// expect(appStatusChangeSpy).toHaveBeenCalledTimes(2);
// loadScriptsAndStylesApp2$.next();
// loadScriptsAndStylesApp1$.complete();
// expect(appStatusChangeSpy).toHaveBeenCalledTimes(3);
// expect(appStatusChangeSpy).toHaveBeenCalledWith({ app: app2, status: ApplicationStatus.bootstrapped });
// tick();
// }));
});
Loading

0 comments on commit 62eed19

Please sign in to comment.