From 1bca34777ae9c909f519cd934f2254f5c2bcb9e5 Mon Sep 17 00:00:00 2001 From: Caleb Ukle Date: Fri, 17 Mar 2023 07:32:30 -0700 Subject: [PATCH] fix(testing): use es2016 for jest-preset-angular projects (#15646) --- packages/angular/migrations.json | 6 + .../update-testing-tsconfig.spec.ts | 106 ++++++++++++++++++ .../update-15-9-0/update-testing-tsconfig.ts | 60 ++++++++++ .../files-angular/tsconfig.spec.json__tmpl__ | 1 + .../jest-project/jest-project.spec.ts | 1 + 5 files changed, 174 insertions(+) create mode 100644 packages/angular/src/migrations/update-15-9-0/update-testing-tsconfig.spec.ts create mode 100644 packages/angular/src/migrations/update-15-9-0/update-testing-tsconfig.ts diff --git a/packages/angular/migrations.json b/packages/angular/migrations.json index 3cae3a1b2b..6b20adf595 100644 --- a/packages/angular/migrations.json +++ b/packages/angular/migrations.json @@ -152,6 +152,12 @@ "version": "15.8.0-beta.4", "description": "Update the @angular/cli package version to ~15.2.0.", "factory": "./src/migrations/update-15-8-0/update-angular-cli" + }, + "update-tsconfig-spec-jest": { + "cli": "nx", + "version": "15.9.0-beta.3", + "description": "Update the tsconfig.spec.json to use target es2016 for jest-preset-angular v13", + "factory": "./src/migrations/update-15-9-0/update-testing-tsconfig" } }, "packageJsonUpdates": { diff --git a/packages/angular/src/migrations/update-15-9-0/update-testing-tsconfig.spec.ts b/packages/angular/src/migrations/update-15-9-0/update-testing-tsconfig.spec.ts new file mode 100644 index 0000000000..712f0c63c0 --- /dev/null +++ b/packages/angular/src/migrations/update-15-9-0/update-testing-tsconfig.spec.ts @@ -0,0 +1,106 @@ +import { + ProjectGraph, + readJson, + readProjectConfiguration, + Tree, + updateJson, +} from '@nrwl/devkit'; +import { createTreeWithEmptyWorkspace } from 'nx/src/devkit-testing-exports'; +import applicationGenerator from '../../generators/application/application'; +import libraryGenerator from '../../generators/library/library'; +import { updateTestingTsconfigForJest } from './update-testing-tsconfig'; + +let projectGraph: ProjectGraph; +jest.mock('@nrwl/devkit', () => ({ + ...jest.requireActual('@nrwl/devkit'), + createProjectGraphAsync: jest.fn().mockImplementation(async () => { + return projectGraph; + }), +})); +describe('Jest+Ng - 15.9.0 - tsconfig updates', () => { + let tree: Tree; + beforeEach(() => { + tree = createTreeWithEmptyWorkspace(); + tree.write('.gitignore', ''); + }); + + it('should update tsconfig.spec.json with target es2016', async () => { + await setup(tree, 'proj'); + await updateTestingTsconfigForJest(tree); + expect( + readJson(tree, 'proj/tsconfig.spec.json').compilerOptions.target + ).toEqual('es2016'); + expect( + readJson(tree, 'proj-lib/tsconfig.spec.json').compilerOptions.target + ).toEqual('es2016'); + }); + + it('should not change tsconfig.spec.json target if already set', async () => { + await setup(tree, 'proj'); + updateJson(tree, 'proj/tsconfig.spec.json', (json) => { + json.compilerOptions.target = 'es2015'; + return json; + }); + await updateTestingTsconfigForJest(tree); + expect( + readJson(tree, 'proj/tsconfig.spec.json').compilerOptions.target + ).toEqual('es2015'); + expect( + readJson(tree, 'proj-lib/tsconfig.spec.json').compilerOptions.target + ).toEqual('es2016'); + }); + + it('should not change tsconfig.spec.json target if not jest-preset-angular', async () => { + await setup(tree, 'proj'); + const updated = tree + .read('proj/jest.config.ts', 'utf-8') + .replace(/jest-preset-angular/g, ''); + tree.write('proj/jest.config.ts', updated); + + await updateTestingTsconfigForJest(tree); + expect( + readJson(tree, 'proj/tsconfig.spec.json').compilerOptions.target + ).toBeUndefined(); + expect( + readJson(tree, 'proj-lib/tsconfig.spec.json').compilerOptions.target + ).toEqual('es2016'); + }); +}); + +async function setup(tree: Tree, name: string) { + await applicationGenerator(tree, { + name, + skipPackageJson: true, + }); + + updateJson(tree, `${name}/tsconfig.spec.json`, (json) => { + // revert to before jest-preset-angular v13 + delete json.compilerOptions.target; + return json; + }); + + await libraryGenerator(tree, { + name: `${name}-lib`, + }); + + updateJson(tree, `${name}/tsconfig.spec.json`, (json) => { + // revert to before jest-preset-angular v13 + delete json.compilerOptions.target; + return json; + }); + projectGraph = { + dependencies: {}, + nodes: { + [name]: { + name, + type: 'app', + data: readProjectConfiguration(tree, name), + } as any, + [`${name}-lib`]: { + name: `${name}-lib`, + type: 'lib', + data: readProjectConfiguration(tree, `${name}-lib`), + } as any, + }, + }; +} diff --git a/packages/angular/src/migrations/update-15-9-0/update-testing-tsconfig.ts b/packages/angular/src/migrations/update-15-9-0/update-testing-tsconfig.ts new file mode 100644 index 0000000000..8eabea510c --- /dev/null +++ b/packages/angular/src/migrations/update-15-9-0/update-testing-tsconfig.ts @@ -0,0 +1,60 @@ +import { + createProjectGraphAsync, + getProjects, + joinPathFragments, + Tree, + updateJson, +} from '@nrwl/devkit'; +import { forEachExecutorOptionsInGraph } from '@nrwl/devkit/src/generators/executor-options-utils'; +import type { JestExecutorOptions } from '@nrwl/jest/src/executors/jest/schema'; + +export async function updateTestingTsconfigForJest(tree: Tree) { + const graph = await createProjectGraphAsync(); + const projects = getProjects(tree); + forEachExecutorOptionsInGraph( + graph, + '@nrwl/jest:jest', + (options, projectName) => { + const projectConfig = projects.get(projectName); + + if (!isJestPresetAngular(tree, options.jestConfig)) { + return; + } + const tsconfigPath = joinPathFragments( + projectConfig.root, + 'tsconfig.spec.json' + ); + + if (tree.exists(tsconfigPath)) { + updateJson( + tree, + tsconfigPath, + (json) => { + json.compilerOptions ??= {}; + json.compilerOptions.target ??= 'es2016'; + + return json; + }, + { expectComments: true, allowTrailingComma: true } + ); + } + } + ); +} + +function isJestPresetAngular(tree: Tree, jestConfigPath: string) { + if (jestConfigPath && tree.exists(jestConfigPath)) { + const contents = tree.read(jestConfigPath, 'utf-8'); + + return contents.includes('jest-preset-angular'); + } + return false; +} + +export default updateTestingTsconfigForJest; + +interface TsConfig { + compilerOptions: { + target?: string; + }; +} diff --git a/packages/jest/src/generators/jest-project/files-angular/tsconfig.spec.json__tmpl__ b/packages/jest/src/generators/jest-project/files-angular/tsconfig.spec.json__tmpl__ index 534bbd8701..3307b9d362 100644 --- a/packages/jest/src/generators/jest-project/files-angular/tsconfig.spec.json__tmpl__ +++ b/packages/jest/src/generators/jest-project/files-angular/tsconfig.spec.json__tmpl__ @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "<%= offsetFromRoot %>dist/out-tsc", "module": "commonjs", + "target": "es2016", "types": ["jest", "node"] },<% if(setupFile !== 'none') { %> "files": ["src/test-setup.ts"],<% } %> 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 2381d0f361..c53d7886a3 100644 --- a/packages/jest/src/generators/jest-project/jest-project.spec.ts +++ b/packages/jest/src/generators/jest-project/jest-project.spec.ts @@ -123,6 +123,7 @@ describe('jestProject', () => { module: 'commonjs', outDir: '../../dist/out-tsc', types: ['jest', 'node'], + target: 'es2016', }, files: ['src/test-setup.ts'], include: [