From ecf88a6995f9a43bf03fc7bb5ebcf8a048409624 Mon Sep 17 00:00:00 2001 From: Caleb Ukle Date: Wed, 11 May 2022 13:04:29 -0500 Subject: [PATCH] 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 --- e2e/jest/src/jest.test.ts | 12 +- e2e/js/src/js.test.ts | 5 + e2e/next/src/next.test.ts | 4 + e2e/node/src/node.test.ts | 10 +- e2e/react/src/react.test.ts | 6 + e2e/utils/index.ts | 27 +++ e2e/web/src/web.test.ts | 5 + e2e/workspace-core/src/aux-commands.test.ts | 6 +- e2e/workspace-core/src/workspace-lib.test.ts | 12 +- .../storybook-configuration.spec.ts.snap | 4 +- packages/jest/migrations.json | 6 + packages/jest/preset/index.ts | 4 +- packages/jest/preset/jest-preset.ts | 2 +- .../init/__snapshots__/init.spec.ts.snap | 29 +++ .../jest/src/generators/init/init.spec.ts | 29 ++- packages/jest/src/generators/init/init.ts | 30 +-- .../__snapshots__/jest-project.spec.ts.snap | 51 ++++- .../files-angular/jest.config.ts__tmpl__ | 5 +- .../jest-project/files/jest.config.ts__tmpl__ | 5 +- .../jest-project/jest-project.spec.ts | 17 +- .../jest-project/lib/create-files.ts | 3 +- .../update-jest-config-ext.spec.ts.snap | 37 +++- .../update-jest-config-ext.spec.ts | 116 +++++++++--- .../update-14-0-0/update-jest-config-ext.ts | 97 +++++----- .../update-exports-jest-config.spec.ts.snap | 76 ++++++++ .../update-exports-jest-config.spec.ts | 178 ++++++++++++++++++ .../update-exports-jest-config.ts | 85 +++++++++ .../__snapshots__/functions.spec.ts.snap | 14 ++ .../src/utils/config/find-root-jest-files.ts | 4 - .../jest/src/utils/config/functions.spec.ts | 122 +++++++----- packages/jest/src/utils/config/functions.ts | 91 ++++++--- .../__snapshots__/library.spec.ts.snap | 22 +++ .../files/jest-config/jest.config.__ext__ | 8 +- .../js/src/generators/library/library.spec.ts | 29 ++- packages/js/src/generators/library/library.ts | 14 +- .../workspace-rules-project.spec.ts.snap | 5 +- .../__snapshots__/library.spec.ts.snap | 10 +- .../generators/application/lib/add-jest.ts | 8 + .../application/application.spec.ts | 5 +- .../src/generators/library/library.spec.ts | 5 +- .../application/application.spec.ts | 10 +- .../src/generators/library/library.spec.ts | 14 +- .../src/generators/move/move.spec.ts | 4 +- 43 files changed, 974 insertions(+), 252 deletions(-) create mode 100644 packages/jest/src/generators/init/__snapshots__/init.spec.ts.snap create mode 100644 packages/jest/src/migrations/update-14-1-5/__snapshots__/update-exports-jest-config.spec.ts.snap create mode 100644 packages/jest/src/migrations/update-14-1-5/update-exports-jest-config.spec.ts create mode 100644 packages/jest/src/migrations/update-14-1-5/update-exports-jest-config.ts create mode 100644 packages/jest/src/utils/config/__snapshots__/functions.spec.ts.snap create mode 100644 packages/js/src/generators/library/__snapshots__/library.spec.ts.snap diff --git a/e2e/jest/src/jest.test.ts b/e2e/jest/src/jest.test.ts index 3ed5352601554..ab71f72864ab1 100644 --- a/e2e/jest/src/jest.test.ts +++ b/e2e/jest/src/jest.test.ts @@ -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 () => { diff --git a/e2e/js/src/js.test.ts b/e2e/js/src/js.test.ts index 955d5c21fd4d2..ed8d171bfba51 100644 --- a/e2e/js/src/js.test.ts +++ b/e2e/js/src/js.test.ts @@ -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'); + }); }); diff --git a/e2e/next/src/next.test.ts b/e2e/next/src/next.test.ts index f7f2bdf58aadd..0505a6860f90a 100644 --- a/e2e/next/src/next.test.ts +++ b/e2e/next/src/next.test.ts @@ -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 { diff --git a/e2e/node/src/node.test.ts b/e2e/node/src/node.test.ts index 8d511e1230874..2348e4dba1981 100644 --- a/e2e/node/src/node.test.ts +++ b/e2e/node/src/node.test.ts @@ -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: '/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'); + }); }); diff --git a/e2e/react/src/react.test.ts b/e2e/react/src/react.test.ts index 2130b0ecfd166..2c6eb55db5d29 100644 --- a/e2e/react/src/react.test.ts +++ b/e2e/react/src/react.test.ts @@ -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'); + }); }); diff --git a/e2e/utils/index.ts b/e2e/utils/index.ts index b8c1b9b6753e0..0c5cd980f9d99 100644 --- a/e2e/utils/index.ts +++ b/e2e/utils/index.ts @@ -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'); +} diff --git a/e2e/web/src/web.test.ts b/e2e/web/src/web.test.ts index 3875af3079278..11217e1b6232f 100644 --- a/e2e/web/src/web.test.ts +++ b/e2e/web/src/web.test.ts @@ -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', () => { diff --git a/e2e/workspace-core/src/aux-commands.test.ts b/e2e/workspace-core/src/aux-commands.test.ts index c69a5b1e30118..d7202982fc7e8 100644 --- a/e2e/workspace-core/src/aux-commands.test.ts +++ b/e2e/workspace-core/src/aux-commands.test.ts @@ -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`; diff --git a/e2e/workspace-core/src/workspace-lib.test.ts b/e2e/workspace-core/src/workspace-lib.test.ts index f1772e95036d5..9dfb45a9c1b92 100644 --- a/e2e/workspace-core/src/workspace-lib.test.ts +++ b/e2e/workspace-core/src/workspace-lib.test.ts @@ -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'); }); }); diff --git a/packages/angular/src/generators/storybook-configuration/__snapshots__/storybook-configuration.spec.ts.snap b/packages/angular/src/generators/storybook-configuration/__snapshots__/storybook-configuration.spec.ts.snap index e17bfa9471c28..d054fbd540611 100644 --- a/packages/angular/src/generators/storybook-configuration/__snapshots__/storybook-configuration.spec.ts.snap +++ b/packages/angular/src/generators/storybook-configuration/__snapshots__/storybook-configuration.spec.ts.snap @@ -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", diff --git a/packages/jest/migrations.json b/packages/jest/migrations.json index 7c4376e1e6f9a..322b8c1869c92 100644 --- a/packages/jest/migrations.json +++ b/packages/jest/migrations.json @@ -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": { diff --git a/packages/jest/preset/index.ts b/packages/jest/preset/index.ts index 6256a436c833d..d26da6054e25e 100644 --- a/packages/jest/preset/index.ts +++ b/packages/jest/preset/index.ts @@ -1 +1,3 @@ -export = require('./jest-preset'); +import { nxPreset } from './jest-preset'; + +export default nxPreset; diff --git a/packages/jest/preset/jest-preset.ts b/packages/jest/preset/jest-preset.ts index b637601044fac..dccfb6310bab8 100644 --- a/packages/jest/preset/jest-preset.ts +++ b/packages/jest/preset/jest-preset.ts @@ -1,4 +1,4 @@ -export = { +export const nxPreset = { testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], resolver: '@nrwl/jest/plugins/resolver', moduleFileExtensions: ['ts', 'js', 'mjs', 'html'], diff --git a/packages/jest/src/generators/init/__snapshots__/init.spec.ts.snap b/packages/jest/src/generators/init/__snapshots__/init.spec.ts.snap new file mode 100644 index 0000000000000..2525de8ad0ee4 --- /dev/null +++ b/packages/jest/src/generators/init/__snapshots__/init.spec.ts.snap @@ -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 }" +`; diff --git a/packages/jest/src/generators/init/init.spec.ts b/packages/jest/src/generators/init/init.spec.ts index 893ebfdeeb031..1fd0ef6cc48ec 100644 --- a/packages/jest/src/generators/init/init.spec.ts +++ b/packages/jest/src/generators/init/init.spec.ts @@ -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 () => { diff --git a/packages/jest/src/generators/init/init.ts b/packages/jest/src/generators/init/init.ts index bb37ed9fe2fa3..2963925198aed 100644 --- a/packages/jest/src/generators/init/init.ts +++ b/packages/jest/src/generators/init/init.ts @@ -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'); - - module.exports = { - projects: getJestProjects() - };` - ); + const contents = js + ? stripIndents` + const { getJestProjects } = require('@nrwl/jest'); + + 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 }` ); diff --git a/packages/jest/src/generators/jest-project/__snapshots__/jest-project.spec.ts.snap b/packages/jest/src/generators/jest-project/__snapshots__/jest-project.spec.ts.snap index 907fc146f418f..eae545c739857 100644 --- a/packages/jest/src/generators/jest-project/__snapshots__/jest-project.spec.ts.snap +++ b/packages/jest/src/generators/jest-project/__snapshots__/jest-project.spec.ts.snap @@ -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: ['/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: '/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: ['/src/test-setup.ts'], + globals: { + 'ts-jest': { + tsconfig: '/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", diff --git a/packages/jest/src/generators/jest-project/files-angular/jest.config.ts__tmpl__ b/packages/jest/src/generators/jest-project/files-angular/jest.config.ts__tmpl__ index d89c298e7ed73..9effaf14a6c18 100644 --- a/packages/jest/src/generators/jest-project/files-angular/jest.config.ts__tmpl__ +++ b/packages/jest/src/generators/jest-project/files-angular/jest.config.ts__tmpl__ @@ -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: ['/src/test-setup.ts'], globals: { 'ts-jest': { diff --git a/packages/jest/src/generators/jest-project/files/jest.config.ts__tmpl__ b/packages/jest/src/generators/jest-project/files/jest.config.ts__tmpl__ index 4ec65f341db20..f40d5896697ba 100644 --- a/packages/jest/src/generators/jest-project/files/jest.config.ts__tmpl__ +++ b/packages/jest/src/generators/jest-project/files/jest.config.ts__tmpl__ @@ -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: ['/src/test-setup.ts'],<% } %><% if (transformer === 'ts-jest') { %> globals: { 'ts-jest': { diff --git a/packages/jest/src/generators/jest-project/jest-project.spec.ts b/packages/jest/src/generators/jest-project/jest-project.spec.ts index 8954b6e936e92..09e0fd2c58edd 100644 --- a/packages/jest/src/generators/jest-project/jest-project.spec.ts +++ b/packages/jest/src/generators/jest-project/jest-project.spec.ts @@ -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 = {' ); }); diff --git a/packages/jest/src/generators/jest-project/lib/create-files.ts b/packages/jest/src/generators/jest-project/lib/create-files.ts index a7360fa93a55b..930aa4f92aa40 100644 --- a/packages/jest/src/generators/jest-project/lib/create-files.ts +++ b/packages/jest/src/generators/jest-project/lib/create-files.ts @@ -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), }); diff --git a/packages/jest/src/migrations/update-14-0-0/__snapshots__/update-jest-config-ext.spec.ts.snap b/packages/jest/src/migrations/update-14-0-0/__snapshots__/update-jest-config-ext.spec.ts.snap index c058727ed8fef..d5a5826a709de 100644 --- a/packages/jest/src/migrations/update-14-0-0/__snapshots__/update-jest-config-ext.spec.ts.snap +++ b/packages/jest/src/migrations/update-14-0-0/__snapshots__/update-jest-config-ext.spec.ts.snap @@ -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: '/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: '/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 {}, +} +`; diff --git a/packages/jest/src/migrations/update-14-0-0/update-jest-config-ext.spec.ts b/packages/jest/src/migrations/update-14-0-0/update-jest-config-ext.spec.ts index f5914dde487b2..8e8c71d3ce2ef 100644 --- a/packages/jest/src/migrations/update-14-0-0/update-jest-config-ext.spec.ts +++ b/packages/jest/src/migrations/update-14-0-0/update-jest-config-ext.spec.ts @@ -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']); + }); }); diff --git a/packages/jest/src/migrations/update-14-0-0/update-jest-config-ext.ts b/packages/jest/src/migrations/update-14-0-0/update-jest-config-ext.ts index 69bf9c3915dc7..03bab41987400 100644 --- a/packages/jest/src/migrations/update-14-0-0/update-jest-config-ext.ts +++ b/packages/jest/src/migrations/update-14-0-0/update-jest-config-ext.ts @@ -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( 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; } diff --git a/packages/jest/src/migrations/update-14-1-5/__snapshots__/update-exports-jest-config.spec.ts.snap b/packages/jest/src/migrations/update-14-1-5/__snapshots__/update-exports-jest-config.spec.ts.snap new file mode 100644 index 0000000000000..af142b5a2ca9b --- /dev/null +++ b/packages/jest/src/migrations/update-14-1-5/__snapshots__/update-exports-jest-config.spec.ts.snap @@ -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: ['/src/test-setup.ts'], + globals: { + 'ts-jest': { + tsconfig: '/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: ['/src/test-setup.ts'], + globals: { + 'ts-jest': { + tsconfig: '/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', + ], +}; +" +`; diff --git a/packages/jest/src/migrations/update-14-1-5/update-exports-jest-config.spec.ts b/packages/jest/src/migrations/update-14-1-5/update-exports-jest-config.spec.ts new file mode 100644 index 0000000000000..61ccc54797ae9 --- /dev/null +++ b/packages/jest/src/migrations/update-14-1-5/update-exports-jest-config.spec.ts @@ -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: ['/src/test-setup.ts'], + globals: { + 'ts-jest': { + tsconfig: '/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: ['/src/test-setup.ts'], + globals: { + 'ts-jest': { + tsconfig: '/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(); + }); +}); diff --git a/packages/jest/src/migrations/update-14-1-5/update-exports-jest-config.ts b/packages/jest/src/migrations/update-14-1-5/update-exports-jest-config.ts new file mode 100644 index 0000000000000..8434833c9fc70 --- /dev/null +++ b/packages/jest/src/migrations/update-14-1-5/update-exports-jest-config.ts @@ -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( + 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; diff --git a/packages/jest/src/utils/config/__snapshots__/functions.spec.ts.snap b/packages/jest/src/utils/config/__snapshots__/functions.spec.ts.snap new file mode 100644 index 0000000000000..b8019bb491bba --- /dev/null +++ b/packages/jest/src/utils/config/__snapshots__/functions.spec.ts.snap @@ -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' + }" +`; diff --git a/packages/jest/src/utils/config/find-root-jest-files.ts b/packages/jest/src/utils/config/find-root-jest-files.ts index ba22b8e26fe30..1edd1a8793f41 100644 --- a/packages/jest/src/utils/config/find-root-jest-files.ts +++ b/packages/jest/src/utils/config/find-root-jest-files.ts @@ -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; } diff --git a/packages/jest/src/utils/config/functions.spec.ts b/packages/jest/src/utils/config/functions.spec.ts index 595604738591b..1982a9330b726 100644 --- a/packages/jest/src/utils/config/functions.spec.ts +++ b/packages/jest/src/utils/config/functions.spec.ts @@ -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: () => ['/project-a', '/project-b'], - })); - tree.write( - 'jest.config.js', - ` + xit('should work with async functions', async () => { + const tree = createTree(); + jest.mock('@nrwl/jest', () => ({ + getJestProjects: () => ['/project-a', '/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: () => ['/project-a', '/project-b'], - })); - tree.write( - 'jest.config.js', - ` + it('should work with `getJestConfig`', () => { + const tree = createTree(); + jest.mock('@nrwl/jest', () => ({ + getJestProjects: () => ['/project-a', '/project-b'], + })); + tree.write( + 'jest.config.js', + ` const { getJestProjects } = require('@nrwl/jest'); module.exports = { projects: getJestProjects() }; ` - ); + ); - expect(jestConfigObject(tree, 'jest.config.js')).toEqual({ - projects: ['/project-a', '/project-b'], + 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('@nrwl/jest', () => ({ - getJestProjects: () => ['/project-a', '/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: () => ['/project-a', '/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: ['/project-a', '/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(jestConfigObject(tree, 'jest.config.js')).toEqual({ - dirname: '/virtual', - filename: '/virtual/jest.config.js', - env: process.env, - projects: ['/project-a', '/project-b'], + expect(jestConfigObjectAst(content).getText()).toMatchSnapshot(); }); }); }); diff --git a/packages/jest/src/utils/config/functions.ts b/packages/jest/src/utils/config/functions.ts index cc6282eb05b2e..571ed6cc02ab5 100644 --- a/packages/jest/src/utils/config/functions.ts +++ b/packages/jest/src/utils/config/functions.ts @@ -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; + 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.` + ); + } + + ast = moduleExports.right as ts.ObjectLiteralExpression; + } else if (ts.isExportAssignment(exportStatement)) { + const defaultExport = + exportStatement.expression as ts.ObjectLiteralExpression; - if (!moduleExports) { + 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 provided jest config file does not have the expected 'module.exports' expression. - See https://jestjs.io/docs/en/configuration for more details.` + 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.` ); } - if (!ts.isObjectLiteralExpression(moduleExports.right)) { + if (!ts.isObjectLiteralExpression(ast)) { throw new Error( - `The 'module.exports' expression is not an object literal.` + `The 'export default' or 'module.exports' expression is not an object literal.` ); } - return moduleExports.right as ts.ObjectLiteralExpression; + 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, diff --git a/packages/js/src/generators/library/__snapshots__/library.spec.ts.snap b/packages/js/src/generators/library/__snapshots__/library.spec.ts.snap new file mode 100644 index 0000000000000..aaa14053ee3da --- /dev/null +++ b/packages/js/src/generators/library/__snapshots__/library.spec.ts.snap @@ -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' +}; +" +`; diff --git a/packages/js/src/generators/library/files/jest-config/jest.config.__ext__ b/packages/js/src/generators/library/files/jest-config/jest.config.__ext__ index 2937501e62745..acafb3c173142 100644 --- a/packages/js/src/generators/library/files/jest-config/jest.config.__ext__ +++ b/packages/js/src/generators/library/files/jest-config/jest.config.__ext__ @@ -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], }, diff --git a/packages/js/src/generators/library/library.spec.ts b/packages/js/src/generators/library/library.spec.ts index 305a1404e551a..c02b8b501c42c 100644 --- a/packages/js/src/generators/library/library.spec.ts +++ b/packages/js/src/generators/library/library.spec.ts @@ -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: '/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, { diff --git a/packages/js/src/generators/library/library.ts b/packages/js/src/generators/library/library.ts index 2fad2669785dd..223d8af9b16cb 100644 --- a/packages/js/src/generators/library/library.ts +++ b/packages/js/src/generators/library/library.ts @@ -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, diff --git a/packages/linter/src/generators/workspace-rules-project/__snapshots__/workspace-rules-project.spec.ts.snap b/packages/linter/src/generators/workspace-rules-project/__snapshots__/workspace-rules-project.spec.ts.snap index 4a0d6b98b410c..89be3050a8167 100644 --- a/packages/linter/src/generators/workspace-rules-project/__snapshots__/workspace-rules-project.spec.ts.snap +++ b/packages/linter/src/generators/workspace-rules-project/__snapshots__/workspace-rules-project.spec.ts.snap @@ -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: '/tsconfig.spec.json', diff --git a/packages/nest/src/generators/library/__snapshots__/library.spec.ts.snap b/packages/nest/src/generators/library/__snapshots__/library.spec.ts.snap index 130e8779108fb..e6a45c591e7f9 100644 --- a/packages/nest/src/generators/library/__snapshots__/library.spec.ts.snap +++ b/packages/nest/src/generators/library/__snapshots__/library.spec.ts.snap @@ -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: '/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: '/tsconfig.spec.json', diff --git a/packages/next/src/generators/application/lib/add-jest.ts b/packages/next/src/generators/application/lib/add-jest.ts index e17fec046681a..3237a4ebb664f 100644 --- a/packages/next/src/generators/application/lib/add-jest.ts +++ b/packages/next/src/generators/application/lib/add-jest.ts @@ -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; } ); diff --git a/packages/node/src/generators/application/application.spec.ts b/packages/node/src/generators/application/application.spec.ts index b08bf4ae2fd7a..1738836028c86 100644 --- a/packages/node/src/generators/application/application.spec.ts +++ b/packages/node/src/generators/application/application.spec.ts @@ -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' diff --git a/packages/node/src/generators/library/library.spec.ts b/packages/node/src/generators/library/library.spec.ts index b7091a8adbb9d..95919c10a5d38 100644 --- a/packages/node/src/generators/library/library.spec.ts +++ b/packages/node/src/generators/library/library.spec.ts @@ -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' diff --git a/packages/web/src/generators/application/application.spec.ts b/packages/web/src/generators/application/application.spec.ts index 1469652436cb5..842535151e5e9 100644 --- a/packages/web/src/generators/application/application.spec.ts +++ b/packages/web/src/generators/application/application.spec.ts @@ -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: ['/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: ['/src/test-setup.ts'], transform: { '^.+\\\\\\\\.[tj]s$': '@swc/jest' diff --git a/packages/workspace/src/generators/library/library.spec.ts b/packages/workspace/src/generators/library/library.spec.ts index e461a83d3f22a..b84ee7188df15 100644 --- a/packages/workspace/src/generators/library/library.spec.ts +++ b/packages/workspace/src/generators/library/library.spec.ts @@ -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: '/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' }, diff --git a/packages/workspace/src/generators/move/move.spec.ts b/packages/workspace/src/generators/move/move.spec.ts index ca9afbc43ca81..ca68e190d44c8 100644 --- a/packages/workspace/src/generators/move/move.spec.ts +++ b/packages/workspace/src/generators/move/move.spec.ts @@ -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'" );