jest-preset-angular: tests failing on angular 9 after running ngcc with @angular/localize

Describe the Bug

After running ngcc as proposed in the angular update guide (https://update.angular.io/#8.2:9.0), tests are failing with the error message

It looks like your application or one of its dependencies is using i18n.
Angular 9 introduced a global `$localize()` function that needs to be loaded.
Please run `ng add @angular/localize` from the Angular CLI.
(For non-CLI projects, add `import '@angular/localize/init';` to your `polyfills.ts` file.
For server-side rendering applications add the import to your `main.server.ts` file.)

I added a small reproduction below (updated and adapted the example app in this repository), where I installed @angular/localized with the help of the cli (ng add @angular/localized). It then added an import to the polyfills.ts files automatically (polyfills.ts). After I investigated a bit, I found out, that polyfills.ts is not picked up during the test run. When you add either import './polyfills'; or import '@angular/localize/init'; to setupJest.ts, the tests run successfully. But isn’t that what we have the tsconfig’s for? In tsconfig.spec.json for example, you can see that we have

"files": [
    "src/polyfills.ts"
  ]

What seems strange to me is and what I don’t understand is, that before you run ngcc, the tests run successfully, even though polyfills.ts is not picked up. However, I also don’t know exactly what ngcc is doing.

Minimal Reproduction

https://github.com/pkaufi/ngcc-i18n-jest/tree/jest-preset-angular

Expected Behavior

Tests should run successfully after running ngcc

Environment

see reproduction repository

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 12
  • Comments: 21

Most upvoted comments

This temporary solution works for me: jest.config.js

module.exports = {
    name: 'module-report',
    ...
    setupFiles: ['./setup-jest.ts']
};

setup-jest.js

import '@angular/localize/init';

FYI: ts-jest25.3.0 (has some downgrade in performance but will be fixed in 25.3.1) released which includes possibility to access internal ts Program created by ts-jest for any AST transformers.

Ivy does quite some magic under the hood, as it is a compiler. Instead of tackling all issues with ivy directly by implementing workarounds (which might become quite a lot the more people use jest + angular in edge cases), we decided to use the Angular Compiler itself wrapped in a jest transformer.

It is still a long way to go, but we are on the way (in our free time, unpaid). Shout-out to @ahnpnl for the ton of work he is currently putting in.

Subscribe #409 for more updates.

Due to the fact that testing with jest is different from Angular CLI karma + jasmine so any files which are required for test environment should be included in your setup jest file. On contrary, Angular CLI actually loads assets with webpack and browser will load all files including files like polyfills.ts

We can solve this difference by using AST transformer to inject polyfills, angular localized import or any global files into your setup jest, but this comes with a cost on performance (walking in AST tree is not free).

I would propose that adding polyfills.ts or import Angular localize in your test file is the best solution.

Ok! I will be free-ish from next week on, will definitely get into this then!

Hey! Thanks for reporting and providing a repro!

The ngcc (angular compatibility compiler) basically upgrades modules, that have not been compiled with the ivy compiler (ngtsc), to be compatible with it. In the README:.

This compiler will convert node_modules compiled with ngc, into node_modules which appear to have been compiled with ngtsc.

There are currently four types of code that have to be transformed, although the migrations itself are not defined inside the ngcc package (link to transformation calls):

  • Switch Marker
  • Decorators
  • Modules with providers
  • Private declarations

I personally do not have time to look into it before March, but I just had an idea. Maybe you can try to move the import to setupJest? Probably it won’t work though, as there are probably have to happen transformations during the compilation.

I’ll have a look at it in two weeks.