Skip to content

Commit dd1d4ef

Browse files
billyjovalan-agius4
authored andcommitted
fix(@schematics/angular): avoid unuse imports for canLoad guard generation
(cherry picked from commit 3081524)
1 parent ef9710b commit dd1d4ef

File tree

3 files changed

+62
-20
lines changed

3 files changed

+62
-20
lines changed

packages/schematics/angular/guard/files/__name@dasherize__.guard.ts.template

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Injectable } from '@angular/core';
2-
import { <%= implementationImports %>ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
2+
import { <%= implementationImports %> } from '@angular/router';
33
import { Observable } from 'rxjs';
44

55
@Injectable({

packages/schematics/angular/guard/index.ts

+16-3
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,25 @@ export default function (options: GuardOptions): Rule {
3939
const implementations = options.implements
4040
.map(implement => implement === 'CanDeactivate' ? 'CanDeactivate<unknown>' : implement)
4141
.join(', ');
42-
let implementationImports = `${options.implements.join(', ')}, `;
43-
// As long as we aren't in IE... ;)
42+
const commonRouterNameImports = ['ActivatedRouteSnapshot', 'RouterStateSnapshot'];
43+
const routerNamedImports: string[] = [...options.implements, 'UrlTree'];
44+
4445
if (options.implements.includes(GuardInterface.CanLoad)) {
45-
implementationImports = `${implementationImports}Route, UrlSegment, `;
46+
routerNamedImports.push(
47+
'Route',
48+
'UrlSegment',
49+
);
50+
51+
if (options.implements.length > 1) {
52+
routerNamedImports.push(...commonRouterNameImports);
53+
}
54+
} else {
55+
routerNamedImports.push(...commonRouterNameImports);
4656
}
4757

58+
routerNamedImports.sort();
59+
60+
const implementationImports = routerNamedImports.join(', ');
4861
const parsedPath = parseName(options.path, options.name);
4962
options.name = parsedPath.name;
5063
options.path = parsedPath.path;

packages/schematics/angular/guard/index_spec.ts

+45-16
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,14 @@ describe('Guard Schematic', () => {
3838
let appTree: UnitTestTree;
3939
beforeEach(async () => {
4040
appTree = await schematicRunner.runSchematicAsync('workspace', workspaceOptions).toPromise();
41-
appTree = await schematicRunner.runSchematicAsync('application', appOptions, appTree)
41+
appTree = await schematicRunner
42+
.runSchematicAsync('application', appOptions, appTree)
4243
.toPromise();
4344
});
4445

4546
it('should create a guard', async () => {
46-
const tree = await schematicRunner.runSchematicAsync('guard', defaultOptions, appTree)
47+
const tree = await schematicRunner
48+
.runSchematicAsync('guard', defaultOptions, appTree)
4749
.toPromise();
4850
const files = tree.files;
4951
expect(files).toContain('/projects/bar/src/app/foo.guard.spec.ts');
@@ -53,8 +55,7 @@ describe('Guard Schematic', () => {
5355
it('should respect the skipTests flag', async () => {
5456
const options = { ...defaultOptions, skipTests: true };
5557

56-
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree)
57-
.toPromise();
58+
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
5859
const files = tree.files;
5960
expect(files).not.toContain('/projects/bar/src/app/foo.guard.spec.ts');
6061
expect(files).toContain('/projects/bar/src/app/foo.guard.ts');
@@ -63,8 +64,7 @@ describe('Guard Schematic', () => {
6364
it('should respect the flat flag', async () => {
6465
const options = { ...defaultOptions, flat: false };
6566

66-
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree)
67-
.toPromise();
67+
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
6868
const files = tree.files;
6969
expect(files).toContain('/projects/bar/src/app/foo/foo.guard.spec.ts');
7070
expect(files).toContain('/projects/bar/src/app/foo/foo.guard.ts');
@@ -74,15 +74,13 @@ describe('Guard Schematic', () => {
7474
const config = JSON.parse(appTree.readContent('/angular.json'));
7575
config.projects.bar.sourceRoot = 'projects/bar/custom';
7676
appTree.overwrite('/angular.json', JSON.stringify(config, null, 2));
77-
appTree = await schematicRunner.runSchematicAsync('guard', defaultOptions, appTree)
78-
.toPromise();
77+
appTree = await schematicRunner.runSchematicAsync('guard', defaultOptions, appTree).toPromise();
7978
expect(appTree.files).toContain('/projects/bar/custom/app/foo.guard.ts');
8079
});
8180

8281
it('should respect the implements value', async () => {
83-
const options = { ...defaultOptions, implements: ['CanActivate']};
84-
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree)
85-
.toPromise();
82+
const options = { ...defaultOptions, implements: ['CanActivate'] };
83+
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
8684
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
8785
expect(fileString).toContain('CanActivate');
8886
expect(fileString).toContain('canActivate');
@@ -94,9 +92,8 @@ describe('Guard Schematic', () => {
9492

9593
it('should respect the implements values', async () => {
9694
const implementationOptions = ['CanActivate', 'CanLoad', 'CanActivateChild'];
97-
const options = { ...defaultOptions, implements: implementationOptions};
98-
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree)
99-
.toPromise();
95+
const options = { ...defaultOptions, implements: implementationOptions };
96+
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
10097
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
10198

10299
// Should contain all implementations
@@ -109,8 +106,7 @@ describe('Guard Schematic', () => {
109106

110107
it('should use CanActivate if no implements value', async () => {
111108
const options = { ...defaultOptions, implements: undefined };
112-
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree)
113-
.toPromise();
109+
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
114110
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
115111
expect(fileString).toContain('CanActivate');
116112
expect(fileString).toContain('canActivate');
@@ -119,4 +115,37 @@ describe('Guard Schematic', () => {
119115
expect(fileString).not.toContain('CanLoad');
120116
expect(fileString).not.toContain('canLoad');
121117
});
118+
119+
it('should add correct imports based on CanLoad implementation', async () => {
120+
const implementationOptions = ['CanLoad'];
121+
const options = { ...defaultOptions, implements: implementationOptions };
122+
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
123+
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
124+
const expectedImports = `import { CanLoad, Route, UrlSegment, UrlTree } from '@angular/router';`;
125+
126+
expect(fileString).toContain(expectedImports);
127+
});
128+
129+
it('should add correct imports based on CanActivate implementation', async () => {
130+
const implementationOptions = ['CanActivate'];
131+
const options = { ...defaultOptions, implements: implementationOptions };
132+
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
133+
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
134+
const expectedImports = `import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree } from '@angular/router';`;
135+
136+
expect(fileString).toContain(expectedImports);
137+
});
138+
139+
it('should add correct imports if multiple implementations was selected', async () => {
140+
const implementationOptions = ['CanActivate', 'CanLoad', 'CanActivateChild'];
141+
const options = { ...defaultOptions, implements: implementationOptions };
142+
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
143+
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
144+
const expectedImports =
145+
`import ` +
146+
`{ ActivatedRouteSnapshot, CanActivate, CanActivateChild, CanLoad, Route, RouterStateSnapshot, UrlSegment, UrlTree } ` +
147+
`from '@angular/router';`;
148+
149+
expect(fileString).toContain(expectedImports);
150+
});
122151
});

0 commit comments

Comments
 (0)