Skip to content

Commit

Permalink
fix(schematics): ngrx schematics should generate enhanced ngrx files
Browse files Browse the repository at this point in the history
@nrwl/schematics no longer uses the @ngrx/schematics to generate NgRx feature files.
*  `ngrx/files/__directory__` templates are used
*  Templates replicate the simple outputs generated from @ngrx/schematics:feature
*  Templates add significant Nx enhancements.

The following standard files will be scaffolded:
* `<feature>.actions.ts`
* `<feature>.effects.ts` + `<feature>.effects.spec.ts`
* `<feature>.reducer.ts` + `<feature>.reducer.spec.ts`

The following new files will also be scaffolded:
* `<feature>.selectors.ts` +  `<feature>.selectors.spec.ts`

Changes include:

* Change the action/enums to generate a trio of enums for each *feature*: `Load<Feature>`, `<Feature>Loaded`, and `<Feature>LoadError`
* Add code generators for `<feature>.selectors.ts`
* Add code generators for unit and integration testing `*.spec.ts` files
* Update the public barrel [`index.ts`] when adding ngrx to a library
* Use `StoreModule.forFeature()` when adding ngrx feature (without using the `--root` option)
* Use the Effect to respond tp `load<Feature>$` and dispatch `<Feature>Loaded` or `<Feature>LoadError`
* Update the Action to export `<feature>Actions` map of all action classes
* fix `ng-add.test.ts` tests for latest Angular CLI scaffolding
* fix `application.spec.ts` expect fails

Fixes #472,  Fixes #618,  Fixes #317,  Fixes #561, Refs #380.
  • Loading branch information
