cleanup(core): refactor e2e tests for workspace
This commit is contained in:
parent
818727c3f0
commit
1c2eedf9cb
@ -99,6 +99,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Nx CLI E2E Tests Part 1
|
name: Nx CLI E2E Tests Part 1
|
||||||
command: yarn e2e-ci1 nx
|
command: yarn e2e-ci1 nx
|
||||||
|
no_output_timeout: 30m
|
||||||
e2e-nx-2:
|
e2e-nx-2:
|
||||||
executor: default
|
executor: default
|
||||||
steps:
|
steps:
|
||||||
@ -106,6 +107,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Nx CLI E2E Tests Part 2
|
name: Nx CLI E2E Tests Part 2
|
||||||
command: yarn e2e-ci2 nx
|
command: yarn e2e-ci2 nx
|
||||||
|
no_output_timeout: 30m
|
||||||
e2e-nx-3:
|
e2e-nx-3:
|
||||||
executor: default
|
executor: default
|
||||||
steps:
|
steps:
|
||||||
@ -113,6 +115,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Nx CLI E2E Tests Part 3
|
name: Nx CLI E2E Tests Part 3
|
||||||
command: yarn e2e-ci3 nx
|
command: yarn e2e-ci3 nx
|
||||||
|
no_output_timeout: 30m
|
||||||
e2e-nx-4:
|
e2e-nx-4:
|
||||||
executor: default
|
executor: default
|
||||||
steps:
|
steps:
|
||||||
@ -120,6 +123,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Nx CLI E2E Tests Part 4
|
name: Nx CLI E2E Tests Part 4
|
||||||
command: yarn e2e-ci4 nx
|
command: yarn e2e-ci4 nx
|
||||||
|
no_output_timeout: 30m
|
||||||
e2e-ng-1:
|
e2e-ng-1:
|
||||||
executor: default
|
executor: default
|
||||||
steps:
|
steps:
|
||||||
@ -127,6 +131,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Angular CLI E2E Tests Part 1
|
name: Angular CLI E2E Tests Part 1
|
||||||
command: yarn e2e-ci1 angular
|
command: yarn e2e-ci1 angular
|
||||||
|
no_output_timeout: 30m
|
||||||
e2e-ng-2:
|
e2e-ng-2:
|
||||||
executor: default
|
executor: default
|
||||||
steps:
|
steps:
|
||||||
@ -134,6 +139,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Angular CLI E2E Tests Part 2
|
name: Angular CLI E2E Tests Part 2
|
||||||
command: yarn e2e-ci2 angular
|
command: yarn e2e-ci2 angular
|
||||||
|
no_output_timeout: 30m
|
||||||
e2e-ng-3:
|
e2e-ng-3:
|
||||||
executor: default
|
executor: default
|
||||||
steps:
|
steps:
|
||||||
@ -141,6 +147,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Angular CLI E2E Tests Part 3
|
name: Angular CLI E2E Tests Part 3
|
||||||
command: yarn e2e-ci3 angular
|
command: yarn e2e-ci3 angular
|
||||||
|
no_output_timeout: 30m
|
||||||
e2e-ng-4:
|
e2e-ng-4:
|
||||||
executor: default
|
executor: default
|
||||||
steps:
|
steps:
|
||||||
@ -148,6 +155,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Angular CLI E2E Tests Part 4
|
name: Angular CLI E2E Tests Part 4
|
||||||
command: yarn e2e-ci4 angular
|
command: yarn e2e-ci4 angular
|
||||||
|
no_output_timeout: 30m
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
version: 2.1
|
version: 2.1
|
||||||
|
|||||||
@ -1,85 +0,0 @@
|
|||||||
import {
|
|
||||||
ensureProject,
|
|
||||||
readJson,
|
|
||||||
runCommand,
|
|
||||||
uniq,
|
|
||||||
updateFile,
|
|
||||||
runCLI,
|
|
||||||
forEachCli,
|
|
||||||
workspaceConfigName
|
|
||||||
} from './utils';
|
|
||||||
import { NxJson } from '@nrwl/workspace/src/core/shared-interfaces';
|
|
||||||
|
|
||||||
forEachCli(() => {
|
|
||||||
describe('Affected (with Git)', () => {
|
|
||||||
let myapp = uniq('myapp');
|
|
||||||
let myapp2 = uniq('myapp');
|
|
||||||
let mylib = uniq('mylib');
|
|
||||||
it('should not affect other projects by generating a new project', () => {
|
|
||||||
ensureProject();
|
|
||||||
|
|
||||||
const nxJson: NxJson = readJson('nx.json');
|
|
||||||
|
|
||||||
delete nxJson.implicitDependencies;
|
|
||||||
|
|
||||||
updateFile('nx.json', JSON.stringify(nxJson));
|
|
||||||
runCommand(`git init`);
|
|
||||||
runCommand(`git config user.email "test@test.com"`);
|
|
||||||
runCommand(`git config user.name "Test"`);
|
|
||||||
runCommand(
|
|
||||||
`git add . && git commit -am "initial commit" && git checkout -b master`
|
|
||||||
);
|
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp}`);
|
|
||||||
expect(runCommand('yarn affected:apps')).toContain(myapp);
|
|
||||||
runCommand(`git add . && git commit -am "add ${myapp}"`);
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp2}`);
|
|
||||||
expect(runCommand('yarn affected:apps')).not.toContain(myapp);
|
|
||||||
expect(runCommand('yarn affected:apps')).toContain(myapp2);
|
|
||||||
runCommand(`git add . && git commit -am "add ${myapp2}"`);
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/angular:lib ${mylib}`);
|
|
||||||
expect(runCommand('yarn affected:apps')).not.toContain(myapp);
|
|
||||||
expect(runCommand('yarn affected:apps')).not.toContain(myapp2);
|
|
||||||
expect(runCommand('yarn affected:libs')).toContain(mylib);
|
|
||||||
runCommand(`git add . && git commit -am "add ${mylib}"`);
|
|
||||||
}, 1000000);
|
|
||||||
|
|
||||||
it('should detect changes to projects based on the nx.json', () => {
|
|
||||||
const nxJson: NxJson = readJson('nx.json');
|
|
||||||
|
|
||||||
nxJson.projects[myapp].tags = ['tag'];
|
|
||||||
updateFile('nx.json', JSON.stringify(nxJson));
|
|
||||||
expect(runCommand('yarn affected:apps')).toContain(myapp);
|
|
||||||
expect(runCommand('yarn affected:apps')).not.toContain(myapp2);
|
|
||||||
expect(runCommand('yarn affected:libs')).not.toContain(mylib);
|
|
||||||
runCommand(`git add . && git commit -am "add tag to ${myapp}"`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should detect changes to projects based on the workspace.json', () => {
|
|
||||||
const workspaceJson = readJson(workspaceConfigName());
|
|
||||||
|
|
||||||
workspaceJson.projects[myapp].prefix = 'my-app';
|
|
||||||
updateFile(workspaceConfigName(), JSON.stringify(workspaceJson));
|
|
||||||
expect(runCommand('yarn affected:apps')).toContain(myapp);
|
|
||||||
expect(runCommand('yarn affected:apps')).not.toContain(myapp2);
|
|
||||||
expect(runCommand('yarn affected:libs')).not.toContain(mylib);
|
|
||||||
runCommand(`git add . && git commit -am "change prefix for ${myapp}"`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should affect all projects by removing projects', () => {
|
|
||||||
const workspaceJson = readJson(workspaceConfigName());
|
|
||||||
delete workspaceJson.projects[mylib];
|
|
||||||
updateFile(workspaceConfigName(), JSON.stringify(workspaceJson));
|
|
||||||
|
|
||||||
const nxJson = readJson('nx.json');
|
|
||||||
delete nxJson.projects[mylib];
|
|
||||||
updateFile('nx.json', JSON.stringify(nxJson));
|
|
||||||
|
|
||||||
expect(runCommand('yarn affected:apps')).toContain(myapp);
|
|
||||||
expect(runCommand('yarn affected:apps')).toContain(myapp2);
|
|
||||||
expect(runCommand('yarn affected:libs')).not.toContain(mylib);
|
|
||||||
runCommand(`git add . && git commit -am "remove ${mylib}"`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,293 +0,0 @@
|
|||||||
import {
|
|
||||||
ensureProject,
|
|
||||||
readFile,
|
|
||||||
readJson,
|
|
||||||
runCommand,
|
|
||||||
uniq,
|
|
||||||
updateFile,
|
|
||||||
runCLI,
|
|
||||||
forEachCli,
|
|
||||||
supportUi
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
let originalCIValue: any;
|
|
||||||
|
|
||||||
forEachCli(() => {
|
|
||||||
/**
|
|
||||||
* Setting CI=true makes it simpler to configure assertions around output, as there
|
|
||||||
* won't be any colors.
|
|
||||||
*/
|
|
||||||
beforeAll(() => {
|
|
||||||
originalCIValue = process.env.CI;
|
|
||||||
process.env.CI = 'true';
|
|
||||||
});
|
|
||||||
afterAll(() => {
|
|
||||||
process.env.CI = originalCIValue;
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Affected', () => {
|
|
||||||
it('should print, build, and test affected apps', () => {
|
|
||||||
ensureProject();
|
|
||||||
const myapp = uniq('myapp');
|
|
||||||
const myapp2 = uniq('myapp2');
|
|
||||||
const mylib = uniq('mylib');
|
|
||||||
const mylib2 = uniq('mylib2');
|
|
||||||
const mypublishablelib = uniq('mypublishablelib');
|
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp}`);
|
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp2}`);
|
|
||||||
runCLI(`generate @nrwl/angular:lib ${mylib}`);
|
|
||||||
runCLI(`generate @nrwl/angular:lib ${mylib2}`);
|
|
||||||
runCLI(`generate @nrwl/angular:lib ${mypublishablelib} --publishable`);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`apps/${myapp}/src/app/app.component.spec.ts`,
|
|
||||||
`
|
|
||||||
import '@proj/${mylib}';
|
|
||||||
describe('sample test', () => {
|
|
||||||
it('should test', () => {
|
|
||||||
expect(1).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
`
|
|
||||||
);
|
|
||||||
updateFile(
|
|
||||||
`libs/${mypublishablelib}/src/lib/${mypublishablelib}.module.spec.ts`,
|
|
||||||
`
|
|
||||||
import '@proj/${mylib}';
|
|
||||||
describe('sample test', () => {
|
|
||||||
it('should test', () => {
|
|
||||||
expect(1).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
`
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
runCommand(
|
|
||||||
`npm run affected:apps -- --files="libs/${mylib}/src/index.ts" --plain`
|
|
||||||
).split('\n')[4]
|
|
||||||
).toEqual(myapp);
|
|
||||||
|
|
||||||
const affectedApps = runCommand(
|
|
||||||
`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`);
|
|
||||||
|
|
||||||
const implicitlyAffectedApps = runCommand(
|
|
||||||
'npm run affected:apps -- --files="tsconfig.json"'
|
|
||||||
);
|
|
||||||
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(
|
|
||||||
runCommand(
|
|
||||||
`npm run affected:libs -- --files="libs/${mylib}/src/index.ts" --plain`
|
|
||||||
).split('\n')[4]
|
|
||||||
).toEqual(`${mylib} ${mypublishablelib}`);
|
|
||||||
|
|
||||||
const affectedLibs = runCommand(
|
|
||||||
`npm run affected:libs -- --files="libs/${mylib}/src/index.ts"`
|
|
||||||
);
|
|
||||||
expect(affectedLibs).toContain(mypublishablelib);
|
|
||||||
expect(affectedLibs).toContain(mylib);
|
|
||||||
expect(affectedLibs).not.toContain(mylib2);
|
|
||||||
|
|
||||||
const implicitlyAffectedLibs = runCommand(
|
|
||||||
'npm run affected:libs -- --files="tsconfig.json"'
|
|
||||||
);
|
|
||||||
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);
|
|
||||||
|
|
||||||
const build = runCommand(
|
|
||||||
`npm run affected:build -- --files="libs/${mylib}/src/index.ts"`
|
|
||||||
);
|
|
||||||
expect(build).toContain(`Running target build for projects:`);
|
|
||||||
|
|
||||||
expect(build).toContain(`- ${myapp}`);
|
|
||||||
expect(build).toContain(`- ${mypublishablelib}`);
|
|
||||||
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`
|
|
||||||
);
|
|
||||||
expect(buildParallel).toContain(`Running target build for projects:`);
|
|
||||||
expect(buildParallel).toContain(`- ${myapp}`);
|
|
||||||
expect(buildParallel).toContain(`- ${mypublishablelib}`);
|
|
||||||
expect(buildParallel).toContain('Running target "build" succeeded');
|
|
||||||
|
|
||||||
const buildExcluded = runCommand(
|
|
||||||
`npm run affected:build -- --files="libs/${mylib}/src/index.ts" --exclude ${myapp}`
|
|
||||||
);
|
|
||||||
expect(buildExcluded).toContain(`Running target build for projects:`);
|
|
||||||
expect(buildExcluded).toContain(`- ${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`
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(buildWithFlags).toContain(`Running target build for projects:`);
|
|
||||||
expect(buildWithFlags).toContain(`- ${myapp}`);
|
|
||||||
expect(buildWithFlags).toContain(`- ${mypublishablelib}`);
|
|
||||||
expect(buildWithFlags).toContain('With flags:');
|
|
||||||
expect(buildWithFlags).toContain('--stats-json=true');
|
|
||||||
|
|
||||||
if (supportUi()) {
|
|
||||||
const e2e = runCommand(
|
|
||||||
`npm run affected:e2e -- --files="libs/${mylib}/src/index.ts" --headless`
|
|
||||||
);
|
|
||||||
expect(e2e).toContain('should display welcome message');
|
|
||||||
}
|
|
||||||
|
|
||||||
const unitTests = runCommand(
|
|
||||||
`npm run affected:test -- --files="libs/${mylib}/src/index.ts"`
|
|
||||||
);
|
|
||||||
expect(unitTests).toContain(`Running target test for projects:`);
|
|
||||||
expect(unitTests).toContain(`- ${mylib}`);
|
|
||||||
expect(unitTests).toContain(`- ${myapp}`);
|
|
||||||
expect(unitTests).toContain(`- ${mypublishablelib}`);
|
|
||||||
// Fail a Unit Test
|
|
||||||
updateFile(
|
|
||||||
`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"`
|
|
||||||
);
|
|
||||||
expect(failedTests).toContain(`Running target test for projects:`);
|
|
||||||
expect(failedTests).toContain(`- ${mylib}`);
|
|
||||||
expect(failedTests).toContain(`- ${myapp}`);
|
|
||||||
expect(failedTests).toContain(`- ${mypublishablelib}`);
|
|
||||||
expect(failedTests).toContain(`Failed projects:`);
|
|
||||||
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
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fix failing Unit Test
|
|
||||||
updateFile(
|
|
||||||
`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`
|
|
||||||
);
|
|
||||||
expect(isolatedTests).toContain(`Running target test for projects`);
|
|
||||||
expect(isolatedTests).toContain(`- ${myapp}`);
|
|
||||||
|
|
||||||
const linting = runCommand(
|
|
||||||
`npm run affected:lint -- --files="libs/${mylib}/src/index.ts"`
|
|
||||||
);
|
|
||||||
expect(linting).toContain(`Running target lint for projects:`);
|
|
||||||
expect(linting).toContain(`- ${mylib}`);
|
|
||||||
expect(linting).toContain(`- ${myapp}`);
|
|
||||||
expect(linting).toContain(`- ${myapp}-e2e`);
|
|
||||||
expect(linting).toContain(`- ${mypublishablelib}`);
|
|
||||||
|
|
||||||
const lintWithJsonFormatting = runCommand(
|
|
||||||
`npm run affected:lint -- --files="libs/${mylib}/src/index.ts" -- --format json`
|
|
||||||
);
|
|
||||||
expect(lintWithJsonFormatting).toContain('With flags:');
|
|
||||||
expect(lintWithJsonFormatting).toContain('--format=json');
|
|
||||||
|
|
||||||
const unitTestsExcluded = runCommand(
|
|
||||||
`npm run affected:test -- --files="libs/${mylib}/src/index.ts" --exclude=${myapp},${mypublishablelib}`
|
|
||||||
);
|
|
||||||
expect(unitTestsExcluded).toContain(`Running target test for projects:`);
|
|
||||||
expect(unitTestsExcluded).toContain(`- ${mylib}`);
|
|
||||||
|
|
||||||
const i18n = runCommand(
|
|
||||||
`npm run affected -- --target extract-i18n --files="libs/${mylib}/src/index.ts"`
|
|
||||||
);
|
|
||||||
expect(i18n).toContain(`Running target extract-i18n for projects:`);
|
|
||||||
expect(i18n).toContain(`- ${myapp}`);
|
|
||||||
|
|
||||||
const interpolatedTests = runCommand(
|
|
||||||
`npm run affected -- --target test --files="libs/${mylib}/src/index.ts" -- --jest-config {project.root}/jest.config.js`
|
|
||||||
);
|
|
||||||
expect(interpolatedTests).toContain(`Running target \"test\" succeeded`);
|
|
||||||
}, 1000000);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('build in the right order', () => {
|
|
||||||
let myapp, mypublishablelib;
|
|
||||||
beforeEach(() => {
|
|
||||||
ensureProject();
|
|
||||||
|
|
||||||
// create my app depending on mypublishablelib
|
|
||||||
myapp = uniq('myapp');
|
|
||||||
mypublishablelib = uniq('mypublishablelib');
|
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp}`);
|
|
||||||
runCLI(`generate @nrwl/angular:lib ${mypublishablelib} --publishable`);
|
|
||||||
updateFile(
|
|
||||||
`apps/${myapp}/src/app/app.component.spec.ts`,
|
|
||||||
`
|
|
||||||
import '@proj/${mypublishablelib}';
|
|
||||||
describe('sample test', () => {
|
|
||||||
it('should test', () => {
|
|
||||||
expect(1).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should wait for deps to be built before continuing', () => {
|
|
||||||
const build = runCommand(
|
|
||||||
`npm run affected:build -- --files="apps/${myapp}/src/main.ts,libs/${mypublishablelib}/src/index.ts" --parallel`
|
|
||||||
);
|
|
||||||
|
|
||||||
// make sure that the package is done building before we start building the app
|
|
||||||
expect(
|
|
||||||
build.indexOf('Built Angular Package!') <
|
|
||||||
build.indexOf(`Generating ES5 bundles for differential loading.`)
|
|
||||||
).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not invoke build for projects who deps fail', () => {
|
|
||||||
updateFile(
|
|
||||||
`libs/${mypublishablelib}/src/index.ts`,
|
|
||||||
`
|
|
||||||
const x: number = 'string';
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
const build = runCommand(
|
|
||||||
`npm run affected:build -- --files="apps/${myapp}/src/main.ts,libs/${mypublishablelib}/src/index.ts" --parallel`
|
|
||||||
);
|
|
||||||
expect(build.indexOf(`"build" "${myapp}"`)).toEqual(-1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -15,7 +15,7 @@ import {
|
|||||||
import { toClassName } from '@nrwl/workspace';
|
import { toClassName } from '@nrwl/workspace';
|
||||||
|
|
||||||
forEachCli(() => {
|
forEachCli(() => {
|
||||||
describe('Create New Workspace', () => {
|
describe('Angular Package', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
ensureProject();
|
ensureProject();
|
||||||
});
|
});
|
||||||
@ -1,39 +0,0 @@
|
|||||||
import { forEachCli, newProject, runCLI, uniq, updateFile } from './utils';
|
|
||||||
|
|
||||||
forEachCli(() => {
|
|
||||||
describe('Buildable Libraries', () => {
|
|
||||||
it('should be able to run the task for the specified project and its dependencies', () => {
|
|
||||||
newProject();
|
|
||||||
|
|
||||||
const myapp = uniq('myapp');
|
|
||||||
const mylib1 = uniq('mylib1');
|
|
||||||
const mylib2 = uniq('mylib1');
|
|
||||||
runCLI(`generate @nrwl/react:app ${myapp}`);
|
|
||||||
runCLI(`generate @nrwl/react:lib ${mylib1} --publishable`);
|
|
||||||
runCLI(`generate @nrwl/react:lib ${mylib2} --publishable`);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`apps/${myapp}/src/main.ts`,
|
|
||||||
`
|
|
||||||
import "@proj/${mylib1}";
|
|
||||||
import "@proj/${mylib2}";
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
const buildWithDeps = runCLI(`build ${myapp} --with-deps --prod`);
|
|
||||||
expect(buildWithDeps).toContain(`Running target "build" succeeded`);
|
|
||||||
expect(buildWithDeps).toContain(`nx run ${myapp}:build:production`);
|
|
||||||
expect(buildWithDeps).toContain(`nx run ${mylib1}:build`);
|
|
||||||
expect(buildWithDeps).toContain(`nx run ${mylib2}:build`);
|
|
||||||
|
|
||||||
const testsWithDeps = runCLI(`test ${myapp} --with-deps`);
|
|
||||||
expect(testsWithDeps).toContain(`NX Running target test for projects:`);
|
|
||||||
expect(testsWithDeps).toContain(myapp);
|
|
||||||
expect(testsWithDeps).toContain(mylib1);
|
|
||||||
expect(testsWithDeps).toContain(mylib2);
|
|
||||||
|
|
||||||
const testsWithoutDeps = runCLI(`test ${myapp}`);
|
|
||||||
expect(testsWithoutDeps).not.toContain(mylib1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,157 +0,0 @@
|
|||||||
import {
|
|
||||||
forEachCli,
|
|
||||||
listFiles,
|
|
||||||
newProject,
|
|
||||||
rmDist,
|
|
||||||
runCLI,
|
|
||||||
runCommand,
|
|
||||||
uniq,
|
|
||||||
updateFile
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
forEachCli(() => {
|
|
||||||
describe('Cache', () => {
|
|
||||||
it('should cache command execution', async () => {
|
|
||||||
newProject();
|
|
||||||
|
|
||||||
const myapp1 = uniq('myapp1');
|
|
||||||
const myapp2 = uniq('myapp2');
|
|
||||||
runCLI(`generate @nrwl/web:app ${myapp1}`);
|
|
||||||
runCLI(`generate @nrwl/web:app ${myapp2}`);
|
|
||||||
const files = `--files="apps/${myapp1}/src/main.ts,apps/${myapp2}/src/main.ts"`;
|
|
||||||
|
|
||||||
// run without caching
|
|
||||||
// --------------------------------------------
|
|
||||||
const outputWithoutCachingEnabled1 = runCommand(
|
|
||||||
`npm run affected:build -- ${files}`
|
|
||||||
);
|
|
||||||
const filesApp1 = listFiles(`dist/apps/${myapp1}`);
|
|
||||||
const filesApp2 = listFiles(`dist/apps/${myapp2}`);
|
|
||||||
|
|
||||||
expect(outputWithoutCachingEnabled1).not.toContain(
|
|
||||||
'read the output from cache'
|
|
||||||
);
|
|
||||||
|
|
||||||
const outputWithoutCachingEnabled2 = runCommand(
|
|
||||||
`npm run affected:build -- ${files}`
|
|
||||||
);
|
|
||||||
expect(outputWithoutCachingEnabled2).not.toContain(
|
|
||||||
'read the output from cache'
|
|
||||||
);
|
|
||||||
|
|
||||||
// enable caching
|
|
||||||
// --------------------------------------------
|
|
||||||
updateFile('nx.json', c => {
|
|
||||||
const nxJson = JSON.parse(c);
|
|
||||||
nxJson.tasksRunnerOptions = {
|
|
||||||
default: {
|
|
||||||
options: {
|
|
||||||
cacheableOperations: ['build', 'test', 'lint']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return JSON.stringify(nxJson, null, 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
// run build with caching
|
|
||||||
// --------------------------------------------
|
|
||||||
const outputThatPutsDataIntoCache = runCommand(
|
|
||||||
`npm run affected:build -- ${files}`
|
|
||||||
);
|
|
||||||
// now the data is in cache
|
|
||||||
expect(outputThatPutsDataIntoCache).not.toContain(
|
|
||||||
'read the output from cache'
|
|
||||||
);
|
|
||||||
|
|
||||||
rmDist();
|
|
||||||
|
|
||||||
const outputWithBothBuildTasksCached = runCommand(
|
|
||||||
`npm run affected:build -- ${files}`
|
|
||||||
);
|
|
||||||
expect(outputWithBothBuildTasksCached).toContain(
|
|
||||||
'read the output from cache'
|
|
||||||
);
|
|
||||||
expectCached(outputWithBothBuildTasksCached, [myapp1, myapp2]);
|
|
||||||
expect(listFiles(`dist/apps/${myapp1}`)).toEqual(filesApp1);
|
|
||||||
expect(listFiles(`dist/apps/${myapp2}`)).toEqual(filesApp2);
|
|
||||||
|
|
||||||
// run with skipping cache
|
|
||||||
const outputWithBothBuildTasksCachedButSkipped = runCommand(
|
|
||||||
`npm run affected:build -- ${files} --skip-nx-cache`
|
|
||||||
);
|
|
||||||
expect(outputWithBothBuildTasksCachedButSkipped).not.toContain(
|
|
||||||
`read the output from cache`
|
|
||||||
);
|
|
||||||
|
|
||||||
// touch myapp1
|
|
||||||
// --------------------------------------------
|
|
||||||
updateFile(`apps/${myapp1}/src/main.ts`, c => {
|
|
||||||
return `${c}\n//some comment`;
|
|
||||||
});
|
|
||||||
const outputWithBuildApp2Cached = runCommand(
|
|
||||||
`npm run affected:build -- ${files}`
|
|
||||||
);
|
|
||||||
expect(outputWithBuildApp2Cached).toContain('read the output from cache');
|
|
||||||
expectCached(outputWithBuildApp2Cached, [myapp2]);
|
|
||||||
|
|
||||||
// touch package.json
|
|
||||||
// --------------------------------------------
|
|
||||||
updateFile(`package.json`, c => {
|
|
||||||
const r = JSON.parse(c);
|
|
||||||
r.description = 'different';
|
|
||||||
return JSON.stringify(r);
|
|
||||||
});
|
|
||||||
const outputWithNoBuildCached = runCommand(
|
|
||||||
`npm run affected:build -- ${files}`
|
|
||||||
);
|
|
||||||
expect(outputWithNoBuildCached).not.toContain(
|
|
||||||
'read the output from cache'
|
|
||||||
);
|
|
||||||
|
|
||||||
// build individual project with caching
|
|
||||||
const individualBuildWithCache = runCommand(
|
|
||||||
`npm run nx -- build ${myapp1}`
|
|
||||||
);
|
|
||||||
expect(individualBuildWithCache).toContain('Cached Output');
|
|
||||||
|
|
||||||
// skip caching when building individual projects
|
|
||||||
const individualBuildWithSkippedCache = runCommand(
|
|
||||||
`npm run nx -- build ${myapp1} --skip-nx-cache`
|
|
||||||
);
|
|
||||||
expect(individualBuildWithSkippedCache).not.toContain('Cached Output');
|
|
||||||
|
|
||||||
// run lint with caching
|
|
||||||
// --------------------------------------------
|
|
||||||
const outputWithNoLintCached = runCommand(
|
|
||||||
`npm run affected:lint -- ${files}`
|
|
||||||
);
|
|
||||||
expect(outputWithNoLintCached).not.toContain(
|
|
||||||
'read the output from cache'
|
|
||||||
);
|
|
||||||
|
|
||||||
const outputWithBothLintTasksCached = runCommand(
|
|
||||||
`npm run affected:lint -- ${files}`
|
|
||||||
);
|
|
||||||
expect(outputWithBothLintTasksCached).toContain(
|
|
||||||
'read the output from cache'
|
|
||||||
);
|
|
||||||
expectCached(outputWithBothLintTasksCached, [
|
|
||||||
myapp1,
|
|
||||||
myapp2,
|
|
||||||
`${myapp1}-e2e`,
|
|
||||||
`${myapp2}-e2e`
|
|
||||||
]);
|
|
||||||
}, 120000);
|
|
||||||
});
|
|
||||||
|
|
||||||
function expectCached(actual: string, expected: string[]) {
|
|
||||||
const section = actual.split('read the output from cache')[1];
|
|
||||||
const r = section
|
|
||||||
.split('\n')
|
|
||||||
.filter(l => l.trim().startsWith('-'))
|
|
||||||
.map(l => l.split('- ')[1].trim());
|
|
||||||
r.sort((a, b) => a.localeCompare(b));
|
|
||||||
expected.sort((a, b) => a.localeCompare(b));
|
|
||||||
expect(r).toEqual(expected);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
272
e2e/cli.test.ts
Normal file
272
e2e/cli.test.ts
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
import {
|
||||||
|
ensureProject,
|
||||||
|
forEachCli,
|
||||||
|
newProject,
|
||||||
|
readFile,
|
||||||
|
readJson,
|
||||||
|
runCLI,
|
||||||
|
runCommand,
|
||||||
|
tmpProjPath,
|
||||||
|
updateFile
|
||||||
|
} from './utils';
|
||||||
|
import { packagesWeCareAbout } from '@nrwl/workspace/src/command-line/report';
|
||||||
|
import { renameSync } from 'fs';
|
||||||
|
|
||||||
|
forEachCli('nx', () => {
|
||||||
|
describe('Help', () => {
|
||||||
|
it('should show help', async () => {
|
||||||
|
ensureProject();
|
||||||
|
|
||||||
|
let mainHelp = runCLI(`--help`);
|
||||||
|
expect(mainHelp).toContain('Run a target for a project');
|
||||||
|
expect(mainHelp).toContain('Run task for affected projects');
|
||||||
|
|
||||||
|
mainHelp = runCLI(`help`);
|
||||||
|
expect(mainHelp).toContain('Run a target for a project');
|
||||||
|
expect(mainHelp).toContain('Run task for affected projects');
|
||||||
|
|
||||||
|
const genHelp = runCLI(`g @nrwl/web:app --help`);
|
||||||
|
expect(genHelp).toContain(
|
||||||
|
'The file extension to be used for style files. (default: css)'
|
||||||
|
);
|
||||||
|
|
||||||
|
const affectedHelp = runCLI(`affected --help`);
|
||||||
|
expect(affectedHelp).toContain('Run task for affected projects');
|
||||||
|
|
||||||
|
const version = runCLI(`--version`);
|
||||||
|
expect(version).toContain('*'); // stub value
|
||||||
|
}, 120000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
forEachCli('angular', () => {
|
||||||
|
describe('help', () => {
|
||||||
|
it('should show help', async () => {
|
||||||
|
ensureProject();
|
||||||
|
|
||||||
|
let mainHelp = runCLI(`--help`);
|
||||||
|
expect(mainHelp).toContain('Run a target for a project');
|
||||||
|
expect(mainHelp).toContain('Run task for affected projects');
|
||||||
|
|
||||||
|
mainHelp = runCLI(`help`);
|
||||||
|
expect(mainHelp).toContain('Run a target for a project');
|
||||||
|
expect(mainHelp).toContain('Run task for affected projects');
|
||||||
|
|
||||||
|
const genHelp = runCLI(`g @nrwl/web:app --help`);
|
||||||
|
expect(genHelp).toContain(
|
||||||
|
'The file extension to be used for style files.'
|
||||||
|
);
|
||||||
|
|
||||||
|
const affectedHelp = runCLI(`affected --help`);
|
||||||
|
expect(affectedHelp).toContain('Run task for affected projects');
|
||||||
|
|
||||||
|
const version = runCLI(`--version`);
|
||||||
|
expect(version).toContain('*'); // stub value
|
||||||
|
}, 120000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
forEachCli(() => {
|
||||||
|
describe('report', () => {
|
||||||
|
it(`should report package versions`, async () => {
|
||||||
|
ensureProject();
|
||||||
|
|
||||||
|
const reportOutput = runCommand('npm run nx report');
|
||||||
|
|
||||||
|
packagesWeCareAbout.forEach(p => {
|
||||||
|
expect(reportOutput).toContain(p);
|
||||||
|
});
|
||||||
|
}, 120000);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('list', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
newProject();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should work`, async () => {
|
||||||
|
let listOutput = runCommand('npm run nx -- list');
|
||||||
|
|
||||||
|
expect(listOutput).toContain('NX Installed plugins');
|
||||||
|
|
||||||
|
// just check for some, not all
|
||||||
|
expect(listOutput).toContain('@nrwl/angular');
|
||||||
|
expect(listOutput).toContain('@schematics/angular');
|
||||||
|
expect(listOutput).toContain('@ngrx/store');
|
||||||
|
|
||||||
|
expect(listOutput).not.toContain('NX Also available');
|
||||||
|
|
||||||
|
// temporarily make it look like this isn't installed
|
||||||
|
renameSync(
|
||||||
|
tmpProjPath('node_modules/@nrwl/angular'),
|
||||||
|
tmpProjPath('node_modules/@nrwl/angular_tmp')
|
||||||
|
);
|
||||||
|
|
||||||
|
listOutput = runCommand('npm run nx -- list');
|
||||||
|
expect(listOutput).toContain('NX Also available');
|
||||||
|
|
||||||
|
// look for specific plugin
|
||||||
|
listOutput = runCommand('npm run nx -- list @nrwl/workspace');
|
||||||
|
|
||||||
|
expect(listOutput).toContain('Capabilities in @nrwl/workspace');
|
||||||
|
|
||||||
|
// check for schematics
|
||||||
|
expect(listOutput).toContain('workspace');
|
||||||
|
expect(listOutput).toContain('ng-add');
|
||||||
|
expect(listOutput).toContain('library');
|
||||||
|
|
||||||
|
// check for builders
|
||||||
|
expect(listOutput).toContain('run-commands');
|
||||||
|
|
||||||
|
// look for uninstalled approved plugin
|
||||||
|
listOutput = runCommand('npm run nx -- list @nrwl/angular');
|
||||||
|
|
||||||
|
expect(listOutput).toContain(
|
||||||
|
'NX NOTE @nrwl/angular is not currently installed'
|
||||||
|
);
|
||||||
|
|
||||||
|
// look for an unknown plugin
|
||||||
|
listOutput = runCommand('npm run nx -- list @wibble/fish');
|
||||||
|
|
||||||
|
expect(listOutput).toContain(
|
||||||
|
'NX ERROR Could not find plugin @wibble/fish'
|
||||||
|
);
|
||||||
|
|
||||||
|
// put back the @nrwl/angular module (or all the other e2e tests after this will fail)
|
||||||
|
renameSync(
|
||||||
|
tmpProjPath('node_modules/@nrwl/angular_tmp'),
|
||||||
|
tmpProjPath('node_modules/@nrwl/angular')
|
||||||
|
);
|
||||||
|
}, 120000);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('migrate', () => {
|
||||||
|
it('should run migrations', () => {
|
||||||
|
ensureProject();
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`./node_modules/migrate-parent-package/package.json`,
|
||||||
|
JSON.stringify({
|
||||||
|
version: '1.0.0',
|
||||||
|
'nx-migrations': './migrations.json'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`./node_modules/migrate-parent-package/migrations.json`,
|
||||||
|
JSON.stringify({
|
||||||
|
schematics: {
|
||||||
|
run11: {
|
||||||
|
version: '1.1.0',
|
||||||
|
description: '1.1.0',
|
||||||
|
factory: './run11'
|
||||||
|
},
|
||||||
|
run20: {
|
||||||
|
version: '2.0.0',
|
||||||
|
description: '2.0.0',
|
||||||
|
factory: './run20'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`./node_modules/migrate-parent-package/run11.js`,
|
||||||
|
`
|
||||||
|
exports.default = function default_1() {
|
||||||
|
return function(host) {
|
||||||
|
host.create('file-11', 'content11')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`./node_modules/migrate-parent-package/run20.js`,
|
||||||
|
`
|
||||||
|
exports.default = function default_1() {
|
||||||
|
return function(host) {
|
||||||
|
host.create('file-20', 'content20')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`./node_modules/migrate-child-package/package.json`,
|
||||||
|
JSON.stringify({
|
||||||
|
version: '1.0.0'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
'./node_modules/@nrwl/tao/src/commands/migrate.js',
|
||||||
|
content => {
|
||||||
|
const start = content.indexOf('// testing-fetch-start');
|
||||||
|
const end = content.indexOf('// testing-fetch-end');
|
||||||
|
|
||||||
|
const before = content.substring(0, start);
|
||||||
|
const after = content.substring(end);
|
||||||
|
const newFetch = `
|
||||||
|
function createFetcher(logger) {
|
||||||
|
return function fetch(packageName) {
|
||||||
|
if (packageName === 'migrate-parent-package') {
|
||||||
|
return Promise.resolve({
|
||||||
|
version: '2.0.0',
|
||||||
|
schematics: {
|
||||||
|
'run11': {
|
||||||
|
version: '1.1.0'
|
||||||
|
},
|
||||||
|
'run20': {
|
||||||
|
version: '2.0.0'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
packageJsonUpdates: {
|
||||||
|
'run-11': {version: '1.1.0', packages: {'migrate-child-package': {version: '9.0.0', alwaysAddToPackageJson: true}}},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Promise.resolve({version: '9.0.0'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
return `${before}${newFetch}${after}`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
runCLI(
|
||||||
|
'migrate migrate-parent-package@2.0.0 --from="migrate-parent-package@1.0.0"'
|
||||||
|
);
|
||||||
|
|
||||||
|
// updates package.json
|
||||||
|
const packageJson = readJson(`package.json`);
|
||||||
|
expect(packageJson.dependencies['migrate-child-package']).toEqual(
|
||||||
|
'9.0.0'
|
||||||
|
);
|
||||||
|
|
||||||
|
// creates migrations.json
|
||||||
|
const migrationsJson = readJson(`migrations.json`);
|
||||||
|
expect(migrationsJson).toEqual({
|
||||||
|
migrations: [
|
||||||
|
{
|
||||||
|
package: 'migrate-parent-package',
|
||||||
|
version: '1.1.0',
|
||||||
|
name: 'run11'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
package: 'migrate-parent-package',
|
||||||
|
version: '2.0.0',
|
||||||
|
name: 'run20'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// runs migrations
|
||||||
|
runCLI('migrate --run-migrations=migrations.json');
|
||||||
|
expect(readFile('file-11')).toEqual('content11');
|
||||||
|
expect(readFile('file-20')).toEqual('content20');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,328 +0,0 @@
|
|||||||
import {
|
|
||||||
checkFilesExist,
|
|
||||||
newProject,
|
|
||||||
readFile,
|
|
||||||
readJson,
|
|
||||||
runCLI,
|
|
||||||
runCommand,
|
|
||||||
updateFile,
|
|
||||||
exists,
|
|
||||||
ensureProject,
|
|
||||||
uniq,
|
|
||||||
forEachCli,
|
|
||||||
workspaceConfigName
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
forEachCli(() => {
|
|
||||||
describe('Command line', () => {
|
|
||||||
it('lint should ensure module boundaries', () => {
|
|
||||||
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');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp} --tags=validtag`);
|
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp2}`);
|
|
||||||
runCLI(`generate @nrwl/angular:lib ${mylib}`);
|
|
||||||
runCLI(`generate @nrwl/angular:lib ${lazylib}`);
|
|
||||||
runCLI(`generate @nrwl/angular:lib ${invalidtaglib} --tags=invalidtag`);
|
|
||||||
runCLI(`generate @nrwl/angular:lib ${validtaglib} --tags=validtag`);
|
|
||||||
|
|
||||||
const tslint = readJson('tslint.json');
|
|
||||||
tslint.rules['nx-enforce-module-boundaries'][1].depConstraints = [
|
|
||||||
{ sourceTag: 'validtag', onlyDependOnLibsWithTags: ['validtag'] },
|
|
||||||
...tslint.rules['nx-enforce-module-boundaries'][1].depConstraints
|
|
||||||
];
|
|
||||||
updateFile('tslint.json', JSON.stringify(tslint, null, 2));
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`apps/${myapp}/src/main.ts`,
|
|
||||||
`
|
|
||||||
import '../../../libs/${mylib}';
|
|
||||||
import '@proj/${lazylib}';
|
|
||||||
import '@proj/${myapp2}';
|
|
||||||
import '@proj/${invalidtaglib}';
|
|
||||||
import '@proj/${validtaglib}';
|
|
||||||
|
|
||||||
const s = {loadChildren: '@proj/${lazylib}'};
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
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('imports of apps are forbidden');
|
|
||||||
expect(out).toContain(
|
|
||||||
'A project tagged with "validtag" can only depend on libs tagged with "validtag"'
|
|
||||||
);
|
|
||||||
}, 1000000);
|
|
||||||
|
|
||||||
describe('nx lint', () => {
|
|
||||||
afterAll(() => {
|
|
||||||
newProject();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should run nx lint', () => {
|
|
||||||
ensureProject();
|
|
||||||
const appBefore = uniq('before');
|
|
||||||
const appAfter = uniq('after');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/angular:app ${appBefore}`);
|
|
||||||
runCommand(`mv apps/${appBefore} apps/${appAfter}`);
|
|
||||||
|
|
||||||
const stdout = runCommand('./node_modules/.bin/nx workspace-lint');
|
|
||||||
expect(stdout).toContain(
|
|
||||||
`- Cannot find project '${appBefore}' in 'apps/${appBefore}'`
|
|
||||||
);
|
|
||||||
expect(stdout).toContain(
|
|
||||||
'The following file(s) do not belong to any projects:'
|
|
||||||
);
|
|
||||||
expect(stdout).toContain(`- apps/${appAfter}/browserslist`);
|
|
||||||
expect(stdout).toContain(
|
|
||||||
`- apps/${appAfter}/src/app/app.component.css`
|
|
||||||
);
|
|
||||||
expect(stdout).toContain(
|
|
||||||
`- apps/${appAfter}/src/app/app.component.html`
|
|
||||||
);
|
|
||||||
expect(stdout).toContain(
|
|
||||||
`- apps/${appAfter}/src/app/app.component.spec.ts`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('format should check and reformat the code', () => {
|
|
||||||
ensureProject();
|
|
||||||
const myapp = uniq('myapp');
|
|
||||||
const mylib = uniq('mylib');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp}`);
|
|
||||||
runCLI(`generate @nrwl/angular:lib ${mylib}`);
|
|
||||||
updateFile(
|
|
||||||
`apps/${myapp}/src/main.ts`,
|
|
||||||
`
|
|
||||||
const x = 1111;
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`apps/${myapp}/src/app/app.module.ts`,
|
|
||||||
`
|
|
||||||
const y = 1111;
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`apps/${myapp}/src/app/app.component.ts`,
|
|
||||||
`
|
|
||||||
const z = 1111;
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`libs/${mylib}/index.ts`,
|
|
||||||
`
|
|
||||||
const x = 1111;
|
|
||||||
`
|
|
||||||
);
|
|
||||||
updateFile(
|
|
||||||
`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`
|
|
||||||
);
|
|
||||||
expect(stdout).toContain(`libs/${mylib}/index.ts`);
|
|
||||||
expect(stdout).toContain(`libs/${mylib}/src/${mylib}.module.ts`);
|
|
||||||
|
|
||||||
stdout = runCommand(`npm run -s format:check -- --all`);
|
|
||||||
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"`
|
|
||||||
);
|
|
||||||
|
|
||||||
stdout = runCommand('npm run -s format:check -- --all');
|
|
||||||
|
|
||||||
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 -- --all');
|
|
||||||
expect(runCommand('npm run -s format:check -- --all')).toEqual('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support workspace-specific schematics', () => {
|
|
||||||
ensureProject();
|
|
||||||
const custom = uniq('custom');
|
|
||||||
runCLI(`g workspace-schematic ${custom} --no-interactive`);
|
|
||||||
checkFilesExist(
|
|
||||||
`tools/schematics/${custom}/index.ts`,
|
|
||||||
`tools/schematics/${custom}/schema.json`
|
|
||||||
);
|
|
||||||
|
|
||||||
const json = readJson(`tools/schematics/${custom}/schema.json`);
|
|
||||||
json.properties['directory'] = {
|
|
||||||
type: 'string',
|
|
||||||
description: 'lib directory'
|
|
||||||
};
|
|
||||||
json.properties['skipTsConfig'] = {
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'skip changes to tsconfig'
|
|
||||||
};
|
|
||||||
updateFile(
|
|
||||||
`tools/schematics/${custom}/schema.json`,
|
|
||||||
JSON.stringify(json)
|
|
||||||
);
|
|
||||||
|
|
||||||
const indexFile = readFile(`tools/schematics/${custom}/index.ts`);
|
|
||||||
updateFile(
|
|
||||||
`tools/schematics/${custom}/index.ts`,
|
|
||||||
indexFile.replace(
|
|
||||||
'name: schema.name',
|
|
||||||
'name: schema.name, directory: schema.directory, skipTsConfig: schema.skipTsConfig'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const workspace = uniq('workspace');
|
|
||||||
const dryRunOutput = runCommand(
|
|
||||||
`npm run workspace-schematic ${custom} ${workspace} -- --no-interactive --directory=dir --skipTsConfig=true -d`
|
|
||||||
);
|
|
||||||
expect(exists(`libs/dir/${workspace}/src/index.ts`)).toEqual(false);
|
|
||||||
expect(dryRunOutput).toContain(`UPDATE ${workspaceConfigName()}`);
|
|
||||||
expect(dryRunOutput).toContain('UPDATE nx.json');
|
|
||||||
expect(dryRunOutput).not.toContain('UPDATE tsconfig.json');
|
|
||||||
|
|
||||||
const output = runCommand(
|
|
||||||
`npm run workspace-schematic ${custom} ${workspace} -- --no-interactive --directory=dir`
|
|
||||||
);
|
|
||||||
checkFilesExist(`libs/dir/${workspace}/src/index.ts`);
|
|
||||||
expect(output).toContain(`UPDATE ${workspaceConfigName()}`);
|
|
||||||
expect(output).toContain('UPDATE nx.json');
|
|
||||||
|
|
||||||
const another = uniq('another');
|
|
||||||
runCLI(`g workspace-schematic ${another} --no-interactive`);
|
|
||||||
|
|
||||||
const listSchematicsOutput = runCommand(
|
|
||||||
'npm run workspace-schematic -- --list-schematics'
|
|
||||||
);
|
|
||||||
expect(listSchematicsOutput).toContain(
|
|
||||||
'nx workspace-schematic "--list-schematics"'
|
|
||||||
);
|
|
||||||
expect(listSchematicsOutput).toContain(custom);
|
|
||||||
expect(listSchematicsOutput).toContain(another);
|
|
||||||
|
|
||||||
const promptOutput = runCommand(
|
|
||||||
`npm run workspace-schematic ${custom} mylib2 --dry-run`
|
|
||||||
);
|
|
||||||
expect(promptOutput).toContain('UPDATE nx.json');
|
|
||||||
}, 1000000);
|
|
||||||
|
|
||||||
describe('dep-graph', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
newProject();
|
|
||||||
runCLI('generate @nrwl/angular:app myapp');
|
|
||||||
runCLI('generate @nrwl/angular:app myapp2');
|
|
||||||
runCLI('generate @nrwl/angular:app myapp3');
|
|
||||||
runCLI('generate @nrwl/angular:lib mylib');
|
|
||||||
runCLI('generate @nrwl/angular:lib mylib2');
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
'apps/myapp/src/main.ts',
|
|
||||||
`
|
|
||||||
import '@proj/mylib';
|
|
||||||
|
|
||||||
const s = {loadChildren: '@proj/mylib2'};
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
'apps/myapp2/src/app/app.component.spec.ts',
|
|
||||||
`import '@proj/mylib';`
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
'libs/mylib/src/mylib.module.spec.ts',
|
|
||||||
`import '@proj/mylib2';`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('dep-graph should output json to file', () => {
|
|
||||||
runCommand(`npm run dep-graph -- --file=project-graph.json`);
|
|
||||||
|
|
||||||
expect(() => checkFilesExist('project-graph.json')).not.toThrow();
|
|
||||||
|
|
||||||
const jsonFileContents = readJson('project-graph.json');
|
|
||||||
|
|
||||||
expect(jsonFileContents.graph.dependencies).toEqual({
|
|
||||||
'myapp3-e2e': [
|
|
||||||
{
|
|
||||||
source: 'myapp3-e2e',
|
|
||||||
target: 'myapp3',
|
|
||||||
type: 'implicit'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
myapp2: [
|
|
||||||
{
|
|
||||||
source: 'myapp2',
|
|
||||||
target: 'mylib',
|
|
||||||
type: 'static'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'myapp2-e2e': [
|
|
||||||
{
|
|
||||||
source: 'myapp2-e2e',
|
|
||||||
target: 'myapp2',
|
|
||||||
type: 'implicit'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
mylib: [
|
|
||||||
{
|
|
||||||
source: 'mylib',
|
|
||||||
target: 'mylib2',
|
|
||||||
type: 'static'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
mylib2: [],
|
|
||||||
myapp: [
|
|
||||||
{
|
|
||||||
source: 'myapp',
|
|
||||||
target: 'mylib',
|
|
||||||
type: 'static'
|
|
||||||
},
|
|
||||||
{ source: 'myapp', target: 'mylib2', type: 'dynamic' }
|
|
||||||
],
|
|
||||||
'myapp-e2e': [
|
|
||||||
{
|
|
||||||
source: 'myapp-e2e',
|
|
||||||
target: 'myapp',
|
|
||||||
type: 'implicit'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
myapp3: []
|
|
||||||
});
|
|
||||||
|
|
||||||
runCommand(
|
|
||||||
`npm run affected:dep-graph -- --files="libs/mylib/src/index.ts" --file="project-graph.json"`
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(() => checkFilesExist('project-graph.json')).not.toThrow();
|
|
||||||
|
|
||||||
const jsonFileContents2 = readJson('project-graph.json');
|
|
||||||
|
|
||||||
expect(jsonFileContents2.criticalPath).toContain('myapp');
|
|
||||||
expect(jsonFileContents2.criticalPath).toContain('myapp2');
|
|
||||||
expect(jsonFileContents2.criticalPath).toContain('mylib');
|
|
||||||
expect(jsonFileContents2.criticalPath).not.toContain('mylib2');
|
|
||||||
}, 1000000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
import {
|
|
||||||
ensureProject,
|
|
||||||
uniq,
|
|
||||||
runCommand,
|
|
||||||
checkFilesExist,
|
|
||||||
forEachCli
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
forEachCli(() => {
|
|
||||||
describe('Delegate to CLI', () => {
|
|
||||||
it('should delegate to the cli all non-standard commands', async () => {
|
|
||||||
ensureProject();
|
|
||||||
|
|
||||||
const appName = uniq('app');
|
|
||||||
runCommand(`npm run nx -- g @nrwl/web:app ${appName}`);
|
|
||||||
runCommand(`npm run nx -- build ${appName} --prod --outputHashing none`);
|
|
||||||
|
|
||||||
checkFilesExist(
|
|
||||||
`dist/apps/${appName}/index.html`,
|
|
||||||
`dist/apps/${appName}/runtime.js`,
|
|
||||||
`dist/apps/${appName}/polyfills.esm.js`,
|
|
||||||
`dist/apps/${appName}/main.esm.js`,
|
|
||||||
`dist/apps/${appName}/polyfills.es5.js`,
|
|
||||||
`dist/apps/${appName}/main.es5.js`,
|
|
||||||
`dist/apps/${appName}/styles.css`
|
|
||||||
);
|
|
||||||
}, 120000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
import { ensureProject, forEachCli, runCLI } from './utils';
|
|
||||||
|
|
||||||
forEachCli('nx', () => {
|
|
||||||
describe('Help', () => {
|
|
||||||
it('should show help', async () => {
|
|
||||||
ensureProject();
|
|
||||||
|
|
||||||
let mainHelp = runCLI(`--help`);
|
|
||||||
expect(mainHelp).toContain('Run a target for a project');
|
|
||||||
expect(mainHelp).toContain('Run task for affected projects');
|
|
||||||
|
|
||||||
mainHelp = runCLI(`help`);
|
|
||||||
expect(mainHelp).toContain('Run a target for a project');
|
|
||||||
expect(mainHelp).toContain('Run task for affected projects');
|
|
||||||
|
|
||||||
const genHelp = runCLI(`g @nrwl/web:app --help`);
|
|
||||||
expect(genHelp).toContain(
|
|
||||||
'The file extension to be used for style files. (default: css)'
|
|
||||||
);
|
|
||||||
|
|
||||||
const affectedHelp = runCLI(`affected --help`);
|
|
||||||
expect(affectedHelp).toContain('Run task for affected projects');
|
|
||||||
|
|
||||||
const version = runCLI(`--version`);
|
|
||||||
expect(version).toContain('*'); // stub value
|
|
||||||
}, 120000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
forEachCli('angular', () => {
|
|
||||||
describe('Help', () => {
|
|
||||||
it('should show help', async () => {
|
|
||||||
ensureProject();
|
|
||||||
|
|
||||||
let mainHelp = runCLI(`--help`);
|
|
||||||
expect(mainHelp).toContain('Run a target for a project');
|
|
||||||
expect(mainHelp).toContain('Run task for affected projects');
|
|
||||||
|
|
||||||
mainHelp = runCLI(`help`);
|
|
||||||
expect(mainHelp).toContain('Run a target for a project');
|
|
||||||
expect(mainHelp).toContain('Run task for affected projects');
|
|
||||||
|
|
||||||
const genHelp = runCLI(`g @nrwl/web:app --help`);
|
|
||||||
expect(genHelp).toContain(
|
|
||||||
'The file extension to be used for style files.'
|
|
||||||
);
|
|
||||||
|
|
||||||
const affectedHelp = runCLI(`affected --help`);
|
|
||||||
expect(affectedHelp).toContain('Run task for affected projects');
|
|
||||||
|
|
||||||
const version = runCLI(`--version`);
|
|
||||||
expect(version).toContain('*'); // stub value
|
|
||||||
}, 120000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
import { renameSync } from 'fs';
|
|
||||||
import { forEachCli, newProject, runCommand, tmpProjPath } from './utils';
|
|
||||||
|
|
||||||
const testTimeout = 120000;
|
|
||||||
|
|
||||||
forEachCli(() => {
|
|
||||||
describe('list', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
newProject();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(
|
|
||||||
`should work`,
|
|
||||||
async () => {
|
|
||||||
let listOutput = runCommand('npm run nx -- list');
|
|
||||||
|
|
||||||
expect(listOutput).toContain('NX Installed plugins');
|
|
||||||
|
|
||||||
// just check for some, not all
|
|
||||||
expect(listOutput).toContain('@nrwl/angular');
|
|
||||||
expect(listOutput).toContain('@schematics/angular');
|
|
||||||
expect(listOutput).toContain('@ngrx/store');
|
|
||||||
|
|
||||||
expect(listOutput).not.toContain('NX Also available');
|
|
||||||
|
|
||||||
// temporarily make it look like this isn't installed
|
|
||||||
renameSync(
|
|
||||||
tmpProjPath('node_modules/@nrwl/angular'),
|
|
||||||
tmpProjPath('node_modules/@nrwl/angular_tmp')
|
|
||||||
);
|
|
||||||
|
|
||||||
listOutput = runCommand('npm run nx -- list');
|
|
||||||
expect(listOutput).toContain('NX Also available');
|
|
||||||
|
|
||||||
// look for specific plugin
|
|
||||||
listOutput = runCommand('npm run nx -- list @nrwl/workspace');
|
|
||||||
|
|
||||||
expect(listOutput).toContain('Capabilities in @nrwl/workspace');
|
|
||||||
|
|
||||||
// check for schematics
|
|
||||||
expect(listOutput).toContain('workspace');
|
|
||||||
expect(listOutput).toContain('ng-add');
|
|
||||||
expect(listOutput).toContain('library');
|
|
||||||
|
|
||||||
// check for builders
|
|
||||||
expect(listOutput).toContain('run-commands');
|
|
||||||
|
|
||||||
// look for uninstalled approved plugin
|
|
||||||
listOutput = runCommand('npm run nx -- list @nrwl/angular');
|
|
||||||
|
|
||||||
expect(listOutput).toContain(
|
|
||||||
'NX NOTE @nrwl/angular is not currently installed'
|
|
||||||
);
|
|
||||||
|
|
||||||
// look for an unknown plugin
|
|
||||||
listOutput = runCommand('npm run nx -- list @wibble/fish');
|
|
||||||
|
|
||||||
expect(listOutput).toContain(
|
|
||||||
'NX ERROR Could not find plugin @wibble/fish'
|
|
||||||
);
|
|
||||||
|
|
||||||
// put back the @nrwl/angular module (or all the other e2e tests after this will fail)
|
|
||||||
renameSync(
|
|
||||||
tmpProjPath('node_modules/@nrwl/angular_tmp'),
|
|
||||||
tmpProjPath('node_modules/@nrwl/angular')
|
|
||||||
);
|
|
||||||
},
|
|
||||||
testTimeout
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,140 +0,0 @@
|
|||||||
import {
|
|
||||||
ensureProject,
|
|
||||||
forEachCli,
|
|
||||||
readFile,
|
|
||||||
readJson,
|
|
||||||
runCLI,
|
|
||||||
updateFile
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
forEachCli(() => {
|
|
||||||
describe('migrate', () => {
|
|
||||||
it('should run migrations', () => {
|
|
||||||
ensureProject();
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`./node_modules/migrate-parent-package/package.json`,
|
|
||||||
JSON.stringify({
|
|
||||||
version: '1.0.0',
|
|
||||||
'nx-migrations': './migrations.json'
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`./node_modules/migrate-parent-package/migrations.json`,
|
|
||||||
JSON.stringify({
|
|
||||||
schematics: {
|
|
||||||
run11: {
|
|
||||||
version: '1.1.0',
|
|
||||||
description: '1.1.0',
|
|
||||||
factory: './run11'
|
|
||||||
},
|
|
||||||
run20: {
|
|
||||||
version: '2.0.0',
|
|
||||||
description: '2.0.0',
|
|
||||||
factory: './run20'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`./node_modules/migrate-parent-package/run11.js`,
|
|
||||||
`
|
|
||||||
exports.default = function default_1() {
|
|
||||||
return function(host) {
|
|
||||||
host.create('file-11', 'content11')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`./node_modules/migrate-parent-package/run20.js`,
|
|
||||||
`
|
|
||||||
exports.default = function default_1() {
|
|
||||||
return function(host) {
|
|
||||||
host.create('file-20', 'content20')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`./node_modules/migrate-child-package/package.json`,
|
|
||||||
JSON.stringify({
|
|
||||||
version: '1.0.0'
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
'./node_modules/@nrwl/tao/src/commands/migrate.js',
|
|
||||||
content => {
|
|
||||||
const start = content.indexOf('// testing-fetch-start');
|
|
||||||
const end = content.indexOf('// testing-fetch-end');
|
|
||||||
|
|
||||||
const before = content.substring(0, start);
|
|
||||||
const after = content.substring(end);
|
|
||||||
const newFetch = `
|
|
||||||
function createFetcher(logger) {
|
|
||||||
return function fetch(packageName) {
|
|
||||||
if (packageName === 'migrate-parent-package') {
|
|
||||||
return Promise.resolve({
|
|
||||||
version: '2.0.0',
|
|
||||||
schematics: {
|
|
||||||
'run11': {
|
|
||||||
version: '1.1.0'
|
|
||||||
},
|
|
||||||
'run20': {
|
|
||||||
version: '2.0.0'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
packageJsonUpdates: {
|
|
||||||
'run-11': {version: '1.1.0', packages: {'migrate-child-package': {version: '9.0.0', alwaysAddToPackageJson: true}}},
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return Promise.resolve({version: '9.0.0'});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
return `${before}${newFetch}${after}`;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
runCLI(
|
|
||||||
'migrate migrate-parent-package@2.0.0 --from="migrate-parent-package@1.0.0"'
|
|
||||||
);
|
|
||||||
|
|
||||||
// updates package.json
|
|
||||||
const packageJson = readJson(`package.json`);
|
|
||||||
expect(packageJson.dependencies['migrate-child-package']).toEqual(
|
|
||||||
'9.0.0'
|
|
||||||
);
|
|
||||||
|
|
||||||
// creates migrations.json
|
|
||||||
const migrationsJson = readJson(`migrations.json`);
|
|
||||||
expect(migrationsJson).toEqual({
|
|
||||||
migrations: [
|
|
||||||
{
|
|
||||||
package: 'migrate-parent-package',
|
|
||||||
version: '1.1.0',
|
|
||||||
name: 'run11'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
package: 'migrate-parent-package',
|
|
||||||
version: '2.0.0',
|
|
||||||
name: 'run20'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
// runs migrations
|
|
||||||
runCLI('migrate --run-migrations=migrations.json');
|
|
||||||
expect(readFile('file-11')).toEqual('content11');
|
|
||||||
expect(readFile('file-20')).toEqual('content20');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,155 +0,0 @@
|
|||||||
import { classify } from '@nrwl/workspace/src/utils/strings';
|
|
||||||
import {
|
|
||||||
checkFilesExist,
|
|
||||||
forEachCli,
|
|
||||||
newProject,
|
|
||||||
readFile,
|
|
||||||
readJson,
|
|
||||||
runCLI,
|
|
||||||
uniq,
|
|
||||||
updateFile
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
forEachCli(cli => {
|
|
||||||
describe('Move Angular Project', () => {
|
|
||||||
const workspace: string = cli === 'angular' ? 'angular' : 'workspace';
|
|
||||||
|
|
||||||
describe('Apps', () => {
|
|
||||||
let app1: string;
|
|
||||||
let app2: string;
|
|
||||||
let newPath: string;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
app1 = uniq('app1');
|
|
||||||
app2 = uniq('app2');
|
|
||||||
newPath = `subfolder/${app2}`;
|
|
||||||
newProject();
|
|
||||||
runCLI(`generate @nrwl/angular:app ${app1}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries moving an app from ${app1} -> subfolder/${app2}
|
|
||||||
*/
|
|
||||||
it('should work for apps', () => {
|
|
||||||
const moveOutput = runCLI(
|
|
||||||
`generate @nrwl/angular:move --project ${app1} ${newPath}`
|
|
||||||
);
|
|
||||||
|
|
||||||
// just check the output
|
|
||||||
expect(moveOutput).toContain(`DELETE apps/${app1}`);
|
|
||||||
expect(moveOutput).toContain(`CREATE apps/${newPath}/browserslist`);
|
|
||||||
expect(moveOutput).toContain(`CREATE apps/${newPath}/jest.config.js`);
|
|
||||||
expect(moveOutput).toContain(
|
|
||||||
`CREATE apps/${newPath}/tsconfig.app.json`
|
|
||||||
);
|
|
||||||
expect(moveOutput).toContain(`CREATE apps/${newPath}/tsconfig.json`);
|
|
||||||
expect(moveOutput).toContain(
|
|
||||||
`CREATE apps/${newPath}/tsconfig.spec.json`
|
|
||||||
);
|
|
||||||
expect(moveOutput).toContain(`CREATE apps/${newPath}/tslint.json`);
|
|
||||||
expect(moveOutput).toContain(`CREATE apps/${newPath}/src/favicon.ico`);
|
|
||||||
expect(moveOutput).toContain(`CREATE apps/${newPath}/src/index.html`);
|
|
||||||
expect(moveOutput).toContain(`CREATE apps/${newPath}/src/main.ts`);
|
|
||||||
expect(moveOutput).toContain(`CREATE apps/${newPath}/src/polyfills.ts`);
|
|
||||||
expect(moveOutput).toContain(`CREATE apps/${newPath}/src/styles.css`);
|
|
||||||
expect(moveOutput).toContain(
|
|
||||||
`CREATE apps/${newPath}/src/test-setup.ts`
|
|
||||||
);
|
|
||||||
expect(moveOutput).toContain(
|
|
||||||
`CREATE apps/${newPath}/src/app/app.component.html`
|
|
||||||
);
|
|
||||||
expect(moveOutput).toContain(
|
|
||||||
`CREATE apps/${newPath}/src/app/app.module.ts`
|
|
||||||
);
|
|
||||||
expect(moveOutput).toContain(
|
|
||||||
`CREATE apps/${newPath}/src/assets/.gitkeep`
|
|
||||||
);
|
|
||||||
expect(moveOutput).toContain(
|
|
||||||
`CREATE apps/${newPath}/src/environments/environment.prod.ts`
|
|
||||||
);
|
|
||||||
expect(moveOutput).toContain(
|
|
||||||
`CREATE apps/${newPath}/src/environments/environment.ts`
|
|
||||||
);
|
|
||||||
expect(moveOutput).toContain(`UPDATE nx.json`);
|
|
||||||
expect(moveOutput).toContain(`UPDATE ${workspace}.json`);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries moving an e2e project from ${app1} -> ${newPath}
|
|
||||||
*/
|
|
||||||
it('should work for e2e projects', () => {
|
|
||||||
const moveOutput = runCLI(
|
|
||||||
`generate @nrwl/angular:move --projectName=${app1}-e2e --destination=${newPath}-e2e`
|
|
||||||
);
|
|
||||||
|
|
||||||
// just check that the cypress.json is updated correctly
|
|
||||||
const cypressJsonPath = `apps/${newPath}-e2e/cypress.json`;
|
|
||||||
expect(moveOutput).toContain(`CREATE ${cypressJsonPath}`);
|
|
||||||
checkFilesExist(cypressJsonPath);
|
|
||||||
const cypressJson = readJson(cypressJsonPath);
|
|
||||||
expect(cypressJson.videosFolder).toEqual(
|
|
||||||
`../../../dist/cypress/apps/${newPath}-e2e/videos`
|
|
||||||
);
|
|
||||||
expect(cypressJson.screenshotsFolder).toEqual(
|
|
||||||
`../../../dist/cypress/apps/${newPath}-e2e/screenshots`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries moving a library from ${lib} -> shared/${lib}
|
|
||||||
*/
|
|
||||||
it('should work for libraries', () => {
|
|
||||||
const lib1 = uniq('mylib');
|
|
||||||
const lib2 = uniq('mylib');
|
|
||||||
newProject();
|
|
||||||
runCLI(`generate @nrwl/angular:lib ${lib1}`);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a library which imports the module from the other lib
|
|
||||||
*/
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/angular:lib ${lib2}`);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`libs/${lib2}/src/lib/${lib2}.module.ts`,
|
|
||||||
`import { ${classify(lib1)}Module } from '@proj/${lib1}';
|
|
||||||
|
|
||||||
export class ExtendedModule extends ${classify(lib1)}Module { }`
|
|
||||||
);
|
|
||||||
|
|
||||||
const moveOutput = runCLI(
|
|
||||||
`generate @nrwl/angular:move --projectName=${lib1} --destination=shared/${lib1}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const newPath = `libs/shared/${lib1}`;
|
|
||||||
const newModule = `Shared${classify(lib1)}Module`;
|
|
||||||
|
|
||||||
const testSetupPath = `${newPath}/src/test-setup.ts`;
|
|
||||||
expect(moveOutput).toContain(`CREATE ${testSetupPath}`);
|
|
||||||
checkFilesExist(testSetupPath);
|
|
||||||
|
|
||||||
const modulePath = `${newPath}/src/lib/shared-${lib1}.module.ts`;
|
|
||||||
expect(moveOutput).toContain(`CREATE ${modulePath}`);
|
|
||||||
checkFilesExist(modulePath);
|
|
||||||
const moduleFile = readFile(modulePath);
|
|
||||||
expect(moduleFile).toContain(`export class ${newModule}`);
|
|
||||||
|
|
||||||
const indexPath = `${newPath}/src/index.ts`;
|
|
||||||
expect(moveOutput).toContain(`CREATE ${indexPath}`);
|
|
||||||
checkFilesExist(indexPath);
|
|
||||||
const index = readFile(indexPath);
|
|
||||||
expect(index).toContain(`export * from './lib/shared-${lib1}.module'`);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that the import in lib2 has been updated
|
|
||||||
*/
|
|
||||||
const lib2FilePath = `libs/${lib2}/src/lib/${lib2}.module.ts`;
|
|
||||||
const lib2File = readFile(lib2FilePath);
|
|
||||||
expect(lib2File).toContain(
|
|
||||||
`import { ${newModule} } from '@proj/shared/${lib1}';`
|
|
||||||
);
|
|
||||||
expect(lib2File).toContain(`extends ${newModule}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,142 +0,0 @@
|
|||||||
import { NxJson } from '@nrwl/workspace';
|
|
||||||
import {
|
|
||||||
checkFilesExist,
|
|
||||||
exists,
|
|
||||||
forEachCli,
|
|
||||||
newProject,
|
|
||||||
readFile,
|
|
||||||
readJson,
|
|
||||||
runCLI,
|
|
||||||
uniq,
|
|
||||||
updateFile
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
forEachCli(cli => {
|
|
||||||
describe('Move Project', () => {
|
|
||||||
const workspace: string = cli === 'angular' ? 'angular' : 'workspace';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries moving a library from ${lib}/data-access -> shared/${lib}/data-access
|
|
||||||
*/
|
|
||||||
it('should work for libraries', () => {
|
|
||||||
const lib1 = uniq('mylib');
|
|
||||||
const lib2 = uniq('mylib');
|
|
||||||
newProject();
|
|
||||||
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 the other lib
|
|
||||||
*/
|
|
||||||
|
|
||||||
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(); }`
|
|
||||||
);
|
|
||||||
|
|
||||||
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.js`;
|
|
||||||
expect(moveOutput).toContain(`CREATE ${jestConfigPath}`);
|
|
||||||
checkFilesExist(jestConfigPath);
|
|
||||||
const jestConfig = readFile(jestConfigPath);
|
|
||||||
expect(jestConfig).toContain(`name: 'shared-${lib1}-data-access'`);
|
|
||||||
expect(jestConfig).toContain(`preset: '../../../../jest.config.js'`);
|
|
||||||
expect(jestConfig).toContain(
|
|
||||||
`coverageDirectory: '../../../../coverage/${newPath}'`
|
|
||||||
);
|
|
||||||
|
|
||||||
const tsConfigPath = `${newPath}/tsconfig.json`;
|
|
||||||
expect(moveOutput).toContain(`CREATE ${tsConfigPath}`);
|
|
||||||
checkFilesExist(tsConfigPath);
|
|
||||||
const tsConfig = readJson(tsConfigPath);
|
|
||||||
expect(tsConfig.extends).toEqual('../../../../tsconfig.json');
|
|
||||||
|
|
||||||
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 nx.json');
|
|
||||||
const nxJson = JSON.parse(readFile('nx.json')) as NxJson;
|
|
||||||
expect(nxJson.projects[`${lib1}-data-access`]).toBeUndefined();
|
|
||||||
expect(nxJson.projects[newName]).toEqual({
|
|
||||||
tags: []
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(moveOutput).toContain('UPDATE tsconfig.json');
|
|
||||||
const rootTsConfig = readJson('tsconfig.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`]);
|
|
||||||
|
|
||||||
expect(moveOutput).toContain(`UPDATE ${workspace}.json`);
|
|
||||||
const workspaceJson = readJson(`${workspace}.json`);
|
|
||||||
expect(workspaceJson.projects[`${lib1}-data-access`]).toBeUndefined();
|
|
||||||
const project = workspaceJson.projects[newName];
|
|
||||||
expect(project).toBeTruthy();
|
|
||||||
expect(project.root).toBe(newPath);
|
|
||||||
expect(project.sourceRoot).toBe(`${newPath}/src`);
|
|
||||||
expect(project.architect.lint.options.tsConfig).toEqual([
|
|
||||||
`libs/shared/${lib1}/data-access/tsconfig.lib.json`,
|
|
||||||
`libs/shared/${lib1}/data-access/tsconfig.spec.json`
|
|
||||||
]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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';`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,143 +0,0 @@
|
|||||||
import {
|
|
||||||
forEachCli,
|
|
||||||
newProject,
|
|
||||||
runCLI,
|
|
||||||
uniq,
|
|
||||||
updateFile,
|
|
||||||
runCommand
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
forEachCli(cliName => {
|
|
||||||
describe('print-affected', () => {
|
|
||||||
it('should print information about affected projects', () => {
|
|
||||||
newProject();
|
|
||||||
const myapp = uniq('myapp-a');
|
|
||||||
const myapp2 = uniq('myapp-b');
|
|
||||||
const mylib = uniq('mylib');
|
|
||||||
const mylib2 = uniq('mylib2');
|
|
||||||
const mypublishablelib = uniq('mypublishablelib');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${myapp}`);
|
|
||||||
runCLI(`generate @nrwl/react:app ${myapp2}`);
|
|
||||||
runCLI(`generate @nrwl/react:lib ${mylib}`);
|
|
||||||
runCLI(`generate @nrwl/react:lib ${mylib2}`);
|
|
||||||
runCLI(`generate @nrwl/react:lib ${mypublishablelib} --publishable`);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`apps/${myapp}/src/main.tsx`,
|
|
||||||
`
|
|
||||||
import React from 'react';
|
|
||||||
import ReactDOM from 'react-dom';
|
|
||||||
import "@proj/${mylib}";
|
|
||||||
import "@proj/${mypublishablelib}";
|
|
||||||
import App from './app/app';
|
|
||||||
|
|
||||||
ReactDOM.render(<App />, document.getElementById('root'));
|
|
||||||
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`apps/${myapp2}/src/main.tsx`,
|
|
||||||
`
|
|
||||||
import React from 'react';
|
|
||||||
import ReactDOM from 'react-dom';
|
|
||||||
import "@proj/${mylib}";
|
|
||||||
import "@proj/${mypublishablelib}";
|
|
||||||
import App from './app/app';
|
|
||||||
|
|
||||||
ReactDOM.render(<App />, document.getElementById('root'));
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
const resWithoutTarget = JSON.parse(
|
|
||||||
runCommand(
|
|
||||||
`npm run nx print-affected --silent -- --files=apps/${myapp}/src/main.tsx`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
expect(resWithoutTarget.tasks).toEqual([]);
|
|
||||||
compareTwoArrays(resWithoutTarget.projects, [`${myapp}-e2e`, myapp]);
|
|
||||||
|
|
||||||
const resWithTarget = JSON.parse(
|
|
||||||
runCommand(
|
|
||||||
`npm run nx print-affected --silent -- --files=apps/${myapp}/src/main.tsx --target=test`
|
|
||||||
).trim()
|
|
||||||
);
|
|
||||||
|
|
||||||
const cliCommand = cliName === 'angular' ? 'ng' : 'nx';
|
|
||||||
expect(resWithTarget.tasks).toEqual([
|
|
||||||
{
|
|
||||||
id: `${myapp}:test`,
|
|
||||||
overrides: {},
|
|
||||||
target: {
|
|
||||||
project: myapp,
|
|
||||||
target: 'test'
|
|
||||||
},
|
|
||||||
command: `npm run ${cliCommand} -- test ${myapp}`,
|
|
||||||
outputs: []
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
compareTwoArrays(resWithTarget.projects, [`${myapp}-e2e`, myapp]);
|
|
||||||
|
|
||||||
const resWithDeps = JSON.parse(
|
|
||||||
runCommand(
|
|
||||||
`npm run nx print-affected --silent -- --files=apps/${myapp}/src/main.tsx --target=build --with-deps`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
expect(resWithDeps.tasks).toEqual([
|
|
||||||
{
|
|
||||||
id: `${mypublishablelib}:build`,
|
|
||||||
overrides: {},
|
|
||||||
target: {
|
|
||||||
project: mypublishablelib,
|
|
||||||
target: 'build'
|
|
||||||
},
|
|
||||||
command: `npm run ${cliCommand} -- build ${mypublishablelib}`,
|
|
||||||
outputs: [`dist/libs/${mypublishablelib}`]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: `${myapp}:build`,
|
|
||||||
overrides: {},
|
|
||||||
target: {
|
|
||||||
project: myapp,
|
|
||||||
target: 'build'
|
|
||||||
},
|
|
||||||
command: `npm run ${cliCommand} -- build ${myapp}`,
|
|
||||||
outputs: [`dist/apps/${myapp}`]
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
compareTwoArrays(resWithDeps.projects, [
|
|
||||||
mylib,
|
|
||||||
mypublishablelib,
|
|
||||||
myapp,
|
|
||||||
`${myapp}-e2e`
|
|
||||||
]);
|
|
||||||
|
|
||||||
const resWithTargetWithSelect1 = runCommand(
|
|
||||||
`npm run nx print-affected --silent -- --files=apps/${myapp}/src/main.tsx --target=test --select=projects`
|
|
||||||
).trim();
|
|
||||||
compareTwoSerializedArrays(
|
|
||||||
resWithTargetWithSelect1,
|
|
||||||
`${myapp}-e2e, ${myapp}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const resWithTargetWithSelect2 = runCommand(
|
|
||||||
`npm run nx print-affected --silent -- --files=apps/${myapp}/src/main.tsx --target=test --select="tasks.target.project"`
|
|
||||||
).trim();
|
|
||||||
compareTwoSerializedArrays(resWithTargetWithSelect2, `${myapp}`);
|
|
||||||
}, 120000);
|
|
||||||
});
|
|
||||||
|
|
||||||
function compareTwoSerializedArrays(a: string, b: string) {
|
|
||||||
compareTwoArrays(
|
|
||||||
a.split(',').map(_ => _.trim()),
|
|
||||||
b.split(',').map(_ => _.trim())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function compareTwoArrays(a: string[], b: string[]) {
|
|
||||||
expect(a.sort((x, y) => x.localeCompare(y))).toEqual(
|
|
||||||
b.sort((x, y) => x.localeCompare(y))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
import { packagesWeCareAbout } from '../packages/workspace/src/command-line/report';
|
|
||||||
import { ensureProject, forEachCli, runCommand } from './utils';
|
|
||||||
|
|
||||||
const testTimeout = 120000;
|
|
||||||
|
|
||||||
forEachCli(() => {
|
|
||||||
describe('report', () => {
|
|
||||||
it(
|
|
||||||
`should report package versions`,
|
|
||||||
async () => {
|
|
||||||
ensureProject();
|
|
||||||
|
|
||||||
const reportOutput = runCommand('npm run nx report');
|
|
||||||
|
|
||||||
packagesWeCareAbout.forEach(p => {
|
|
||||||
expect(reportOutput).toContain(p);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
testTimeout
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,94 +0,0 @@
|
|||||||
import { updateFile, uniq, runCLI, forEachCli, newProject } from './utils';
|
|
||||||
|
|
||||||
const DEBUG = false;
|
|
||||||
const l = (str: string) => {
|
|
||||||
if (DEBUG) {
|
|
||||||
console.log(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
return str;
|
|
||||||
};
|
|
||||||
|
|
||||||
forEachCli(() => {
|
|
||||||
describe('Run Many', () => {
|
|
||||||
it('should build specific and all projects', () => {
|
|
||||||
newProject();
|
|
||||||
const appA = uniq('appa-rand');
|
|
||||||
const libA = uniq('liba-rand');
|
|
||||||
const libB = uniq('libb-rand');
|
|
||||||
const libC = uniq('libc-rand');
|
|
||||||
const libD = uniq('libd-rand');
|
|
||||||
|
|
||||||
l(runCLI(`generate @nrwl/angular:app ${appA}`));
|
|
||||||
l(runCLI(`generate @nrwl/angular:lib ${libA} --publishable --defaults`));
|
|
||||||
l(runCLI(`generate @nrwl/angular:lib ${libB} --publishable --defaults`));
|
|
||||||
l(runCLI(`generate @nrwl/angular:lib ${libC} --publishable --defaults`));
|
|
||||||
l(runCLI(`generate @nrwl/angular:lib ${libD} --defaults`));
|
|
||||||
|
|
||||||
l('=======> libA depends on libC');
|
|
||||||
updateFile(
|
|
||||||
`libs/${libA}/src/lib/${libA}.module.spec.ts`,
|
|
||||||
`
|
|
||||||
import '@proj/${libC}';
|
|
||||||
describe('sample test', () => {
|
|
||||||
it('should test', () => {
|
|
||||||
expect(1).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
l('=======> testing run many starting');
|
|
||||||
|
|
||||||
const buildParallel = l(
|
|
||||||
runCLI(`run-many --target=build --projects="${libC},${libB}"`)
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(buildParallel).toContain(`Running target build for projects:`);
|
|
||||||
expect(buildParallel).not.toContain(`- ${libA}`);
|
|
||||||
expect(buildParallel).toContain(`- ${libB}`);
|
|
||||||
expect(buildParallel).toContain(`- ${libC}`);
|
|
||||||
expect(buildParallel).not.toContain(`- ${libD}`);
|
|
||||||
expect(buildParallel).toContain('Running target "build" succeeded');
|
|
||||||
|
|
||||||
l('=======> testing run many complete');
|
|
||||||
|
|
||||||
l('=======> testing run many --all starting');
|
|
||||||
const buildAllParallel = l(runCLI(`run-many --target=build --all`));
|
|
||||||
expect(buildAllParallel).toContain(`Running target build for projects:`);
|
|
||||||
expect(buildAllParallel).toContain(`- ${libA}`);
|
|
||||||
expect(buildAllParallel).toContain(`- ${libB}`);
|
|
||||||
expect(buildAllParallel).toContain(`- ${libC}`);
|
|
||||||
expect(buildAllParallel).not.toContain(`- ${libD}`);
|
|
||||||
expect(buildAllParallel).toContain('Running target "build" succeeded');
|
|
||||||
|
|
||||||
l('=======> testing run many --all complete');
|
|
||||||
|
|
||||||
l('=======> testing run many --with-deps');
|
|
||||||
|
|
||||||
const buildWithDeps = l(
|
|
||||||
runCLI(`run-many --target=build --projects="${libA}" --with-deps`)
|
|
||||||
);
|
|
||||||
expect(buildWithDeps).toContain(`Running target build for projects:`);
|
|
||||||
expect(buildWithDeps).toContain(`- ${libA}`);
|
|
||||||
expect(buildWithDeps).toContain(`- ${libC}`);
|
|
||||||
expect(buildWithDeps).not.toContain(`- ${libB}`);
|
|
||||||
expect(buildWithDeps).not.toContain(`- ${libD}`);
|
|
||||||
expect(buildWithDeps).toContain('Running target "build" succeeded');
|
|
||||||
|
|
||||||
l('=======> testing run many --with-deps complete');
|
|
||||||
|
|
||||||
l('=======> testing run many --configuration');
|
|
||||||
|
|
||||||
const buildConfig = l(
|
|
||||||
runCLI(`run-many --target=build --projects="${appA},${libA}" --prod`)
|
|
||||||
);
|
|
||||||
expect(buildConfig).toContain(`Running target build for projects:`);
|
|
||||||
expect(buildConfig).toContain(`run ${appA}:build:production`);
|
|
||||||
expect(buildConfig).toContain(`run ${libA}:build:production`);
|
|
||||||
expect(buildConfig).toContain('Running target "build" succeeded');
|
|
||||||
|
|
||||||
l('=======> testing run many --configuration');
|
|
||||||
}, 1000000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -399,7 +399,7 @@ export function runCLI(
|
|||||||
}
|
}
|
||||||
): string {
|
): string {
|
||||||
try {
|
try {
|
||||||
return execSync(`node ./node_modules/@nrwl/cli/bin/nx.js ${command}`, {
|
const r = execSync(`node ./node_modules/@nrwl/cli/bin/nx.js ${command}`, {
|
||||||
cwd: tmpProjPath()
|
cwd: tmpProjPath()
|
||||||
})
|
})
|
||||||
.toString()
|
.toString()
|
||||||
@ -407,6 +407,8 @@ export function runCLI(
|
|||||||
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
|
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
console.log(r);
|
||||||
|
return r;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (opts.silenceError) {
|
if (opts.silenceError) {
|
||||||
return e.stdout.toString();
|
return e.stdout.toString();
|
||||||
@ -424,10 +426,12 @@ export function expectTestsPass(v: { stdout: string; stderr: string }) {
|
|||||||
|
|
||||||
export function runCommand(command: string): string {
|
export function runCommand(command: string): string {
|
||||||
try {
|
try {
|
||||||
return execSync(command, {
|
const r = execSync(command, {
|
||||||
cwd: tmpProjPath(),
|
cwd: tmpProjPath(),
|
||||||
stdio: ['pipe', 'pipe', 'pipe']
|
stdio: ['pipe', 'pipe', 'pipe']
|
||||||
}).toString();
|
}).toString();
|
||||||
|
console.log(r);
|
||||||
|
return r;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return e.stdout.toString() + e.stderr.toString();
|
return e.stdout.toString() + e.stderr.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
600
e2e/workspace-aux-commands.test.ts
Normal file
600
e2e/workspace-aux-commands.test.ts
Normal file
@ -0,0 +1,600 @@
|
|||||||
|
import {
|
||||||
|
checkFilesExist,
|
||||||
|
newProject,
|
||||||
|
readFile,
|
||||||
|
readJson,
|
||||||
|
runCLI,
|
||||||
|
runCommand,
|
||||||
|
updateFile,
|
||||||
|
exists,
|
||||||
|
ensureProject,
|
||||||
|
uniq,
|
||||||
|
forEachCli,
|
||||||
|
workspaceConfigName
|
||||||
|
} from './utils';
|
||||||
|
import { classify } from '@nrwl/workspace/src/utils/strings';
|
||||||
|
import { NxJson } from '@nrwl/workspace';
|
||||||
|
|
||||||
|
forEachCli(cli => {
|
||||||
|
describe('lint', () => {
|
||||||
|
it('lint should ensure module boundaries', () => {
|
||||||
|
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');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/angular:app ${myapp} --tags=validtag`);
|
||||||
|
runCLI(`generate @nrwl/angular:app ${myapp2}`);
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${mylib}`);
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${lazylib}`);
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${invalidtaglib} --tags=invalidtag`);
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${validtaglib} --tags=validtag`);
|
||||||
|
|
||||||
|
const tslint = readJson('tslint.json');
|
||||||
|
tslint.rules['nx-enforce-module-boundaries'][1].depConstraints = [
|
||||||
|
{ sourceTag: 'validtag', onlyDependOnLibsWithTags: ['validtag'] },
|
||||||
|
...tslint.rules['nx-enforce-module-boundaries'][1].depConstraints
|
||||||
|
];
|
||||||
|
updateFile('tslint.json', JSON.stringify(tslint, null, 2));
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`apps/${myapp}/src/main.ts`,
|
||||||
|
`
|
||||||
|
import '../../../libs/${mylib}';
|
||||||
|
import '@proj/${lazylib}';
|
||||||
|
import '@proj/${myapp2}';
|
||||||
|
import '@proj/${invalidtaglib}';
|
||||||
|
import '@proj/${validtaglib}';
|
||||||
|
|
||||||
|
const s = {loadChildren: '@proj/${lazylib}'};
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
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('imports of apps are forbidden');
|
||||||
|
expect(out).toContain(
|
||||||
|
'A project tagged with "validtag" can only depend on libs tagged with "validtag"'
|
||||||
|
);
|
||||||
|
}, 1000000);
|
||||||
|
|
||||||
|
describe('nx lint', () => {
|
||||||
|
afterAll(() => {
|
||||||
|
newProject();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should run nx lint', () => {
|
||||||
|
ensureProject();
|
||||||
|
const appBefore = uniq('before');
|
||||||
|
const appAfter = uniq('after');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/angular:app ${appBefore}`);
|
||||||
|
runCommand(`mv apps/${appBefore} apps/${appAfter}`);
|
||||||
|
|
||||||
|
const stdout = runCommand('./node_modules/.bin/nx workspace-lint');
|
||||||
|
expect(stdout).toContain(
|
||||||
|
`- Cannot find project '${appBefore}' in 'apps/${appBefore}'`
|
||||||
|
);
|
||||||
|
expect(stdout).toContain(
|
||||||
|
'The following file(s) do not belong to any projects:'
|
||||||
|
);
|
||||||
|
expect(stdout).toContain(`- apps/${appAfter}/browserslist`);
|
||||||
|
expect(stdout).toContain(
|
||||||
|
`- apps/${appAfter}/src/app/app.component.css`
|
||||||
|
);
|
||||||
|
expect(stdout).toContain(
|
||||||
|
`- apps/${appAfter}/src/app/app.component.html`
|
||||||
|
);
|
||||||
|
expect(stdout).toContain(
|
||||||
|
`- apps/${appAfter}/src/app/app.component.spec.ts`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('format should check and reformat the code', () => {
|
||||||
|
ensureProject();
|
||||||
|
const myapp = uniq('myapp');
|
||||||
|
const mylib = uniq('mylib');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/angular:app ${myapp}`);
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${mylib}`);
|
||||||
|
updateFile(
|
||||||
|
`apps/${myapp}/src/main.ts`,
|
||||||
|
`
|
||||||
|
const x = 1111;
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`apps/${myapp}/src/app/app.module.ts`,
|
||||||
|
`
|
||||||
|
const y = 1111;
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`apps/${myapp}/src/app/app.component.ts`,
|
||||||
|
`
|
||||||
|
const z = 1111;
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`libs/${mylib}/index.ts`,
|
||||||
|
`
|
||||||
|
const x = 1111;
|
||||||
|
`
|
||||||
|
);
|
||||||
|
updateFile(
|
||||||
|
`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`
|
||||||
|
);
|
||||||
|
expect(stdout).toContain(`libs/${mylib}/index.ts`);
|
||||||
|
expect(stdout).toContain(`libs/${mylib}/src/${mylib}.module.ts`);
|
||||||
|
|
||||||
|
stdout = runCommand(`npm run -s format:check -- --all`);
|
||||||
|
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"`
|
||||||
|
);
|
||||||
|
|
||||||
|
stdout = runCommand('npm run -s format:check -- --all');
|
||||||
|
|
||||||
|
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 -- --all');
|
||||||
|
expect(runCommand('npm run -s format:check -- --all')).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support workspace-specific schematics', () => {
|
||||||
|
ensureProject();
|
||||||
|
const custom = uniq('custom');
|
||||||
|
runCLI(`g workspace-schematic ${custom} --no-interactive`);
|
||||||
|
checkFilesExist(
|
||||||
|
`tools/schematics/${custom}/index.ts`,
|
||||||
|
`tools/schematics/${custom}/schema.json`
|
||||||
|
);
|
||||||
|
|
||||||
|
const json = readJson(`tools/schematics/${custom}/schema.json`);
|
||||||
|
json.properties['directory'] = {
|
||||||
|
type: 'string',
|
||||||
|
description: 'lib directory'
|
||||||
|
};
|
||||||
|
json.properties['skipTsConfig'] = {
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'skip changes to tsconfig'
|
||||||
|
};
|
||||||
|
updateFile(
|
||||||
|
`tools/schematics/${custom}/schema.json`,
|
||||||
|
JSON.stringify(json)
|
||||||
|
);
|
||||||
|
|
||||||
|
const indexFile = readFile(`tools/schematics/${custom}/index.ts`);
|
||||||
|
updateFile(
|
||||||
|
`tools/schematics/${custom}/index.ts`,
|
||||||
|
indexFile.replace(
|
||||||
|
'name: schema.name',
|
||||||
|
'name: schema.name, directory: schema.directory, skipTsConfig: schema.skipTsConfig'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const workspace = uniq('workspace');
|
||||||
|
const dryRunOutput = runCommand(
|
||||||
|
`npm run workspace-schematic ${custom} ${workspace} -- --no-interactive --directory=dir --skipTsConfig=true -d`
|
||||||
|
);
|
||||||
|
expect(exists(`libs/dir/${workspace}/src/index.ts`)).toEqual(false);
|
||||||
|
expect(dryRunOutput).toContain(`UPDATE ${workspaceConfigName()}`);
|
||||||
|
expect(dryRunOutput).toContain('UPDATE nx.json');
|
||||||
|
expect(dryRunOutput).not.toContain('UPDATE tsconfig.json');
|
||||||
|
|
||||||
|
const output = runCommand(
|
||||||
|
`npm run workspace-schematic ${custom} ${workspace} -- --no-interactive --directory=dir`
|
||||||
|
);
|
||||||
|
checkFilesExist(`libs/dir/${workspace}/src/index.ts`);
|
||||||
|
expect(output).toContain(`UPDATE ${workspaceConfigName()}`);
|
||||||
|
expect(output).toContain('UPDATE nx.json');
|
||||||
|
|
||||||
|
const another = uniq('another');
|
||||||
|
runCLI(`g workspace-schematic ${another} --no-interactive`);
|
||||||
|
|
||||||
|
const listSchematicsOutput = runCommand(
|
||||||
|
'npm run workspace-schematic -- --list-schematics'
|
||||||
|
);
|
||||||
|
expect(listSchematicsOutput).toContain(
|
||||||
|
'nx workspace-schematic "--list-schematics"'
|
||||||
|
);
|
||||||
|
expect(listSchematicsOutput).toContain(custom);
|
||||||
|
expect(listSchematicsOutput).toContain(another);
|
||||||
|
|
||||||
|
const promptOutput = runCommand(
|
||||||
|
`npm run workspace-schematic ${custom} mylib2 --dry-run`
|
||||||
|
);
|
||||||
|
expect(promptOutput).toContain('UPDATE nx.json');
|
||||||
|
}, 1000000);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('dep-graph', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
newProject();
|
||||||
|
runCLI('generate @nrwl/angular:app myapp');
|
||||||
|
runCLI('generate @nrwl/angular:app myapp2');
|
||||||
|
runCLI('generate @nrwl/angular:app myapp3');
|
||||||
|
runCLI('generate @nrwl/angular:lib mylib');
|
||||||
|
runCLI('generate @nrwl/angular:lib mylib2');
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
'apps/myapp/src/main.ts',
|
||||||
|
`
|
||||||
|
import '@proj/mylib';
|
||||||
|
|
||||||
|
const s = {loadChildren: '@proj/mylib2'};
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
'apps/myapp2/src/app/app.component.spec.ts',
|
||||||
|
`import '@proj/mylib';`
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
'libs/mylib/src/mylib.module.spec.ts',
|
||||||
|
`import '@proj/mylib2';`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('dep-graph should output json to file', () => {
|
||||||
|
runCommand(`npm run dep-graph -- --file=project-graph.json`);
|
||||||
|
|
||||||
|
expect(() => checkFilesExist('project-graph.json')).not.toThrow();
|
||||||
|
|
||||||
|
const jsonFileContents = readJson('project-graph.json');
|
||||||
|
|
||||||
|
expect(jsonFileContents.graph.dependencies).toEqual({
|
||||||
|
'myapp3-e2e': [
|
||||||
|
{
|
||||||
|
source: 'myapp3-e2e',
|
||||||
|
target: 'myapp3',
|
||||||
|
type: 'implicit'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
myapp2: [
|
||||||
|
{
|
||||||
|
source: 'myapp2',
|
||||||
|
target: 'mylib',
|
||||||
|
type: 'static'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'myapp2-e2e': [
|
||||||
|
{
|
||||||
|
source: 'myapp2-e2e',
|
||||||
|
target: 'myapp2',
|
||||||
|
type: 'implicit'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
mylib: [
|
||||||
|
{
|
||||||
|
source: 'mylib',
|
||||||
|
target: 'mylib2',
|
||||||
|
type: 'static'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
mylib2: [],
|
||||||
|
myapp: [
|
||||||
|
{
|
||||||
|
source: 'myapp',
|
||||||
|
target: 'mylib',
|
||||||
|
type: 'static'
|
||||||
|
},
|
||||||
|
{ source: 'myapp', target: 'mylib2', type: 'dynamic' }
|
||||||
|
],
|
||||||
|
'myapp-e2e': [
|
||||||
|
{
|
||||||
|
source: 'myapp-e2e',
|
||||||
|
target: 'myapp',
|
||||||
|
type: 'implicit'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
myapp3: []
|
||||||
|
});
|
||||||
|
|
||||||
|
runCommand(
|
||||||
|
`npm run affected:dep-graph -- --files="libs/mylib/src/index.ts" --file="project-graph.json"`
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(() => checkFilesExist('project-graph.json')).not.toThrow();
|
||||||
|
|
||||||
|
const jsonFileContents2 = readJson('project-graph.json');
|
||||||
|
|
||||||
|
expect(jsonFileContents2.criticalPath).toContain('myapp');
|
||||||
|
expect(jsonFileContents2.criticalPath).toContain('myapp2');
|
||||||
|
expect(jsonFileContents2.criticalPath).toContain('mylib');
|
||||||
|
expect(jsonFileContents2.criticalPath).not.toContain('mylib2');
|
||||||
|
}, 1000000);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Move Angular Project', () => {
|
||||||
|
const workspace: string = cli === 'angular' ? 'angular' : 'workspace';
|
||||||
|
|
||||||
|
describe('Apps', () => {
|
||||||
|
let app1: string;
|
||||||
|
let app2: string;
|
||||||
|
let newPath: string;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
app1 = uniq('app1');
|
||||||
|
app2 = uniq('app2');
|
||||||
|
newPath = `subfolder/${app2}`;
|
||||||
|
newProject();
|
||||||
|
runCLI(`generate @nrwl/angular:app ${app1}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries moving an app from ${app1} -> subfolder/${app2}
|
||||||
|
*/
|
||||||
|
it('should work for apps', () => {
|
||||||
|
const moveOutput = runCLI(
|
||||||
|
`generate @nrwl/angular:move --project ${app1} ${newPath}`
|
||||||
|
);
|
||||||
|
|
||||||
|
// just check the output
|
||||||
|
expect(moveOutput).toContain(`DELETE apps/${app1}`);
|
||||||
|
expect(moveOutput).toContain(`CREATE apps/${newPath}/browserslist`);
|
||||||
|
expect(moveOutput).toContain(`CREATE apps/${newPath}/jest.config.js`);
|
||||||
|
expect(moveOutput).toContain(
|
||||||
|
`CREATE apps/${newPath}/tsconfig.app.json`
|
||||||
|
);
|
||||||
|
expect(moveOutput).toContain(`CREATE apps/${newPath}/tsconfig.json`);
|
||||||
|
expect(moveOutput).toContain(
|
||||||
|
`CREATE apps/${newPath}/tsconfig.spec.json`
|
||||||
|
);
|
||||||
|
expect(moveOutput).toContain(`CREATE apps/${newPath}/tslint.json`);
|
||||||
|
expect(moveOutput).toContain(`CREATE apps/${newPath}/src/favicon.ico`);
|
||||||
|
expect(moveOutput).toContain(`CREATE apps/${newPath}/src/index.html`);
|
||||||
|
expect(moveOutput).toContain(`CREATE apps/${newPath}/src/main.ts`);
|
||||||
|
expect(moveOutput).toContain(`CREATE apps/${newPath}/src/polyfills.ts`);
|
||||||
|
expect(moveOutput).toContain(`CREATE apps/${newPath}/src/styles.css`);
|
||||||
|
expect(moveOutput).toContain(
|
||||||
|
`CREATE apps/${newPath}/src/test-setup.ts`
|
||||||
|
);
|
||||||
|
expect(moveOutput).toContain(
|
||||||
|
`CREATE apps/${newPath}/src/app/app.component.html`
|
||||||
|
);
|
||||||
|
expect(moveOutput).toContain(
|
||||||
|
`CREATE apps/${newPath}/src/app/app.module.ts`
|
||||||
|
);
|
||||||
|
expect(moveOutput).toContain(
|
||||||
|
`CREATE apps/${newPath}/src/assets/.gitkeep`
|
||||||
|
);
|
||||||
|
expect(moveOutput).toContain(
|
||||||
|
`CREATE apps/${newPath}/src/environments/environment.prod.ts`
|
||||||
|
);
|
||||||
|
expect(moveOutput).toContain(
|
||||||
|
`CREATE apps/${newPath}/src/environments/environment.ts`
|
||||||
|
);
|
||||||
|
expect(moveOutput).toContain(`UPDATE nx.json`);
|
||||||
|
expect(moveOutput).toContain(`UPDATE ${workspace}.json`);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries moving an e2e project from ${app1} -> ${newPath}
|
||||||
|
*/
|
||||||
|
it('should work for e2e projects', () => {
|
||||||
|
const moveOutput = runCLI(
|
||||||
|
`generate @nrwl/angular:move --projectName=${app1}-e2e --destination=${newPath}-e2e`
|
||||||
|
);
|
||||||
|
|
||||||
|
// just check that the cypress.json is updated correctly
|
||||||
|
const cypressJsonPath = `apps/${newPath}-e2e/cypress.json`;
|
||||||
|
expect(moveOutput).toContain(`CREATE ${cypressJsonPath}`);
|
||||||
|
checkFilesExist(cypressJsonPath);
|
||||||
|
const cypressJson = readJson(cypressJsonPath);
|
||||||
|
expect(cypressJson.videosFolder).toEqual(
|
||||||
|
`../../../dist/cypress/apps/${newPath}-e2e/videos`
|
||||||
|
);
|
||||||
|
expect(cypressJson.screenshotsFolder).toEqual(
|
||||||
|
`../../../dist/cypress/apps/${newPath}-e2e/screenshots`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries moving a library from ${lib} -> shared/${lib}
|
||||||
|
*/
|
||||||
|
it('should work for libraries', () => {
|
||||||
|
const lib1 = uniq('mylib');
|
||||||
|
const lib2 = uniq('mylib');
|
||||||
|
newProject();
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${lib1}`);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a library which imports the module from the other lib
|
||||||
|
*/
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${lib2}`);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`libs/${lib2}/src/lib/${lib2}.module.ts`,
|
||||||
|
`import { ${classify(lib1)}Module } from '@proj/${lib1}';
|
||||||
|
|
||||||
|
export class ExtendedModule extends ${classify(lib1)}Module { }`
|
||||||
|
);
|
||||||
|
|
||||||
|
const moveOutput = runCLI(
|
||||||
|
`generate @nrwl/angular:move --projectName=${lib1} --destination=shared/${lib1}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const newPath = `libs/shared/${lib1}`;
|
||||||
|
const newModule = `Shared${classify(lib1)}Module`;
|
||||||
|
|
||||||
|
const testSetupPath = `${newPath}/src/test-setup.ts`;
|
||||||
|
expect(moveOutput).toContain(`CREATE ${testSetupPath}`);
|
||||||
|
checkFilesExist(testSetupPath);
|
||||||
|
|
||||||
|
const modulePath = `${newPath}/src/lib/shared-${lib1}.module.ts`;
|
||||||
|
expect(moveOutput).toContain(`CREATE ${modulePath}`);
|
||||||
|
checkFilesExist(modulePath);
|
||||||
|
const moduleFile = readFile(modulePath);
|
||||||
|
expect(moduleFile).toContain(`export class ${newModule}`);
|
||||||
|
|
||||||
|
const indexPath = `${newPath}/src/index.ts`;
|
||||||
|
expect(moveOutput).toContain(`CREATE ${indexPath}`);
|
||||||
|
checkFilesExist(indexPath);
|
||||||
|
const index = readFile(indexPath);
|
||||||
|
expect(index).toContain(`export * from './lib/shared-${lib1}.module'`);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that the import in lib2 has been updated
|
||||||
|
*/
|
||||||
|
const lib2FilePath = `libs/${lib2}/src/lib/${lib2}.module.ts`;
|
||||||
|
const lib2File = readFile(lib2FilePath);
|
||||||
|
expect(lib2File).toContain(
|
||||||
|
`import { ${newModule} } from '@proj/shared/${lib1}';`
|
||||||
|
);
|
||||||
|
expect(lib2File).toContain(`extends ${newModule}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Move Project', () => {
|
||||||
|
const workspace: string = cli === 'angular' ? 'angular' : 'workspace';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries moving a library from ${lib}/data-access -> shared/${lib}/data-access
|
||||||
|
*/
|
||||||
|
it('should work for libraries', () => {
|
||||||
|
const lib1 = uniq('mylib');
|
||||||
|
const lib2 = uniq('mylib');
|
||||||
|
newProject();
|
||||||
|
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 the other lib
|
||||||
|
*/
|
||||||
|
|
||||||
|
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(); }`
|
||||||
|
);
|
||||||
|
|
||||||
|
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.js`;
|
||||||
|
expect(moveOutput).toContain(`CREATE ${jestConfigPath}`);
|
||||||
|
checkFilesExist(jestConfigPath);
|
||||||
|
const jestConfig = readFile(jestConfigPath);
|
||||||
|
expect(jestConfig).toContain(`name: 'shared-${lib1}-data-access'`);
|
||||||
|
expect(jestConfig).toContain(`preset: '../../../../jest.config.js'`);
|
||||||
|
expect(jestConfig).toContain(
|
||||||
|
`coverageDirectory: '../../../../coverage/${newPath}'`
|
||||||
|
);
|
||||||
|
|
||||||
|
const tsConfigPath = `${newPath}/tsconfig.json`;
|
||||||
|
expect(moveOutput).toContain(`CREATE ${tsConfigPath}`);
|
||||||
|
checkFilesExist(tsConfigPath);
|
||||||
|
const tsConfig = readJson(tsConfigPath);
|
||||||
|
expect(tsConfig.extends).toEqual('../../../../tsconfig.json');
|
||||||
|
|
||||||
|
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 nx.json');
|
||||||
|
const nxJson = JSON.parse(readFile('nx.json')) as NxJson;
|
||||||
|
expect(nxJson.projects[`${lib1}-data-access`]).toBeUndefined();
|
||||||
|
expect(nxJson.projects[newName]).toEqual({
|
||||||
|
tags: []
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(moveOutput).toContain('UPDATE tsconfig.json');
|
||||||
|
const rootTsConfig = readJson('tsconfig.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`]);
|
||||||
|
|
||||||
|
expect(moveOutput).toContain(`UPDATE ${workspace}.json`);
|
||||||
|
const workspaceJson = readJson(`${workspace}.json`);
|
||||||
|
expect(workspaceJson.projects[`${lib1}-data-access`]).toBeUndefined();
|
||||||
|
const project = workspaceJson.projects[newName];
|
||||||
|
expect(project).toBeTruthy();
|
||||||
|
expect(project.root).toBe(newPath);
|
||||||
|
expect(project.sourceRoot).toBe(`${newPath}/src`);
|
||||||
|
expect(project.architect.lint.options.tsConfig).toEqual([
|
||||||
|
`libs/shared/${lib1}/data-access/tsconfig.lib.json`,
|
||||||
|
`libs/shared/${lib1}/data-access/tsconfig.spec.json`
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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';`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
661
e2e/workspace.test.ts
Normal file
661
e2e/workspace.test.ts
Normal file
@ -0,0 +1,661 @@
|
|||||||
|
import {
|
||||||
|
cli,
|
||||||
|
ensureProject,
|
||||||
|
forEachCli,
|
||||||
|
listFiles,
|
||||||
|
newProject,
|
||||||
|
readFile,
|
||||||
|
readJson,
|
||||||
|
rmDist,
|
||||||
|
runCLI,
|
||||||
|
runCommand,
|
||||||
|
setMaxWorkers,
|
||||||
|
uniq,
|
||||||
|
updateFile,
|
||||||
|
workspaceConfigName
|
||||||
|
} from './utils';
|
||||||
|
import { NxJson } from '@nrwl/workspace';
|
||||||
|
|
||||||
|
let originalCIValue: any;
|
||||||
|
|
||||||
|
forEachCli(cliName => {
|
||||||
|
const cliCommand = cliName === 'angular' ? 'ng' : 'nx';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setting CI=true makes it simpler to configure assertions around output, as there
|
||||||
|
* won't be any colors.
|
||||||
|
*/
|
||||||
|
beforeAll(() => {
|
||||||
|
originalCIValue = process.env.CI;
|
||||||
|
process.env.CI = 'true';
|
||||||
|
});
|
||||||
|
afterAll(() => {
|
||||||
|
process.env.CI = originalCIValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('run-one', () => {
|
||||||
|
it('should build specific project', () => {
|
||||||
|
ensureProject();
|
||||||
|
const myapp = uniq('myapp');
|
||||||
|
const mylib1 = uniq('mylib1');
|
||||||
|
const mylib2 = uniq('mylib1');
|
||||||
|
runCLI(`generate @nrwl/react:app ${myapp}`);
|
||||||
|
setMaxWorkers(myapp);
|
||||||
|
runCLI(`generate @nrwl/react:lib ${mylib1} --publishable`);
|
||||||
|
runCLI(`generate @nrwl/react:lib ${mylib2} --publishable`);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`apps/${myapp}/src/main.ts`,
|
||||||
|
`
|
||||||
|
import "@proj/${mylib1}";
|
||||||
|
import "@proj/${mylib2}";
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
const buildWithDeps = runCLI(`build ${myapp} --with-deps --prod`);
|
||||||
|
expect(buildWithDeps).toContain(`Running target "build" succeeded`);
|
||||||
|
expect(buildWithDeps).toContain(
|
||||||
|
`${cliCommand} run ${myapp}:build:production`
|
||||||
|
);
|
||||||
|
expect(buildWithDeps).toContain(`${cliCommand} run ${mylib1}:build`);
|
||||||
|
expect(buildWithDeps).toContain(`${cliCommand} run ${mylib2}:build`);
|
||||||
|
|
||||||
|
const testsWithDeps = runCLI(`test ${myapp} --with-deps`);
|
||||||
|
expect(testsWithDeps).toContain(`NX Running target test for projects:`);
|
||||||
|
expect(testsWithDeps).toContain(myapp);
|
||||||
|
expect(testsWithDeps).toContain(mylib1);
|
||||||
|
expect(testsWithDeps).toContain(mylib2);
|
||||||
|
|
||||||
|
const testsWithoutDeps = runCLI(`test ${myapp}`);
|
||||||
|
expect(testsWithoutDeps).not.toContain(mylib1);
|
||||||
|
}, 1000000);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('run-many', () => {
|
||||||
|
it('should build specific and all projects', () => {
|
||||||
|
newProject();
|
||||||
|
const appA = uniq('appa-rand');
|
||||||
|
const libA = uniq('liba-rand');
|
||||||
|
const libB = uniq('libb-rand');
|
||||||
|
const libC = uniq('libc-rand');
|
||||||
|
const libD = uniq('libd-rand');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/angular:app ${appA}`);
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${libA} --publishable --defaults`);
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${libB} --publishable --defaults`);
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${libC} --publishable --defaults`);
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${libD} --defaults`);
|
||||||
|
|
||||||
|
// libA depends on libC
|
||||||
|
updateFile(
|
||||||
|
`libs/${libA}/src/lib/${libA}.module.spec.ts`,
|
||||||
|
`
|
||||||
|
import '@proj/${libC}';
|
||||||
|
describe('sample test', () => {
|
||||||
|
it('should test', () => {
|
||||||
|
expect(1).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
// testing run many starting'
|
||||||
|
const buildParallel = runCLI(
|
||||||
|
`run-many --target=build --projects="${libC},${libB}"`
|
||||||
|
);
|
||||||
|
expect(buildParallel).toContain(`Running target build for projects:`);
|
||||||
|
expect(buildParallel).not.toContain(`- ${libA}`);
|
||||||
|
expect(buildParallel).toContain(`- ${libB}`);
|
||||||
|
expect(buildParallel).toContain(`- ${libC}`);
|
||||||
|
expect(buildParallel).not.toContain(`- ${libD}`);
|
||||||
|
expect(buildParallel).toContain('Running target "build" succeeded');
|
||||||
|
|
||||||
|
// testing run many --all starting
|
||||||
|
const buildAllParallel = runCLI(`run-many --target=build --all`);
|
||||||
|
expect(buildAllParallel).toContain(`Running target build for projects:`);
|
||||||
|
expect(buildAllParallel).toContain(`- ${libA}`);
|
||||||
|
expect(buildAllParallel).toContain(`- ${libB}`);
|
||||||
|
expect(buildAllParallel).toContain(`- ${libC}`);
|
||||||
|
expect(buildAllParallel).not.toContain(`- ${libD}`);
|
||||||
|
expect(buildAllParallel).toContain('Running target "build" succeeded');
|
||||||
|
|
||||||
|
// testing run many --with-deps
|
||||||
|
const buildWithDeps = runCLI(
|
||||||
|
`run-many --target=build --projects="${libA}" --with-deps`
|
||||||
|
);
|
||||||
|
expect(buildWithDeps).toContain(`Running target build for projects:`);
|
||||||
|
expect(buildWithDeps).toContain(`- ${libA}`);
|
||||||
|
expect(buildWithDeps).toContain(`- ${libC}`);
|
||||||
|
expect(buildWithDeps).not.toContain(`- ${libB}`);
|
||||||
|
expect(buildWithDeps).not.toContain(`- ${libD}`);
|
||||||
|
expect(buildWithDeps).toContain('Running target "build" succeeded');
|
||||||
|
|
||||||
|
// testing run many --configuration
|
||||||
|
const buildConfig = runCLI(
|
||||||
|
`run-many --target=build --projects="${appA},${libA}" --prod`
|
||||||
|
);
|
||||||
|
expect(buildConfig).toContain(`Running target build for projects:`);
|
||||||
|
expect(buildConfig).toContain(`run ${appA}:build:production`);
|
||||||
|
expect(buildConfig).toContain(`run ${libA}:build:production`);
|
||||||
|
expect(buildConfig).toContain('Running target "build" succeeded');
|
||||||
|
}, 1000000);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('affected:*', () => {
|
||||||
|
it('should print, build, and test affected apps', () => {
|
||||||
|
ensureProject();
|
||||||
|
const myapp = uniq('myapp');
|
||||||
|
const myapp2 = uniq('myapp2');
|
||||||
|
const mylib = uniq('mylib');
|
||||||
|
const mylib2 = uniq('mylib2');
|
||||||
|
const mypublishablelib = uniq('mypublishablelib');
|
||||||
|
runCLI(`generate @nrwl/angular:app ${myapp}`);
|
||||||
|
runCLI(`generate @nrwl/angular:app ${myapp2}`);
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${mylib}`);
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${mylib2}`);
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${mypublishablelib} --publishable`);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`apps/${myapp}/src/app/app.component.spec.ts`,
|
||||||
|
`
|
||||||
|
import '@proj/${mylib}';
|
||||||
|
describe('sample test', () => {
|
||||||
|
it('should test', () => {
|
||||||
|
expect(1).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
`
|
||||||
|
);
|
||||||
|
updateFile(
|
||||||
|
`libs/${mypublishablelib}/src/lib/${mypublishablelib}.module.spec.ts`,
|
||||||
|
`
|
||||||
|
import '@proj/${mylib}';
|
||||||
|
describe('sample test', () => {
|
||||||
|
it('should test', () => {
|
||||||
|
expect(1).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
`
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
runCommand(
|
||||||
|
`npm run affected:apps -- --files="libs/${mylib}/src/index.ts" --plain`
|
||||||
|
).split('\n')[4]
|
||||||
|
).toEqual(myapp);
|
||||||
|
|
||||||
|
const affectedApps = runCommand(
|
||||||
|
`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`);
|
||||||
|
|
||||||
|
const implicitlyAffectedApps = runCommand(
|
||||||
|
'npm run affected:apps -- --files="tsconfig.json"'
|
||||||
|
);
|
||||||
|
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(
|
||||||
|
runCommand(
|
||||||
|
`npm run affected:libs -- --files="libs/${mylib}/src/index.ts" --plain`
|
||||||
|
).split('\n')[4]
|
||||||
|
).toEqual(`${mylib} ${mypublishablelib}`);
|
||||||
|
|
||||||
|
const affectedLibs = runCommand(
|
||||||
|
`npm run affected:libs -- --files="libs/${mylib}/src/index.ts"`
|
||||||
|
);
|
||||||
|
expect(affectedLibs).toContain(mypublishablelib);
|
||||||
|
expect(affectedLibs).toContain(mylib);
|
||||||
|
expect(affectedLibs).not.toContain(mylib2);
|
||||||
|
|
||||||
|
const implicitlyAffectedLibs = runCommand(
|
||||||
|
'npm run affected:libs -- --files="tsconfig.json"'
|
||||||
|
);
|
||||||
|
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);
|
||||||
|
|
||||||
|
// build
|
||||||
|
const build = runCommand(
|
||||||
|
`npm run affected:build -- --files="libs/${mylib}/src/index.ts" --parallel`
|
||||||
|
);
|
||||||
|
expect(build).toContain(`Running target build for projects:`);
|
||||||
|
expect(build).toContain(`- ${myapp}`);
|
||||||
|
expect(build).toContain(`- ${mypublishablelib}`);
|
||||||
|
expect(build).not.toContain('is not registered with the build command');
|
||||||
|
expect(build).toContain('Running target "build" succeeded');
|
||||||
|
|
||||||
|
const buildExcluded = runCommand(
|
||||||
|
`npm run affected:build -- --files="libs/${mylib}/src/index.ts" --exclude ${myapp}`
|
||||||
|
);
|
||||||
|
expect(buildExcluded).toContain(`Running target build for projects:`);
|
||||||
|
expect(buildExcluded).toContain(`- ${mypublishablelib}`);
|
||||||
|
|
||||||
|
// test
|
||||||
|
updateFile(
|
||||||
|
`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"`
|
||||||
|
);
|
||||||
|
expect(failedTests).toContain(`Running target test for projects:`);
|
||||||
|
expect(failedTests).toContain(`- ${mylib}`);
|
||||||
|
expect(failedTests).toContain(`- ${myapp}`);
|
||||||
|
expect(failedTests).toContain(`- ${mypublishablelib}`);
|
||||||
|
expect(failedTests).toContain(`Failed projects:`);
|
||||||
|
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
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fix failing Unit Test
|
||||||
|
updateFile(
|
||||||
|
`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`
|
||||||
|
);
|
||||||
|
expect(isolatedTests).toContain(`Running target test for projects`);
|
||||||
|
expect(isolatedTests).toContain(`- ${myapp}`);
|
||||||
|
|
||||||
|
const interpolatedTests = runCommand(
|
||||||
|
`npm run affected -- --target test --files="libs/${mylib}/src/index.ts" -- --jest-config {project.root}/jest.config.js`
|
||||||
|
);
|
||||||
|
expect(interpolatedTests).toContain(`Running target \"test\" succeeded`);
|
||||||
|
}, 1000000);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('affected (with git)', () => {
|
||||||
|
let myapp = uniq('myapp');
|
||||||
|
let myapp2 = uniq('myapp');
|
||||||
|
let mylib = uniq('mylib');
|
||||||
|
it('should not affect other projects by generating a new project', () => {
|
||||||
|
ensureProject();
|
||||||
|
|
||||||
|
const nxJson: NxJson = readJson('nx.json');
|
||||||
|
|
||||||
|
delete nxJson.implicitDependencies;
|
||||||
|
|
||||||
|
updateFile('nx.json', JSON.stringify(nxJson));
|
||||||
|
runCommand(`git init`);
|
||||||
|
runCommand(`git config user.email "test@test.com"`);
|
||||||
|
runCommand(`git config user.name "Test"`);
|
||||||
|
runCommand(
|
||||||
|
`git add . && git commit -am "initial commit" && git checkout -b master`
|
||||||
|
);
|
||||||
|
runCLI(`generate @nrwl/angular:app ${myapp}`);
|
||||||
|
expect(runCommand('yarn affected:apps')).toContain(myapp);
|
||||||
|
runCommand(`git add . && git commit -am "add ${myapp}"`);
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/angular:app ${myapp2}`);
|
||||||
|
expect(runCommand('yarn affected:apps')).not.toContain(myapp);
|
||||||
|
expect(runCommand('yarn affected:apps')).toContain(myapp2);
|
||||||
|
runCommand(`git add . && git commit -am "add ${myapp2}"`);
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/angular:lib ${mylib}`);
|
||||||
|
expect(runCommand('yarn affected:apps')).not.toContain(myapp);
|
||||||
|
expect(runCommand('yarn affected:apps')).not.toContain(myapp2);
|
||||||
|
expect(runCommand('yarn affected:libs')).toContain(mylib);
|
||||||
|
runCommand(`git add . && git commit -am "add ${mylib}"`);
|
||||||
|
}, 1000000);
|
||||||
|
|
||||||
|
it('should detect changes to projects based on the nx.json', () => {
|
||||||
|
const nxJson: NxJson = readJson('nx.json');
|
||||||
|
|
||||||
|
nxJson.projects[myapp].tags = ['tag'];
|
||||||
|
updateFile('nx.json', JSON.stringify(nxJson));
|
||||||
|
expect(runCommand('yarn affected:apps')).toContain(myapp);
|
||||||
|
expect(runCommand('yarn affected:apps')).not.toContain(myapp2);
|
||||||
|
expect(runCommand('yarn affected:libs')).not.toContain(mylib);
|
||||||
|
runCommand(`git add . && git commit -am "add tag to ${myapp}"`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect changes to projects based on the workspace.json', () => {
|
||||||
|
const workspaceJson = readJson(workspaceConfigName());
|
||||||
|
|
||||||
|
workspaceJson.projects[myapp].prefix = 'my-app';
|
||||||
|
updateFile(workspaceConfigName(), JSON.stringify(workspaceJson));
|
||||||
|
expect(runCommand('yarn affected:apps')).toContain(myapp);
|
||||||
|
expect(runCommand('yarn affected:apps')).not.toContain(myapp2);
|
||||||
|
expect(runCommand('yarn affected:libs')).not.toContain(mylib);
|
||||||
|
runCommand(`git add . && git commit -am "change prefix for ${myapp}"`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should affect all projects by removing projects', () => {
|
||||||
|
const workspaceJson = readJson(workspaceConfigName());
|
||||||
|
delete workspaceJson.projects[mylib];
|
||||||
|
updateFile(workspaceConfigName(), JSON.stringify(workspaceJson));
|
||||||
|
|
||||||
|
const nxJson = readJson('nx.json');
|
||||||
|
delete nxJson.projects[mylib];
|
||||||
|
updateFile('nx.json', JSON.stringify(nxJson));
|
||||||
|
|
||||||
|
expect(runCommand('yarn affected:apps')).toContain(myapp);
|
||||||
|
expect(runCommand('yarn affected:apps')).toContain(myapp2);
|
||||||
|
expect(runCommand('yarn affected:libs')).not.toContain(mylib);
|
||||||
|
runCommand(`git add . && git commit -am "remove ${mylib}"`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('print-affected', () => {
|
||||||
|
it('should print information about affected projects', () => {
|
||||||
|
newProject();
|
||||||
|
const myapp = uniq('myapp-a');
|
||||||
|
const myapp2 = uniq('myapp-b');
|
||||||
|
const mylib = uniq('mylib');
|
||||||
|
const mylib2 = uniq('mylib2');
|
||||||
|
const mypublishablelib = uniq('mypublishablelib');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/react:app ${myapp}`);
|
||||||
|
runCLI(`generate @nrwl/react:app ${myapp2}`);
|
||||||
|
runCLI(`generate @nrwl/react:lib ${mylib}`);
|
||||||
|
runCLI(`generate @nrwl/react:lib ${mylib2}`);
|
||||||
|
runCLI(`generate @nrwl/react:lib ${mypublishablelib} --publishable`);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`apps/${myapp}/src/main.tsx`,
|
||||||
|
`
|
||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import "@proj/${mylib}";
|
||||||
|
import "@proj/${mypublishablelib}";
|
||||||
|
import App from './app/app';
|
||||||
|
|
||||||
|
ReactDOM.render(<App />, document.getElementById('root'));
|
||||||
|
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`apps/${myapp2}/src/main.tsx`,
|
||||||
|
`
|
||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import "@proj/${mylib}";
|
||||||
|
import "@proj/${mypublishablelib}";
|
||||||
|
import App from './app/app';
|
||||||
|
|
||||||
|
ReactDOM.render(<App />, document.getElementById('root'));
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
const resWithoutTarget = JSON.parse(
|
||||||
|
runCommand(
|
||||||
|
`npm run nx print-affected --silent -- --files=apps/${myapp}/src/main.tsx`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
expect(resWithoutTarget.tasks).toEqual([]);
|
||||||
|
compareTwoArrays(resWithoutTarget.projects, [`${myapp}-e2e`, myapp]);
|
||||||
|
|
||||||
|
const resWithTarget = JSON.parse(
|
||||||
|
runCommand(
|
||||||
|
`npm run nx print-affected --silent -- --files=apps/${myapp}/src/main.tsx --target=test`
|
||||||
|
).trim()
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(resWithTarget.tasks).toEqual([
|
||||||
|
{
|
||||||
|
id: `${myapp}:test`,
|
||||||
|
overrides: {},
|
||||||
|
target: {
|
||||||
|
project: myapp,
|
||||||
|
target: 'test'
|
||||||
|
},
|
||||||
|
command: `npm run ${cliCommand} -- test ${myapp}`,
|
||||||
|
outputs: []
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
compareTwoArrays(resWithTarget.projects, [`${myapp}-e2e`, myapp]);
|
||||||
|
|
||||||
|
const resWithDeps = JSON.parse(
|
||||||
|
runCommand(
|
||||||
|
`npm run nx print-affected --silent -- --files=apps/${myapp}/src/main.tsx --target=build --with-deps`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
expect(resWithDeps.tasks).toEqual([
|
||||||
|
{
|
||||||
|
id: `${mypublishablelib}:build`,
|
||||||
|
overrides: {},
|
||||||
|
target: {
|
||||||
|
project: mypublishablelib,
|
||||||
|
target: 'build'
|
||||||
|
},
|
||||||
|
command: `npm run ${cliCommand} -- build ${mypublishablelib}`,
|
||||||
|
outputs: [`dist/libs/${mypublishablelib}`]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: `${myapp}:build`,
|
||||||
|
overrides: {},
|
||||||
|
target: {
|
||||||
|
project: myapp,
|
||||||
|
target: 'build'
|
||||||
|
},
|
||||||
|
command: `npm run ${cliCommand} -- build ${myapp}`,
|
||||||
|
outputs: [`dist/apps/${myapp}`]
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
compareTwoArrays(resWithDeps.projects, [
|
||||||
|
mylib,
|
||||||
|
mypublishablelib,
|
||||||
|
myapp,
|
||||||
|
`${myapp}-e2e`
|
||||||
|
]);
|
||||||
|
|
||||||
|
const resWithTargetWithSelect1 = runCommand(
|
||||||
|
`npm run nx print-affected --silent -- --files=apps/${myapp}/src/main.tsx --target=test --select=projects`
|
||||||
|
).trim();
|
||||||
|
compareTwoSerializedArrays(
|
||||||
|
resWithTargetWithSelect1,
|
||||||
|
`${myapp}-e2e, ${myapp}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const resWithTargetWithSelect2 = runCommand(
|
||||||
|
`npm run nx print-affected --silent -- --files=apps/${myapp}/src/main.tsx --target=test --select="tasks.target.project"`
|
||||||
|
).trim();
|
||||||
|
compareTwoSerializedArrays(resWithTargetWithSelect2, `${myapp}`);
|
||||||
|
}, 120000);
|
||||||
|
|
||||||
|
function compareTwoSerializedArrays(a: string, b: string) {
|
||||||
|
compareTwoArrays(
|
||||||
|
a.split(',').map(_ => _.trim()),
|
||||||
|
b.split(',').map(_ => _.trim())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function compareTwoArrays(a: string[], b: string[]) {
|
||||||
|
expect(a.sort((x, y) => x.localeCompare(y))).toEqual(
|
||||||
|
b.sort((x, y) => x.localeCompare(y))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('cache', () => {
|
||||||
|
afterAll(() => {
|
||||||
|
updateFile('nx.json', c => {
|
||||||
|
const nxJson = JSON.parse(c);
|
||||||
|
nxJson.tasksRunnerOptions = {
|
||||||
|
default: {
|
||||||
|
options: {
|
||||||
|
cacheableOperations: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return JSON.stringify(nxJson, null, 2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should cache command execution', async () => {
|
||||||
|
ensureProject();
|
||||||
|
|
||||||
|
const myapp1 = uniq('myapp1');
|
||||||
|
const myapp2 = uniq('myapp2');
|
||||||
|
runCLI(`generate @nrwl/web:app ${myapp1}`);
|
||||||
|
runCLI(`generate @nrwl/web:app ${myapp2}`);
|
||||||
|
const files = `--files="apps/${myapp1}/src/main.ts,apps/${myapp2}/src/main.ts"`;
|
||||||
|
|
||||||
|
// run without caching
|
||||||
|
// --------------------------------------------
|
||||||
|
const outputWithoutCachingEnabled1 = runCommand(
|
||||||
|
`npm run affected:build -- ${files}`
|
||||||
|
);
|
||||||
|
const filesApp1 = listFiles(`dist/apps/${myapp1}`);
|
||||||
|
const filesApp2 = listFiles(`dist/apps/${myapp2}`);
|
||||||
|
|
||||||
|
expect(outputWithoutCachingEnabled1).not.toContain(
|
||||||
|
'read the output from cache'
|
||||||
|
);
|
||||||
|
|
||||||
|
const outputWithoutCachingEnabled2 = runCommand(
|
||||||
|
`npm run affected:build -- ${files}`
|
||||||
|
);
|
||||||
|
expect(outputWithoutCachingEnabled2).not.toContain(
|
||||||
|
'read the output from cache'
|
||||||
|
);
|
||||||
|
|
||||||
|
// enable caching
|
||||||
|
// --------------------------------------------
|
||||||
|
updateFile('nx.json', c => {
|
||||||
|
const nxJson = JSON.parse(c);
|
||||||
|
nxJson.tasksRunnerOptions = {
|
||||||
|
default: {
|
||||||
|
options: {
|
||||||
|
cacheableOperations: ['build', 'test', 'lint']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return JSON.stringify(nxJson, null, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
// run build with caching
|
||||||
|
// --------------------------------------------
|
||||||
|
const outputThatPutsDataIntoCache = runCommand(
|
||||||
|
`npm run affected:build -- ${files}`
|
||||||
|
);
|
||||||
|
// now the data is in cache
|
||||||
|
expect(outputThatPutsDataIntoCache).not.toContain(
|
||||||
|
'read the output from cache'
|
||||||
|
);
|
||||||
|
|
||||||
|
rmDist();
|
||||||
|
|
||||||
|
const outputWithBothBuildTasksCached = runCommand(
|
||||||
|
`npm run affected:build -- ${files}`
|
||||||
|
);
|
||||||
|
expect(outputWithBothBuildTasksCached).toContain(
|
||||||
|
'read the output from cache'
|
||||||
|
);
|
||||||
|
expectCached(outputWithBothBuildTasksCached, [myapp1, myapp2]);
|
||||||
|
expect(listFiles(`dist/apps/${myapp1}`)).toEqual(filesApp1);
|
||||||
|
expect(listFiles(`dist/apps/${myapp2}`)).toEqual(filesApp2);
|
||||||
|
|
||||||
|
// run with skipping cache
|
||||||
|
const outputWithBothBuildTasksCachedButSkipped = runCommand(
|
||||||
|
`npm run affected:build -- ${files} --skip-nx-cache`
|
||||||
|
);
|
||||||
|
expect(outputWithBothBuildTasksCachedButSkipped).not.toContain(
|
||||||
|
`read the output from cache`
|
||||||
|
);
|
||||||
|
|
||||||
|
// touch myapp1
|
||||||
|
// --------------------------------------------
|
||||||
|
updateFile(`apps/${myapp1}/src/main.ts`, c => {
|
||||||
|
return `${c}\n//some comment`;
|
||||||
|
});
|
||||||
|
const outputWithBuildApp2Cached = runCommand(
|
||||||
|
`npm run affected:build -- ${files}`
|
||||||
|
);
|
||||||
|
expect(outputWithBuildApp2Cached).toContain('read the output from cache');
|
||||||
|
expectCached(outputWithBuildApp2Cached, [myapp2]);
|
||||||
|
|
||||||
|
// touch package.json
|
||||||
|
// --------------------------------------------
|
||||||
|
updateFile(`package.json`, c => {
|
||||||
|
const r = JSON.parse(c);
|
||||||
|
r.description = 'different';
|
||||||
|
return JSON.stringify(r);
|
||||||
|
});
|
||||||
|
const outputWithNoBuildCached = runCommand(
|
||||||
|
`npm run affected:build -- ${files}`
|
||||||
|
);
|
||||||
|
expect(outputWithNoBuildCached).not.toContain(
|
||||||
|
'read the output from cache'
|
||||||
|
);
|
||||||
|
|
||||||
|
// build individual project with caching
|
||||||
|
const individualBuildWithCache = runCommand(
|
||||||
|
`npm run nx -- build ${myapp1}`
|
||||||
|
);
|
||||||
|
expect(individualBuildWithCache).toContain('Cached Output');
|
||||||
|
|
||||||
|
// skip caching when building individual projects
|
||||||
|
const individualBuildWithSkippedCache = runCommand(
|
||||||
|
`npm run nx -- build ${myapp1} --skip-nx-cache`
|
||||||
|
);
|
||||||
|
expect(individualBuildWithSkippedCache).not.toContain('Cached Output');
|
||||||
|
|
||||||
|
// run lint with caching
|
||||||
|
// --------------------------------------------
|
||||||
|
const outputWithNoLintCached = runCommand(
|
||||||
|
`npm run affected:lint -- ${files}`
|
||||||
|
);
|
||||||
|
expect(outputWithNoLintCached).not.toContain(
|
||||||
|
'read the output from cache'
|
||||||
|
);
|
||||||
|
|
||||||
|
const outputWithBothLintTasksCached = runCommand(
|
||||||
|
`npm run affected:lint -- ${files}`
|
||||||
|
);
|
||||||
|
expect(outputWithBothLintTasksCached).toContain(
|
||||||
|
'read the output from cache'
|
||||||
|
);
|
||||||
|
expectCached(outputWithBothLintTasksCached, [
|
||||||
|
myapp1,
|
||||||
|
myapp2,
|
||||||
|
`${myapp1}-e2e`,
|
||||||
|
`${myapp2}-e2e`
|
||||||
|
]);
|
||||||
|
}, 120000);
|
||||||
|
|
||||||
|
function expectCached(actual: string, expected: string[]) {
|
||||||
|
const section = actual.split('read the output from cache')[1];
|
||||||
|
const r = section
|
||||||
|
.split('\n')
|
||||||
|
.filter(l => l.trim().startsWith('-'))
|
||||||
|
.map(l => l.split('- ')[1].trim());
|
||||||
|
r.sort((a, b) => a.localeCompare(b));
|
||||||
|
expected.sort((a, b) => a.localeCompare(b));
|
||||||
|
expect(r).toEqual(expected);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -7,8 +7,8 @@ mkdir -p tmp/angular
|
|||||||
mkdir -p tmp/nx
|
mkdir -p tmp/nx
|
||||||
|
|
||||||
export SELECTED_CLI=$1
|
export SELECTED_CLI=$1
|
||||||
jest --maxWorkers=1 ./build/e2e/new.test.js &&
|
jest --maxWorkers=1 ./build/e2e/angular.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/affected.test.js &&
|
jest --maxWorkers=1 ./build/e2e/cli.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/affected-git.test.js &&
|
jest --maxWorkers=1 ./build/e2e/workspace.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/command-line.test.js &&
|
jest --maxWorkers=1 ./build/e2e/workspace-aux-commands.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/cypress.test.js
|
jest --maxWorkers=1 ./build/e2e/cypress.test.js
|
||||||
|
|||||||
@ -7,15 +7,8 @@ mkdir -p tmp/angular
|
|||||||
mkdir -p tmp/nx
|
mkdir -p tmp/nx
|
||||||
|
|
||||||
export SELECTED_CLI=$1
|
export SELECTED_CLI=$1
|
||||||
jest --maxWorkers=1 ./build/e2e/help.test.js &&
|
|
||||||
jest --maxWorkers=1 ./build/e2e/jest.test.js &&
|
jest --maxWorkers=1 ./build/e2e/jest.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/karma.test.js &&
|
jest --maxWorkers=1 ./build/e2e/karma.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/list.test.js &&
|
|
||||||
jest --maxWorkers=1 ./build/e2e/migrate.test.js &&
|
|
||||||
jest --maxWorkers=1 ./build/e2e/move.angular.test.js &&
|
|
||||||
jest --maxWorkers=1 ./build/e2e/move.workspace.test.js &&
|
|
||||||
jest --maxWorkers=1 ./build/e2e/next.test.js &&
|
jest --maxWorkers=1 ./build/e2e/next.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/nx-plugin.test.js &&
|
jest --maxWorkers=1 ./build/e2e/nx-plugin.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/print-affected.test.js &&
|
|
||||||
jest --maxWorkers=1 ./build/e2e/delegate-to-cli.test.js &&
|
|
||||||
jest --maxWorkers=1 ./build/e2e/downgrade-module.test.js
|
jest --maxWorkers=1 ./build/e2e/downgrade-module.test.js
|
||||||
|
|||||||
@ -7,12 +7,9 @@ mkdir -p tmp/angular
|
|||||||
mkdir -p tmp/nx
|
mkdir -p tmp/nx
|
||||||
|
|
||||||
export SELECTED_CLI=$1
|
export SELECTED_CLI=$1
|
||||||
jest --maxWorkers=1 ./build/e2e/run-many.test.js &&
|
|
||||||
jest --maxWorkers=1 ./build/e2e/storybook.test.js &&
|
jest --maxWorkers=1 ./build/e2e/storybook.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/upgrade-module.test.js &&
|
jest --maxWorkers=1 ./build/e2e/upgrade-module.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/web.test.js &&
|
jest --maxWorkers=1 ./build/e2e/web.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/cache.test.js &&
|
|
||||||
jest --maxWorkers=1 ./build/e2e/buildable-libraries.test.js &&
|
|
||||||
jest --maxWorkers=1 ./build/e2e/angular-package.test.js &&
|
jest --maxWorkers=1 ./build/e2e/angular-package.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/react-package.test.js &&
|
jest --maxWorkers=1 ./build/e2e/react-package.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/ngrx.test.js
|
jest --maxWorkers=1 ./build/e2e/ngrx.test.js
|
||||||
|
|||||||
@ -9,5 +9,4 @@ mkdir -p tmp/nx
|
|||||||
export SELECTED_CLI=$1
|
export SELECTED_CLI=$1
|
||||||
jest --maxWorkers=1 ./build/e2e/ng-add.test.js &&
|
jest --maxWorkers=1 ./build/e2e/ng-add.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/node.test.js &&
|
jest --maxWorkers=1 ./build/e2e/node.test.js &&
|
||||||
jest --maxWorkers=1 ./build/e2e/react.test.js &&
|
jest --maxWorkers=1 ./build/e2e/react.test.js
|
||||||
jest --maxWorkers=1 ./build/e2e/report.test.js
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user