mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-15 01:54:04 +08:00
feat(@schematics/angular): generate functional resolvers and guards by default
As Angular v15.2 deprecates class-based resolvers and guards, this commit switches the `functional` flag default value to `true`. BREAKING CHANGE: `ng g resolver` and `ng g guard` now generate a functional resolver or guard by default. It is still possible to generate a (deprecated) class-based resolver or guard by using `ng g resolver --no-functional` or `ng g guard --no-functional`.
This commit is contained in:
parent
2435b46560
commit
22fdd7da97
@ -43,8 +43,12 @@ describe('Guard Schematic', () => {
|
||||
appTree = await schematicRunner.runSchematic('application', appOptions, appTree);
|
||||
});
|
||||
|
||||
it('should create a guard', async () => {
|
||||
const tree = await schematicRunner.runSchematic('guard', defaultOptions, appTree);
|
||||
it('should create a (deprecated) class-based guard with --no-functional', async () => {
|
||||
const tree = await schematicRunner.runSchematic(
|
||||
'guard',
|
||||
{ ...defaultOptions, functional: false },
|
||||
appTree,
|
||||
);
|
||||
|
||||
const files = tree.files;
|
||||
expect(files).toContain('/projects/bar/src/app/foo.guard.spec.ts');
|
||||
@ -78,7 +82,7 @@ describe('Guard Schematic', () => {
|
||||
});
|
||||
|
||||
it('should respect the implements value', async () => {
|
||||
const options = { ...defaultOptions, implements: ['CanActivate'] };
|
||||
const options = { ...defaultOptions, implements: ['CanActivate'], functional: false };
|
||||
const tree = await schematicRunner.runSchematic('guard', options, appTree);
|
||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
||||
expect(fileString).toContain('CanActivate');
|
||||
@ -89,8 +93,8 @@ describe('Guard Schematic', () => {
|
||||
expect(fileString).not.toContain('canMatch');
|
||||
});
|
||||
|
||||
it('should respect the functional guard value', async () => {
|
||||
const options = { ...defaultOptions, implements: ['CanActivate'], functional: true };
|
||||
it('should generate a functional guard by default', async () => {
|
||||
const options = { ...defaultOptions, implements: ['CanActivate'] };
|
||||
const tree = await schematicRunner.runSchematic('guard', options, appTree);
|
||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
||||
expect(fileString).toContain('export const fooGuard: CanActivateFn = (route, state) => {');
|
||||
@ -101,7 +105,7 @@ describe('Guard Schematic', () => {
|
||||
});
|
||||
|
||||
it('should generate a helper function to execute the guard in a test', async () => {
|
||||
const options = { ...defaultOptions, implements: ['CanActivate'], functional: true };
|
||||
const options = { ...defaultOptions, implements: ['CanActivate'] };
|
||||
const tree = await schematicRunner.runSchematic('guard', options, appTree);
|
||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.spec.ts');
|
||||
expect(fileString).toContain('const executeGuard: CanActivateFn = (...guardParameters) => ');
|
||||
@ -111,7 +115,7 @@ describe('Guard Schematic', () => {
|
||||
});
|
||||
|
||||
it('should generate CanDeactivateFn with unknown functional guard', async () => {
|
||||
const options = { ...defaultOptions, implements: ['CanDeactivate'], functional: true };
|
||||
const options = { ...defaultOptions, implements: ['CanDeactivate'] };
|
||||
const tree = await schematicRunner.runSchematic('guard', options, appTree);
|
||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
||||
expect(fileString).toContain(
|
||||
@ -120,9 +124,9 @@ describe('Guard Schematic', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should respect the implements values', async () => {
|
||||
it('should respect the implements values in (deprecated) class-based guards', async () => {
|
||||
const implementationOptions = ['CanActivate', 'CanDeactivate', 'CanActivateChild'];
|
||||
const options = { ...defaultOptions, implements: implementationOptions };
|
||||
const options = { ...defaultOptions, implements: implementationOptions, functional: false };
|
||||
const tree = await schematicRunner.runSchematic('guard', options, appTree);
|
||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
||||
|
||||
@ -134,9 +138,9 @@ describe('Guard Schematic', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should add correct imports based on CanMatch implementation', async () => {
|
||||
it('should add correct imports based on CanMatch implementation in (deprecated) class-based guards', async () => {
|
||||
const implementationOptions = ['CanMatch'];
|
||||
const options = { ...defaultOptions, implements: implementationOptions };
|
||||
const options = { ...defaultOptions, implements: implementationOptions, functional: false };
|
||||
const tree = await schematicRunner.runSchematic('guard', options, appTree);
|
||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
||||
const expectedImports = `import { CanMatch, Route, UrlSegment, UrlTree } from '@angular/router';`;
|
||||
@ -144,9 +148,9 @@ describe('Guard Schematic', () => {
|
||||
expect(fileString).toContain(expectedImports);
|
||||
});
|
||||
|
||||
it('should add correct imports based on CanActivate implementation', async () => {
|
||||
it('should add correct imports based on CanActivate implementation in (deprecated) class-based guards', async () => {
|
||||
const implementationOptions = ['CanActivate'];
|
||||
const options = { ...defaultOptions, implements: implementationOptions };
|
||||
const options = { ...defaultOptions, implements: implementationOptions, functional: false };
|
||||
const tree = await schematicRunner.runSchematic('guard', options, appTree);
|
||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
||||
const expectedImports = `import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree } from '@angular/router';`;
|
||||
@ -155,7 +159,7 @@ describe('Guard Schematic', () => {
|
||||
});
|
||||
|
||||
it('should add correct imports based on canActivate functional guard', async () => {
|
||||
const options = { ...defaultOptions, implements: ['CanActivate'], functional: true };
|
||||
const options = { ...defaultOptions, implements: ['CanActivate'] };
|
||||
const tree = await schematicRunner.runSchematic('guard', options, appTree);
|
||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
||||
const expectedImports = `import { CanActivateFn } from '@angular/router';`;
|
||||
@ -163,9 +167,9 @@ describe('Guard Schematic', () => {
|
||||
expect(fileString).toContain(expectedImports);
|
||||
});
|
||||
|
||||
it('should add correct imports if multiple implementations was selected', async () => {
|
||||
it('should add correct imports if multiple implementations was selected in (deprecated) class-based guards', async () => {
|
||||
const implementationOptions = ['CanActivate', 'CanMatch', 'CanActivateChild'];
|
||||
const options = { ...defaultOptions, implements: implementationOptions };
|
||||
const options = { ...defaultOptions, implements: implementationOptions, functional: false };
|
||||
const tree = await schematicRunner.runSchematic('guard', options, appTree);
|
||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
||||
const expectedImports =
|
||||
|
@ -44,7 +44,7 @@
|
||||
"functional": {
|
||||
"type": "boolean",
|
||||
"description": "Specifies whether to generate a guard as a function.",
|
||||
"default": false
|
||||
"default": true
|
||||
},
|
||||
"implements": {
|
||||
"alias": "guardType",
|
||||
|
@ -41,11 +41,17 @@ describe('resolver Schematic', () => {
|
||||
appTree = await schematicRunner.runSchematic('application', appOptions, appTree);
|
||||
});
|
||||
|
||||
it('should create a resolver', async () => {
|
||||
const tree = await schematicRunner.runSchematic('resolver', defaultOptions, appTree);
|
||||
it('should create a (deprecated) class-based resolver with --no-functional', async () => {
|
||||
const tree = await schematicRunner.runSchematic(
|
||||
'resolver',
|
||||
{ ...defaultOptions, functional: false },
|
||||
appTree,
|
||||
);
|
||||
const files = tree.files;
|
||||
expect(files).toContain('/projects/bar/src/app/foo.resolver.spec.ts');
|
||||
expect(files).toContain('/projects/bar/src/app/foo.resolver.ts');
|
||||
const fileString = tree.readContent('/projects/bar/src/app/foo.resolver.ts');
|
||||
expect(fileString).toContain('export class FooResolver implements Resolve<boolean>');
|
||||
});
|
||||
|
||||
it('should respect the skipTests flag', async () => {
|
||||
@ -75,11 +81,7 @@ describe('resolver Schematic', () => {
|
||||
});
|
||||
|
||||
it('should create a functional resolver', async () => {
|
||||
const tree = await schematicRunner.runSchematic(
|
||||
'resolver',
|
||||
{ ...defaultOptions, functional: true },
|
||||
appTree,
|
||||
);
|
||||
const tree = await schematicRunner.runSchematic('resolver', defaultOptions, appTree);
|
||||
const fileString = tree.readContent('/projects/bar/src/app/foo.resolver.ts');
|
||||
expect(fileString).toContain(
|
||||
'export const fooResolver: ResolveFn<boolean> = (route, state) => {',
|
||||
@ -87,11 +89,7 @@ describe('resolver Schematic', () => {
|
||||
});
|
||||
|
||||
it('should create a helper function to run a functional resolver in a test', async () => {
|
||||
const tree = await schematicRunner.runSchematic(
|
||||
'resolver',
|
||||
{ ...defaultOptions, functional: true },
|
||||
appTree,
|
||||
);
|
||||
const tree = await schematicRunner.runSchematic('resolver', defaultOptions, appTree);
|
||||
const fileString = tree.readContent('/projects/bar/src/app/foo.resolver.spec.ts');
|
||||
expect(fileString).toContain(
|
||||
'const executeResolver: ResolveFn<boolean> = (...resolverParameters) => ',
|
||||
|
@ -28,7 +28,7 @@
|
||||
"functional": {
|
||||
"type": "boolean",
|
||||
"description": "Creates the resolver as a `ResolveFn`.",
|
||||
"default": false
|
||||
"default": true
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
|
@ -9,7 +9,10 @@ export default async function () {
|
||||
await ng('generate', 'guard', 'test-guard');
|
||||
await expectFileToExist(guardDir);
|
||||
await expectFileToExist(join(guardDir, 'test-guard.guard.ts'));
|
||||
await expectFileToMatch(join(guardDir, 'test-guard.guard.ts'), /implements CanActivate/);
|
||||
await expectFileToMatch(
|
||||
join(guardDir, 'test-guard.guard.ts'),
|
||||
/export const testGuardGuard: CanActivateFn/,
|
||||
);
|
||||
await expectFileToExist(join(guardDir, 'test-guard.guard.spec.ts'));
|
||||
await ng('test', '--watch=false');
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ export default async function () {
|
||||
await ng('generate', 'guard', 'match', '--implements=CanMatch');
|
||||
await expectFileToExist(guardDir);
|
||||
await expectFileToExist(join(guardDir, 'match.guard.ts'));
|
||||
await expectFileToMatch(join(guardDir, 'match.guard.ts'), /implements CanMatch/);
|
||||
await expectFileToMatch(join(guardDir, 'match.guard.ts'), /export const matchGuard: CanMatch/);
|
||||
await expectFileToExist(join(guardDir, 'match.guard.spec.ts'));
|
||||
await ng('test', '--watch=false');
|
||||
}
|
||||
|
@ -6,12 +6,14 @@ export default async function () {
|
||||
// Does not create a sub directory.
|
||||
const guardDir = join('src', 'app');
|
||||
|
||||
// multiple implements are only supported in (deprecated) class-based guards
|
||||
await ng(
|
||||
'generate',
|
||||
'guard',
|
||||
'multiple',
|
||||
'--implements=CanActivate',
|
||||
'--implements=CanDeactivate',
|
||||
'--no-functional',
|
||||
);
|
||||
await expectFileToExist(guardDir);
|
||||
await expectFileToExist(join(guardDir, 'multiple.guard.ts'));
|
||||
|
Loading…
x
Reference in New Issue
Block a user