ThomasBurleson authored and vsavkin committed Jul 22, 2018
1 parent a55412c commit 04e99b0
Show file tree
Hide file tree
Showing 41 changed files with 2,327 additions and 2,245 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -7,4 +7,5 @@ test
.DS_Store
tmp
*.log
.ng_pkg_build
.ng_pkg_build
jest.debug.config.js
9 changes: 5 additions & 4 deletions e2e/schematics/ng-add.test.ts
Expand Up @@ -97,10 +97,6 @@ describe('Nrwl Convert to Nx Workspace', () => {
updatedPackageJson.dependencies['@ngrx/store-devtools']
).toBeDefined();
expect(updatedPackageJson.dependencies['rxjs-compat']).toBeDefined();

expect(
updatedPackageJson.devDependencies['@ngrx/schematics']
).toBeDefined();
expect(updatedPackageJson.devDependencies['@angular/cli']).toBeDefined();

const nxJson = readJson('nx.json');
Expand Down Expand Up @@ -203,6 +199,11 @@ describe('Nrwl Convert to Nx Workspace', () => {
);
expect(updatedAngularCLIJson.projects['proj-e2e'].architect.e2e).toEqual({
builder: '@angular-devkit/build-angular:protractor',
configurations: {
production: {
devServerTarget: 'proj:serve:production'
}
},
options: {
protractorConfig: 'apps/proj-e2e/protractor.conf.js',
devServerTarget: 'proj:serve'
Expand Down
17 changes: 15 additions & 2 deletions e2e/schematics/ngrx.test.ts
Expand Up @@ -6,12 +6,25 @@ describe('ngrx', () => {
() => {
newProject();
newApp('myapp');

// Generate root ngrx state management
runCLI(
'generate ngrx users --module=apps/myapp/src/app/app.module.ts --root --collection=@nrwl/schematics'
);

// Generate feature library and ngrx state within that library
runCLI('g @nrwl/schematics:lib feature-flights --prefix=fl');
runCLI(
'generate ngrx app --module=apps/myapp/src/app/app.module.ts --root --collection=@nrwl/schematics'
'generate ngrx flights --module=libs/feature-flights/src/lib/feature-flights.module.ts --collection=@nrwl/schematics'
);

expect(runCLI('build')).toContain('chunk {main} main.js,');
expect(runCLI('test --no-watch')).toContain('Executed 5 of 5 SUCCESS');
expect(runCLI('test myapp --no-watch')).toContain(
'Executed 10 of 10 SUCCESS'
);
expect(runCLI('test feature-flights --no-watch')).toContain(
'Executed 8 of 8 SUCCESS'
);
},
1000000
);
Expand Down
5 changes: 5 additions & 0 deletions e2e/utils.ts
Expand Up @@ -65,6 +65,11 @@ export function copyMissingPackages(): void {
`rm -rf tmp/${projectName}/node_modules/@angular-devkit/core/node_modules`
);

execSync(`rm tmp/${projectName}/node_modules/.bin/semver`);
execSync(
`cp -a node_modules/.bin/semver tmp/${projectName}/node_modules/.bin/semver`
);

const libIndex = `./tmp/${projectName}/node_modules/@schematics/angular/library/index.js`;
const content = readFileSync(libIndex).toString();
const updatedContent = content.replace(
Expand Down
30 changes: 17 additions & 13 deletions package.json
Expand Up @@ -17,9 +17,10 @@
"checkformat": "prettier \"{packages,e2e}/**/*.ts\" --list-different"
},
"devDependencies": {
"jasmine-marbles": "0.3.1",
"@angular-devkit/build-angular": "^0.6.8",
"@angular-devkit/core": "^0.6.1",
"@angular-devkit/schematics": "^0.6.1",
"@angular/cli": "6.0.1",
"@angular-devkit/build-angular": "~0.6.1",
"@angular/common": "6.0.1",
"@angular/compiler": "6.0.1",
"@angular/compiler-cli": "6.0.1",
Expand All @@ -28,16 +29,15 @@
"@angular/platform-browser-dynamic": "6.0.1",
"@angular/router": "6.0.1",
"@angular/upgrade": "6.0.1",
"@ngrx/effects": "5.2.0",
"@ngrx/router-store": "5.2.0",
"@ngrx/schematics": "5.2.0",
"@ngrx/store": "5.2.0",
"@ngrx/store-devtools": "5.2.0",
"@ngrx/effects": "6.0.1",
"@ngrx/router-store": "6.0.1",
"@ngrx/schematics": "6.0.1",
"@ngrx/store": "6.0.1",
"@ngrx/store-devtools": "6.0.1",
"@schematics/angular": "^0.6.1",
"@types/jasmine": "~2.8.6",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"@types/prettier": "^1.10.0",
"@types/yargs": "^11.0.0",
"angular": "1.6.6",
Expand All @@ -47,7 +47,11 @@
"fs-extra": "5.0.0",
"graphviz": "^0.0.8",
"husky": "^0.14.3",
"jest": "20.0.4",
"jasmine-core": "~2.99.1",
"jasmine-marbles": "0.3.1",
"jasmine-spec-reporter": "~4.2.1",
"jest": "^23.4.0",
"jest-jasmine2": "^23.4.1",
"karma": "~1.7.1",
"karma-chrome-launcher": "~2.2.0",
"karma-jasmine": "~1.1.1",
Expand All @@ -58,8 +62,8 @@
"precise-commits": "1.0.2",
"prettier": "1.10.2",
"release-it": "^7.4.0",
"rxjs": "^6.0.0",
"rxjs-compat": "^6.0.0",
"rxjs": "^6.1.0",
"rxjs-compat": "^6.1.0",
"semver": "5.4.1",
"strip-json-comments": "2.0.1",
"tmp": "0.0.33",
Expand All @@ -68,7 +72,7 @@
"viz.js": "^1.8.1",
"yargs": "^11.0.0",
"yargs-parser": "10.0.0",
"zone.js": "^0.8.19"
"zone.js": "^0.8.26"
},
"author": "Victor Savkin",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/bazel/package.json
Expand Up @@ -9,7 +9,7 @@
"license": "MIT",
"schematics": "./src/collection.json",
"dependencies": {
"@ngrx/schematics": "5.2.0",
"@ngrx/schematics": "6.0.1",
"@schematics/angular": "0.4.6",
"app-root-path": "^2.0.1",
"npm-run-all": "4.1.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/bazel/src/collection.json
@@ -1,7 +1,7 @@
{
"name": "nx-bazel",
"version": "0.1",
"extends": "@ngrx/schematics",
"extends": "@schematics/angular",
"schematics": {
"application": {
"factory": "./collection/application",
Expand Down
Expand Up @@ -23,6 +23,5 @@
"node_modules/@angular/tsc-wrapped/**",
"node_modules/@nrwl/bazel/**",
"node_modules/@nrwl/schematics/**",
"node_modules/@ngrx/schematics/**",
]
}
}
Expand Up @@ -38,10 +38,10 @@
"rxjs": "<%= rxjsVersion %>",
"zone.js": "^0.8.19",
"@nrwl/nx": "<%= nxVersion %>",
"@ngrx/effects": "5.2.0",
"@ngrx/router-store": "5.2.0",
"@ngrx/store": "5.2.0",
"@ngrx/store-devtools": "5.2.0"
"@ngrx/effects": "<%= ngrxVersion %>",
"@ngrx/router-store": "<%= ngrxVersion %>",
"@ngrx/store": "<%= ngrxVersion %>",
"@ngrx/store-devtools": "<%= ngrxVersion %>"
},
"devDependencies": {
"@angular/cli": "<%= angularCliVersion %>",
Expand Down
9 changes: 4 additions & 5 deletions packages/schematics/migrations/update-6-0-0/update-6-0-0.ts
Expand Up @@ -385,10 +385,10 @@ const updatePackageJson = updateJsonInTree('package.json', json => {
'zone.js': '^0.8.26',
'core-js': '^2.5.4',
// End Angular Versions
'@ngrx/effects': '5.2.0',
'@ngrx/router-store': '5.2.0',
'@ngrx/store': '5.2.0',
'@ngrx/store-devtools': '5.2.0',
'@ngrx/effects': '6.0.1',
'@ngrx/router-store': '6.0.1',
'@ngrx/store': '6.0.1',
'@ngrx/store-devtools': '6.0.1',
'@nrwl/nx': '6.0.2'
};
json.devDependencies = {
Expand All @@ -397,7 +397,6 @@ const updatePackageJson = updateJsonInTree('package.json', json => {
'@angular/compiler-cli': '6.0.1',
'@angular/language-service': '6.0.1',
// End Angular Versions
'@ngrx/schematics': '5.2.0',
typescript: '2.7.2',
'jasmine-marbles': '0.3.1',
'@types/jasmine': '~2.8.6',
Expand Down
9 changes: 4 additions & 5 deletions packages/schematics/package.json
@@ -1,6 +1,6 @@
{
"name": "@nrwl/schematics",
"version": "0.0.1",
"version": "0.0.2",
"description": "Nrwl Extensions for Angular: Schematics",
"repository": {
"type": "git",
Expand All @@ -20,7 +20,6 @@
},
"main": "index.js",
"types": "index.d.js",
"peerDependencies": {},
"author": "Victor Savkin",
"license": "MIT",
"bugs": {
Expand All @@ -34,7 +33,6 @@
"migrations": "./migrations/migrations.json"
},
"dependencies": {
"@ngrx/schematics": "5.2.0",
"@types/yargs": "^11.0.0",
"app-root-path": "^2.0.1",
"cosmiconfig": "4.0.0",
Expand All @@ -50,7 +48,8 @@
"yargs": "^11.0.0"
},
"peerDependencies": {
"@schematics/angular": "^0.6.0",
"@angular-devkit/schematics": "^0.6.0"
"@schematics/angular": "^0.6.8",
"@angular-devkit/core": "^0.6.8",
"@angular-devkit/schematics": "^0.6.8"
}
}
2 changes: 1 addition & 1 deletion packages/schematics/src/collection.json
@@ -1,7 +1,7 @@
{
"name": "nx",
"version": "0.1",
"extends": "@ngrx/schematics",
"extends": "@schematics/angular",
"schematics": {
"ng-add": {
"factory": "./collection/ng-add",
Expand Down
108 changes: 58 additions & 50 deletions packages/schematics/src/collection/application/application.spec.ts
Expand Up @@ -99,27 +99,33 @@ describe('app', () => {
{ name: 'myApp' },
appTree
);
expect(
JSON.parse(noPrefix.read('angular.json').toString()).projects['my-app']
.prefix
).toEqual('proj');
expect(
noPrefix.read('apps/my-app-e2e/src/app.e2e-spec.ts').toString()
).toContain('Welcome to proj!');

const withPrefix = schematicRunner.runSchematic(
'app',
{ name: 'myApp', prefix: 'custom' },
appTree
);
expect(
JSON.parse(withPrefix.read('angular.json').toString()).projects[
'my-app'
].prefix
).toEqual('custom');
expect(
withPrefix.read('apps/my-app-e2e/src/app.e2e-spec.ts').toString()
).toContain('Welcome to custom!');

// Testing without prefix

let appE2eSpec = noPrefix
.read('apps/my-app-e2e/src/app.e2e-spec.ts')
.toString();
let angularJson = JSON.parse(noPrefix.read('angular.json').toString());
let myAppPrefix = angularJson.projects['my-app'].prefix;

expect(myAppPrefix).toEqual('proj');
expect(appE2eSpec).toContain('Welcome to my-app!');

// Testing WITH prefix

appE2eSpec = withPrefix
.read('apps/my-app-e2e/src/app.e2e-spec.ts')
.toString();
angularJson = JSON.parse(withPrefix.read('angular.json').toString());
myAppPrefix = angularJson.projects['my-app'].prefix;

expect(myAppPrefix).toEqual('custom');
expect(appE2eSpec).toContain('Welcome to my-app!');
});
});

Expand Down Expand Up @@ -161,48 +167,50 @@ describe('app', () => {
});

it('should generate files', () => {
const hasJsonValue = ({ path, expectedValue, lookupFn }) => {
const content = getFileContent(tree, path);
const config = JSON.parse(stripJsonComments(content));

expect(lookupFn(config)).toEqual(expectedValue);
};
const tree = schematicRunner.runSchematic(
'app',
{ name: 'myApp', directory: 'myDir' },
appTree
);
expect(tree.exists(`apps/my-dir/my-app/karma.conf.js`)).toBeTruthy();
expect(tree.exists('apps/my-dir/my-app/src/main.ts')).toBeTruthy();
expect(
tree.exists('apps/my-dir/my-app/src/app/app.module.ts')
).toBeTruthy();
expect(
tree.exists('apps/my-dir/my-app/src/app/app.component.ts')
).toBeTruthy();
expect(
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.module.ts')
).toContain('class AppModule');

const tsconfigApp = JSON.parse(
stripJsonComments(
getFileContent(tree, 'apps/my-dir/my-app/tsconfig.app.json')
)
);
expect(tsconfigApp.compilerOptions.outDir).toEqual(
'../../../dist/out-tsc/apps/my-dir/my-app'
);
const appModulePath = 'apps/my-dir/my-app/src/app/app.module.ts';
expect(getFileContent(tree, appModulePath)).toContain('class AppModule');

const tslintJson = JSON.parse(
stripJsonComments(
getFileContent(tree, 'apps/my-dir/my-app/tslint.json')
)
);
expect(tslintJson.extends).toEqual('../../../tslint.json');
// Make sure these exist
[
`apps/my-dir/my-app/karma.conf.js`,
'apps/my-dir/my-app/src/main.ts',
'apps/my-dir/my-app/src/app/app.module.ts',
'apps/my-dir/my-app/src/app/app.component.ts',
'apps/my-dir/my-app-e2e/src/app.po.ts'
].forEach(path => {
expect(tree.exists(path)).toBeTruthy();
});

expect(tree.exists('apps/my-dir/my-app-e2e/src/app.po.ts')).toBeTruthy();
const tsconfigE2E = JSON.parse(
stripJsonComments(
getFileContent(tree, 'apps/my-dir/my-app-e2e/tsconfig.e2e.json')
)
);
expect(tsconfigE2E.compilerOptions.outDir).toEqual(
'../../../dist/out-tsc/apps/my-dir/my-app-e2e'
);
// Make sure these have properties
[
{
path: 'apps/my-dir/my-app/tsconfig.app.json',
lookupFn: json => json.compilerOptions.outDir,
expectedValue: '../../../dist/out-tsc/apps/my-dir/my-app'
},
{
path: 'apps/my-dir/my-app-e2e/tsconfig.e2e.json',
lookupFn: json => json.compilerOptions.outDir,
expectedValue: '../../../dist/out-tsc/apps/my-dir/my-app-e2e'
},
{
path: 'apps/my-dir/my-app/tslint.json',
lookupFn: json => json.extends,
expectedValue: '../../../tslint.json'
}
].forEach(hasJsonValue);
});
});

Expand Down
3 changes: 0 additions & 3 deletions packages/schematics/src/collection/ng-add/index.ts
Expand Up @@ -99,9 +99,6 @@ function updatePackageJson() {
if (!packageJson.dependencies['rxjs-compat']) {
packageJson.dependencies['rxjs-compat'] = rxjsVersion;
}
if (!packageJson.devDependencies['@ngrx/schematics']) {
packageJson.devDependencies['@ngrx/schematics'] = ngrxSchematicsVersion;
}
if (!packageJson.devDependencies['@nrwl/schematics']) {
packageJson.devDependencies['@nrwl/schematics'] = schematicsVersion;
}
Expand Down

0 comments on commit 04e99b0

Please sign in to comment.