jest-preset-angular 14.2.3 → 14.3.0
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 +48 -0
- package/README.md +1 -1
- package/build/compiler/ng-jest-compiler.d.ts +11 -0
- package/build/compiler/ng-jest-compiler.js +71 -0
- package/build/config/global-setup.d.ts +1 -0
- package/build/config/global-setup.js +21 -0
- package/build/config/ng-jest-config.d.ts +9 -0
- package/build/config/ng-jest-config.js +29 -0
- package/build/constants.d.ts +7 -0
- package/build/constants.js +10 -0
- package/build/index.d.ts +6 -0
- package/build/index.js +6 -0
- package/build/ng-jest-transformer.d.ts +9 -0
- package/build/ng-jest-transformer.js +66 -0
- package/build/presets/index.d.ts +39 -0
- package/build/presets/index.js +30 -0
- package/build/resolvers/ng-jest-resolver.d.ts +3 -0
- package/build/resolvers/ng-jest-resolver.js +7 -0
- package/build/serializers/html-comment.d.ts +5 -0
- package/build/serializers/html-comment.js +8 -0
- package/build/serializers/index.d.ts +2 -0
- package/build/serializers/index.js +6 -0
- package/build/serializers/ng-snapshot.d.ts +11 -0
- package/build/serializers/ng-snapshot.js +48 -0
- package/build/serializers/no-ng-attributes.d.ts +5 -0
- package/build/serializers/no-ng-attributes.js +57 -0
- package/build/transformers/esm_interop_inject.cjs +4 -0
- package/build/transformers/esm_interop_inject.d.cts +1 -0
- package/build/transformers/jit_transform.js +173 -0
- package/build/transformers/replace-resources.d.ts +2 -0
- package/build/transformers/replace-resources.js +206 -0
- package/build/utils/ngcc-jest-processor.d.ts +1 -0
- package/build/utils/ngcc-jest-processor.js +75 -0
- package/package.json +26 -25
- package/setup-env/utils.mjs +19 -0
- package/setup-env/zone/index.d.mts +3 -0
- package/setup-env/zone/index.d.ts +6 -0
- package/setup-env/zone/index.js +43 -0
- package/setup-env/zone/index.mjs +18 -0
- package/setup-env/zoneless/index.d.mts +3 -0
- package/setup-env/zoneless/index.d.ts +6 -0
- package/setup-env/zoneless/index.js +11 -0
- package/setup-env/zoneless/index.mjs +39 -0
- package/setup-jest.js +10 -0
- package/setup-jest.mjs +12 -1
- package/jest-cjs.config.ts +0 -8
- package/jest-esm.config.ts +0 -8
- package/jest-src.config.ts +0 -18
- package/jest-transpile-cjs.config.ts +0 -8
- package/jest-transpile-esm.config.ts +0 -8
- package/tsconfig-base.spec.json +0 -7
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.replaceResources = replaceResources;
|
|
7
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
8
|
+
const constants_1 = require("../constants");
|
|
9
|
+
const isAfterVersion = (targetMajor, targetMinor) => {
|
|
10
|
+
const [major, minor] = typescript_1.default.versionMajorMinor.split('.').map((part) => parseInt(part));
|
|
11
|
+
if (major < targetMajor) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
else if (major > targetMajor) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
return minor >= targetMinor;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const IS_TS_48 = isAfterVersion(4, 8);
|
|
22
|
+
const IS_AFTER_TS_50 = isAfterVersion(5, 0);
|
|
23
|
+
const shouldTransform = (fileName) => !fileName.endsWith('.ngfactory.ts') && !fileName.endsWith('.ngstyle.ts');
|
|
24
|
+
function replaceResources(program) {
|
|
25
|
+
return (context) => {
|
|
26
|
+
const typeChecker = program.getTypeChecker();
|
|
27
|
+
const resourceImportDeclarations = [];
|
|
28
|
+
const moduleKind = context.getCompilerOptions().module;
|
|
29
|
+
const nodeFactory = context.factory;
|
|
30
|
+
const visitNode = (node) => {
|
|
31
|
+
if (typescript_1.default.isClassDeclaration(node)) {
|
|
32
|
+
return visitClassDeclaration(nodeFactory, typeChecker, node, resourceImportDeclarations, moduleKind);
|
|
33
|
+
}
|
|
34
|
+
return typescript_1.default.visitEachChild(node, visitNode, context);
|
|
35
|
+
};
|
|
36
|
+
return (sourceFile) => {
|
|
37
|
+
if (!shouldTransform(sourceFile.fileName)) {
|
|
38
|
+
return sourceFile;
|
|
39
|
+
}
|
|
40
|
+
const updatedSourceFile = typescript_1.default.visitNode(sourceFile, visitNode);
|
|
41
|
+
if (resourceImportDeclarations.length) {
|
|
42
|
+
return nodeFactory.updateSourceFile(updatedSourceFile, typescript_1.default.setTextRange(nodeFactory.createNodeArray([...resourceImportDeclarations, ...updatedSourceFile.statements]), updatedSourceFile.statements));
|
|
43
|
+
}
|
|
44
|
+
return updatedSourceFile;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function visitClassDeclaration(nodeFactory, typeChecker, node, resourceImportDeclarations, moduleKind) {
|
|
49
|
+
var _a, _b, _c;
|
|
50
|
+
let decorators;
|
|
51
|
+
let modifiers;
|
|
52
|
+
if (IS_TS_48) {
|
|
53
|
+
(_a = node.modifiers) === null || _a === void 0 ? void 0 : _a.forEach((modifier) => {
|
|
54
|
+
if (typescript_1.default.isDecorator(modifier)) {
|
|
55
|
+
decorators !== null && decorators !== void 0 ? decorators : (decorators = []);
|
|
56
|
+
decorators.push(modifier);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
modifiers = modifiers !== null && modifiers !== void 0 ? modifiers : (modifiers = []);
|
|
60
|
+
modifiers.push(modifier);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
decorators = [...((_b = typescript_1.default.getDecorators(node)) !== null && _b !== void 0 ? _b : [])];
|
|
66
|
+
modifiers = [...((_c = typescript_1.default.getModifiers(node)) !== null && _c !== void 0 ? _c : [])];
|
|
67
|
+
}
|
|
68
|
+
if (!decorators || !decorators.length) {
|
|
69
|
+
return node;
|
|
70
|
+
}
|
|
71
|
+
decorators = decorators.map((current) => visitDecorator(nodeFactory, current, typeChecker, resourceImportDeclarations, moduleKind));
|
|
72
|
+
return IS_TS_48
|
|
73
|
+
? nodeFactory.updateClassDeclaration(node, [...decorators, ...(modifiers !== null && modifiers !== void 0 ? modifiers : [])], node.name, node.typeParameters, node.heritageClauses, node.members)
|
|
74
|
+
: nodeFactory.updateClassDeclaration(node, decorators, modifiers, node.name, node.typeParameters, node.heritageClauses, node.members);
|
|
75
|
+
}
|
|
76
|
+
function visitDecorator(nodeFactory, node, typeChecker, resourceImportDeclarations, moduleKind) {
|
|
77
|
+
if (!isComponentDecorator(node, typeChecker)) {
|
|
78
|
+
return node;
|
|
79
|
+
}
|
|
80
|
+
if (!typescript_1.default.isCallExpression(node.expression)) {
|
|
81
|
+
return node;
|
|
82
|
+
}
|
|
83
|
+
const decoratorFactory = node.expression;
|
|
84
|
+
const args = decoratorFactory.arguments;
|
|
85
|
+
if (args.length !== 1 || !typescript_1.default.isObjectLiteralExpression(args[0])) {
|
|
86
|
+
return node;
|
|
87
|
+
}
|
|
88
|
+
const objectExpression = args[0];
|
|
89
|
+
const styleReplacements = [];
|
|
90
|
+
let properties = typescript_1.default.visitNodes(objectExpression.properties, (objExpressionNode) => typescript_1.default.isObjectLiteralElementLike(objExpressionNode)
|
|
91
|
+
? visitComponentMetadata(nodeFactory, objExpressionNode, resourceImportDeclarations, moduleKind)
|
|
92
|
+
: objExpressionNode);
|
|
93
|
+
if (styleReplacements.length) {
|
|
94
|
+
const styleProperty = nodeFactory.createPropertyAssignment(nodeFactory.createIdentifier(constants_1.STYLES), nodeFactory.createArrayLiteralExpression(styleReplacements));
|
|
95
|
+
properties = nodeFactory.createNodeArray([...properties, styleProperty]);
|
|
96
|
+
}
|
|
97
|
+
return nodeFactory.updateDecorator(node, nodeFactory.updateCallExpression(decoratorFactory, decoratorFactory.expression, decoratorFactory.typeArguments, [
|
|
98
|
+
nodeFactory.updateObjectLiteralExpression(objectExpression, properties),
|
|
99
|
+
]));
|
|
100
|
+
}
|
|
101
|
+
function visitComponentMetadata(nodeFactory, node, resourceImportDeclarations, moduleKind) {
|
|
102
|
+
if (!typescript_1.default.isPropertyAssignment(node) || typescript_1.default.isComputedPropertyName(node.name)) {
|
|
103
|
+
return node;
|
|
104
|
+
}
|
|
105
|
+
const name = node.name.text;
|
|
106
|
+
switch (name) {
|
|
107
|
+
case 'moduleId':
|
|
108
|
+
return undefined;
|
|
109
|
+
case constants_1.TEMPLATE_URL:
|
|
110
|
+
const url = getResourceUrl(node.initializer);
|
|
111
|
+
if (!url) {
|
|
112
|
+
return node;
|
|
113
|
+
}
|
|
114
|
+
const importName = createResourceImport(nodeFactory, url, resourceImportDeclarations, moduleKind);
|
|
115
|
+
if (!importName) {
|
|
116
|
+
return node;
|
|
117
|
+
}
|
|
118
|
+
return nodeFactory.updatePropertyAssignment(node, nodeFactory.createIdentifier(constants_1.TEMPLATE), importName);
|
|
119
|
+
case constants_1.STYLES:
|
|
120
|
+
if (!typescript_1.default.isArrayLiteralExpression(node.initializer) && !typescript_1.default.isStringLiteralLike(node.initializer)) {
|
|
121
|
+
return node;
|
|
122
|
+
}
|
|
123
|
+
return undefined;
|
|
124
|
+
case constants_1.STYLE_URLS:
|
|
125
|
+
if (!typescript_1.default.isArrayLiteralExpression(node.initializer)) {
|
|
126
|
+
return node;
|
|
127
|
+
}
|
|
128
|
+
return undefined;
|
|
129
|
+
case constants_1.STYLE_URL:
|
|
130
|
+
if (!typescript_1.default.isStringLiteralLike(node.initializer)) {
|
|
131
|
+
return node;
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
default:
|
|
135
|
+
return node;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function getResourceUrl(node) {
|
|
139
|
+
if (!typescript_1.default.isStringLiteral(node) && !typescript_1.default.isNoSubstitutionTemplateLiteral(node)) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
return `${/^\.?\.\//.test(node.text) ? '' : './'}${node.text}`;
|
|
143
|
+
}
|
|
144
|
+
function isComponentDecorator(node, typeChecker) {
|
|
145
|
+
if (!typescript_1.default.isDecorator(node)) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
const origin = getDecoratorOrigin(node, typeChecker);
|
|
149
|
+
return !!(origin && origin.module === '@angular/core' && origin.name === constants_1.COMPONENT);
|
|
150
|
+
}
|
|
151
|
+
function createResourceImport(nodeFactory, url, resourceImportDeclarations, moduleKind = typescript_1.default.ModuleKind.ES2015) {
|
|
152
|
+
const urlLiteral = nodeFactory.createStringLiteral(url);
|
|
153
|
+
if (moduleKind < typescript_1.default.ModuleKind.ES2015) {
|
|
154
|
+
return nodeFactory.createCallExpression(nodeFactory.createIdentifier(constants_1.REQUIRE), [], [urlLiteral]);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
const importName = nodeFactory.createIdentifier(`__NG_CLI_RESOURCE__${resourceImportDeclarations.length}`);
|
|
158
|
+
let importDeclaration;
|
|
159
|
+
if (IS_AFTER_TS_50) {
|
|
160
|
+
importDeclaration = nodeFactory.createImportDeclaration(undefined, nodeFactory.createImportClause(false, importName, undefined), urlLiteral);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
importDeclaration = nodeFactory.createImportDeclaration(undefined, undefined, nodeFactory.createImportClause(false, importName, undefined), urlLiteral);
|
|
164
|
+
}
|
|
165
|
+
resourceImportDeclarations.push(importDeclaration);
|
|
166
|
+
return importName;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function getDecoratorOrigin(decorator, typeChecker) {
|
|
170
|
+
if (!typescript_1.default.isCallExpression(decorator.expression)) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
let identifier;
|
|
174
|
+
let name = '';
|
|
175
|
+
if (typescript_1.default.isPropertyAccessExpression(decorator.expression.expression)) {
|
|
176
|
+
identifier = decorator.expression.expression.expression;
|
|
177
|
+
name = decorator.expression.expression.name.text;
|
|
178
|
+
}
|
|
179
|
+
else if (typescript_1.default.isIdentifier(decorator.expression.expression)) {
|
|
180
|
+
identifier = decorator.expression.expression;
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
const symbol = typeChecker.getSymbolAtLocation(identifier);
|
|
186
|
+
if (symbol && symbol.declarations && symbol.declarations.length > 0) {
|
|
187
|
+
const declaration = symbol.declarations[0];
|
|
188
|
+
let module;
|
|
189
|
+
if (typescript_1.default.isImportSpecifier(declaration)) {
|
|
190
|
+
name = (declaration.propertyName || declaration.name).text;
|
|
191
|
+
module = declaration.parent.parent.parent.moduleSpecifier.text;
|
|
192
|
+
}
|
|
193
|
+
else if (typescript_1.default.isNamespaceImport(declaration)) {
|
|
194
|
+
module = declaration.parent.parent.moduleSpecifier.text;
|
|
195
|
+
}
|
|
196
|
+
else if (typescript_1.default.isImportClause(declaration)) {
|
|
197
|
+
name = declaration.name.text;
|
|
198
|
+
module = declaration.parent.moduleSpecifier.text;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
return { name, module };
|
|
204
|
+
}
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const runNgccJestProcessor: (tsconfigPath: string | undefined) => void;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runNgccJestProcessor = void 0;
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const ANGULAR_COMPILER_CLI_PKG_NAME = '@angular/compiler-cli';
|
|
10
|
+
let ngccPath = '';
|
|
11
|
+
try {
|
|
12
|
+
ngccPath = require.resolve('@angular/compiler-cli/ngcc/main-ngcc.js');
|
|
13
|
+
}
|
|
14
|
+
catch (_a) {
|
|
15
|
+
try {
|
|
16
|
+
const compilerCliNgccPath = require.resolve('@angular/compiler-cli/ngcc');
|
|
17
|
+
const compilerCliNgccFolder = compilerCliNgccPath.substring(0, compilerCliNgccPath.lastIndexOf(path_1.default.sep));
|
|
18
|
+
ngccPath = path_1.default.resolve(compilerCliNgccFolder, 'main-ngcc.js');
|
|
19
|
+
}
|
|
20
|
+
catch (_b) {
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function findNodeModulesDirectory() {
|
|
24
|
+
return ngccPath.substring(0, ngccPath.indexOf(ANGULAR_COMPILER_CLI_PKG_NAME.replace('/', path_1.default.sep)));
|
|
25
|
+
}
|
|
26
|
+
function findAngularCompilerCliVersion() {
|
|
27
|
+
const packagePath = require.resolve(ANGULAR_COMPILER_CLI_PKG_NAME);
|
|
28
|
+
const substringLength = packagePath.indexOf(ANGULAR_COMPILER_CLI_PKG_NAME.replace('/', path_1.default.sep)) +
|
|
29
|
+
ANGULAR_COMPILER_CLI_PKG_NAME.length;
|
|
30
|
+
const ngCompilerCliFolder = packagePath.substring(0, substringLength);
|
|
31
|
+
const ngCompilerCliPackageJson = `${ngCompilerCliFolder}/package.json`;
|
|
32
|
+
const { version } = require(ngCompilerCliPackageJson);
|
|
33
|
+
return version;
|
|
34
|
+
}
|
|
35
|
+
const nodeModuleDirPath = findNodeModulesDirectory();
|
|
36
|
+
const runNgccJestProcessor = (tsconfigPath) => {
|
|
37
|
+
var _a;
|
|
38
|
+
if (nodeModuleDirPath) {
|
|
39
|
+
process.stdout.write('\nngcc-jest-processor: running ngcc\n');
|
|
40
|
+
const ngccBaseArgs = [
|
|
41
|
+
ngccPath,
|
|
42
|
+
'--source',
|
|
43
|
+
nodeModuleDirPath,
|
|
44
|
+
'--properties',
|
|
45
|
+
...['es2015', 'main'],
|
|
46
|
+
'--first-only',
|
|
47
|
+
'false',
|
|
48
|
+
'--async',
|
|
49
|
+
];
|
|
50
|
+
if (tsconfigPath) {
|
|
51
|
+
ngccBaseArgs.push(...['--tsconfig', tsconfigPath]);
|
|
52
|
+
}
|
|
53
|
+
const { status, error } = (0, child_process_1.spawnSync)(process.execPath, ngccBaseArgs, {
|
|
54
|
+
stdio: ['inherit', process.stderr, process.stderr],
|
|
55
|
+
});
|
|
56
|
+
if (status !== 0) {
|
|
57
|
+
const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
|
|
58
|
+
throw new Error(`${errorMessage} NGCC failed ${errorMessage ? ', see above' : ''}.`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const ngCompilerCliVersion = findAngularCompilerCliVersion();
|
|
63
|
+
const [ngMajorVersion] = ngCompilerCliVersion.split('.');
|
|
64
|
+
if (parseInt(ngMajorVersion, 10) < 16) {
|
|
65
|
+
console.log(`Warning: Could not locate '@angular/compiler-cli' to run 'ngcc' automatically.` +
|
|
66
|
+
`Please make sure you are running 'ngcc-jest-processor.js' from root level of your project.` +
|
|
67
|
+
`'ngcc' must be run before running Jest`);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
console.log(`@angular/compiler-cli@${ngCompilerCliVersion} detected. Skipping 'ngcc'`);
|
|
71
|
+
console.log(`Tip: To avoid this message you can remove 'jest-preset-angular/global-setup' from your jest config`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
exports.runNgccJestProcessor = runNgccJestProcessor;
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jest-preset-angular",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.3.0",
|
|
4
4
|
"description": "Jest preset configuration for Angular projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": "^14.15.0 || >=16.10.0"
|
|
8
8
|
},
|
|
9
9
|
"main": "build/index.js",
|
|
10
|
+
"typings": "build/index.d.ts",
|
|
10
11
|
"repository": {
|
|
11
12
|
"type": "git",
|
|
12
13
|
"url": "git+https://github.com/thymikee/jest-preset-angular.git"
|
|
@@ -64,30 +65,30 @@
|
|
|
64
65
|
"typescript": ">=4.8"
|
|
65
66
|
},
|
|
66
67
|
"devDependencies": {
|
|
67
|
-
"@angular-devkit/build-angular": "^18.2.
|
|
68
|
-
"@angular-eslint/eslint-plugin": "^18.
|
|
69
|
-
"@angular-eslint/eslint-plugin-template": "^18.
|
|
70
|
-
"@angular-eslint/template-parser": "^18.
|
|
71
|
-
"@angular/animations": "^18.2.
|
|
72
|
-
"@angular/cdk": "^18.2.
|
|
73
|
-
"@angular/common": "^18.2.
|
|
74
|
-
"@angular/compiler": "^18.2.
|
|
75
|
-
"@angular/compiler-cli": "^18.2.
|
|
76
|
-
"@angular/core": "^18.2.
|
|
77
|
-
"@angular/forms": "^18.2.
|
|
78
|
-
"@angular/material": "^18.2.
|
|
79
|
-
"@angular/platform-browser": "^18.2.
|
|
80
|
-
"@angular/platform-browser-dynamic": "^18.2.
|
|
81
|
-
"@babel/core": "^7.
|
|
82
|
-
"@babel/preset-env": "^7.
|
|
68
|
+
"@angular-devkit/build-angular": "^18.2.12",
|
|
69
|
+
"@angular-eslint/eslint-plugin": "^18.4.0",
|
|
70
|
+
"@angular-eslint/eslint-plugin-template": "^18.4.0",
|
|
71
|
+
"@angular-eslint/template-parser": "^18.4.0",
|
|
72
|
+
"@angular/animations": "^18.2.12",
|
|
73
|
+
"@angular/cdk": "^18.2.13",
|
|
74
|
+
"@angular/common": "^18.2.12",
|
|
75
|
+
"@angular/compiler": "^18.2.12",
|
|
76
|
+
"@angular/compiler-cli": "^18.2.12",
|
|
77
|
+
"@angular/core": "^18.2.12",
|
|
78
|
+
"@angular/forms": "^18.2.12",
|
|
79
|
+
"@angular/material": "^18.2.13",
|
|
80
|
+
"@angular/platform-browser": "^18.2.12",
|
|
81
|
+
"@angular/platform-browser-dynamic": "^18.2.12",
|
|
82
|
+
"@babel/core": "^7.26.0",
|
|
83
|
+
"@babel/preset-env": "^7.26.0",
|
|
83
84
|
"@commitlint/cli": "^19.5.0",
|
|
84
85
|
"@commitlint/config-angular": "^19.5.0",
|
|
85
86
|
"@jest/transform": "^29.7.0",
|
|
86
87
|
"@jest/types": "^29.6.3",
|
|
87
88
|
"@types/babel__core": "^7.20.5",
|
|
88
89
|
"@types/babel__preset-env": "^7.9.7",
|
|
89
|
-
"@types/jest": "^29.5.
|
|
90
|
-
"@types/node": "^
|
|
90
|
+
"@types/jest": "^29.5.14",
|
|
91
|
+
"@types/node": "^22.9.0",
|
|
91
92
|
"@types/semver": "^7.5.8",
|
|
92
93
|
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
93
94
|
"@typescript-eslint/parser": "^7.18.0",
|
|
@@ -95,11 +96,11 @@
|
|
|
95
96
|
"chalk": "^4.1.2",
|
|
96
97
|
"conventional-changelog-cli": "^5.0.0",
|
|
97
98
|
"cross-env": "^7.0.3",
|
|
98
|
-
"eslint": "^8.57.
|
|
99
|
+
"eslint": "^8.57.1",
|
|
99
100
|
"eslint-config-prettier": "^9.1.0",
|
|
100
|
-
"eslint-plugin-import": "^2.
|
|
101
|
-
"eslint-plugin-jest": "^28.
|
|
102
|
-
"eslint-plugin-jsdoc": "^50.
|
|
101
|
+
"eslint-plugin-import": "^2.31.0",
|
|
102
|
+
"eslint-plugin-jest": "^28.9.0",
|
|
103
|
+
"eslint-plugin-jsdoc": "^50.5.0",
|
|
103
104
|
"eslint-plugin-prettier": "^4.2.1",
|
|
104
105
|
"execa": "5.1.1",
|
|
105
106
|
"fs-extra": "^11.2.0",
|
|
@@ -112,9 +113,9 @@
|
|
|
112
113
|
"rimraf": "^5.0.10",
|
|
113
114
|
"rxjs": "^7.8.1",
|
|
114
115
|
"ts-node": "^10.9.2",
|
|
115
|
-
"tslib": "^2.
|
|
116
|
+
"tslib": "^2.8.1",
|
|
116
117
|
"typescript": "~5.5.4",
|
|
117
118
|
"zone.js": "~0.15.0"
|
|
118
119
|
},
|
|
119
|
-
"packageManager": "yarn@4.
|
|
120
|
+
"packageManager": "yarn@4.5.1"
|
|
120
121
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { TextDecoder, TextEncoder } from 'util';
|
|
2
|
+
|
|
3
|
+
export const polyfillEncoder = () => {
|
|
4
|
+
if (typeof globalThis.TextEncoder === 'undefined') {
|
|
5
|
+
globalThis.TextEncoder = TextEncoder;
|
|
6
|
+
globalThis.TextDecoder = TextDecoder;
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const resolveTestEnvOptions = (options) => {
|
|
11
|
+
const globalTestEnvOptions = globalThis.ngJest?.testEnvironmentOptions;
|
|
12
|
+
if (globalTestEnvOptions) {
|
|
13
|
+
console.warn(
|
|
14
|
+
'Setting testEnvironmentOptions via globalThis.ngJest is deprecated. Please provide testEnvironmentOptions via function argument',
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return globalTestEnvOptions ?? options;
|
|
19
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require('zone.js');
|
|
2
|
+
require('zone.js/testing');
|
|
3
|
+
|
|
4
|
+
const { TextEncoder, TextDecoder } = require('util');
|
|
5
|
+
|
|
6
|
+
const { getTestBed } = require('@angular/core/testing');
|
|
7
|
+
const {
|
|
8
|
+
BrowserDynamicTestingModule,
|
|
9
|
+
platformBrowserDynamicTesting,
|
|
10
|
+
} = require('@angular/platform-browser-dynamic/testing');
|
|
11
|
+
|
|
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
|
+
};
|
|
29
|
+
|
|
30
|
+
const setupZoneTestEnv = (options) => {
|
|
31
|
+
polyfillEncoder();
|
|
32
|
+
const testEnvironmentOptions = resolveTestEnvOptions(options);
|
|
33
|
+
|
|
34
|
+
getTestBed().initTestEnvironment(
|
|
35
|
+
BrowserDynamicTestingModule,
|
|
36
|
+
platformBrowserDynamicTesting(),
|
|
37
|
+
testEnvironmentOptions,
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
setupZoneTestEnv,
|
|
43
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import 'zone.js';
|
|
2
|
+
import 'zone.js/testing';
|
|
3
|
+
|
|
4
|
+
import { getTestBed } from '@angular/core/testing';
|
|
5
|
+
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
|
6
|
+
|
|
7
|
+
import { polyfillEncoder, resolveTestEnvOptions } from '../utils.mjs';
|
|
8
|
+
|
|
9
|
+
export const setupZoneTestEnv = (options) => {
|
|
10
|
+
polyfillEncoder();
|
|
11
|
+
const testEnvironmentOptions = resolveTestEnvOptions(options);
|
|
12
|
+
|
|
13
|
+
getTestBed().initTestEnvironment(
|
|
14
|
+
BrowserDynamicTestingModule,
|
|
15
|
+
platformBrowserDynamicTesting(),
|
|
16
|
+
testEnvironmentOptions,
|
|
17
|
+
);
|
|
18
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2
|
+
const setupZonelessTestEnv = (_options) => {
|
|
3
|
+
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.',
|
|
6
|
+
);
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
setupZonelessTestEnv,
|
|
11
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ErrorHandler, NgModule, provideExperimentalZonelessChangeDetection } from '@angular/core';
|
|
2
|
+
import { getTestBed } from '@angular/core/testing';
|
|
3
|
+
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
|
4
|
+
|
|
5
|
+
import { polyfillEncoder, resolveTestEnvOptions } from '../utils.mjs';
|
|
6
|
+
|
|
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
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
})
|
|
24
|
+
export class TestModule {}
|
|
25
|
+
|
|
26
|
+
getTestBed().initTestEnvironment(
|
|
27
|
+
[BrowserDynamicTestingModule, TestModule],
|
|
28
|
+
platformBrowserDynamicTesting(),
|
|
29
|
+
testEnvironmentOptions,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
throw Error(
|
|
36
|
+
'Cannot find provideExperimentalZonelessChangeDetection() to setup zoneless testing environment. ' +
|
|
37
|
+
'Please use setupZoneTestEnv() from jest-preset-angular/setup-env/setup-zone-env.mjs instead.',
|
|
38
|
+
);
|
|
39
|
+
};
|
package/setup-jest.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
console.warn(`
|
|
2
|
+
Importing "setup-jest.js" directly is deprecated. The file "setup-jest.js" will be removed in the future.
|
|
3
|
+
Please use "setupZoneTestEnv" function instead. Example:
|
|
4
|
+
|
|
5
|
+
// setup-jest.ts
|
|
6
|
+
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone';
|
|
7
|
+
|
|
8
|
+
setupZoneTestEnv();
|
|
9
|
+
`);
|
|
10
|
+
|
|
1
11
|
require('zone.js');
|
|
2
12
|
require('zone.js/testing');
|
|
3
13
|
const { TextEncoder, TextDecoder } = require('util');
|
package/setup-jest.mjs
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
|
+
console.warn(`
|
|
2
|
+
Importing "setup-jest.mjs" directly is deprecated. The file "setup-jest.mjs" will be removed in the future.
|
|
3
|
+
Please use "setupZoneTestEnv" function instead. Example:
|
|
4
|
+
|
|
5
|
+
// setup-jest.ts
|
|
6
|
+
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone/index.mjs';
|
|
7
|
+
|
|
8
|
+
setupZoneTestEnv();
|
|
9
|
+
`);
|
|
10
|
+
|
|
1
11
|
import 'zone.js';
|
|
2
12
|
import 'zone.js/testing';
|
|
13
|
+
import { TextEncoder, TextDecoder } from 'util';
|
|
14
|
+
|
|
3
15
|
import { getTestBed } from '@angular/core/testing';
|
|
4
16
|
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
|
5
|
-
import { TextEncoder, TextDecoder } from 'util';
|
|
6
17
|
|
|
7
18
|
if (typeof globalThis.TextEncoder === 'undefined') {
|
|
8
19
|
globalThis.TextEncoder = TextEncoder;
|
package/jest-cjs.config.ts
DELETED
package/jest-esm.config.ts
DELETED
package/jest-src.config.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { JestConfigWithTsJest } from 'ts-jest';
|
|
2
|
-
|
|
3
|
-
const config: JestConfigWithTsJest = {
|
|
4
|
-
modulePathIgnorePatterns: ['examples/.*', 'website/.*'],
|
|
5
|
-
testMatch: ['<rootDir>/src/**/*.spec.ts'],
|
|
6
|
-
testEnvironment: 'jsdom',
|
|
7
|
-
transform: {
|
|
8
|
-
'^.+\\.(ts|js|mjs|html)$': [
|
|
9
|
-
'<rootDir>/build/index.js',
|
|
10
|
-
{
|
|
11
|
-
tsconfig: 'tsconfig-base.spec.json',
|
|
12
|
-
isolatedModules: true,
|
|
13
|
-
},
|
|
14
|
-
],
|
|
15
|
-
},
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export default config;
|