Skip to content

Commit

Permalink
refactor: cleanup schematics
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitry-stepanenko committed Aug 14, 2023
1 parent 1a9445b commit ffa184b
Show file tree
Hide file tree
Showing 74 changed files with 564 additions and 676 deletions.
22 changes: 11 additions & 11 deletions packages/store/schematics/collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,34 @@
"$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"store": {
"factory": "./factories/store/store.factory#store",
"factory": "./src/store/store.factory#store",
"description": "Create a NGXS full store",
"aliases": ["ngxs-store"],
"schema": "./factories/store/schema.json"
"schema": "./src/store/schema.json"
},
"state": {
"factory": "./factories/state/state.factory#state",
"factory": "./src/state/state.factory#state",
"description": "Create a NGXS state",
"aliases": ["ngxs-state"],
"schema": "./factories/state/schema.json"
"schema": "./src/state/schema.json"
},
"actions": {
"factory": "./factories/actions/actions.factory#actions",
"factory": "./src/actions/actions.factory#actions",
"description": "Create a NGXS actions",
"aliases": ["ngxs-actions"],
"schema": "./factories/actions/schema.json"
"schema": "./src/actions/schema.json"
},
"starter-kit": {
"factory": "./factories/starter-kit/starter-kit.factory#starterKit",
"description": "Create a NGXS starter kit with simple or best practise type",
"factory": "./src/starter-kit/starter-kit.factory#starterKit",
"description": "Create a NGXS starter kit with simple or best practice type",
"aliases": ["ngxs-sk"],
"schema": "./factories/starter-kit/schema.json"
"schema": "./src/starter-kit/schema.json"
},
"ng-add": {
"factory": "./factories/ng-add/ng-add.factory#ngAdd",
"factory": "./src/ng-add/ng-add.factory#ngAdd",
"description": "Add Ngxs Store and plugins in package.json",
"aliases": ["ngxs-init"],
"schema": "./factories/ng-add/schema.json"
"schema": "./src/ng-add/schema.json"
}
}
}

This file was deleted.

76 changes: 0 additions & 76 deletions packages/store/schematics/factories/ng-add/ng-add.factory.spec.ts

This file was deleted.

This file was deleted.

8 changes: 0 additions & 8 deletions packages/store/schematics/factories/state/state.factory.ts

This file was deleted.

8 changes: 0 additions & 8 deletions packages/store/schematics/factories/store/store.factory.ts

This file was deleted.

30 changes: 30 additions & 0 deletions packages/store/schematics/src/actions/actions.factory.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import { workspaceRoot } from '@nrwl/devkit';

import * as path from 'path';

import { ActionsSchema } from './actions.schema';

describe('NGXS Actions', () => {
const runner: SchematicTestRunner = new SchematicTestRunner(
'.',
path.join(workspaceRoot, 'packages/store/schematics/collection.json')
);
it('should create action in a folder by default', async () => {
const options: ActionsSchema = {
name: 'todos'
};
const tree: UnitTestTree = await runner.runSchematicAsync('actions', options).toPromise();
const files: string[] = tree.files;
expect(files).toEqual(['/todos/todos.actions.ts']);
});
it('should create action without folder if "flat" is set to "true"', async () => {
const options: ActionsSchema = {
name: 'todos',
flat: true
};
const tree: UnitTestTree = await runner.runSchematicAsync('actions', options).toPromise();
const files: string[] = tree.files;
expect(files).toEqual(['/todos.actions.ts']);
});
});
21 changes: 21 additions & 0 deletions packages/store/schematics/src/actions/actions.factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Rule, SchematicsException, url } from '@angular-devkit/schematics';
import { ActionsSchema } from './actions.schema';
import { generateFiles } from '../utils/generate-utils';
import { isEmpty } from '../utils/common/properties';
import { normalizeBaseOptions } from '../utils/normalize-options';
import { join } from 'path';

