Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7a270b1

Browse files
committedNov 22, 2024
feat: support config zoneless env for CJS
1 parent 9677d79 commit 7a270b1

23 files changed

+365
-113
lines changed
 

‎.editorconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ tab_width = 4
1919
[*.{yml, yaml}]
2020
indent_size = 2
2121

22-
[*.{js,jsx,ts,tsx}]
22+
[*.{js,jsx,ts,tsx,mjs,mjsx,tsx,mtsx}]
2323
indent_size = 4
2424

2525
[*.html]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { TestBed } from '@angular/core/testing';
2+
3+
import { FooComponent } from '../foo.component';
4+
5+
describe('FooComponent', () => {
6+
it('should trigger change detection without fixture.detectChanges', () => {
7+
TestBed.configureTestingModule({
8+
imports: [FooComponent],
9+
});
10+
const fixture = TestBed.createComponent(FooComponent);
11+
12+
expect(fixture.componentInstance.value1()).toBe('val1');
13+
14+
fixture.componentRef.setInput('value1', 'hello');
15+
16+
expect(fixture.componentInstance.value1()).toBe('hello');
17+
});
18+
});

‎e2e/zoneless-env/foo.component.html

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!-- SOMETHING -->
2+
<p>Line 1</p>
3+
<div>
4+
<div *ngIf="condition1">
5+
{{ value1() }}
6+
</div>
7+
<span *ngIf="condition2">
8+
{{ value2() }}
9+
</span>
10+
</div>

‎e2e/zoneless-env/foo.component.scss

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
p {
2+
font-size: 1.6rem;
3+
}

‎e2e/zoneless-env/foo.component.ts

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { NgIf } from '@angular/common';
2+
import { Component, input } from '@angular/core';
3+
4+
@Component({
5+
selector: 'foo',
6+
standalone: true,
7+
templateUrl: './foo.component.html',
8+
styleUrls: ['./foo.component.scss'],
9+
// we have to setup styles this way, since simple styles/styleUrs properties will be removed (jest does not unit test styles)
10+
styles: [
11+
`
12+
p {
13+
color: red;
14+
}
15+
`,
16+
],
17+
imports: [NgIf],
18+
})
19+
export class FooComponent {
20+
readonly value1 = input('val1');
21+
readonly value2 = input('val2');
22+
23+
protected readonly condition1 = true;
24+
protected readonly condition2 = false;
25+
}

‎e2e/zoneless-env/jest-cjs.config.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import type { JestConfigWithTsJest } from 'ts-jest';
2+
3+
const config: JestConfigWithTsJest = {
4+
displayName: 'e2e-zoneless-env',
5+
testEnvironment: 'jsdom',
6+
snapshotSerializers: [
7+
'<rootDir>/../../build/serializers/html-comment',
8+
'<rootDir>/../../build/serializers/ng-snapshot',
9+
'<rootDir>/../../build/serializers/no-ng-attributes',
10+
],
11+
setupFilesAfterEnv: ['./setup-zoneless-env.ts'],
12+
transform: {
13+
'^.+\\.(ts|js|mjs|html)$': [
14+
'<rootDir>/../../build/index.js',
15+
{
16+
tsconfig: '<rootDir>/tsconfig-cjs.spec.json',
17+
stringifyContentPathRegex: '\\.(html|svg)$',
18+
},
19+
],
20+
},
21+
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
22+
};
23+
24+
export default config;

