Skip to content

Commit b31e54e

Browse files
committed
angular router handler
1 parent 72641c1 commit b31e54e

File tree

6 files changed

+161
-7
lines changed

6 files changed

+161
-7
lines changed

spec/fixtures/components/home-page/home-page.component.spec.expected.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
22
import { HomePageComponent } from './home-page.component';
3-
import { Router, ActivatedRoute } from '@angular/router';
3+
import { ActivatedRoute, ParamMap, Router, RouterEvent } from '@angular/router';
4+
import { ReplaySubject } from 'rxjs';
45

56
describe('HomePageComponent', () => {
67
let component: HomePageComponent;
78
let fixture: ComponentFixture<HomePageComponent>;
89
let fakeRouter: jasmine.SpyObj<Router>;
10+
let routerEvents: ReplaySubject<RouterEvent>;
911
let fakeRoute: jasmine.SpyObj<ActivatedRoute>;
1012
let fakeWindow: jasmine.SpyObj<Window>;
1113

1214
beforeEach(waitForAsync(() => {
1315
fakeRouter = jasmine.createSpyObj<Router>('Router', ['navigate']);
1416
fakeRoute = {} as jasmine.SpyObj<ActivatedRoute>;
17+
routerEvents = new ReplaySubject<RouterEvent>(1);
1518
fakeWindow = {} as jasmine.SpyObj<Window>;
1619

1720
TestBed.configureTestingModule({
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2+
import { HomePageComponent } from './home-page.component';
3+
import { ActivatedRoute, ParamMap, Router, RouterEvent } from '@angular/router';
4+
import { Observable, ReplaySubject } from 'rxjs';
5+
6+
describe('HomePageComponent', () => {
7+
let component: HomePageComponent;
8+
let fixture: ComponentFixture<HomePageComponent>;
9+
let fakeRouter: jasmine.SpyObj<Router>;
10+
let routerEventsSubject: ReplaySubject<RouterEvent>;
11+
let fakeRoute: jasmine.SpyObj<ActivatedRoute>;
12+
let routeParams: { [prop: string]: string };
13+
let routeParamMap: jasmine.SpyObj<ParamMap>;
14+
let routeParamsSubject: ReplaySubject<ParamMap>;
15+
16+
beforeEach(async(() => {
17+
fakeRouter = jasmine.createSpyObj<Router>('Router', ['navigate']);
18+
routerEventsSubject = new ReplaySubject<RouterEvent>(1);
19+
fakeRoute = jasmine.createSpyObj<ActivatedRoute>('ActivatedRoute', []);
20+
routeParams = {};
21+
routeParamMap = jasmine.createSpyObj<ParamMap>('ParamMap', ['get', 'has']);
22+
routeParamMap.get.and.callFake((k) => routeParams[k]);
23+
routeParamMap.has.and.callFake((k) => !!routeParams[k]);
24+
routeParamsSubject = (fakeRoute as { paramMap: Observable<ParamMap> }).paramMap = new ReplaySubject<ParamMap>(1);
25+
26+
TestBed.configureTestingModule({
27+
declarations: [HomePageComponent],
28+
providers: [
29+
{ provide: Router, useFactory: () => fakeRouter },
30+
{ provide: ActivatedRoute, useFactory: () => fakeRoute },
31+
]
32+
})
33+
.compileComponents();
34+
}));
35+
36+
beforeEach(() => {
37+
fixture = TestBed.createComponent(HomePageComponent);
38+
component = fixture.componentInstance;
39+
});
40+
41+
it('should create', () => {
42+
expect(component).toBeTruthy();
43+
});
44+
45+
});

spec/fixtures/components/home-page/home-page.component.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Component, Inject, OnInit } from '@angular/core';
2-
import { Router, ActivatedRoute } from '@angular/router';
2+
import { Router, ActivatedRoute, NavigationStart } from '@angular/router';
3+
import { take, filter } from 'rxjs/operators';
34

45
@Component({
56
selector: 'app-name',
@@ -14,10 +15,22 @@ export class HomePageComponent implements OnInit {
1415
) { }
1516

1617
ngOnInit(): void {
18+
const value = this.route.snapshot.queryParams['value'];
19+
console.info(value);
20+
1721
this.route.paramMap.subscribe(params => {
1822
if (params.has('type') && params.get('type') === 'user') {
1923
this.router.navigate(['home', 'user']);
2024
}
2125
});
26+
27+
this.router.events
28+
.pipe(
29+
take(1),
30+
filter(ev => ev instanceof NavigationStart)
31+
)
32+
.subscribe(()=>{
33+
console.info('nav start event')
34+
});
2235
}
2336
}

spec/integration.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { run } from '../src/main';
22
import { unlinkSync, readFileSync } from 'fs';
33

4-
const leaveSpecFilesOnDisk = false;
4+
const leaveSpecFilesOnDisk = true;
55

66
describe('integration', () => {
77

@@ -15,7 +15,7 @@ describe('integration', () => {
1515

1616
});
1717

18-
describe(`home component test`, () => {
18+
fdescribe(`home component test`, () => {
1919

2020
createSpec({
2121
file: 'spec/fixtures/components/home-page/home-page.component.ts',
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
2+
import { DependencyHandler } from '../model';
3+
import defaultDependencyHandler from './default.handler';
4+
5+
export default {
6+
run(result, dep, options) {
7+
defaultDependencyHandler.run(result, dep, options);
8+
9+
// extra subject to support router events if property is used
10+
if (dep.type === 'Router' && options.sourceCode.includes(`${dep.name}.events`)) {
11+
result.imports.push({
12+
path: 'rxjs',
13+
names: ['ReplaySubject']
14+
});
15+
result.imports.push({
16+
path: '@angular/router',
17+
names: ['RouterEvent']
18+
});
19+
20+
result.declarations.push({
21+
name: 'routerEventsSubject',
22+
type: 'ReplaySubject<RouterEvent>'
23+
});
24+
25+
result.initializers.push({
26+
name: 'routerEventsSubject',
27+
value: 'new ReplaySubject<RouterEvent>(1)'
28+
});
29+
}
30+
31+
if (dep.type === 'ActivatedRoute') {
32+
// param map mock
33+
if (options.sourceCode.includes(`${dep.name}.paramMap`)) {
34+
result.imports.push({
35+
path: '@angular/router',
36+
names: ['ParamMap']
37+
});
38+
39+
result.imports.push({
40+
path: 'rxjs',
41+
names: ['Observable']
42+
});
43+
44+
45+
result.declarations.push({
46+
name: 'routeParams',
47+
type: '{ [prop: string]: string }'
48+
});
49+
50+
result.initializers.push({
51+
name: 'routeParams',
52+
value: '{}'
53+
});
54+
55+
result.declarations.push({
56+
name: 'routeParamMap',
57+
type: 'jasmine.SpyObj<ParamMap>'
58+
});
59+
60+
result.initializers.push({
61+
name: 'routeParamMap',
62+
value: `jasmine.createSpyObj<ParamMap>(${options.quoteSymbol}ParamMap${options.quoteSymbol}, [${options.quoteSymbol}get${options.quoteSymbol}, ${options.quoteSymbol}has${options.quoteSymbol}])`
63+
});
64+
result.initializers.push({
65+
value: 'routeParamMap.get.and.callFake((k) => routeParams[k])'
66+
});
67+
68+
result.initializers.push({
69+
value: 'routeParamMap.has.and.callFake((k) => !!routeParams[k])'
70+
});
71+
72+
result.declarations.push({
73+
name: 'routeParamsSubject',
74+
type: 'ReplaySubject<ParamMap>'
75+
});
76+
77+
result.initializers.push({
78+
// cast below makes sure that typescript is checking asignment
79+
// this is basically a workaround for readonly properties
80+
name: 'routeParamsSubject',
81+
value: `(${options.variableName} as { paramMap: Observable<ParamMap> }).paramMap = new ReplaySubject<ParamMap>(1)`
82+
});
83+
}
84+
}
85+
},
86+
87+
test(dep) {
88+
return dep.type === 'Router' || dep.type === 'ActivatedRoute';
89+
}
90+
} as DependencyHandler;

src/dependency-handlers/index.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
import handler from './default.handler';
21
import { DependencyHandler } from '../model';
2+
import _defaultDependencyHandler from './default.handler';
3+
import _angularRouterHandler from './angular.router.handler';
34

4-
export const defaultDependencyHandler: typeof handler = handler;
5+
export const defaultDependencyHandler: DependencyHandler = _defaultDependencyHandler;
6+
export const angularRouterHandler: DependencyHandler = _angularRouterHandler;
57

68
export const dependencyHandlers: DependencyHandler[] = [
7-
handler
9+
angularRouterHandler,
10+
defaultDependencyHandler,
811
];

0 commit comments

Comments
 (0)