feat(nx): switch defaults to jest, cypress, and nest
This commit is contained in:
parent
328aaab67a
commit
03992c7de1
@ -24,6 +24,6 @@ ng generate application ...
|
||||
| `skipTests` | S | Skip creating spec files. | boolean | `false` |
|
||||
| `skipFormat` | | Skip formatting files | boolean | `false` |
|
||||
| `skipPackageJson` | | Do not add dependencies to package.json. | boolean | `false` |
|
||||
| `unitTestRunner` | | Test runner to use for unit tests | string | `karma` |
|
||||
| `e2eTestRunner` | | Test runner to use for end to end (e2e) tests | string | `protractor` |
|
||||
| `unitTestRunner` | | Test runner to use for unit tests | string | `jest` |
|
||||
| `e2eTestRunner` | | Test runner to use for end to end (e2e) tests | string | `cypress` |
|
||||
| `tags` | | Add tags to the application (used for linting) | string | `undefined` |
|
||||
16
docs/api-schematics/karma-project.md
Normal file
16
docs/api-schematics/karma-project.md
Normal file
@ -0,0 +1,16 @@
|
||||
# karma-project [hidden]
|
||||
|
||||
Add Karma configuration to a project
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
ng generate karma-project ...
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Alias | Description | Type | Default value |
|
||||
| --------- | ----- | ------------------------ | ------ | ------------- |
|
||||
| `project` | | The name of the project. | string | `undefined` |
|
||||
16
docs/api-schematics/karma.md
Normal file
16
docs/api-schematics/karma.md
Normal file
@ -0,0 +1,16 @@
|
||||
# karma [hidden]
|
||||
|
||||
Add Karma configuration to the workspace
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
ng generate karma ...
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Alias | Description | Type | Default value |
|
||||
| ---- | ----- | ----------- | ---- | ------------- |
|
||||
|
||||
@ -28,4 +28,4 @@ ng generate library ...
|
||||
| `lazy` | | Add RouterModule.forChild when set to true, and a simple array of routes when set to false. | boolean | `false` |
|
||||
| `module` | | [Deprecated]: Include an NgModule in the library. | boolean | `true` |
|
||||
| `tags` | | Add tags to the library (used for linting) | string | `undefined` |
|
||||
| `unitTestRunner` | | Test runner to use for unit tests | string | `karma` |
|
||||
| `unitTestRunner` | | Test runner to use for unit tests | string | `jest` |
|
||||
@ -15,7 +15,7 @@ ng generate node-application ...
|
||||
| ----------------- | ----- | ----------------------------------------------------------------------------------------- | ------- | ------------- |
|
||||
| `name` | | The name of the application. | string | `undefined` |
|
||||
| `directory` | | The directory of the new application. | string | `undefined` |
|
||||
| `framework` | | Node Framework to use for application. | string | `express` |
|
||||
| `framework` | | Node Framework to use for application. | string | `nestjs` |
|
||||
| `skipFormat` | | Skip formatting files | boolean | `false` |
|
||||
| `skipPackageJson` | | Do not add dependencies to package.json. | boolean | `false` |
|
||||
| `unitTestRunner` | | Test runner to use for unit tests | string | `jest` |
|
||||
@ -1,28 +1,33 @@
|
||||
import {
|
||||
copyMissingPackages,
|
||||
ensureProject,
|
||||
newApp,
|
||||
newLib,
|
||||
newProject,
|
||||
readFile,
|
||||
readJson,
|
||||
runCommand,
|
||||
runsInWSL,
|
||||
uniq,
|
||||
updateFile
|
||||
} from '../utils';
|
||||
|
||||
describe('Affected', () => {
|
||||
it('should print, build, and test affected apps', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
newApp('myapp2');
|
||||
newLib('mylib');
|
||||
newLib('mylib2');
|
||||
newLib('mypublishablelib --publishable');
|
||||
copyMissingPackages();
|
||||
ensureProject();
|
||||
const myapp = uniq('myapp');
|
||||
const myapp2 = uniq('myapp2');
|
||||
const mylib = uniq('mylib');
|
||||
const mylib2 = uniq('mylib2');
|
||||
const mypublishablelib = uniq('mypublishablelib');
|
||||
newApp(myapp);
|
||||
newApp(myapp2);
|
||||
newLib(mylib);
|
||||
newLib(mylib2);
|
||||
newLib(`${mypublishablelib} --publishable`);
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.spec.ts',
|
||||
`apps/${myapp}/src/app/app.component.spec.ts`,
|
||||
`
|
||||
import '@proj/mylib';
|
||||
import '@proj/${mylib}';
|
||||
describe('sample test', () => {
|
||||
it('should test', () => {
|
||||
expect(1).toEqual(1);
|
||||
@ -31,9 +36,9 @@ describe('Affected', () => {
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
'libs/mypublishablelib/src/lib/mypublishablelib.module.spec.ts',
|
||||
`libs/${mypublishablelib}/src/lib/${mypublishablelib}.module.spec.ts`,
|
||||
`
|
||||
import '@proj/mylib';
|
||||
import '@proj/${mylib}';
|
||||
describe('sample test', () => {
|
||||
it('should test', () => {
|
||||
expect(1).toEqual(1);
|
||||
@ -43,197 +48,155 @@ describe('Affected', () => {
|
||||
);
|
||||
|
||||
const affectedApps = runCommand(
|
||||
'npm run affected:apps -- --files="libs/mylib/src/index.ts"'
|
||||
`npm run affected:apps -- --files="libs/${mylib}/src/index.ts"`
|
||||
);
|
||||
expect(affectedApps).toContain('myapp');
|
||||
expect(affectedApps).not.toContain('myapp2');
|
||||
expect(affectedApps).not.toContain('myapp-e2e');
|
||||
expect(affectedApps).toContain(myapp);
|
||||
expect(affectedApps).not.toContain(myapp2);
|
||||
expect(affectedApps).not.toContain(`${myapp}-e2e`);
|
||||
|
||||
const implicitlyAffectedApps = runCommand(
|
||||
'npm run affected:apps -- --files="package.json"'
|
||||
);
|
||||
expect(implicitlyAffectedApps).toContain('myapp');
|
||||
expect(implicitlyAffectedApps).toContain('myapp2');
|
||||
expect(implicitlyAffectedApps).toContain(myapp);
|
||||
expect(implicitlyAffectedApps).toContain(myapp2);
|
||||
|
||||
const noAffectedApps = runCommand(
|
||||
'npm run affected:apps -- --files="README.md"'
|
||||
);
|
||||
expect(noAffectedApps).not.toContain('myapp');
|
||||
expect(noAffectedApps).not.toContain('myapp2');
|
||||
expect(noAffectedApps).not.toContain(myapp);
|
||||
expect(noAffectedApps).not.toContain(myapp2);
|
||||
|
||||
const affectedLibs = runCommand(
|
||||
'npm run affected:libs -- --files="libs/mylib/src/index.ts"'
|
||||
`npm run affected:libs -- --files="libs/${mylib}/src/index.ts"`
|
||||
);
|
||||
expect(affectedLibs).toContain('mypublishablelib');
|
||||
expect(affectedLibs).toContain('mylib');
|
||||
expect(affectedLibs).not.toContain('mylib2');
|
||||
expect(affectedLibs).toContain(mypublishablelib);
|
||||
expect(affectedLibs).toContain(mylib);
|
||||
expect(affectedLibs).not.toContain(mylib2);
|
||||
|
||||
const implicitlyAffectedLibs = runCommand(
|
||||
'npm run affected:libs -- --files="package.json"'
|
||||
);
|
||||
expect(implicitlyAffectedLibs).toContain('mypublishablelib');
|
||||
expect(implicitlyAffectedLibs).toContain('mylib');
|
||||
expect(implicitlyAffectedLibs).toContain('mylib2');
|
||||
expect(implicitlyAffectedLibs).toContain(mypublishablelib);
|
||||
expect(implicitlyAffectedLibs).toContain(mylib);
|
||||
expect(implicitlyAffectedLibs).toContain(mylib2);
|
||||
|
||||
const noAffectedLibs = runCommand(
|
||||
'npm run affected:libs -- --files="README.md"'
|
||||
);
|
||||
expect(noAffectedLibs).not.toContain('mypublishablelib');
|
||||
expect(noAffectedLibs).not.toContain('mylib');
|
||||
expect(noAffectedLibs).not.toContain('mylib2');
|
||||
expect(noAffectedLibs).not.toContain(mypublishablelib);
|
||||
expect(noAffectedLibs).not.toContain(mylib);
|
||||
expect(noAffectedLibs).not.toContain(mylib2);
|
||||
|
||||
const build = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts"'
|
||||
`npm run affected:build -- --files="libs/${mylib}/src/index.ts"`
|
||||
);
|
||||
expect(build).toContain('Running build for mypublishablelib');
|
||||
expect(build).toContain('Running build for myapp');
|
||||
expect(build).toContain(`Running build for ${mypublishablelib}`);
|
||||
expect(build).toContain(`Running build for ${myapp}`);
|
||||
expect(build).not.toContain('is not registered with the build command');
|
||||
expect(build).not.toContain('with flags:');
|
||||
|
||||
// Should work in parallel
|
||||
const buildParallel = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts" --parallel'
|
||||
`npm run affected:build -- --files="libs/${mylib}/src/index.ts" --parallel`
|
||||
);
|
||||
expect(buildParallel).toContain(
|
||||
'Running build for projects:\n myapp,\n mypublishablelib'
|
||||
`Running build for projects:\n ${myapp},\n ${mypublishablelib}`
|
||||
);
|
||||
expect(buildParallel).toContain(
|
||||
'Running build for affected projects succeeded.'
|
||||
);
|
||||
|
||||
const buildExcluded = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts" --exclude myapp'
|
||||
`npm run affected:build -- --files="libs/${mylib}/src/index.ts" --exclude ${myapp}`
|
||||
);
|
||||
expect(buildExcluded).toContain('Running build for mypublishablelib');
|
||||
|
||||
const buildExcludedCsv = runCommand(
|
||||
'npm run affected:build -- --files="package.json" --exclude myapp,myapp2,mypublishablelib'
|
||||
);
|
||||
expect(buildExcludedCsv).toContain('No projects to run build');
|
||||
expect(buildExcluded).toContain(`Running build for ${mypublishablelib}`);
|
||||
|
||||
// affected:build should pass non-nx flags to the CLI
|
||||
const buildWithFlags = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts" --stats-json'
|
||||
`npm run affected:build -- --files="libs/${mylib}/src/index.ts" --stats-json`
|
||||
);
|
||||
expect(buildWithFlags).toContain('Running build for mypublishablelib');
|
||||
expect(buildWithFlags).toContain('Running build for myapp');
|
||||
expect(buildWithFlags).toContain(`Running build for ${mypublishablelib}`);
|
||||
expect(buildWithFlags).toContain(`Running build for ${myapp}`);
|
||||
expect(buildWithFlags).toContain('With flags: --stats-json=true');
|
||||
|
||||
const e2e = runCommand(
|
||||
'npm run affected:e2e -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(e2e).toContain('should display welcome message');
|
||||
if (!runsInWSL()) {
|
||||
const e2e = runCommand(
|
||||
`npm run affected:e2e -- --files="libs/${mylib}/src/index.ts" --headless --no-watch`
|
||||
);
|
||||
expect(e2e).toContain('should display welcome message');
|
||||
}
|
||||
|
||||
const unitTests = runCommand(
|
||||
'npm run affected:test -- --files="libs/mylib/src/index.ts"'
|
||||
`npm run affected:test -- --files="libs/${mylib}/src/index.ts"`
|
||||
);
|
||||
expect(unitTests).toContain('Running test for mylib');
|
||||
expect(unitTests).toContain('Running test for mypublishablelib');
|
||||
expect(unitTests).toContain('Running test for myapp');
|
||||
expect(unitTests).toContain(`Running test for ${mylib}`);
|
||||
expect(unitTests).toContain(`Running test for ${mypublishablelib}`);
|
||||
expect(unitTests).toContain(`Running test for ${myapp}`);
|
||||
|
||||
// Fail a Unit Test
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.spec.ts',
|
||||
readFile('apps/myapp/src/app/app.component.spec.ts').replace(
|
||||
`apps/${myapp}/src/app/app.component.spec.ts`,
|
||||
readFile(`apps/${myapp}/src/app/app.component.spec.ts`).replace(
|
||||
'.toEqual(1)',
|
||||
'.toEqual(2)'
|
||||
)
|
||||
);
|
||||
|
||||
const failedTests = runCommand(
|
||||
'npm run affected:test -- --files="libs/mylib/src/index.ts"'
|
||||
`npm run affected:test -- --files="libs/${mylib}/src/index.ts"`
|
||||
);
|
||||
|
||||
expect(failedTests).toContain('Running test for mylib');
|
||||
expect(failedTests).toContain('Running test for mypublishablelib');
|
||||
expect(failedTests).toContain('Running test for myapp');
|
||||
expect(failedTests).toContain('Failed projects: myapp');
|
||||
expect(failedTests).toContain(`Running test for ${mylib}`);
|
||||
expect(failedTests).toContain(`Running test for ${mypublishablelib}`);
|
||||
expect(failedTests).toContain(`Running test for ${myapp}`);
|
||||
expect(failedTests).toContain(`Failed projects: ${myapp}`);
|
||||
expect(failedTests).toContain(
|
||||
'You can isolate the above projects by passing --only-failed'
|
||||
);
|
||||
expect(readJson('dist/.nx-results')).toEqual({
|
||||
command: 'test',
|
||||
results: {
|
||||
myapp: false,
|
||||
mylib: true,
|
||||
mypublishablelib: true
|
||||
[myapp]: false,
|
||||
[mylib]: true,
|
||||
[mypublishablelib]: true
|
||||
}
|
||||
});
|
||||
|
||||
// Fix failing Unit Test
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.spec.ts',
|
||||
readFile('apps/myapp/src/app/app.component.spec.ts').replace(
|
||||
`apps/${myapp}/src/app/app.component.spec.ts`,
|
||||
readFile(`apps/${myapp}/src/app/app.component.spec.ts`).replace(
|
||||
'.toEqual(2)',
|
||||
'.toEqual(1)'
|
||||
)
|
||||
);
|
||||
|
||||
const isolatedTests = runCommand(
|
||||
'npm run affected:test -- --files="libs/mylib/src/index.ts" --only-failed'
|
||||
`npm run affected:test -- --files="libs/${mylib}/src/index.ts" --only-failed`
|
||||
);
|
||||
expect(isolatedTests).toContain('Running test for myapp');
|
||||
expect(isolatedTests).toContain(`Running test for ${myapp}`);
|
||||
|
||||
const linting = runCommand(
|
||||
'npm run affected:lint -- --files="libs/mylib/src/index.ts"'
|
||||
`npm run affected:lint -- --files="libs/${mylib}/src/index.ts"`
|
||||
);
|
||||
expect(linting).toContain('Running lint for mylib');
|
||||
expect(linting).toContain('Running lint for myapp');
|
||||
expect(linting).toContain('Running lint for myapp-e2e');
|
||||
expect(linting).toContain('Running lint for mypublishablelib');
|
||||
expect(linting).toContain(`Running lint for ${mylib}`);
|
||||
expect(linting).toContain(`Running lint for ${myapp}`);
|
||||
expect(linting).toContain(`Running lint for ${myapp}-e2e`);
|
||||
expect(linting).toContain(`Running lint for ${mypublishablelib}`);
|
||||
|
||||
const lintWithJsonFormating = runCommand(
|
||||
'npm run affected:lint -- --files="libs/mylib/src/index.ts" -- --format json'
|
||||
`npm run affected:lint -- --files="libs/${mylib}/src/index.ts" -- --format json`
|
||||
);
|
||||
expect(lintWithJsonFormating).toContain('With flags: --format json');
|
||||
|
||||
const unitTestsExcluded = runCommand(
|
||||
'npm run affected:test -- --files="libs/mylib/src/index.ts" --exclude=myapp,mypublishablelib'
|
||||
`npm run affected:test -- --files="libs/${mylib}/src/index.ts" --exclude=${myapp},${mypublishablelib}`
|
||||
);
|
||||
expect(unitTestsExcluded).toContain('Running test for mylib');
|
||||
expect(unitTestsExcluded).toContain(`Running test for ${mylib}`);
|
||||
|
||||
const i18n = runCommand(
|
||||
'npm run affected -- --target extract-i18n --files="libs/mylib/src/index.ts"'
|
||||
`npm run affected -- --target extract-i18n --files="libs/${mylib}/src/index.ts"`
|
||||
);
|
||||
expect(i18n).toContain('Running extract-i18n for myapp');
|
||||
}, 1000000);
|
||||
|
||||
it('should print, build, and test all apps', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
newApp('myapp2');
|
||||
newLib('mylib');
|
||||
newLib('mypublishablelib --publishable');
|
||||
copyMissingPackages();
|
||||
|
||||
const affectedApps = runCommand('npm run affected:apps -- --all');
|
||||
expect(affectedApps).toContain('myapp');
|
||||
expect(affectedApps).toContain('myapp2');
|
||||
expect(affectedApps).not.toContain('myapp-e2e');
|
||||
|
||||
const build = runCommand('npm run affected:build -- --all');
|
||||
expect(build).toContain('Running build for myapp');
|
||||
expect(build).toContain('Running build for myapp2');
|
||||
expect(build).toContain('Running build for mypublishablelib');
|
||||
expect(build).not.toContain('is not registered with the build command');
|
||||
|
||||
const buildExcluded = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts" --exclude myapp,myapp2,mypublishablelib'
|
||||
);
|
||||
expect(buildExcluded).toContain('No projects to run build');
|
||||
|
||||
const e2e = runCommand('npm run affected:e2e -- --all');
|
||||
expect(e2e).toContain('Running e2e for myapp-e2e');
|
||||
expect(e2e).toContain('Running e2e for myapp2-e2e');
|
||||
|
||||
const unitTests = runCommand('npm run affected:test -- --all');
|
||||
expect(unitTests).toContain('Running test for mypublishablelib');
|
||||
expect(unitTests).toContain('Running test for myapp2');
|
||||
expect(unitTests).toContain('Running test for myapp');
|
||||
expect(unitTests).toContain('Running test for mylib');
|
||||
|
||||
const i18n = runCommand('npm run affected -- --target extract-i18n --all');
|
||||
expect(i18n).toContain('Running extract-i18n for myapp2');
|
||||
expect(i18n).toContain('Running extract-i18n for myapp');
|
||||
expect(i18n).toContain(`Running extract-i18n for ${myapp}`);
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
@ -1,140 +0,0 @@
|
||||
import { checkFilesExist, newApp, newBazelProject, newLib } from '../utils';
|
||||
|
||||
xdescribe('Nrwl Workspace (Bazel)', () => {
|
||||
it('should work', () => {
|
||||
newBazelProject();
|
||||
newApp('myApp --directory=myDir');
|
||||
newLib('myLib --directory=myDir');
|
||||
|
||||
checkFilesExist('WORKSPACE', 'BUILD.bazel');
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
// afterEach(() => {
|
||||
// runCommand('bazel build ...');
|
||||
// });
|
||||
|
||||
// itShould('create a bazel project', () => {
|
||||
// newBazelProject();
|
||||
// checkFilesExist('WORKSPACE', 'BUILD.bazel');
|
||||
// });
|
||||
|
||||
// itShould('create an app', () => {
|
||||
// newApp('myApp --directory=myDir');
|
||||
// });
|
||||
|
||||
// itShould('create a lib', () => {
|
||||
// newLib('myLib --directory=myDir');
|
||||
|
||||
// runCommand('bazel test //libs/my-dir/my-lib/src:test');
|
||||
// });
|
||||
|
||||
// itShould('allow adding a lib to a module', () => {
|
||||
// updateFile(
|
||||
// 'apps/my-dir/my-app/src/app/app.module.ts',
|
||||
// `import { NgModule } from '@angular/core';
|
||||
// import { BrowserModule } from '@angular/platform-browser';
|
||||
// import { MyLibModule } from 'proj/libs/my-dir/my-lib/src/my-lib.module';
|
||||
// import { AppComponent } from './app.component';
|
||||
// import { StoreModule } from '@ngrx/store';
|
||||
// import { NxModule } from '@nrwl/nx';
|
||||
|
||||
// @NgModule({
|
||||
// imports: [BrowserModule, MyLibModule, StoreModule.forRoot({}),
|
||||
// NxModule.forRoot()], declarations: [AppComponent], bootstrap: [AppComponent]
|
||||
// })
|
||||
// export class AppModule {}
|
||||
// `);
|
||||
|
||||
// // TODO: Replace this with a buildozer command to add the lib as a dep.
|
||||
// updateFile('apps/my-dir/my-app/src/app/BUILD.bazel', `
|
||||
// package(default_visibility = ["//visibility:public"])
|
||||
|
||||
// load("@angular//:index.bzl", "ng_module")
|
||||
|
||||
// ng_module(
|
||||
// name = "app",
|
||||
// srcs = glob(
|
||||
// ["*.ts"],
|
||||
// exclude = ["*.spec.ts"],
|
||||
// ),
|
||||
// assets = [
|
||||
// "app.component.css",
|
||||
// "app.component.html",
|
||||
// ],
|
||||
// deps = [
|
||||
// "//libs/my-dir/my-lib/src",
|
||||
// "@rxjs",
|
||||
// ],
|
||||
// )
|
||||
// `);
|
||||
// });
|
||||
|
||||
// itShould('add a module', () => {
|
||||
// newModule('helloWorld --directory=myDir');
|
||||
// });
|
||||
|
||||
// itShould('run protractor', () => {
|
||||
// const prodServerPort = 8080;
|
||||
// headlessProtractorConfig(prodServerPort);
|
||||
// runCommand([
|
||||
// 'node', 'node_modules/concurrently/src/main.js',
|
||||
// '"bazel run //apps/my-dir/my-app/src:prodserver"',
|
||||
// `"while ! nc -z 127.0.0.1 ${prodServerPort}; do sleep 1; done && ng
|
||||
// e2e -s=false --app=my-dir/my-app"`,
|
||||
// '--kill-others', '--success', 'first'
|
||||
// ].join(' '));
|
||||
|
||||
// const devServerPort = 5432;
|
||||
// headlessProtractorConfig(devServerPort);
|
||||
// runCommand([
|
||||
// 'node', 'node_modules/concurrently/src/main.js',
|
||||
// '"bazel run //apps/my-dir/my-app/src:devserver"',
|
||||
// `"while ! nc -z 127.0.0.1 ${devServerPort}; do sleep 1; done && ng
|
||||
// e2e -s=false --app=my-dir/my-app"`,
|
||||
// '--kill-others', '--success', 'first'
|
||||
// ].join(' '));
|
||||
// });
|
||||
// });
|
||||
|
||||
// function headlessProtractorConfig(port: number): void {
|
||||
// return updateFile(
|
||||
// 'protractor.conf.js',
|
||||
// `const { SpecReporter } = require('jasmine-spec-reporter');
|
||||
// const { getAppDirectoryUsingCliConfig } =
|
||||
// require('@nrwl/schematics/src/utils/cli-config-utils'); const appDir =
|
||||
// getAppDirectoryUsingCliConfig();
|
||||
|
||||
// exports.config = {
|
||||
// allScriptsTimeout: 11000,
|
||||
// specs: [
|
||||
// appDir + '/e2e/**/*.e2e-spec.ts'
|
||||
// ],
|
||||
// multiCapabilities: {
|
||||
// 'browserName': 'chrome',
|
||||
|
||||
// chromeOptions: {
|
||||
// args: [
|
||||
// '--headless',
|
||||
// '--disable-gpu',
|
||||
// '--window-size=1280x720',
|
||||
// ],
|
||||
// },
|
||||
// },
|
||||
// directConnect: true,
|
||||
// baseUrl: 'http://localhost:${port}/',
|
||||
// framework: 'jasmine',
|
||||
// jasmineNodeOpts: {
|
||||
// showColors: true,
|
||||
// defaultTimeoutInterval: 30000,
|
||||
// print: function() {}
|
||||
// },
|
||||
// onPrepare() {
|
||||
// require('ts-node').register({
|
||||
// project: appDir + '/e2e/tsconfig.e2e.json'
|
||||
// });
|
||||
// jasmine.getEnv().addReporter(new SpecReporter({ spec: {
|
||||
// displayStacktrace: true } }));
|
||||
// }
|
||||
// };`);
|
||||
// }
|
||||
@ -8,18 +8,28 @@ import {
|
||||
runCLI,
|
||||
runCommand,
|
||||
updateFile,
|
||||
exists
|
||||
exists,
|
||||
ensureProject,
|
||||
uniq
|
||||
} from '../utils';
|
||||
|
||||
describe('Command line', () => {
|
||||
it('lint should ensure module boundaries', () => {
|
||||
newProject();
|
||||
newApp('myapp --tags=validtag');
|
||||
newApp('myapp2');
|
||||
newLib('mylib');
|
||||
newLib('lazylib');
|
||||
newLib('invalidtaglib --tags=invalidtag');
|
||||
newLib('validtaglib --tags=validtag');
|
||||
ensureProject();
|
||||
|
||||
const myapp = uniq('myapp');
|
||||
const myapp2 = uniq('myapp2');
|
||||
const mylib = uniq('mylib');
|
||||
const lazylib = uniq('lazylib');
|
||||
const invalidtaglib = uniq('invalidtaglib');
|
||||
const validtaglib = uniq('validtaglib');
|
||||
|
||||
newApp(`${myapp} --tags=validtag`);
|
||||
newApp(`${myapp2}`);
|
||||
newLib(`${mylib}`);
|
||||
newLib(`${lazylib}`);
|
||||
newLib(`${invalidtaglib} --tags=invalidtag`);
|
||||
newLib(`${validtaglib} --tags=validtag`);
|
||||
|
||||
const tslint = readJson('tslint.json');
|
||||
tslint.rules['nx-enforce-module-boundaries'][1].depConstraints = [
|
||||
@ -29,20 +39,20 @@ describe('Command line', () => {
|
||||
updateFile('tslint.json', JSON.stringify(tslint, null, 2));
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/main.ts',
|
||||
`apps/${myapp}/src/main.ts`,
|
||||
`
|
||||
import '../../../libs/mylib';
|
||||
import '@proj/lazylib';
|
||||
import '@proj/mylib/deep';
|
||||
import '@proj/myapp2';
|
||||
import '@proj/invalidtaglib';
|
||||
import '@proj/validtaglib';
|
||||
import '../../../libs/${mylib}';
|
||||
import '@proj/${lazylib}';
|
||||
import '@proj/${mylib}/deep';
|
||||
import '@proj/${myapp2}';
|
||||
import '@proj/${invalidtaglib}';
|
||||
import '@proj/${validtaglib}';
|
||||
|
||||
const s = {loadChildren: '@proj/lazylib'};
|
||||
const s = {loadChildren: '@proj/${lazylib}'};
|
||||
`
|
||||
);
|
||||
|
||||
const out = runCLI('lint', { silenceError: true });
|
||||
const out = runCLI(`lint ${myapp}`, { silenceError: true });
|
||||
expect(out).toContain('library imports must start with @proj/');
|
||||
expect(out).toContain('imports of lazy-loaded libraries are forbidden');
|
||||
expect(out).toContain('deep imports into libraries are forbidden');
|
||||
@ -52,139 +62,143 @@ describe('Command line', () => {
|
||||
);
|
||||
}, 1000000);
|
||||
|
||||
it('should run nx lint', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
newApp('app_before');
|
||||
runCommand('mv apps/app-before apps/app-after');
|
||||
describe('nx lint', () => {
|
||||
afterAll(() => {
|
||||
newProject();
|
||||
});
|
||||
|
||||
const stdout = runCommand('npm run lint');
|
||||
it('should run nx lint', () => {
|
||||
ensureProject();
|
||||
const appBefore = uniq('before');
|
||||
const appAfter = uniq('after');
|
||||
|
||||
expect(stdout).toContain(
|
||||
`Cannot find project 'app-before' in 'apps/app-before/'`
|
||||
);
|
||||
expect(stdout).toContain(
|
||||
`The 'apps/app-after/browserslist' file doesn't belong to any project.`
|
||||
);
|
||||
});
|
||||
newApp(appBefore);
|
||||
runCommand(`mv apps/${appBefore} apps/${appAfter}`);
|
||||
|
||||
it('update should print deprecation information', () => {
|
||||
newProject();
|
||||
const update = runCommand('./node_modules/.bin/nx update');
|
||||
expect(update).toContain('Nx update is now deprecated.');
|
||||
expect(update).toContain(
|
||||
'Please use "ng update @nrwl/schematics" instead.'
|
||||
);
|
||||
const stdout = runCommand('./node_modules/.bin/nx lint');
|
||||
expect(stdout).toContain(
|
||||
`Cannot find project '${appBefore}' in 'apps/${appBefore}/'`
|
||||
);
|
||||
expect(stdout).toContain(
|
||||
`The 'apps/${appAfter}/browserslist' file doesn't belong to any project.`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('format should check and reformat the code', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
newLib('mylib');
|
||||
ensureProject();
|
||||
const myapp = uniq('myapp');
|
||||
const mylib = uniq('mylib');
|
||||
|
||||
newApp(myapp);
|
||||
newLib(mylib);
|
||||
updateFile(
|
||||
'apps/myapp/src/main.ts',
|
||||
`apps/${myapp}/src/main.ts`,
|
||||
`
|
||||
const x = 1111;
|
||||
`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.module.ts',
|
||||
`apps/${myapp}/src/app/app.module.ts`,
|
||||
`
|
||||
const y = 1111;
|
||||
`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.ts',
|
||||
`apps/${myapp}/src/app/app.component.ts`,
|
||||
`
|
||||
const z = 1111;
|
||||
`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
'libs/mylib/index.ts',
|
||||
`libs/${mylib}/index.ts`,
|
||||
`
|
||||
const x = 1111;
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
'libs/mylib/src/mylib.module.ts',
|
||||
`libs/${mylib}/src/${mylib}.module.ts`,
|
||||
`
|
||||
const y = 1111;
|
||||
`
|
||||
);
|
||||
|
||||
let stdout = runCommand(
|
||||
'npm run -s format:check -- --files="libs/mylib/index.ts" --libs-and-apps'
|
||||
`npm run -s format:check -- --files="libs/${mylib}/index.ts" --libs-and-apps`
|
||||
);
|
||||
expect(stdout).toContain('libs/mylib/index.ts');
|
||||
expect(stdout).toContain('libs/mylib/src/mylib.module.ts');
|
||||
expect(stdout).toContain(`libs/${mylib}/index.ts`);
|
||||
expect(stdout).toContain(`libs/${mylib}/src/${mylib}.module.ts`);
|
||||
|
||||
stdout = runCommand('npm run -s format:check');
|
||||
expect(stdout).toContain('apps/myapp/src/main.ts');
|
||||
expect(stdout).toContain('apps/myapp/src/app/app.module.ts');
|
||||
expect(stdout).toContain('apps/myapp/src/app/app.component.ts');
|
||||
stdout = runCommand(`npm run -s format:check`);
|
||||
expect(stdout).toContain(`apps/${myapp}/src/main.ts`);
|
||||
expect(stdout).toContain(`apps/${myapp}/src/app/app.module.ts`);
|
||||
expect(stdout).toContain(`apps/${myapp}/src/app/app.component.ts`);
|
||||
|
||||
runCommand(
|
||||
'npm run format:write -- --files="apps/myapp/src/app/app.module.ts,apps/myapp/src/app/app.component.ts"'
|
||||
`npm run format:write -- --files="apps/${myapp}/src/app/app.module.ts,apps/${myapp}/src/app/app.component.ts"`
|
||||
);
|
||||
|
||||
stdout = runCommand('npm run -s format:check');
|
||||
|
||||
expect(stdout).toContain('apps/myapp/src/main.ts');
|
||||
expect(stdout).not.toContain('apps/myapp/src/app/app.module.ts');
|
||||
expect(stdout).not.toContain('apps/myapp/src/app/app.component.ts');
|
||||
expect(stdout).toContain(`apps/${myapp}/src/main.ts`);
|
||||
expect(stdout).not.toContain(`apps/${myapp}/src/app/app.module.ts`);
|
||||
expect(stdout).not.toContain(`apps/${myapp}/src/app/app.component.ts`);
|
||||
|
||||
runCommand('npm run format:write');
|
||||
expect(runCommand('npm run -s format:check')).toEqual('');
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
it('should support workspace-specific schematics', () => {
|
||||
newProject();
|
||||
runCLI('g workspace-schematic custom --no-interactive');
|
||||
ensureProject();
|
||||
const custom = uniq('custom');
|
||||
runCLI(`g workspace-schematic ${custom} --no-interactive`);
|
||||
checkFilesExist(
|
||||
'tools/schematics/custom/index.ts',
|
||||
'tools/schematics/custom/schema.json'
|
||||
`tools/schematics/${custom}/index.ts`,
|
||||
`tools/schematics/${custom}/schema.json`
|
||||
);
|
||||
|
||||
const json = readJson('tools/schematics/custom/schema.json');
|
||||
const json = readJson(`tools/schematics/${custom}/schema.json`);
|
||||
json.properties['directory'] = {
|
||||
type: 'string',
|
||||
description: 'lib directory'
|
||||
};
|
||||
updateFile('tools/schematics/custom/schema.json', JSON.stringify(json));
|
||||
updateFile(`tools/schematics/${custom}/schema.json`, JSON.stringify(json));
|
||||
|
||||
const indexFile = readFile('tools/schematics/custom/index.ts');
|
||||
const indexFile = readFile(`tools/schematics/${custom}/index.ts`);
|
||||
updateFile(
|
||||
'tools/schematics/custom/index.ts',
|
||||
`tools/schematics/${custom}/index.ts`,
|
||||
indexFile.replace(
|
||||
'name: schema.name',
|
||||
'name: schema.name, directory: schema.directory'
|
||||
)
|
||||
);
|
||||
|
||||
const workspace = uniq('workspace');
|
||||
const dryRunOutput = runCommand(
|
||||
'npm run workspace-schematic custom mylib -- --no-interactive --directory=dir -d'
|
||||
`npm run workspace-schematic ${custom} ${workspace} -- --no-interactive --directory=dir -d`
|
||||
);
|
||||
expect(exists('libs/dir/mylib/src/index.ts')).toEqual(false);
|
||||
expect(exists(`libs/dir/${workspace}/src/index.ts`)).toEqual(false);
|
||||
expect(dryRunOutput).toContain(
|
||||
'create libs/dir/mylib/src/lib/dir-mylib.module.ts'
|
||||
`create libs/dir/${workspace}/src/lib/dir-${workspace}.module.ts`
|
||||
);
|
||||
expect(dryRunOutput).toContain('update angular.json');
|
||||
expect(dryRunOutput).toContain('update nx.json');
|
||||
|
||||
const output = runCommand(
|
||||
'npm run workspace-schematic custom mylib -- --no-interactive --directory=dir'
|
||||
`npm run workspace-schematic ${custom} ${workspace} -- --no-interactive --directory=dir`
|
||||
);
|
||||
checkFilesExist('libs/dir/mylib/src/index.ts');
|
||||
checkFilesExist(`libs/dir/${workspace}/src/index.ts`);
|
||||
expect(output).toContain(
|
||||
'create libs/dir/mylib/src/lib/dir-mylib.module.ts'
|
||||
`create libs/dir/${workspace}/src/lib/dir-${workspace}.module.ts`
|
||||
);
|
||||
expect(output).toContain('update angular.json');
|
||||
expect(output).toContain('update nx.json');
|
||||
|
||||
runCLI('g workspace-schematic another --no-interactive');
|
||||
const another = uniq('another');
|
||||
runCLI(`g workspace-schematic ${another} --no-interactive`);
|
||||
|
||||
const listSchematicsOutput = runCommand(
|
||||
'npm run workspace-schematic -- --list-schematics'
|
||||
@ -192,11 +206,11 @@ describe('Command line', () => {
|
||||
expect(listSchematicsOutput).toContain(
|
||||
'nx workspace-schematic "--list-schematics"'
|
||||
);
|
||||
expect(listSchematicsOutput).toContain('custom');
|
||||
expect(listSchematicsOutput).toContain('another');
|
||||
expect(listSchematicsOutput).toContain(custom);
|
||||
expect(listSchematicsOutput).toContain(another);
|
||||
|
||||
const promptOutput = runCommand(
|
||||
'npm run workspace-schematic custom mylib2 --'
|
||||
`npm run workspace-schematic ${custom} mylib2 --`
|
||||
);
|
||||
expect(promptOutput).toContain(
|
||||
'In which directory should the library be generated?'
|
||||
@ -204,7 +218,7 @@ describe('Command line', () => {
|
||||
}, 1000000);
|
||||
|
||||
describe('dep-graph', () => {
|
||||
beforeEach(() => {
|
||||
beforeAll(() => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
newApp('myapp2');
|
||||
|
||||
@ -6,55 +6,60 @@ import {
|
||||
readJson,
|
||||
runCLI,
|
||||
updateFile,
|
||||
readFile
|
||||
readFile,
|
||||
ensureProject,
|
||||
uniq,
|
||||
runsInWSL
|
||||
} from '../utils';
|
||||
|
||||
describe('Cypress E2E Test runner', () => {
|
||||
describe('project scaffolding', () => {
|
||||
it('should generate an app with the Cypress as e2e test runner', () => {
|
||||
newProject();
|
||||
newApp('myApp --e2eTestRunner=cypress');
|
||||
copyMissingPackages();
|
||||
ensureProject();
|
||||
const myapp = uniq('myapp');
|
||||
newApp(`${myapp} --e2eTestRunner=cypress`);
|
||||
|
||||
// Making sure the package.json file contains the Cypress dependency
|
||||
const packageJson = readJson('package.json');
|
||||
expect(packageJson.devDependencies['cypress']).toBeTruthy();
|
||||
|
||||
// Making sure the cypress folders & files are created
|
||||
checkFilesExist('apps/my-app-e2e/cypress.json');
|
||||
checkFilesExist('apps/my-app-e2e/tsconfig.e2e.json');
|
||||
checkFilesExist(`apps/${myapp}-e2e/cypress.json`);
|
||||
checkFilesExist(`apps/${myapp}-e2e/tsconfig.e2e.json`);
|
||||
|
||||
checkFilesExist('apps/my-app-e2e/src/fixtures/example.json');
|
||||
checkFilesExist('apps/my-app-e2e/src/integration/app.spec.ts');
|
||||
checkFilesExist('apps/my-app-e2e/src/plugins/index.ts');
|
||||
checkFilesExist('apps/my-app-e2e/src/support/app.po.ts');
|
||||
checkFilesExist('apps/my-app-e2e/src/support/index.ts');
|
||||
checkFilesExist('apps/my-app-e2e/src/support/commands.ts');
|
||||
checkFilesExist(`apps/${myapp}-e2e/src/fixtures/example.json`);
|
||||
checkFilesExist(`apps/${myapp}-e2e/src/integration/app.spec.ts`);
|
||||
checkFilesExist(`apps/${myapp}-e2e/src/plugins/index.ts`);
|
||||
checkFilesExist(`apps/${myapp}-e2e/src/support/app.po.ts`);
|
||||
checkFilesExist(`apps/${myapp}-e2e/src/support/index.ts`);
|
||||
checkFilesExist(`apps/${myapp}-e2e/src/support/commands.ts`);
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
describe('running Cypress', () => {
|
||||
it('should execute e2e tests using Cypress', () => {
|
||||
newProject();
|
||||
newApp('myApp --e2eTestRunner=cypress');
|
||||
copyMissingPackages();
|
||||
if (!runsInWSL()) {
|
||||
describe('running Cypress', () => {
|
||||
it('should execute e2e tests using Cypress', () => {
|
||||
ensureProject();
|
||||
const myapp = uniq('myapp');
|
||||
newApp(`${myapp} --e2eTestRunner=cypress`);
|
||||
|
||||
expect(
|
||||
runCLI('e2e --project=my-app-e2e --headless --watch=false')
|
||||
).toContain('All specs passed!');
|
||||
expect(
|
||||
runCLI(`e2e --project=${myapp}-e2e --headless --watch=false`)
|
||||
).toContain('All specs passed!');
|
||||
|
||||
const originalContents = JSON.parse(
|
||||
readFile('apps/my-app-e2e/cypress.json')
|
||||
);
|
||||
delete originalContents.fixturesFolder;
|
||||
updateFile(
|
||||
'apps/my-app-e2e/cypress.json',
|
||||
JSON.stringify(originalContents)
|
||||
);
|
||||
const originalContents = JSON.parse(
|
||||
readFile(`apps/${myapp}-e2e/cypress.json`)
|
||||
);
|
||||
delete originalContents.fixturesFolder;
|
||||
updateFile(
|
||||
`apps/${myapp}-e2e/cypress.json`,
|
||||
JSON.stringify(originalContents)
|
||||
);
|
||||
|
||||
expect(
|
||||
runCLI('e2e --project=my-app-e2e --headless --watch=false')
|
||||
).toContain('All specs passed!');
|
||||
}, 1000000);
|
||||
});
|
||||
expect(
|
||||
runCLI(`e2e --project=${myapp}-e2e --headless --watch=false`)
|
||||
).toContain('All specs passed!');
|
||||
}, 1000000);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,20 +1,31 @@
|
||||
import { newApp, newProject, runCLI, updateFile } from '../utils';
|
||||
import {
|
||||
ensureProject,
|
||||
expectTestsPass,
|
||||
newApp,
|
||||
newProject,
|
||||
runCLI,
|
||||
runCLIAsync,
|
||||
uniq,
|
||||
updateFile
|
||||
} from '../utils';
|
||||
|
||||
describe('DowngradeModule', () => {
|
||||
it('should generate a downgradeModule setup', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
it('should generate a downgradeModule setup', async () => {
|
||||
ensureProject();
|
||||
|
||||
const myapp = uniq('myapp');
|
||||
newApp(`${myapp} --unit-test-runner=karma`);
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/legacy.js',
|
||||
`apps/${myapp}/src/legacy.js`,
|
||||
`window.angular.module('legacy', []);`
|
||||
);
|
||||
|
||||
runCLI(
|
||||
'generate downgrade-module legacy --angularJsImport=./legacy --project=myapp'
|
||||
`generate downgrade-module legacy --angularJsImport=./legacy --project=${myapp}`
|
||||
);
|
||||
|
||||
runCLI('build');
|
||||
expect(runCLI('test --no-watch')).toContain('Executed 3 of 3 SUCCESS');
|
||||
runCLI(`build ${myapp}`);
|
||||
expect(runCLI(`test ${myapp} --no-watch`)).toContain('3 SUCCESS');
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
@ -4,34 +4,36 @@ import {
|
||||
newLib,
|
||||
runCLIAsync,
|
||||
newApp,
|
||||
copyMissingPackages
|
||||
copyMissingPackages,
|
||||
ensureProject,
|
||||
uniq
|
||||
} from '../utils';
|
||||
|
||||
describe('Jest', () => {
|
||||
beforeAll(() => {
|
||||
newProject();
|
||||
});
|
||||
|
||||
it('should be able to generate a testable library using jest', async done => {
|
||||
newLib('jestlib --unit-test-runner jest');
|
||||
copyMissingPackages();
|
||||
ensureProject();
|
||||
const mylib = uniq('mylib');
|
||||
newLib(`${mylib} --unit-test-runner jest`);
|
||||
|
||||
await Promise.all([
|
||||
runCLIAsync('generate service test --project jestlib'),
|
||||
runCLIAsync('generate component test --project jestlib')
|
||||
runCLIAsync(`generate service test --project ${mylib}`),
|
||||
runCLIAsync(`generate component test --project ${mylib}`)
|
||||
]);
|
||||
const jestResult = await runCLIAsync('test jestlib');
|
||||
const jestResult = await runCLIAsync(`test ${mylib}`);
|
||||
expect(jestResult.stderr).toContain('Test Suites: 3 passed, 3 total');
|
||||
done();
|
||||
}, 10000);
|
||||
|
||||
it('should be able to generate a testable application using jest', async () => {
|
||||
newApp('jestapp --unit-test-runner jest');
|
||||
copyMissingPackages();
|
||||
ensureProject();
|
||||
const myapp = uniq('myapp');
|
||||
newApp(`${myapp} --unit-test-runner jest`);
|
||||
|
||||
await Promise.all([
|
||||
runCLIAsync('generate service test --project jestapp'),
|
||||
runCLIAsync('generate component test --project jestapp')
|
||||
runCLIAsync(`generate service test --project ${myapp}`),
|
||||
runCLIAsync(`generate component test --project ${myapp}`)
|
||||
]);
|
||||
const jestResult = await runCLIAsync('test jestapp');
|
||||
const jestResult = await runCLIAsync(`test ${myapp}`);
|
||||
expect(jestResult.stderr).toContain('Test Suites: 3 passed, 3 total');
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
41
e2e/schematics/karma.test.ts
Normal file
41
e2e/schematics/karma.test.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import {
|
||||
newProject,
|
||||
runCLI,
|
||||
newLib,
|
||||
runCLIAsync,
|
||||
newApp,
|
||||
copyMissingPackages,
|
||||
ensureProject,
|
||||
uniq,
|
||||
patchKarmaToWorkOnWSL
|
||||
} from '../utils';
|
||||
|
||||
describe('Karma', () => {
|
||||
it('should be able to generate a testable library using karma', async done => {
|
||||
ensureProject();
|
||||
const mylib = uniq('mylib');
|
||||
newLib(`${mylib} --unit-test-runner karma`);
|
||||
|
||||
await Promise.all([
|
||||
runCLIAsync(`generate service test --project ${mylib}`),
|
||||
runCLIAsync(`generate component test --project ${mylib}`)
|
||||
]);
|
||||
const karmaResult = await runCLIAsync(`test ${mylib}`);
|
||||
expect(karmaResult.stdout).toContain('3 SUCCESS');
|
||||
done();
|
||||
}, 30000);
|
||||
|
||||
it('should be able to generate a testable application using karma', async done => {
|
||||
ensureProject();
|
||||
const myapp = uniq('myapp');
|
||||
newApp(`${myapp} --unit-test-runner karma`);
|
||||
|
||||
await Promise.all([
|
||||
runCLIAsync(`generate service test --project ${myapp}`),
|
||||
runCLIAsync(`generate component test --project ${myapp}`)
|
||||
]);
|
||||
const karmaResult = await runCLIAsync(`test ${myapp}`);
|
||||
expect(karmaResult.stdout).toContain('5 SUCCESS');
|
||||
done();
|
||||
}, 30000);
|
||||
});
|
||||
@ -8,461 +8,475 @@ import {
|
||||
readJson,
|
||||
readFile,
|
||||
runCommand,
|
||||
runCLIAsync
|
||||
runCLIAsync,
|
||||
runsInWSL
|
||||
} from '../utils';
|
||||
|
||||
describe('Nrwl Convert to Nx Workspace', () => {
|
||||
beforeEach(cleanup);
|
||||
if (!runsInWSL()) {
|
||||
describe('Nrwl Convert to Nx Workspace', () => {
|
||||
beforeEach(cleanup);
|
||||
afterAll(cleanup);
|
||||
|
||||
it('should generate a workspace', () => {
|
||||
runNgNew();
|
||||
it('should generate a workspace', () => {
|
||||
runNgNew();
|
||||
|
||||
// update package.json
|
||||
const packageJson = readJson('package.json');
|
||||
packageJson.description = 'some description';
|
||||
updateFile('package.json', JSON.stringify(packageJson, null, 2));
|
||||
// confirm that @nrwl and @ngrx dependencies do not exist yet
|
||||
expect(packageJson.devDependencies['@nrwl/schematics']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@nrwl/nx']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/store']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/effects']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/router-store']).not.toBeDefined();
|
||||
expect(
|
||||
packageJson.devDependencies['@ngrx/store-devtools']
|
||||
).not.toBeDefined();
|
||||
// update package.json
|
||||
const packageJson = readJson('package.json');
|
||||
packageJson.description = 'some description';
|
||||
updateFile('package.json', JSON.stringify(packageJson, null, 2));
|
||||
// confirm that @nrwl and @ngrx dependencies do not exist yet
|
||||
expect(packageJson.devDependencies['@nrwl/schematics']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@nrwl/nx']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/store']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/effects']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/router-store']).not.toBeDefined();
|
||||
expect(
|
||||
packageJson.devDependencies['@ngrx/store-devtools']
|
||||
).not.toBeDefined();
|
||||
|
||||
// update tsconfig.json
|
||||
const tsconfigJson = readJson('tsconfig.json');
|
||||
tsconfigJson.compilerOptions.paths = { a: ['b'] };
|
||||
updateFile('tsconfig.json', JSON.stringify(tsconfigJson, null, 2));
|
||||
// update tsconfig.json
|
||||
const tsconfigJson = readJson('tsconfig.json');
|
||||
tsconfigJson.compilerOptions.paths = { a: ['b'] };
|
||||
updateFile('tsconfig.json', JSON.stringify(tsconfigJson, null, 2));
|
||||
|
||||
updateFile('src/scripts.ts', '');
|
||||
updateFile('src/scripts.ts', '');
|
||||
|
||||
// update angular-cli.json
|
||||
const angularCLIJson = readJson('angular.json');
|
||||
angularCLIJson.projects.proj.architect.build.options.scripts = angularCLIJson.projects.proj.architect.test.options.scripts = [
|
||||
'src/scripts.ts'
|
||||
];
|
||||
angularCLIJson.projects.proj.architect.test.options.styles = [
|
||||
'src/styles.css'
|
||||
];
|
||||
updateFile('angular.json', JSON.stringify(angularCLIJson, null, 2));
|
||||
// update angular-cli.json
|
||||
const angularCLIJson = readJson('angular.json');
|
||||
angularCLIJson.projects.proj.architect.build.options.scripts = angularCLIJson.projects.proj.architect.test.options.scripts = [
|
||||
'src/scripts.ts'
|
||||
];
|
||||
angularCLIJson.projects.proj.architect.test.options.styles = [
|
||||
'src/styles.css'
|
||||
];
|
||||
updateFile('angular.json', JSON.stringify(angularCLIJson, null, 2));
|
||||
|
||||
// run the command
|
||||
runCLI('add @nrwl/schematics --npmScope projscope');
|
||||
copyMissingPackages();
|
||||
// run the command
|
||||
runCLI('add @nrwl/schematics --npmScope projscope');
|
||||
|
||||
// check that prettier config exits and that files have been moved!
|
||||
checkFilesExist(
|
||||
'.vscode/extensions.json',
|
||||
'.prettierrc',
|
||||
'apps/proj/src/main.ts',
|
||||
'apps/proj/src/app/app.module.ts'
|
||||
);
|
||||
// check that prettier config exits and that files have been moved!
|
||||
checkFilesExist(
|
||||
'.vscode/extensions.json',
|
||||
'.prettierrc',
|
||||
'apps/proj/src/main.ts',
|
||||
'apps/proj/src/app/app.module.ts'
|
||||
);
|
||||
|
||||
expect(readJson('.vscode/extensions.json').recommendations).toEqual([
|
||||
'nrwl.angular-console',
|
||||
'angular.ng-template',
|
||||
'esbenp.prettier-vscode'
|
||||
]);
|
||||
expect(readJson('.vscode/extensions.json').recommendations).toEqual([
|
||||
'nrwl.angular-console',
|
||||
'angular.ng-template',
|
||||
'esbenp.prettier-vscode'
|
||||
]);
|
||||
|
||||
const appModuleContents = readFile('apps/proj/src/app/app.module.ts');
|
||||
expect(appModuleContents).toContain(`import { NxModule } from '@nrwl/nx';`);
|
||||
expect(appModuleContents).toContain(`NxModule.forRoot()`);
|
||||
const appModuleContents = readFile('apps/proj/src/app/app.module.ts');
|
||||
expect(appModuleContents).toContain(
|
||||
`import { NxModule } from '@nrwl/nx';`
|
||||
);
|
||||
expect(appModuleContents).toContain(`NxModule.forRoot()`);
|
||||
|
||||
// check that package.json got merged
|
||||
const updatedPackageJson = readJson('package.json');
|
||||
expect(updatedPackageJson.description).toEqual('some description');
|
||||
expect(updatedPackageJson.scripts).toEqual({
|
||||
ng: 'ng',
|
||||
start: 'ng serve',
|
||||
build: 'ng build',
|
||||
test: 'ng test',
|
||||
lint: './node_modules/.bin/nx lint && ng lint',
|
||||
e2e: 'ng e2e',
|
||||
'affected:apps': './node_modules/.bin/nx affected:apps',
|
||||
'affected:libs': './node_modules/.bin/nx affected:libs',
|
||||
'affected:build': './node_modules/.bin/nx affected:build',
|
||||
'affected:e2e': './node_modules/.bin/nx affected:e2e',
|
||||
'affected:test': './node_modules/.bin/nx affected:test',
|
||||
'affected:lint': './node_modules/.bin/nx affected:lint',
|
||||
'affected:dep-graph': './node_modules/.bin/nx affected:dep-graph',
|
||||
affected: './node_modules/.bin/nx affected',
|
||||
format: './node_modules/.bin/nx format:write',
|
||||
'format:write': './node_modules/.bin/nx format:write',
|
||||
'format:check': './node_modules/.bin/nx format:check',
|
||||
update: 'ng update @nrwl/schematics',
|
||||
'update:check': 'ng update',
|
||||
'dep-graph': './node_modules/.bin/nx dep-graph',
|
||||
'workspace-schematic': './node_modules/.bin/nx workspace-schematic',
|
||||
help: './node_modules/.bin/nx help'
|
||||
});
|
||||
expect(
|
||||
updatedPackageJson.devDependencies['@nrwl/schematics']
|
||||
).toBeDefined();
|
||||
expect(updatedPackageJson.dependencies['@nrwl/nx']).toBeDefined();
|
||||
expect(updatedPackageJson.dependencies['@ngrx/store']).toBeDefined();
|
||||
expect(updatedPackageJson.dependencies['@ngrx/effects']).toBeDefined();
|
||||
expect(updatedPackageJson.dependencies['@ngrx/router-store']).toBeDefined();
|
||||
expect(
|
||||
updatedPackageJson.devDependencies['@ngrx/store-devtools']
|
||||
).toBeDefined();
|
||||
expect(updatedPackageJson.devDependencies['@angular/cli']).toBeDefined();
|
||||
// check that package.json got merged
|
||||
const updatedPackageJson = readJson('package.json');
|
||||
expect(updatedPackageJson.description).toEqual('some description');
|
||||
expect(updatedPackageJson.scripts).toEqual({
|
||||
ng: 'ng',
|
||||
start: 'ng serve',
|
||||
build: 'ng build',
|
||||
test: 'ng test',
|
||||
lint: './node_modules/.bin/nx lint && ng lint',
|
||||
e2e: 'ng e2e',
|
||||
'affected:apps': './node_modules/.bin/nx affected:apps',
|
||||
'affected:libs': './node_modules/.bin/nx affected:libs',
|
||||
'affected:build': './node_modules/.bin/nx affected:build',
|
||||
'affected:e2e': './node_modules/.bin/nx affected:e2e',
|
||||
'affected:test': './node_modules/.bin/nx affected:test',
|
||||
'affected:lint': './node_modules/.bin/nx affected:lint',
|
||||
'affected:dep-graph': './node_modules/.bin/nx affected:dep-graph',
|
||||
affected: './node_modules/.bin/nx affected',
|
||||
format: './node_modules/.bin/nx format:write',
|
||||
'format:write': './node_modules/.bin/nx format:write',
|
||||
'format:check': './node_modules/.bin/nx format:check',
|
||||
update: 'ng update @nrwl/schematics',
|
||||
'update:check': 'ng update',
|
||||
'dep-graph': './node_modules/.bin/nx dep-graph',
|
||||
'workspace-schematic': './node_modules/.bin/nx workspace-schematic',
|
||||
help: './node_modules/.bin/nx help'
|
||||
});
|
||||
expect(
|
||||
updatedPackageJson.devDependencies['@nrwl/schematics']
|
||||
).toBeDefined();
|
||||
expect(updatedPackageJson.dependencies['@nrwl/nx']).toBeDefined();
|
||||
expect(updatedPackageJson.dependencies['@ngrx/store']).toBeDefined();
|
||||
expect(updatedPackageJson.dependencies['@ngrx/effects']).toBeDefined();
|
||||
expect(
|
||||
updatedPackageJson.dependencies['@ngrx/router-store']
|
||||
).toBeDefined();
|
||||
expect(
|
||||
updatedPackageJson.devDependencies['@ngrx/store-devtools']
|
||||
).toBeDefined();
|
||||
expect(updatedPackageJson.devDependencies['@angular/cli']).toBeDefined();
|
||||
|
||||
const nxJson = readJson('nx.json');
|
||||
expect(nxJson).toEqual({
|
||||
npmScope: 'projscope',
|
||||
implicitDependencies: {
|
||||
'angular.json': '*',
|
||||
'package.json': '*',
|
||||
'tslint.json': '*',
|
||||
'tsconfig.json': '*',
|
||||
'nx.json': '*'
|
||||
},
|
||||
projects: {
|
||||
proj: {
|
||||
tags: []
|
||||
const nxJson = readJson('nx.json');
|
||||
expect(nxJson).toEqual({
|
||||
npmScope: 'projscope',
|
||||
implicitDependencies: {
|
||||
'angular.json': '*',
|
||||
'package.json': '*',
|
||||
'tslint.json': '*',
|
||||
'tsconfig.json': '*',
|
||||
'nx.json': '*'
|
||||
},
|
||||
'proj-e2e': {
|
||||
tags: []
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// check if angular-cli.json get merged
|
||||
const updatedAngularCLIJson = readJson('angular.json');
|
||||
expect(updatedAngularCLIJson.projects.proj.root).toEqual('apps/proj');
|
||||
expect(updatedAngularCLIJson.projects.proj.sourceRoot).toEqual(
|
||||
'apps/proj/src'
|
||||
);
|
||||
|
||||
expect(updatedAngularCLIJson.projects.proj.architect.build).toEqual({
|
||||
builder: '@angular-devkit/build-angular:browser',
|
||||
options: {
|
||||
outputPath: 'dist/apps/proj',
|
||||
index: 'apps/proj/src/index.html',
|
||||
main: 'apps/proj/src/main.ts',
|
||||
polyfills: 'apps/proj/src/polyfills.ts',
|
||||
tsConfig: 'apps/proj/tsconfig.app.json',
|
||||
assets: ['apps/proj/src/favicon.ico', 'apps/proj/src/assets'],
|
||||
styles: ['apps/proj/src/styles.css'],
|
||||
scripts: ['apps/proj/src/scripts.ts']
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
fileReplacements: [
|
||||
{
|
||||
replace: 'apps/proj/src/environments/environment.ts',
|
||||
with: 'apps/proj/src/environments/environment.prod.ts'
|
||||
}
|
||||
],
|
||||
budgets: [
|
||||
{
|
||||
maximumError: '5mb',
|
||||
maximumWarning: '2mb',
|
||||
type: 'initial'
|
||||
}
|
||||
],
|
||||
optimization: true,
|
||||
outputHashing: 'all',
|
||||
sourceMap: false,
|
||||
extractCss: true,
|
||||
namedChunks: false,
|
||||
aot: true,
|
||||
extractLicenses: true,
|
||||
vendorChunk: false,
|
||||
buildOptimizer: true
|
||||
}
|
||||
}
|
||||
});
|
||||
expect(updatedAngularCLIJson.projects.proj.architect.serve).toEqual({
|
||||
builder: '@angular-devkit/build-angular:dev-server',
|
||||
options: {
|
||||
browserTarget: 'proj:build'
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
browserTarget: 'proj:build:production'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects.proj.architect.test).toEqual({
|
||||
builder: '@angular-devkit/build-angular:karma',
|
||||
options: {
|
||||
main: 'apps/proj/src/test.ts',
|
||||
polyfills: 'apps/proj/src/polyfills.ts',
|
||||
tsConfig: 'apps/proj/tsconfig.spec.json',
|
||||
karmaConfig: 'apps/proj/karma.conf.js',
|
||||
styles: ['apps/proj/src/styles.css'],
|
||||
scripts: ['apps/proj/src/scripts.ts'],
|
||||
assets: ['apps/proj/src/favicon.ico', 'apps/proj/src/assets']
|
||||
}
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects.proj.architect.lint).toEqual({
|
||||
builder: '@angular-devkit/build-angular:tslint',
|
||||
options: {
|
||||
tsConfig: [
|
||||
'apps/proj/tsconfig.app.json',
|
||||
'apps/proj/tsconfig.spec.json'
|
||||
],
|
||||
exclude: ['**/node_modules/**']
|
||||
}
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects['proj-e2e'].root).toEqual(
|
||||
'apps/proj-e2e'
|
||||
);
|
||||
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'
|
||||
}
|
||||
});
|
||||
expect(updatedAngularCLIJson.projects['proj-e2e'].architect.lint).toEqual({
|
||||
builder: '@angular-devkit/build-angular:tslint',
|
||||
options: {
|
||||
tsConfig: 'apps/proj-e2e/tsconfig.e2e.json',
|
||||
exclude: ['**/node_modules/**']
|
||||
}
|
||||
});
|
||||
|
||||
// check if tsconfig.json get merged
|
||||
const updatedTsConfig = readJson('tsconfig.json');
|
||||
expect(updatedTsConfig.compilerOptions.paths).toEqual({
|
||||
a: ['b'],
|
||||
'@projscope/*': ['libs/*']
|
||||
});
|
||||
|
||||
const updatedTslint = readJson('tslint.json');
|
||||
expect(updatedTslint.rules['nx-enforce-module-boundaries']).toEqual([
|
||||
true,
|
||||
{
|
||||
allow: [],
|
||||
depConstraints: [{ sourceTag: '*', onlyDependOnLibsWithTags: ['*'] }]
|
||||
}
|
||||
]);
|
||||
|
||||
runCLI('build --prod --outputHashing none');
|
||||
checkFilesExist('dist/apps/proj/main.js');
|
||||
});
|
||||
|
||||
it('should generate a workspace and not change dependencies, devDependencies, or vscode extensions if they already exist', () => {
|
||||
// create a new AngularCLI app
|
||||
runNgNew();
|
||||
const nxVersion = '0.0.0';
|
||||
const schematicsVersion = '0.0.0';
|
||||
const ngrxVersion = '0.0.0';
|
||||
// update package.json
|
||||
const existingPackageJson = readJson('package.json');
|
||||
existingPackageJson.devDependencies['@nrwl/schematics'] = schematicsVersion;
|
||||
existingPackageJson.dependencies['@nrwl/nx'] = nxVersion;
|
||||
existingPackageJson.dependencies['@ngrx/store'] = ngrxVersion;
|
||||
existingPackageJson.dependencies['@ngrx/effects'] = ngrxVersion;
|
||||
existingPackageJson.dependencies['@ngrx/router-store'] = ngrxVersion;
|
||||
existingPackageJson.devDependencies['@ngrx/store-devtools'] = ngrxVersion;
|
||||
updateFile('package.json', JSON.stringify(existingPackageJson, null, 2));
|
||||
|
||||
updateFile(
|
||||
'.vscode/extensions.json',
|
||||
JSON.stringify({
|
||||
recommendations: ['eamodio.gitlens', 'angular.ng-template']
|
||||
})
|
||||
);
|
||||
// run the command
|
||||
runCLI('add @nrwl/schematics --npmScope projscope --skip-install');
|
||||
// check that dependencies and devDependencies remained the same
|
||||
const packageJson = readJson('package.json');
|
||||
expect(packageJson.devDependencies['@nrwl/schematics']).toEqual(
|
||||
schematicsVersion
|
||||
);
|
||||
expect(packageJson.dependencies['@nrwl/nx']).toEqual(nxVersion);
|
||||
expect(packageJson.dependencies['@ngrx/store']).toEqual(ngrxVersion);
|
||||
expect(packageJson.dependencies['@ngrx/effects']).toEqual(ngrxVersion);
|
||||
expect(packageJson.dependencies['@ngrx/router-store']).toEqual(ngrxVersion);
|
||||
expect(packageJson.devDependencies['@ngrx/store-devtools']).toEqual(
|
||||
ngrxVersion
|
||||
);
|
||||
|
||||
expect(readJson('.vscode/extensions.json').recommendations).toEqual([
|
||||
'eamodio.gitlens',
|
||||
'angular.ng-template',
|
||||
'nrwl.angular-console',
|
||||
'esbenp.prettier-vscode'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should generate a workspace from a universal cli project', () => {
|
||||
// create a new AngularCLI app
|
||||
runNgNew();
|
||||
|
||||
// Add Universal
|
||||
runCLI('generate universal --client-project proj');
|
||||
|
||||
// Add @nrwl/schematics
|
||||
runCLI('add @nrwl/schematics --npmScope projscope');
|
||||
copyMissingPackages();
|
||||
|
||||
checkFilesExist('apps/proj/tsconfig.server.json');
|
||||
|
||||
const serverTsConfig = readJson('apps/proj/tsconfig.server.json');
|
||||
|
||||
expect(serverTsConfig).toEqual({
|
||||
extends: './tsconfig.app.json',
|
||||
compilerOptions: {
|
||||
outDir: '../../dist/out-tsc/apps/proj-server',
|
||||
baseUrl: '.'
|
||||
},
|
||||
angularCompilerOptions: {
|
||||
entryModule: 'src/app/app.server.module#AppServerModule'
|
||||
}
|
||||
});
|
||||
|
||||
const updatedAngularCLIJson = readJson('angular.json');
|
||||
|
||||
expect(updatedAngularCLIJson.projects.proj.architect.server).toEqual({
|
||||
builder: '@angular-devkit/build-angular:server',
|
||||
options: {
|
||||
outputPath: 'dist/apps/proj-server',
|
||||
main: 'apps/proj/src/main.server.ts',
|
||||
tsConfig: 'apps/proj/tsconfig.server.json'
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
optimization: {
|
||||
scripts: false,
|
||||
styles: true
|
||||
projects: {
|
||||
proj: {
|
||||
tags: []
|
||||
},
|
||||
sourceMap: false,
|
||||
fileReplacements: [
|
||||
{
|
||||
replace: 'src/environments/environment.ts',
|
||||
with: 'src/environments/environment.prod.ts'
|
||||
}
|
||||
]
|
||||
'proj-e2e': {
|
||||
tags: []
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// check if angular-cli.json get merged
|
||||
const updatedAngularCLIJson = readJson('angular.json');
|
||||
expect(updatedAngularCLIJson.projects.proj.root).toEqual('apps/proj');
|
||||
expect(updatedAngularCLIJson.projects.proj.sourceRoot).toEqual(
|
||||
'apps/proj/src'
|
||||
);
|
||||
|
||||
expect(updatedAngularCLIJson.projects.proj.architect.build).toEqual({
|
||||
builder: '@angular-devkit/build-angular:browser',
|
||||
options: {
|
||||
outputPath: 'dist/apps/proj',
|
||||
index: 'apps/proj/src/index.html',
|
||||
main: 'apps/proj/src/main.ts',
|
||||
polyfills: 'apps/proj/src/polyfills.ts',
|
||||
tsConfig: 'apps/proj/tsconfig.app.json',
|
||||
assets: ['apps/proj/src/favicon.ico', 'apps/proj/src/assets'],
|
||||
styles: ['apps/proj/src/styles.css'],
|
||||
scripts: ['apps/proj/src/scripts.ts']
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
fileReplacements: [
|
||||
{
|
||||
replace: 'apps/proj/src/environments/environment.ts',
|
||||
with: 'apps/proj/src/environments/environment.prod.ts'
|
||||
}
|
||||
],
|
||||
budgets: [
|
||||
{
|
||||
maximumError: '5mb',
|
||||
maximumWarning: '2mb',
|
||||
type: 'initial'
|
||||
}
|
||||
],
|
||||
optimization: true,
|
||||
outputHashing: 'all',
|
||||
sourceMap: false,
|
||||
extractCss: true,
|
||||
namedChunks: false,
|
||||
aot: true,
|
||||
extractLicenses: true,
|
||||
vendorChunk: false,
|
||||
buildOptimizer: true
|
||||
}
|
||||
}
|
||||
});
|
||||
expect(updatedAngularCLIJson.projects.proj.architect.serve).toEqual({
|
||||
builder: '@angular-devkit/build-angular:dev-server',
|
||||
options: {
|
||||
browserTarget: 'proj:build'
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
browserTarget: 'proj:build:production'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects.proj.architect.test).toEqual({
|
||||
builder: '@angular-devkit/build-angular:karma',
|
||||
options: {
|
||||
main: 'apps/proj/src/test.ts',
|
||||
polyfills: 'apps/proj/src/polyfills.ts',
|
||||
tsConfig: 'apps/proj/tsconfig.spec.json',
|
||||
karmaConfig: 'apps/proj/karma.conf.js',
|
||||
styles: ['apps/proj/src/styles.css'],
|
||||
scripts: ['apps/proj/src/scripts.ts'],
|
||||
assets: ['apps/proj/src/favicon.ico', 'apps/proj/src/assets']
|
||||
}
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects.proj.architect.lint).toEqual({
|
||||
builder: '@angular-devkit/build-angular:tslint',
|
||||
options: {
|
||||
tsConfig: [
|
||||
'apps/proj/tsconfig.app.json',
|
||||
'apps/proj/tsconfig.spec.json'
|
||||
],
|
||||
exclude: ['**/node_modules/**']
|
||||
}
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects['proj-e2e'].root).toEqual(
|
||||
'apps/proj-e2e'
|
||||
);
|
||||
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'
|
||||
}
|
||||
});
|
||||
expect(updatedAngularCLIJson.projects['proj-e2e'].architect.lint).toEqual(
|
||||
{
|
||||
builder: '@angular-devkit/build-angular:tslint',
|
||||
options: {
|
||||
tsConfig: 'apps/proj-e2e/tsconfig.e2e.json',
|
||||
exclude: ['**/node_modules/**']
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// check if tsconfig.json get merged
|
||||
const updatedTsConfig = readJson('tsconfig.json');
|
||||
expect(updatedTsConfig.compilerOptions.paths).toEqual({
|
||||
a: ['b'],
|
||||
'@projscope/*': ['libs/*']
|
||||
});
|
||||
|
||||
const updatedTslint = readJson('tslint.json');
|
||||
expect(updatedTslint.rules['nx-enforce-module-boundaries']).toEqual([
|
||||
true,
|
||||
{
|
||||
allow: [],
|
||||
depConstraints: [{ sourceTag: '*', onlyDependOnLibsWithTags: ['*'] }]
|
||||
}
|
||||
]);
|
||||
|
||||
runCLI('build --prod --outputHashing none');
|
||||
checkFilesExist('dist/apps/proj/main.js');
|
||||
});
|
||||
|
||||
runCLI('run proj:server');
|
||||
checkFilesExist('dist/apps/proj-server/main.js');
|
||||
});
|
||||
it('should generate a workspace and not change dependencies, devDependencies, or vscode extensions if they already exist', () => {
|
||||
// create a new AngularCLI app
|
||||
runNgNew();
|
||||
const nxVersion = '0.0.0';
|
||||
const schematicsVersion = '0.0.0';
|
||||
const ngrxVersion = '0.0.0';
|
||||
// update package.json
|
||||
const existingPackageJson = readJson('package.json');
|
||||
existingPackageJson.devDependencies[
|
||||
'@nrwl/schematics'
|
||||
] = schematicsVersion;
|
||||
existingPackageJson.dependencies['@nrwl/nx'] = nxVersion;
|
||||
existingPackageJson.dependencies['@ngrx/store'] = ngrxVersion;
|
||||
existingPackageJson.dependencies['@ngrx/effects'] = ngrxVersion;
|
||||
existingPackageJson.dependencies['@ngrx/router-store'] = ngrxVersion;
|
||||
existingPackageJson.devDependencies['@ngrx/store-devtools'] = ngrxVersion;
|
||||
updateFile('package.json', JSON.stringify(existingPackageJson, null, 2));
|
||||
|
||||
it('should convert a project with common libraries in the ecosystem', () => {
|
||||
// create a new AngularCLI app
|
||||
runNgNew();
|
||||
updateFile(
|
||||
'.vscode/extensions.json',
|
||||
JSON.stringify({
|
||||
recommendations: ['eamodio.gitlens', 'angular.ng-template']
|
||||
})
|
||||
);
|
||||
// run the command
|
||||
runCLI('add @nrwl/schematics --npmScope projscope --skip-install');
|
||||
// check that dependencies and devDependencies remained the same
|
||||
const packageJson = readJson('package.json');
|
||||
expect(packageJson.devDependencies['@nrwl/schematics']).toEqual(
|
||||
schematicsVersion
|
||||
);
|
||||
expect(packageJson.dependencies['@nrwl/nx']).toEqual(nxVersion);
|
||||
expect(packageJson.dependencies['@ngrx/store']).toEqual(ngrxVersion);
|
||||
expect(packageJson.dependencies['@ngrx/effects']).toEqual(ngrxVersion);
|
||||
expect(packageJson.dependencies['@ngrx/router-store']).toEqual(
|
||||
ngrxVersion
|
||||
);
|
||||
expect(packageJson.devDependencies['@ngrx/store-devtools']).toEqual(
|
||||
ngrxVersion
|
||||
);
|
||||
|
||||
// Add some Angular libraries
|
||||
runCLI('add @angular/elements');
|
||||
runCLI('add @angular/material');
|
||||
runCLI('add @angular/pwa');
|
||||
runCLI('add @ngrx/store');
|
||||
runCLI('add @ngrx/effects');
|
||||
copyMissingPackages();
|
||||
// Add Nx
|
||||
runCLI('add @nrwl/schematics');
|
||||
});
|
||||
expect(readJson('.vscode/extensions.json').recommendations).toEqual([
|
||||
'eamodio.gitlens',
|
||||
'angular.ng-template',
|
||||
'nrwl.angular-console',
|
||||
'esbenp.prettier-vscode'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should handle workspaces with no e2e project', async () => {
|
||||
// create a new AngularCLI app
|
||||
runNgNew();
|
||||
it('should generate a workspace from a universal cli project', () => {
|
||||
// create a new AngularCLI app
|
||||
runNgNew();
|
||||
|
||||
// Remove e2e
|
||||
runCommand('rm -rf e2e');
|
||||
const existingAngularJson = readJson('angular.json');
|
||||
delete existingAngularJson.projects['proj-e2e'];
|
||||
updateFile('angular.json', JSON.stringify(existingAngularJson, null, 2));
|
||||
// Add Universal
|
||||
runCLI('generate universal --client-project proj');
|
||||
|
||||
// Add @nrwl/schematics
|
||||
const result = await runCLIAsync(
|
||||
'add @nrwl/schematics --npmScope projscope --skip-install'
|
||||
);
|
||||
// Add @nrwl/schematics
|
||||
runCLI('add @nrwl/schematics --npmScope projscope');
|
||||
|
||||
checkFilesExist(
|
||||
'.prettierrc',
|
||||
'apps/proj/src/main.ts',
|
||||
'apps/proj/src/app/app.module.ts'
|
||||
);
|
||||
checkFilesExist('apps/proj/tsconfig.server.json');
|
||||
|
||||
expect(result.stderr).toContain(
|
||||
'No e2e project was migrated because there was none declared in angular.json'
|
||||
);
|
||||
});
|
||||
const serverTsConfig = readJson('apps/proj/tsconfig.server.json');
|
||||
|
||||
it('should handle type array at tslint builder options.tsConfig (e2e project)', () => {
|
||||
// create a new AngularCLI app
|
||||
runNgNew();
|
||||
expect(serverTsConfig).toEqual({
|
||||
extends: './tsconfig.app.json',
|
||||
compilerOptions: {
|
||||
outDir: '../../dist/out-tsc/apps/proj-server',
|
||||
baseUrl: '.'
|
||||
},
|
||||
angularCompilerOptions: {
|
||||
entryModule: 'src/app/app.server.module#AppServerModule'
|
||||
}
|
||||
});
|
||||
|
||||
// set array at tslint builder options.tsConfig
|
||||
const existingAngularJson = readJson('angular.json');
|
||||
existingAngularJson.projects['proj-e2e'].architect.lint.options.tsConfig = [
|
||||
'e2e/tsconfig.e2e.json'
|
||||
];
|
||||
updateFile('angular.json', JSON.stringify(existingAngularJson, null, 2));
|
||||
const updatedAngularCLIJson = readJson('angular.json');
|
||||
|
||||
// Add @nrwl/schematics
|
||||
runCLI('add @nrwl/schematics --npmScope projscope --skip-install');
|
||||
expect(updatedAngularCLIJson.projects.proj.architect.server).toEqual({
|
||||
builder: '@angular-devkit/build-angular:server',
|
||||
options: {
|
||||
outputPath: 'dist/apps/proj-server',
|
||||
main: 'apps/proj/src/main.server.ts',
|
||||
tsConfig: 'apps/proj/tsconfig.server.json'
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
optimization: {
|
||||
scripts: false,
|
||||
styles: true
|
||||
},
|
||||
sourceMap: false,
|
||||
fileReplacements: [
|
||||
{
|
||||
replace: 'src/environments/environment.ts',
|
||||
with: 'src/environments/environment.prod.ts'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const updatedAngularCLIJson = readJson('angular.json');
|
||||
runCLI('run proj:server');
|
||||
checkFilesExist('dist/apps/proj-server/main.js');
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects['proj-e2e'].architect.lint).toEqual({
|
||||
builder: '@angular-devkit/build-angular:tslint',
|
||||
options: {
|
||||
tsConfig: ['apps/proj-e2e/tsconfig.e2e.json'],
|
||||
exclude: ['**/node_modules/**']
|
||||
it('should convert a project with common libraries in the ecosystem', () => {
|
||||
// create a new AngularCLI app
|
||||
runNgNew();
|
||||
|
||||
// Add some Angular libraries
|
||||
runCLI('add @angular/elements');
|
||||
runCLI('add @angular/material');
|
||||
runCLI('add @angular/pwa');
|
||||
runCLI('add @ngrx/store');
|
||||
runCLI('add @ngrx/effects');
|
||||
|
||||
// Add Nx
|
||||
runCLI('add @nrwl/schematics');
|
||||
});
|
||||
|
||||
it('should handle workspaces with no e2e project', async () => {
|
||||
// create a new AngularCLI app
|
||||
runNgNew();
|
||||
|
||||
// Remove e2e
|
||||
runCommand('rm -rf e2e');
|
||||
const existingAngularJson = readJson('angular.json');
|
||||
delete existingAngularJson.projects['proj-e2e'];
|
||||
updateFile('angular.json', JSON.stringify(existingAngularJson, null, 2));
|
||||
|
||||
// Add @nrwl/schematics
|
||||
const result = await runCLIAsync(
|
||||
'add @nrwl/schematics --npmScope projscope --skip-install'
|
||||
);
|
||||
|
||||
checkFilesExist(
|
||||
'.prettierrc',
|
||||
'apps/proj/src/main.ts',
|
||||
'apps/proj/src/app/app.module.ts'
|
||||
);
|
||||
|
||||
expect(result.stderr).toContain(
|
||||
'No e2e project was migrated because there was none declared in angular.json'
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle type array at tslint builder options.tsConfig (e2e project)', () => {
|
||||
// create a new AngularCLI app
|
||||
runNgNew();
|
||||
|
||||
// set array at tslint builder options.tsConfig
|
||||
const existingAngularJson = readJson('angular.json');
|
||||
existingAngularJson.projects[
|
||||
'proj-e2e'
|
||||
].architect.lint.options.tsConfig = ['e2e/tsconfig.e2e.json'];
|
||||
updateFile('angular.json', JSON.stringify(existingAngularJson, null, 2));
|
||||
|
||||
// Add @nrwl/schematics
|
||||
runCLI('add @nrwl/schematics --npmScope projscope --skip-install');
|
||||
|
||||
const updatedAngularCLIJson = readJson('angular.json');
|
||||
|
||||
expect(updatedAngularCLIJson.projects['proj-e2e'].architect.lint).toEqual(
|
||||
{
|
||||
builder: '@angular-devkit/build-angular:tslint',
|
||||
options: {
|
||||
tsConfig: ['apps/proj-e2e/tsconfig.e2e.json'],
|
||||
exclude: ['**/node_modules/**']
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle different types of errors', () => {
|
||||
// create a new AngularCLI app
|
||||
runNgNew();
|
||||
|
||||
// Only remove e2e directory
|
||||
runCommand('mv e2e e2e-bak');
|
||||
try {
|
||||
runCLI('add @nrwl/schematics --npmScope projscope --skip-install');
|
||||
fail('Did not handle not having a e2e directory');
|
||||
} catch (e) {
|
||||
expect(e.stderr.toString()).toContain(
|
||||
'Your workspace could not be converted into an Nx Workspace because of the above error.'
|
||||
);
|
||||
}
|
||||
|
||||
// Put e2e back
|
||||
runCommand('mv e2e-bak e2e');
|
||||
|
||||
// Remove package.json
|
||||
runCommand('mv package.json package.json.bak');
|
||||
try {
|
||||
runCLI('add @nrwl/schematics --npmScope projscope --skip-install');
|
||||
fail('Did not handle not having a package.json');
|
||||
} catch (e) {
|
||||
expect(e.stderr.toString()).toContain(
|
||||
'Your workspace could not be converted into an Nx Workspace because of the above error.'
|
||||
);
|
||||
}
|
||||
|
||||
// Put package.json back
|
||||
runCommand('mv package.json.bak package.json');
|
||||
|
||||
// Remove src
|
||||
runCommand('mv src src-bak');
|
||||
try {
|
||||
runCLI('add @nrwl/schematics --npmScope projscope --skip-install');
|
||||
fail('Did not handle not having a src directory');
|
||||
} catch (e) {
|
||||
expect(e.stderr.toString()).toContain('Path: src does not exist');
|
||||
}
|
||||
|
||||
// Put src back
|
||||
runCommand('mv src-bak src');
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle different types of errors', () => {
|
||||
// create a new AngularCLI app
|
||||
runNgNew();
|
||||
|
||||
// Only remove e2e directory
|
||||
runCommand('mv e2e e2e-bak');
|
||||
try {
|
||||
runCLI('add @nrwl/schematics --npmScope projscope --skip-install');
|
||||
fail('Did not handle not having a e2e directory');
|
||||
} catch (e) {
|
||||
expect(e.stderr.toString()).toContain(
|
||||
'Your workspace could not be converted into an Nx Workspace because of the above error.'
|
||||
);
|
||||
}
|
||||
|
||||
// Put e2e back
|
||||
runCommand('mv e2e-bak e2e');
|
||||
|
||||
// Remove package.json
|
||||
runCommand('mv package.json package.json.bak');
|
||||
try {
|
||||
runCLI('add @nrwl/schematics --npmScope projscope --skip-install');
|
||||
fail('Did not handle not having a package.json');
|
||||
} catch (e) {
|
||||
expect(e.stderr.toString()).toContain(
|
||||
'Your workspace could not be converted into an Nx Workspace because of the above error.'
|
||||
);
|
||||
}
|
||||
|
||||
// Put package.json back
|
||||
runCommand('mv package.json.bak package.json');
|
||||
|
||||
// Remove src
|
||||
runCommand('mv src src-bak');
|
||||
try {
|
||||
runCLI('add @nrwl/schematics --npmScope projscope --skip-install');
|
||||
fail('Did not handle not having a src directory');
|
||||
} catch (e) {
|
||||
expect(e.stderr.toString()).toContain('Path: src does not exist');
|
||||
}
|
||||
|
||||
// Put src back
|
||||
runCommand('mv src-bak src');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -9,115 +9,96 @@ import {
|
||||
runNgNew,
|
||||
cleanup,
|
||||
copyMissingPackages,
|
||||
getSize
|
||||
getSize,
|
||||
expectTestsPass,
|
||||
runCLIAsync,
|
||||
ensureProject,
|
||||
uniq,
|
||||
runsInWSL
|
||||
} from '../utils';
|
||||
import { toClassName } from '@nrwl/schematics/src/utils/name-utils';
|
||||
|
||||
describe('Nrwl Workspace', () => {
|
||||
it('should work', () => {
|
||||
newProject();
|
||||
newApp('myApp --directory=myDir');
|
||||
newLib('myLib --directory=myDir');
|
||||
fit('should work', async () => {
|
||||
ensureProject();
|
||||
const myapp = uniq('myapp');
|
||||
const mylib = uniq('mylib');
|
||||
newApp(`${myapp} --directory=myDir`);
|
||||
newLib(`${mylib} --directory=myDir`);
|
||||
|
||||
updateFile(
|
||||
'apps/my-dir/my-app/src/app/app.module.ts',
|
||||
`apps/my-dir/${myapp}/src/app/app.module.ts`,
|
||||
`
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { MyDirMyLibModule } from '@proj/my-dir/my-lib';
|
||||
import { MyDir${toClassName(
|
||||
mylib
|
||||
)}Module } from '@proj/my-dir/${mylib}';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule, MyDirMyLibModule],
|
||||
imports: [BrowserModule, MyDir${toClassName(mylib)}Module],
|
||||
declarations: [AppComponent],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule {}
|
||||
`
|
||||
);
|
||||
runCLI('build --prod --project=my-dir-my-app --output-hashing none');
|
||||
expect(exists('./tmp/proj/dist/apps/my-dir/my-app/main.js')).toEqual(true);
|
||||
runCLI(`build --prod --project=my-dir-${myapp} --output-hashing none`);
|
||||
expect(exists(`./tmp/proj/dist/apps/my-dir/${myapp}/main.js`)).toEqual(
|
||||
true
|
||||
);
|
||||
|
||||
// This is a loose requirement because there are a lot of
|
||||
// influences external from this project that affect this.
|
||||
const bundleSize = getSize('./tmp/proj/dist/apps/my-dir/my-app/main.js');
|
||||
const bundleSize = getSize(`./tmp/proj/dist/apps/my-dir/${myapp}/main.js`);
|
||||
console.log(`The current bundle size is ${bundleSize} KB`);
|
||||
expect(bundleSize).toBeLessThanOrEqual(200000);
|
||||
|
||||
// running tests for the app
|
||||
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
||||
'Executed 3 of 3 SUCCESS'
|
||||
expectTestsPass(
|
||||
await runCLIAsync(`test --project=my-dir-${myapp} --no-watch`)
|
||||
);
|
||||
|
||||
// running tests for the lib
|
||||
expect(runCLI('test --project=my-dir-my-lib --no-watch')).toContain(
|
||||
'Executed 1 of 1 SUCCESS'
|
||||
expectTestsPass(
|
||||
await runCLIAsync(`test --project=my-dir-${mylib} --no-watch`)
|
||||
);
|
||||
|
||||
// e2e tests
|
||||
expect(runCLI('e2e --project=my-dir-my-app-e2e')).toContain(
|
||||
'Executed 1 of 1 spec SUCCESS'
|
||||
if (!runsInWSL()) {
|
||||
expect(
|
||||
runCLI(`e2e --project=my-dir-${myapp}-e2e --headless --watch=false`)
|
||||
).toContain('All specs passed!');
|
||||
}
|
||||
}, 1000000);
|
||||
|
||||
it('should support router config generation (lazy)', async () => {
|
||||
ensureProject();
|
||||
const myapp = uniq('myapp');
|
||||
const mylib = uniq('mylib');
|
||||
newApp(`${myapp} --directory=myDir --routing`);
|
||||
newLib(
|
||||
`${mylib} --directory=myDir --routing --lazy --parentModule=apps/my-dir/${myapp}/src/app/app.module.ts`
|
||||
);
|
||||
|
||||
runCLI(`build --aot --project=my-dir-${myapp}`);
|
||||
expectTestsPass(
|
||||
await runCLIAsync(`test --project=my-dir-${myapp} --no-watch`)
|
||||
);
|
||||
}, 1000000);
|
||||
|
||||
it('should support router config generation (lazy)', () => {
|
||||
newProject();
|
||||
newApp('myApp --directory=myDir --routing');
|
||||
it('should support router config generation (eager)', async () => {
|
||||
ensureProject();
|
||||
const myapp = uniq('myapp');
|
||||
newApp(`${myapp} --directory=myDir --routing`);
|
||||
const mylib = uniq('mylib');
|
||||
newLib(
|
||||
'myLib --directory=myDir --routing --lazy --parentModule=apps/my-dir/my-app/src/app/app.module.ts'
|
||||
`${mylib} --directory=myDir --routing --parentModule=apps/my-dir/${myapp}/src/app/app.module.ts`
|
||||
);
|
||||
|
||||
runCLI('build --aot --project=my-dir-my-app');
|
||||
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
||||
'Executed 3 of 3 SUCCESS'
|
||||
runCLI(`build --aot --project=my-dir-${myapp}`);
|
||||
expectTestsPass(
|
||||
await runCLIAsync(`test --project=my-dir-${myapp} --no-watch`)
|
||||
);
|
||||
}, 1000000);
|
||||
|
||||
it('should support router config generation (eager)', () => {
|
||||
newProject();
|
||||
newApp('myApp --directory=myDir --routing');
|
||||
newLib(
|
||||
'myLib --directory=myDir --routing --parentModule=apps/my-dir/my-app/src/app/app.module.ts'
|
||||
);
|
||||
|
||||
runCLI('build --aot --project=my-dir-my-app');
|
||||
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
||||
'Executed 3 of 3 SUCCESS'
|
||||
);
|
||||
}, 1000000);
|
||||
|
||||
it('should support scss for styles', () => {
|
||||
cleanup();
|
||||
runNgNew('--collection=@nrwl/schematics --npmScope=proj --style scss');
|
||||
copyMissingPackages();
|
||||
newApp('myApp --directory=myDir');
|
||||
newLib(
|
||||
'myLib --directory=myDir --routing --parentModule=apps/my-dir/my-app/src/app/app.module.ts'
|
||||
);
|
||||
runCLI('generate component comp --project my-dir-my-app');
|
||||
runCLI('generate component comp --project my-dir-my-lib');
|
||||
|
||||
expect(
|
||||
exists('./tmp/proj/apps/my-dir/my-app/src/app/comp/comp.component.scss')
|
||||
).toEqual(true);
|
||||
expect(
|
||||
exists('./tmp/proj/libs/my-dir/my-lib/src/lib/comp/comp.component.scss')
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
// TODO: Fix this test. This test was incorrect before.. and fails after fixing it.
|
||||
xit('should not generate e2e configuration', () => {
|
||||
newProject();
|
||||
newApp('myApp --e2eTestRunner=none');
|
||||
|
||||
// Making sure the angular.json file doesn't contain e2e project
|
||||
const angularJson = readJson('angular.json');
|
||||
expect(angularJson.projects['my-app-e2e']).toBeUndefined();
|
||||
|
||||
// Making sure the nx.json file doesn't contain e2e project
|
||||
const nxJson = readJson('angular.json');
|
||||
expect(nxJson.projects['my-app-e2e']).toBeUndefined();
|
||||
|
||||
// Making sure the e2e folder is not created
|
||||
expect(exists('./tmp/proj/apps/my-app-e2e')).toBeFalsy();
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
@ -1,30 +1,33 @@
|
||||
import { newApp, newProject, runCLI, copyMissingPackages } from '../utils';
|
||||
import {
|
||||
newApp,
|
||||
runCLI,
|
||||
expectTestsPass,
|
||||
runCLIAsync,
|
||||
uniq,
|
||||
ensureProject
|
||||
} from '../utils';
|
||||
|
||||
describe('ngrx', () => {
|
||||
it('should work', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
it('should work', async () => {
|
||||
ensureProject();
|
||||
|
||||
const myapp = uniq('myapp');
|
||||
newApp(myapp);
|
||||
|
||||
// Generate root ngrx state management
|
||||
runCLI(
|
||||
'generate ngrx users --module=apps/myapp/src/app/app.module.ts --root'
|
||||
`generate ngrx users --module=apps/${myapp}/src/app/app.module.ts --root`
|
||||
);
|
||||
copyMissingPackages();
|
||||
|
||||
const mylib = uniq('mylib');
|
||||
// Generate feature library and ngrx state within that library
|
||||
runCLI('g @nrwl/schematics:lib feature-flights --prefix=fl');
|
||||
runCLI(`g lib ${mylib} --prefix=fl`);
|
||||
runCLI(
|
||||
'generate ngrx flights --module=libs/feature-flights/src/lib/feature-flights.module.ts --facade'
|
||||
`generate ngrx flights --module=libs/${mylib}/src/lib/${mylib}.module.ts --facade`
|
||||
);
|
||||
|
||||
expect(runCLI('lint', { silenceError: true })).not.toContain('ERROR');
|
||||
|
||||
expect(runCLI('build')).toContain('chunk {main} main.js,');
|
||||
expect(runCLI('test myapp --no-watch')).toContain(
|
||||
'Executed 10 of 10 SUCCESS'
|
||||
);
|
||||
expect(runCLI('test feature-flights --no-watch')).toContain(
|
||||
'Executed 10 of 10 SUCCESS'
|
||||
);
|
||||
expect(runCLI(`build ${myapp}`)).toContain('chunk {main} main.js,');
|
||||
expectTestsPass(await runCLIAsync(`test ${myapp} --no-watch`));
|
||||
expectTestsPass(await runCLIAsync(`test ${mylib} --no-watch`));
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
@ -5,7 +5,9 @@ import {
|
||||
exists,
|
||||
runCLIAsync,
|
||||
updateFile,
|
||||
readJson
|
||||
readJson,
|
||||
ensureProject,
|
||||
uniq
|
||||
} from '../utils';
|
||||
import { fork, spawn, execSync } from 'child_process';
|
||||
import * as http from 'http';
|
||||
@ -28,18 +30,13 @@ function getData() {
|
||||
}
|
||||
|
||||
describe('Node Applications', () => {
|
||||
beforeAll(() => {
|
||||
newProject();
|
||||
runCLI('generate jest');
|
||||
copyMissingPackages();
|
||||
});
|
||||
|
||||
it('should be able to generate a node application', async done => {
|
||||
runCLI('generate node-app node-app1');
|
||||
copyMissingPackages();
|
||||
ensureProject();
|
||||
const nodeapp = uniq('nodeapp');
|
||||
runCLI(`generate node-app ${nodeapp} --framework express`);
|
||||
|
||||
updateFile(
|
||||
'apps/node-app1/src/app/test.spec.ts',
|
||||
`apps/${nodeapp}/src/app/test.spec.ts`,
|
||||
`
|
||||
describe('test', () => {
|
||||
it('should work', () => {
|
||||
@ -49,23 +46,23 @@ describe('Node Applications', () => {
|
||||
`
|
||||
);
|
||||
|
||||
updateFile('apps/node-app1/src/assets/file.txt', ``);
|
||||
const jestResult = await runCLIAsync('test node-app1');
|
||||
updateFile(`apps/${nodeapp}/src/assets/file.txt`, ``);
|
||||
const jestResult = await runCLIAsync(`test ${nodeapp}`);
|
||||
expect(jestResult.stderr).toContain('Test Suites: 1 passed, 1 total');
|
||||
|
||||
await runCLIAsync('build node-app1');
|
||||
await runCLIAsync(`build ${nodeapp}`);
|
||||
|
||||
expect(exists('./tmp/proj/dist/apps/node-app1/main.js')).toBeTruthy();
|
||||
expect(exists(`./tmp/proj/dist/apps/${nodeapp}/main.js`)).toBeTruthy();
|
||||
expect(
|
||||
exists('./tmp/proj/dist/apps/node-app1/assets/file.txt')
|
||||
exists(`./tmp/proj/dist/apps/${nodeapp}/assets/file.txt`)
|
||||
).toBeTruthy();
|
||||
expect(exists('./tmp/proj/dist/apps/node-app1/main.js.map')).toBeTruthy();
|
||||
expect(exists(`./tmp/proj/dist/apps/${nodeapp}/main.js.map`)).toBeTruthy();
|
||||
|
||||
const server = fork(
|
||||
path.join(
|
||||
__dirname,
|
||||
'../../../tmp/proj',
|
||||
`./dist/apps/node-app1/main.js`
|
||||
`./dist/apps/${nodeapp}/main.js`
|
||||
),
|
||||
[],
|
||||
{
|
||||
@ -80,7 +77,7 @@ describe('Node Applications', () => {
|
||||
expect(data.toString()).toContain('Listening at http://localhost:3333');
|
||||
const result = await getData();
|
||||
|
||||
expect(result).toEqual('Welcome to node-app1!');
|
||||
expect(result).toEqual(`Welcome to ${nodeapp}!`);
|
||||
treeKill(server.pid, 'SIGTERM', err => {
|
||||
expect(err).toBeFalsy();
|
||||
resolve();
|
||||
@ -89,7 +86,7 @@ describe('Node Applications', () => {
|
||||
});
|
||||
|
||||
const config = readJson('angular.json');
|
||||
config.projects['node-app1'].architect.waitAndPrint = {
|
||||
config.projects[nodeapp].architect.waitAndPrint = {
|
||||
builder: '@nrwl/builders:run-commands',
|
||||
options: {
|
||||
commands: [
|
||||
@ -100,14 +97,14 @@ describe('Node Applications', () => {
|
||||
readyWhen: 'DONE'
|
||||
}
|
||||
};
|
||||
config.projects['node-app1'].architect.serve.options.waitUntilTargets = [
|
||||
'node-app1:waitAndPrint'
|
||||
config.projects[nodeapp].architect.serve.options.waitUntilTargets = [
|
||||
`${nodeapp}:waitAndPrint`
|
||||
];
|
||||
updateFile('angular.json', JSON.stringify(config));
|
||||
|
||||
const process = spawn(
|
||||
'node',
|
||||
['./node_modules/.bin/ng', 'serve', 'node-app1'],
|
||||
['./node_modules/.bin/ng', 'serve', nodeapp],
|
||||
{
|
||||
cwd: './tmp/proj'
|
||||
}
|
||||
@ -121,7 +118,7 @@ describe('Node Applications', () => {
|
||||
}
|
||||
|
||||
const result = await getData();
|
||||
expect(result).toEqual('Welcome to node-app1!');
|
||||
expect(result).toEqual(`Welcome to ${nodeapp}!`);
|
||||
treeKill(process.pid, 'SIGTERM', err => {
|
||||
expect(collectedOutput.startsWith('DONE')).toBeTruthy();
|
||||
expect(err).toBeFalsy();
|
||||
@ -131,23 +128,28 @@ describe('Node Applications', () => {
|
||||
}, 30000);
|
||||
|
||||
it('should be able to generate a nest application', async done => {
|
||||
runCLI('generate node-app nest-app --framework nestjs');
|
||||
copyMissingPackages();
|
||||
ensureProject();
|
||||
const nestapp = uniq('nestapp');
|
||||
runCLI(`generate node-app ${nestapp} --framework nestjs`);
|
||||
|
||||
updateFile('apps/nest-app/src/assets/file.txt', ``);
|
||||
const jestResult = await runCLIAsync('test nest-app');
|
||||
updateFile(`apps/${nestapp}/src/assets/file.txt`, ``);
|
||||
const jestResult = await runCLIAsync(`test ${nestapp}`);
|
||||
expect(jestResult.stderr).toContain('Test Suites: 2 passed, 2 total');
|
||||
|
||||
await runCLIAsync('build nest-app');
|
||||
await runCLIAsync(`build ${nestapp}`);
|
||||
|
||||
expect(exists('./tmp/proj/dist/apps/nest-app/main.js')).toBeTruthy();
|
||||
expect(exists(`./tmp/proj/dist/apps/${nestapp}/main.js`)).toBeTruthy();
|
||||
expect(
|
||||
exists('./tmp/proj/dist/apps/nest-app/assets/file.txt')
|
||||
exists(`./tmp/proj/dist/apps/${nestapp}/assets/file.txt`)
|
||||
).toBeTruthy();
|
||||
expect(exists('./tmp/proj/dist/apps/nest-app/main.js.map')).toBeTruthy();
|
||||
expect(exists(`./tmp/proj/dist/apps/${nestapp}/main.js.map`)).toBeTruthy();
|
||||
|
||||
const server = fork(
|
||||
path.join(__dirname, '../../../tmp/proj', `./dist/apps/nest-app/main.js`),
|
||||
path.join(
|
||||
__dirname,
|
||||
'../../../tmp/proj',
|
||||
`./dist/apps/${nestapp}/main.js`
|
||||
),
|
||||
[],
|
||||
{
|
||||
cwd: './tmp/proj',
|
||||
@ -162,7 +164,7 @@ describe('Node Applications', () => {
|
||||
if (message.includes('Listening at http://localhost:3333')) {
|
||||
const result = await getData();
|
||||
|
||||
expect(result).toEqual('Welcome to nest-app!');
|
||||
expect(result).toEqual(`Welcome to ${nestapp}!`);
|
||||
treeKill(server.pid, 'SIGTERM', err => {
|
||||
expect(err).toBeFalsy();
|
||||
resolve();
|
||||
@ -173,7 +175,7 @@ describe('Node Applications', () => {
|
||||
|
||||
const process = spawn(
|
||||
'node',
|
||||
['./node_modules/.bin/ng', 'serve', 'nest-app'],
|
||||
['./node_modules/.bin/ng', 'serve', nestapp],
|
||||
{
|
||||
cwd: './tmp/proj'
|
||||
}
|
||||
@ -184,7 +186,7 @@ describe('Node Applications', () => {
|
||||
return;
|
||||
}
|
||||
const result = await getData();
|
||||
expect(result).toEqual('Welcome to nest-app!');
|
||||
expect(result).toEqual(`Welcome to ${nestapp}!`);
|
||||
treeKill(process.pid, 'SIGTERM', err => {
|
||||
expect(err).toBeFalsy();
|
||||
done();
|
||||
@ -193,11 +195,14 @@ describe('Node Applications', () => {
|
||||
}, 30000);
|
||||
|
||||
it('should be able to generate an empty application', async () => {
|
||||
runCLI('generate node-app node-app2 --framework none');
|
||||
updateFile('apps/node-app2/src/main.ts', `console.log('Hello World!');`);
|
||||
await runCLIAsync('build node-app2');
|
||||
expect(exists('./tmp/proj/dist/apps/node-app2/main.js')).toBeTruthy();
|
||||
const result = execSync('node dist/apps/node-app2/main.js', {
|
||||
ensureProject();
|
||||
const nodeapp = uniq('nodeapp');
|
||||
|
||||
runCLI(`generate node-app ${nodeapp} --framework none`);
|
||||
updateFile(`apps/${nodeapp}/src/main.ts`, `console.log('Hello World!');`);
|
||||
await runCLIAsync(`build ${nodeapp}`);
|
||||
expect(exists(`./tmp/proj/dist/apps/${nodeapp}/main.js`)).toBeTruthy();
|
||||
const result = execSync(`node dist/apps/${nodeapp}/main.js`, {
|
||||
cwd: './tmp/proj'
|
||||
}).toString();
|
||||
expect(result).toContain('Hello World!');
|
||||
|
||||
@ -1,12 +1,22 @@
|
||||
import { newApp, newProject, runCLI, updateFile } from '../utils';
|
||||
import {
|
||||
ensureProject,
|
||||
expectTestsPass,
|
||||
newApp,
|
||||
newProject,
|
||||
runCLI,
|
||||
runCLIAsync,
|
||||
uniq,
|
||||
updateFile
|
||||
} from '../utils';
|
||||
|
||||
describe('Upgrade', () => {
|
||||
it('should generate an UpgradeModule setup', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
it('should generate an UpgradeModule setup', async () => {
|
||||
ensureProject();
|
||||
const myapp = uniq('myapp');
|
||||
newApp(`${myapp} --unit-test-runner=karma`);
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/legacy.js',
|
||||
`apps/${myapp}/src/legacy.js`,
|
||||
`
|
||||
const angular = window.angular.module('legacy', []);
|
||||
angular.component('proj-root-legacy', {
|
||||
@ -16,22 +26,20 @@ describe('Upgrade', () => {
|
||||
);
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.html',
|
||||
`apps/${myapp}/src/app/app.component.html`,
|
||||
`
|
||||
EXPECTED [<proj-root-legacy></proj-root-legacy>]
|
||||
`
|
||||
);
|
||||
|
||||
updateFile('apps/myapp/src/app/app.component.spec.ts', ``);
|
||||
updateFile(`apps/${myapp}/src/app/app.component.spec.ts`, ``);
|
||||
|
||||
runCLI(
|
||||
'generate upgrade-module legacy --angularJsImport=./legacy ' +
|
||||
'--angularJsCmpSelector=proj-root-legacy --project=myapp'
|
||||
`--angularJsCmpSelector=proj-root-legacy --project=${myapp}`
|
||||
);
|
||||
|
||||
expect(runCLI('lint', { silenceError: true })).not.toContain('ERROR');
|
||||
|
||||
runCLI('build');
|
||||
runCLI('test --no-watch');
|
||||
runCLI(`build ${myapp}`);
|
||||
expect(runCLI(`test ${myapp} --no-watch`)).toContain('1 SUCCESS');
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
116
e2e/utils.ts
116
e2e/utils.ts
@ -1,52 +1,61 @@
|
||||
import { execSync, exec } from 'child_process';
|
||||
import { exec, execSync } from 'child_process';
|
||||
import { readFileSync, statSync, writeFileSync } from 'fs';
|
||||
import { ensureDirSync } from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
|
||||
const projectName: string = 'proj';
|
||||
|
||||
export function uniq(prefix: string) {
|
||||
return `${prefix}${Math.floor(Math.random() * 10000000)}`;
|
||||
}
|
||||
|
||||
export function runNgNew(command?: string, silent?: boolean): string {
|
||||
return execSync(
|
||||
const buffer = execSync(
|
||||
`../node_modules/.bin/ng new proj --no-interactive ${command}`,
|
||||
{
|
||||
cwd: `./tmp`,
|
||||
...(silent ? { stdio: ['ignore', 'ignore', 'ignore'] } : {})
|
||||
}
|
||||
).toString();
|
||||
);
|
||||
return buffer ? buffer.toString() : null;
|
||||
}
|
||||
|
||||
export function newProject(): void {
|
||||
cleanup();
|
||||
if (!directoryExists('./tmp/proj_backup')) {
|
||||
// TODO delete the try catch after 0.8.0 is released
|
||||
try {
|
||||
runNgNew('--collection=@nrwl/schematics --npmScope=proj', true);
|
||||
} catch (e) {}
|
||||
runNgNew('--collection=@nrwl/schematics --npmScope=proj', true);
|
||||
copyMissingPackages();
|
||||
execSync('mv ./tmp/proj ./tmp/proj_backup');
|
||||
}
|
||||
execSync('cp -a ./tmp/proj_backup ./tmp/proj');
|
||||
}
|
||||
|
||||
export function newBazelProject(): void {
|
||||
cleanup();
|
||||
if (!directoryExists('./tmp/proj_bazel_backup')) {
|
||||
// TODO delete the try catch after 0.8.0 is released
|
||||
try {
|
||||
runNgNew('--collection=@nrwl/bazel --npmScope=proj', true);
|
||||
} catch (e) {}
|
||||
copyMissingPackages();
|
||||
execSync('mv ./tmp/proj ./tmp/proj_backup');
|
||||
export function ensureProject(): void {
|
||||
if (!directoryExists('./tmp/proj')) {
|
||||
newProject();
|
||||
}
|
||||
execSync('cp -a ./tmp/proj_bazel_backup ./tmp/proj');
|
||||
}
|
||||
|
||||
export function createNxWorkspace(command: string): string {
|
||||
cleanup();
|
||||
return execSync(
|
||||
`node ../node_modules/@nrwl/schematics/bin/create-nx-workspace.js ${command}`,
|
||||
{ cwd: `./tmp` }
|
||||
).toString();
|
||||
export function runsInWSL() {
|
||||
return !!process.env['WINDOWSTMP'];
|
||||
}
|
||||
|
||||
export function patchKarmaToWorkOnWSL(): void {
|
||||
try {
|
||||
const karma = readFile('karma.conf.js');
|
||||
if (process.env['WINDOWSTMP']) {
|
||||
updateFile(
|
||||
'karma.conf.js',
|
||||
karma.replace(
|
||||
`const { constants } = require('karma');`,
|
||||
`
|
||||
const { constants } = require('karma');
|
||||
process.env['TMPDIR']="${process.env['WINDOWSTMP']}";
|
||||
`
|
||||
)
|
||||
);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
export function copyMissingPackages(): void {
|
||||
@ -55,15 +64,53 @@ export function copyMissingPackages(): void {
|
||||
'@nrwl',
|
||||
'angular',
|
||||
'@angular/upgrade',
|
||||
'@angular-devkit/build-ng-packagr',
|
||||
'npm-run-all',
|
||||
'yargs',
|
||||
'yargs-parser'
|
||||
'yargs-parser',
|
||||
|
||||
'cypress',
|
||||
'@types/jquery',
|
||||
'jest',
|
||||
'@types/jest',
|
||||
'jest-preset-angular',
|
||||
'karma',
|
||||
'karma-chrome-launcher',
|
||||
'karma-coverage-istanbul-reporter',
|
||||
'karma-jasmine',
|
||||
'karma-jasmine-html-reporter',
|
||||
'jasmine-core',
|
||||
'jasmine-spec-reporter',
|
||||
'jasmine-marbles',
|
||||
'@types/jasmine',
|
||||
'@types/jasminewd2',
|
||||
'@nestjs',
|
||||
'express',
|
||||
'@types/express'
|
||||
];
|
||||
modulesToCopy.forEach(m => copyNodeModule(projectName, m));
|
||||
updateFile(
|
||||
'node_modules/@angular-devkit/schematics/tasks/node-package/executor.js',
|
||||
`
|
||||
function default_1() {
|
||||
return () => {
|
||||
const rxjs = require("rxjs");
|
||||
return new rxjs.Observable(obs => {
|
||||
obs.next();
|
||||
obs.complete();
|
||||
});
|
||||
};
|
||||
}
|
||||
exports.default = default_1;
|
||||
`
|
||||
);
|
||||
|
||||
execSync('rm -rf tmp/proj/node_modules/.bin/webpack');
|
||||
execSync(
|
||||
`cp -a node_modules/.bin/webpack tmp/proj/node_modules/.bin/webpack`
|
||||
);
|
||||
execSync(`rm -rf ./tmp/proj/node_modules/cypress/node_modules/@types`);
|
||||
execSync(`rm -rf ./tmp/proj/@types/sinon-chai/node_modules/@types`);
|
||||
}
|
||||
|
||||
function copyNodeModule(path: string, name: string) {
|
||||
@ -127,16 +174,21 @@ export function runCLI(
|
||||
}
|
||||
}
|
||||
|
||||
export function expectTestsPass(v: { stdout: string; stderr: string }) {
|
||||
expect(v.stderr).toContain('Ran all test suites');
|
||||
expect(v.stderr).not.toContain('fail');
|
||||
}
|
||||
|
||||
export function newApp(name: string): string {
|
||||
return runCLI(`generate app --no-interactive ${name}`);
|
||||
const r = runCLI(`generate app --no-interactive ${name}`);
|
||||
patchKarmaToWorkOnWSL();
|
||||
return r;
|
||||
}
|
||||
|
||||
export function newLib(name: string): string {
|
||||
return runCLI(`generate lib --no-interactive ${name}`);
|
||||
}
|
||||
|
||||
export function newModule(name: string): string {
|
||||
return runCLI(`generate module ${name}`);
|
||||
const r = runCLI(`generate lib --no-interactive ${name}`);
|
||||
patchKarmaToWorkOnWSL();
|
||||
return r;
|
||||
}
|
||||
|
||||
export function runCommand(command: string): string {
|
||||
@ -179,10 +231,6 @@ export function cleanup() {
|
||||
execSync('rm -rf ./tmp/proj');
|
||||
}
|
||||
|
||||
export function purge() {
|
||||
execSync('rm -rf ./tmp');
|
||||
}
|
||||
|
||||
export function getCwd(): string {
|
||||
return process.cwd();
|
||||
}
|
||||
|
||||
13
package.json
13
package.json
@ -9,6 +9,7 @@
|
||||
"commit": "git-cz",
|
||||
"checkcommit": "node ./scripts/commit-lint.js",
|
||||
"e2e": "./scripts/e2e.sh",
|
||||
"e2e-rerun": "./scripts/e2e-rerun.sh",
|
||||
"format": "./scripts/format.sh",
|
||||
"linknpm": "./scripts/link.sh",
|
||||
"nx-release": "./scripts/nx-release.js",
|
||||
@ -24,6 +25,7 @@
|
||||
"@angular-devkit/build-angular": "~0.12.2",
|
||||
"@angular-devkit/build-webpack": "~0.12.2",
|
||||
"@angular-devkit/core": "~7.2.2",
|
||||
"@angular-devkit/build-ng-packagr": "^0.13.1",
|
||||
"@angular-devkit/schematics": "~7.2.2",
|
||||
"@angular/cli": "~7.2.2",
|
||||
"@angular/common": "^7.2.1",
|
||||
@ -65,10 +67,13 @@
|
||||
"jasmine-spec-reporter": "~4.2.1",
|
||||
"jest": "^23.4.0",
|
||||
"jest-jasmine2": "^23.4.1",
|
||||
"jest-preset-angular": "^6.0.2",
|
||||
"karma": "~2.0.0",
|
||||
"karma-chrome-launcher": "~2.2.0",
|
||||
"karma-jasmine": "~1.1.1",
|
||||
"karma-webpack": "2.0.4",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"karma-coverage-istanbul-reporter": "~2.0.1",
|
||||
"license-webpack-plugin": "^1.4.0",
|
||||
"ng-packagr": "4.3.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
@ -92,7 +97,13 @@
|
||||
"yargs": "^11.0.0",
|
||||
"yargs-parser": "10.0.0",
|
||||
"zone.js": "^0.8.26",
|
||||
"dotenv": "6.2.0"
|
||||
"dotenv": "6.2.0",
|
||||
"@nestjs/core": "5.5.0",
|
||||
"@nestjs/common": "5.5.0",
|
||||
"@nestjs/testing": "5.5.0",
|
||||
"@nestjs/schematics": "5.11.2",
|
||||
"express": "4.16.3",
|
||||
"@types/express": "4.16.0"
|
||||
},
|
||||
"author": "Victor Savkin",
|
||||
"license": "MIT",
|
||||
|
||||
@ -153,6 +153,35 @@ describe('Update 7.6.0', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('setting defaults to karma, protractor, express', () => {
|
||||
it('should default to karma, protractor and express', async () => {
|
||||
const result = await schematicRunner
|
||||
.runSchematicAsync('update-7.6.0', {}, initialTree)
|
||||
.toPromise();
|
||||
|
||||
expect(
|
||||
readJsonInTree(result, 'angular.json').schematics[
|
||||
'@nrwl/schematics:library'
|
||||
].unitTestRunner
|
||||
).toEqual('karma');
|
||||
expect(
|
||||
readJsonInTree(result, 'angular.json').schematics[
|
||||
'@nrwl/schematics:application'
|
||||
].unitTestRunner
|
||||
).toEqual('karma');
|
||||
expect(
|
||||
readJsonInTree(result, 'angular.json').schematics[
|
||||
'@nrwl/schematics:application'
|
||||
].e2eTestRunner
|
||||
).toEqual('protractor');
|
||||
expect(
|
||||
readJsonInTree(result, 'angular.json').schematics[
|
||||
'@nrwl/schematics:node-application'
|
||||
].framework
|
||||
).toEqual('express');
|
||||
});
|
||||
});
|
||||
|
||||
describe('NgRx Migration', () => {
|
||||
it('should update ngrx to 7.1.0', async () => {
|
||||
const result = await schematicRunner
|
||||
|
||||
@ -372,12 +372,42 @@ const addDotEnv = updateJsonInTree('package.json', json => {
|
||||
return json;
|
||||
});
|
||||
|
||||
const setDefaults = updateJsonInTree('angular.json', json => {
|
||||
if (!json.schematics) {
|
||||
json.schematics = {};
|
||||
}
|
||||
if (!json.schematics['@nrwl/schematics:library']) {
|
||||
json.schematics['@nrwl/schematics:library'] = {};
|
||||
}
|
||||
if (!json.schematics['@nrwl/schematics:library'].unitTestRunner) {
|
||||
json.schematics['@nrwl/schematics:library'].unitTestRunner = 'karma';
|
||||
}
|
||||
if (!json.schematics['@nrwl/schematics:application']) {
|
||||
json.schematics['@nrwl/schematics:application'] = {};
|
||||
}
|
||||
if (!json.schematics['@nrwl/schematics:application'].unitTestRunner) {
|
||||
json.schematics['@nrwl/schematics:application'].unitTestRunner = 'karma';
|
||||
}
|
||||
if (!json.schematics['@nrwl/schematics:application'].e2eTestRunner) {
|
||||
json.schematics['@nrwl/schematics:application'].e2eTestRunner =
|
||||
'protractor';
|
||||
}
|
||||
if (!json.schematics['@nrwl/schematics:node-application']) {
|
||||
json.schematics['@nrwl/schematics:node-application'] = {};
|
||||
}
|
||||
if (!json.schematics['@nrwl/schematics:node-application'].framework) {
|
||||
json.schematics['@nrwl/schematics:node-application'].framework = 'express';
|
||||
}
|
||||
return json;
|
||||
});
|
||||
|
||||
export default function(): Rule {
|
||||
return chain([
|
||||
addExtensionRecommendations,
|
||||
addDotEnv,
|
||||
migrateNgrx,
|
||||
updateNgrx,
|
||||
setDefaults,
|
||||
formatFiles()
|
||||
]);
|
||||
}
|
||||
|
||||
@ -57,6 +57,20 @@
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
"karma": {
|
||||
"factory": "./collection/karma",
|
||||
"schema": "./collection/karma/schema.json",
|
||||
"description": "Add Karma configuration to the workspace",
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
"karma-project": {
|
||||
"factory": "./collection/karma-project",
|
||||
"schema": "./collection/karma-project/schema.json",
|
||||
"description": "Add Karma configuration to a project",
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
"cypress-project": {
|
||||
"factory": "./collection/cypress-project",
|
||||
"schema": "./collection/cypress-project/schema.json",
|
||||
|
||||
@ -52,7 +52,7 @@ describe('app', () => {
|
||||
|
||||
it('should generate files', async () => {
|
||||
const tree = await runSchematic('app', { name: 'myApp' }, appTree);
|
||||
expect(tree.exists(`apps/my-app/karma.conf.js`)).toBeTruthy();
|
||||
expect(tree.exists(`apps/my-app/jest.config.js`)).toBeTruthy();
|
||||
expect(tree.exists('apps/my-app/src/main.ts')).toBeTruthy();
|
||||
expect(tree.exists('apps/my-app/src/app/app.module.ts')).toBeTruthy();
|
||||
expect(tree.exists('apps/my-app/src/app/app.component.ts')).toBeTruthy();
|
||||
@ -62,7 +62,7 @@ describe('app', () => {
|
||||
|
||||
const tsconfig = readJsonInTree(tree, 'apps/my-app/tsconfig.json');
|
||||
expect(tsconfig.extends).toEqual('../../tsconfig.json');
|
||||
expect(tsconfig.compilerOptions.types).toContain('jasmine');
|
||||
expect(tsconfig.compilerOptions.types).toContain('jest');
|
||||
|
||||
const tsconfigApp = JSON.parse(
|
||||
stripJsonComments(getFileContent(tree, 'apps/my-app/tsconfig.app.json'))
|
||||
@ -77,23 +77,27 @@ describe('app', () => {
|
||||
);
|
||||
expect(tslintJson.extends).toEqual('../../tslint.json');
|
||||
|
||||
expect(tree.exists('apps/my-app-e2e/src/app.po.ts')).toBeTruthy();
|
||||
expect(tree.exists('apps/my-app-e2e/cypress.json')).toBeTruthy();
|
||||
const tsconfigE2E = JSON.parse(
|
||||
stripJsonComments(
|
||||
getFileContent(tree, 'apps/my-app-e2e/tsconfig.e2e.json')
|
||||
)
|
||||
);
|
||||
expect(tsconfigE2E.compilerOptions.outDir).toEqual(
|
||||
'../../dist/out-tsc/apps/my-app-e2e'
|
||||
);
|
||||
// expect(tsconfigE2E.compilerOptions.outDir).toEqual(
|
||||
// '../../dist/out-tsc/apps/my-app-e2e'
|
||||
// );
|
||||
expect(tsconfigE2E.extends).toEqual('./tsconfig.json');
|
||||
});
|
||||
|
||||
it('should default the prefix to npmScope', async () => {
|
||||
const noPrefix = await runSchematic('app', { name: 'myApp' }, appTree);
|
||||
const noPrefix = await runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', e2eTestRunner: 'protractor' },
|
||||
appTree
|
||||
);
|
||||
const withPrefix = await runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', prefix: 'custom' },
|
||||
{ name: 'myApp', prefix: 'custom', e2eTestRunner: 'protractor' },
|
||||
appTree
|
||||
);
|
||||
|
||||
@ -120,7 +124,7 @@ describe('app', () => {
|
||||
expect(appE2eSpec).toContain('Welcome to my-app!');
|
||||
});
|
||||
|
||||
it('should work if the new project root is changed', async () => {
|
||||
xit('should work if the new project root is changed', async () => {
|
||||
appTree = await schematicRunner
|
||||
.callRule(
|
||||
updateJsonInTree('/angular.json', json => ({
|
||||
@ -192,11 +196,11 @@ describe('app', () => {
|
||||
|
||||
// Make sure these exist
|
||||
[
|
||||
`apps/my-dir/my-app/karma.conf.js`,
|
||||
`apps/my-dir/my-app/jest.config.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'
|
||||
'apps/my-dir/my-app-e2e/cypress.json'
|
||||
].forEach(path => {
|
||||
expect(tree.exists(path)).toBeTruthy();
|
||||
});
|
||||
@ -218,11 +222,11 @@ describe('app', () => {
|
||||
lookupFn: json => json.extends,
|
||||
expectedValue: '../../../tsconfig.json'
|
||||
},
|
||||
{
|
||||
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-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,
|
||||
@ -325,20 +329,19 @@ describe('app', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('--unit-test-runner jest', () => {
|
||||
it('should generate a jest config', async () => {
|
||||
describe('--unit-test-runner karma', () => {
|
||||
it('should generate a karma config', async () => {
|
||||
const tree = await runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', unitTestRunner: 'jest' },
|
||||
{ name: 'myApp', unitTestRunner: 'karma' },
|
||||
appTree
|
||||
);
|
||||
expect(tree.exists('apps/my-app/src/test.ts')).toBeFalsy();
|
||||
expect(tree.exists('apps/my-app/src/test-setup.ts')).toBeTruthy();
|
||||
|
||||
expect(tree.exists('apps/my-app/tsconfig.spec.json')).toBeTruthy();
|
||||
expect(tree.exists('apps/my-app/jest.config.js')).toBeTruthy();
|
||||
expect(tree.exists('apps/my-app/karma.conf.js')).toBeTruthy();
|
||||
const angularJson = readJsonInTree(tree, 'angular.json');
|
||||
expect(angularJson.projects['my-app'].architect.test.builder).toEqual(
|
||||
'@nrwl/builders:jest'
|
||||
'@angular-devkit/build-angular:karma'
|
||||
);
|
||||
expect(
|
||||
angularJson.projects['my-app'].architect.lint.options.tsConfig
|
||||
@ -350,10 +353,7 @@ describe('app', () => {
|
||||
tree,
|
||||
'apps/my-app/tsconfig.app.json'
|
||||
);
|
||||
expect(tsconfigAppJson.exclude).toEqual([
|
||||
'src/test-setup.ts',
|
||||
'**/*.spec.ts'
|
||||
]);
|
||||
expect(tsconfigAppJson.exclude).toEqual(['src/test.ts', '**/*.spec.ts']);
|
||||
expect(tsconfigAppJson.compilerOptions.outDir).toEqual(
|
||||
'../../dist/out-tsc/apps/my-app'
|
||||
);
|
||||
|
||||
@ -33,8 +33,9 @@ import {
|
||||
angularSchematicNames
|
||||
} from '../../utils/cli-config-utils';
|
||||
import { formatFiles } from '../../utils/rules/format-files';
|
||||
import { updateKarmaConf } from '../../utils/rules/update-karma-conf';
|
||||
import { join, normalize } from '@angular-devkit/core';
|
||||
import { readJson } from '../../../../../e2e/utils';
|
||||
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
|
||||
|
||||
interface NormalizedSchema extends Schema {
|
||||
appProjectRoot: string;
|
||||
@ -200,15 +201,13 @@ function updateProject(options: NormalizedSchema): Rule {
|
||||
});
|
||||
}
|
||||
|
||||
if (options.unitTestRunner !== 'karma') {
|
||||
delete fixedProject.architect.test;
|
||||
delete fixedProject.architect.test;
|
||||
|
||||
fixedProject.architect.lint.options.tsConfig = fixedProject.architect.lint.options.tsConfig.filter(
|
||||
path =>
|
||||
path !==
|
||||
join(normalize(options.appProjectRoot), 'tsconfig.spec.json')
|
||||
);
|
||||
}
|
||||
fixedProject.architect.lint.options.tsConfig = fixedProject.architect.lint.options.tsConfig.filter(
|
||||
path =>
|
||||
path !==
|
||||
join(normalize(options.appProjectRoot), 'tsconfig.spec.json')
|
||||
);
|
||||
if (options.e2eTestRunner === 'none') {
|
||||
delete json.projects[options.e2eProjectName];
|
||||
}
|
||||
@ -228,44 +227,14 @@ function updateProject(options: NormalizedSchema): Rule {
|
||||
exclude:
|
||||
options.unitTestRunner === 'jest'
|
||||
? ['src/test-setup.ts', '**/*.spec.ts']
|
||||
: json.exclude || [],
|
||||
: ['src/test.ts', '**/*.spec.ts'],
|
||||
include: ['**/*.ts']
|
||||
};
|
||||
}),
|
||||
options.unitTestRunner === 'karma'
|
||||
? chain([
|
||||
updateJsonInTree(
|
||||
`${options.appProjectRoot}/tsconfig.json`,
|
||||
json => {
|
||||
return {
|
||||
...json,
|
||||
compilerOptions: {
|
||||
...json.compilerOptions,
|
||||
types: [...(json.compilerOptions.types || []), 'jasmine']
|
||||
}
|
||||
};
|
||||
}
|
||||
),
|
||||
updateJsonInTree(
|
||||
`${options.appProjectRoot}/tsconfig.spec.json`,
|
||||
json => {
|
||||
return {
|
||||
...json,
|
||||
extends: `./tsconfig.json`,
|
||||
compilerOptions: {
|
||||
...json.compilerOptions,
|
||||
outDir: `${offsetFromRoot(
|
||||
options.appProjectRoot
|
||||
)}dist/out-tsc/${options.appProjectRoot}`
|
||||
}
|
||||
};
|
||||
}
|
||||
)
|
||||
])
|
||||
: host => {
|
||||
host.delete(`${options.appProjectRoot}/tsconfig.spec.json`);
|
||||
return host;
|
||||
},
|
||||
host => {
|
||||
host.delete(`${options.appProjectRoot}/tsconfig.spec.json`);
|
||||
return host;
|
||||
},
|
||||
updateJsonInTree(`${options.appProjectRoot}/tslint.json`, json => {
|
||||
return {
|
||||
...json,
|
||||
@ -286,27 +255,23 @@ function updateProject(options: NormalizedSchema): Rule {
|
||||
return resultJson;
|
||||
}),
|
||||
host => {
|
||||
if (options.unitTestRunner !== 'karma') {
|
||||
host.delete(`${options.appProjectRoot}/karma.conf.js`);
|
||||
host.delete(`${options.appProjectRoot}/src/test.ts`);
|
||||
} else {
|
||||
const karma = host
|
||||
.read(`${options.appProjectRoot}/karma.conf.js`)
|
||||
.toString();
|
||||
host.overwrite(
|
||||
`${options.appProjectRoot}/karma.conf.js`,
|
||||
karma.replace(
|
||||
`'../../coverage${options.appProjectRoot}'`,
|
||||
`'${offsetFromRoot(options.appProjectRoot)}coverage'`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
host.delete(`${options.appProjectRoot}/karma.conf.js`);
|
||||
host.delete(`${options.appProjectRoot}/src/test.ts`);
|
||||
if (options.e2eTestRunner !== 'protractor') {
|
||||
host.delete(`${options.e2eProjectRoot}/src/app.e2e-spec.ts`);
|
||||
host.delete(`${options.e2eProjectRoot}/src/app.po.ts`);
|
||||
host.delete(`${options.e2eProjectRoot}/protractor.conf.js`);
|
||||
}
|
||||
},
|
||||
(host, context) => {
|
||||
if (options.e2eTestRunner === 'protractor') {
|
||||
updateJsonInTree('/package.json', json => {
|
||||
if (!json.devDependencies.protractor) {
|
||||
json.devDependencies.protractor = '~5.4.0';
|
||||
context.addTask(new NodePackageInstallTask());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]);
|
||||
};
|
||||
@ -375,6 +340,7 @@ export default function(schema: Schema): Rule {
|
||||
// Determine the roots where @schematics/angular will place the projects
|
||||
// This is not where the projects actually end up
|
||||
const angularJson = readJsonInTree(host, getWorkspacePath(host));
|
||||
|
||||
const appProjectRoot = angularJson.newProjectRoot
|
||||
? `${angularJson.newProjectRoot}/${options.name}`
|
||||
: options.name;
|
||||
@ -414,16 +380,16 @@ export default function(schema: Schema): Rule {
|
||||
updateComponentTemplate(options),
|
||||
addNxModule(options),
|
||||
options.routing ? addRouterRootConfiguration(options) : noop(),
|
||||
options.unitTestRunner === 'karma'
|
||||
? updateKarmaConf({
|
||||
projectName: options.name
|
||||
})
|
||||
: noop(),
|
||||
options.unitTestRunner === 'jest'
|
||||
? schematic('jest-project', {
|
||||
project: options.name
|
||||
})
|
||||
: noop(),
|
||||
options.unitTestRunner === 'karma'
|
||||
? schematic('karma-project', {
|
||||
project: options.name
|
||||
})
|
||||
: noop(),
|
||||
formatFiles(options)
|
||||
])(host, context);
|
||||
};
|
||||
|
||||
@ -83,7 +83,7 @@
|
||||
"type": "string",
|
||||
"enum": ["karma", "jest", "none"],
|
||||
"description": "Test runner to use for unit tests",
|
||||
"default": "karma",
|
||||
"default": "jest",
|
||||
"x-prompt": {
|
||||
"message": "Which Unit Test Runner would you like to use for the application?",
|
||||
"type": "list",
|
||||
@ -100,7 +100,7 @@
|
||||
"type": "string",
|
||||
"enum": ["protractor", "cypress", "none"],
|
||||
"description": "Test runner to use for end to end (e2e) tests",
|
||||
"default": "protractor",
|
||||
"default": "cypress",
|
||||
"x-prompt": {
|
||||
"message": "Which E2E Test Runner would you like to use for the application?",
|
||||
"type": "list",
|
||||
|
||||
@ -2,12 +2,9 @@
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"outDir": "<%= offsetFromRoot %>dist/out-tsc/<%= projectRoot %>/src",
|
||||
"lib": ["es2015", "dom"],
|
||||
"types": ["cypress", "node"]
|
||||
"outDir": "<%= offsetFromRoot %>dist/out-tsc/<%= projectRoot %>/src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"../../node_modules/cypress"
|
||||
"src/**/*.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
|
||||
import * as path from 'path';
|
||||
import { Tree, VirtualTree } from '@angular-devkit/schematics';
|
||||
import { createEmptyWorkspace, runSchematic } from '../../utils/testing-utils';
|
||||
import { readJsonInTree } from '@nrwl/schematics/src/utils/ast-utils';
|
||||
|
||||
describe('lib', () => {
|
||||
describe('jestProject', () => {
|
||||
let appTree: Tree;
|
||||
|
||||
beforeEach(async () => {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"id": "SchematicsNxJestProject",
|
||||
"title": "Create Jest Configuration for the workspace",
|
||||
"title": "Create Jest Configuration for a project",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project": {
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
const { join } = require('path');
|
||||
const getBaseKarmaConfig = require('<%= offsetFromRoot %>karma.conf');
|
||||
|
||||
module.exports = function(config) {
|
||||
const baseConfig = getBaseKarmaConfig();
|
||||
config.set({
|
||||
...baseConfig,
|
||||
coverageIstanbulReporter: {
|
||||
...baseConfig.coverageIstanbulReporter,
|
||||
dir: join(__dirname, '<%= offsetFromRoot %>coverage/<%= projectRoot %>')
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,23 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
<% if (isLibrary) { %>
|
||||
import 'core-js/es7/reflect';
|
||||
import 'zone.js/dist/zone';
|
||||
<% } %>
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: any;
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "<%= offsetFromRoot %>dist/out-tsc/<%= projectRoot %>",
|
||||
"types": ["jasmine", "node"]
|
||||
},
|
||||
"files": ["src/test.ts"],
|
||||
"include": ["**/*.spec.ts", "**/*.d.ts"]
|
||||
}
|
||||
133
packages/schematics/src/collection/karma-project/index.ts
Normal file
133
packages/schematics/src/collection/karma-project/index.ts
Normal file
@ -0,0 +1,133 @@
|
||||
import {
|
||||
Rule,
|
||||
Tree,
|
||||
mergeWith,
|
||||
chain,
|
||||
url,
|
||||
apply,
|
||||
SchematicContext,
|
||||
move,
|
||||
template,
|
||||
noop,
|
||||
filter,
|
||||
schematic
|
||||
} from '@angular-devkit/schematics';
|
||||
import {
|
||||
getProjectConfig,
|
||||
readJsonInTree,
|
||||
updateJsonInTree
|
||||
} from '../../utils/ast-utils';
|
||||
import { offsetFromRoot } from '../../utils/common';
|
||||
import { join, normalize } from '@angular-devkit/core';
|
||||
|
||||
export interface KarmaProjectSchema {
|
||||
project: string;
|
||||
}
|
||||
|
||||
function generateFiles(options: KarmaProjectSchema): Rule {
|
||||
return (host, context) => {
|
||||
const projectConfig = getProjectConfig(host, options.project);
|
||||
return mergeWith(
|
||||
apply(url('./files'), [
|
||||
template({
|
||||
tmpl: '',
|
||||
...options,
|
||||
projectRoot: projectConfig.root,
|
||||
isLibrary: projectConfig.projectType === 'library',
|
||||
offsetFromRoot: offsetFromRoot(projectConfig.root)
|
||||
}),
|
||||
move(projectConfig.root)
|
||||
])
|
||||
)(host, context);
|
||||
};
|
||||
}
|
||||
|
||||
function updateTsConfig(options: KarmaProjectSchema): Rule {
|
||||
return (host: Tree, context: SchematicContext) => {
|
||||
const projectConfig = getProjectConfig(host, options.project);
|
||||
return updateJsonInTree(join(projectConfig.root, 'tsconfig.json'), json => {
|
||||
return {
|
||||
...json,
|
||||
compilerOptions: {
|
||||
...json.compilerOptions,
|
||||
types: Array.from(
|
||||
new Set([...(json.compilerOptions.types || []), 'jasmine'])
|
||||
)
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function updateTsSpecConfig(options: KarmaProjectSchema): Rule {
|
||||
return (host: Tree, context: SchematicContext) => {
|
||||
const projectConfig = getProjectConfig(host, options.project);
|
||||
const extraFiles =
|
||||
projectConfig.projectType === 'library' ? [] : ['src/polyfills.ts'];
|
||||
return updateJsonInTree(
|
||||
join(projectConfig.root, 'tsconfig.spec.json'),
|
||||
json => {
|
||||
return {
|
||||
...json,
|
||||
files: [...json.files, ...extraFiles]
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
function updateAngularJson(options: KarmaProjectSchema): Rule {
|
||||
return updateJsonInTree('angular.json', json => {
|
||||
const projectConfig = json.projects[options.project];
|
||||
projectConfig.architect.test = {
|
||||
builder: '@angular-devkit/build-angular:karma',
|
||||
options: {
|
||||
main: join(normalize(projectConfig.sourceRoot), 'test.ts'),
|
||||
tsConfig: join(normalize(projectConfig.root), 'tsconfig.spec.json'),
|
||||
karmaConfig: join(normalize(projectConfig.root), 'karma.conf.js')
|
||||
}
|
||||
};
|
||||
|
||||
if (projectConfig.projectType === 'application') {
|
||||
projectConfig.architect.test.options = {
|
||||
...projectConfig.architect.test.options,
|
||||
polyfills: join(normalize(projectConfig.sourceRoot), 'polyfills.ts'),
|
||||
styles: [],
|
||||
scripts: [],
|
||||
assets: []
|
||||
};
|
||||
}
|
||||
if (projectConfig.architect.lint) {
|
||||
projectConfig.architect.lint.options.tsConfig = [
|
||||
...projectConfig.architect.lint.options.tsConfig,
|
||||
join(normalize(projectConfig.root), 'tsconfig.spec.json')
|
||||
];
|
||||
}
|
||||
return json;
|
||||
});
|
||||
}
|
||||
|
||||
function check(options: KarmaProjectSchema): Rule {
|
||||
return (host: Tree, context: SchematicContext) => {
|
||||
const projectConfig = getProjectConfig(host, options.project);
|
||||
if (projectConfig.architect.test) {
|
||||
throw new Error(
|
||||
`${options.project} already has a test architect option.`
|
||||
);
|
||||
}
|
||||
const packageJson = readJsonInTree(host, 'package.json');
|
||||
if (!packageJson.devDependencies.karma) {
|
||||
return schematic('karma', {});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default function(options: KarmaProjectSchema): Rule {
|
||||
return chain([
|
||||
check(options),
|
||||
generateFiles(options),
|
||||
updateTsConfig(options),
|
||||
updateTsSpecConfig(options),
|
||||
updateAngularJson(options)
|
||||
]);
|
||||
}
|
||||
@ -0,0 +1,205 @@
|
||||
import { Tree, VirtualTree } from '@angular-devkit/schematics';
|
||||
import { createEmptyWorkspace, runSchematic } from '../../utils/testing-utils';
|
||||
import { readJsonInTree } from '@nrwl/schematics/src/utils/ast-utils';
|
||||
|
||||
describe('karmaProject', () => {
|
||||
let appTree: Tree;
|
||||
|
||||
beforeEach(async () => {
|
||||
appTree = new VirtualTree();
|
||||
appTree = createEmptyWorkspace(appTree);
|
||||
appTree = await runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'lib1',
|
||||
unitTestRunner: 'none'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
appTree = await runSchematic(
|
||||
'app',
|
||||
{
|
||||
name: 'app1',
|
||||
unitTestRunner: 'none'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
});
|
||||
|
||||
it('should generate files', async () => {
|
||||
const resultTree = await runSchematic(
|
||||
'karma-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
expect(resultTree.exists('/libs/lib1/karma.conf.js')).toBeTruthy();
|
||||
expect(resultTree.exists('/libs/lib1/tsconfig.spec.json')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should create a karma.conf.js', async () => {
|
||||
const resultTree = await runSchematic(
|
||||
'karma-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
expect(resultTree.readContent('libs/lib1/karma.conf.js'))
|
||||
.toBe(`// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
const { join } = require('path');
|
||||
const getBaseKarmaConfig = require('../../karma.conf');
|
||||
|
||||
module.exports = function(config) {
|
||||
const baseConfig = getBaseKarmaConfig();
|
||||
config.set({
|
||||
...baseConfig,
|
||||
coverageIstanbulReporter: {
|
||||
...baseConfig.coverageIstanbulReporter,
|
||||
dir: join(__dirname, '../../coverage/libs/lib1')
|
||||
}
|
||||
});
|
||||
};
|
||||
`);
|
||||
});
|
||||
|
||||
it('should update the local tsconfig.json', async () => {
|
||||
const resultTree = await runSchematic(
|
||||
'karma-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const tsConfig = readJsonInTree(resultTree, 'libs/lib1/tsconfig.json');
|
||||
expect(tsConfig.compilerOptions.types).toContain('jasmine');
|
||||
expect(tsConfig.compilerOptions.types).not.toContain('node');
|
||||
});
|
||||
|
||||
describe('library', () => {
|
||||
it('should alter angular.json', async () => {
|
||||
const resultTree = await runSchematic(
|
||||
'karma-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const angularJson = readJsonInTree(resultTree, 'angular.json');
|
||||
expect(angularJson.projects.lib1.architect.test).toEqual({
|
||||
builder: '@angular-devkit/build-angular:karma',
|
||||
options: {
|
||||
main: 'libs/lib1/src/test.ts',
|
||||
tsConfig: 'libs/lib1/tsconfig.spec.json',
|
||||
karmaConfig: 'libs/lib1/karma.conf.js'
|
||||
}
|
||||
});
|
||||
expect(
|
||||
angularJson.projects.lib1.architect.lint.options.tsConfig
|
||||
).toContain('libs/lib1/tsconfig.spec.json');
|
||||
});
|
||||
|
||||
it('should create a tsconfig.spec.json', async () => {
|
||||
const resultTree = await runSchematic(
|
||||
'karma-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const tsConfig = readJsonInTree(
|
||||
resultTree,
|
||||
'libs/lib1/tsconfig.spec.json'
|
||||
);
|
||||
expect(tsConfig).toEqual({
|
||||
extends: './tsconfig.json',
|
||||
compilerOptions: {
|
||||
outDir: '../../dist/out-tsc/libs/lib1',
|
||||
types: ['jasmine', 'node']
|
||||
},
|
||||
files: ['src/test.ts'],
|
||||
include: ['**/*.spec.ts', '**/*.d.ts']
|
||||
});
|
||||
});
|
||||
|
||||
it('should create test.ts', async () => {
|
||||
const resultTree = await runSchematic(
|
||||
'karma-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const testTs = resultTree.read('libs/lib1/src/test.ts').toString();
|
||||
expect(testTs).toContain("import 'core-js/es7/reflect';");
|
||||
expect(testTs).toContain("import 'zone.js/dist/zone';");
|
||||
});
|
||||
});
|
||||
|
||||
describe('applications', () => {
|
||||
it('should alter angular.json', async () => {
|
||||
const resultTree = await runSchematic(
|
||||
'karma-project',
|
||||
{
|
||||
project: 'app1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const angularJson = readJsonInTree(resultTree, 'angular.json');
|
||||
expect(angularJson.projects.app1.architect.test).toEqual({
|
||||
builder: '@angular-devkit/build-angular:karma',
|
||||
options: {
|
||||
main: 'apps/app1/src/test.ts',
|
||||
polyfills: 'apps/app1/src/polyfills.ts',
|
||||
tsConfig: 'apps/app1/tsconfig.spec.json',
|
||||
karmaConfig: 'apps/app1/karma.conf.js',
|
||||
styles: [],
|
||||
scripts: [],
|
||||
assets: []
|
||||
}
|
||||
});
|
||||
expect(
|
||||
angularJson.projects.app1.architect.lint.options.tsConfig
|
||||
).toContain('apps/app1/tsconfig.spec.json');
|
||||
});
|
||||
|
||||
it('should create a tsconfig.spec.json', async () => {
|
||||
const resultTree = await runSchematic(
|
||||
'karma-project',
|
||||
{
|
||||
project: 'app1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const tsConfig = readJsonInTree(
|
||||
resultTree,
|
||||
'apps/app1/tsconfig.spec.json'
|
||||
);
|
||||
expect(tsConfig).toEqual({
|
||||
extends: './tsconfig.json',
|
||||
compilerOptions: {
|
||||
outDir: '../../dist/out-tsc/apps/app1/',
|
||||
types: ['jasmine', 'node']
|
||||
},
|
||||
files: ['src/test.ts', 'src/polyfills.ts'],
|
||||
include: ['**/*.spec.ts', '**/*.d.ts']
|
||||
});
|
||||
});
|
||||
|
||||
it('should create test.ts', async () => {
|
||||
const resultTree = await runSchematic(
|
||||
'karma-project',
|
||||
{
|
||||
project: 'app1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const testTs = resultTree.read('apps/app1/src/test.ts').toString();
|
||||
expect(testTs).not.toContain("import 'core-js/es7/reflect';");
|
||||
expect(testTs).not.toContain("import 'zone.js/dist/zone';");
|
||||
});
|
||||
});
|
||||
});
|
||||
16
packages/schematics/src/collection/karma-project/schema.json
Normal file
16
packages/schematics/src/collection/karma-project/schema.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"id": "SchematicsNxKarmaProject",
|
||||
"title": "Create Karma Configuration for a project",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The name of the project.",
|
||||
"$default": {
|
||||
"$source": "projectName"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
35
packages/schematics/src/collection/karma/index.ts
Normal file
35
packages/schematics/src/collection/karma/index.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import {
|
||||
chain,
|
||||
mergeWith,
|
||||
Rule,
|
||||
SchematicContext,
|
||||
url
|
||||
} from '@angular-devkit/schematics';
|
||||
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
|
||||
import { updateJsonInTree } from '../../utils/ast-utils';
|
||||
import { jasmineMarblesVersion } from '../../lib-versions';
|
||||
|
||||
const updatePackageJson = updateJsonInTree('package.json', json => {
|
||||
json.devDependencies = {
|
||||
...json.devDependencies,
|
||||
karma: '~3.0.0',
|
||||
'karma-chrome-launcher': '~2.2.0',
|
||||
'karma-coverage-istanbul-reporter': '~2.0.1',
|
||||
'karma-jasmine': '~1.1.0',
|
||||
'karma-jasmine-html-reporter': '^0.2.2',
|
||||
'jasmine-core': '~2.99.1',
|
||||
'jasmine-spec-reporter': '~4.2.1',
|
||||
'jasmine-marbles': jasmineMarblesVersion,
|
||||
'@types/jasmine': '~2.8.6',
|
||||
'@types/jasminewd2': '~2.0.3'
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
function addInstall(_, context: SchematicContext) {
|
||||
context.addTask(new NodePackageInstallTask());
|
||||
}
|
||||
|
||||
export default function(): Rule {
|
||||
return chain([mergeWith(url('./files')), updatePackageJson, addInstall]);
|
||||
}
|
||||
32
packages/schematics/src/collection/karma/karma.spec.ts
Normal file
32
packages/schematics/src/collection/karma/karma.spec.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { Tree, VirtualTree } from '@angular-devkit/schematics';
|
||||
import { createEmptyWorkspace, runSchematic } from '../../utils/testing-utils';
|
||||
import { readJsonInTree } from '@nrwl/schematics/src/utils/ast-utils';
|
||||
|
||||
describe('karma', () => {
|
||||
let appTree: Tree;
|
||||
|
||||
beforeEach(() => {
|
||||
appTree = new VirtualTree();
|
||||
appTree = createEmptyWorkspace(appTree);
|
||||
});
|
||||
|
||||
it('should generate files', async () => {
|
||||
const resultTree = await runSchematic('karma', {}, appTree);
|
||||
expect(resultTree.exists('karma.conf.js')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should add dependencies', async () => {
|
||||
const resultTree = await runSchematic('karma', {}, appTree);
|
||||
const packageJson = readJsonInTree(resultTree, 'package.json');
|
||||
|
||||
expect(packageJson.devDependencies.karma).toBeDefined();
|
||||
expect(packageJson.devDependencies['karma-chrome-launcher']).toBeDefined();
|
||||
expect(
|
||||
packageJson.devDependencies['karma-coverage-istanbul-reporter']
|
||||
).toBeDefined();
|
||||
expect(packageJson.devDependencies['karma-jasmine']).toBeDefined();
|
||||
expect(
|
||||
packageJson.devDependencies['karma-jasmine-html-reporter']
|
||||
).toBeDefined();
|
||||
});
|
||||
});
|
||||
8
packages/schematics/src/collection/karma/schema.json
Normal file
8
packages/schematics/src/collection/karma/schema.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"id": "SchematicsNxKamra",
|
||||
"title": "Create Karma Configuration for the workspace",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"required": []
|
||||
}
|
||||
@ -40,7 +40,6 @@ import {
|
||||
replaceAppNameWithPath
|
||||
} from '../../utils/cli-config-utils';
|
||||
import { formatFiles } from '../../utils/rules/format-files';
|
||||
import { updateKarmaConf } from '../../utils/rules/update-karma-conf';
|
||||
import { Framework } from '../../utils/frameworks';
|
||||
|
||||
interface NormalizedSchema extends Schema {
|
||||
@ -255,11 +254,9 @@ function updateProject(options: NormalizedSchema): Rule {
|
||||
host.delete(path.join(options.projectRoot, 'package.json'));
|
||||
}
|
||||
|
||||
if (options.unitTestRunner !== 'karma') {
|
||||
host.delete(path.join(options.projectRoot, 'karma.conf.js'));
|
||||
host.delete(path.join(options.projectRoot, 'src/test.ts'));
|
||||
host.delete(path.join(options.projectRoot, 'tsconfig.spec.json'));
|
||||
}
|
||||
host.delete(path.join(options.projectRoot, 'karma.conf.js'));
|
||||
host.delete(path.join(options.projectRoot, 'src/test.ts'));
|
||||
host.delete(path.join(options.projectRoot, 'tsconfig.spec.json'));
|
||||
|
||||
if (options.framework === Framework.Angular) {
|
||||
host.delete(path.join(libRoot, `${options.name}.module.ts`));
|
||||
@ -343,15 +340,12 @@ function updateProject(options: NormalizedSchema): Rule {
|
||||
delete fixedProject.architect.build;
|
||||
}
|
||||
|
||||
if (options.unitTestRunner !== 'karma') {
|
||||
delete fixedProject.architect.test;
|
||||
delete fixedProject.architect.test;
|
||||
|
||||
fixedProject.architect.lint.options.tsConfig = fixedProject.architect.lint.options.tsConfig.filter(
|
||||
path =>
|
||||
path !==
|
||||
join(normalize(options.projectRoot), 'tsconfig.spec.json')
|
||||
);
|
||||
}
|
||||
fixedProject.architect.lint.options.tsConfig = fixedProject.architect.lint.options.tsConfig.filter(
|
||||
path =>
|
||||
path !== join(normalize(options.projectRoot), 'tsconfig.spec.json')
|
||||
);
|
||||
|
||||
json.projects[options.name] = fixedProject;
|
||||
return json;
|
||||
@ -384,53 +378,11 @@ function updateProject(options: NormalizedSchema): Rule {
|
||||
}
|
||||
};
|
||||
}),
|
||||
updateNgPackage(options),
|
||||
options.unitTestRunner === 'karma' ? updateKarmaConfig(options) : noop()
|
||||
updateNgPackage(options)
|
||||
])(host, context);
|
||||
};
|
||||
}
|
||||
|
||||
function updateKarmaConfig(options: NormalizedSchema) {
|
||||
return chain([
|
||||
host => {
|
||||
const karma = host
|
||||
.read(`${options.projectRoot}/karma.conf.js`)
|
||||
.toString();
|
||||
host.overwrite(
|
||||
`${options.projectRoot}/karma.conf.js`,
|
||||
karma.replace(
|
||||
`'../../coverage${options.projectRoot}'`,
|
||||
`'${offsetFromRoot(options.projectRoot)}coverage'`
|
||||
)
|
||||
);
|
||||
},
|
||||
updateJsonInTree(`${options.projectRoot}/tsconfig.json`, json => {
|
||||
return {
|
||||
...json,
|
||||
compilerOptions: {
|
||||
...json.compilerOptions,
|
||||
types: [...(json.compilerOptions.types || []), 'jasmine']
|
||||
}
|
||||
};
|
||||
}),
|
||||
updateJsonInTree(`${options.projectRoot}/tsconfig.spec.json`, json => {
|
||||
return {
|
||||
...json,
|
||||
extends: `./tsconfig.json`,
|
||||
compilerOptions: {
|
||||
...json.compilerOptions,
|
||||
outDir: `${offsetFromRoot(options.projectRoot)}dist/out-tsc/${
|
||||
options.projectRoot
|
||||
}`
|
||||
}
|
||||
};
|
||||
}),
|
||||
updateKarmaConf({
|
||||
projectName: options.name
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
function updateTsConfig(options: NormalizedSchema): Rule {
|
||||
return chain([
|
||||
(host: Tree, context: SchematicContext) => {
|
||||
@ -498,7 +450,11 @@ export default function(schema: Schema): Rule {
|
||||
skipSerializers: options.framework !== Framework.Angular
|
||||
})
|
||||
: noop(),
|
||||
|
||||
options.unitTestRunner === 'karma'
|
||||
? schematic('karma-project', {
|
||||
project: options.name
|
||||
})
|
||||
: noop(),
|
||||
options.publishable ? updateLibPackageNpmScope(options) : noop(),
|
||||
options.framework === Framework.Angular ? addModule(options) : noop(),
|
||||
formatFiles(options)
|
||||
|
||||
@ -124,7 +124,7 @@ describe('lib', () => {
|
||||
expect(tsconfigJson).toEqual({
|
||||
extends: '../../tsconfig.json',
|
||||
compilerOptions: {
|
||||
types: ['jasmine']
|
||||
types: ['node', 'jest']
|
||||
},
|
||||
include: ['**/*.ts']
|
||||
});
|
||||
@ -150,7 +150,7 @@ describe('lib', () => {
|
||||
|
||||
it('should generate files', async () => {
|
||||
const tree = await runSchematic('lib', { name: 'myLib' }, appTree);
|
||||
expect(tree.exists(`libs/my-lib/karma.conf.js`)).toBeTruthy();
|
||||
expect(tree.exists(`libs/my-lib/jest.config.js`)).toBeTruthy();
|
||||
expect(tree.exists('libs/my-lib/src/index.ts')).toBeTruthy();
|
||||
expect(tree.exists('libs/my-lib/src/lib/my-lib.module.ts')).toBeTruthy();
|
||||
|
||||
@ -170,7 +170,7 @@ describe('lib', () => {
|
||||
{ name: 'myLib2', simpleModuleName: true },
|
||||
tree
|
||||
);
|
||||
expect(tree2.exists(`libs/my-lib2/karma.conf.js`)).toBeTruthy();
|
||||
expect(tree2.exists(`libs/my-lib2/jest.config.js`)).toBeTruthy();
|
||||
expect(tree2.exists('libs/my-lib2/src/index.ts')).toBeTruthy();
|
||||
expect(
|
||||
tree2.exists('libs/my-lib2/src/lib/my-lib2.module.ts')
|
||||
@ -299,7 +299,7 @@ describe('lib', () => {
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
expect(tree.exists(`libs/my-dir/my-lib/karma.conf.js`)).toBeTruthy();
|
||||
expect(tree.exists(`libs/my-dir/my-lib/jest.config.js`)).toBeTruthy();
|
||||
expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy();
|
||||
expect(
|
||||
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.module.ts')
|
||||
@ -323,7 +323,7 @@ describe('lib', () => {
|
||||
{ name: 'myLib2', directory: 'myDir', simpleModuleName: true },
|
||||
tree
|
||||
);
|
||||
expect(tree2.exists(`libs/my-dir/my-lib2/karma.conf.js`)).toBeTruthy();
|
||||
expect(tree2.exists(`libs/my-dir/my-lib2/jest.config.js`)).toBeTruthy();
|
||||
expect(tree2.exists('libs/my-dir/my-lib2/src/index.ts')).toBeTruthy();
|
||||
expect(
|
||||
tree2.exists('libs/my-dir/my-lib2/src/lib/my-lib2.module.ts')
|
||||
@ -399,7 +399,7 @@ describe('lib', () => {
|
||||
expect(tsconfigJson).toEqual({
|
||||
extends: '../../../tsconfig.json',
|
||||
compilerOptions: {
|
||||
types: ['jasmine']
|
||||
types: ['node', 'jest']
|
||||
},
|
||||
include: ['**/*.ts']
|
||||
});
|
||||
@ -716,20 +716,20 @@ describe('lib', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('--unit-test-runner jest', () => {
|
||||
it('should generate jest configuration', async () => {
|
||||
describe('--unit-test-runner karma', () => {
|
||||
it('should generate karma configuration', async () => {
|
||||
const resultTree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', unitTestRunner: 'jest' },
|
||||
{ name: 'myLib', unitTestRunner: 'karma' },
|
||||
appTree
|
||||
);
|
||||
expect(resultTree.exists('libs/my-lib/src/test.ts')).toBeFalsy();
|
||||
expect(resultTree.exists('libs/my-lib/src/test-setup.ts')).toBeTruthy();
|
||||
expect(resultTree.exists('libs/my-lib/src/test.ts')).toBeTruthy();
|
||||
expect(resultTree.exists('libs/my-lib/src/test-setup.ts')).toBeFalsy();
|
||||
expect(resultTree.exists('libs/my-lib/tsconfig.spec.json')).toBeTruthy();
|
||||
expect(resultTree.exists('libs/my-lib/jest.config.js')).toBeTruthy();
|
||||
expect(resultTree.exists('libs/my-lib/karma.conf.js')).toBeTruthy();
|
||||
const angularJson = readJsonInTree(resultTree, 'angular.json');
|
||||
expect(angularJson.projects['my-lib'].architect.test.builder).toEqual(
|
||||
'@nrwl/builders:jest'
|
||||
'@angular-devkit/build-angular:karma'
|
||||
);
|
||||
expect(
|
||||
angularJson.projects['my-lib'].architect.lint.options.tsConfig
|
||||
@ -770,7 +770,7 @@ describe('lib', () => {
|
||||
expect(resultTree.exists('libs/my-lib/src/test.ts')).toBeFalsy();
|
||||
expect(resultTree.exists('libs/my-lib/tsconfig.spec.json')).toBeFalsy();
|
||||
expect(resultTree.exists('libs/my-lib/jest.config.js')).toBeFalsy();
|
||||
expect(resultTree.exists('libs/my-lib/karma.config.js')).toBeFalsy();
|
||||
expect(resultTree.exists('libs/my-lib/karma.conf.js')).toBeFalsy();
|
||||
const angularJson = readJsonInTree(resultTree, 'angular.json');
|
||||
expect(angularJson.projects['my-lib'].architect.test).toBeUndefined();
|
||||
expect(
|
||||
|
||||
@ -116,7 +116,7 @@
|
||||
"type": "string",
|
||||
"enum": ["karma", "jest", "none"],
|
||||
"description": "Test runner to use for unit tests",
|
||||
"default": "karma",
|
||||
"default": "jest",
|
||||
"x-prompt": {
|
||||
"message": "Which Unit Test Runner would you like to use for the library?",
|
||||
"type": "list",
|
||||
|
||||
@ -52,20 +52,9 @@
|
||||
"@ngrx/store-devtools": "<%= ngrxVersion %>",
|
||||
"ngrx-store-freeze": "<%= ngrxStoreFreezeVersion %>",
|
||||
"@nrwl/schematics": "<%= schematicsVersion %>",
|
||||
"jasmine-marbles": "<%= jasmineMarblesVersion %>",
|
||||
"@types/jasmine": "~2.8.6",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "~8.9.4",
|
||||
"codelyzer": "~4.5.0",
|
||||
"dotenv": "6.2.0",
|
||||
"jasmine-core": "~2.99.1",
|
||||
"jasmine-spec-reporter": "~4.2.1",
|
||||
"karma": "~3.0.0",
|
||||
"karma-chrome-launcher": "~2.2.0",
|
||||
"karma-coverage-istanbul-reporter": "~2.0.1",
|
||||
"karma-jasmine": "~1.1.0",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"protractor": "~5.4.0",
|
||||
"ts-node": "~7.0.0",
|
||||
"tslint": "~5.11.0",
|
||||
"typescript": "<%= typescriptVersion %>",
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
"module": "es2015",
|
||||
"typeRoots": ["node_modules/@types"],
|
||||
"lib": ["es2017", "dom"],
|
||||
"skipLibCheck": true,
|
||||
"skipDefaultLibCheck": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {}
|
||||
},
|
||||
|
||||
@ -34,7 +34,6 @@ describe('app', () => {
|
||||
expect(tree.exists('/proj/angular.json')).toBe(true);
|
||||
expect(tree.exists('/proj/.prettierrc')).toBe(true);
|
||||
expect(tree.exists('/proj/.prettierignore')).toBe(true);
|
||||
expect(tree.exists('/proj/karma.conf.js')).toBe(true);
|
||||
});
|
||||
|
||||
it('should create nx.json', () => {
|
||||
@ -75,51 +74,6 @@ describe('app', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should create a root karma configuration', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'ng-new',
|
||||
{ name: 'proj' },
|
||||
projectTree
|
||||
);
|
||||
expect(tree.readContent('/proj/karma.conf.js')).toBe(
|
||||
`// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
const { join } = require('path');
|
||||
const { constants } = require('karma');
|
||||
|
||||
module.exports = () => {
|
||||
return {
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: join(__dirname, '../../coverage'),
|
||||
reports: ['html', 'lcovonly'],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: constants.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: true
|
||||
};
|
||||
};
|
||||
`
|
||||
);
|
||||
});
|
||||
|
||||
it('should not set package manager by default', () => {
|
||||
const treeNoPackages = schematicRunner.runSchematic(
|
||||
'ng-new',
|
||||
|
||||
@ -83,7 +83,7 @@ describe('node-app', () => {
|
||||
it('should generate files', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'node-app',
|
||||
{ name: 'myNodeApp' },
|
||||
{ name: 'myNodeApp', framework: 'express' },
|
||||
appTree
|
||||
);
|
||||
expect(tree.exists(`apps/my-node-app/jest.config.js`)).toBeTruthy();
|
||||
@ -121,7 +121,7 @@ describe('node-app', () => {
|
||||
it('should add dependencies', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'node-app',
|
||||
{ name: 'myNodeApp' },
|
||||
{ name: 'myNodeApp', framework: 'express' },
|
||||
appTree
|
||||
);
|
||||
const packageJson = readJsonInTree(tree, 'package.json');
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
]
|
||||
},
|
||||
|
||||
"default": "express"
|
||||
"default": "nestjs"
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files",
|
||||
|
||||
@ -63,7 +63,7 @@ export class WorkspaceIntegrityChecks {
|
||||
? []
|
||||
: [
|
||||
{
|
||||
header: `All files in 'apps' and 'libs' must be part of a project.`,
|
||||
header: `All files in 'apps' and 'libs' must be part of a project`,
|
||||
errors
|
||||
}
|
||||
];
|
||||
|
||||
@ -20,7 +20,7 @@ const buildersSourceDirectory = path.join(
|
||||
__dirname,
|
||||
'../../build/packages/builders/src'
|
||||
);
|
||||
const buildersOutputDirectory = path.join(__dirname, '../../docs/builders');
|
||||
const buildersOutputDirectory = path.join(__dirname, '../../docs/api-builders');
|
||||
const builderCollectionFile = path.join(
|
||||
buildersSourceDirectory,
|
||||
'builders.json'
|
||||
|
||||
@ -2,5 +2,5 @@
|
||||
|
||||
echo "Generating API documentation"
|
||||
ts-node ./scripts/documentation/builders.ts
|
||||
ts-node ./scripts/documentation/commands.ts
|
||||
ts-node ./scripts/documentation/schematics.ts
|
||||
ts-node ./scripts/documentation/npmscripts.ts
|
||||
ts-node ./scripts/documentation/schematics.ts
|
||||
|
||||
@ -7,7 +7,7 @@ import { commandsObject } from '../../packages/schematics/src/command-line/nx-co
|
||||
|
||||
const commandsOutputDirectory = path.join(
|
||||
__dirname,
|
||||
'../../docs/command-lines'
|
||||
'../../docs/api-npmscripts'
|
||||
);
|
||||
|
||||
function getCommands(command) {
|
||||
@ -69,10 +69,10 @@ function generateFile(
|
||||
|
||||
// TODO: Try to add option's type, examples, and group?
|
||||
// TODO: split one command per page / Create an index
|
||||
const commands = getCommands(commandsObject);
|
||||
const npmscripts = getCommands(commandsObject);
|
||||
|
||||
Object.keys(commands)
|
||||
.map(name => parseCommandInstance(name, commands[name]))
|
||||
Object.keys(npmscripts)
|
||||
.map(name => parseCommandInstance(name, npmscripts[name]))
|
||||
.map(command => generateMarkdown(command))
|
||||
.forEach(templateObject =>
|
||||
generateFile(commandsOutputDirectory, templateObject)
|
||||
@ -21,7 +21,10 @@ const schematicsSourceDirectory = path.join(
|
||||
__dirname,
|
||||
'../../build/packages/schematics/src'
|
||||
);
|
||||
const schematicsOutputDirectory = path.join(__dirname, '../../docs/schematics');
|
||||
const schematicsOutputDirectory = path.join(
|
||||
__dirname,
|
||||
'../../docs/api-schematics'
|
||||
);
|
||||
const schematicCollectionFile = path.join(
|
||||
schematicsSourceDirectory,
|
||||
'collection.json'
|
||||
|
||||
11
scripts/e2e-rerun.sh
Normal file
11
scripts/e2e-rerun.sh
Normal file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
./scripts/link.sh fast
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
jest --maxWorkers=1 ./build/e2e/schematics/$1.test.js
|
||||
else
|
||||
jest --maxWorkers=1 ./build/e2e/schematics
|
||||
fi
|
||||
|
||||
|
||||
@ -5,9 +5,9 @@ rm -rf tmp
|
||||
mkdir tmp
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
jest --maxWorkers=1 ./build/e2e/schematics/$1.test.js
|
||||
jest --maxWorkers=1 ./build/e2e/schematics/$1.test.js
|
||||
else
|
||||
jest --maxWorkers=1 ./build/e2e/schematics
|
||||
jest --maxWorkers=1 ./build/e2e/schematics
|
||||
fi
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user