@nx/jest
Version:
170 lines (169 loc) • 7.21 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.getJestProjects = getJestProjects;
exports.getNestedJestProjects = getNestedJestProjects;
exports.getJestProjectsAsync = getJestProjectsAsync;
const devkit_1 = require("@nx/devkit");
const file_utils_1 = require("nx/src/project-graph/file-utils");
const path_1 = require("path");
const yargs = require("yargs-parser");
function getJestConfigProjectPath(projectJestConfigPath) {
return (0, path_1.join)('<rootDir>', projectJestConfigPath);
}
/**
* TODO(v21): Remove this function
* @deprecated To get projects use {@link getJestProjectsAsync} instead. This will be removed in v21.
* Get a list of paths to all the jest config files
* using the Nx Jest executor.
*
* This is used to configure Jest multi-project support. To support projects
* using inferred targets @see getJestProjectsAsync
*
* To add a project not using the Nx Jest executor:
* export default {
* projects: [...getJestProjects(), '<rootDir>/path/to/jest.config.ts'];
* }
*
**/
function getJestProjects() {
const ws = (0, file_utils_1.readWorkspaceConfig)({
format: 'nx',
});
const jestConfigurationSet = new Set();
for (const projectConfig of Object.values(ws.projects)) {
if (!projectConfig.targets) {
continue;
}
for (const targetConfiguration of Object.values(projectConfig.targets)) {
if (targetConfiguration.executor !== '@nx/jest:jest' &&
targetConfiguration.executor !== '@nrwl/jest:jest') {
continue;
}
if (targetConfiguration.options?.jestConfig) {
jestConfigurationSet.add(getJestConfigProjectPath(targetConfiguration.options.jestConfig));
}
if (targetConfiguration.configurations) {
for (const configurationObject of Object.values(targetConfiguration.configurations)) {
if (configurationObject.jestConfig) {
jestConfigurationSet.add(getJestConfigProjectPath(configurationObject.jestConfig));
}
}
}
}
}
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
* */
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/'];
}
/**
* Get a list of paths to all the jest config files
* using the Nx Jest executor and `@nx/run:commands`
* running `jest`.
*
* This is used to configure Jest multi-project support.
*
* To add a project not using the Nx Jest executor:
* export default async () => ({
* projects: [...(await getJestProjectsAsync()), '<rootDir>/path/to/jest.config.ts'];
* });
*
**/
async function getJestProjectsAsync() {
const graph = await (0, devkit_1.createProjectGraphAsync)({
exitOnError: false,
resetDaemonClient: true,
});
const jestConfigurations = new Set();
for (const node of Object.values(graph.nodes)) {
const projectConfig = node.data;
if (!projectConfig.targets) {
continue;
}
for (const targetConfiguration of Object.values(projectConfig.targets)) {
if (targetConfiguration.executor === '@nx/jest:jest' ||
targetConfiguration.executor === '@nrwl/jest:jest') {
collectJestConfigFromJestExecutor(targetConfiguration, jestConfigurations);
}
else if (targetConfiguration.executor === 'nx:run-commands') {
collectJestConfigFromRunCommandsExecutor(targetConfiguration, projectConfig.root, jestConfigurations);
}
}
}
removeDuplicates(jestConfigurations);
return Array.from(jestConfigurations);
}
// If two paths result in same project, prefer the more specific path.
// e.g. <rootDir>/demo/jest.config.js over <rootDir>/demo
function removeDuplicates(configs) {
configs.forEach((config) => {
const { dir, ext } = (0, path_1.parse)(config);
// If the directory has been added previously, remove it and keep the current, more specific path.
if (ext)
configs.delete(dir);
});
}
function collectJestConfigFromJestExecutor(targetConfiguration, jestConfigurations) {
if (targetConfiguration.options?.jestConfig) {
jestConfigurations.add(getJestConfigProjectPath(targetConfiguration.options.jestConfig));
}
if (targetConfiguration.configurations) {
for (const configurationObject of Object.values(targetConfiguration.configurations)) {
if (configurationObject.jestConfig) {
jestConfigurations.add(getJestConfigProjectPath(configurationObject.jestConfig));
}
}
}
}
function collectJestConfigFromRunCommandsExecutor(targetConfiguration, projectRoot, jestConfigurations) {
if (targetConfiguration.options?.command) {
collectJestConfigFromCommand(targetConfiguration.options.command, targetConfiguration.options.cwd ?? projectRoot, jestConfigurations);
}
else if (targetConfiguration.options?.commands) {
for (const command of targetConfiguration.options.commands) {
const commandScript = typeof command === 'string' ? command : command.command;
collectJestConfigFromCommand(commandScript, targetConfiguration.options.cwd ?? projectRoot, jestConfigurations);
}
}
if (targetConfiguration.configurations) {
for (const configurationObject of Object.values(targetConfiguration.configurations)) {
if (configurationObject.command) {
collectJestConfigFromCommand(configurationObject.command, configurationObject.cwd ?? projectRoot, jestConfigurations);
}
else if (configurationObject.commands) {
for (const command of configurationObject.commands) {
const commandScript = typeof command === 'string' ? command : command.command;
collectJestConfigFromCommand(commandScript, configurationObject.cwd ?? projectRoot, jestConfigurations);
}
}
}
}
}
function collectJestConfigFromCommand(command, cwd, jestConfigurations) {
const jestCommandRegex = /(?<=^|&)(?:[^&\r\n\s]* )*jest(?: [^&\r\n\s]*)*(?=$|&)/g;
const matches = command.match(jestCommandRegex);
if (!matches) {
return;
}
for (const match of matches) {
const parsed = yargs(match, {
configuration: { 'strip-dashed': true },
string: ['config'],
});
if (parsed.config) {
jestConfigurations.add(getJestConfigProjectPath((0, path_1.join)(cwd, parsed.config)));
}
else {
jestConfigurations.add(getJestConfigProjectPath(cwd));
}
}
}
;