feat(testing): Using getJestProjects() out of the box (#5900)
* feat(testing): updating nx to use getJestProjects() itself * feat(testing): using getJestProjects() for new workspaces * feat(testing): accomodating for getJestConfig() when adding new project * feat(testing): migration for updating the base jest.config.js * testing... * fix(testing): fixing formatting in tests and bumping to next version * fix(testing): fixing broken tests * fix(testing): fixing test for jest init * fix(testing): removing unnecessary test in jest project * fix(testing): updating remove generator to work with jest utility fn * fix(testing): fixing line break on package.json * fix(testing): fixing import statement * fix(testing): using AST to update the jest config contents * fix(testing): fixing snapshot tests * fix(testing): fixing describe to 12.6 * fix(testing): adding back in import statement to jest.config.js * fix(testing): updating generated docs
This commit is contained in:
parent
033579712f
commit
2524fdbc3d
@ -1,32 +1,5 @@
|
|||||||
|
const { getJestProjects } = require('@nrwl/jest');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
projects: [
|
projects: getJestProjects(),
|
||||||
'<rootDir>/packages/tao',
|
|
||||||
'<rootDir>/packages/workspace',
|
|
||||||
'<rootDir>/packages/web',
|
|
||||||
'<rootDir>/packages/cypress',
|
|
||||||
'<rootDir>/packages/jest',
|
|
||||||
'<rootDir>/packages/storybook',
|
|
||||||
'<rootDir>/packages/react',
|
|
||||||
'<rootDir>/packages/nx-plugin',
|
|
||||||
'<rootDir>/packages/node',
|
|
||||||
'<rootDir>/packages/next',
|
|
||||||
'<rootDir>/packages/nest',
|
|
||||||
'<rootDir>/packages/linter',
|
|
||||||
'<rootDir>/packages/express',
|
|
||||||
'<rootDir>/packages/eslint-plugin-nx',
|
|
||||||
'<rootDir>/packages/create-nx-workspace',
|
|
||||||
'<rootDir>/packages/create-nx-plugin',
|
|
||||||
'<rootDir>/packages/cli',
|
|
||||||
'<rootDir>/packages/angular',
|
|
||||||
'<rootDir>/packages/gatsby',
|
|
||||||
'<rootDir>/dep-graph/dep-graph',
|
|
||||||
'<rootDir>/nx-dev/nx-dev',
|
|
||||||
'<rootDir>/nx-dev/ui/common',
|
|
||||||
'<rootDir>/nx-dev/feature-doc-viewer',
|
|
||||||
'<rootDir>/nx-dev/data-access-documents',
|
|
||||||
'<rootDir>/nx-dev/data-access-menu',
|
|
||||||
'<rootDir>/nx-dev/feature-search',
|
|
||||||
'<rootDir>/nx-dev/feature-analytics',
|
|
||||||
'<rootDir>/typedoc-theme',
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -83,6 +83,12 @@
|
|||||||
"cli": "nx",
|
"cli": "nx",
|
||||||
"description": "Support for Jest 27 via updating ts-jest + jest-preset-angular",
|
"description": "Support for Jest 27 via updating ts-jest + jest-preset-angular",
|
||||||
"factory": "./src/migrations/update-12-4-0/update-jest-preset-angular"
|
"factory": "./src/migrations/update-12-4-0/update-jest-preset-angular"
|
||||||
|
},
|
||||||
|
"update-jest-config-to-use-util": {
|
||||||
|
"version": "12.6.0-beta.0",
|
||||||
|
"cli": "nx",
|
||||||
|
"description": "Uses `getJestProjects()` to populate projects array in root level `jest.config.js` file.",
|
||||||
|
"factory": "./src/migrations/update-12-6-0/update-base-jest-config"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
|
|||||||
@ -14,8 +14,10 @@ describe('jest', () => {
|
|||||||
|
|
||||||
expect(tree.exists('jest.config.js')).toBeTruthy();
|
expect(tree.exists('jest.config.js')).toBeTruthy();
|
||||||
expect(tree.read('jest.config.js', 'utf-8')).toMatchInlineSnapshot(`
|
expect(tree.read('jest.config.js', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
"module.exports = {
|
"const { getJestProjects } = require('@nrwl/jest');
|
||||||
projects: []
|
|
||||||
|
module.exports = {
|
||||||
|
projects: getJestProjects()
|
||||||
};"
|
};"
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -39,8 +39,10 @@ function createJestConfig(host: Tree) {
|
|||||||
host.write(
|
host.write(
|
||||||
'jest.config.js',
|
'jest.config.js',
|
||||||
stripIndents`
|
stripIndents`
|
||||||
|
const { getJestProjects } = require('@nrwl/jest');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
projects: []
|
projects: getJestProjects()
|
||||||
};`
|
};`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,16 +83,6 @@ describe('jestProject', () => {
|
|||||||
expect(tree.read('libs/lib1/jest.config.js', 'utf-8')).toMatchSnapshot();
|
expect(tree.read('libs/lib1/jest.config.js', 'utf-8')).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add a project reference in the root jest.config.js', async () => {
|
|
||||||
await jestProjectGenerator(tree, {
|
|
||||||
...defaultOptions,
|
|
||||||
project: 'lib1',
|
|
||||||
} as JestProjectSchema);
|
|
||||||
const jestConfig = jestConfigObject(tree, 'jest.config.js');
|
|
||||||
|
|
||||||
expect(jestConfig.projects).toEqual(['<rootDir>/libs/lib1']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a reference to solution tsconfig.json', async () => {
|
it('should add a reference to solution tsconfig.json', async () => {
|
||||||
await jestProjectGenerator(tree, {
|
await jestProjectGenerator(tree, {
|
||||||
...defaultOptions,
|
...defaultOptions,
|
||||||
|
|||||||
@ -2,7 +2,14 @@ import { JestProjectSchema } from '../schema';
|
|||||||
import { addPropertyToJestConfig } from '../../../utils/config/update-config';
|
import { addPropertyToJestConfig } from '../../../utils/config/update-config';
|
||||||
import { readProjectConfiguration, Tree } from '@nrwl/devkit';
|
import { readProjectConfiguration, Tree } from '@nrwl/devkit';
|
||||||
|
|
||||||
|
function isUsingUtilityFunction(host: Tree) {
|
||||||
|
return host.read('jest.config.js').toString().includes('getJestProjects()');
|
||||||
|
}
|
||||||
|
|
||||||
export function updateJestConfig(host: Tree, options: JestProjectSchema) {
|
export function updateJestConfig(host: Tree, options: JestProjectSchema) {
|
||||||
|
if (isUsingUtilityFunction(host)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const project = readProjectConfiguration(host, options.project);
|
const project = readProjectConfiguration(host, options.project);
|
||||||
addPropertyToJestConfig(
|
addPropertyToJestConfig(
|
||||||
host,
|
host,
|
||||||
|
|||||||
@ -0,0 +1,53 @@
|
|||||||
|
const mockGetJestProjects = jest.fn(() => []);
|
||||||
|
jest.mock('../../utils/config/get-jest-projects', () => ({
|
||||||
|
getJestProjects: mockGetJestProjects,
|
||||||
|
}));
|
||||||
|
const mockResolveConfig = jest.fn(() =>
|
||||||
|
Promise.resolve({ singleQuote: true, endOfLine: 'lf' })
|
||||||
|
);
|
||||||
|
|
||||||
|
import { Tree } from '@nrwl/devkit';
|
||||||
|
import { createTreeWithEmptyWorkspace } from 'packages/devkit/src/tests/create-tree-with-empty-workspace';
|
||||||
|
import update from './update-base-jest-config';
|
||||||
|
|
||||||
|
describe('update 12.6.0', () => {
|
||||||
|
let tree: Tree;
|
||||||
|
beforeEach(() => {
|
||||||
|
tree = createTreeWithEmptyWorkspace();
|
||||||
|
tree.write(
|
||||||
|
'jest.config.js',
|
||||||
|
`module.exports = {
|
||||||
|
projects: ['<rootDir>/test-1']
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const prettier = await import('prettier');
|
||||||
|
prettier.resolveConfig = mockResolveConfig as any;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('all jest projects covered', async () => {
|
||||||
|
mockGetJestProjects.mockImplementation(() => ['<rootDir>/test-1']);
|
||||||
|
await update(tree);
|
||||||
|
const result = tree.read('jest.config.js').toString();
|
||||||
|
expect(result).toMatchInlineSnapshot(`
|
||||||
|
"const { getJestProjects } = require('@nrwl/jest');
|
||||||
|
|
||||||
|
module.exports = { projects: getJestProjects() };
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('some jest projects uncovered', async () => {
|
||||||
|
mockGetJestProjects.mockImplementation(() => ['<rootDir>/test-2']);
|
||||||
|
await update(tree);
|
||||||
|
const result = tree.read('jest.config.js').toString();
|
||||||
|
expect(result).toMatchInlineSnapshot(`
|
||||||
|
"const { getJestProjects } = require('@nrwl/jest');
|
||||||
|
|
||||||
|
module.exports = { projects: [...getJestProjects(), '<rootDir>/test-1'] };
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
import { formatFiles, Tree } from '@nrwl/devkit';
|
||||||
|
import { jestConfigObject } from '../../utils/config/functions';
|
||||||
|
import { getJestProjects } from '../../utils/config/get-jest-projects';
|
||||||
|
import {
|
||||||
|
addImportStatementToJestConfig,
|
||||||
|
addPropertyToJestConfig,
|
||||||
|
removePropertyFromJestConfig,
|
||||||
|
} from '../../utils/config/update-config';
|
||||||
|
|
||||||
|
function determineUncoveredJestProjects(existingProjects: string[]) {
|
||||||
|
const coveredJestProjects = (getJestProjects() as string[]).reduce(
|
||||||
|
(acc, key) => {
|
||||||
|
acc[key] = true;
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
return existingProjects.filter((project) => !coveredJestProjects[project]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function determineProjectsValue(uncoveredJestProjects: string[]): string {
|
||||||
|
if (!uncoveredJestProjects.length) {
|
||||||
|
return `getJestProjects()`;
|
||||||
|
}
|
||||||
|
return `[...getJestProjects(), ${uncoveredJestProjects.map(
|
||||||
|
(projectName) => `'${projectName}', `
|
||||||
|
)}]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateBaseJestConfig(
|
||||||
|
tree: Tree,
|
||||||
|
baseJestConfigPath = 'jest.config.js'
|
||||||
|
) {
|
||||||
|
const currentConfig = jestConfigObject(tree, baseJestConfigPath);
|
||||||
|
const uncoveredJestProjects = determineUncoveredJestProjects(
|
||||||
|
currentConfig.projects as string[]
|
||||||
|
);
|
||||||
|
removePropertyFromJestConfig(tree, baseJestConfigPath, 'projects');
|
||||||
|
addPropertyToJestConfig(
|
||||||
|
tree,
|
||||||
|
baseJestConfigPath,
|
||||||
|
'projects',
|
||||||
|
determineProjectsValue(uncoveredJestProjects),
|
||||||
|
{ valueAsString: true }
|
||||||
|
);
|
||||||
|
addImportStatementToJestConfig(
|
||||||
|
tree,
|
||||||
|
baseJestConfigPath,
|
||||||
|
`const { getJestProjects } = require('@nrwl/jest');`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function update(tree: Tree) {
|
||||||
|
updateBaseJestConfig(tree);
|
||||||
|
await formatFiles(tree);
|
||||||
|
}
|
||||||
@ -11,12 +11,14 @@ import {
|
|||||||
* @param path - path to the jest config file
|
* @param path - path to the jest config file
|
||||||
* @param propertyName - Property to update. Can be dot delimited to access deeply nested properties
|
* @param propertyName - Property to update. Can be dot delimited to access deeply nested properties
|
||||||
* @param value
|
* @param value
|
||||||
|
* @param options - set `valueAsString` option to true if the `value` being passed represents a string of the code that should be associated with the `propertyName`
|
||||||
*/
|
*/
|
||||||
export function addPropertyToJestConfig(
|
export function addPropertyToJestConfig(
|
||||||
host: Tree,
|
host: Tree,
|
||||||
path: string,
|
path: string,
|
||||||
propertyName: string,
|
propertyName: string,
|
||||||
value: unknown
|
value: unknown,
|
||||||
|
options: { valueAsString: boolean } = { valueAsString: false }
|
||||||
) {
|
) {
|
||||||
if (!host.exists(path)) {
|
if (!host.exists(path)) {
|
||||||
throw new Error(`Cannot find '${path}' in your workspace.`);
|
throw new Error(`Cannot find '${path}' in your workspace.`);
|
||||||
@ -28,7 +30,7 @@ export function addPropertyToJestConfig(
|
|||||||
host,
|
host,
|
||||||
configObject,
|
configObject,
|
||||||
properties,
|
properties,
|
||||||
JSON.stringify(value),
|
options.valueAsString ? value : JSON.stringify(value),
|
||||||
path
|
path
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -83,3 +85,15 @@ export function removePropertyFromJestConfig(
|
|||||||
console.log(`Please manually update ${path}`);
|
console.log(`Please manually update ${path}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addImportStatementToJestConfig(
|
||||||
|
host: Tree,
|
||||||
|
path: string,
|
||||||
|
importStatement: string
|
||||||
|
) {
|
||||||
|
const currentContents = host.read(path, 'utf-8');
|
||||||
|
const newContents = `${importStatement}
|
||||||
|
|
||||||
|
${currentContents}`;
|
||||||
|
host.write(path, newContents);
|
||||||
|
}
|
||||||
|
|||||||
@ -143,22 +143,25 @@ describe('lib', () => {
|
|||||||
...defaultOptions,
|
...defaultOptions,
|
||||||
name: 'myLib',
|
name: 'myLib',
|
||||||
});
|
});
|
||||||
|
const expectedRootJestConfig = `
|
||||||
|
"const { getJestProjects } = require('@nrwl/jest');
|
||||||
|
|
||||||
expect(tree.read('jest.config.js', 'utf-8')).toMatchInlineSnapshot(`
|
module.exports = {
|
||||||
"module.exports = {
|
projects: getJestProjects()
|
||||||
projects: [\\"<rootDir>/libs/my-lib\\"]
|
|
||||||
};"
|
};"
|
||||||
`);
|
`;
|
||||||
|
|
||||||
|
expect(tree.read('jest.config.js', 'utf-8')).toMatchInlineSnapshot(
|
||||||
|
expectedRootJestConfig
|
||||||
|
);
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
...defaultOptions,
|
...defaultOptions,
|
||||||
name: 'myLib2',
|
name: 'myLib2',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(tree.read('jest.config.js', 'utf-8')).toMatchInlineSnapshot(`
|
expect(tree.read('jest.config.js', 'utf-8')).toMatchInlineSnapshot(
|
||||||
"module.exports = {
|
expectedRootJestConfig
|
||||||
projects: [\\"<rootDir>/libs/my-lib\\",\\"<rootDir>/libs/my-lib2\\"]
|
);
|
||||||
};"
|
|
||||||
`);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -66,8 +66,7 @@ describe('updateJestConfig', () => {
|
|||||||
`coverageDirectory: '../../coverage/libs/my-destination'`
|
`coverageDirectory: '../../coverage/libs/my-destination'`
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(rootJestConfigAfter).not.toContain('<rootDir>/libs/my-source');
|
expect(rootJestConfigAfter).toContain('getJestProjects()');
|
||||||
expect(rootJestConfigAfter).toContain('<rootDir>/libs/my-destination');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update jest configs properly even if project is in many layers of subfolders', async () => {
|
it('should update jest configs properly even if project is in many layers of subfolders', async () => {
|
||||||
|
|||||||
@ -19,6 +19,10 @@ import {
|
|||||||
} from 'typescript';
|
} from 'typescript';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
|
function isUsingUtilityFunction(host: Tree) {
|
||||||
|
return host.read('jest.config.js').toString().includes('getJestProjects()');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the root jest config projects array and removes the project.
|
* Updates the root jest config projects array and removes the project.
|
||||||
*/
|
*/
|
||||||
@ -31,7 +35,8 @@ export function updateJestConfig(
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
!tree.exists('jest.config.js') ||
|
!tree.exists('jest.config.js') ||
|
||||||
!tree.exists(join(projectConfig.root, 'jest.config.js'))
|
!tree.exists(join(projectConfig.root, 'jest.config.js')) ||
|
||||||
|
isUsingUtilityFunction(tree)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user