jest-preset-angular 15.0.2 → 15.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## [15.0.3](https://github.com/thymikee/jest-preset-angular/compare/v15.0.2...v15.0.3) (2025-10-17)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * handle `processWithEsbuild` transform option ([6779107](https://github.com/thymikee/jest-preset-angular/commit/67791077ea20b3a7f3dcf237ecbe35f2f9decd3f))
7
+
8
+
9
+
1
10
  ## [15.0.2](https://github.com/thymikee/jest-preset-angular/compare/v15.0.1...v15.0.2) (2025-10-01)
2
11
 
3
12
 
@@ -63,6 +72,15 @@
63
72
 
64
73
 
65
74
 
75
+ ## [14.6.2](https://github.com/thymikee/jest-preset-angular/compare/v14.6.1...v14.6.2) (2025-10-17)
76
+
77
+
78
+ ### Bug Fixes
79
+
80
+ * handle `processWithEsbuild` transform option ([6779107](https://github.com/thymikee/jest-preset-angular/commit/67791077ea20b3a7f3dcf237ecbe35f2f9decd3f))
81
+
82
+
83
+
66
84
  ## [14.6.1](https://github.com/thymikee/jest-preset-angular/compare/v14.6.0...v14.6.1) (2025-07-21)
67
85
 
68
86
 
@@ -0,0 +1,4 @@
1
+ import type { TsJestTransformerOptions } from 'ts-jest';
2
+ export type NgJestTransformerOptions = TsJestTransformerOptions & {
3
+ processWithEsbuild?: string[];
4
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export declare const globalSetup: () => Promise<void>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.globalSetup = void 0;
13
+ const ngcc_jest_processor_1 = require("../utils/ngcc-jest-processor");
14
+ const globalSetup = () => __awaiter(void 0, void 0, void 0, function* () {
15
+ const ngJestConfig = globalThis.ngJest;
16
+ const tsconfig = ngJestConfig === null || ngJestConfig === void 0 ? void 0 : ngJestConfig.tsconfig;
17
+ if (!(ngJestConfig === null || ngJestConfig === void 0 ? void 0 : ngJestConfig.skipNgcc)) {
18
+ (0, ngcc_jest_processor_1.runNgccJestProcessor)(tsconfig);
19
+ }
20
+ });
21
+ exports.globalSetup = globalSetup;
@@ -9,6 +9,9 @@ class NgJestConfig extends ts_jest_1.ConfigSet {
9
9
  constructor(jestConfig, parentLogger) {
10
10
  super(jestConfig, parentLogger);
11
11
  const jestGlobalsConfig = jestConfig?.globals?.ngJest ?? Object.create(null);
12
+ if (jestGlobalsConfig.processWithEsbuild) {
13
+ this.logger.warn('Specifying `processWithEsbuild` in `ngJest` config is deprecated and will be removed in the next major version. Please follow this documentation https://thymikee.github.io/jest-preset-angular/docs/getting-started/options#processing-with-esbuild instead.');
14
+ }
12
15
  this.processWithEsbuild = (0, jest_util_1.globsToMatcher)([
13
16
  ...(jestGlobalsConfig.processWithEsbuild ?? []),
14
17
  ...defaultProcessWithEsbuildPatterns,
@@ -0,0 +1,27 @@
1
+ import type { Context } from 'node:vm';
2
+ import type { EnvironmentContext, JestEnvironment, JestEnvironmentConfig } from '@jest/environment';
3
+ import { LegacyFakeTimers, ModernFakeTimers } from '@jest/fake-timers';
4
+ import type { Global } from '@jest/types';
5
+ import { ModuleMocker } from 'jest-mock';
6
+ import type * as jsdom from 'jsdom';
7
+ type Win = Window & Global.Global & {
8
+ Error: {
9
+ stackTraceLimit: number;
10
+ };
11
+ };
12
+ export default abstract class BaseJSDOMEnvironment implements JestEnvironment<number> {
13
+ dom: jsdom.JSDOM | null;
14
+ fakeTimers: LegacyFakeTimers<number> | null;
15
+ fakeTimersModern: ModernFakeTimers | null;
16
+ global: Win;
17
+ private errorEventListener;
18
+ moduleMocker: ModuleMocker | null;
19
+ customExportConditions: string[];
20
+ private readonly _configuredExportConditions?;
21
+ protected constructor(config: JestEnvironmentConfig, context: EnvironmentContext, jsdomModule: typeof jsdom);
22
+ setup(): Promise<void>;
23
+ teardown(): Promise<void>;
24
+ exportConditions(): Array<string>;
25
+ getVmContext(): Context | null;
26
+ }
27
+ export {};
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const fake_timers_1 = require("@jest/fake-timers");
13
+ const jest_mock_1 = require("jest-mock");
14
+ const jest_util_1 = require("jest-util");
15
+ function isString(value) {
16
+ return typeof value === 'string';
17
+ }
18
+ class BaseJSDOMEnvironment {
19
+ constructor(config, context, jsdomModule) {
20
+ this.customExportConditions = ['browser'];
21
+ const { projectConfig } = config;
22
+ const { JSDOM, ResourceLoader, VirtualConsole } = jsdomModule;
23
+ const virtualConsole = new VirtualConsole();
24
+ virtualConsole.sendTo(context.console, { omitJSDOMErrors: true });
25
+ virtualConsole.on('jsdomError', (error) => {
26
+ context.console.error(error);
27
+ });
28
+ this.dom = new JSDOM(typeof projectConfig.testEnvironmentOptions.html === 'string'
29
+ ? projectConfig.testEnvironmentOptions.html
30
+ : '<!DOCTYPE html>', Object.assign({ pretendToBeVisual: true, resources: typeof projectConfig.testEnvironmentOptions.userAgent === 'string'
31
+ ? new ResourceLoader({
32
+ userAgent: projectConfig.testEnvironmentOptions.userAgent,
33
+ })
34
+ : undefined, runScripts: 'dangerously', url: 'http://localhost/', virtualConsole }, projectConfig.testEnvironmentOptions));
35
+ const global = (this.global = this.dom.window);
36
+ if (global == null) {
37
+ throw new Error('JSDOM did not return a Window object');
38
+ }
39
+ global.global = global;
40
+ this.global.Error.stackTraceLimit = 100;
41
+ (0, jest_util_1.installCommonGlobals)(global, projectConfig.globals);
42
+ this.errorEventListener = (event) => {
43
+ if (userErrorListenerCount === 0 && event.error != null) {
44
+ process.emit('uncaughtException', event.error);
45
+ }
46
+ };
47
+ global.addEventListener('error', this.errorEventListener);
48
+ const originalAddListener = global.addEventListener.bind(global);
49
+ const originalRemoveListener = global.removeEventListener.bind(global);
50
+ let userErrorListenerCount = 0;
51
+ global.addEventListener = function (...args) {
52
+ if (args[0] === 'error') {
53
+ userErrorListenerCount++;
54
+ }
55
+ return originalAddListener.apply(this, args);
56
+ };
57
+ global.removeEventListener = function (...args) {
58
+ if (args[0] === 'error') {
59
+ userErrorListenerCount--;
60
+ }
61
+ return originalRemoveListener.apply(this, args);
62
+ };
63
+ if ('customExportConditions' in projectConfig.testEnvironmentOptions) {
64
+ const { customExportConditions } = projectConfig.testEnvironmentOptions;
65
+ if (Array.isArray(customExportConditions) && customExportConditions.every(isString)) {
66
+ this._configuredExportConditions = customExportConditions;
67
+ }
68
+ else {
69
+ throw new Error('Custom export conditions specified but they are not an array of strings');
70
+ }
71
+ }
72
+ this.moduleMocker = new jest_mock_1.ModuleMocker(global);
73
+ this.fakeTimers = new fake_timers_1.LegacyFakeTimers({
74
+ config: projectConfig,
75
+ global: global,
76
+ moduleMocker: this.moduleMocker,
77
+ timerConfig: {
78
+ idToRef: (id) => id,
79
+ refToId: (ref) => ref,
80
+ },
81
+ });
82
+ this.fakeTimersModern = new fake_timers_1.ModernFakeTimers({
83
+ config: projectConfig,
84
+ global: global,
85
+ });
86
+ }
87
+ setup() {
88
+ return __awaiter(this, void 0, void 0, function* () { });
89
+ }
90
+ teardown() {
91
+ return __awaiter(this, void 0, void 0, function* () {
92
+ if (this.fakeTimers) {
93
+ this.fakeTimers.dispose();
94
+ }
95
+ if (this.fakeTimersModern) {
96
+ this.fakeTimersModern.dispose();
97
+ }
98
+ if (this.global != null) {
99
+ if (this.errorEventListener) {
100
+ this.global.removeEventListener('error', this.errorEventListener);
101
+ }
102
+ this.global.close();
103
+ }
104
+ this.errorEventListener = null;
105
+ this.global = null;
106
+ this.dom = null;
107
+ this.fakeTimers = null;
108
+ this.fakeTimersModern = null;
109
+ });
110
+ }
111
+ exportConditions() {
112
+ var _a;
113
+ return (_a = this._configuredExportConditions) !== null && _a !== void 0 ? _a : this.customExportConditions;
114
+ }
115
+ getVmContext() {
116
+ if (this.dom) {
117
+ return this.dom.getInternalVMContext();
118
+ }
119
+ return null;
120
+ }
121
+ }
122
+ exports.default = BaseJSDOMEnvironment;
@@ -0,0 +1,6 @@
1
+ import * as jsdom from 'jsdom';
2
+ export declare class MockableJSDOM extends jsdom.JSDOM {
3
+ #private;
4
+ constructor(html?: string, options?: jsdom.ConstructorOptions);
5
+ get window(): jsdom.DOMWindow;
6
+ }
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MockableJSDOM = void 0;
37
+ const jsdom = __importStar(require("jsdom"));
38
+ class DummyLocation {
39
+ _hash = '';
40
+ _host = '';
41
+ _hostname = '';
42
+ _href = '';
43
+ _origin = '';
44
+ _pathname = '';
45
+ _port = '';
46
+ _protocol = '';
47
+ _search = '';
48
+ get hash() {
49
+ return this._hash;
50
+ }
51
+ set hash(value) {
52
+ this._hash = value;
53
+ }
54
+ get host() {
55
+ return this._host;
56
+ }
57
+ set host(value) {
58
+ this._host = value;
59
+ }
60
+ get hostname() {
61
+ return this._hostname;
62
+ }
63
+ set hostname(value) {
64
+ this._hostname = value;
65
+ }
66
+ get href() {
67
+ return this._href;
68
+ }
69
+ set href(value) {
70
+ this._href = value;
71
+ }
72
+ get origin() {
73
+ return this._origin;
74
+ }
75
+ set origin(value) {
76
+ this._origin = value;
77
+ }
78
+ get pathname() {
79
+ return this._pathname;
80
+ }
81
+ set pathname(value) {
82
+ this._pathname = value;
83
+ }
84
+ get port() {
85
+ return this._port;
86
+ }
87
+ set port(value) {
88
+ this._port = value;
89
+ }
90
+ get protocol() {
91
+ return this._protocol;
92
+ }
93
+ set protocol(value) {
94
+ this._protocol = value;
95
+ }
96
+ get search() {
97
+ return this._search;
98
+ }
99
+ set search(value) {
100
+ this._search = value;
101
+ }
102
+ toString() {
103
+ return this._href;
104
+ }
105
+ assign(url) {
106
+ this._href = String(url);
107
+ }
108
+ reload() { }
109
+ replace(url) {
110
+ this._href = String(url);
111
+ }
112
+ }
113
+ class MockableJSDOM extends jsdom.JSDOM {
114
+ #mockLocation = new DummyLocation();
115
+ #originalWindow;
116
+ #documentProxy;
117
+ #windowProxy;
118
+ constructor(html, options) {
119
+ super(html, options);
120
+ this.#originalWindow = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Object.getPrototypeOf(this)), 'window').get.call(this);
121
+ this.#documentProxy = new Proxy(this.#originalWindow.document, {
122
+ get: (target, prop, receiver) => {
123
+ if (prop !== 'location')
124
+ return Reflect.get(target, prop, receiver);
125
+ return this.#mockLocation;
126
+ },
127
+ set: (target, prop, value, receiver) => {
128
+ if (prop === 'location') {
129
+ return true;
130
+ }
131
+ return Reflect.set(target, prop, value, receiver);
132
+ },
133
+ });
134
+ this.#windowProxy = new Proxy(this.#originalWindow, {
135
+ get: (target, prop, receiver) => {
136
+ switch (prop) {
137
+ case 'document':
138
+ return this.#documentProxy;
139
+ case 'location':
140
+ return this.#mockLocation;
141
+ default: {
142
+ const value = Reflect.get(target, prop, target);
143
+ return value;
144
+ }
145
+ }
146
+ },
147
+ });
148
+ }
149
+ get window() {
150
+ return this.#windowProxy;
151
+ }
152
+ }
153
+ exports.MockableJSDOM = MockableJSDOM;
@@ -1,8 +1,9 @@
1
1
  import type { TransformedSource } from '@jest/transform';
2
- import { type TsJestTransformerOptions, ConfigSet, TsJestTransformer, type TsJestTransformOptions } from 'ts-jest';
2
+ import { ConfigSet, TsJestTransformer, type TsJestTransformOptions } from 'ts-jest';
3
+ import type { NgJestTransformerOptions } from './config/config';
3
4
  export declare class NgJestTransformer extends TsJestTransformer {
4
5
  #private;
5
- constructor(tsJestConfig?: TsJestTransformerOptions);
6
+ constructor(transformerConfig?: NgJestTransformerOptions);
6
7
  protected _createConfigSet(config: TsJestTransformOptions['config'] | undefined): ConfigSet;
7
8
  protected _createCompiler(configSet: ConfigSet, cacheFS: Map<string, string>): void;
8
9
  private get version();
@@ -4,6 +4,7 @@ exports.NgJestTransformer = void 0;
4
4
  const node_crypto_1 = require("node:crypto");
5
5
  const bs_logger_1 = require("bs-logger");
6
6
  const esbuild_1 = require("esbuild");
7
+ const jest_util_1 = require("jest-util");
7
8
  const ts_jest_1 = require("ts-jest");
8
9
  const compiler_utils_1 = require("ts-jest/dist/legacy/compiler/compiler-utils");
9
10
  const ng_jest_compiler_1 = require("./compiler/ng-jest-compiler");
@@ -35,7 +36,9 @@ const sha1 = (...data) => {
35
36
  };
36
37
  class NgJestTransformer extends ts_jest_1.TsJestTransformer {
37
38
  #ngJestLogger;
38
- constructor(tsJestConfig) {
39
+ #processWithEsbuild;
40
+ constructor(transformerConfig) {
41
+ const { processWithEsbuild, ...tsJestConfig } = transformerConfig ?? {};
39
42
  super(tsJestConfig);
40
43
  this.#ngJestLogger = (0, bs_logger_1.createLogger)({
41
44
  context: {
@@ -45,6 +48,7 @@ class NgJestTransformer extends ts_jest_1.TsJestTransformer {
45
48
  },
46
49
  targets: process.env.NG_JEST_LOG ?? undefined,
47
50
  });
51
+ this.#processWithEsbuild = (0, jest_util_1.globsToMatcher)(processWithEsbuild ?? []);
48
52
  }
49
53
  _createConfigSet(config) {
50
54
  return new ng_jest_config_1.NgJestConfig(config);
@@ -57,7 +61,7 @@ class NgJestTransformer extends ts_jest_1.TsJestTransformer {
57
61
  }
58
62
  process(fileContent, filePath, transformOptions) {
59
63
  const configSet = super._configsFor(transformOptions);
60
- if (configSet.processWithEsbuild(filePath)) {
64
+ if (configSet.processWithEsbuild(filePath) || this.#processWithEsbuild(filePath)) {
61
65
  this.#ngJestLogger.debug({ filePath }, 'process with esbuild');
62
66
  const compilerOpts = configSet.parsedTsConfig.options;
63
67
  const useESM = transformOptions.supportsStaticESM && configSet.useESM;
@@ -0,0 +1,3 @@
1
+ import type { SyncResolver } from 'jest-resolve';
2
+ declare const ngJestResolver: SyncResolver;
3
+ export = ngJestResolver;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ const ngJestResolver = (path, options) => {
3
+ return options.defaultResolver(path, Object.assign(Object.assign({}, options), { packageFilter(pkg) {
4
+ return Object.assign(Object.assign({}, pkg), { main: pkg.main || pkg.es2015 || pkg.module });
5
+ } }));
6
+ };
7
+ module.exports = ngJestResolver;