fix(testing): update v14 migration and migrate jest.config.ts to use export default (#10035)
* fix(testing): jest.preset.ts => jest.preset.js * fix(testing): update to export default * fix(testing): migration for moving to export default * fix(testing): add eslint ignore comments for jest config properties fixes: #10021 * fix(testing): update tsconfig.spec.json for next apps with project parserOptions fixes: #9982 * fix(testing): prevent renaming root jest preset fixes: #9973 * fix(testing): update snapshots for export default * fix(testing): bump migration version to run * fix(testing): make sure default jest tests pass for various projects * fix(js): generate correct jest config for --compiler=swc --js
This commit is contained in:
parent
4dbd6559cf
commit
ecf88a6995
@ -5,21 +5,17 @@ import {
|
||||
runCLIAsync,
|
||||
uniq,
|
||||
updateFile,
|
||||
expectJestTestsToPass,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
describe('Jest', () => {
|
||||
beforeAll(() => {
|
||||
newProject({ name: uniq('proj') });
|
||||
newProject({ name: uniq('proj-jest') });
|
||||
});
|
||||
|
||||
it('should be able test projects using jest', async () => {
|
||||
const mylib = uniq('mylib');
|
||||
runCLI(`generate @nrwl/workspace:lib ${mylib} --unit-test-runner jest`);
|
||||
|
||||
const libResult = await runCLIAsync(`test ${mylib}`);
|
||||
expect(libResult.combinedOutput).toContain(
|
||||
'Test Suites: 1 passed, 1 total'
|
||||
);
|
||||
await expectJestTestsToPass('@nrwl/workspace:lib');
|
||||
await expectJestTestsToPass('@nrwl/js:lib');
|
||||
}, 500000);
|
||||
|
||||
it('should merge with jest config globals', async () => {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {
|
||||
checkFilesExist,
|
||||
expectJestTestsToPass,
|
||||
checkFilesDoNotExist,
|
||||
newProject,
|
||||
readFile,
|
||||
@ -242,4 +243,8 @@ describe('js e2e', () => {
|
||||
|
||||
checkFilesDoNotExist(`libs/${lib}/.babelrc`);
|
||||
});
|
||||
|
||||
it('should run default jest tests', async () => {
|
||||
await expectJestTestsToPass('@nrwl/js:lib');
|
||||
});
|
||||
});
|
||||
|
||||
@ -3,6 +3,7 @@ import {
|
||||
checkFilesExist,
|
||||
cleanupProject,
|
||||
createFile,
|
||||
expectJestTestsToPass,
|
||||
isNotWindows,
|
||||
killPorts,
|
||||
newProject,
|
||||
@ -409,6 +410,9 @@ describe('Next.js Applications', () => {
|
||||
checkExport: false,
|
||||
});
|
||||
}, 300000);
|
||||
it('should run default jest tests', async () => {
|
||||
await expectJestTestsToPass('@nrwl/next:app');
|
||||
});
|
||||
});
|
||||
|
||||
function getData(port: number, path = ''): Promise<any> {
|
||||
|
||||
@ -2,6 +2,7 @@ import { stripIndents } from '@angular-devkit/core/src/utils/literals';
|
||||
import {
|
||||
checkFilesDoNotExist,
|
||||
checkFilesExist,
|
||||
expectJestTestsToPass,
|
||||
killPorts,
|
||||
newProject,
|
||||
packageInstall,
|
||||
@ -359,9 +360,10 @@ describe('nest libraries', function () {
|
||||
const jestConfigContent = readFile(`libs/${nestlib}/jest.config.ts`);
|
||||
|
||||
expect(stripIndents`${jestConfigContent}`).toEqual(
|
||||
stripIndents`module.exports = {
|
||||
stripIndents`/* eslint-disable */
|
||||
export default {
|
||||
displayName: '${nestlib}',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
@ -481,4 +483,8 @@ exports.FooModel = FooModel;
|
||||
checkFilesDoNotExist('workspace.json', 'angular.json')
|
||||
).not.toThrow();
|
||||
}, 1000000);
|
||||
|
||||
it('should run default jest tests', async () => {
|
||||
await expectJestTestsToPass('@nrwl/node:lib');
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,6 +2,7 @@ import {
|
||||
checkFilesDoNotExist,
|
||||
checkFilesExist,
|
||||
createFile,
|
||||
expectJestTestsToPass,
|
||||
killPorts,
|
||||
newProject,
|
||||
readFile,
|
||||
@ -289,4 +290,9 @@ describe('React Applications and Libs with PostCSS', () => {
|
||||
expect(buildResults.combinedOutput).toMatch(/HELLO FROM APP/);
|
||||
expect(buildResults.combinedOutput).not.toMatch(/HELLO FROM LIB/);
|
||||
}, 250_000);
|
||||
|
||||
it('should run default jest tests', async () => {
|
||||
await expectJestTestsToPass('@nrwl/react:lib');
|
||||
await expectJestTestsToPass('@nrwl/react:app');
|
||||
});
|
||||
});
|
||||
|
||||
@ -881,3 +881,30 @@ export function waitUntil(
|
||||
}, opts.timeout);
|
||||
});
|
||||
}
|
||||
|
||||
type GeneratorsWithDefaultTests =
|
||||
| '@nrwl/js:lib'
|
||||
| '@nrwl/node:lib'
|
||||
| '@nrwl/react:lib'
|
||||
| '@nrwl/react:app'
|
||||
| '@nrwl/next:app'
|
||||
| '@nrwl/angular:app'
|
||||
| '@nrwl/workspace:lib'
|
||||
| '@nrwl/web:app';
|
||||
|
||||
/**
|
||||
* Runs the pass in generator and then runs test on
|
||||
* the generated project to make sure the default tests pass.
|
||||
*/
|
||||
export async function expectJestTestsToPass(
|
||||
generator: GeneratorsWithDefaultTests | string
|
||||
) {
|
||||
const name = uniq('proj');
|
||||
const generatedResults = runCLI(
|
||||
`generate ${generator} ${name} --no-interactive`
|
||||
);
|
||||
expect(generatedResults).toContain(`jest.config.ts`);
|
||||
|
||||
const results = await runCLIAsync(`test ${name}`);
|
||||
expect(results.combinedOutput).toContain('Test Suites: 1 passed, 1 total');
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ import {
|
||||
uniq,
|
||||
updateFile,
|
||||
updateProjectConfig,
|
||||
expectJestTestsToPass,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
describe('Web Components Applications', () => {
|
||||
@ -186,6 +187,10 @@ describe('Web Components Applications', () => {
|
||||
checkFilesDoNotExist('workspace.json', 'angular.json')
|
||||
).not.toThrow();
|
||||
}, 1000000);
|
||||
|
||||
it('should run default jest tests', async () => {
|
||||
await expectJestTestsToPass('@nrwl/web:app');
|
||||
});
|
||||
});
|
||||
|
||||
describe('CLI - Environment Variables', () => {
|
||||
|
||||
@ -262,7 +262,7 @@ describe('move project', () => {
|
||||
checkFilesExist(jestConfigPath);
|
||||
const jestConfig = readFile(jestConfigPath);
|
||||
expect(jestConfig).toContain(`displayName: 'shared-${lib1}-data-access'`);
|
||||
expect(jestConfig).toContain(`preset: '../../../../jest.preset.ts'`);
|
||||
expect(jestConfig).toContain(`preset: '../../../../jest.preset.js'`);
|
||||
expect(jestConfig).toContain(`'../../../../coverage/${newPath}'`);
|
||||
|
||||
const tsConfigPath = `${newPath}/tsconfig.json`;
|
||||
@ -399,7 +399,7 @@ describe('move project', () => {
|
||||
checkFilesExist(jestConfigPath);
|
||||
const jestConfig = readFile(jestConfigPath);
|
||||
expect(jestConfig).toContain(`displayName: 'shared-${lib1}-data-access'`);
|
||||
expect(jestConfig).toContain(`preset: '../../../../jest.preset.ts'`);
|
||||
expect(jestConfig).toContain(`preset: '../../../../jest.preset.js'`);
|
||||
expect(jestConfig).toContain(`'../../../../coverage/${newPath}'`);
|
||||
|
||||
const tsConfigPath = `${newPath}/tsconfig.json`;
|
||||
@ -531,7 +531,7 @@ describe('move project', () => {
|
||||
checkFilesExist(jestConfigPath);
|
||||
const jestConfig = readFile(jestConfigPath);
|
||||
expect(jestConfig).toContain(`displayName: 'shared-${lib1}-data-access'`);
|
||||
expect(jestConfig).toContain(`preset: '../../../../jest.preset.ts'`);
|
||||
expect(jestConfig).toContain(`preset: '../../../../jest.preset.js'`);
|
||||
expect(jestConfig).toContain(`'../../../../coverage/${newPath}'`);
|
||||
|
||||
const tsConfigPath = `${newPath}/tsconfig.json`;
|
||||
|
||||
@ -7,6 +7,7 @@ import {
|
||||
runCLIAsync,
|
||||
uniq,
|
||||
updateFile,
|
||||
expectJestTestsToPass,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
let proj: string;
|
||||
@ -44,15 +45,8 @@ describe('@nrwl/workspace:library', () => {
|
||||
});
|
||||
|
||||
describe('unit testing', () => {
|
||||
it('should support jest', async () => {
|
||||
const libName = uniq('mylib');
|
||||
|
||||
runCLI(`generate @nrwl/workspace:lib ${libName}`);
|
||||
|
||||
const { stderr: result } = await runCLIAsync(`test ${libName}`);
|
||||
|
||||
expect(result).toContain(`Test Suites: 1 passed, 1 total`);
|
||||
expect(result).toContain('Tests: 1 passed, 1 total');
|
||||
it('should run default jest tests', async () => {
|
||||
await expectJestTestsToPass('@nrwl/workspace:lib');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -55,7 +55,7 @@ Array [
|
||||
"apps/one/two/test-ui-lib-e2e/src/support/index.ts",
|
||||
"apps/one/two/test-ui-lib-e2e/tsconfig.json",
|
||||
"jest.config.ts",
|
||||
"jest.preset.ts",
|
||||
"jest.preset.js",
|
||||
"libs/test-ui-lib/.eslintrc.json",
|
||||
"libs/test-ui-lib/.storybook/main.js",
|
||||
"libs/test-ui-lib/.storybook/preview.js",
|
||||
@ -160,7 +160,7 @@ Array [
|
||||
"apps/test-ui-lib-e2e/src/support/index.ts",
|
||||
"apps/test-ui-lib-e2e/tsconfig.json",
|
||||
"jest.config.ts",
|
||||
"jest.preset.ts",
|
||||
"jest.preset.js",
|
||||
"libs/test-ui-lib/.eslintrc.json",
|
||||
"libs/test-ui-lib/.storybook/main.js",
|
||||
"libs/test-ui-lib/.storybook/preview.js",
|
||||
|
||||
@ -47,6 +47,12 @@
|
||||
"cli": "nx",
|
||||
"description": "Update move jest config files to .ts files.",
|
||||
"factory": "./src/migrations/update-14-0-0/update-jest-config-ext"
|
||||
},
|
||||
"update-to-export-default": {
|
||||
"version": "14.1.5-beta.0",
|
||||
"cli": "nx",
|
||||
"description": "Update to export default in jest config and revert jest.preset.ts to jest.preset.js",
|
||||
"factory": "./src/migrations/update-14-1-5/update-exports-jest-config"
|
||||
}
|
||||
},
|
||||
"packageJsonUpdates": {
|
||||
|
||||
@ -1 +1,3 @@
|
||||
export = require('./jest-preset');
|
||||
import { nxPreset } from './jest-preset';
|
||||
|
||||
export default nxPreset;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export = {
|
||||
export const nxPreset = {
|
||||
testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
|
||||
resolver: '@nrwl/jest/plugins/resolver',
|
||||
moduleFileExtensions: ['ts', 'js', 'mjs', 'html'],
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`jest should generate files 1`] = `
|
||||
"import { getJestProjects } from '@nrwl/jest';
|
||||
|
||||
export default {
|
||||
projects: getJestProjects()
|
||||
};"
|
||||
`;
|
||||
|
||||
exports[`jest should generate files 2`] = `
|
||||
"const nxPreset = require('@nrwl/jest/preset').default;
|
||||
|
||||
module.exports = { ...nxPreset }"
|
||||
`;
|
||||
|
||||
exports[`jest should generate files with --js flag 1`] = `
|
||||
"const { getJestProjects } = require('@nrwl/jest');
|
||||
|
||||
module.exports = {
|
||||
projects: getJestProjects()
|
||||
};"
|
||||
`;
|
||||
|
||||
exports[`jest should generate files with --js flag 2`] = `
|
||||
"const nxPreset = require('@nrwl/jest/preset').default;
|
||||
|
||||
module.exports = { ...nxPreset }"
|
||||
`;
|
||||
@ -1,4 +1,4 @@
|
||||
import { readJson, Tree, writeJson } from '@nrwl/devkit';
|
||||
import { readJson, stripIndents, Tree, writeJson } from '@nrwl/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||
import { jestInitGenerator } from './init';
|
||||
|
||||
@ -9,17 +9,28 @@ describe('jest', () => {
|
||||
tree = createTreeWithEmptyWorkspace();
|
||||
});
|
||||
|
||||
it('should generate files', async () => {
|
||||
it('should generate files with --js flag', async () => {
|
||||
jestInitGenerator(tree, { js: true });
|
||||
|
||||
expect(tree.exists('jest.config.js')).toBeTruthy();
|
||||
expect(
|
||||
stripIndents`${tree.read('jest.config.js', 'utf-8')}`
|
||||
).toMatchSnapshot();
|
||||
expect(
|
||||
stripIndents`${tree.read('jest.preset.js', 'utf-8')}`
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate files ', async () => {
|
||||
jestInitGenerator(tree, {});
|
||||
|
||||
expect(tree.exists('jest.config.ts')).toBeTruthy();
|
||||
expect(tree.read('jest.config.ts', 'utf-8')).toMatchInlineSnapshot(`
|
||||
"const { getJestProjects } = require('@nrwl/jest');
|
||||
|
||||
module.exports = {
|
||||
projects: getJestProjects()
|
||||
};"
|
||||
`);
|
||||
expect(
|
||||
stripIndents`${tree.read('jest.config.ts', 'utf-8')}`
|
||||
).toMatchSnapshot();
|
||||
expect(
|
||||
stripIndents`${tree.read('jest.preset.js', 'utf-8')}`
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should not override existing files', async () => {
|
||||
|
||||
@ -29,22 +29,28 @@ const schemaDefaults = {
|
||||
function createJestConfig(host: Tree, js: boolean = false) {
|
||||
// if the root ts config already exists then don't make a js one or vice versa
|
||||
if (!host.exists('jest.config.ts') && !host.exists('jest.config.js')) {
|
||||
host.write(
|
||||
`jest.config.${js ? 'js' : 'ts'}`,
|
||||
stripIndents`
|
||||
const { getJestProjects } = require('@nrwl/jest');
|
||||
const contents = js
|
||||
? stripIndents`
|
||||
const { getJestProjects } = require('@nrwl/jest');
|
||||
|
||||
module.exports = {
|
||||
projects: getJestProjects()
|
||||
};`
|
||||
);
|
||||
module.exports = {
|
||||
projects: getJestProjects()
|
||||
};`
|
||||
: stripIndents`
|
||||
import { getJestProjects } from '@nrwl/jest';
|
||||
|
||||
export default {
|
||||
projects: getJestProjects()
|
||||
};`;
|
||||
host.write(`jest.config.${js ? 'js' : 'ts'}`, contents);
|
||||
}
|
||||
|
||||
if (!host.exists('jest.preset.ts') && !host.exists('jest.preset.js')) {
|
||||
if (!host.exists('jest.preset.js')) {
|
||||
// preset is always js file.
|
||||
host.write(
|
||||
`jest.preset.${js ? 'js' : 'ts'}`,
|
||||
`jest.preset.js`,
|
||||
`
|
||||
const nxPreset = require('@nrwl/jest/preset');
|
||||
const nxPreset = require('@nrwl/jest/preset').default;
|
||||
|
||||
module.exports = { ...nxPreset }`
|
||||
);
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`jestProject --babelJest should generate proper jest.transform when --compiler=swc and supportTsx is true 1`] = `
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'lib1',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
transform: {
|
||||
'^.+\\\\\\\\.[tj]sx?$': ['@swc/jest', { jsc: { transform: { react: { runtime: 'automatic' } } } }]
|
||||
},
|
||||
@ -14,9 +15,10 @@ exports[`jestProject --babelJest should generate proper jest.transform when --co
|
||||
`;
|
||||
|
||||
exports[`jestProject --babelJest should generate proper jest.transform when babelJest and supportTsx is true 1`] = `
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'lib1',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
transform: {
|
||||
'^.+\\\\\\\\.[tj]sx?$': 'babel-jest'
|
||||
},
|
||||
@ -27,9 +29,10 @@ exports[`jestProject --babelJest should generate proper jest.transform when babe
|
||||
`;
|
||||
|
||||
exports[`jestProject --babelJest should generate proper jest.transform when babelJest is true 1`] = `
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'lib1',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
transform: {
|
||||
'^.+\\\\\\\\.[tj]s$': 'babel-jest'
|
||||
},
|
||||
@ -40,9 +43,10 @@ exports[`jestProject --babelJest should generate proper jest.transform when babe
|
||||
`;
|
||||
|
||||
exports[`jestProject --setup-file should have setupFilesAfterEnv and globals.ts-jest in the jest.config when generated for angular 1`] = `
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'lib1',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
@ -65,9 +69,10 @@ exports[`jestProject --setup-file should have setupFilesAfterEnv and globals.ts-
|
||||
`;
|
||||
|
||||
exports[`jestProject should create a jest.config.ts 1`] = `
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'lib1',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
@ -78,6 +83,32 @@ exports[`jestProject should create a jest.config.ts 1`] = `
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`jestProject should generate files 1`] = `
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'lib1',
|
||||
preset: '../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
stringifyContentPathRegex: '\\\\\\\\.(html|svg)$',
|
||||
}
|
||||
},
|
||||
coverageDirectory: '../../coverage/libs/lib1',
|
||||
transform: {
|
||||
'^.+\\\\\\\\.(ts|mjs|js|html)$': 'jest-preset-angular'
|
||||
},
|
||||
transformIgnorePatterns: ['node_modules/(?!.*\\\\\\\\.mjs$)'],
|
||||
snapshotSerializers: [
|
||||
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||
'jest-preset-angular/build/serializers/html-comment',
|
||||
]
|
||||
};
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`jestProject should use jest.config.js in project config with --js flag 1`] = `
|
||||
Object {
|
||||
"executor": "@nrwl/jest:jest",
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
module.exports = {
|
||||
/* eslint-disable */
|
||||
<% if(js){ %>module.exports =<% } else{ %>export default<% } %> {
|
||||
displayName: '<%= project %>',
|
||||
preset: '<%= offsetFromRoot %>jest.preset.ts',
|
||||
preset: '<%= offsetFromRoot %>jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
module.exports = {
|
||||
/* eslint-disable */
|
||||
<% if(js){ %>module.exports =<% } else{ %>export default<% } %> {
|
||||
displayName: '<%= project %>',
|
||||
preset: '<%= offsetFromRoot %>jest.preset<%= ext %>',<% if(setupFile !== 'none') { %>
|
||||
preset: '<%= offsetFromRoot %>jest.preset.js',<% if(setupFile !== 'none') { %>
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],<% } %><% if (transformer === 'ts-jest') { %>
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
|
||||
@ -53,6 +53,7 @@ describe('jestProject', () => {
|
||||
expect(tree.exists('libs/lib1/src/test-setup.ts')).toBeTruthy();
|
||||
expect(tree.exists('libs/lib1/jest.config.ts')).toBeTruthy();
|
||||
expect(tree.exists('libs/lib1/tsconfig.spec.json')).toBeTruthy();
|
||||
expect(tree.read('libs/lib1/jest.config.ts', 'utf-8')).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate files w/babel-jest', async () => {
|
||||
@ -284,7 +285,7 @@ describe('jestProject', () => {
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should use the jest.preset.ts when preset with --js', async () => {
|
||||
it('should always use jest.preset.js with --js', async () => {
|
||||
tree.write('jest.preset.ts', '');
|
||||
await jestProjectGenerator(tree, {
|
||||
...defaultOptions,
|
||||
@ -293,7 +294,19 @@ describe('jestProject', () => {
|
||||
} as JestProjectSchema);
|
||||
expect(tree.exists('libs/lib1/jest.config.js')).toBeTruthy();
|
||||
expect(tree.read('libs/lib1/jest.config.js', 'utf-8')).toContain(
|
||||
"preset: '../../jest.preset.ts',"
|
||||
"preset: '../../jest.preset.js',"
|
||||
);
|
||||
});
|
||||
|
||||
it('should use module.exports with --js flag', async () => {
|
||||
await jestProjectGenerator(tree, {
|
||||
...defaultOptions,
|
||||
project: 'lib1',
|
||||
js: true,
|
||||
} as JestProjectSchema);
|
||||
expect(tree.exists('libs/lib1/jest.config.js')).toBeTruthy();
|
||||
expect(tree.read('libs/lib1/jest.config.js', 'utf-8')).toContain(
|
||||
'module.exports = {'
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@ -4,7 +4,6 @@ import {
|
||||
readProjectConfiguration,
|
||||
Tree,
|
||||
} from '@nrwl/devkit';
|
||||
import { findRootJestPreset } from '../../../utils/config/find-root-jest-files';
|
||||
import { join } from 'path';
|
||||
import { JestProjectSchema } from '../schema';
|
||||
|
||||
@ -27,7 +26,7 @@ export function createFiles(tree: Tree, options: JestProjectSchema) {
|
||||
tmpl: '',
|
||||
...options,
|
||||
transformer,
|
||||
ext: findRootJestPreset(tree) === 'jest.preset.js' ? '.js' : '.ts',
|
||||
js: !!options.js,
|
||||
projectRoot: projectConfig.root,
|
||||
offsetFromRoot: offsetFromRoot(projectConfig.root),
|
||||
});
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Jest Migration (v14.0.0) should rename project jest.config.js to jest.config.ts 1`] = `
|
||||
"module.exports = {
|
||||
exports[`Jest Migration (v14.0.0) should NOT update jest.config.ts preset 1`] = `
|
||||
"/* eslint-disable */
|
||||
|
||||
module.exports = {
|
||||
displayName: 'lib-one',
|
||||
|
||||
preset: '../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
@ -13,15 +15,17 @@ exports[`Jest Migration (v14.0.0) should rename project jest.config.js to jest.c
|
||||
'^.+\\\\\\\\.[tj]sx?$': 'ts-jest'
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||
coverageDirectory: '../../coverage/libs/lib-one',\\"preset\\": \\"../../jest.preset.ts\\"
|
||||
coverageDirectory: '../../coverage/libs/lib-one'
|
||||
};
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`Jest Migration (v14.0.0) should update jest.config.ts preset to use the jest.preset.ts 1`] = `
|
||||
"module.exports = {
|
||||
exports[`Jest Migration (v14.0.0) should rename project jest.config.js to jest.config.ts 1`] = `
|
||||
"/* eslint-disable */
|
||||
|
||||
module.exports = {
|
||||
displayName: 'lib-one',
|
||||
|
||||
preset: '../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
@ -31,7 +35,24 @@ exports[`Jest Migration (v14.0.0) should update jest.config.ts preset to use the
|
||||
'^.+\\\\\\\\.[tj]sx?$': 'ts-jest'
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||
coverageDirectory: '../../coverage/libs/lib-one',\\"preset\\": \\"../../jest.preset.ts\\"
|
||||
coverageDirectory: '../../coverage/libs/lib-one'
|
||||
};
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`Jest Migration (v14.0.0) should update the excludes of next js apps using the project parser settings 1`] = `
|
||||
Object {
|
||||
"files": Array [
|
||||
"*.ts",
|
||||
"*.tsx",
|
||||
"*.js",
|
||||
"*.jsx",
|
||||
],
|
||||
"parserOptions": Object {
|
||||
"project": Array [
|
||||
"libs/lib-one/tsconfig.*?.json",
|
||||
],
|
||||
},
|
||||
"rules": Object {},
|
||||
}
|
||||
`;
|
||||
|
||||
@ -7,48 +7,80 @@ import {
|
||||
} from '@nrwl/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||
import { jestInitGenerator } from '@nrwl/jest';
|
||||
import { updateJestConfigExt } from './update-jest-config-ext';
|
||||
import { libraryGenerator as workspaceLib } from '@nrwl/workspace';
|
||||
import { updateJestConfigExt } from './update-jest-config-ext';
|
||||
|
||||
const setupDefaults = {
|
||||
js: true,
|
||||
skipPackageJson: true,
|
||||
libName: 'lib-one',
|
||||
setParserOptionsProject: false,
|
||||
};
|
||||
|
||||
async function libSetUp(tree: Tree, options = setupDefaults) {
|
||||
jestInitGenerator(tree, {
|
||||
js: options.js,
|
||||
skipPackageJson: options.skipPackageJson,
|
||||
});
|
||||
await workspaceLib(tree, {
|
||||
name: options.libName,
|
||||
setParserOptionsProject: options.setParserOptionsProject,
|
||||
});
|
||||
tree.rename(
|
||||
`libs/${options.libName}/jest.config.ts`,
|
||||
`libs/${options.libName}/jest.config.js`
|
||||
);
|
||||
const config = tree.read(`libs/${options.libName}/jest.config.js`, 'utf-8');
|
||||
tree.write(
|
||||
`libs/${options.libName}/jest.config.js`,
|
||||
config
|
||||
.replace(/\/\* eslint-disable \*\//g, '')
|
||||
.replace(/export default/g, 'module.exports =')
|
||||
);
|
||||
updateProjectConfiguration(tree, options.libName, {
|
||||
...readProjectConfiguration(tree, options.libName),
|
||||
targets: {
|
||||
test: {
|
||||
executor: '@nrwl/jest:jest',
|
||||
options: {
|
||||
jestConfig: `libs/${options.libName}/jest.config.js`,
|
||||
passWithNoTests: true,
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
silent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
describe('Jest Migration (v14.0.0)', () => {
|
||||
let tree: Tree;
|
||||
beforeEach(async () => {
|
||||
tree = createTreeWithEmptyWorkspace(2);
|
||||
jestInitGenerator(tree, { js: true, skipPackageJson: true });
|
||||
await workspaceLib(tree, { name: 'lib-one' });
|
||||
tree.rename('libs/lib-one/jest.config.ts', 'libs/lib-one/jest.config.js');
|
||||
updateProjectConfiguration(tree, 'lib-one', {
|
||||
...readProjectConfiguration(tree, 'lib-one'),
|
||||
targets: {
|
||||
test: {
|
||||
executor: '@nrwl/jest:jest',
|
||||
options: {
|
||||
jestConfig: 'libs/lib-one/jest.config.js',
|
||||
passWithNoTests: true,
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
silent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should rename project jest.config.js to jest.config.ts', async () => {
|
||||
await libSetUp(tree);
|
||||
|
||||
await updateJestConfigExt(tree);
|
||||
expect(tree.exists('libs/lib-one/jest.config.ts')).toBeTruthy();
|
||||
expect(tree.read('libs/lib-one/jest.config.ts', 'utf-8')).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should rename root jest files', async () => {
|
||||
it('should rename root jest.config.js', async () => {
|
||||
await libSetUp(tree);
|
||||
|
||||
await updateJestConfigExt(tree);
|
||||
expect(tree.exists('jest.config.ts')).toBeTruthy();
|
||||
expect(tree.exists('jest.preset.ts')).toBeTruthy();
|
||||
expect(tree.exists('jest.preset.js')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should update jest.config.ts preset to use the jest.preset.ts', async () => {
|
||||
it('should NOT update jest.config.ts preset', async () => {
|
||||
await libSetUp(tree);
|
||||
|
||||
tree.rename('libs/lib-one/jest.config.js', 'libs/lib-one/jest.config.ts');
|
||||
const projectConfig = readProjectConfiguration(tree, 'lib-one');
|
||||
updateProjectConfiguration(tree, 'lib-one', {
|
||||
@ -70,6 +102,8 @@ describe('Jest Migration (v14.0.0)', () => {
|
||||
});
|
||||
|
||||
it('should only update js/ts files', async () => {
|
||||
await libSetUp(tree);
|
||||
|
||||
tree.rename('libs/lib-one/jest.config.js', 'libs/lib-one/jest.config.ts');
|
||||
updateProjectConfiguration(tree, 'lib-one', {
|
||||
...readProjectConfiguration(tree, 'lib-one'),
|
||||
@ -84,7 +118,7 @@ describe('Jest Migration (v14.0.0)', () => {
|
||||
},
|
||||
});
|
||||
|
||||
await workspaceLib(tree, { name: 'lib-two' });
|
||||
await libSetUp(tree, { ...setupDefaults, libName: 'lib-two' });
|
||||
tree.delete('libs/lib-two/jest.config.ts'); // lib generator creates a ts file
|
||||
tree.write('libs/lib-two/jest.config.json', '{}');
|
||||
updateProjectConfiguration(tree, 'lib-two', {
|
||||
@ -99,8 +133,8 @@ describe('Jest Migration (v14.0.0)', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
await workspaceLib(tree, { name: 'lib-three' });
|
||||
|
||||
await libSetUp(tree, { ...setupDefaults, libName: 'lib-three' });
|
||||
expect(tree.exists('libs/lib-one/jest.config.ts')).toBeTruthy();
|
||||
await updateJestConfigExt(tree);
|
||||
expect(tree.exists('libs/lib-one/jest.config.ts')).toBeTruthy();
|
||||
@ -110,6 +144,8 @@ describe('Jest Migration (v14.0.0)', () => {
|
||||
});
|
||||
|
||||
it('should not throw error if file does not exit', async () => {
|
||||
await libSetUp(tree);
|
||||
|
||||
tree.delete('libs/lib-one/jest.config.js');
|
||||
await updateJestConfigExt(tree);
|
||||
expect(tree.exists('libs/lib-one/jest.config.ts')).toBeFalsy();
|
||||
@ -117,6 +153,8 @@ describe('Jest Migration (v14.0.0)', () => {
|
||||
});
|
||||
|
||||
it('should update correct tsconfigs', async () => {
|
||||
await libSetUp(tree);
|
||||
|
||||
updateJson(tree, 'libs/lib-one/tsconfig.lib.json', (json) => {
|
||||
json.exclude = ['**/*.spec.ts'];
|
||||
return json;
|
||||
@ -140,6 +178,8 @@ describe('Jest Migration (v14.0.0)', () => {
|
||||
});
|
||||
|
||||
it('should add exclude to root tsconfig with no references', async () => {
|
||||
await libSetUp(tree);
|
||||
|
||||
tree.delete('libs/lib-one/tsconfig.spec.json');
|
||||
tree.delete('libs/lib-one/tsconfig.lib.json');
|
||||
|
||||
@ -156,4 +196,28 @@ describe('Jest Migration (v14.0.0)', () => {
|
||||
expect(tree.exists('libs/lib-one/tsconfig.spec.json')).toBeFalsy();
|
||||
expect(tree.exists('libs/lib-one/tsconfig.lib.json')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should update the excludes of next js apps using the project parser settings', async () => {
|
||||
await libSetUp(tree, { ...setupDefaults, setParserOptionsProject: true });
|
||||
|
||||
const projectConfig = readProjectConfiguration(tree, 'lib-one');
|
||||
projectConfig.targets['build'] = {
|
||||
executor: '@nrwl/next:build',
|
||||
options: {},
|
||||
};
|
||||
updateProjectConfiguration(tree, 'lib-one', projectConfig);
|
||||
updateJson(tree, 'libs/lib-one/tsconfig.json', (json) => {
|
||||
// simulate nextJS tsconfig;
|
||||
json.exclude = ['node_modules'];
|
||||
return json;
|
||||
});
|
||||
const esLintJson = readJson(tree, 'libs/lib-one/.eslintrc.json');
|
||||
// make sure the parserOptions are set correctly
|
||||
expect(esLintJson.overrides[0]).toMatchSnapshot();
|
||||
|
||||
await updateJestConfigExt(tree);
|
||||
|
||||
const tsconfigSpec = readJson(tree, 'libs/lib-one/tsconfig.spec.json');
|
||||
expect(tsconfigSpec.exclude).toEqual(['node_modules']);
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,7 +2,6 @@ import {
|
||||
formatFiles,
|
||||
joinPathFragments,
|
||||
logger,
|
||||
offsetFromRoot,
|
||||
ProjectConfiguration,
|
||||
readJson,
|
||||
readProjectConfiguration,
|
||||
@ -11,43 +10,11 @@ import {
|
||||
updateJson,
|
||||
updateProjectConfiguration,
|
||||
} from '@nrwl/devkit';
|
||||
import { jestConfigObject } from '../../utils/config/functions';
|
||||
import { dirname, extname, join } from 'path';
|
||||
import {
|
||||
removePropertyFromJestConfig,
|
||||
addPropertyToJestConfig,
|
||||
} from '../../utils/config/update-config';
|
||||
import { extname } from 'path';
|
||||
import { JestExecutorOptions } from '../../executors/jest/schema';
|
||||
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils';
|
||||
|
||||
const allowedExt = ['.ts', '.js'];
|
||||
let isRootPresetUpdated = false;
|
||||
|
||||
function updateJestPreset(
|
||||
tree: Tree,
|
||||
options: JestExecutorOptions,
|
||||
projectName: string
|
||||
) {
|
||||
const oldConfig = jestConfigObject(tree, options.jestConfig);
|
||||
if (!oldConfig) {
|
||||
return;
|
||||
}
|
||||
// if using the root preset and the root preset was updated to ts file.
|
||||
// then update the jest config
|
||||
if (isRootPresetUpdated && oldConfig?.preset?.endsWith('jest.preset.js')) {
|
||||
removePropertyFromJestConfig(tree, options.jestConfig, 'preset');
|
||||
addPropertyToJestConfig(
|
||||
tree,
|
||||
options.jestConfig,
|
||||
'preset',
|
||||
joinPathFragments(
|
||||
offsetFromRoot(dirname(options.jestConfig)),
|
||||
'jest.preset.ts'
|
||||
),
|
||||
{ valueAsString: false }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function updateTsConfig(tree: Tree, tsConfigPath: string) {
|
||||
try {
|
||||
@ -64,6 +31,17 @@ function updateTsConfig(tree: Tree, tsConfigPath: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function addEsLintIgnoreComments(tree: Tree, filePath: string) {
|
||||
if (tree.exists(filePath)) {
|
||||
const contents = tree.read(filePath, 'utf-8');
|
||||
tree.write(
|
||||
filePath,
|
||||
`/* eslint-disable */
|
||||
${contents}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function isJestConfigValid(tree: Tree, options: JestExecutorOptions) {
|
||||
const configExt = extname(options.jestConfig);
|
||||
|
||||
@ -81,26 +59,49 @@ function isJestConfigValid(tree: Tree, options: JestExecutorOptions) {
|
||||
function updateTsconfigSpec(
|
||||
tree: Tree,
|
||||
projectConfig: ProjectConfiguration,
|
||||
path
|
||||
path,
|
||||
options: { isNextWithProjectParse: boolean; tsConfigPath: string } = {
|
||||
isNextWithProjectParse: false,
|
||||
tsConfigPath: '',
|
||||
}
|
||||
) {
|
||||
updateJson(tree, joinPathFragments(projectConfig.root, path), (json) => {
|
||||
json.include = Array.from(
|
||||
new Set([...(json.include || []), 'jest.config.ts'])
|
||||
);
|
||||
if (options.isNextWithProjectParse) {
|
||||
const tsConfig = readJson(tree, options.tsConfigPath);
|
||||
const tsConfigExclude = (tsConfig.exclude || []).filter(
|
||||
(e) => e !== 'jest.config.ts'
|
||||
);
|
||||
json.exclude = Array.from(
|
||||
new Set([...(json.exclude || []), ...tsConfigExclude])
|
||||
);
|
||||
}
|
||||
return json;
|
||||
});
|
||||
}
|
||||
|
||||
function isNextWithProjectLint(
|
||||
projectConfig: ProjectConfiguration,
|
||||
esLintJson: any
|
||||
) {
|
||||
const esLintOverrides = esLintJson?.overrides?.find((o) =>
|
||||
['*.ts', '*.tsx', '*.js', '*.jsx'].every((ext) => o.files.includes(ext))
|
||||
);
|
||||
|
||||
// check if it's a next app and has a parserOptions.project set in the eslint overrides
|
||||
return !!(
|
||||
projectConfig?.targets?.['build']?.executor === '@nrwl/next:build' &&
|
||||
esLintOverrides?.parserOptions?.project
|
||||
);
|
||||
}
|
||||
|
||||
export async function updateJestConfigExt(tree: Tree) {
|
||||
if (tree.exists('jest.config.js')) {
|
||||
tree.rename('jest.config.js', 'jest.config.ts');
|
||||
}
|
||||
|
||||
if (tree.exists('jest.preset.js')) {
|
||||
isRootPresetUpdated = true;
|
||||
tree.rename('jest.preset.js', 'jest.preset.ts');
|
||||
}
|
||||
|
||||
forEachExecutorOptions<JestExecutorOptions>(
|
||||
tree,
|
||||
'@nrwl/jest:jest',
|
||||
@ -111,7 +112,7 @@ export async function updateJestConfigExt(tree: Tree) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateJestPreset(tree, options, projectName);
|
||||
addEsLintIgnoreComments(tree, options.jestConfig);
|
||||
|
||||
const newJestConfigPath = options.jestConfig.replace('.js', '.ts');
|
||||
tree.rename(options.jestConfig, newJestConfigPath);
|
||||
@ -125,7 +126,19 @@ export async function updateJestConfigExt(tree: Tree) {
|
||||
if (tsConfig.references) {
|
||||
for (const { path } of tsConfig.references) {
|
||||
if (path.endsWith('tsconfig.spec.json')) {
|
||||
updateTsconfigSpec(tree, projectConfig, path);
|
||||
const eslintPath = joinPathFragments(
|
||||
projectConfig.root,
|
||||
'.eslintrc.json'
|
||||
);
|
||||
updateTsconfigSpec(tree, projectConfig, path, {
|
||||
isNextWithProjectParse: tree.exists(eslintPath)
|
||||
? isNextWithProjectLint(
|
||||
projectConfig,
|
||||
readJson(tree, eslintPath)
|
||||
)
|
||||
: false,
|
||||
tsConfigPath: filePath,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Jest Migration (v14.1.2) should convert module.exports => export default 1`] = `
|
||||
"const { getJestProjects } = require('@nrwl/jest');
|
||||
const nxPreset = require('@nrwl/jest/preset');
|
||||
|
||||
|
||||
const someFn = () => ({more: 'stuff'});
|
||||
module.export.abc = someFn;
|
||||
export default {
|
||||
...nxPreset,
|
||||
more: 'stuff',
|
||||
someFn,
|
||||
projects: getJestProjects()
|
||||
};"
|
||||
`;
|
||||
|
||||
exports[`Jest Migration (v14.1.2) should update individual project jest configs 1`] = `
|
||||
"
|
||||
const nxPreset = require('@nrwl/jest/preset').default;
|
||||
const someOtherImport = require('../something/else.js');
|
||||
export default {
|
||||
...someOtherImport,
|
||||
...nxPreset,
|
||||
displayName: 'lib-one',
|
||||
preset: '../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
stringifyContentPathRegex: '\\\\\\\\.(html|svg)$',
|
||||
},
|
||||
},
|
||||
coverageDirectory: '../../coverage/apps/lib-one',
|
||||
transform: {
|
||||
'^.+\\\\\\\\.(ts|mjs|js|html)$': 'jest-preset-angular',
|
||||
},
|
||||
transformIgnorePatterns: ['node_modules/(?!.*\\\\\\\\.mjs$)'],
|
||||
snapshotSerializers: [
|
||||
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||
'jest-preset-angular/build/serializers/html-comment',
|
||||
],
|
||||
};
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`Jest Migration (v14.1.2) should work with multiple configurations 1`] = `
|
||||
"
|
||||
const nxPreset = require('@nrwl/jest/preset').default;
|
||||
const someOtherImport = require('../something/else.js');
|
||||
export default {
|
||||
...someOtherImport,
|
||||
...nxPreset,
|
||||
displayName: 'lib-one',
|
||||
preset: '../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
stringifyContentPathRegex: '\\\\\\\\.(html|svg)$',
|
||||
},
|
||||
},
|
||||
coverageDirectory: '../../coverage/apps/lib-one',
|
||||
transform: {
|
||||
'^.+\\\\\\\\.(ts|mjs|js|html)$': 'jest-preset-angular',
|
||||
},
|
||||
transformIgnorePatterns: ['node_modules/(?!.*\\\\\\\\.mjs$)'],
|
||||
snapshotSerializers: [
|
||||
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||
'jest-preset-angular/build/serializers/html-comment',
|
||||
],
|
||||
};
|
||||
"
|
||||
`;
|
||||
@ -0,0 +1,178 @@
|
||||
import {
|
||||
readProjectConfiguration,
|
||||
stripIndents,
|
||||
Tree,
|
||||
updateProjectConfiguration,
|
||||
} from '@nrwl/devkit';
|
||||
import { createTree, createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||
import { libraryGenerator as workspaceLib } from '@nrwl/workspace';
|
||||
import {
|
||||
updateExportsJestConfig,
|
||||
updateRootFiles,
|
||||
updateToDefaultExport,
|
||||
} from './update-exports-jest-config';
|
||||
|
||||
describe('Jest Migration (v14.1.2)', () => {
|
||||
let tree: Tree;
|
||||
beforeEach(() => {
|
||||
tree = createTreeWithEmptyWorkspace(2);
|
||||
});
|
||||
|
||||
it('should update root jest files', () => {
|
||||
tree.write(
|
||||
'jest.config.ts',
|
||||
stripIndents`
|
||||
const { getJestProjects } = require('@nrwl/jest');
|
||||
|
||||
module.exports = {
|
||||
projects: getJestProjects()
|
||||
};`
|
||||
);
|
||||
|
||||
tree.write(
|
||||
'jest.preset.ts',
|
||||
stripIndents`
|
||||
const nxPreset = require('@nrwl/jest/preset');
|
||||
|
||||
module.exports = { ...nxPreset };`
|
||||
);
|
||||
|
||||
const status = updateRootFiles(tree);
|
||||
|
||||
expect(status).toEqual({ didUpdateRootPreset: true });
|
||||
expect(tree.read('jest.config.ts', 'utf-8')).toEqual(stripIndents`
|
||||
const { getJestProjects } = require('@nrwl/jest');
|
||||
|
||||
export default {
|
||||
projects: getJestProjects()
|
||||
};
|
||||
`);
|
||||
expect(tree.read('jest.preset.js', 'utf-8')).toEqual(stripIndents`
|
||||
const nxPreset = require('@nrwl/jest/preset').default;
|
||||
|
||||
module.exports = { ...nxPreset };`);
|
||||
});
|
||||
|
||||
it('should update individual project jest configs', async () => {
|
||||
await workspaceLib(tree, { name: 'lib-one' });
|
||||
tree.rename('jest.preset.js', 'jest.preset.ts');
|
||||
tree.write(
|
||||
'libs/lib-one/jest.config.ts',
|
||||
`
|
||||
const nxPreset = require('@nrwl/jest/preset');
|
||||
const someOtherImport = require('../something/else.js');
|
||||
module.exports = {
|
||||
...someOtherImport,
|
||||
...nxPreset,
|
||||
displayName: 'lib-one',
|
||||
preset: '../../jest.preset.ts',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
stringifyContentPathRegex: '\\\\.(html|svg)$',
|
||||
},
|
||||
},
|
||||
coverageDirectory: '../../coverage/apps/lib-one',
|
||||
transform: {
|
||||
'^.+\\\\.(ts|mjs|js|html)$': 'jest-preset-angular',
|
||||
},
|
||||
transformIgnorePatterns: ['node_modules/(?!.*\\\\.mjs$)'],
|
||||
snapshotSerializers: [
|
||||
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||
'jest-preset-angular/build/serializers/html-comment',
|
||||
],
|
||||
};
|
||||
`
|
||||
);
|
||||
updateExportsJestConfig(tree);
|
||||
|
||||
const config = tree.read('libs/lib-one/jest.config.ts', 'utf-8');
|
||||
expect(config).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should work with multiple configurations', async () => {
|
||||
await workspaceLib(tree, { name: 'lib-one' });
|
||||
tree.rename('jest.preset.js', 'jest.preset.ts');
|
||||
updateProjectConfiguration(tree, 'lib-one', {
|
||||
...readProjectConfiguration(tree, 'lib-one'),
|
||||
targets: {
|
||||
test: {
|
||||
executor: '@nrwl/jest:jest',
|
||||
options: {
|
||||
jestConfig: 'libs/lib-one/jest.config.ts',
|
||||
passWithoutTests: true,
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
silent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
tree.write(
|
||||
'libs/lib-one/jest.config.ts',
|
||||
`
|
||||
const nxPreset = require('@nrwl/jest/preset');
|
||||
const someOtherImport = require('../something/else.js');
|
||||
module.exports = {
|
||||
...someOtherImport,
|
||||
...nxPreset,
|
||||
displayName: 'lib-one',
|
||||
preset: '../../jest.preset.ts',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
stringifyContentPathRegex: '\\\\.(html|svg)$',
|
||||
},
|
||||
},
|
||||
coverageDirectory: '../../coverage/apps/lib-one',
|
||||
transform: {
|
||||
'^.+\\\\.(ts|mjs|js|html)$': 'jest-preset-angular',
|
||||
},
|
||||
transformIgnorePatterns: ['node_modules/(?!.*\\\\.mjs$)'],
|
||||
snapshotSerializers: [
|
||||
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||
'jest-preset-angular/build/serializers/html-comment',
|
||||
],
|
||||
};
|
||||
`
|
||||
);
|
||||
|
||||
updateExportsJestConfig(tree);
|
||||
|
||||
const config = tree.read('libs/lib-one/jest.config.ts', 'utf-8');
|
||||
expect(config).toMatchSnapshot();
|
||||
expect(tree.exists('jest.preset.ts')).toBeFalsy();
|
||||
expect(tree.exists('jest.preset.js')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should convert module.exports => export default', () => {
|
||||
tree = createTree();
|
||||
|
||||
tree.write(
|
||||
'jest.config.js',
|
||||
stripIndents`
|
||||
const { getJestProjects } = require('@nrwl/jest');
|
||||
const nxPreset = require('@nrwl/jest/preset');
|
||||
|
||||
|
||||
const someFn = () => ({more: 'stuff'});
|
||||
module.export.abc = someFn;
|
||||
module.exports = {
|
||||
...nxPreset,
|
||||
more: 'stuff',
|
||||
someFn,
|
||||
projects: getJestProjects()
|
||||
};`
|
||||
);
|
||||
updateToDefaultExport(tree, 'jest.config.js');
|
||||
|
||||
expect(tree.read('jest.config.js', 'utf-8')).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,85 @@
|
||||
import type { Tree } from '@nrwl/devkit';
|
||||
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils';
|
||||
import { tsquery } from '@phenomnomnominal/tsquery';
|
||||
import type { BinaryExpression } from 'typescript';
|
||||
import type { JestExecutorOptions } from '../../executors/jest/schema';
|
||||
|
||||
export function updateExportsJestConfig(tree: Tree) {
|
||||
const { didUpdateRootPreset } = updateRootFiles(tree);
|
||||
forEachExecutorOptions<JestExecutorOptions>(
|
||||
tree,
|
||||
'@nrwl/jest:jest',
|
||||
(options) => {
|
||||
if (options.jestConfig && tree.exists(options.jestConfig)) {
|
||||
if (options.jestConfig.endsWith('.ts')) {
|
||||
updateToDefaultExport(tree, options.jestConfig);
|
||||
}
|
||||
|
||||
const updatedImport = updateNxPresetImport(
|
||||
tree.read(options.jestConfig, 'utf-8')
|
||||
);
|
||||
tree.write(options.jestConfig, updatedImport);
|
||||
|
||||
// jest.preset.ts => jest.preset.js
|
||||
if (didUpdateRootPreset) {
|
||||
const projectConfig = tree.read(options.jestConfig, 'utf-8');
|
||||
const updatedConfig = projectConfig.replace(
|
||||
/(preset:\s*['"][.\/]*)(jest\.preset\.ts)(['"])/g,
|
||||
'$1jest.preset.js$3'
|
||||
);
|
||||
tree.write(options.jestConfig, updatedConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function updateRootFiles(tree: Tree): { didUpdateRootPreset: boolean } {
|
||||
let didUpdateRootPreset = false;
|
||||
if (tree.exists('jest.config.ts')) {
|
||||
updateToDefaultExport(tree, 'jest.config.ts');
|
||||
}
|
||||
|
||||
if (tree.exists('jest.preset.ts')) {
|
||||
// fix those who ran v14 migration where this was renamed.
|
||||
tree.rename('jest.preset.ts', 'jest.preset.js');
|
||||
didUpdateRootPreset = true;
|
||||
}
|
||||
|
||||
if (tree.exists('jest.preset.js')) {
|
||||
const newContents = updateNxPresetImport(
|
||||
tree.read('jest.preset.js', 'utf-8')
|
||||
);
|
||||
tree.write('jest.preset.js', newContents);
|
||||
}
|
||||
|
||||
return {
|
||||
didUpdateRootPreset,
|
||||
};
|
||||
}
|
||||
|
||||
function updateNxPresetImport(fileContents: string): string {
|
||||
return fileContents.replace(
|
||||
/require\(['"]@nrwl\/jest\/preset['"]\)[;\s]*?[\n\r]/g,
|
||||
`require('@nrwl/jest/preset').default;
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
export function updateToDefaultExport(tree: Tree, filePath: string) {
|
||||
const newConfig = tsquery.replace(
|
||||
tree.read(filePath, 'utf-8'),
|
||||
'ExpressionStatement BinaryExpression',
|
||||
(node: BinaryExpression) => {
|
||||
if (node.left.getText() === 'module.exports') {
|
||||
return `export default ${node.right.getText()}`;
|
||||
}
|
||||
|
||||
return node.getText();
|
||||
}
|
||||
);
|
||||
|
||||
tree.write(filePath, newConfig);
|
||||
}
|
||||
|
||||
export default updateExportsJestConfig;
|
||||
@ -0,0 +1,14 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`jestConfigObject export default should handle spread assignments 1`] = `
|
||||
"{
|
||||
...nxPreset,
|
||||
abc: 'xyz'
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`jestConfigObject export default should work for basic cases 1`] = `
|
||||
"{
|
||||
abc: 'xyz'
|
||||
}"
|
||||
`;
|
||||
@ -17,9 +17,5 @@ export function findRootJestPreset(tree: Tree): string | null {
|
||||
return 'jest.preset.js';
|
||||
}
|
||||
|
||||
if (tree.exists('jest.preset.ts')) {
|
||||
return 'jest.preset.ts';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1,70 +1,72 @@
|
||||
import { createTree } from '@nrwl/devkit/testing';
|
||||
import { jestConfigObject } from './functions';
|
||||
import { jestConfigObject, jestConfigObjectAst } from './functions';
|
||||
|
||||
describe('jestConfigObject', () => {
|
||||
it('should work for basic cases', () => {
|
||||
const tree = createTree();
|
||||
tree.write(
|
||||
'jest.config.js',
|
||||
`
|
||||
describe('module.exports', () => {
|
||||
it('should work for basic cases', () => {
|
||||
const tree = createTree();
|
||||
tree.write(
|
||||
'jest.config.js',
|
||||
`
|
||||
module.exports = {
|
||||
foo: 'bar'
|
||||
};
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
expect(jestConfigObject(tree, 'jest.config.js')).toEqual({
|
||||
foo: 'bar',
|
||||
expect(jestConfigObject(tree, 'jest.config.js')).toEqual({
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
xit('should work with async functions', async () => {
|
||||
const tree = createTree();
|
||||
jest.mock('@nrwl/jest', () => ({
|
||||
getJestProjects: () => ['<rootDir>/project-a', '<rootDir>/project-b'],
|
||||
}));
|
||||
tree.write(
|
||||
'jest.config.js',
|
||||
`
|
||||
xit('should work with async functions', async () => {
|
||||
const tree = createTree();
|
||||
jest.mock('@nrwl/jest', () => ({
|
||||
getJestProjects: () => ['<rootDir>/project-a', '<rootDir>/project-b'],
|
||||
}));
|
||||
tree.write(
|
||||
'jest.config.js',
|
||||
`
|
||||
const { getJestProjects } = require('@nrwl/jest');
|
||||
module.exports = async () => ({
|
||||
foo: 'bar'
|
||||
});
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
expect(await jestConfigObject(tree, 'jest.config.js')).toEqual({
|
||||
foo: 'bar',
|
||||
expect(await jestConfigObject(tree, 'jest.config.js')).toEqual({
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with `getJestConfig`', () => {
|
||||
const tree = createTree();
|
||||
jest.mock('@nrwl/jest', () => ({
|
||||
getJestProjects: () => ['<rootDir>/project-a', '<rootDir>/project-b'],
|
||||
}));
|
||||
tree.write(
|
||||
'jest.config.js',
|
||||
`
|
||||
it('should work with `getJestConfig`', () => {
|
||||
const tree = createTree();
|
||||
jest.mock('@nrwl/jest', () => ({
|
||||
getJestProjects: () => ['<rootDir>/project-a', '<rootDir>/project-b'],
|
||||
}));
|
||||
tree.write(
|
||||
'jest.config.js',
|
||||
`
|
||||
const { getJestProjects } = require('@nrwl/jest');
|
||||
module.exports = {
|
||||
projects: getJestProjects()
|
||||
};
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
expect(jestConfigObject(tree, 'jest.config.js')).toEqual({
|
||||
projects: ['<rootDir>/project-a', '<rootDir>/project-b'],
|
||||
expect(jestConfigObject(tree, 'jest.config.js')).toEqual({
|
||||
projects: ['<rootDir>/project-a', '<rootDir>/project-b'],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with node globals (require, __dirname, process, __filename, console, and other globals)', () => {
|
||||
const tree = createTree();
|
||||
jest.mock('@nrwl/jest', () => ({
|
||||
getJestProjects: () => ['<rootDir>/project-a', '<rootDir>/project-b'],
|
||||
}));
|
||||
tree.write(
|
||||
'jest.config.js',
|
||||
`
|
||||
it('should work with node globals (require, __dirname, process, __filename, console, and other globals)', () => {
|
||||
const tree = createTree();
|
||||
jest.mock('@nrwl/jest', () => ({
|
||||
getJestProjects: () => ['<rootDir>/project-a', '<rootDir>/project-b'],
|
||||
}));
|
||||
tree.write(
|
||||
'jest.config.js',
|
||||
`
|
||||
const { getJestProjects } = require('@nrwl/jest');
|
||||
module.exports = {
|
||||
projects: getJestProjects(),
|
||||
@ -73,13 +75,37 @@ describe('jestConfigObject', () => {
|
||||
dirname: __dirname
|
||||
};
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
expect(jestConfigObject(tree, 'jest.config.js')).toEqual({
|
||||
dirname: '/virtual',
|
||||
filename: '/virtual/jest.config.js',
|
||||
env: process.env,
|
||||
projects: ['<rootDir>/project-a', '<rootDir>/project-b'],
|
||||
expect(jestConfigObject(tree, 'jest.config.js')).toEqual({
|
||||
dirname: '/virtual',
|
||||
filename: '/virtual/jest.config.js',
|
||||
env: process.env,
|
||||
projects: ['<rootDir>/project-a', '<rootDir>/project-b'],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('export default', () => {
|
||||
it('should work for basic cases', () => {
|
||||
const content = `
|
||||
export default {
|
||||
abc: 'xyz'
|
||||
}`;
|
||||
|
||||
expect(jestConfigObjectAst(content).getText()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should handle spread assignments', () => {
|
||||
const content = `
|
||||
import { nxPreset } from '@nrwl/jest/preset';
|
||||
|
||||
export default {
|
||||
...nxPreset,
|
||||
abc: 'xyz'
|
||||
}`;
|
||||
|
||||
expect(jestConfigObjectAst(content).getText()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,12 +1,4 @@
|
||||
import * as ts from 'typescript';
|
||||
import {
|
||||
BinaryExpression,
|
||||
ExpressionStatement,
|
||||
isBinaryExpression,
|
||||
isExpressionStatement,
|
||||
isPropertyAssignment,
|
||||
SyntaxKind,
|
||||
} from 'typescript';
|
||||
import { applyChangesToString, ChangeType, Tree } from '@nrwl/devkit';
|
||||
import { Config } from '@jest/types';
|
||||
import { createContext, runInContext } from 'vm';
|
||||
@ -24,7 +16,7 @@ function findPropertyAssignment(
|
||||
propertyName: string
|
||||
) {
|
||||
return object.properties.find((prop) => {
|
||||
if (!isPropertyAssignment(prop)) {
|
||||
if (!ts.isPropertyAssignment(prop)) {
|
||||
return false;
|
||||
}
|
||||
const propNameText = prop.name.getText();
|
||||
@ -171,11 +163,27 @@ export function removeProperty(
|
||||
}
|
||||
}
|
||||
|
||||
function isModuleExport(node: ts.Statement) {
|
||||
return (
|
||||
ts.isExpressionStatement(node) &&
|
||||
node.expression?.kind &&
|
||||
ts.isBinaryExpression(node.expression) &&
|
||||
node.expression.left.getText() === 'module.exports' &&
|
||||
node.expression.operatorToken?.kind === ts.SyntaxKind.EqualsToken
|
||||
);
|
||||
}
|
||||
|
||||
function isDefaultExport(node: ts.Statement) {
|
||||
return (
|
||||
ts.isExportAssignment(node) &&
|
||||
node.expression?.kind &&
|
||||
ts.isObjectLiteralExpression(node.expression) &&
|
||||
node.getText().startsWith('export default')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be used to get the jest config object.
|
||||
*
|
||||
* @param host
|
||||
* @param path
|
||||
* Should be used to get the jest config object as AST
|
||||
*/
|
||||
export function jestConfigObjectAst(
|
||||
fileContent: string
|
||||
@ -187,32 +195,51 @@ export function jestConfigObjectAst(
|
||||
true
|
||||
);
|
||||
|
||||
const moduleExportsStatement = sourceFile.statements.find(
|
||||
(statement) =>
|
||||
isExpressionStatement(statement) &&
|
||||
isBinaryExpression(statement.expression) &&
|
||||
statement.expression.left.getText() === 'module.exports' &&
|
||||
statement.expression.operatorToken.kind === SyntaxKind.EqualsToken
|
||||
const exportStatement = sourceFile.statements.find(
|
||||
(statement) => isModuleExport(statement) || isDefaultExport(statement)
|
||||
);
|
||||
|
||||
const moduleExports = (moduleExportsStatement as ExpressionStatement)
|
||||
.expression as BinaryExpression;
|
||||
|
||||
if (!moduleExports) {
|
||||
throw new Error(
|
||||
`
|
||||
let ast: ts.ObjectLiteralExpression;
|
||||
if (ts.isExpressionStatement(exportStatement)) {
|
||||
const moduleExports = exportStatement.expression as ts.BinaryExpression;
|
||||
if (!moduleExports) {
|
||||
throw new Error(
|
||||
`
|
||||
The provided jest config file does not have the expected 'module.exports' expression.
|
||||
See https://jestjs.io/docs/en/configuration for more details.`
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (!ts.isObjectLiteralExpression(moduleExports.right)) {
|
||||
ast = moduleExports.right as ts.ObjectLiteralExpression;
|
||||
} else if (ts.isExportAssignment(exportStatement)) {
|
||||
const defaultExport =
|
||||
exportStatement.expression as ts.ObjectLiteralExpression;
|
||||
|
||||
if (!defaultExport) {
|
||||
throw new Error(
|
||||
`
|
||||
The provided jest config file does not have the expected 'export default' expression.
|
||||
See https://jestjs.io/docs/en/configuration for more details.`
|
||||
);
|
||||
}
|
||||
|
||||
ast = defaultExport;
|
||||
}
|
||||
if (!ast) {
|
||||
throw new Error(
|
||||
`The 'module.exports' expression is not an object literal.`
|
||||
`
|
||||
The provided jest config file does not have the expected 'module.exports' or 'export default' expression.
|
||||
See https://jestjs.io/docs/en/configuration for more details.`
|
||||
);
|
||||
}
|
||||
|
||||
return moduleExports.right as ts.ObjectLiteralExpression;
|
||||
if (!ts.isObjectLiteralExpression(ast)) {
|
||||
throw new Error(
|
||||
`The 'export default' or 'module.exports' expression is not an object literal.`
|
||||
);
|
||||
}
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -228,10 +255,18 @@ export function jestConfigObject(
|
||||
const contents = host.read(path, 'utf-8');
|
||||
let module = { exports: {} };
|
||||
|
||||
// transform the export default syntax to module.exports
|
||||
// this will work for the default config, but will break if there are any other ts syntax
|
||||
// TODO(caleb): use the AST to transform back to the module.exports syntax so this will keep working
|
||||
// or deprecate and make a new method for getting the jest config object
|
||||
const forcedModuleSyntax = contents.replace(
|
||||
/export\s+default/,
|
||||
'module.exports ='
|
||||
);
|
||||
// Run the contents of the file with some stuff from this current context
|
||||
// The module.exports will be mutated by the contents of the file...
|
||||
runInContext(
|
||||
contents,
|
||||
forcedModuleSyntax,
|
||||
createContext({
|
||||
module,
|
||||
require,
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`lib --unit-test-runner jest should generate test configuration with swc and js 1`] = `
|
||||
"/* eslint-disable */
|
||||
const { readFileSync } = require('fs')
|
||||
|
||||
// Reading the SWC compilation config and remove the \\"exclude\\"
|
||||
// for the test files to be compiled by SWC
|
||||
const { exclude: _, ...swcJestConfig } = JSON.parse(
|
||||
readFileSync(\`\${__dirname}/.lib.swcrc\`, 'utf-8')
|
||||
);
|
||||
module.exports = {
|
||||
displayName: 'my-lib',
|
||||
preset: '../../jest.preset.js',
|
||||
transform: {
|
||||
'^.+\\\\\\\\.[tj]s$': ['@swc/jest', swcJestConfig],
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'js', 'html'],
|
||||
coverageDirectory: '../../coverage/libs/my-lib'
|
||||
};
|
||||
"
|
||||
`;
|
||||
@ -1,14 +1,14 @@
|
||||
import { readFileSync } from 'fs';
|
||||
/* eslint-disable */
|
||||
<% if(js) {%>const { readFileSync } = require('fs')<% } else { %>import { readFileSync } from 'fs';<% } %>
|
||||
|
||||
// Reading the SWC compilation config and remove the "exclude"
|
||||
// for the test files to be compiled by SWC
|
||||
const { exclude: _, ...swcJestConfig } = JSON.parse(
|
||||
readFileSync(`${__dirname}/.lib.swcrc`, 'utf-8')
|
||||
);
|
||||
|
||||
module.exports = {
|
||||
<% if(js) {%>module.exports =<% } else { %>export default<% } %> {
|
||||
displayName: '<%= project %>',
|
||||
preset: '<%= offsetFromRoot %>jest.preset.<%= ext %>',
|
||||
preset: '<%= offsetFromRoot %>jest.preset.js',
|
||||
transform: {
|
||||
'^.+\\.[tj]s$': ['@swc/jest', swcJestConfig],
|
||||
},
|
||||
|
||||
@ -698,9 +698,10 @@ describe('lib', () => {
|
||||
expect(tree.exists(`libs/my-lib/jest.config.ts`)).toBeTruthy();
|
||||
expect(tree.read(`libs/my-lib/jest.config.ts`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'my-lib',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
@ -718,6 +719,30 @@ describe('lib', () => {
|
||||
expect(readme).toContain('nx test my-lib');
|
||||
});
|
||||
|
||||
it('should generate test configuration with swc and js', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
...defaultOptions,
|
||||
name: 'myLib',
|
||||
unitTestRunner: 'jest',
|
||||
compiler: 'swc',
|
||||
js: true,
|
||||
});
|
||||
|
||||
expect(tree.exists('libs/my-lib/tsconfig.spec.json')).toBeTruthy();
|
||||
expect(tree.exists('libs/my-lib/jest.config.js')).toBeTruthy();
|
||||
expect(tree.exists('libs/my-lib/src/lib/my-lib.spec.js')).toBeTruthy();
|
||||
|
||||
const projectConfig = readProjectConfiguration(tree, 'my-lib');
|
||||
expect(projectConfig.targets.test).toBeDefined();
|
||||
|
||||
expect(tree.exists(`libs/my-lib/jest.config.js`)).toBeTruthy();
|
||||
expect(
|
||||
tree.read(`libs/my-lib/jest.config.js`, 'utf-8')
|
||||
).toMatchSnapshot();
|
||||
const readme = tree.read('libs/my-lib/README.md', 'utf-8');
|
||||
expect(readme).toContain('nx test my-lib');
|
||||
});
|
||||
|
||||
describe('--buildable', () => {
|
||||
it('should generate the build target', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
|
||||
@ -216,7 +216,6 @@ function addBabelRc(tree: Tree, options: NormalizedSchema) {
|
||||
|
||||
function createFiles(tree: Tree, options: NormalizedSchema, filesDir: string) {
|
||||
const { className, name, propertyName } = names(options.name);
|
||||
|
||||
generateFiles(tree, filesDir, options.projectRoot, {
|
||||
...options,
|
||||
dot: '.',
|
||||
@ -290,10 +289,19 @@ function replaceJestConfig(
|
||||
options: NormalizedSchema,
|
||||
filesDir: string
|
||||
) {
|
||||
// the existing config has to be deleted otherwise the new config won't overwrite it
|
||||
const existingJestConfig = joinPathFragments(
|
||||
filesDir,
|
||||
`jest.config.${options.js ? 'js' : 'ts'}`
|
||||
);
|
||||
if (tree.exists(existingJestConfig)) {
|
||||
tree.delete(existingJestConfig);
|
||||
}
|
||||
|
||||
// replace with JS:SWC specific jest config
|
||||
generateFiles(tree, filesDir, options.projectRoot, {
|
||||
tmpl: '',
|
||||
ext: findRootJestPreset(tree) === 'jest.preset.js' ? 'js' : 'ts',
|
||||
ext: options.js ? 'js' : 'ts',
|
||||
js: !!options.js,
|
||||
project: options.name,
|
||||
offsetFromRoot: offsetFromRoot(options.projectRoot),
|
||||
projectRoot: options.projectRoot,
|
||||
|
||||
@ -83,9 +83,10 @@ exports[`@nrwl/linter:workspace-rules-project should generate the required files
|
||||
`;
|
||||
|
||||
exports[`@nrwl/linter:workspace-rules-project should generate the required files 5`] = `
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'eslint-rules',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`lib --testEnvironment should set target jest testEnvironment to jsdom 1`] = `
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'my-lib',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
@ -19,9 +20,10 @@ exports[`lib --testEnvironment should set target jest testEnvironment to jsdom 1
|
||||
`;
|
||||
|
||||
exports[`lib --testEnvironment should set target jest testEnvironment to node by default 1`] = `
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'my-lib',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
|
||||
@ -40,6 +40,14 @@ export async function addJest(host: Tree, options: NormalizedSchema) {
|
||||
joinPathFragments(options.appProjectRoot, 'tsconfig.spec.json'),
|
||||
(json) => {
|
||||
json.compilerOptions.jsx = 'react';
|
||||
// have to override exclude otherwise lint will fail with setParserOptionsProject and jest.config.ts
|
||||
if (options.setParserOptionsProject) {
|
||||
const tsConfig = readJson(
|
||||
host,
|
||||
joinPathFragments(options.appProjectRoot, 'tsconfig.json')
|
||||
);
|
||||
json.exclude = tsConfig.exclude.filter((e) => e !== 'jest.config.ts');
|
||||
}
|
||||
return json;
|
||||
}
|
||||
);
|
||||
|
||||
@ -374,9 +374,10 @@ describe('app', () => {
|
||||
|
||||
expect(tree.read(`apps/my-node-app/jest.config.ts`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'my-node-app',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\\\\\\\.[tj]s$': 'babel-jest'
|
||||
|
||||
@ -462,9 +462,10 @@ describe('lib', () => {
|
||||
|
||||
expect(tree.read(`libs/my-lib/jest.config.ts`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'my-lib',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\\\\\\\.[tj]sx?$': 'babel-jest'
|
||||
|
||||
@ -421,9 +421,10 @@ describe('app', () => {
|
||||
|
||||
expect(tree.read(`apps/my-app/jest.config.ts`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'my-app',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
transform: {
|
||||
'^.+\\\\\\\\.[tj]s$': 'babel-jest'
|
||||
@ -443,9 +444,10 @@ describe('app', () => {
|
||||
|
||||
expect(tree.read(`apps/my-app/jest.config.ts`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'my-app',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
transform: {
|
||||
'^.+\\\\\\\\.[tj]s$': '@swc/jest'
|
||||
|
||||
@ -195,9 +195,10 @@ describe('lib', () => {
|
||||
expect(tree.exists(`libs/my-lib/jest.config.ts`)).toBeTruthy();
|
||||
expect(tree.read(`libs/my-lib/jest.config.ts`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'my-lib',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
@ -227,9 +228,9 @@ describe('lib', () => {
|
||||
name: 'myLib',
|
||||
});
|
||||
const expectedRootJestConfig = `
|
||||
"const { getJestProjects } = require('@nrwl/jest');
|
||||
"import { getJestProjects } from '@nrwl/jest';
|
||||
|
||||
module.exports = {
|
||||
export default {
|
||||
projects: getJestProjects()
|
||||
};"
|
||||
`;
|
||||
@ -829,9 +830,10 @@ describe('lib', () => {
|
||||
|
||||
expect(tree.read(`libs/my-lib/jest.config.ts`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"module.exports = {
|
||||
"/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'my-lib',
|
||||
preset: '../../jest.preset.ts',
|
||||
preset: '../../jest.preset.js',
|
||||
transform: {
|
||||
'^.+\\\\\\\\.[tj]sx?$': 'babel-jest'
|
||||
},
|
||||
|
||||
@ -21,7 +21,7 @@ describe('move', () => {
|
||||
const jestConfigPath = 'libs/shared/my-lib-new/jest.config.ts';
|
||||
const afterJestConfig = tree.read(jestConfigPath, 'utf-8');
|
||||
expect(tree.exists(jestConfigPath)).toBeTruthy();
|
||||
expect(afterJestConfig).toContain("preset: '../../../jest.preset.ts'");
|
||||
expect(afterJestConfig).toContain("preset: '../../../jest.preset.js'");
|
||||
expect(afterJestConfig).toContain(
|
||||
"coverageDirectory: '../../../coverage/libs/shared/my-lib-new'"
|
||||
);
|
||||
@ -39,7 +39,7 @@ describe('move', () => {
|
||||
const jestConfigPath = 'libs/my-lib-new/jest.config.ts';
|
||||
const afterJestConfig = tree.read(jestConfigPath, 'utf-8');
|
||||
expect(tree.exists(jestConfigPath)).toBeTruthy();
|
||||
expect(afterJestConfig).toContain("preset: '../../jest.preset.ts'");
|
||||
expect(afterJestConfig).toContain("preset: '../../jest.preset.js'");
|
||||
expect(afterJestConfig).toContain(
|
||||
"coverageDirectory: '../../coverage/libs/my-lib-new'"
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user