Skip to content

Commit

Permalink
chore(testing): add deprecated comment for getJestProjects (#28178)
Browse files Browse the repository at this point in the history
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
  • Loading branch information
xiongemi authored Oct 2, 2024
1 parent a637f9e commit 10fb324
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 2 deletions.
6 changes: 6 additions & 0 deletions packages/jest/migrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
"version": "17.1.0-beta.2",
"description": "Move jest executor options to nx.json targetDefaults",
"implementation": "./src/migrations/update-17-1-0/move-options-to-target-defaults"
},
"replace-getJestProjects-with-getJestProjectsAsync": {
"cli": "nx",
"version": "20.0.0-beta.5",
"description": "replace getJestProjects with getJestProjectsAsync",
"implementation": "./src/migrations/update-20-0-0/replace-getJestProjects-with-getJestProjectsAsync"
}
},
"packageJsonUpdates": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
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', 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');
export default async () => ({
projects: await getJestProjectsAsync(),
});
"
`);
});

it('should replace getJestProjects with getJestProjectsAsync with additonal 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');
export default async () => ({
projects: await getJestProjectsAsync(),
filename: __filename,
env: process.env,
dirname: __dirname
});
"
`);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// 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 } 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 the import statement for @nx/jest
const importStatement = 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'
)
);
if (importStatement) {
// find export statement with `projects: getJestProjects()`
let exportStatement = 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 (exportStatement) {
// replace getJestProjects with getJestProjectsAsync in export statement
const rightExpression = (
exportStatement.expression as BinaryExpression
).right.getText();
const newExpression = rightExpression.replace(
'getJestProjects()',
'await getJestProjectsAsync()'
);
const newStatement = `export default async () => (${newExpression});`;
let newContent = oldContent.replace(
exportStatement.getText(),
newStatement
);

// replace getJestProjects with getJestProjectsAsync in import statement
newContent = newContent.replace(
'getJestProjects',
'getJestProjectsAsync'
);

tree.write(jestConfigPath, newContent);
}
}
}
});
}
2 changes: 2 additions & 0 deletions packages/jest/src/utils/config/get-jest-projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ function getJestConfigProjectPath(projectJestConfigPath: string): string {
}

/**
* 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.
*
Expand Down
4 changes: 2 additions & 2 deletions packages/nx/src/project-graph/file-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ function defaultReadFileAtRevision(
}

/**
* TODO(v20): Remove this function
* @deprecated To get projects use {@link retrieveProjectConfigurations} instead. This will be removed in v20.
* TODO(v21): Remove this function
* @deprecated To get projects use {@link retrieveProjectConfigurations} instead. This will be removed in v21.
*/
export function readWorkspaceConfig(opts: {
format: 'angularCli' | 'nx';
Expand Down

0 comments on commit 10fb324

Please sign in to comment.