export function actions(options: ActionsSchema): Rule {
if (isEmpty(options.name)) {
throw new SchematicsException('Invalid options, "name" is required.');
}

const normalizedOptions = normalizeBaseOptions(options);
const path = options.flat
? normalizedOptions.path
: join(normalizedOptions.path, normalizedOptions.name);

return generateFiles(url('./files'), path, {
name: normalizedOptions.name
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface ActionsSchema {
*/
path?: string;
/**
* The source root path
* Flag to indicate if a dir is created.
*/
sourceRoot?: string;
flat?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
"format": "path",
"description": "The path to create the actions."
},
"sourceRoot": {
"type": "string",
"format": "path",
"description": "The source root path"
"flat": {
"type": "boolean",
"default": false,
"description": "Flag to indicate if a dir is created."
}
},
"required": ["name"]
Expand Down
152 changes: 152 additions & 0 deletions packages/store/schematics/src/ng-add/ng-add.factory.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import { Tree } from '@angular-devkit/schematics';
import { workspaceRoot } from '@nrwl/devkit';
import { join } from 'path';
import { Schema as ApplicationOptions } from '@schematics/angular/application/schema';
import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema';

import { LIBRARIES } from '../utils/common/lib.config';
import { NgxsPackageSchema } from './ng-add.schema';

describe('Ngxs ng-add Schematic', () => {
const angularSchematicRunner = new SchematicTestRunner(
'@schematics/angular',
join(workspaceRoot, 'node_modules/@schematics/angular/collection.json')
);

const ngxsSchematicRunner = new SchematicTestRunner(
'@ngxs/store/schematics',
join(workspaceRoot, 'packages/store/schematics/collection.json')
);

const defaultOptions: NgxsPackageSchema = {
skipInstall: false,
packages: [],
name: ''
};

const workspaceOptions: WorkspaceOptions = {
name: 'workspace',
newProjectRoot: 'projects',
version: '1.0.0'
};

const appOptions: ApplicationOptions = {
name: 'foo',
inlineStyle: false,
inlineTemplate: false,
routing: true,
skipTests: false,
skipPackageJson: false
};

let appTree: UnitTestTree;
beforeEach(async () => {
appTree = await angularSchematicRunner
.runSchematicAsync('workspace', workspaceOptions)
.toPromise();
appTree = await angularSchematicRunner
.runSchematicAsync('application', appOptions, appTree)
.toPromise();
});

it('should not import Ngxs module into the application module if a project name is not provided', async () => {
// Arrange
const options: NgxsPackageSchema = { ...defaultOptions };
// Act
const tree = await ngxsSchematicRunner
.runSchematicAsync('ngxs-init', options, appTree)
.toPromise();
// Assert
const content = tree.readContent('/projects/foo/src/app/app.module.ts');
expect(content).not.toMatch(/import { NgxsModule } from '@ngxs\/store'/);
expect(content).not.toMatch(/imports: \[[^\]]*NgxsModule[^\]]*\]/m);
});

it('should import Ngxs module into the application module if a project name is provided', async () => {
// Arrange
const options: NgxsPackageSchema = { ...defaultOptions, name: 'foo' };
// Act
const tree = await ngxsSchematicRunner
.runSchematicAsync('ngxs-init', options, appTree)
.toPromise();
// Assert
const content = tree.readContent('/projects/foo/src/app/app.module.ts');
expect(content).toMatch(/import { NgxsModule } from '@ngxs\/store'/);
expect(content).toMatch(/imports: \[[^\]]*NgxsModule.forRoot\(\[\],[^\]]*\]/m);
expect(content).toMatch(
/imports: \[[^\]]*NgxsModule.forRoot\(\[\], \{ developmentMode\: \!environment\.production, selectorOptions\: \{ suppressErrors\: false, injectContainerState\: false \} \}\)[^\]]*\]/m
);
});
});

describe('ng-add package in package.json', () => {
const runner: SchematicTestRunner = new SchematicTestRunner(
'schematics',
join(workspaceRoot, 'packages/store/schematics/collection.json')
);
let testTree: UnitTestTree;
let inputTree: Tree;

beforeEach(() => {
inputTree = Tree.empty();
inputTree.create(
'/package.json',
JSON.stringify({
name: 'test',
version: '0.0.0',
license: 'MIT',
scripts: {
ng: 'ng',
start: 'ng serve',
build: 'ng build',
test: 'ng test',
lint: 'ng lint',
e2e: 'ng e2e'
},
private: true,
dependencies: {}
})
);
});

it('should add ngxs store in package.json', async () => {
testTree = await runner.runSchematicAsync('ng-add', {}, inputTree).toPromise();
const packageJsonText = testTree.readContent('/package.json');
const packageJson = JSON.parse(packageJsonText);
expect(Object.keys(packageJson.dependencies)).toEqual([LIBRARIES.STORE]);
expect(packageJson.devDependencies).toBeUndefined();
});

it('should add ngxs store with provided plugins in package.json', async () => {
const packages = [LIBRARIES.DEVTOOLS, LIBRARIES.LOGGER];
const options: NgxsPackageSchema = { packages };
testTree = await runner.runSchematicAsync('ng-add', options, inputTree).toPromise();
const packageJsonText = testTree.readContent('/package.json');
const packageJson = JSON.parse(packageJsonText);
expect(Object.keys(packageJson.dependencies).sort()).toEqual(
packages.concat(LIBRARIES.STORE).sort()
);
expect(packageJson.devDependencies).toBeUndefined();
});

it('should add ngxs store with all plugins in package.json', async () => {
const packages = Object.values(LIBRARIES).filter(v => v !== LIBRARIES.STORE);
const options: NgxsPackageSchema = { packages };
testTree = await runner.runSchematicAsync('ng-add', options, inputTree).toPromise();
const packageJsonText = testTree.readContent('/package.json');
const packageJson = JSON.parse(packageJsonText);
expect(Object.keys(packageJson.dependencies).sort()).toEqual(
packages.concat(LIBRARIES.STORE).sort()
);
expect(packageJson.devDependencies).toBeUndefined();
});

it('should not attempt to add non-existent package', async () => {
const packages = ['who-am-i'];
const options: NgxsPackageSchema = { packages };
await expect(
runner.runSchematicAsync('ng-add', options, inputTree).toPromise()
).rejects.toThrow();
});
});
Loading

0 comments on commit ffa184b

Please sign in to comment.