‎e2e/zoneless-env/jest-esm.config.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import type { JestConfigWithTsJest } from 'ts-jest';
2+
3+
const config: JestConfigWithTsJest = {
4+
displayName: 'e2e-zoneless-env',
5+
testEnvironment: 'jsdom',
6+
snapshotSerializers: [
7+
'<rootDir>/../../build/serializers/html-comment',
8+
'<rootDir>/../../build/serializers/ng-snapshot',
9+
'<rootDir>/../../build/serializers/no-ng-attributes',
10+
],
11+
setupFilesAfterEnv: ['./setup-zoneless-env.mts'],
12+
moduleNameMapper: {
13+
rxjs: '<rootDir>/../../node_modules/rxjs/dist/bundles/rxjs.umd.js',
14+
},
15+
extensionsToTreatAsEsm: ['.ts', '.mts'],
16+
transform: {
17+
'^.+\\.(ts|mts|js|mjs|html)$': [
18+
'<rootDir>/../../build/index.js',
19+
{
20+
useESM: true,
21+
tsconfig: '<rootDir>/tsconfig-esm.spec.json',
22+
stringifyContentPathRegex: '\\.(html|svg)$',
23+
},
24+
],
25+
},
26+
};
27+
28+
export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { JestConfigWithTsJest } from 'ts-jest';
2+
3+
const config: JestConfigWithTsJest = {
4+
displayName: 'e2e-snapshot-serializers',
5+
testEnvironment: 'jsdom',
6+
snapshotSerializers: [
7+
'<rootDir>/../../build/serializers/html-comment',
8+
'<rootDir>/../../build/serializers/ng-snapshot',
9+
'<rootDir>/../../build/serializers/no-ng-attributes',
10+
],
11+
setupFilesAfterEnv: ['./setup-zoneless-env.ts'],
12+
transform: {
13+
'^.+\\.(ts|js|mjs|html)$': [
14+
'<rootDir>/../../build/index.js',
15+
{
16+
tsconfig: '<rootDir>/tsconfig-cjs.spec.json',
17+
stringifyContentPathRegex: '\\.(html|svg)$',
18+
isolatedModules: true,
19+
},
20+
],
21+
},
22+
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
23+
};
24+
25+
export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import type { JestConfigWithTsJest } from 'ts-jest';
2+
3+
const config: JestConfigWithTsJest = {
4+
displayName: 'e2e-snapshot-serializers',
5+
testEnvironment: 'jsdom',
6+
snapshotSerializers: [
7+
'<rootDir>/../../build/serializers/html-comment',
8+
'<rootDir>/../../build/serializers/ng-snapshot',
9+
'<rootDir>/../../build/serializers/no-ng-attributes',
10+
],
11+
setupFilesAfterEnv: ['./setup-zoneless-env.mts'],
12+
moduleNameMapper: {
13+
rxjs: '<rootDir>/../../node_modules/rxjs/dist/bundles/rxjs.umd.js',
14+
},
15+
extensionsToTreatAsEsm: ['.ts', '.mts'],
16+
transform: {
17+
'^.+\\.(ts|mts|js|mjs|html)$': [
18+
'<rootDir>/../../build/index.js',
19+
{
20+
useESM: true,
21+
tsconfig: '<rootDir>/tsconfig-esm.spec.json',
22+
stringifyContentPathRegex: '\\.(html|svg)$',
23+
isolatedModules: true,
24+
},
25+
],
26+
},
27+
};
28+
29+
export default config;
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { setupZonelessTestEnv } from '../../setup-env/zoneless/index.mjs';
2+
3+
setupZonelessTestEnv();
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { setupZonelessTestEnv } from '../../setup-env/zoneless';
2+
3+
setupZonelessTestEnv();
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "../../tsconfig-base.spec.json"
3+
}
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "../../tsconfig-base.spec.json",
3+
"compilerOptions": {
4+
"module": "ES2022",
5+
"esModuleInterop": true
6+
}
7+
}
+8-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { TextDecoder, TextEncoder } from 'util';
1+
const { TextDecoder, TextEncoder } = require('util');
22

