From c0aa245d9cc15fc648b09acd5ef6aead11a1b153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leosvel=20P=C3=A9rez=20Espinosa?= Date: Fri, 25 Apr 2025 15:12:13 +0200 Subject: [PATCH] feat(testing): remove deprecated `getJestProjects` (#30844) Remove the deprecated function `getJestProjects`. BREAKING CHANGE: The previously deprecated `getJestProjects` function was removed in favor of `getJestProjectsAsync`. --- docs/generated/manifests/nx-api.json | 12 +- docs/generated/packages-metadata.json | 12 +- ...rojects-with-getJestProjectsAsync-v21.json | 13 ++ ...estProjects-with-getJestProjectsAsync.json | 4 +- packages/jest/index.ts | 6 +- packages/jest/migrations.json | 8 +- .../lib/create-jest-config.spec.ts | 8 +- .../configuration/lib/update-jestconfig.ts | 37 ---- ...tJestProjects-with-getJestProjectsAsync.md | 4 +- ...tJestProjects-with-getJestProjectsAsync.md | 30 +++ ...Projects-with-getJestProjectsAsync.spec.ts | 191 ++++++++++++++++++ ...tJestProjects-with-getJestProjectsAsync.ts | 140 +++++++++++++ .../jest/src/utils/config/functions.spec.ts | 66 ------ .../utils/config/get-jest-projects.spec.ts | 188 +---------------- .../src/utils/config/get-jest-projects.ts | 73 +------ .../move/lib/update-jest-config.spec.ts | 26 +-- .../generators/move/lib/update-jest-config.ts | 6 +- .../remove/lib/update-jest-config.ts | 5 +- 18 files changed, 432 insertions(+), 397 deletions(-) create mode 100644 docs/generated/packages/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync-v21.json delete mode 100644 packages/jest/src/generators/configuration/lib/update-jestconfig.ts create mode 100644 packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.md create mode 100644 packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.spec.ts create mode 100644 packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.ts diff --git a/docs/generated/manifests/nx-api.json b/docs/generated/manifests/nx-api.json index 534b664ae8..c87a39674b 100644 --- a/docs/generated/manifests/nx-api.json +++ b/docs/generated/manifests/nx-api.json @@ -2429,8 +2429,18 @@ } }, "migrations": { + "/nx-api/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync-v21": { + "description": "Replace usage of `getJestProjects` with `getJestProjectsAsync`.", + "file": "generated/packages/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync-v21.json", + "hidden": false, + "name": "replace-getJestProjects-with-getJestProjectsAsync-v21", + "version": "21.0.0-beta.9", + "originalFilePath": "/packages/jest", + "path": "/nx-api/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync-v21", + "type": "migration" + }, "/nx-api/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync": { - "description": "replace getJestProjects with getJestProjectsAsync", + "description": "Replace usage of `getJestProjects` with `getJestProjectsAsync`.", "file": "generated/packages/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync.json", "hidden": false, "name": "replace-getJestProjects-with-getJestProjectsAsync", diff --git a/docs/generated/packages-metadata.json b/docs/generated/packages-metadata.json index ca5f2aeed4..bd3d6da2d2 100644 --- a/docs/generated/packages-metadata.json +++ b/docs/generated/packages-metadata.json @@ -2413,7 +2413,17 @@ ], "migrations": [ { - "description": "replace getJestProjects with getJestProjectsAsync", + "description": "Replace usage of `getJestProjects` with `getJestProjectsAsync`.", + "file": "generated/packages/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync-v21.json", + "hidden": false, + "name": "replace-getJestProjects-with-getJestProjectsAsync-v21", + "version": "21.0.0-beta.9", + "originalFilePath": "/packages/jest", + "path": "jest/migrations/replace-getJestProjects-with-getJestProjectsAsync-v21", + "type": "migration" + }, + { + "description": "Replace usage of `getJestProjects` with `getJestProjectsAsync`.", "file": "generated/packages/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync.json", "hidden": false, "name": "replace-getJestProjects-with-getJestProjectsAsync", diff --git a/docs/generated/packages/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync-v21.json b/docs/generated/packages/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync-v21.json new file mode 100644 index 0000000000..bf774d4776 --- /dev/null +++ b/docs/generated/packages/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync-v21.json @@ -0,0 +1,13 @@ +{ + "name": "replace-getJestProjects-with-getJestProjectsAsync-v21", + "cli": "nx", + "version": "21.0.0-beta.9", + "description": "Replace usage of `getJestProjects` with `getJestProjectsAsync`.", + "implementation": "/packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.ts", + "aliases": [], + "hidden": false, + "path": "/packages/jest", + "schema": null, + "type": "migration", + "examplesFile": "#### Replace Usage of `getJestProjects` with `getJestProjectsAsync`\n\nReplaces the usage of the removed `getJestProjects` function with the `getJestProjectsAsync` function.\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```ts {% fileName=\"jest.config.ts\" %}\nimport { getJestProjects } from '@nx/jest';\n\nexport default {\n projects: getJestProjects(),\n};\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```ts {% fileName=\"jest.config.ts\" %}\nimport { getJestProjectsAsync } from '@nx/jest';\n\nexport default async () => ({\n projects: await getJestProjectsAsync(),\n});\n```\n\n{% /tab %}\n{% /tabs %}\n" +} diff --git a/docs/generated/packages/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync.json b/docs/generated/packages/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync.json index 044ef0191a..235ea744a4 100644 --- a/docs/generated/packages/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync.json +++ b/docs/generated/packages/jest/migrations/replace-getJestProjects-with-getJestProjectsAsync.json @@ -2,12 +2,12 @@ "name": "replace-getJestProjects-with-getJestProjectsAsync", "cli": "nx", "version": "20.0.0-beta.5", - "description": "replace getJestProjects with getJestProjectsAsync", + "description": "Replace usage of `getJestProjects` with `getJestProjectsAsync`.", "implementation": "/packages/jest/src/migrations/update-20-0-0/replace-getJestProjects-with-getJestProjectsAsync.ts", "aliases": [], "hidden": false, "path": "/packages/jest", "schema": null, "type": "migration", - "examplesFile": "#### Replace getJestProjects with getJestProjectsAsync\n\nReplace getJestProjects with getJestProjectsAsync\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```ts {% fileName=\"jest.config.ts\" %}\nimport { getJestProjects } from '@nx/jest';\n\nexport default {\n projects: getJestProjects(),\n};\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```ts {% fileName=\"jest.config.ts\" %}\nimport { getJestProjectsAsync } from '@nx/jest';\n\nexport default async () => ({\n projects: await getJestProjectsAsync(),\n});\n```\n\n{% /tab %}\n{% /tabs %}\n" + "examplesFile": "#### Replace Usage of `getJestProjects` with `getJestProjectsAsync`\n\nReplaces the usage of the deprecated `getJestProjects` function with the `getJestProjectsAsync` function.\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```ts {% fileName=\"jest.config.ts\" %}\nimport { getJestProjects } from '@nx/jest';\n\nexport default {\n projects: getJestProjects(),\n};\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```ts {% fileName=\"jest.config.ts\" %}\nimport { getJestProjectsAsync } from '@nx/jest';\n\nexport default async () => ({\n projects: await getJestProjectsAsync(),\n});\n```\n\n{% /tab %}\n{% /tabs %}\n" } diff --git a/packages/jest/index.ts b/packages/jest/index.ts index cbc98ef823..d0afae2d18 100644 --- a/packages/jest/index.ts +++ b/packages/jest/index.ts @@ -11,8 +11,4 @@ export { } from './src/utils/config/update-config'; export { jestConfigObjectAst } from './src/utils/config/functions'; export { jestInitGenerator } from './src/generators/init/init'; -export { - getJestProjects, - getJestProjectsAsync, - getNestedJestProjects, -} from './src/utils/config/get-jest-projects'; +export { getJestProjectsAsync } from './src/utils/config/get-jest-projects'; diff --git a/packages/jest/migrations.json b/packages/jest/migrations.json index 73fcf3cf6e..fd694e5f59 100644 --- a/packages/jest/migrations.json +++ b/packages/jest/migrations.json @@ -8,8 +8,14 @@ "replace-getJestProjects-with-getJestProjectsAsync": { "cli": "nx", "version": "20.0.0-beta.5", - "description": "replace getJestProjects with getJestProjectsAsync", + "description": "Replace usage of `getJestProjects` with `getJestProjectsAsync`.", "implementation": "./src/migrations/update-20-0-0/replace-getJestProjects-with-getJestProjectsAsync" + }, + "replace-getJestProjects-with-getJestProjectsAsync-v21": { + "cli": "nx", + "version": "21.0.0-beta.9", + "description": "Replace usage of `getJestProjects` with `getJestProjectsAsync`.", + "implementation": "./src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync" } }, "packageJsonUpdates": { diff --git a/packages/jest/src/generators/configuration/lib/create-jest-config.spec.ts b/packages/jest/src/generators/configuration/lib/create-jest-config.spec.ts index 17e3532719..f79595287c 100644 --- a/packages/jest/src/generators/configuration/lib/create-jest-config.spec.ts +++ b/packages/jest/src/generators/configuration/lib/create-jest-config.spec.ts @@ -75,11 +75,11 @@ describe('createJestConfig', () => { }, }); const expected = ` -import { getJestProjects } from '@nx/jest'; -export default { - projects: getJestProjects(), +import { getJestProjectsAsync } from '@nx/jest'; +export default async () => ({ + projects: await getJestProjectsAsync(), extraThing: "Goes Here" -} +}); `; tree.write('jest.config.ts', expected); diff --git a/packages/jest/src/generators/configuration/lib/update-jestconfig.ts b/packages/jest/src/generators/configuration/lib/update-jestconfig.ts deleted file mode 100644 index d33a9a98f8..0000000000 --- a/packages/jest/src/generators/configuration/lib/update-jestconfig.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { readProjectConfiguration, type Tree } from '@nx/devkit'; -import { findRootJestConfig } from '../../../utils/config/config-file'; -import { addPropertyToJestConfig } from '../../../utils/config/update-config'; -import type { NormalizedJestProjectSchema } from '../schema'; - -function isUsingUtilityFunction(host: Tree) { - const rootConfig = findRootJestConfig(host); - if (!rootConfig) { - return false; - } - - const rootConfigContent = host.read(rootConfig, 'utf-8'); - - return ( - rootConfigContent.includes('getJestProjects()') || - rootConfigContent.includes('getJestProjectsAsync()') - ); -} - -export function updateJestConfig( - host: Tree, - options: NormalizedJestProjectSchema -) { - if (isUsingUtilityFunction(host)) { - return; - } - const project = readProjectConfiguration(host, options.project); - const rootConfig = findRootJestConfig(host); - if (rootConfig) { - addPropertyToJestConfig( - host, - findRootJestConfig(host), - 'projects', - `/${project.root}` - ); - } -} diff --git a/packages/jest/src/migrations/update-20-0-0/replace-getJestProjects-with-getJestProjectsAsync.md b/packages/jest/src/migrations/update-20-0-0/replace-getJestProjects-with-getJestProjectsAsync.md index 5f05e4609a..0ba63e283e 100644 --- a/packages/jest/src/migrations/update-20-0-0/replace-getJestProjects-with-getJestProjectsAsync.md +++ b/packages/jest/src/migrations/update-20-0-0/replace-getJestProjects-with-getJestProjectsAsync.md @@ -1,6 +1,6 @@ -#### Replace getJestProjects with getJestProjectsAsync +#### Replace Usage of `getJestProjects` with `getJestProjectsAsync` -Replace getJestProjects with getJestProjectsAsync +Replaces the usage of the deprecated `getJestProjects` function with the `getJestProjectsAsync` function. #### Sample Code Changes diff --git a/packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.md b/packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.md new file mode 100644 index 0000000000..5abf871973 --- /dev/null +++ b/packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.md @@ -0,0 +1,30 @@ +#### Replace Usage of `getJestProjects` with `getJestProjectsAsync` + +Replaces the usage of the removed `getJestProjects` function with the `getJestProjectsAsync` function. + +#### Sample Code Changes + +{% tabs %} +{% tab label="Before" %} + +```ts {% fileName="jest.config.ts" %} +import { getJestProjects } from '@nx/jest'; + +export default { + projects: getJestProjects(), +}; +``` + +{% /tab %} +{% tab label="After" %} + +```ts {% fileName="jest.config.ts" %} +import { getJestProjectsAsync } from '@nx/jest'; + +export default async () => ({ + projects: await getJestProjectsAsync(), +}); +``` + +{% /tab %} +{% /tabs %} diff --git a/packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.spec.ts b/packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.spec.ts new file mode 100644 index 0000000000..b136c3b05a --- /dev/null +++ b/packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.spec.ts @@ -0,0 +1,191 @@ +import { Tree } from '@nx/devkit'; +import { createTree } from '@nx/devkit/testing'; +import update from './replace-getJestProjects-with-getJestProjectsAsync'; + +describe('replace-getJestProjects-with-getJestProjectsAsync', () => { + let tree: Tree; + + beforeEach(() => { + tree = createTree(); + }); + + it('should replace getJestProjects with getJestProjectsAsync using `require`', async () => { + tree.write( + 'jest.config.ts', + ` + const { getJestProjects } = require('@nx/jest'); + + module.exports = { + projects: getJestProjects(), + }; + ` + ); + await update(tree); + const updatedJestConfig = tree.read('jest.config.ts')?.toString(); + expect(updatedJestConfig).toMatchInlineSnapshot(` + " + const { getJestProjectsAsync } = require('@nx/jest'); + + module.exports = async () => ({ + projects: await getJestProjectsAsync(), + }); + " + `); + }); + + it('should replace getJestProjects with getJestProjectsAsync using `import`', async () => { + tree.write( + 'jest.config.ts', + ` + import { getJestProjects } from '@nx/jest'; + + export default { + projects: getJestProjects(), + }; + ` + ); + await update(tree); + const updatedJestConfig = tree.read('jest.config.ts')?.toString(); + expect(updatedJestConfig).toMatchInlineSnapshot(` + " + import { getJestProjectsAsync } from '@nx/jest'; + + export default async () => ({ + projects: await getJestProjectsAsync(), + }); + " + `); + }); + + it('should replace getJestProjects with getJestProjectsAsync using `require` with `export default`', async () => { + tree.write( + 'jest.config.ts', + ` + const { getJestProjects } = require('@nx/jest'); + + export default { + projects: getJestProjects(), + }; + ` + ); + await update(tree); + const updatedJestConfig = tree.read('jest.config.ts')?.toString(); + expect(updatedJestConfig).toMatchInlineSnapshot(` + " + const { getJestProjectsAsync } = require('@nx/jest'); + + export default async () => ({ + projects: await getJestProjectsAsync(), + }); + " + `); + }); + + it('should replace getJestProjects with getJestProjectsAsync using `import` with `module.exports`', async () => { + tree.write( + 'jest.config.ts', + ` + import { getJestProjects } from '@nx/jest'; + + module.exports = { + projects: getJestProjects(), + }; + ` + ); + await update(tree); + const updatedJestConfig = tree.read('jest.config.ts')?.toString(); + expect(updatedJestConfig).toMatchInlineSnapshot(` + " + import { getJestProjectsAsync } from '@nx/jest'; + + module.exports = async () => ({ + projects: await getJestProjectsAsync(), + }); + " + `); + }); + + it('should replace getJestProjects with getJestProjectsAsync with additional properties', async () => { + tree.write( + 'jest.config.ts', + ` + const { getJestProjects } = require('@nx/jest'); + + module.exports = { + projects: getJestProjects(), + filename: __filename, + env: process.env, + dirname: __dirname + }; + ` + ); + await update(tree); + const updatedJestConfig = tree.read('jest.config.ts')?.toString(); + expect(updatedJestConfig).toMatchInlineSnapshot(` + " + const { getJestProjectsAsync } = require('@nx/jest'); + + module.exports = async () => ({ + projects: await getJestProjectsAsync(), + filename: __filename, + env: process.env, + dirname: __dirname + }); + " + `); + }); + + it('should not update config that are not in supported format', async () => { + // Users don't tend to update the root jest config file since it's only meant to be able to run + // `jest` command from the root of the repo. If the AST doesn't match what we generate + // then bail on the update. Users will still see that `getJestProjects` is deprecated when + // viewing the file. + tree.write( + 'jest.config.ts', + ` + import { getJestProjects } from '@nx/jest'; + + const obj = { + projects: getJestProjects(), + }; + export default obj + ` + ); + await update(tree); + let updatedJestConfig = tree.read('jest.config.ts')?.toString(); + expect(updatedJestConfig).toMatchInlineSnapshot(` + " + import { getJestProjects } from '@nx/jest'; + + const obj = { + projects: getJestProjects(), + }; + export default obj + " + `); + + tree.write( + 'jest.config.ts', + ` + const { getJestProjects } = require('@nx/jest'); + + const obj = { + projects: getJestProjects(), + }; + module.exports = obj; + ` + ); + await update(tree); + updatedJestConfig = tree.read('jest.config.ts')?.toString(); + expect(updatedJestConfig).toMatchInlineSnapshot(` + " + const { getJestProjects } = require('@nx/jest'); + + const obj = { + projects: getJestProjects(), + }; + module.exports = obj; + " + `); + }); +}); diff --git a/packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.ts b/packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.ts new file mode 100644 index 0000000000..a607beda9c --- /dev/null +++ b/packages/jest/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.ts @@ -0,0 +1,140 @@ +// go through the jest.config files +// see if it imports from @nx/jest and if it uses getJestProjects +// replace getJestProjects with getJestProjectsAsync + +import { globAsync, Tree } from '@nx/devkit'; +import { ensureTypescript } from '@nx/js/src/utils/typescript/ensure-typescript'; +import { + BinaryExpression, + ExpressionStatement, + ExportAssignment, +} from 'typescript'; + +let tsModule: typeof import('typescript'); + +export default async function update(tree: Tree) { + if (!tsModule) { + tsModule = ensureTypescript(); + } + + const jestConfigPaths = await globAsync(tree, [ + '**/jest.config.{cjs,mjs,js,cts,mts,ts}', + ]); + jestConfigPaths.forEach((jestConfigPath) => { + const oldContent = tree.read(jestConfigPath).toString(); + if (oldContent?.includes('projects: getJestProjects()')) { + let sourceFile = tsModule.createSourceFile( + jestConfigPath, + oldContent, + tsModule.ScriptTarget.Latest, + true + ); + + // find `require('@nx/jest')` or `import { getJestProjects } from '@nx/jest` + const requireStatement = sourceFile.statements.find( + (statement) => + tsModule.isVariableStatement(statement) && + statement.declarationList.declarations.some( + (declaration) => + tsModule.isCallExpression(declaration.initializer) && + tsModule.isIdentifier(declaration.initializer.expression) && + declaration.initializer.expression.escapedText === 'require' && + tsModule.isStringLiteral(declaration.initializer.arguments[0]) && + declaration.initializer.arguments[0].text === '@nx/jest' + ) + ); + const importStatement = sourceFile.statements.find( + (statement) => + tsModule.isImportDeclaration(statement) && + statement.moduleSpecifier.getText() === `'@nx/jest'` + ); + if (requireStatement || importStatement) { + // find `module.exports` statement with `projects: getJestProjects()` + const moduleExports = sourceFile.statements.find( + (statement) => + tsModule.isExpressionStatement(statement) && + tsModule.isBinaryExpression(statement.expression) && + tsModule.isPropertyAccessExpression(statement.expression.left) && + tsModule.isObjectLiteralExpression(statement.expression.right) && + statement.expression.operatorToken.kind === + tsModule.SyntaxKind.EqualsToken && + tsModule.isIdentifier(statement.expression.left.expression) && + statement.expression.left.expression.escapedText === 'module' && + tsModule.isIdentifier(statement.expression.left.name) && + statement.expression.left.name.escapedText === 'exports' && + statement.expression.right.properties.some( + (property) => + tsModule.isPropertyAssignment(property) && + tsModule.isIdentifier(property.name) && + property.name.escapedText === 'projects' && + tsModule.isCallExpression(property.initializer) && + tsModule.isIdentifier(property.initializer.expression) && + property.initializer.expression.escapedText === + 'getJestProjects' + ) + ) as ExpressionStatement; + + if (moduleExports) { + // replace getJestProjects with getJestProjectsAsync in export statement + const rightExpression = ( + moduleExports.expression as BinaryExpression + ).right.getText(); + const newExpression = rightExpression.replace( + 'getJestProjects()', + 'await getJestProjectsAsync()' + ); + const newStatement = `module.exports = async () => (${newExpression});`; + let newContent = oldContent.replace( + moduleExports.getText(), + newStatement + ); + + // replace getJestProjects with getJestProjectsAsync in import statement + newContent = newContent.replace( + 'getJestProjects', + 'getJestProjectsAsync' + ); + + tree.write(jestConfigPath, newContent); + } else { + // find `export default` statement with `projects: getJestProjects()` + const exportAssignment = sourceFile.statements.find((statement) => + tsModule.isExportAssignment(statement) + ) as ExportAssignment; + const defaultExport = + exportAssignment?.expression && + tsModule.isObjectLiteralExpression(exportAssignment?.expression) + ? exportAssignment?.expression + : null; + const projectProperty = defaultExport?.properties.find( + (property) => + tsModule.isPropertyAssignment(property) && + property.name.getText() === 'projects' && + tsModule.isCallExpression(property.initializer) && + tsModule.isIdentifier(property.initializer.expression) && + property.initializer.expression.escapedText === 'getJestProjects' + ); + if (projectProperty) { + // replace getJestProjects with getJestProjectsAsync in export statement + const newExpression = defaultExport + .getText() + .replace('getJestProjects()', 'await getJestProjectsAsync()'); + const newStatement = `export default async () => (${newExpression});`; + let newContent = oldContent.replace( + exportAssignment.getText(), + newStatement + ); + + // replace getJestProjects with getJestProjectsAsync in import statement + newContent = newContent.replace( + 'getJestProjects', + 'getJestProjectsAsync' + ); + + tree.write(jestConfigPath, newContent); + } + } + } + } + }); +} diff --git a/packages/jest/src/utils/config/functions.spec.ts b/packages/jest/src/utils/config/functions.spec.ts index c6f3665bca..3af8de26fa 100644 --- a/packages/jest/src/utils/config/functions.spec.ts +++ b/packages/jest/src/utils/config/functions.spec.ts @@ -18,72 +18,6 @@ describe('jestConfigObject', () => { foo: 'bar', }); }); - - xit('should work with async functions', async () => { - const tree = createTree(); - jest.mock('@nx/jest', () => ({ - getJestProjects: () => ['/project-a', '/project-b'], - })); - tree.write( - 'jest.config.js', - ` - const { getJestProjects } = require('@nx/jest'); - module.exports = async () => ({ - foo: 'bar' - }); - ` - ); - - expect(await jestConfigObject(tree, 'jest.config.js')).toEqual({ - foo: 'bar', - }); - }); - - it('should work with `getJestConfig`', () => { - const tree = createTree(); - jest.mock('@nx/jest', () => ({ - getJestProjects: () => ['/project-a', '/project-b'], - })); - tree.write( - 'jest.config.js', - ` - const { getJestProjects } = require('@nx/jest'); - module.exports = { - projects: getJestProjects() - }; - ` - ); - - expect(jestConfigObject(tree, 'jest.config.js')).toEqual({ - projects: ['/project-a', '/project-b'], - }); - }); - - it('should work with node globals (require, __dirname, process, __filename, console, and other globals)', () => { - const tree = createTree(); - jest.mock('@nx/jest', () => ({ - getJestProjects: () => ['/project-a', '/project-b'], - })); - tree.write( - 'jest.config.js', - ` - const { getJestProjects } = require('@nx/jest'); - module.exports = { - projects: getJestProjects(), - filename: __filename, - env: process.env, - dirname: __dirname - }; - ` - ); - - expect(jestConfigObject(tree, 'jest.config.js')).toEqual({ - dirname: '/virtual', - filename: '/virtual/jest.config.js', - env: process.env, - projects: ['/project-a', '/project-b'], - }); - }); }); describe('export default', () => { diff --git a/packages/jest/src/utils/config/get-jest-projects.spec.ts b/packages/jest/src/utils/config/get-jest-projects.spec.ts index 857c615db4..6253fa2610 100644 --- a/packages/jest/src/utils/config/get-jest-projects.spec.ts +++ b/packages/jest/src/utils/config/get-jest-projects.spec.ts @@ -1,190 +1,6 @@ -import type { - ProjectConfiguration, - ProjectGraph, - WorkspaceJsonConfiguration, -} from '@nx/devkit'; +import type { ProjectConfiguration, ProjectGraph } from '@nx/devkit'; import * as devkit from '@nx/devkit'; -import * as Workspace from 'nx/src/project-graph/file-utils'; -import { getJestProjects, getJestProjectsAsync } from './get-jest-projects'; - -describe('getJestProjects', () => { - test('single project', () => { - const mockedWorkspaceConfig: WorkspaceJsonConfiguration = { - projects: { - 'test-1': { - root: 'blah', - targets: { - test: { - executor: '@nx/jest:jest', - options: { - jestConfig: 'test/jest/config/location/jest.config.js', - }, - }, - }, - }, - }, - version: 1, - }; - jest - .spyOn(Workspace, 'readWorkspaceConfig') - .mockImplementation(() => mockedWorkspaceConfig); - const expectedResults = [ - '/test/jest/config/location/jest.config.js', - ]; - expect(getJestProjects()).toEqual(expectedResults); - }); - - test('custom target name', () => { - const mockedWorkspaceConfig: WorkspaceJsonConfiguration = { - projects: { - 'test-1': { - root: 'blah', - targets: { - 'test-with-jest': { - executor: '@nx/jest:jest', - options: { - jestConfig: 'test/jest/config/location/jest.config.js', - }, - }, - }, - }, - }, - version: 1, - }; - jest - .spyOn(Workspace, 'readWorkspaceConfig') - .mockImplementation(() => mockedWorkspaceConfig); - const expectedResults = [ - '/test/jest/config/location/jest.config.js', - ]; - expect(getJestProjects()).toEqual(expectedResults); - }); - - test('root project', () => { - const mockedWorkspaceConfig: WorkspaceJsonConfiguration = { - projects: { - 'test-1': { - root: '.', - targets: { - test: { - executor: '@nx/jest:jest', - options: { - jestConfig: 'jest.config.app.js', - }, - }, - }, - }, - }, - version: 1, - }; - jest - .spyOn(Workspace, 'readWorkspaceConfig') - .mockImplementation(() => mockedWorkspaceConfig); - const expectedResults = ['/jest.config.app.js']; - expect(getJestProjects()).toEqual(expectedResults); - }); - - test('configuration set with unique jestConfig', () => { - const mockedWorkspaceConfig: WorkspaceJsonConfiguration = { - projects: { - test: { - root: 'blah', - targets: { - 'test-with-jest': { - executor: '@nx/jest:jest', - options: { - jestConfig: 'test/jest/config/location/jest.config.js', - }, - configurations: { - prod: { - jestConfig: 'configuration-specific/jest.config.js', - }, - }, - }, - }, - }, - }, - version: 1, - }; - jest - .spyOn(Workspace, 'readWorkspaceConfig') - .mockImplementation(() => mockedWorkspaceConfig); - const expectedResults = [ - '/test/jest/config/location/jest.config.js', - '/configuration-specific/jest.config.js', - ]; - expect(getJestProjects()).toEqual(expectedResults); - }); - - test('configuration, set with same jestConfig on configuration', () => { - const mockedWorkspaceConfig: WorkspaceJsonConfiguration = { - projects: { - test: { - root: 'blah', - targets: { - 'test-with-jest': { - executor: '@nx/jest:jest', - options: { - jestConfig: 'test/jest/config/location/jest.config.js', - }, - configurations: { - prod: { - jestConfig: 'test/jest/config/location/jest.config.js', - }, - }, - }, - }, - }, - }, - version: 1, - }; - jest - .spyOn(Workspace, 'readWorkspaceConfig') - .mockImplementation(() => mockedWorkspaceConfig); - const expectedResults = [ - '/test/jest/config/location/jest.config.js', - ]; - expect(getJestProjects()).toEqual(expectedResults); - }); - - test('other projects and targets that do not use the nx jest test runner', () => { - const mockedWorkspaceConfig: WorkspaceJsonConfiguration = { - projects: { - otherTarget: { - root: 'test', - targets: { - test: { - executor: 'something else', - options: {}, - }, - }, - }, - test: { - root: 'blah', - targets: { - 'test-with-jest': { - executor: 'something else', - options: { - jestConfig: 'something random', - }, - configurations: { - prod: { - jestConfig: 'configuration-specific/jest.config.js', - }, - }, - }, - }, - }, - }, - version: 1, - }; - jest - .spyOn(Workspace, 'readWorkspaceConfig') - .mockImplementation(() => mockedWorkspaceConfig); - const expectedResults = []; - expect(getJestProjects()).toEqual(expectedResults); - }); -}); +import { getJestProjectsAsync } from './get-jest-projects'; describe('getJestProjectsAsync', () => { let projectGraph: ProjectGraph; diff --git a/packages/jest/src/utils/config/get-jest-projects.ts b/packages/jest/src/utils/config/get-jest-projects.ts index b7307ab2b5..083d785880 100644 --- a/packages/jest/src/utils/config/get-jest-projects.ts +++ b/packages/jest/src/utils/config/get-jest-projects.ts @@ -1,9 +1,4 @@ -import { - createProjectGraphAsync, - type ProjectsConfigurations, - type TargetConfiguration, -} from '@nx/devkit'; -import { readWorkspaceConfig } from 'nx/src/project-graph/file-utils'; +import { createProjectGraphAsync, type TargetConfiguration } from '@nx/devkit'; import { join, parse } from 'path'; import * as yargs from 'yargs-parser'; @@ -11,72 +6,6 @@ function getJestConfigProjectPath(projectJestConfigPath: string): string { return join('', 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(), '/path/to/jest.config.ts']; - * } - * - **/ -export function getJestProjects() { - const ws = readWorkspaceConfig({ - format: 'nx', - }) as ProjectsConfigurations; - 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 - * */ -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/']; -} - /** * Get a list of paths to all the jest config files * using the Nx Jest executor and `@nx/run:commands` diff --git a/packages/workspace/src/generators/move/lib/update-jest-config.spec.ts b/packages/workspace/src/generators/move/lib/update-jest-config.spec.ts index 732afd06e2..c75cbe1119 100644 --- a/packages/workspace/src/generators/move/lib/update-jest-config.spec.ts +++ b/packages/workspace/src/generators/move/lib/update-jest-config.spec.ts @@ -143,7 +143,7 @@ describe('updateJestConfig', () => { expect(rootJestConfigAfter).toContain('getJestProjectsAsync()'); }); - it('updates the root config if not using `getJestProjects()`', async () => { + it('updates the root config if not using `getJestProjectsAsync()`', async () => { const rootJestConfigPath = '/jest.config.ts'; await libraryGenerator(tree, { name: 'some-test-dir-my-source', @@ -180,7 +180,7 @@ describe('updateJestConfig', () => { ); }); - it('updates the root config if `getJestProjects()` is used but old path exists', async () => { + it('updates the root config if `getJestProjectsAsync()` is used but old path exists', async () => { const rootJestConfigPath = '/jest.config.ts'; await libraryGenerator(tree, { name: 'some-test-dir-my-source', @@ -188,11 +188,11 @@ describe('updateJestConfig', () => { }); tree.write( rootJestConfigPath, - `const { getJestProjects } = require('@nx/jest'); + `const { getJestProjectsAsync } = require('@nx/jest'); -module.exports = { - projects: [...getJestProjects(), '/some/test/dir/my-source'] -}; +module.exports = async () => ({ + projects: [...(await getJestProjectsAsync()), '/some/test/dir/my-source'] +}); ` ); const projectConfig = readProjectConfiguration( @@ -217,10 +217,10 @@ module.exports = { expect(rootJestConfigAfter).not.toContain( '/other/test/dir/my-destination' ); - expect(rootJestConfigAfter).toContain('getJestProjects()'); + expect(rootJestConfigAfter).toContain('getJestProjectsAsync()'); }); - it('updates the root config if `getJestProjects()` is used with other projects in the array', async () => { + it('updates the root config if `getJestProjectsAsync()` is used with other projects in the array', async () => { const rootJestConfigPath = '/jest.config.ts'; await libraryGenerator(tree, { name: 'some-test-dir-my-source', @@ -228,11 +228,11 @@ module.exports = { }); tree.write( rootJestConfigPath, - `const { getJestProjects } = require('@nx/jest'); + `const { getJestProjectsAsync } = require('@nx/jest'); -module.exports = { - projects: [...getJestProjects(), '/some/test/dir/my-source', '/foo'] -}; +module.exports = async () => ({ + projects: [...(await getJestProjectsAsync()), '/some/test/dir/my-source', '/foo'] +}); ` ); const projectConfig = readProjectConfiguration( @@ -258,6 +258,6 @@ module.exports = { '/other/test/dir/my-destination' ); expect(rootJestConfigAfter).toContain('/foo'); - expect(rootJestConfigAfter).toContain('getJestProjects()'); + expect(rootJestConfigAfter).toContain('getJestProjectsAsync()'); }); }); diff --git a/packages/workspace/src/generators/move/lib/update-jest-config.ts b/packages/workspace/src/generators/move/lib/update-jest-config.ts index c5a76a0a52..8808ebb357 100644 --- a/packages/workspace/src/generators/move/lib/update-jest-config.ts +++ b/packages/workspace/src/generators/move/lib/update-jest-config.ts @@ -68,9 +68,9 @@ export function updateJestConfig( const findProject = `'/${project.root}'`; const oldRootJestConfigContent = tree.read(rootJestConfigPath, 'utf-8'); - const usingJestProjects = - oldRootJestConfigContent.includes('getJestProjects()') || - oldRootJestConfigContent.includes('getJestProjectsAsync()'); + const usingJestProjects = oldRootJestConfigContent.includes( + 'getJestProjectsAsync()' + ); const newRootJestConfigContent = oldRootJestConfigContent.replace( findProject, diff --git a/packages/workspace/src/generators/remove/lib/update-jest-config.ts b/packages/workspace/src/generators/remove/lib/update-jest-config.ts index 8ac17f22b0..45320bd438 100644 --- a/packages/workspace/src/generators/remove/lib/update-jest-config.ts +++ b/packages/workspace/src/generators/remove/lib/update-jest-config.ts @@ -26,10 +26,7 @@ function isUsingUtilityFunction(host: Tree) { const rootConfig = host.read(rootConfigPath, 'utf-8'); - return ( - rootConfig.includes('getJestProjects()') || - rootConfig.includes('getJestProjectsAsync()') - ); + return rootConfig.includes('getJestProjectsAsync()'); } /**