Skip to content

Commit

Permalink
fix(@schematics/angular): avoid unuse imports for canLoad guard gener…
Browse files Browse the repository at this point in the history
…ation
  • Loading branch information
billyjov authored and alan-agius4 committed Apr 28, 2021
1 parent 0597a1a commit 3081524
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { <%= implementationImports %>ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { <%= implementationImports %> } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
Expand Down
19 changes: 16 additions & 3 deletions packages/schematics/angular/guard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,25 @@ export default function (options: GuardOptions): Rule {
const implementations = options.implements
.map(implement => implement === 'CanDeactivate' ? 'CanDeactivate<unknown>' : implement)
.join(', ');
let implementationImports = `${options.implements.join(', ')}, `;
// As long as we aren't in IE... ;)
const commonRouterNameImports = ['ActivatedRouteSnapshot', 'RouterStateSnapshot'];
const routerNamedImports: string[] = [...options.implements, 'UrlTree'];

if (options.implements.includes(GuardInterface.CanLoad)) {
implementationImports = `${implementationImports}Route, UrlSegment, `;
routerNamedImports.push(
'Route',
'UrlSegment',
);

if (options.implements.length > 1) {
routerNamedImports.push(...commonRouterNameImports);
}
} else {
routerNamedImports.push(...commonRouterNameImports);
}

routerNamedImports.sort();

const implementationImports = routerNamedImports.join(', ');
const parsedPath = parseName(options.path, options.name);
options.name = parsedPath.name;
options.path = parsedPath.path;
Expand Down
61 changes: 45 additions & 16 deletions packages/schematics/angular/guard/index_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ describe('Guard Schematic', () => {
let appTree: UnitTestTree;
beforeEach(async () => {
appTree = await schematicRunner.runSchematicAsync('workspace', workspaceOptions).toPromise();
appTree = await schematicRunner.runSchematicAsync('application', appOptions, appTree)
appTree = await schematicRunner
.runSchematicAsync('application', appOptions, appTree)
.toPromise();
});

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

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

const tree = await schematicRunner.runSchematicAsync('guard', options, appTree)
.toPromise();
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
const files = tree.files;
expect(files).toContain('/projects/bar/src/app/foo/foo.guard.spec.ts');
expect(files).toContain('/projects/bar/src/app/foo/foo.guard.ts');
Expand All @@ -74,15 +74,13 @@ describe('Guard Schematic', () => {
const config = JSON.parse(appTree.readContent('/angular.json'));
config.projects.bar.sourceRoot = 'projects/bar/custom';
appTree.overwrite('/angular.json', JSON.stringify(config, null, 2));
appTree = await schematicRunner.runSchematicAsync('guard', defaultOptions, appTree)
.toPromise();
appTree = await schematicRunner.runSchematicAsync('guard', defaultOptions, appTree).toPromise();
expect(appTree.files).toContain('/projects/bar/custom/app/foo.guard.ts');
});

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

it('should respect the implements values', async () => {
const implementationOptions = ['CanActivate', 'CanLoad', 'CanActivateChild'];
const options = { ...defaultOptions, implements: implementationOptions};
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree)
.toPromise();
const options = { ...defaultOptions, implements: implementationOptions };
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');

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

it('should use CanActivate if no implements value', async () => {
const options = { ...defaultOptions, implements: undefined };
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree)
.toPromise();
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
expect(fileString).toContain('CanActivate');
expect(fileString).toContain('canActivate');
Expand All @@ -119,4 +115,37 @@ describe('Guard Schematic', () => {
expect(fileString).not.toContain('CanLoad');
expect(fileString).not.toContain('canLoad');
});

it('should add correct imports based on CanLoad implementation', async () => {
const implementationOptions = ['CanLoad'];
const options = { ...defaultOptions, implements: implementationOptions };
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
const expectedImports = `import { CanLoad, Route, UrlSegment, UrlTree } from '@angular/router';`;

expect(fileString).toContain(expectedImports);
});

it('should add correct imports based on CanActivate implementation', async () => {
const implementationOptions = ['CanActivate'];
const options = { ...defaultOptions, implements: implementationOptions };
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
const expectedImports = `import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree } from '@angular/router';`;

expect(fileString).toContain(expectedImports);
});

it('should add correct imports if multiple implementations was selected', async () => {
const implementationOptions = ['CanActivate', 'CanLoad', 'CanActivateChild'];
const options = { ...defaultOptions, implements: implementationOptions };
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
const expectedImports =
`import ` +
`{ ActivatedRouteSnapshot, CanActivate, CanActivateChild, CanLoad, Route, RouterStateSnapshot, UrlSegment, UrlTree } ` +
`from '@angular/router';`;

expect(fileString).toContain(expectedImports);
});
});

0 comments on commit 3081524

Please sign in to comment.