3-
export const polyfillEncoder = () => {
3+
const polyfillEncoder = () => {
44
if (typeof globalThis.TextEncoder === 'undefined') {
55
globalThis.TextEncoder = TextEncoder;
66
globalThis.TextDecoder = TextDecoder;
77
}
88
};
99

10-
export const resolveTestEnvOptions = (options) => {
10+
const resolveTestEnvOptions = (options) => {
1111
const globalTestEnvOptions = globalThis.ngJest?.testEnvironmentOptions;
1212
if (globalTestEnvOptions) {
1313
console.warn(
@@ -17,3 +17,8 @@ export const resolveTestEnvOptions = (options) => {
1717

1818
return globalTestEnvOptions ?? options;
1919
};
20+
21+
module.exports = {
22+
polyfillEncoder,
23+
resolveTestEnvOptions,
24+
};

‎setup-env/zone/index.js

+2-20
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,20 @@
11
require('zone.js');
22
require('zone.js/testing');
33

4-
const { TextEncoder, TextDecoder } = require('util');
5-
64
const { getTestBed } = require('@angular/core/testing');
75
const {
86
BrowserDynamicTestingModule,
97
platformBrowserDynamicTesting,
108
} = require('@angular/platform-browser-dynamic/testing');
119

12-
const polyfillEncoder = () => {
13-
if (typeof globalThis.TextEncoder === 'undefined') {
14-
globalThis.TextEncoder = TextEncoder;
15-
globalThis.TextDecoder = TextDecoder;
16-
}
17-
};
18-
19-
const resolveTestEnvOptions = (options) => {
20-
const globalTestEnvOptions = globalThis.ngJest?.testEnvironmentOptions;
21-
if (globalTestEnvOptions) {
22-
console.warn(
23-
'Setting testEnvironmentOptions via globalThis.ngJest is deprecated. Please provide testEnvironmentOptions via function argument',
24-
);
25-
}
26-
27-
return globalTestEnvOptions ?? options;
28-
};
10+
const { polyfillEncoder, resolveTestEnvOptions } = require('../utils');
2911

3012
const setupZoneTestEnv = (options) => {
3113
polyfillEncoder();
3214
const testEnvironmentOptions = resolveTestEnvOptions(options);
3315

3416
getTestBed().initTestEnvironment(
35-
BrowserDynamicTestingModule,
17+
[BrowserDynamicTestingModule],
3618
platformBrowserDynamicTesting(),
3719
testEnvironmentOptions,
3820
);

‎setup-env/zone/index.mjs

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@ import 'zone.js/testing';
44
import { getTestBed } from '@angular/core/testing';
55
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
66

7-
import { polyfillEncoder, resolveTestEnvOptions } from '../utils.mjs';
7+
import { polyfillEncoder, resolveTestEnvOptions } from '../utils';
88

9-
export const setupZoneTestEnv = (options) => {
9+
const setupZoneTestEnv = (options) => {
1010
polyfillEncoder();
1111
const testEnvironmentOptions = resolveTestEnvOptions(options);
1212

1313
getTestBed().initTestEnvironment(
14-
BrowserDynamicTestingModule,
14+
[BrowserDynamicTestingModule],
1515
platformBrowserDynamicTesting(),
1616
testEnvironmentOptions,
1717
);
1818
};
19+
20+
export {
21+
setupZoneTestEnv,
22+
}

‎setup-env/zoneless/index.js

+44-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,48 @@
1-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2-
const setupZonelessTestEnv = (_options) => {
1+
const { provideExperimentalZonelessChangeDetection, NgModule, ErrorHandler } = require('@angular/core');
2+
const { getTestBed } = require('@angular/core/testing');
3+
const {
4+
BrowserDynamicTestingModule,
5+
platformBrowserDynamicTesting,
6+
} = require('@angular/platform-browser-dynamic/testing');
7+
8+
const { polyfillEncoder, resolveTestEnvOptions } = require('../utils');
9+
10+
const provideZonelessConfig = () => {
11+
class TestModule {}
12+
NgModule({
13+
providers: [
14+
provideExperimentalZonelessChangeDetection(),
15+
{
16+
provide: ErrorHandler,
17+
useValue: {
18+
handleError: (e) => {
19+
throw e;
20+
},
21+
},
22+
},
23+
],
24+
})(TestModule);
25+
26+
return TestModule;
27+
};
28+
29+
const setupZonelessTestEnv = (options) => {
30+
polyfillEncoder();
31+
if (typeof provideExperimentalZonelessChangeDetection !== 'undefined') {
32+
const testEnvironmentOptions = resolveTestEnvOptions(options);
33+
34+
getTestBed().initTestEnvironment(
35+
[BrowserDynamicTestingModule, provideZonelessConfig()],
36+
platformBrowserDynamicTesting(),
37+
testEnvironmentOptions,
38+
);
39+
40+
return;
41+
}
42+
343
throw Error(
4-
'Zoneless testing environment only works when running Jest in ESM mode with Jest 29. ' +
5-
'Jest 30+ will support to work with CommonJS mode.',
44+
'Cannot find provideExperimentalZonelessChangeDetection() to setup zoneless testing environment. ' +
45+
'Please use setupZoneTestEnv() from jest-preset-angular/setup-env/setup-zone-env.mjs instead.',
646
);
747
};
848

‎setup-env/zoneless/index.mjs

+28-19
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,34 @@ import { ErrorHandler, NgModule, provideExperimentalZonelessChangeDetection } fr
22
import { getTestBed } from '@angular/core/testing';
33
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
44

5-
import { polyfillEncoder, resolveTestEnvOptions } from '../utils.mjs';
5+
import { polyfillEncoder, resolveTestEnvOptions } from '../utils';
66

7-
export const setupZonelessTestEnv = (options) => {
8-
if (typeof provideExperimentalZonelessChangeDetection !== 'undefined') {
9-
polyfillEncoder();
10-
const testEnvironmentOptions = resolveTestEnvOptions(options);
11-
@NgModule({
12-
providers: [
13-
provideExperimentalZonelessChangeDetection(),
14-
{
15-
provide: ErrorHandler,
16-
useValue: {
17-
handleError: (e) => {
18-
throw e;
19-
},
7+
const provideZonelessConfig = () => {
8+
class TestModule {}
9+
NgModule({
10+
providers: [
11+
provideExperimentalZonelessChangeDetection(),
12+
{
13+
provide: ErrorHandler,
14+
useValue: {
15+
handleError: (e) => {
16+
throw e;
2017
},
2118
},
22-
],
23-
})
24-
export class TestModule {}
19+
},
20+
],
21+
})(TestModule);
22+
23+
return TestModule;
24+
};
25+
26+
const setupZonelessTestEnv = (options) => {
27+
polyfillEncoder();
28+
if (typeof provideExperimentalZonelessChangeDetection !== 'undefined') {
29+
const testEnvironmentOptions = resolveTestEnvOptions(options);
2530

2631
getTestBed().initTestEnvironment(
27-
[BrowserDynamicTestingModule, TestModule],
32+
[BrowserDynamicTestingModule, provideZonelessConfig()],
2833
platformBrowserDynamicTesting(),
2934
testEnvironmentOptions,
3035
);
@@ -34,6 +39,10 @@ export const setupZonelessTestEnv = (options) => {
3439

3540
throw Error(
3641
'Cannot find provideExperimentalZonelessChangeDetection() to setup zoneless testing environment. ' +
37-
'Please use setupZoneTestEnv() from jest-preset-angular/setup-env/setup-zone-env.mjs instead.',
42+
'Please use setupZoneTestEnv() from jest-preset-angular/setup-env/setup-zone-env.mjs instead.',
3843
);
3944
};
45+
46+
export {
47+
setupZonelessTestEnv
48+
}

‎setup-jest.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,8 @@ if (typeof globalThis.TextEncoder === 'undefined') {
2525

2626
const testEnvironmentOptions = globalThis.ngJest?.testEnvironmentOptions ?? Object.create(null);
2727

28-
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), testEnvironmentOptions);
28+
getTestBed().initTestEnvironment(
29+
[BrowserDynamicTestingModule],
30+
platformBrowserDynamicTesting(),
31+
testEnvironmentOptions,
32+
);

‎setup-jest.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ if (typeof globalThis.TextEncoder === 'undefined') {
2222

2323
const testEnvironmentOptions = globalThis.ngJest?.testEnvironmentOptions ?? Object.create(null);
2424

25-
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), testEnvironmentOptions);
25+
getTestBed().initTestEnvironment([BrowserDynamicTestingModule], platformBrowserDynamicTesting(), testEnvironmentOptions);

‎src/config/setup-jest.spec.ts

+49-49
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,39 @@ jest.mock('@angular/core/testing', () => {
2828

2929
class BrowserDynamicTestingModuleStub {}
3030
class PlatformRefStub {}
31+
class ErrorHandlerStub {}
3132
const mockPlatformBrowserDynamicTesting = jest.fn(() => new PlatformRefStub());
3233
jest.mock('@angular/platform-browser-dynamic/testing', () => {
3334
return {
3435
BrowserDynamicTestingModule: new BrowserDynamicTestingModuleStub(),
3536
platformBrowserDynamicTesting: mockPlatformBrowserDynamicTesting,
3637
};
3738
});
39+
const mockProvideExperimentalZonelessChangeDetection = jest.fn();
40+
jest.mock('@angular/core', () => {
41+
return {
42+
provideExperimentalZonelessChangeDetection: mockProvideExperimentalZonelessChangeDetection,
43+
ErrorHandler: ErrorHandlerStub,
44+
NgModule: () => {
45+
return jest.fn();
46+
},
47+
};
48+
});
3849

3950
describe('setup-jest', () => {
4051
const assertOnInitTestEnv = (): void => {
4152
expect(mockGetTestBed).toHaveBeenCalled();
42-
expect(mockInitTestEnvironment).toHaveBeenCalled();
43-
expect(mockInitTestEnvironment.mock.calls[0][0]).toBeInstanceOf(BrowserDynamicTestingModuleStub);
53+
expect(mockInitTestEnvironment.mock.calls[0][0][0]).toBeInstanceOf(BrowserDynamicTestingModuleStub);
4454
expect(mockPlatformBrowserDynamicTesting).toHaveBeenCalled();
4555
expect(mockPlatformBrowserDynamicTesting.mock.results[0].value).toBeInstanceOf(PlatformRefStub);
56+
expect(mockInitTestEnvironment.mock.calls[0][2]).toEqual({
57+
teardown: {
58+
destroyAfterEach: false,
59+
rethrowErrors: true,
60+
},
61+
errorOnUnknownElements: true,
62+
errorOnUnknownProperties: true,
63+
});
4664
};
4765

4866
beforeEach(() => {
@@ -53,7 +71,7 @@ describe('setup-jest', () => {
5371
});
5472

5573
describe('for CJS setup-jest, test environment initialization', () => {
56-
test('should call getTestBed() and initTestEnvironment() with the testEnvironmentOptions passed to ngJest', async () => {
74+
it('should setup test environment with setup-jest file', async () => {
5775
globalThis.ngJest = {
5876
testEnvironmentOptions: {
5977
teardown: {
@@ -65,28 +83,15 @@ describe('setup-jest', () => {
6583
},
6684
};
6785

68-
await import('../../setup-jest');
86+
await import('../../setup-jest.js');
6987

88+
expect(globalThis.TextEncoder).toBeDefined();
7089
expect(mockZoneJs).toHaveBeenCalled();
7190
expect(mockZoneJsTesting).toHaveBeenCalled();
7291
assertOnInitTestEnv();
73-
expect(mockInitTestEnvironment.mock.calls[0][2]).toEqual({
74-
teardown: {
75-
destroyAfterEach: false,
76-
rethrowErrors: true,
77-
},
78-
errorOnUnknownElements: true,
79-
errorOnUnknownProperties: true,
80-
});
8192
});
8293

83-
test('should always have TextEncoder in globalThis', async () => {
84-
await import('../../setup-jest');
85-
86-
expect(globalThis.TextEncoder).toBeDefined();
87-
});
88-
89-
it('should call getTestBed() and initTestEnvironment() with the testEnvironmentOptions passed as argument with setupZoneTestEnv()', async () => {
94+
it('should setup test environment with setupZoneTestEnv()', async () => {
9095
const { setupZoneTestEnv } = await import('../../setup-env/zone/index.js');
9196

9297
setupZoneTestEnv({
@@ -98,30 +103,34 @@ describe('setup-jest', () => {
98103
errorOnUnknownProperties: true,
99104
});
100105

106+
expect(globalThis.TextEncoder).toBeDefined();
101107
expect(mockZoneJs).toHaveBeenCalled();
102108
expect(mockZoneJsTesting).toHaveBeenCalled();
103109
assertOnInitTestEnv();
104-
expect(mockInitTestEnvironment.mock.calls[0][2]).toEqual({
110+
});
111+
112+
it('should setup test environment with setupZonelessTestEnv()', async () => {
113+
const { setupZonelessTestEnv } = await import('../../setup-env/zoneless/index.js');
114+
115+
setupZonelessTestEnv({
105116
teardown: {
106117
destroyAfterEach: false,
107118
rethrowErrors: true,
108119
},
109120
errorOnUnknownElements: true,
110121
errorOnUnknownProperties: true,
111122
});
112-
});
113-
114-
it('should always have TextEncoder in globalThis with setupZoneTestEnv()', async () => {
115-
const { setupZoneTestEnv } = await import('../../setup-env/zone/index.js');
116-
117-
setupZoneTestEnv();
118123

119124
expect(globalThis.TextEncoder).toBeDefined();
125+
expect(mockZoneJs).not.toHaveBeenCalled();
126+
expect(mockZoneJsTesting).not.toHaveBeenCalled();
127+
assertOnInitTestEnv();
128+
expect(mockProvideExperimentalZonelessChangeDetection).toHaveBeenCalled();
120129
});
121130
});
122131

123132
describe('for ESM setup-jest, test environment initialization', () => {
124-
test('should call getTestBed() and initTestEnvironment() with the testEnvironmentOptions passed to ngJest', async () => {
133+
it('should setup test environment with setup-jest file', async () => {
125134
globalThis.ngJest = {
126135
testEnvironmentOptions: {
127136
teardown: {
@@ -135,26 +144,13 @@ describe('setup-jest', () => {
135144

136145
await import('../../setup-jest.mjs');
137146

147+
expect(globalThis.TextEncoder).toBeDefined();
138148
expect(mockZoneJs).toHaveBeenCalled();
139149
expect(mockZoneJsTesting).toHaveBeenCalled();
140150
assertOnInitTestEnv();
141-
expect(mockInitTestEnvironment.mock.calls[0][2]).toEqual({
142-
teardown: {
143-
destroyAfterEach: false,
144-
rethrowErrors: true,
145-
},
146-
errorOnUnknownElements: true,
147-
errorOnUnknownProperties: true,
148-
});
149151
});
150152

151-
test('should always have TextEncoder in globalThis', async () => {
152-
await import('../../setup-jest.mjs');
153-
154-
expect(globalThis.TextEncoder).toBeDefined();
155-
});
156-
157-
it('should call getTestBed() and initTestEnvironment() with the testEnvironmentOptions passed as argument with setupZoneTestEnv()', async () => {
153+
it('should setup test environment with setupZoneTestEnv()', async () => {
158154
const { setupZoneTestEnv } = await import('../../setup-env/zone/index.mjs');
159155

160156
setupZoneTestEnv({
@@ -166,25 +162,29 @@ describe('setup-jest', () => {
166162
errorOnUnknownProperties: true,
167163
});
168164

165+
expect(globalThis.TextEncoder).toBeDefined();
169166
expect(mockZoneJs).toHaveBeenCalled();
170167
expect(mockZoneJsTesting).toHaveBeenCalled();
171168
assertOnInitTestEnv();
172-
expect(mockInitTestEnvironment.mock.calls[0][2]).toEqual({
169+
});
170+
171+
it('should setup test environment with setupZonelessTestEnv()', async () => {
172+
const { setupZonelessTestEnv } = await import('../../setup-env/zoneless/index.mjs');
173+
174+
setupZonelessTestEnv({
173175
teardown: {
174176
destroyAfterEach: false,
175177
rethrowErrors: true,
176178
},
177179
errorOnUnknownElements: true,
178180
errorOnUnknownProperties: true,
179181
});
180-
});
181-
182-
it('should always have TextEncoder in globalThis with setupZoneTestEnv()', async () => {
183-
const { setupZoneTestEnv } = await import('../../setup-env/zone/index.mjs');
184-
185-
setupZoneTestEnv();
186182

187183
expect(globalThis.TextEncoder).toBeDefined();
184+
expect(mockZoneJs).not.toHaveBeenCalled();
185+
expect(mockZoneJsTesting).not.toHaveBeenCalled();
186+
assertOnInitTestEnv();
187+
expect(mockProvideExperimentalZonelessChangeDetection).toHaveBeenCalled();
188188
});
189189
});
190190
});

‎website/docs/getting-started/test-environment.md

+21-6
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,6 @@ export default jestConfig;
8282
Configures a test environment that **DOESN'T** use `zone.js`, as described in [Angular experimental zoneless guide](https://angular.dev/guide/experimental/zoneless).
8383
It is designed for projects that have disabled `zone.js`, which can lead to improved performance and simplified testing.
8484

85-
:::important
86-
87-
This function is only supported in Jest `ESM` mode in [Jest 29](https://github.com/jestjs/jest/issues/10962). Jest 30+ will support to use for `CommonJS` mode.
88-
89-
:::
90-
9185
You can customize the environment by providing options as function arguments.
9286

9387
#### Parameters
@@ -98,6 +92,15 @@ You can customize the environment by providing options as function arguments.
9892

9993
- Create a Jest setup file:
10094

95+
```ts tab={"label": "TypeScript CJS"}
96+
// setup-jest.ts
97+
import { setupZonelessTestEnv } from 'jest-preset-angular/setup-env/zoneless';
98+
99+
setupZonelessTestEnv({
100+
//...options
101+
});
102+
```
103+
101104
```ts tab={"label": "TypeScript ESM"}
102105
// setup-jest.ts
103106
import { setupZonelessTestEnv } from 'jest-preset-angular/setup-env/zoneless/index.mjs';
@@ -109,6 +112,18 @@ setupZonelessTestEnv({
109112

110113
- Update your Jest configuration:
111114

115+
```ts tab={"label": "TypeScript CJS"}
116+
// jest.config.mts
117+
import type { Config } from 'jest';
118+
119+
const jestConfig: Config = {
120+
preset: 'jest-preset-angular',
121+
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
122+
};
123+
124+
export default jestConfig;
125+
```
126+
112127
```ts tab={"label": "TypeScript ESM"}
113128
// jest.config.mts
114129
import type { Config } from 'jest';

‎website/versioned_docs/version-14.3/getting-started/test-environment.md

+21-6
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,6 @@ export default jestConfig;
8282
Configures a test environment that **DOESN'T** use `zone.js`, as described in [Angular experimental zoneless guide](https://angular.dev/guide/experimental/zoneless).
8383
It is designed for projects that have disabled `zone.js`, which can lead to improved performance and simplified testing.
8484

85-
:::important
86-
87-
This function is only supported in Jest `ESM` mode in [Jest 29](https://github.com/jestjs/jest/issues/10962). Jest 30+ will support to use for `CommonJS` mode.
88-
89-
:::
90-
9185
You can customize the environment by providing options as function arguments.
9286

9387
#### Parameters
@@ -98,6 +92,15 @@ You can customize the environment by providing options as function arguments.
9892

9993
- Create a Jest setup file:
10094

95+
```ts tab={"label": "TypeScript CJS"}
96+
// setup-jest.ts
97+
import { setupZonelessTestEnv } from 'jest-preset-angular/setup-env/zoneless';
98+
99+
setupZonelessTestEnv({
100+
//...options
101+
});
102+
```
103+
101104
```ts tab={"label": "TypeScript ESM"}
102105
// setup-jest.ts
103106
import { setupZonelessTestEnv } from 'jest-preset-angular/setup-env/zoneless/index.mjs';
@@ -109,6 +112,18 @@ setupZonelessTestEnv({
109112

110113
- Update your Jest configuration:
111114

115+
```ts tab={"label": "TypeScript CJS"}
116+
// jest.config.mts
117+
import type { Config } from 'jest';
118+
119+
const jestConfig: Config = {
120+
preset: 'jest-preset-angular',
121+
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
122+
};
123+
124+
export default jestConfig;
125+
```
126+
112127
```ts tab={"label": "TypeScript ESM"}
113128
// jest.config.mts
114129
import type { Config } from 'jest';

0 commit comments

Comments
 (0)
Please sign in to comment.