feat(testing): support root project generation for jest (#13353)
Co-authored-by: Miroslav Jonas <missing.manual@gmail.com>
This commit is contained in:
parent
8f2fb24605
commit
74bd0bb00c
@ -41,6 +41,12 @@
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Use JavaScript instead of TypeScript for config files"
|
||||
},
|
||||
"rootProject": {
|
||||
"description": "initialize Jest for an application at the root of the workspace",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"hidden": true
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
@ -123,6 +129,12 @@
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Use JavaScript instead of TypeScript for config files"
|
||||
},
|
||||
"rootProject": {
|
||||
"description": "Add Jest to an application at the root of the workspace",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"hidden": true
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
|
||||
73
e2e/jest/src/jest-root.test.ts
Normal file
73
e2e/jest/src/jest-root.test.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import { newProject, runCLI, uniq, runCLIAsync } from '@nrwl/e2e/utils';
|
||||
|
||||
describe('Jest root projects', () => {
|
||||
const myapp = uniq('myapp');
|
||||
const mylib = uniq('mylib');
|
||||
|
||||
describe('angular', () => {
|
||||
beforeAll(() => {
|
||||
newProject();
|
||||
});
|
||||
|
||||
it('should test root level app projects', async () => {
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --rootProject=true`);
|
||||
|
||||
const rootProjectTestResults = await runCLIAsync(`test ${myapp}`);
|
||||
|
||||
expect(rootProjectTestResults.combinedOutput).toContain(
|
||||
'Test Suites: 1 passed, 1 total'
|
||||
);
|
||||
}, 300_000);
|
||||
|
||||
it('should add lib project and tests should still work', async () => {
|
||||
runCLI(`generate @nrwl/angular:lib ${mylib}`);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:component ${mylib} --export --standalone --project=${mylib} --no-interactive`
|
||||
);
|
||||
|
||||
const libProjectTestResults = await runCLIAsync(`test ${mylib}`);
|
||||
|
||||
expect(libProjectTestResults.combinedOutput).toContain(
|
||||
'Test Suites: 1 passed, 1 total'
|
||||
);
|
||||
|
||||
const rootProjectTestResults = await runCLIAsync(`test ${myapp}`);
|
||||
|
||||
expect(rootProjectTestResults.combinedOutput).toContain(
|
||||
'Test Suites: 1 passed, 1 total'
|
||||
);
|
||||
}, 300_000);
|
||||
});
|
||||
|
||||
describe('react', () => {
|
||||
beforeAll(() => {
|
||||
newProject();
|
||||
});
|
||||
|
||||
it('should test root level app projects', async () => {
|
||||
runCLI(`generate @nrwl/react:app ${myapp} --rootProject=true`);
|
||||
|
||||
const rootProjectTestResults = await runCLIAsync(`test ${myapp}`);
|
||||
|
||||
expect(rootProjectTestResults.combinedOutput).toContain(
|
||||
'Test Suites: 1 passed, 1 total'
|
||||
);
|
||||
}, 300_000);
|
||||
|
||||
it('should add lib project and tests should still work', async () => {
|
||||
runCLI(`generate @nrwl/react:lib ${mylib}`);
|
||||
|
||||
const libProjectTestResults = await runCLIAsync(`test ${mylib}`);
|
||||
|
||||
expect(libProjectTestResults.combinedOutput).toContain(
|
||||
'Test Suites: 1 passed, 1 total'
|
||||
);
|
||||
|
||||
const rootProjectTestResults = await runCLIAsync(`test ${myapp}`);
|
||||
|
||||
expect(rootProjectTestResults.combinedOutput).toContain(
|
||||
'Test Suites: 1 passed, 1 total'
|
||||
);
|
||||
}, 300_000);
|
||||
});
|
||||
});
|
||||
@ -4,9 +4,12 @@ import {
|
||||
runCLI,
|
||||
runCLIAsync,
|
||||
uniq,
|
||||
readJson,
|
||||
updateFile,
|
||||
expectJestTestsToPass,
|
||||
cleanupProject,
|
||||
readFile,
|
||||
checkFilesExist,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
describe('Jest', () => {
|
||||
|
||||
@ -473,9 +473,6 @@ export function tslibC(): string {
|
||||
'plugin:@nrwl/nx/javascript',
|
||||
]);
|
||||
|
||||
console.log(JSON.stringify(rootEslint, null, 2));
|
||||
console.log(JSON.stringify(e2eEslint, null, 2));
|
||||
|
||||
runCLI(`generate @nrwl/react:lib ${mylib}`);
|
||||
// should add new tslint
|
||||
expect(() => checkFilesExist(`.eslintrc.base.json`)).not.toThrow();
|
||||
|
||||
@ -14,6 +14,7 @@ export async function addUnitTestRunner(host: Tree, options: NormalizedSchema) {
|
||||
supportTsx: false,
|
||||
skipSerializers: false,
|
||||
skipPackageJson: options.skipPackageJson,
|
||||
rootProject: options.rootProject,
|
||||
});
|
||||
} else if (options.unitTestRunner === UnitTestRunner.Karma) {
|
||||
await karmaProjectGenerator(host, {
|
||||
|
||||
@ -5,4 +5,7 @@ export {
|
||||
export { jestConfigObjectAst } from './src/utils/config/functions';
|
||||
export { jestProjectGenerator } from './src/generators/jest-project/jest-project';
|
||||
export { jestInitGenerator } from './src/generators/init/init';
|
||||
export { getJestProjects } from './src/utils/config/get-jest-projects';
|
||||
export {
|
||||
getJestProjects,
|
||||
getNestedJestProjects,
|
||||
} from './src/utils/config/get-jest-projects';
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import {
|
||||
addProjectConfiguration,
|
||||
NxJsonConfiguration,
|
||||
readJson,
|
||||
readProjectConfiguration,
|
||||
stripIndents,
|
||||
Tree,
|
||||
updateJson,
|
||||
@ -41,9 +43,29 @@ describe('jest', () => {
|
||||
});
|
||||
|
||||
it('should not override existing files', async () => {
|
||||
tree.write('jest.config.ts', `test`);
|
||||
addProjectConfiguration(tree, 'my-project', {
|
||||
root: 'apps/my-app',
|
||||
name: 'my-app',
|
||||
sourceRoot: 'apps/my-app/src',
|
||||
targets: {
|
||||
test: {
|
||||
executor: '@nrwl/jest:jest',
|
||||
options: {
|
||||
jestConfig: 'apps/my-app/jest.config.ts',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const expected = stripIndents`
|
||||
import { getJestProjects } from '@nrwl/jest';
|
||||
export default {
|
||||
projects: getJestProjects(),
|
||||
extraThing: "Goes Here"
|
||||
}
|
||||
`;
|
||||
tree.write('jest.config.ts', expected);
|
||||
jestInitGenerator(tree, {});
|
||||
expect(tree.read('jest.config.ts', 'utf-8')).toEqual('test');
|
||||
expect(tree.read('jest.config.ts', 'utf-8')).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should add target defaults for test', async () => {
|
||||
@ -144,6 +166,102 @@ describe('jest', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('root project', () => {
|
||||
it('should not add a monorepo jest.config.ts to the project', () => {
|
||||
jestInitGenerator(tree, { rootProject: true });
|
||||
expect(tree.exists('jest.config.ts')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should rename the project jest.config.ts to project jest config', () => {
|
||||
addProjectConfiguration(tree, 'my-project', {
|
||||
root: '.',
|
||||
name: 'my-project',
|
||||
sourceRoot: 'src',
|
||||
targets: {
|
||||
test: {
|
||||
executor: '@nrwl/jest:jest',
|
||||
options: {
|
||||
jestConfig: 'jest.config.ts',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
tree.write(
|
||||
'jest.config.ts',
|
||||
`
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
transform: {
|
||||
'^.+\\.[tj]sx?$': 'ts-jest',
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
|
||||
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
|
||||
displayName: 'my-project',
|
||||
testEnvironment: 'node',
|
||||
preset: './jest.preset.js',
|
||||
};
|
||||
`
|
||||
);
|
||||
jestInitGenerator(tree, { rootProject: false });
|
||||
expect(tree.exists('jest.config.app.ts')).toBeTruthy();
|
||||
expect(tree.read('jest.config.ts', 'utf-8'))
|
||||
.toEqual(`import { getJestProjects } from '@nrwl/jest';
|
||||
|
||||
export default {
|
||||
projects: getJestProjects()
|
||||
};`);
|
||||
expect(readProjectConfiguration(tree, 'my-project').targets.test)
|
||||
.toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"options": Object {
|
||||
"jestConfig": "jest.config.app.ts",
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should work with --js', () => {
|
||||
addProjectConfiguration(tree, 'my-project', {
|
||||
root: '.',
|
||||
name: 'my-project',
|
||||
sourceRoot: 'src',
|
||||
targets: {
|
||||
test: {
|
||||
executor: '@nrwl/jest:jest',
|
||||
options: {
|
||||
jestConfig: 'jest.config.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
tree.write(
|
||||
'jest.config.js',
|
||||
`
|
||||
/* eslint-disable */
|
||||
module.exports = {
|
||||
transform: {
|
||||
'^.+\\.[tj]sx?$': 'ts-jest',
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
|
||||
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
|
||||
displayName: 'my-project',
|
||||
testEnvironment: 'node',
|
||||
preset: './jest.preset.js',
|
||||
};
|
||||
`
|
||||
);
|
||||
jestInitGenerator(tree, { js: true, rootProject: false });
|
||||
expect(tree.exists('jest.config.app.js')).toBeTruthy();
|
||||
expect(tree.read('jest.config.js', 'utf-8'))
|
||||
.toEqual(`const { getJestProjects } = require('@nrwl/jest');
|
||||
|
||||
module.exports = {
|
||||
projects: getJestProjects()
|
||||
};`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('adds jest extension', () => {
|
||||
beforeEach(async () => {
|
||||
writeJson(tree, '.vscode/extensions.json', {
|
||||
|
||||
@ -8,7 +8,10 @@ import {
|
||||
Tree,
|
||||
updateJson,
|
||||
updateWorkspaceConfiguration,
|
||||
updateProjectConfiguration,
|
||||
getProjects,
|
||||
} from '@nrwl/devkit';
|
||||
import { findRootJestConfig } from '../../utils/config/find-root-jest-files';
|
||||
import {
|
||||
babelJestVersion,
|
||||
jestTypesVersion,
|
||||
@ -18,6 +21,7 @@ import {
|
||||
tsJestVersion,
|
||||
tslibVersion,
|
||||
tsNodeVersion,
|
||||
typesNodeVersion,
|
||||
} from '../../utils/versions';
|
||||
import { JestInitSchema } from './schema';
|
||||
|
||||
@ -26,39 +30,81 @@ interface NormalizedSchema extends ReturnType<typeof normalizeOptions> {}
|
||||
const schemaDefaults = {
|
||||
compiler: 'tsc',
|
||||
js: false,
|
||||
rootProject: false,
|
||||
} as const;
|
||||
|
||||
function createJestConfig(tree: Tree, js: boolean = false) {
|
||||
// if the root ts config already exists then don't make a js one or vice versa
|
||||
if (!tree.exists('jest.config.ts') && !tree.exists('jest.config.js')) {
|
||||
const contents = js
|
||||
? stripIndents`
|
||||
const { getJestProjects } = require('@nrwl/jest');
|
||||
function generateGlobalConfig(tree: Tree, isJS: boolean) {
|
||||
const contents = isJS
|
||||
? stripIndents`
|
||||
const { getJestProjects } = require('@nrwl/jest');
|
||||
|
||||
module.exports = {
|
||||
projects: getJestProjects()
|
||||
};`
|
||||
: stripIndents`
|
||||
import { getJestProjects } from '@nrwl/jest';
|
||||
module.exports = {
|
||||
projects: getJestProjects()
|
||||
};`
|
||||
: stripIndents`
|
||||
import { getJestProjects } from '@nrwl/jest';
|
||||
|
||||
export default {
|
||||
projects: getJestProjects()
|
||||
};`;
|
||||
tree.write(`jest.config.${js ? 'js' : 'ts'}`, contents);
|
||||
}
|
||||
export default {
|
||||
projects: getJestProjects()
|
||||
};`;
|
||||
tree.write(`jest.config.${isJS ? 'js' : 'ts'}`, contents);
|
||||
}
|
||||
|
||||
function createJestConfig(tree: Tree, options: NormalizedSchema) {
|
||||
if (!tree.exists('jest.preset.js')) {
|
||||
// preset is always js file.
|
||||
tree.write(
|
||||
`jest.preset.js`,
|
||||
`
|
||||
const nxPreset = require('@nrwl/jest/preset').default;
|
||||
|
||||
|
||||
module.exports = { ...nxPreset }`
|
||||
);
|
||||
|
||||
addTestInputs(tree);
|
||||
}
|
||||
if (options.rootProject) {
|
||||
// we don't want any config to be made because the `jestProjectGenerator`
|
||||
// will copy the template config file
|
||||
return;
|
||||
}
|
||||
const rootJestPath = findRootJestConfig(tree);
|
||||
if (!rootJestPath) {
|
||||
// if there's not root jest config, we will create one and return
|
||||
// this can happen when:
|
||||
// - root jest config was renamed => in which case there is migration needed
|
||||
// - root project didn't have jest setup => again, no migration is needed
|
||||
generateGlobalConfig(tree, options.js);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tree.exists(rootJestPath)) {
|
||||
// moving from root project config to monorepo-style config
|
||||
const projects = getProjects(tree);
|
||||
const projectNames = Array.from(projects.keys());
|
||||
const rootProject = projectNames.find(
|
||||
(projectName) => projects.get(projectName)?.root === '.'
|
||||
);
|
||||
// root project might have been removed,
|
||||
// if it's missing there's nothing to migrate
|
||||
if (rootProject) {
|
||||
const rootProjectConfig = projects.get(rootProject);
|
||||
const jestTarget = Object.values(rootProjectConfig.targets || {}).find(
|
||||
(t) => t?.executor === '@nrwl/jest:jest'
|
||||
);
|
||||
const isProjectConfig = jestTarget?.options?.jestConfig === rootJestPath;
|
||||
// if root project doesn't have jest target, there's nothing to migrate
|
||||
if (isProjectConfig) {
|
||||
const jestAppConfig = `jest.config.app.${options.js ? 'js' : 'ts'}`;
|
||||
|
||||
tree.rename(rootJestPath, jestAppConfig);
|
||||
jestTarget.options.jestConfig = jestAppConfig;
|
||||
updateProjectConfiguration(tree, rootProject, rootProjectConfig);
|
||||
}
|
||||
// generate new global config as it was move to project config or is missing
|
||||
generateGlobalConfig(tree, options.js);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addTestInputs(tree: Tree) {
|
||||
@ -113,7 +159,7 @@ function updateDependencies(tree: Tree, options: NormalizedSchema) {
|
||||
if (!options.js) {
|
||||
devDeps['ts-node'] = tsNodeVersion;
|
||||
devDeps['@types/jest'] = jestTypesVersion;
|
||||
devDeps['@types/node'] = '16.11.7';
|
||||
devDeps['@types/node'] = typesNodeVersion;
|
||||
}
|
||||
|
||||
if (options.compiler === 'babel' || options.babelJest) {
|
||||
@ -144,7 +190,7 @@ function updateExtensions(host: Tree) {
|
||||
|
||||
export function jestInitGenerator(tree: Tree, schema: JestInitSchema) {
|
||||
const options = normalizeOptions(schema);
|
||||
createJestConfig(tree, options.js);
|
||||
createJestConfig(tree, options);
|
||||
|
||||
let installTask: GeneratorCallback = () => {};
|
||||
if (!options.skipPackageJson) {
|
||||
|
||||
@ -6,4 +6,5 @@ export interface JestInitSchema {
|
||||
* @deprecated
|
||||
*/
|
||||
babelJest?: boolean;
|
||||
rootProject?: boolean;
|
||||
}
|
||||
|
||||
@ -21,6 +21,12 @@
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Use JavaScript instead of TypeScript for config files"
|
||||
},
|
||||
"rootProject": {
|
||||
"description": "initialize Jest for an application at the root of the workspace",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"hidden": true
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
|
||||
@ -19,5 +19,9 @@
|
||||
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||
'jest-preset-angular/build/serializers/html-comment',
|
||||
]<% } %>
|
||||
]<% } %><% if(rootProject){ %>,
|
||||
testMatch: [
|
||||
'<rootDir>/src/**/__tests__/**/*.[jt]s?(x)',
|
||||
'<rootDir>/src/**/?(*.)+(spec|test).[jt]s?(x)',
|
||||
],<% } %>
|
||||
};
|
||||
|
||||
@ -13,5 +13,9 @@
|
||||
<% if (supportTsx){ %>'^.+\\.[tj]sx?$'<% } else { %>'^.+\\.[tj]s$'<% } %>: <% if (supportTsx && transformer === '@swc/jest') { %>['<%= transformer %>', { jsc: { transform: { react: { runtime: 'automatic' } } } }]<% } else { %>'<%= transformer %>'<% } %>
|
||||
},
|
||||
<% if (supportTsx) { %>moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],<% } else { %>moduleFileExtensions: ['ts', 'js', 'html'],<% } %><% } %>
|
||||
coverageDirectory: '<%= offsetFromRoot %>coverage/<%= projectRoot %>'
|
||||
coverageDirectory: '<%= offsetFromRoot %>coverage/<%= projectRoot %>'<% if(rootProject){ %>,
|
||||
testMatch: [
|
||||
'<rootDir>/src/**/__tests__/**/*.[jt]s?(x)',
|
||||
'<rootDir>/src/**/?(*.)+(spec|test).[jt]s?(x)',
|
||||
],<% } %>
|
||||
};
|
||||
|
||||
@ -362,4 +362,81 @@ describe('jestProject', () => {
|
||||
expect(tree.read('libs/lib1/jest.config.ts', 'utf-8')).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('root project', () => {
|
||||
it('root jest.config.ts should be project config', async () => {
|
||||
writeJson(tree, 'tsconfig.json', {
|
||||
files: [],
|
||||
include: [],
|
||||
references: [],
|
||||
});
|
||||
addProjectConfiguration(tree, 'my-project', {
|
||||
root: '',
|
||||
sourceRoot: 'src',
|
||||
name: 'my-project',
|
||||
targets: {},
|
||||
});
|
||||
await jestProjectGenerator(tree, {
|
||||
...defaultOptions,
|
||||
project: 'my-project',
|
||||
rootProject: true,
|
||||
});
|
||||
expect(tree.read('jest.config.ts', 'utf-8')).toMatchInlineSnapshot(`
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'my-project',
|
||||
preset: '../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
}
|
||||
},
|
||||
coverageDirectory: '../coverage/my-project',
|
||||
testMatch: [
|
||||
'<rootDir>/src/**/__tests__/**/*.[jt]s?(x)',
|
||||
'<rootDir>/src/**/?(*.)+(spec|test).[jt]s?(x)',
|
||||
],
|
||||
};
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('root jest.config.js should be project config', async () => {
|
||||
writeJson(tree, 'tsconfig.json', {
|
||||
files: [],
|
||||
include: [],
|
||||
references: [],
|
||||
});
|
||||
addProjectConfiguration(tree, 'my-project', {
|
||||
root: '',
|
||||
sourceRoot: 'src',
|
||||
name: 'my-project',
|
||||
targets: {},
|
||||
});
|
||||
await jestProjectGenerator(tree, {
|
||||
...defaultOptions,
|
||||
project: 'my-project',
|
||||
rootProject: true,
|
||||
js: true,
|
||||
});
|
||||
expect(tree.read('jest.config.js', 'utf-8')).toMatchInlineSnapshot(`
|
||||
"/* eslint-disable */
|
||||
module.exports = {
|
||||
displayName: 'my-project',
|
||||
preset: '../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
}
|
||||
},
|
||||
coverageDirectory: '../coverage/my-project',
|
||||
testMatch: [
|
||||
'<rootDir>/src/**/__tests__/**/*.[jt]s?(x)',
|
||||
'<rootDir>/src/**/?(*.)+(spec|test).[jt]s?(x)',
|
||||
],
|
||||
};
|
||||
"
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -13,6 +13,7 @@ const schemaDefaults = {
|
||||
supportTsx: false,
|
||||
skipSetupFile: false,
|
||||
skipSerializers: false,
|
||||
rootProject: false,
|
||||
} as const;
|
||||
|
||||
function normalizeOptions(options: JestProjectSchema) {
|
||||
@ -42,7 +43,6 @@ function normalizeOptions(options: JestProjectSchema) {
|
||||
|
||||
// setupFile is always 'none'
|
||||
options.setupFile = schemaDefaults.setupFile;
|
||||
|
||||
return {
|
||||
...schemaDefaults,
|
||||
...options,
|
||||
@ -55,11 +55,12 @@ export async function jestProjectGenerator(
|
||||
) {
|
||||
const options = normalizeOptions(schema);
|
||||
const installTask = init(tree, options);
|
||||
|
||||
checkForTestTarget(tree, options);
|
||||
createFiles(tree, options);
|
||||
updateTsConfig(tree, options);
|
||||
updateWorkspace(tree, options);
|
||||
updateJestConfig(tree, options);
|
||||
|
||||
if (!schema.skipFormat) {
|
||||
await formatFiles(tree);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import { JestProjectSchema } from '../schema';
|
||||
|
||||
export function checkForTestTarget(tree: Tree, options: JestProjectSchema) {
|
||||
const projectConfig = readProjectConfiguration(tree, options.project);
|
||||
if (projectConfig.targets.test) {
|
||||
throw new Error(`${options.project}: already has a test architect option.`);
|
||||
if (projectConfig?.targets?.test) {
|
||||
throw new Error(`${options.project}: already has a test target set.`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,8 @@ export function createFiles(tree: Tree, options: JestProjectSchema) {
|
||||
...options,
|
||||
transformer,
|
||||
js: !!options.js,
|
||||
projectRoot: projectConfig.root,
|
||||
rootProject: options.rootProject,
|
||||
projectRoot: options.rootProject ? options.project : projectConfig.root,
|
||||
offsetFromRoot: offsetFromRoot(projectConfig.root),
|
||||
});
|
||||
|
||||
|
||||
@ -4,10 +4,10 @@ import { addPropertyToJestConfig } from '../../../utils/config/update-config';
|
||||
import { readProjectConfiguration, Tree } from '@nrwl/devkit';
|
||||
|
||||
function isUsingUtilityFunction(host: Tree) {
|
||||
return host
|
||||
.read(findRootJestConfig(host))
|
||||
.toString()
|
||||
.includes('getJestProjects()');
|
||||
const rootConfig = findRootJestConfig(host);
|
||||
return (
|
||||
rootConfig && host.read(rootConfig).toString().includes('getJestProjects()')
|
||||
);
|
||||
}
|
||||
|
||||
export function updateJestConfig(host: Tree, options: JestProjectSchema) {
|
||||
@ -15,10 +15,13 @@ export function updateJestConfig(host: Tree, options: JestProjectSchema) {
|
||||
return;
|
||||
}
|
||||
const project = readProjectConfiguration(host, options.project);
|
||||
addPropertyToJestConfig(
|
||||
host,
|
||||
findRootJestConfig(host),
|
||||
'projects',
|
||||
`<rootDir>/${project.root}`
|
||||
);
|
||||
const rootConfig = findRootJestConfig(host);
|
||||
if (rootConfig) {
|
||||
addPropertyToJestConfig(
|
||||
host,
|
||||
findRootJestConfig(host),
|
||||
'projects',
|
||||
`<rootDir>/${project.root}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,4 +16,5 @@ export interface JestProjectSchema {
|
||||
compiler?: 'tsc' | 'babel' | 'swc';
|
||||
skipPackageJson?: boolean;
|
||||
js?: boolean;
|
||||
rootProject?: boolean;
|
||||
}
|
||||
|
||||
@ -68,6 +68,12 @@
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Use JavaScript instead of TypeScript for config files"
|
||||
},
|
||||
"rootProject": {
|
||||
"description": "Add Jest to an application at the root of the workspace",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"hidden": true
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
|
||||
@ -41,3 +41,17 @@ export function getJestProjects() {
|
||||
}
|
||||
return Array.from(jestConfigurationSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* a list of nested projects that have jest configured
|
||||
* to be used in the testPathIgnorePatterns property of a given jest config
|
||||
* https://jestjs.io/docs/configuration#testpathignorepatterns-arraystring
|
||||
* */
|
||||
export function getNestedJestProjects() {
|
||||
// TODO(caleb): get current project path and list of all projects and their rootDir
|
||||
// return a list of all projects that are nested in the current projects path
|
||||
// always include node_modules as that's the default
|
||||
|
||||
const allProjects = getJestProjects();
|
||||
return ['/node_modules/'];
|
||||
}
|
||||
|
||||
@ -14,5 +14,6 @@ export async function addJest(host: Tree, options: NormalizedSchema) {
|
||||
skipSerializers: true,
|
||||
setupFile: 'none',
|
||||
compiler: options.compiler,
|
||||
rootProject: options.rootProject,
|
||||
});
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ import {
|
||||
Tree,
|
||||
updateWorkspaceConfiguration,
|
||||
} from '@nrwl/devkit';
|
||||
import { jestInitGenerator } from '@nrwl/jest';
|
||||
import { webInitGenerator } from '@nrwl/web';
|
||||
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
|
||||
import {
|
||||
@ -71,10 +70,6 @@ export async function reactInitGenerator(host: Tree, schema: InitSchema) {
|
||||
|
||||
setDefault(host);
|
||||
|
||||
if (!schema.unitTestRunner || schema.unitTestRunner === 'jest') {
|
||||
const jestTask = jestInitGenerator(host, schema);
|
||||
tasks.push(jestTask);
|
||||
}
|
||||
if (!schema.e2eTestRunner || schema.e2eTestRunner === 'cypress') {
|
||||
const cypressTask = cypressInitGenerator(host, {});
|
||||
tasks.push(cypressTask);
|
||||
|
||||
@ -44,7 +44,6 @@ async function createPreset(tree: Tree, options: Schema) {
|
||||
name: options.name,
|
||||
style: options.style,
|
||||
linter: options.linter,
|
||||
unitTestRunner: 'none',
|
||||
standaloneConfig: options.standaloneConfig,
|
||||
rootProject: true,
|
||||
});
|
||||
@ -68,7 +67,6 @@ async function createPreset(tree: Tree, options: Schema) {
|
||||
name: options.name,
|
||||
style: options.style,
|
||||
linter: options.linter,
|
||||
unitTestRunner: 'none',
|
||||
standaloneConfig: options.standaloneConfig,
|
||||
rootProject: true,
|
||||
bundler: 'vite',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user