483 lines
16 KiB
TypeScript
483 lines
16 KiB
TypeScript
import {
|
|
checkFilesExist,
|
|
cleanup,
|
|
copyMissingPackages,
|
|
runCLI,
|
|
runNgNew,
|
|
updateFile,
|
|
readJson,
|
|
readFile,
|
|
runCommand,
|
|
runCLIAsync,
|
|
runsInWSL
|
|
} from '../utils';
|
|
|
|
if (!runsInWSL()) {
|
|
describe('Nrwl Convert to Nx Workspace', () => {
|
|
beforeEach(cleanup);
|
|
afterAll(cleanup);
|
|
|
|
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 tsconfig.json
|
|
const tsconfigJson = readJson('tsconfig.json');
|
|
tsconfigJson.compilerOptions.paths = { a: ['b'] };
|
|
updateFile('tsconfig.json', JSON.stringify(tsconfigJson, null, 2));
|
|
|
|
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));
|
|
|
|
// 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'
|
|
);
|
|
|
|
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()`);
|
|
|
|
// 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: []
|
|
},
|
|
'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');
|
|
|
|
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
|
|
},
|
|
sourceMap: false,
|
|
fileReplacements: [
|
|
{
|
|
replace: 'src/environments/environment.ts',
|
|
with: 'src/environments/environment.prod.ts'
|
|
}
|
|
]
|
|
}
|
|
}
|
|
});
|
|
|
|
runCLI('run proj:server');
|
|
checkFilesExist('dist/apps/proj-server/main.js');
|
|
});
|
|
|
|
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');
|
|
});
|
|
});
|
|
}
|