Skip to content

Commit

Permalink
feat(schematics): remove creators option
Browse files Browse the repository at this point in the history
BREAKING CHANGE:

BEFORE:

Creating actions, reducers, and effects is possible without using the creators syntax is possible.

AFTER:

All schematics use the non-creators syntax to scaffold the code.
The option `--creators` (and `-c`) is removed from the schematic options.
  • Loading branch information
timdeschryver committed Feb 8, 2022
1 parent 5b54ac4 commit b60595d
Show file tree
Hide file tree
Showing 48 changed files with 403 additions and 862 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{ "argsIgnorePattern": "^_" }
{ "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }
],
"@typescript-eslint/naming-convention": [
"error",
Expand Down
3 changes: 0 additions & 3 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -671,9 +671,6 @@
{
"command": "cpy modules/schematics/src/**/files/**/*.* dist/ --parents"
},
{
"command": "cpy modules/schematics/src/**/creator-files/**/*.* dist/ --parents"
},
{
"command": "cpy modules/schematics/src/**/common-files/**/*.* dist/ --parents"
},
Expand Down
6 changes: 2 additions & 4 deletions modules/component-store/schematics-core/utility/ngrx-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,6 @@ export function omit<T extends { [key: string]: any }>(
.reduce((result, key) => Object.assign(result, { [key]: object[key] }), {});
}

export function getPrefix(options: { prefix?: string; creators?: boolean }) {
return options.creators
? stringUtils.camelize(options.prefix || 'load')
: stringUtils.capitalize(options.prefix || 'load');
export function getPrefix(options: { prefix?: string }) {
return stringUtils.camelize(options.prefix || 'load');
}
6 changes: 2 additions & 4 deletions modules/component/schematics-core/utility/ngrx-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,6 @@ export function omit<T extends { [key: string]: any }>(
.reduce((result, key) => Object.assign(result, { [key]: object[key] }), {});
}

export function getPrefix(options: { prefix?: string; creators?: boolean }) {
return options.creators
? stringUtils.camelize(options.prefix || 'load')
: stringUtils.capitalize(options.prefix || 'load');
export function getPrefix(options: { prefix?: string }) {
return stringUtils.camelize(options.prefix || 'load');
}
6 changes: 2 additions & 4 deletions modules/data/schematics-core/utility/ngrx-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,6 @@ export function omit<T extends { [key: string]: any }>(
.reduce((result, key) => Object.assign(result, { [key]: object[key] }), {});
}

export function getPrefix(options: { prefix?: string; creators?: boolean }) {
return options.creators
? stringUtils.camelize(options.prefix || 'load')
: stringUtils.capitalize(options.prefix || 'load');
export function getPrefix(options: { prefix?: string }) {
return stringUtils.camelize(options.prefix || 'load');
}
6 changes: 2 additions & 4 deletions modules/effects/schematics-core/utility/ngrx-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,6 @@ export function omit<T extends { [key: string]: any }>(
.reduce((result, key) => Object.assign(result, { [key]: object[key] }), {});
}

export function getPrefix(options: { prefix?: string; creators?: boolean }) {
return options.creators
? stringUtils.camelize(options.prefix || 'load')
: stringUtils.capitalize(options.prefix || 'load');
export function getPrefix(options: { prefix?: string }) {
return stringUtils.camelize(options.prefix || 'load');
}
6 changes: 2 additions & 4 deletions modules/entity/schematics-core/utility/ngrx-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,6 @@ export function omit<T extends { [key: string]: any }>(
.reduce((result, key) => Object.assign(result, { [key]: object[key] }), {});
}

export function getPrefix(options: { prefix?: string; creators?: boolean }) {
return options.creators
? stringUtils.camelize(options.prefix || 'load')
: stringUtils.capitalize(options.prefix || 'load');
export function getPrefix(options: { prefix?: string }) {
return stringUtils.camelize(options.prefix || 'load');
}
6 changes: 2 additions & 4 deletions modules/router-store/schematics-core/utility/ngrx-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,6 @@ export function omit<T extends { [key: string]: any }>(
.reduce((result, key) => Object.assign(result, { [key]: object[key] }), {});
}

export function getPrefix(options: { prefix?: string; creators?: boolean }) {
return options.creators
? stringUtils.camelize(options.prefix || 'load')
: stringUtils.capitalize(options.prefix || 'load');
export function getPrefix(options: { prefix?: string }) {
return stringUtils.camelize(options.prefix || 'load');
}
6 changes: 2 additions & 4 deletions modules/schematics-core/utility/ngrx-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,6 @@ export function omit<T extends { [key: string]: any }>(
.reduce((result, key) => Object.assign(result, { [key]: object[key] }), {});
}

export function getPrefix(options: { prefix?: string; creators?: boolean }) {
return options.creators
? stringUtils.camelize(options.prefix || 'load')
: stringUtils.capitalize(options.prefix || 'load');
export function getPrefix(options: { prefix?: string }) {
return stringUtils.camelize(options.prefix || 'load');
}
6 changes: 2 additions & 4 deletions modules/schematics/schematics-core/utility/ngrx-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,6 @@ export function omit<T extends { [key: string]: any }>(
.reduce((result, key) => Object.assign(result, { [key]: object[key] }), {});
}

export function getPrefix(options: { prefix?: string; creators?: boolean }) {
return options.creators
? stringUtils.camelize(options.prefix || 'load')
: stringUtils.capitalize(options.prefix || 'load');
export function getPrefix(options: { prefix?: string }) {
return stringUtils.camelize(options.prefix || 'load');
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as <%= classify(name) %>Actions from './<%= dasherize(name) %>.actions';
import * as from<%= classify(name) %> from './<%= dasherize(name) %>.actions';

describe('<%= classify(name) %>', () => {
it('should create an instance', () => {
expect(new <%= classify(name)%>Actions.<%= prefix %><%= classify(name) %>s()).toBeTruthy();
describe('<%= prefix %><%= classify(name) %>s', () => {
it('should return an action', () => {
expect(from<%= classify(name) %>.<%= prefix %><%= classify(name) %>s().type).toBe('[<%= classify(name) %>] <%= classify(prefix) %> <%= classify(name) %>s');
});
});
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
import { Action } from '@ngrx/store';
import { createAction, props } from '@ngrx/store';

export enum <%= classify(name) %>ActionTypes {
<%= prefix %><%= classify(name) %>s = '[<%= classify(name) %>] <%= prefix %> <%= classify(name) %>s',
<% if (api) { %><%= prefix %><%= classify(name) %>sSuccess = '[<%= classify(name) %>] <%= prefix %> <%= classify(name) %>s Success',<% } %>
<% if (api) { %><%= prefix %><%= classify(name) %>sFailure = '[<%= classify(name) %>] <%= prefix %> <%= classify(name) %>s Failure',<% } %>
}
export const <%= prefix %><%= classify(name) %>s = createAction(
'[<%= classify(name) %>] <%= classify(prefix) %> <%= classify(name) %>s'
);

export class <%= prefix %><%= classify(name) %>s implements Action {
readonly type = <%= classify(name) %>ActionTypes.<%= prefix %><%= classify(name) %>s;
}
<% if (api) { %>
export class <%= prefix %><%= classify(name) %>sSuccess implements Action {
readonly type = <%= classify(name) %>ActionTypes.<%= prefix %><%= classify(name) %>sSuccess;
constructor(public payload: { data: any }) { }
}
<% if (api) { %>export const <%= prefix %><%= classify(name) %>sSuccess = createAction(
'[<%= classify(name) %>] <%= classify(prefix) %> <%= classify(name) %>s Success',
props<{ data: any }>()
);<% } %>

export class <%= prefix %><%= classify(name) %>sFailure implements Action {
readonly type = <%= classify(name) %>ActionTypes.<%= prefix %><%= classify(name) %>sFailure;
constructor(public payload: { error: any }) { }
}
<% } %>
<% if (api) { %>export type <%= classify(name) %>Actions = <%= prefix %><%= classify(name) %>s | <%= prefix %><%= classify(name) %>sSuccess | <%= prefix %><%= classify(name) %>sFailure;<% } %>
<% if (!api) { %>export type <%= classify(name) %>Actions = <%= prefix %><%= classify(name) %>s;<% } %>
<% if (api) { %>export const <%= prefix %><%= classify(name) %>sFailure = createAction(
'[<%= classify(name) %>] <%= classify(prefix) %> <%= classify(name) %>s Failure',
props<{ error: any }>()
);<% } %>
156 changes: 44 additions & 112 deletions modules/schematics/src/action/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,111 +93,64 @@ describe('Action Schematic', () => {
).toBeGreaterThanOrEqual(0);
});

describe('action classes', () => {
const actionClassesDefaultOptions = { ...defaultOptions, creators: false };

it('should create an enum named "Foo"', async () => {
const tree = await schematicRunner
.runSchematicAsync('action', actionClassesDefaultOptions, appTree)
.toPromise();
const fileContent = tree.readContent(
`${projectPath}/src/app/foo.actions.ts`
);

expect(fileContent).toMatch(/export enum FooActionTypes/);
});

it('should create a class based on the provided name', async () => {
const tree = await schematicRunner
.runSchematicAsync('action', actionClassesDefaultOptions, appTree)
.toPromise();
const fileContent = tree.readContent(
`${projectPath}/src/app/foo.actions.ts`
);
it('should create a const for the action creator', async () => {
const options = {
...defaultOptions,
};

expect(fileContent).toMatch(/export class LoadFoos implements Action/);
});
const tree = await schematicRunner
.runSchematicAsync('action', options, appTree)
.toPromise();
const fileContent = tree.readContent(
`${projectPath}/src/app/foo.actions.ts`
);

it('should create the union type based on the provided name', async () => {
const tree = await schematicRunner
.runSchematicAsync('action', actionClassesDefaultOptions, appTree)
.toPromise();
const fileContent = tree.readContent(
`${projectPath}/src/app/foo.actions.ts`
);
expect(fileContent).toMatch(/export const loadFoos = createAction\(/);
expect(fileContent).toMatch(/\[Foo\] Load Foos'/);
});

expect(fileContent).toMatch(/export type FooActions = LoadFoos/);
});
it('should create success/error actions when the api flag is set', async () => {
const options = {
...defaultOptions,
api: true,
};

it('should create spec class with right imports', async () => {
const options = { ...actionClassesDefaultOptions };
const tree = await schematicRunner
.runSchematicAsync('action', options, appTree)
.toPromise();
const fileContent = tree.readContent(
`${projectPath}/src/app/foo.actions.spec.ts`
);
const tree = await schematicRunner
.runSchematicAsync('action', options, appTree)
.toPromise();
const fileContent = tree.readContent(
`${projectPath}/src/app/foo.actions.ts`
);

expect(fileContent).toMatch(/expect\(new FooActions.LoadFoos\(\)\)/);
});
expect(fileContent).toMatch(/export const loadFoos = createAction\(/);
expect(fileContent).toMatch(/\[Foo\] Load Foos Success/);
expect(fileContent).toMatch(/props<{ data: any }>\(\)/);
expect(fileContent).toMatch(/\[Foo\] Load Foos Failure/);
expect(fileContent).toMatch(/props<{ error: any }>\(\)/);
});

describe('action creators', () => {
const creatorDefaultOptions = { ...defaultOptions };
it.each(['load', 'delete', 'update'])(
'should create a action with prefix',
async (prefix) => {
const options = {
...defaultOptions,
prefix: prefix,
};

it('should create a const for the action creator', async () => {
const tree = await schematicRunner
.runSchematicAsync('action', creatorDefaultOptions, appTree)
.runSchematicAsync('action', options, appTree)
.toPromise();
const fileContent = tree.readContent(
`${projectPath}/src/app/foo.actions.ts`
);

expect(fileContent).toMatch(/export const loadFoos = createAction\(/);
expect(fileContent).toMatch(/\[Foo\] Load Foos'/);
});

it('should create success/error actions when the api flag is set', async () => {
const tree = await schematicRunner
.runSchematicAsync(
'action',
{ ...creatorDefaultOptions, api: true },
appTree
)
.toPromise();
const fileContent = tree.readContent(
`${projectPath}/src/app/foo.actions.ts`
expect(fileContent).toMatch(
new RegExp(`export const ${prefix}Foos = createAction`)
);

expect(fileContent).toMatch(/export const loadFoos = createAction\(/);
expect(fileContent).toMatch(/\[Foo\] Load Foos Success/);
expect(fileContent).toMatch(/props<{ data: any }>\(\)/);
expect(fileContent).toMatch(/\[Foo\] Load Foos Failure/);
expect(fileContent).toMatch(/props<{ error: any }>\(\)/);
});

it.each(['load', 'delete', 'update'])(
'should create a action with prefix',
async (prefix) => {
const tree = await schematicRunner
.runSchematicAsync(
'action',
{ ...creatorDefaultOptions, prefix: prefix },
appTree
)
.toPromise();
const fileContent = tree.readContent(
`${projectPath}/src/app/foo.actions.ts`
);
expect(fileContent).toMatch(
new RegExp(`export const ${prefix}Foos = createAction`)
);
expect(fileContent).toMatch(
new RegExp(`'\\[Foo] ${capitalize(prefix)} Foos'`)
);
}
);
});
expect(fileContent).toMatch(
new RegExp(`'\\[Foo] ${capitalize(prefix)} Foos'`)
);
}
);

describe('api', () => {
it('should group within an "actions" folder if group is set', async () => {
Expand Down Expand Up @@ -255,26 +208,5 @@ describe('Action Schematic', () => {
/export const loadFoosFailure = createAction\(\r?\n?\s*'\[Foo\] Load Foos Failure'\r?\n?\s*,/
);
});

it('should create the union type with success and failure based on the provided name, given api and creators false', async () => {
const tree = await schematicRunner
.runSchematicAsync(
'action',
{
...defaultOptions,
api: true,
creators: false,
},
appTree
)
.toPromise();
const fileContent = tree.readContent(
`${projectPath}/src/app/foo.actions.ts`
);

expect(fileContent).toMatch(
/export type FooActions = LoadFoos \| LoadFoosSuccess \| LoadFoosFailure/
);
});
});
});
Loading

0 comments on commit b60595d

Please sign in to comment.