Skip to content

Commit 126d0a1

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

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

Lines changed: 1 addition & 1 deletion
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

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

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

packages/schematics/angular/guard/index_spec.ts

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ describe('Guard Schematic', () => {
3737
let appTree: UnitTestTree;
3838
beforeEach(async () => {
3939
appTree = await schematicRunner.runSchematicAsync('workspace', workspaceOptions).toPromise();
40-
appTree = await schematicRunner.runSchematicAsync('application', appOptions, appTree)
40+
appTree = await schematicRunner
41+
.runSchematicAsync('application', appOptions, appTree)
4142
.toPromise();
4243
});
4344

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

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

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

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

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

10198
// Should contain all implementations
@@ -108,8 +105,7 @@ describe('Guard Schematic', () => {
108105

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

0 commit comments

Comments
 (0)