From 3c992a18b209f9d6500e34255b8f74c7fc5f3560 Mon Sep 17 00:00:00 2001 From: Ahn <27772165+ahnpnl@users.noreply.github.com> Date: Tue, 9 Nov 2021 14:02:54 +0100 Subject: [PATCH] fix(presets): add `mjs` to the list of `moduleFileExtensions` (#1155) Closes #1147 --- .github/PULL_REQUEST_TEMPLATE.md | 4 ---- .prettierignore | 5 +++++ LICENSE.md | 2 +- README.md | 4 ++-- e2e/__tests__/ng-deep-import.test.ts | 15 +++++++++++++++ e2e/async/jest-isolated.config.js | 6 ++++-- e2e/custom-typings/jest-isolated.config.js | 4 +++- .../__tests__/ng-deep-import.spec.ts | 5 +++++ e2e/ng-deep-import/jest-isolated.config.js | 10 ++++++++++ e2e/ng-deep-import/jest.config.js | 8 ++++++++ e2e/ng-deep-import/package.json | 3 +++ package.json | 4 ++-- presets/index.js | 2 +- .../__snapshots__/jest-preset.spec.ts.snap | 2 ++ src/zone-patch/README.md | 1 + website/docs/getting-started/options.md | 4 ++-- website/docs/guides/angular-13+.md | 18 +++++++++--------- .../version-10.x/getting-started/options.md | 2 +- .../version-8.x/getting-started/options.md | 2 +- .../version-9.x/getting-started/options.md | 2 +- 20 files changed, 76 insertions(+), 27 deletions(-) create mode 100644 .prettierignore create mode 100644 e2e/__tests__/ng-deep-import.test.ts create mode 100644 e2e/ng-deep-import/__tests__/ng-deep-import.spec.ts create mode 100644 e2e/ng-deep-import/jest-isolated.config.js create mode 100644 e2e/ng-deep-import/jest.config.js create mode 100644 e2e/ng-deep-import/package.json diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f503d60d08..757b6deafc 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,12 +4,10 @@ - ## Test plan - ## Does this PR introduce a breaking change? - [ ] Yes @@ -17,6 +15,4 @@ - ## Other information - diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..ce8433833e --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +build/ +node_modules/ +src/**/__snapshots__/ +e2e/__tests__/__snapshots__/ +CHANGELOG.md diff --git a/LICENSE.md b/LICENSE.md index 9e39ac6340..d3138196de 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/README.md b/README.md index e7e7b316fc..1aa866de12 100644 --- a/README.md +++ b/README.md @@ -73,9 +73,9 @@ Adjust your `tsconfig.spec.json` to be: } ``` -## Notes on usage with Angular >=13 +## Migration from Angular < 13 -Check out our [Angular >=13 usage notes](https://thymikee.github.io/jest-preset-angular/docs/next/guides/angular-13+) +Check out our [Migration from Angular < 13 guidance](https://thymikee.github.io/jest-preset-angular/docs/next/guides/angular-13+) ## Angular Ivy diff --git a/e2e/__tests__/ng-deep-import.test.ts b/e2e/__tests__/ng-deep-import.test.ts new file mode 100644 index 0000000000..99f70b2526 --- /dev/null +++ b/e2e/__tests__/ng-deep-import.test.ts @@ -0,0 +1,15 @@ +import { json as runWithJson } from '../run-jest'; + +const DIR = 'ng-deep-import'; + +test(`successfully runs the tests inside ${DIR} with isolatedModules: false`, () => { + const { json } = runWithJson(DIR); + + expect(json.success).toBe(true); +}); + +test(`successfully runs the tests inside ${DIR} with isolatedModules: true`, () => { + const { json } = runWithJson(DIR, ['-c=jest-isolated.config.js']); + + expect(json.success).toBe(true); +}); diff --git a/e2e/async/jest-isolated.config.js b/e2e/async/jest-isolated.config.js index 37f9113ed2..1ab56b5bf2 100644 --- a/e2e/async/jest-isolated.config.js +++ b/e2e/async/jest-isolated.config.js @@ -3,7 +3,9 @@ const baseCfg = require('./jest.config'); module.exports = { ...baseCfg, globals: { - ...baseCfg.globals['ts-jest'], - isolatedModules: true, + 'ts-jest': { + ...baseCfg.globals['ts-jest'], + isolatedModules: true, + }, }, }; diff --git a/e2e/custom-typings/jest-isolated.config.js b/e2e/custom-typings/jest-isolated.config.js index ef04755e58..307dd460ab 100644 --- a/e2e/custom-typings/jest-isolated.config.js +++ b/e2e/custom-typings/jest-isolated.config.js @@ -3,6 +3,8 @@ const baseCfg = require('./jest.config'); module.exports = { ...baseCfg, globals: { - isolatedModules: true, + 'ts-jest': { + isolatedModules: true, + }, }, }; diff --git a/e2e/ng-deep-import/__tests__/ng-deep-import.spec.ts b/e2e/ng-deep-import/__tests__/ng-deep-import.spec.ts new file mode 100644 index 0000000000..39f0e64819 --- /dev/null +++ b/e2e/ng-deep-import/__tests__/ng-deep-import.spec.ts @@ -0,0 +1,5 @@ +import localeFr from '@angular/common/locales/fr'; + +test('should work with deep import of Angular ESM package', () => { + expect(localeFr).toBeDefined(); +}); diff --git a/e2e/ng-deep-import/jest-isolated.config.js b/e2e/ng-deep-import/jest-isolated.config.js new file mode 100644 index 0000000000..307dd460ab --- /dev/null +++ b/e2e/ng-deep-import/jest-isolated.config.js @@ -0,0 +1,10 @@ +const baseCfg = require('./jest.config'); + +module.exports = { + ...baseCfg, + globals: { + 'ts-jest': { + isolatedModules: true, + }, + }, +}; diff --git a/e2e/ng-deep-import/jest.config.js b/e2e/ng-deep-import/jest.config.js new file mode 100644 index 0000000000..e408a10242 --- /dev/null +++ b/e2e/ng-deep-import/jest.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleFileExtensions: ['ts', 'html', 'js', 'json', 'mjs'], + resolver: '/../../build/resolvers/ng-jest-resolver.js', + transform: { + '^.+\\.(ts|js|mjs|html)$': '/../../build/index.js', + }, + transformIgnorePatterns: ['node_modules/(?!@angular)'], +}; diff --git a/e2e/ng-deep-import/package.json b/e2e/ng-deep-import/package.json new file mode 100644 index 0000000000..e9b31b3e6e --- /dev/null +++ b/e2e/ng-deep-import/package.json @@ -0,0 +1,3 @@ +{ + "name": "ng-deep-import" +} diff --git a/package.json b/package.json index a52a521c71..d43f97c71f 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,8 @@ "postinstall": "husky install", "lint": "eslint --ext .js,.ts .", "lint-fix": "eslint --fix --ext .js,.ts .", - "lint-prettier": "prettier '**/*.{yml,yaml}' 'website/**/*.{css,js,md}' 'README.md' --write --ignore-path .gitignore", - "lint-prettier-ci": "prettier '**/*.{yml,yaml}' 'website/**/*.{css,js,md}' 'README.md' --check --ignore-path .gitignore", + "lint-prettier": "prettier '**/*.{yml,yaml,md}' --write", + "lint-prettier-ci": "prettier '**/*.{yml,yaml,md}' --check", "pretest": "tsc -p tsconfig.spec.json --noEmit", "test-unit": "jest", "test-e2e": "jest -c=jest-e2e.config.js", diff --git a/presets/index.js b/presets/index.js index c159b1f1bd..099af0836a 100644 --- a/presets/index.js +++ b/presets/index.js @@ -9,7 +9,7 @@ const basePreset = { }, resolver: 'jest-preset-angular/build/resolvers/ng-jest-resolver.js', testEnvironment: 'jsdom', - moduleFileExtensions: ['ts', 'html', 'js', 'json'], + moduleFileExtensions: ['ts', 'html', 'js', 'json', 'mjs'], snapshotSerializers, }; diff --git a/src/__tests__/__snapshots__/jest-preset.spec.ts.snap b/src/__tests__/__snapshots__/jest-preset.spec.ts.snap index b347bc3295..e31f7def50 100644 --- a/src/__tests__/__snapshots__/jest-preset.spec.ts.snap +++ b/src/__tests__/__snapshots__/jest-preset.spec.ts.snap @@ -13,6 +13,7 @@ Object { "html", "js", "json", + "mjs", ], "resolver": "jest-preset-angular/build/resolvers/ng-jest-resolver.js", "snapshotSerializers": Array [ @@ -47,6 +48,7 @@ Object { "html", "js", "json", + "mjs", ], "moduleNameMapper": Object { "tslib": "tslib/tslib.es6.js", diff --git a/src/zone-patch/README.md b/src/zone-patch/README.md index 55a8fa7eec..f05a66af5d 100644 --- a/src/zone-patch/README.md +++ b/src/zone-patch/README.md @@ -1,4 +1,5 @@ # zone-patch + Enables Jest functions to be run within Zone.js context, specifically for [Angular](https://angular.io) apps. It's crucial to run this patch here, because at this point patched functions like `test` or `describe` are available in global scope. diff --git a/website/docs/getting-started/options.md b/website/docs/getting-started/options.md index 9ab48cfa97..4d4c51edd5 100644 --- a/website/docs/getting-started/options.md +++ b/website/docs/getting-started/options.md @@ -36,7 +36,7 @@ module.exports = { stringifyContentPathRegex: '\\.(html|svg)$', }, }, - moduleFileExtensions: ['ts', 'html', 'js', 'json'], + moduleFileExtensions: ['ts', 'html', 'js', 'json', 'mjs'], resolver: 'jest-preset-angular/build/resolvers/ng-jest-resolver.js', snapshotSerializers, testEnvironment: 'jsdom', @@ -57,7 +57,7 @@ Jest runs with `jest-preset-angular` neither in browser nor through dev server. ### Brief explanation of config - we're using some `"globals"` to pass information about where our tsconfig.json file is that we'd like to be able to transform HTML files through `ts-jest`. -- `"moduleFileExtensions"` – our modules are TypeScript and JavaScript files. +- `"moduleFileExtensions"` – our modules are TypeScript (`ts`), HTML (`html`), JavaScript (`js`), JSON (`json`) and ESM JavaScript (`mjs`) files. - `"moduleNameMapper"` – if you're using absolute imports here's how to tell Jest where to look for them; uses `RegExp`. - `"resolver"` - instruct Jest how to resolve entry file based on `package.json` definitions. - `"snapshotSerializers"` - array of serializers which will be applied to snapshot the code. Note: by default angular adds diff --git a/website/docs/guides/angular-13+.md b/website/docs/guides/angular-13+.md index d0b87abbaf..96c750c3b5 100644 --- a/website/docs/guides/angular-13+.md +++ b/website/docs/guides/angular-13+.md @@ -11,6 +11,8 @@ Starting from **11.0.0**, `jest-preset-angular` introduces a few extra changes t - `ng-jest-resolver` is introduced as a custom Jest resolver to resolve `.mjs` files. +- `moduleFileExtensions` is updated to include `mjs` files as accepted module format. + - `transformIgnorePatterns` is added to inform Jest to transform `.mjs` files. - `transform` is updated to include `.mjs` extension to transform to `CommonJS` codes. @@ -37,6 +39,7 @@ there are no migration steps required // jest.config.js module.exports = { // ...other options + moduleFileExtensions: ['ts', 'html', 'js', 'json', 'mjs'], resolver: 'jest-preset-angular/build/resolvers/ng-jest-resolver.js', transformIgnorePatterns: ['node_modules/(?!@angular)'], transform: { @@ -47,30 +50,27 @@ module.exports = { ## Potential issues with Angular 13 ESM package format and workaround -### Cannot import locale data from `@angular/common/locales` or any deep import paths +### `Cannot find modules` error when importing any deep paths from Angular ESM format packages -- Angular 13 ESM package format makes Jest resolution not able to resolve the correct locale files. Even though we introduced +- Angular 13 ESM package format makes Jest resolution not able to resolve the correct `.mjs` files. Even though we introduced `ng-jest-resolver` as a part of the preset, this resolver won't work for all scenarios. One might get Jest error like ``` Cannot find module '@angular/common/locales/xx' from 'src/app/app.component.spec.ts' ``` -To fix this issue, one needs to define -`moduleNameMapper` to instruct Jest where to find the files, e.g. +To fix this issue, one needs to add `mjs` to `moduleFileExtensions` as following ```js // jest.config.js module.exports = { // ...other options - moduleNameMapper: { - '@angular/common/locales/(.*)$': '/node_modules/@angular/common/locales/$1.mjs', - }, + moduleFileExtensions: ['ts', 'html', 'js', 'json', 'mjs'], }; ``` -- Another alternative solution is extending the default [resolver](https://github.com/thymikee/jest-preset-angular/blob/main/src/resolvers/ng-jest-resolver.ts) - of this preset to instruct Jest where to find the files. +If the issue still **persists**, you might need to configure [moduleNameMapper](https://jestjs.io/docs/configuration#modulenamemapper-objectstring-string--arraystring) +or extend the behavior the default [resolver](https://github.com/thymikee/jest-preset-angular/blob/main/src/resolvers/ng-jest-resolver.ts) of this preset. ### Usage with Angular libraries which are built with Angular CLI 13 diff --git a/website/versioned_docs/version-10.x/getting-started/options.md b/website/versioned_docs/version-10.x/getting-started/options.md index 6f83b3d410..6b4f76a48c 100644 --- a/website/versioned_docs/version-10.x/getting-started/options.md +++ b/website/versioned_docs/version-10.x/getting-started/options.md @@ -57,7 +57,7 @@ Jest runs with `jest-preset-angular` neither in browser nor through dev server. - we're using some `"globals"` to pass information about where our tsconfig.json file is that we'd like to be able to transform HTML files through `ts-jest`. - `"transform"` – run every TS, JS, or HTML file through so called _Jest transformer_; this lets Jest understand non-JS syntax. - `"testEnvironment"` – the test environment to run on. -- `"moduleFileExtensions"` – our modules are TypeScript and JavaScript files. +- `"moduleFileExtensions"` – our modules are TypeScript (`ts`), HTML (`html`), JavaScript (`js`) and JSON (`json`) files. - `"moduleNameMapper"` – if you're using absolute imports here's how to tell Jest where to look for them; uses regex. - `"snapshotSerializers"` - array of serializers which will be applied to snapshot the code. Note: by default angular adds some angular-specific attributes to the code (like `ng-reflect-*`, `ng-version="*"`, `_ngcontent-c*` etc). diff --git a/website/versioned_docs/version-8.x/getting-started/options.md b/website/versioned_docs/version-8.x/getting-started/options.md index ec2a60b4c0..46b2722584 100644 --- a/website/versioned_docs/version-8.x/getting-started/options.md +++ b/website/versioned_docs/version-8.x/getting-started/options.md @@ -55,7 +55,7 @@ to make `XHR` call for our templates and fail miserably. - we're using some `"globals"` to pass information about where our tsconfig.json file is that we'd like to be able to transform HTML files through `ts-jest`. - `"transform"` – run every TS, JS, or HTML file through so called _Jest transformer_; this lets Jest understand non-JS syntax. -- `"moduleFileExtensions"` – our modules are TypeScript and JavaScript files. +- `"moduleFileExtensions"` – our modules are TypeScript (`ts`), HTML (`html`), JavaScript (`js`) and JSON (`json`) files. - `"moduleNameMapper"` – if you're using absolute imports here's how to tell Jest where to look for them; uses regex. - `"transformIgnorePatterns"` – unfortunately some modules (like @ngrx) are released as TypeScript files, not pure JavaScript; in such cases we cannot ignore them (all node_modules are ignored by default), so they can be transformed through TS compiler diff --git a/website/versioned_docs/version-9.x/getting-started/options.md b/website/versioned_docs/version-9.x/getting-started/options.md index 6f83b3d410..6b4f76a48c 100644 --- a/website/versioned_docs/version-9.x/getting-started/options.md +++ b/website/versioned_docs/version-9.x/getting-started/options.md @@ -57,7 +57,7 @@ Jest runs with `jest-preset-angular` neither in browser nor through dev server. - we're using some `"globals"` to pass information about where our tsconfig.json file is that we'd like to be able to transform HTML files through `ts-jest`. - `"transform"` – run every TS, JS, or HTML file through so called _Jest transformer_; this lets Jest understand non-JS syntax. - `"testEnvironment"` – the test environment to run on. -- `"moduleFileExtensions"` – our modules are TypeScript and JavaScript files. +- `"moduleFileExtensions"` – our modules are TypeScript (`ts`), HTML (`html`), JavaScript (`js`) and JSON (`json`) files. - `"moduleNameMapper"` – if you're using absolute imports here's how to tell Jest where to look for them; uses regex. - `"snapshotSerializers"` - array of serializers which will be applied to snapshot the code. Note: by default angular adds some angular-specific attributes to the code (like `ng-reflect-*`, `ng-version="*"`, `_ngcontent-c*` etc).