cleanup(core): refactor e2e tests for workspace
This commit is contained in:
parent
818727c3f0
commit
1c2eedf9cb
@ -99,6 +99,7 @@ jobs:
|
||||
- run:
|
||||
name: Nx CLI E2E Tests Part 1
|
||||
command: yarn e2e-ci1 nx
|
||||
no_output_timeout: 30m
|
||||
e2e-nx-2:
|
||||
executor: default
|
||||
steps:
|
||||
@ -106,6 +107,7 @@ jobs:
|
||||
- run:
|
||||
name: Nx CLI E2E Tests Part 2
|
||||
command: yarn e2e-ci2 nx
|
||||
no_output_timeout: 30m
|
||||
e2e-nx-3:
|
||||
executor: default
|
||||
steps:
|
||||
@ -113,6 +115,7 @@ jobs:
|
||||
- run:
|
||||
name: Nx CLI E2E Tests Part 3
|
||||
command: yarn e2e-ci3 nx
|
||||
no_output_timeout: 30m
|
||||
e2e-nx-4:
|
||||
executor: default
|
||||
steps:
|
||||
@ -120,6 +123,7 @@ jobs:
|
||||
- run:
|
||||
name: Nx CLI E2E Tests Part 4
|
||||
command: yarn e2e-ci4 nx
|
||||
no_output_timeout: 30m
|
||||
e2e-ng-1:
|
||||
executor: default
|
||||
steps:
|
||||
@ -127,6 +131,7 @@ jobs:
|
||||
- run:
|
||||
name: Angular CLI E2E Tests Part 1
|
||||
command: yarn e2e-ci1 angular
|
||||
no_output_timeout: 30m
|
||||
e2e-ng-2:
|
||||
executor: default
|
||||
steps:
|
||||
@ -134,6 +139,7 @@ jobs:
|
||||
- run:
|
||||
name: Angular CLI E2E Tests Part 2
|
||||
command: yarn e2e-ci2 angular
|
||||
no_output_timeout: 30m
|
||||
e2e-ng-3:
|
||||
executor: default
|
||||
steps:
|
||||
@ -141,6 +147,7 @@ jobs:
|
||||
- run:
|
||||
name: Angular CLI E2E Tests Part 3
|
||||
command: yarn e2e-ci3 angular
|
||||
no_output_timeout: 30m
|
||||
e2e-ng-4:
|
||||
executor: default
|
||||
steps:
|
||||
@ -148,6 +155,7 @@ jobs:
|
||||
- run:
|
||||
name: Angular CLI E2E Tests Part 4
|
||||
command: yarn e2e-ci4 angular
|
||||
no_output_timeout: 30m
|
||||
|
||||
workflows:
|
||||
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';
|
||||
|
||||
forEachCli(() => {
|
||||
describe('Create New Workspace', () => {
|
||||
describe('Angular Package', () => {
|
||||
beforeEach(() => {
|
||||
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 {
|
||||
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()
|
||||
})
|
||||
.toString()
|
||||
@ -407,6 +407,8 @@ export function runCLI(
|
||||
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
|
||||
''
|
||||
);
|
||||
console.log(r);
|
||||
return r;
|
||||
} catch (e) {
|
||||
if (opts.silenceError) {
|
||||
return e.stdout.toString();
|
||||
@ -424,10 +426,12 @@ export function expectTestsPass(v: { stdout: string; stderr: string }) {
|
||||
|
||||
export function runCommand(command: string): string {
|
||||
try {
|
||||
return execSync(command, {
|
||||
const r = execSync(command, {
|
||||
cwd: tmpProjPath(),
|
||||
stdio: ['pipe', 'pipe', 'pipe']
|
||||
}).toString();
|
||||
console.log(r);
|
||||
return r;
|
||||
} catch (e) {
|
||||
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
|
||||
|
||||
export SELECTED_CLI=$1
|
||||
jest --maxWorkers=1 ./build/e2e/new.test.js &&
|
||||
jest --maxWorkers=1 ./build/e2e/affected.test.js &&
|
||||
jest --maxWorkers=1 ./build/e2e/affected-git.test.js &&
|
||||
jest --maxWorkers=1 ./build/e2e/command-line.test.js &&
|
||||
jest --maxWorkers=1 ./build/e2e/angular.test.js &&
|
||||
jest --maxWorkers=1 ./build/e2e/cli.test.js &&
|
||||
jest --maxWorkers=1 ./build/e2e/workspace.test.js &&
|
||||
jest --maxWorkers=1 ./build/e2e/workspace-aux-commands.test.js &&
|
||||
jest --maxWorkers=1 ./build/e2e/cypress.test.js
|
||||
|
||||
@ -7,15 +7,8 @@ mkdir -p tmp/angular
|
||||
mkdir -p tmp/nx
|
||||
|
||||
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/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/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
|
||||
|
||||
@ -7,12 +7,9 @@ mkdir -p tmp/angular
|
||||
mkdir -p tmp/nx
|
||||
|
||||
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/upgrade-module.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/react-package.test.js &&
|
||||
jest --maxWorkers=1 ./build/e2e/ngrx.test.js
|
||||
|
||||
@ -9,5 +9,4 @@ mkdir -p tmp/nx
|
||||
export SELECTED_CLI=$1
|
||||
jest --maxWorkers=1 ./build/e2e/ng-add.test.js &&
|
||||
jest --maxWorkers=1 ./build/e2e/node.test.js &&
|
||||
jest --maxWorkers=1 ./build/e2e/react.test.js &&
|
||||
jest --maxWorkers=1 ./build/e2e/report.test.js
|
||||
jest --maxWorkers=1 ./build/e2e/react.test.js
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user