diff --git a/e2e/async/__tests__/async-zone.test.ts b/e2e/async/__tests__/async-zone.test.ts new file mode 100644 index 0000000000..f14f80d282 --- /dev/null +++ b/e2e/async/__tests__/async-zone.test.ts @@ -0,0 +1,61 @@ +import type { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { Component } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { MatButtonModule } from '@angular/material/button'; +import { MatButtonHarness } from '@angular/material/button/testing'; +import { MATERIAL_SANITY_CHECKS } from '@angular/material/core'; + +@Component({ + selector: 'snd-button-page', + template: ` +

button-page works!

+

+ +

+ `, + styles: [], +}) +class ButtonPageComponent { + r = 0; + + click(): void { + this.r = 1; + } +} + +describe('ButtonPageComponent', () => { + let component: ButtonPageComponent; + let fixture: ComponentFixture; + let loader: HarnessLoader; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [MatButtonModule], + declarations: [ButtonPageComponent], + providers: [ + { + provide: MATERIAL_SANITY_CHECKS, + useValue: false, + }, + ], + }).compileComponents(); + fixture = TestBed.createComponent(ButtonPageComponent); + loader = TestbedHarnessEnvironment.loader(fixture); + }); + + beforeEach(() => { + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should click', async () => { + const button = await loader.getHarness(MatButtonHarness); + await button.click(); + expect(component.r).toBe(1); + }); +}); diff --git a/e2e/async/jest-esm.config.js b/e2e/async/jest-esm.config.js index c6fa203589..a02f745d06 100644 --- a/e2e/async/jest-esm.config.js +++ b/e2e/async/jest-esm.config.js @@ -1,13 +1,23 @@ +const jestCfg = require('./jest.config'); + /** @type {import('ts-jest/dist/types').ProjectConfigTsJest} */ module.exports = { - displayName: 'async', - preset: '/../../node_modules/ts-jest/presets/default-esm', + ...jestCfg, globals: { 'ts-jest': { useESM: true, - tsconfig: '/../tsconfig-esm.json', + tsconfig: { + ...require('../tsconfig-esm.json').compilerOptions, + /** + * Set at ES2018 to test Angular doesn't work with ES2017+ + * see https://github.com/angular/components/issues/21632#issuecomment-764975917 + */ + target: 'ES2018', + }, }, }, - setupFilesAfterEnv: ['/../../setup-jest.js'], - transform: { '^.+\\.(ts|js|html)$': '/../../build/index.js' }, + moduleNameMapper: { + tslib: 'tslib/tslib.es6.js', + }, + transformIgnorePatterns: ['node_modules/(?!tslib)'], }; diff --git a/e2e/async/jest.config.js b/e2e/async/jest.config.js index 08553118ed..e06d22928a 100644 --- a/e2e/async/jest.config.js +++ b/e2e/async/jest.config.js @@ -3,9 +3,17 @@ module.exports = { displayName: 'async', globals: { 'ts-jest': { - tsconfig: '/../tsconfig.json', + tsconfig: { + ...require('../tsconfig.json').compilerOptions, + /** + * Set at ES2018 to test Angular doesn't work with ES2017+ + * see https://github.com/angular/components/issues/21632#issuecomment-764975917 + */ + target: 'ES2018', + }, }, }, + testEnvironment: 'jsdom', setupFilesAfterEnv: ['/../../setup-jest.js'], transform: { '^.+\\.(ts|js|html)$': '/../../build/index.js' }, }; diff --git a/package.json b/package.json index a43bb066a3..87ec801248 100644 --- a/package.json +++ b/package.json @@ -53,10 +53,14 @@ "@angular/platform-browser-dynamic": ">=10.0.0" }, "devDependencies": { + "@angular/animations": "^12.2.11", + "@angular/cdk": "^12.2.11", "@angular/common": "^12.2.11", "@angular/compiler": "^12.2.11", "@angular/compiler-cli": "^12.2.11", "@angular/core": "^12.2.11", + "@angular/forms": "^12.2.11", + "@angular/material": "^12.2.11", "@angular/platform-browser": "^12.2.11", "@angular/platform-browser-dynamic": "^12.2.11", "@babel/core": "^7.15.5", diff --git a/src/__tests__/ng-jest-config.spec.ts b/src/__tests__/ng-jest-config.spec.ts index 123a7d75b3..c36ba7143e 100644 --- a/src/__tests__/ng-jest-config.spec.ts +++ b/src/__tests__/ng-jest-config.spec.ts @@ -1,3 +1,5 @@ +import ts from 'typescript'; + import { NgJestConfig } from '../config/ng-jest-config'; describe('NgJestConfig', () => { @@ -11,5 +13,21 @@ describe('NgJestConfig', () => { expect(compilerOptions.annotationsAs).toBe('decorators'); expect(compilerOptions.enableResourceInlining).toBe(false); expect(compilerOptions.allowJs).toBe(true); + expect(compilerOptions.target).toBe(ts.ScriptTarget.ES2015); + }); + + test('should set typescript target to ES2015 if user is using target higher than ES2016', () => { + expect( + new NgJestConfig({ + globals: { + 'ts-jest': { + tsconfig: { + target: 'ES2017', + }, + }, + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any).parsedTsConfig.options.target, + ).toBe(ts.ScriptTarget.ES2015); }); }); diff --git a/src/config/ng-jest-config.ts b/src/config/ng-jest-config.ts index d3fbbf4d56..97f9072b04 100644 --- a/src/config/ng-jest-config.ts +++ b/src/config/ng-jest-config.ts @@ -7,7 +7,7 @@ export class NgJestConfig extends ConfigSet { * Override `ts-jest` behavior because we use `readConfiguration` which will read and resolve tsconfig. */ protected _resolveTsConfig(compilerOptions?: RawCompilerOptions, resolvedConfigFile?: string): ParsedCommandLine { - const result = super._resolveTsConfig(compilerOptions, resolvedConfigFile); + const result = super._resolveTsConfig(compilerOptions, resolvedConfigFile) as ParsedCommandLine; result.options.enableIvy = true; result.options.noEmitOnError = false; result.options.suppressOutputPathCheck = true; @@ -16,7 +16,13 @@ export class NgJestConfig extends ConfigSet { result.options.enableResourceInlining = false; // Since we define preset default also transform `js` so we need to set `allowJs` true result.options.allowJs = true; + const ts = this.compilerModule; + const scriptTarget = result.options.target ?? ts.ScriptTarget?.ES2015; + if (scriptTarget > ts.ScriptTarget?.ES2016) { + // See https://github.com/angular/components/issues/21632#issuecomment-764975917 + result.options.target = ts.ScriptTarget?.ES2015; + } - return result as ParsedCommandLine; + return result; } } diff --git a/tsconfig.json b/tsconfig.json index 546c81c281..f8079bd39f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,8 @@ "skipLibCheck": true, "importHelpers": true, "esModuleInterop": true, - "target": "es2015", + "moduleResolution": "Node", + "target": "ES2015", "module": "CommonJS", "lib": ["esnext", "dom"], "types": ["node", "jest"] diff --git a/yarn.lock b/yarn.lock index 6545c7d255..3f7f94e87c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,22 @@ # yarn lockfile v1 +"@angular/animations@^12.2.11": + version "12.2.11" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-12.2.11.tgz#ada712ba0c9d28d2609da8adb13badcc57638217" + integrity sha512-J6tXNCEgI3SYPfFy9F0QDQNx0g4F8gfJA05iaf6scpZvqziQ80g0vwrBQdV6JqkFvSPQqLJDxyIxDQJSrCt8YA== + dependencies: + tslib "^2.2.0" + +"@angular/cdk@^12.2.11": + version "12.2.11" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-12.2.11.tgz#e4f9f45508a0a808eba0b7f6df86e20c86df8306" + integrity sha512-GgBB3NdVSv6RnDDOMspeLGg3uCbbmWIEIQ9VIqT5TWXWnljd2EANOQWdLu+fkmRzJn66FFdlTtJ6rHYoY/oBkA== + dependencies: + tslib "^2.2.0" + optionalDependencies: + parse5 "^5.0.0" + "@angular/common@^12.2.11": version "12.2.11" resolved "https://registry.yarnpkg.com/@angular/common/-/common-12.2.11.tgz#46b62009d57c187a9a838d9021dcd928073ebc3c" @@ -43,6 +59,20 @@ dependencies: tslib "^2.2.0" +"@angular/forms@^12.2.11": + version "12.2.11" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-12.2.11.tgz#7994d6fb659851d104fe61c17b7eac84edb942d8" + integrity sha512-mylti7rtz2FcM3hwPSj2JnX8y8BrXmzrjEWjcLlXmwoMzv/M3vY5HlgKzOmPN03bVgxC7b7EFfGMXfJ3YoPWpg== + dependencies: + tslib "^2.2.0" + +"@angular/material@^12.2.11": + version "12.2.11" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-12.2.11.tgz#87d78d3e8d42373fa170aa2b9aeb0b039bae30be" + integrity sha512-3SIraessvZRfUgUA9LsJ0OUmvdm0ePj4v81l5uMRF9uUMVoM6OrW8MmIMzS1vAoHz9bpDakx5Xz3yqgZGco5Zw== + dependencies: + tslib "^2.2.0" + "@angular/platform-browser-dynamic@^12.2.11": version "12.2.11" resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-12.2.11.tgz#1340b35f5b3cdba118900da6bea87c8f90096dbf" @@ -4674,6 +4704,11 @@ parse5@6.0.1: resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== +parse5@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== + path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"