nx/e2e/nx-misc/src/workspace.test.ts

885 lines
28 KiB
TypeScript

import {
checkFilesExist,
newProject,
readJson,
cleanupProject,
runCLI,
uniq,
updateFile,
expectJestTestsToPass,
readFile,
exists,
renameFile,
updateProjectConfig,
readProjectConfig,
tmpProjPath,
readResolvedConfiguration,
removeFile,
getPackageManagerCommand,
getSelectedPackageManager,
runCommand,
} from '@nrwl/e2e/utils';
let proj: string;
describe('Workspace Tests', () => {
beforeAll(() => {
proj = newProject();
});
afterAll(() => cleanupProject());
describe('@nrwl/workspace:library', () => {
it('should create a library that can be tested and linted', async () => {
const libName = uniq('mylib');
const dirName = uniq('dir');
runCLI(`generate @nrwl/workspace:lib ${libName} --directory ${dirName}`);
checkFilesExist(
`libs/${dirName}/${libName}/src/index.ts`,
`libs/${dirName}/${libName}/README.md`
);
// Lint
const result = runCLI(`lint ${dirName}-${libName}`);
expect(result).toContain(`Linting "${dirName}-${libName}"...`);
expect(result).toContain('All files pass linting.');
// Test
await expectJestTestsToPass('@nrwl/workspace:lib');
}, 100000);
it('should be able to use and be used by other libs', () => {
const consumerLib = uniq('consumer');
const producerLib = uniq('producer');
runCLI(`generate @nrwl/workspace:lib ${consumerLib}`);
runCLI(`generate @nrwl/workspace:lib ${producerLib}`);
updateFile(
`libs/${producerLib}/src/lib/${producerLib}.ts`,
'export const a = 0;'
);
updateFile(
`libs/${consumerLib}/src/lib/${consumerLib}.ts`,
`
import { a } from '@${proj}/${producerLib}';
export function ${consumerLib}() {
return a + 1;
}`
);
updateFile(
`libs/${consumerLib}/src/lib/${consumerLib}.spec.ts`,
`
import { ${consumerLib} } from './${consumerLib}';
describe('', () => {
it('should return 1', () => {
expect(${consumerLib}()).toEqual(1);
});
});`
);
runCLI(`test ${consumerLib}`);
});
it('should be able to be built when it is buildable', () => {
const buildableLib = uniq('buildable');
runCLI(`generate @nrwl/workspace:lib ${buildableLib} --buildable`);
const result = runCLI(`build ${buildableLib}`);
expect(result).toContain(
`Compiling TypeScript files for project "${buildableLib}"...`
);
expect(result).toContain(
`Done compiling TypeScript files for project "${buildableLib}".`
);
checkFilesExist(`dist/libs/${buildableLib}/README.md`);
const json = readJson(`dist/libs/${buildableLib}/package.json`);
expect(json.main).toEqual('./src/index.js');
expect(json.types).toEqual('./src/index.d.ts');
});
});
describe('@nrwl/workspace:npm-package', () => {
it('should create a minimal npm package', () => {
const npmPackage = uniq('npm-package');
runCLI(`generate @nrwl/workspace:npm-package ${npmPackage}`);
updateFile('package.json', (content) => {
const json = JSON.parse(content);
json.workspaces = ['libs/*'];
return JSON.stringify(json);
});
const pmc = getPackageManagerCommand({
packageManager: getSelectedPackageManager(),
});
runCommand(pmc.install);
const result = runCLI(`test ${npmPackage}`);
expect(result).toContain('Hello World');
});
});
describe('workspace-generator', () => {
let custom: string;
let failing: string;
beforeEach(() => {
custom = uniq('custom');
failing = uniq('custom-failing');
runCLI(
`g @nrwl/workspace:workspace-generator ${custom} --no-interactive`
);
runCLI(
`g @nrwl/workspace:workspace-generator ${failing} --no-interactive`
);
checkFilesExist(
`tools/generators/${custom}/index.ts`,
`tools/generators/${custom}/schema.json`
);
checkFilesExist(
`tools/generators/${failing}/index.ts`,
`tools/generators/${failing}/schema.json`
);
});
it('should compile only generator files with dependencies', () => {
const workspace = uniq('workspace');
updateFile(
'tools/utils/command-line-utils.ts',
`
export const noop = () => {}
`
);
updateFile(
'tools/utils/logger.ts',
`
export const log = (...args: any[]) => console.log(...args)
`
);
updateFile(
`tools/generators/utils.ts`,
`
export const noop = ()=>{}
`
);
updateFile(`tools/generators/${custom}/index.ts`, (content) => {
return `
import { log } from '../../utils/logger'; \n
${content}
`;
});
runCLI(`workspace-generator ${custom} ${workspace} --no-interactive -d`);
expect(() =>
checkFilesExist(
`dist/out-tsc/tools/generators/${custom}/index.js`,
`dist/out-tsc/tools/generators/utils.js`,
`dist/out-tsc/tools/utils/logger.js`
)
).not.toThrow();
expect(() =>
checkFilesExist(`dist/out-tsc/tools/utils/utils.js`)
).toThrow();
});
it('should support workspace-specific generators', async () => {
const json = readJson(`tools/generators/${custom}/schema.json`);
json.properties['directory'] = {
type: 'string',
description: 'lib directory',
};
json.properties['skipTsConfig'] = {
type: 'boolean',
description: 'skip changes to tsconfig',
};
json.properties['inlineprop'] = json.properties['name'];
json.required = ['inlineprop'];
delete json.properties['name'];
updateFile(
`tools/generators/${custom}/schema.json`,
JSON.stringify(json)
);
const indexFile = readFile(`tools/generators/${custom}/index.ts`);
updateFile(
`tools/generators/${custom}/index.ts`,
indexFile.replace(
'name: schema.name',
'name: schema.inlineprop, directory: schema.directory, skipTsConfig: schema.skipTsConfig'
)
);
const helpOutput = runCLI(`workspace-generator ${custom} --help`);
expect(helpOutput).toContain(
`workspace-generator ${custom} [inlineprop] (options)`
);
expect(helpOutput).toContain(`--directory`);
expect(helpOutput).toContain(`--skipTsConfig`);
const workspace = uniq('workspace');
const dryRunOutput = runCLI(
`workspace-generator ${custom} ${workspace} --no-interactive --directory=dir --skipTsConfig=true -d`
);
expect(exists(`libs/dir/${workspace}/src/index.ts`)).toEqual(false);
expect(dryRunOutput).toContain(
`CREATE libs/dir/${workspace}/src/index.ts`
);
runCLI(
`workspace-generator ${custom} ${workspace} --no-interactive --directory=dir`
);
checkFilesExist(`libs/dir/${workspace}/src/index.ts`);
const jsonFailing = readJson(`tools/generators/${failing}/schema.json`);
jsonFailing.properties = {};
jsonFailing.required = [];
updateFile(
`tools/generators/${failing}/schema.json`,
JSON.stringify(jsonFailing)
);
updateFile(
`tools/generators/${failing}/index.ts`,
`
export default function() {
throw new Error();
}
`
);
try {
await runCLI(`workspace-generator ${failing} --no-interactive`);
fail(`Should exit 1 for a workspace-generator that throws an error`);
} catch (e) {}
const listOutput = runCLI('workspace-generator --list-generators');
expect(listOutput).toContain(custom);
expect(listOutput).toContain(failing);
}, 1000000);
it('should support angular devkit schematics', () => {
const angularDevkitSchematic = uniq('angular-devkit-schematic');
runCLI(
`g @nrwl/workspace:workspace-generator ${angularDevkitSchematic} --no-interactive`
);
const json = readJson(
`tools/generators/${angularDevkitSchematic}/schema.json`
);
json.properties = {};
json.required = [];
delete json.cli;
updateFile(
`tools/generators/${angularDevkitSchematic}/schema.json`,
JSON.stringify(json)
);
updateFile(
`tools/generators/${angularDevkitSchematic}/index.ts`,
`
export default function() {
return (tree) => tree;
}
`
);
runCLI(`workspace-generator ${angularDevkitSchematic} --no-interactive`);
});
});
// TODO: vsavkin rerenable
xdescribe('move project', () => {
/**
* Tries moving a library from ${lib}/data-access -> shared/${lib}/data-access
*/
it('should work for libraries', async () => {
const lib1 = uniq('mylib');
const lib2 = uniq('mylib');
const lib3 = uniq('mylib');
runCLI(`generate @nrwl/workspace:lib ${lib1}/data-access`);
updateFile(
`libs/${lib1}/data-access/src/lib/${lib1}-data-access.ts`,
`export function fromLibOne() { console.log('This is completely pointless'); }`
);
updateFile(
`libs/${lib1}/data-access/src/index.ts`,
`export * from './lib/${lib1}-data-access.ts'`
);
/**
* Create a library which imports a class from lib1
*/
runCLI(`generate @nrwl/workspace:lib ${lib2}/ui`);
updateFile(
`libs/${lib2}/ui/src/lib/${lib2}-ui.ts`,
`import { fromLibOne } from '@${proj}/${lib1}/data-access';
export const fromLibTwo = () => fromLibOne();`
);
/**
* Create a library which has an implicit dependency on lib1
*/
runCLI(`generate @nrwl/workspace:lib ${lib3}`);
updateProjectConfig(lib3, (config) => {
config.implicitDependencies = [`${lib1}-data-access`];
return config;
});
/**
* Now try to move lib1
*/
const moveOutput = runCLI(
`generate @nrwl/workspace:move --project ${lib1}-data-access shared/${lib1}/data-access`
);
expect(moveOutput).toContain(`DELETE libs/${lib1}/data-access`);
expect(exists(`libs/${lib1}/data-access`)).toBeFalsy();
const newPath = `libs/shared/${lib1}/data-access`;
const newName = `shared-${lib1}-data-access`;
const readmePath = `${newPath}/README.md`;
expect(moveOutput).toContain(`CREATE ${readmePath}`);
checkFilesExist(readmePath);
const jestConfigPath = `${newPath}/jest.config.ts`;
expect(moveOutput).toContain(`CREATE ${jestConfigPath}`);
checkFilesExist(jestConfigPath);
const jestConfig = readFile(jestConfigPath);
expect(jestConfig).toContain(`displayName: 'shared-${lib1}-data-access'`);
expect(jestConfig).toContain(`preset: '../../../../jest.preset.js'`);
expect(jestConfig).toContain(`'../../../../coverage/${newPath}'`);
const tsConfigPath = `${newPath}/tsconfig.json`;
expect(moveOutput).toContain(`CREATE ${tsConfigPath}`);
checkFilesExist(tsConfigPath);
const tsConfigLibPath = `${newPath}/tsconfig.lib.json`;
expect(moveOutput).toContain(`CREATE ${tsConfigLibPath}`);
checkFilesExist(tsConfigLibPath);
const tsConfigLib = readJson(tsConfigLibPath);
expect(tsConfigLib.compilerOptions.outDir).toEqual(
'../../../../dist/out-tsc'
);
const tsConfigSpecPath = `${newPath}/tsconfig.spec.json`;
expect(moveOutput).toContain(`CREATE ${tsConfigSpecPath}`);
checkFilesExist(tsConfigSpecPath);
const tsConfigSpec = readJson(tsConfigSpecPath);
expect(tsConfigSpec.compilerOptions.outDir).toEqual(
'../../../../dist/out-tsc'
);
const indexPath = `${newPath}/src/index.ts`;
expect(moveOutput).toContain(`CREATE ${indexPath}`);
checkFilesExist(indexPath);
const rootClassPath = `${newPath}/src/lib/${lib1}-data-access.ts`;
expect(moveOutput).toContain(`CREATE ${rootClassPath}`);
checkFilesExist(rootClassPath);
let workspace = await readResolvedConfiguration();
expect(workspace.projects[`${lib1}-data-access`]).toBeUndefined();
const newConfig = readProjectConfig(newName);
expect(newConfig).toMatchObject({
tags: [],
});
const lib3Config = readProjectConfig(lib3);
expect(lib3Config.implicitDependencies).toEqual([
`shared-${lib1}-data-access`,
]);
expect(moveOutput).toContain('UPDATE tsconfig.base.json');
const rootTsConfig = readJson('tsconfig.base.json');
expect(
rootTsConfig.compilerOptions.paths[`@${proj}/${lib1}/data-access`]
).toBeUndefined();
expect(
rootTsConfig.compilerOptions.paths[
`@${proj}/shared/${lib1}/data-access`
]
).toEqual([`libs/shared/${lib1}/data-access/src/index.ts`]);
workspace = readResolvedConfiguration();
expect(workspace.projects[`${lib1}-data-access`]).toBeUndefined();
const project = readProjectConfig(newName);
expect(project).toBeTruthy();
expect(project.sourceRoot).toBe(`${newPath}/src`);
expect(project.targets.lint.options.lintFilePatterns).toEqual([
`libs/shared/${lib1}/data-access/**/*.ts`,
]);
/**
* Check that the import in lib2 has been updated
*/
const lib2FilePath = `libs/${lib2}/ui/src/lib/${lib2}-ui.ts`;
const lib2File = readFile(lib2FilePath);
expect(lib2File).toContain(
`import { fromLibOne } from '@${proj}/shared/${lib1}/data-access';`
);
});
it('should work for libs created with --importPath', async () => {
const importPath = '@wibble/fish';
const lib1 = uniq('mylib');
const lib2 = uniq('mylib');
const lib3 = uniq('mylib');
runCLI(
`generate @nrwl/workspace:lib ${lib1}/data-access --importPath=${importPath}`
);
updateFile(
`libs/${lib1}/data-access/src/lib/${lib1}-data-access.ts`,
`export function fromLibOne() { console.log('This is completely pointless'); }`
);
updateFile(
`libs/${lib1}/data-access/src/index.ts`,
`export * from './lib/${lib1}-data-access.ts'`
);
/**
* Create a library which imports a class from lib1
*/
runCLI(`generate @nrwl/workspace:lib ${lib2}/ui`);
updateFile(
`libs/${lib2}/ui/src/lib/${lib2}-ui.ts`,
`import { fromLibOne } from '${importPath}';
export const fromLibTwo = () => fromLibOne();`
);
/**
* Create a library which has an implicit dependency on lib1
*/
runCLI(`generate @nrwl/workspace:lib ${lib3}`);
updateProjectConfig(lib3, (config) => {
config.implicitDependencies = [`${lib1}-data-access`];
return config;
});
/**
* Now try to move lib1
*/
const moveOutput = runCLI(
`generate @nrwl/workspace:move --project ${lib1}-data-access shared/${lib1}/data-access`
);
expect(moveOutput).toContain(`DELETE libs/${lib1}/data-access`);
expect(exists(`libs/${lib1}/data-access`)).toBeFalsy();
const newPath = `libs/shared/${lib1}/data-access`;
const newName = `shared-${lib1}-data-access`;
const readmePath = `${newPath}/README.md`;
expect(moveOutput).toContain(`CREATE ${readmePath}`);
checkFilesExist(readmePath);
const jestConfigPath = `${newPath}/jest.config.ts`;
expect(moveOutput).toContain(`CREATE ${jestConfigPath}`);
checkFilesExist(jestConfigPath);
const jestConfig = readFile(jestConfigPath);
expect(jestConfig).toContain(`displayName: 'shared-${lib1}-data-access'`);
expect(jestConfig).toContain(`preset: '../../../../jest.preset.js'`);
expect(jestConfig).toContain(`'../../../../coverage/${newPath}'`);
const tsConfigPath = `${newPath}/tsconfig.json`;
expect(moveOutput).toContain(`CREATE ${tsConfigPath}`);
checkFilesExist(tsConfigPath);
const tsConfigLibPath = `${newPath}/tsconfig.lib.json`;
expect(moveOutput).toContain(`CREATE ${tsConfigLibPath}`);
checkFilesExist(tsConfigLibPath);
const tsConfigLib = readJson(tsConfigLibPath);
expect(tsConfigLib.compilerOptions.outDir).toEqual(
'../../../../dist/out-tsc'
);
const tsConfigSpecPath = `${newPath}/tsconfig.spec.json`;
expect(moveOutput).toContain(`CREATE ${tsConfigSpecPath}`);
checkFilesExist(tsConfigSpecPath);
const tsConfigSpec = readJson(tsConfigSpecPath);
expect(tsConfigSpec.compilerOptions.outDir).toEqual(
'../../../../dist/out-tsc'
);
const indexPath = `${newPath}/src/index.ts`;
expect(moveOutput).toContain(`CREATE ${indexPath}`);
checkFilesExist(indexPath);
const rootClassPath = `${newPath}/src/lib/${lib1}-data-access.ts`;
expect(moveOutput).toContain(`CREATE ${rootClassPath}`);
checkFilesExist(rootClassPath);
expect(moveOutput).toContain('UPDATE tsconfig.base.json');
const rootTsConfig = readJson('tsconfig.base.json');
expect(
rootTsConfig.compilerOptions.paths[`@${proj}/${lib1}/data-access`]
).toBeUndefined();
expect(
rootTsConfig.compilerOptions.paths[
`@${proj}/shared/${lib1}/data-access`
]
).toEqual([`libs/shared/${lib1}/data-access/src/index.ts`]);
const workspace = await readResolvedConfiguration();
expect(workspace.projects[`${lib1}-data-access`]).toBeUndefined();
const project = readProjectConfig(newName);
expect(project).toBeTruthy();
expect(project.sourceRoot).toBe(`${newPath}/src`);
expect(project.tags).toEqual([]);
const lib3Config = readProjectConfig(lib3);
expect(lib3Config.implicitDependencies).toEqual([newName]);
expect(project.targets.lint.options.lintFilePatterns).toEqual([
`libs/shared/${lib1}/data-access/**/*.ts`,
]);
/**
* Check that the import in lib2 has been updated
*/
const lib2FilePath = `libs/${lib2}/ui/src/lib/${lib2}-ui.ts`;
const lib2File = readFile(lib2FilePath);
expect(lib2File).toContain(
`import { fromLibOne } from '@${proj}/shared/${lib1}/data-access';`
);
});
it('should work for custom workspace layouts', async () => {
const lib1 = uniq('mylib');
const lib2 = uniq('mylib');
const lib3 = uniq('mylib');
let nxJson = readJson('nx.json');
nxJson.workspaceLayout = { libsDir: 'packages' };
updateFile('nx.json', JSON.stringify(nxJson));
runCLI(`generate @nrwl/workspace:lib ${lib1}/data-access`);
updateFile(
`packages/${lib1}/data-access/src/lib/${lib1}-data-access.ts`,
`export function fromLibOne() { console.log('This is completely pointless'); }`
);
updateFile(
`packages/${lib1}/data-access/src/index.ts`,
`export * from './lib/${lib1}-data-access.ts'`
);
/**
* Create a library which imports a class from lib1
*/
runCLI(`generate @nrwl/workspace:lib ${lib2}/ui`);
updateFile(
`packages/${lib2}/ui/src/lib/${lib2}-ui.ts`,
`import { fromLibOne } from '@${proj}/${lib1}/data-access';
export const fromLibTwo = () => fromLibOne();`
);
/**
* Create a library which has an implicit dependency on lib1
*/
runCLI(`generate @nrwl/workspace:lib ${lib3}`);
updateProjectConfig(lib3, (config) => {
config.implicitDependencies = [`${lib1}-data-access`];
return config;
});
/**
* Now try to move lib1
*/
const moveOutput = runCLI(
`generate @nrwl/workspace:move --project ${lib1}-data-access shared/${lib1}/data-access`
);
expect(moveOutput).toContain(`DELETE packages/${lib1}/data-access`);
expect(exists(`packages/${lib1}/data-access`)).toBeFalsy();
const newPath = `packages/shared/${lib1}/data-access`;
const newName = `shared-${lib1}-data-access`;
const readmePath = `${newPath}/README.md`;
expect(moveOutput).toContain(`CREATE ${readmePath}`);
checkFilesExist(readmePath);
const jestConfigPath = `${newPath}/jest.config.ts`;
expect(moveOutput).toContain(`CREATE ${jestConfigPath}`);
checkFilesExist(jestConfigPath);
const jestConfig = readFile(jestConfigPath);
expect(jestConfig).toContain(`displayName: 'shared-${lib1}-data-access'`);
expect(jestConfig).toContain(`preset: '../../../../jest.preset.js'`);
expect(jestConfig).toContain(`'../../../../coverage/${newPath}'`);
const tsConfigPath = `${newPath}/tsconfig.json`;
expect(moveOutput).toContain(`CREATE ${tsConfigPath}`);
checkFilesExist(tsConfigPath);
const tsConfigLibPath = `${newPath}/tsconfig.lib.json`;
expect(moveOutput).toContain(`CREATE ${tsConfigLibPath}`);
checkFilesExist(tsConfigLibPath);
const tsConfigLib = readJson(tsConfigLibPath);
expect(tsConfigLib.compilerOptions.outDir).toEqual(
'../../../../dist/out-tsc'
);
const tsConfigSpecPath = `${newPath}/tsconfig.spec.json`;
expect(moveOutput).toContain(`CREATE ${tsConfigSpecPath}`);
checkFilesExist(tsConfigSpecPath);
const tsConfigSpec = readJson(tsConfigSpecPath);
expect(tsConfigSpec.compilerOptions.outDir).toEqual(
'../../../../dist/out-tsc'
);
const indexPath = `${newPath}/src/index.ts`;
expect(moveOutput).toContain(`CREATE ${indexPath}`);
checkFilesExist(indexPath);
const rootClassPath = `${newPath}/src/lib/${lib1}-data-access.ts`;
expect(moveOutput).toContain(`CREATE ${rootClassPath}`);
checkFilesExist(rootClassPath);
expect(moveOutput).toContain('UPDATE tsconfig.base.json');
const rootTsConfig = readJson('tsconfig.base.json');
expect(
rootTsConfig.compilerOptions.paths[`@${proj}/${lib1}/data-access`]
).toBeUndefined();
expect(
rootTsConfig.compilerOptions.paths[
`@${proj}/shared/${lib1}/data-access`
]
).toEqual([`packages/shared/${lib1}/data-access/src/index.ts`]);
const workspace = await readResolvedConfiguration();
expect(workspace.projects[`${lib1}-data-access`]).toBeUndefined();
const project = readProjectConfig(newName);
expect(project).toBeTruthy();
expect(project.sourceRoot).toBe(`${newPath}/src`);
expect(project.targets.lint.options.lintFilePatterns).toEqual([
`packages/shared/${lib1}/data-access/**/*.ts`,
]);
expect(project.tags).toEqual([]);
/**
* Check that the import in lib2 has been updated
*/
const lib2FilePath = `packages/${lib2}/ui/src/lib/${lib2}-ui.ts`;
const lib2File = readFile(lib2FilePath);
expect(lib2File).toContain(
`import { fromLibOne } from '@${proj}/shared/${lib1}/data-access';`
);
nxJson = readJson('nx.json');
delete nxJson.workspaceLayout;
updateFile('nx.json', JSON.stringify(nxJson));
});
it('should work for libraries when scope is unset', async () => {
const json = readJson('nx.json');
delete json.npmScope;
updateFile('nx.json', JSON.stringify(json));
const lib1 = uniq('mylib');
const lib2 = uniq('mylib');
const lib3 = uniq('mylib');
runCLI(`generate @nrwl/workspace:lib ${lib1}/data-access`);
let rootTsConfig = readJson('tsconfig.base.json');
expect(
rootTsConfig.compilerOptions.paths[`@${proj}/${lib1}/data-access`]
).toBeUndefined();
expect(
rootTsConfig.compilerOptions.paths[`${lib1}/data-access`]
).toBeDefined();
updateFile(
`libs/${lib1}/data-access/src/lib/${lib1}-data-access.ts`,
`export function fromLibOne() { console.log('This is completely pointless'); }`
);
updateFile(
`libs/${lib1}/data-access/src/index.ts`,
`export * from './lib/${lib1}-data-access.ts'`
);
/**
* Create a library which imports a class from lib1
*/
runCLI(`generate @nrwl/workspace:lib ${lib2}/ui`);
updateFile(
`libs/${lib2}/ui/src/lib/${lib2}-ui.ts`,
`import { fromLibOne } from '${lib1}/data-access';
export const fromLibTwo = () => fromLibOne();`
);
/**
* Create a library which has an implicit dependency on lib1
*/
runCLI(`generate @nrwl/workspace:lib ${lib3}`);
updateProjectConfig(lib3, (config) => {
config.implicitDependencies = [`${lib1}-data-access`];
return config;
});
/**
* Now try to move lib1
*/
const moveOutput = runCLI(
`generate @nrwl/workspace:move --project ${lib1}-data-access shared/${lib1}/data-access`
);
expect(moveOutput).toContain(`DELETE libs/${lib1}/data-access`);
expect(exists(`libs/${lib1}/data-access`)).toBeFalsy();
const newPath = `libs/shared/${lib1}/data-access`;
const newName = `shared-${lib1}-data-access`;
const readmePath = `${newPath}/README.md`;
expect(moveOutput).toContain(`CREATE ${readmePath}`);
checkFilesExist(readmePath);
const indexPath = `${newPath}/src/index.ts`;
expect(moveOutput).toContain(`CREATE ${indexPath}`);
checkFilesExist(indexPath);
const rootClassPath = `${newPath}/src/lib/${lib1}-data-access.ts`;
expect(moveOutput).toContain(`CREATE ${rootClassPath}`);
checkFilesExist(rootClassPath);
const newConfig = readProjectConfig(newName);
expect(newConfig).toMatchObject({
tags: [],
});
const lib3Config = readProjectConfig(lib3);
expect(lib3Config.implicitDependencies).toEqual([
`shared-${lib1}-data-access`,
]);
expect(moveOutput).toContain('UPDATE tsconfig.base.json');
rootTsConfig = readJson('tsconfig.base.json');
expect(
rootTsConfig.compilerOptions.paths[`${lib1}/data-access`]
).toBeUndefined();
expect(
rootTsConfig.compilerOptions.paths[`shared/${lib1}/data-access`]
).toEqual([`libs/shared/${lib1}/data-access/src/index.ts`]);
const projects = readResolvedConfiguration();
expect(projects.projects[`${lib1}-data-access`]).toBeUndefined();
const project = readProjectConfig(newName);
expect(project).toBeTruthy();
expect(project.sourceRoot).toBe(`${newPath}/src`);
expect(project.targets.lint.options.lintFilePatterns).toEqual([
`libs/shared/${lib1}/data-access/**/*.ts`,
]);
/**
* Check that the import in lib2 has been updated
*/
const lib2FilePath = `libs/${lib2}/ui/src/lib/${lib2}-ui.ts`;
const lib2File = readFile(lib2FilePath);
expect(lib2File).toContain(
`import { fromLibOne } from 'shared/${lib1}/data-access';`
);
});
});
//TODO: vsavkin reenable
xdescribe('remove project', () => {
/**
* Tries creating then deleting a lib
*/
it('should work', async () => {
const lib1 = uniq('myliba');
const lib2 = uniq('mylibb');
runCLI(`generate @nrwl/workspace:lib ${lib1}`);
expect(exists(tmpProjPath(`libs/${lib1}`))).toBeTruthy();
/**
* Create a library which has an implicit dependency on lib1
*/
runCLI(`generate @nrwl/workspace:lib ${lib2}`);
updateProjectConfig(lib2, (config) => {
config.implicitDependencies = [lib1];
return config;
});
/**
* Try removing the project (should fail)
*/
let error;
try {
console.log(
runCLI(`generate @nrwl/workspace:remove --project ${lib1}`)
);
} catch (e) {
error = e;
}
expect(error).toBeDefined();
expect(error.stdout.toString()).toContain(
`${lib1} is still depended on by the following projects`
);
expect(error.stdout.toString()).toContain(lib2);
/**
* Try force removing the project
*/
const removeOutputForced = runCLI(
`generate @nrwl/workspace:remove --project ${lib1} --forceRemove`
);
expect(removeOutputForced).toContain(`DELETE libs/${lib1}`);
expect(exists(tmpProjPath(`libs/${lib1}`))).toBeFalsy();
expect(removeOutputForced).not.toContain(`UPDATE nx.json`);
const projectsConfigurations = readResolvedConfiguration();
expect(projectsConfigurations.projects[`${lib1}`]).toBeUndefined();
const lib2Config = readProjectConfig(lib2);
expect(lib2Config.implicitDependencies).toEqual([]);
expect(projectsConfigurations.projects[`${lib1}`]).toBeUndefined();
});
});
});