jest-preset-angular 8.3.2 → 8.4.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 +440 -0
- package/LICENSE.md +21 -0
- package/README.md +40 -462
- package/build/AngularNoNgAttributesSnapshotSerializer.js +18 -35
- package/build/AngularSnapshotSerializer.js +20 -20
- package/build/HTMLCommentSerializer.js +9 -9
- package/build/InlineFilesTransformer.js +16 -18
- package/build/StripStylesTransformer.js +14 -24
- package/build/TransformUtils.js +1 -1
- package/build/reflect-metadata.js +7 -7
- package/build/serializers/html-comment.js +8 -0
- package/build/serializers/index.js +6 -0
- package/build/serializers/ng-snapshot.js +59 -0
- package/build/serializers/no-ng-attributes.js +42 -0
- package/build/setup-jest.js +3 -3
- package/build/utils/ngcc-jest-processor.js +38 -0
- package/build/zone-patch/index.js +28 -68
- package/index.js +7 -0
- package/jest-preset.js +3 -3
- package/ngcc-jest-processor.js +1 -0
- package/package.json +60 -1
- package/setup-jest.js +1 -0
- package/AngularNoNgAttributesSnapshotSerializer.js +0 -57
- package/AngularSnapshotSerializer.js +0 -79
- package/HTMLCommentSerializer.js +0 -25
- package/zone-patch/README.md +0 -6
- package/zone-patch/index.js +0 -136
package/package.json
CHANGED
|
@@ -1,12 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jest-preset-angular",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.4.0",
|
|
4
4
|
"description": "Jest preset configuration for Angular projects",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": "git@github.com:thymikee/jest-preset-angular.git",
|
|
7
7
|
"homepage": "https://github.com/thymikee/jest-preset-angular",
|
|
8
8
|
"author": "Michał Pierzchała <thymikee@gmail.com>",
|
|
9
9
|
"license": "MIT",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"jest",
|
|
12
|
+
"typescript",
|
|
13
|
+
"angular",
|
|
14
|
+
"testing"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"prebuild": "rimraf ./build",
|
|
18
|
+
"build": "tsc -p tsconfig.build.json",
|
|
19
|
+
"prepare": "yarn build",
|
|
20
|
+
"lint": "eslint --ext .js,.ts .",
|
|
21
|
+
"lint:fix": "eslint --fix --ext .js,.ts .",
|
|
22
|
+
"test:ci": "jest -i",
|
|
23
|
+
"test:e2e": "node scripts/e2e.js",
|
|
24
|
+
"changelog": "conventional-changelog -p angular -i ./CHANGELOG.md -s -r 1"
|
|
25
|
+
},
|
|
10
26
|
"dependencies": {
|
|
11
27
|
"pretty-format": "26.x",
|
|
12
28
|
"ts-jest": "26.x"
|
|
@@ -16,6 +32,49 @@
|
|
|
16
32
|
"@angular/platform-browser-dynamic": ">=2.0.0",
|
|
17
33
|
"jest": "^26.0.0"
|
|
18
34
|
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@angular-eslint/eslint-plugin": "latest",
|
|
37
|
+
"@angular/core": "^9.1.13",
|
|
38
|
+
"@commitlint/cli": "latest",
|
|
39
|
+
"@commitlint/config-angular": "latest",
|
|
40
|
+
"@types/jest": "26.x",
|
|
41
|
+
"@types/node": "12.x",
|
|
42
|
+
"@typescript-eslint/eslint-plugin": "latest",
|
|
43
|
+
"@typescript-eslint/parser": "latest",
|
|
44
|
+
"conventional-changelog-cli": "2.x",
|
|
45
|
+
"eslint": "7.x",
|
|
46
|
+
"eslint-config-prettier": "latest",
|
|
47
|
+
"eslint-plugin-import": "^2.22.1",
|
|
48
|
+
"eslint-plugin-jest": "latest",
|
|
49
|
+
"eslint-plugin-jsdoc": "latest",
|
|
50
|
+
"eslint-plugin-prefer-arrow": "^1.2.3",
|
|
51
|
+
"eslint-plugin-prettier": "latest",
|
|
52
|
+
"execa": "4.x",
|
|
53
|
+
"fs-extra": "^9.1.0",
|
|
54
|
+
"husky": "4.x",
|
|
55
|
+
"jest": "26.x",
|
|
56
|
+
"lint-staged": "latest",
|
|
57
|
+
"lodash.memoize": "4.x",
|
|
58
|
+
"prettier": "2.x",
|
|
59
|
+
"rxjs": "^6.6.6",
|
|
60
|
+
"ts-jest": "26.x",
|
|
61
|
+
"tslib": "1.14.1",
|
|
62
|
+
"typescript": "3.x",
|
|
63
|
+
"zone.js": "0.10.3"
|
|
64
|
+
},
|
|
65
|
+
"husky": {
|
|
66
|
+
"hooks": {
|
|
67
|
+
"pre-commit": "lint-staged",
|
|
68
|
+
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
|
|
69
|
+
"post-commit": "git reset"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"lint-staged": {
|
|
73
|
+
"*.{ts,js}": [
|
|
74
|
+
"eslint --fix",
|
|
75
|
+
"git add"
|
|
76
|
+
]
|
|
77
|
+
},
|
|
19
78
|
"engines": {
|
|
20
79
|
"node": ">= 10"
|
|
21
80
|
}
|
package/setup-jest.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./build/setup-jest');
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const jestDOMElementSerializer = require('pretty-format').plugins.DOMElement;
|
|
4
|
-
|
|
5
|
-
const attributesToRemovePatterns = ['ng-reflect', '_nghost', '_ngcontent', 'ng-version'];
|
|
6
|
-
const attributesToClean = {
|
|
7
|
-
class: [/^(?:mat|cdk|ng).*-\w*\d+-\d+$/, /^ng-star-inserted$/], // e.g. "ng-tns-c25-1" or "ng-star-inserted", literally
|
|
8
|
-
id: [/^(?:mat|cdk|ng).*-\d+$/], // e.g. "mat-input-4", "cdk-step-content-0-0"
|
|
9
|
-
for: [/^(?:mat|cdk|ng).*-\d+$/], // e.g. "mat-form-field-label-9"
|
|
10
|
-
'aria-owns': [/^(?:mat|cdk|ng).*-\d+$/], // e.g. "mat-input-4"
|
|
11
|
-
'aria-labelledby': [/^(?:mat|cdk|ng).*-\d+$/], // e.g. "mat-input-4", "cdk-step-label-0-0"
|
|
12
|
-
'aria-controls': [/^(?:mat|cdk|ng).*-\d+$/], // e.g. "cdk-step-content-2-0"
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const hasAttributesToRemove = (attribute) =>
|
|
16
|
-
attributesToRemovePatterns.some((removePattern) => attribute.name.startsWith(removePattern));
|
|
17
|
-
const hasAttributesToClean = (attribute) =>
|
|
18
|
-
Object.keys(attributesToClean).some((removePatternKey) => attribute.name === removePatternKey);
|
|
19
|
-
|
|
20
|
-
const serialize = (node, ...rest) => {
|
|
21
|
-
const nodeCopy = node.cloneNode(true);
|
|
22
|
-
// Remove angular-specific attributes
|
|
23
|
-
Object.values(nodeCopy.attributes)
|
|
24
|
-
.filter(hasAttributesToRemove)
|
|
25
|
-
.forEach((attribute) => nodeCopy.attributes.removeNamedItem(attribute.name));
|
|
26
|
-
// Remove angular auto-added classes
|
|
27
|
-
Object.values(nodeCopy.attributes)
|
|
28
|
-
.filter(hasAttributesToClean)
|
|
29
|
-
.forEach((attribute) => {
|
|
30
|
-
attribute.value = attribute.value
|
|
31
|
-
.split(' ')
|
|
32
|
-
.filter(
|
|
33
|
-
(attrValue) =>
|
|
34
|
-
!attributesToClean[attribute.name].some((attributeCleanRegex) => attributeCleanRegex.test(attrValue))
|
|
35
|
-
)
|
|
36
|
-
.join(' ');
|
|
37
|
-
if (attribute.value === '') {
|
|
38
|
-
nodeCopy.attributes.removeNamedItem(attribute.name);
|
|
39
|
-
} else {
|
|
40
|
-
nodeCopy.attributes.setNamedItem(attribute);
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
return jestDOMElementSerializer.serialize(nodeCopy, ...rest);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const serializeTestFn = (val) =>
|
|
48
|
-
val.attributes !== undefined &&
|
|
49
|
-
Object.values(val.attributes).some(
|
|
50
|
-
(attribute) => hasAttributesToRemove(attribute) || hasAttributesToClean(attribute)
|
|
51
|
-
);
|
|
52
|
-
const test = (val) => jestDOMElementSerializer.test(val) && serializeTestFn(val);
|
|
53
|
-
|
|
54
|
-
module.exports = {
|
|
55
|
-
serialize,
|
|
56
|
-
test,
|
|
57
|
-
};
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const printAttributes = (val, attributes, print, indent, colors, opts) => {
|
|
4
|
-
return attributes
|
|
5
|
-
.sort()
|
|
6
|
-
.map((attribute) => {
|
|
7
|
-
return (
|
|
8
|
-
opts.spacing +
|
|
9
|
-
indent(colors.prop.open + attribute + colors.prop.close + '=') +
|
|
10
|
-
colors.value.open +
|
|
11
|
-
(val.componentInstance[attribute] && val.componentInstance[attribute].constructor
|
|
12
|
-
? '{[Function ' + val.componentInstance[attribute].constructor.name + ']}'
|
|
13
|
-
: `"${val.componentInstance[attribute]}"`) +
|
|
14
|
-
colors.value.close
|
|
15
|
-
);
|
|
16
|
-
})
|
|
17
|
-
.join('');
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const ivyEnabled = () => {
|
|
21
|
-
// Should be required lazily, since it will throw an exception
|
|
22
|
-
// `Cannot resolve parameters...`.
|
|
23
|
-
const { ɵivyEnabled } = require('@angular/core');
|
|
24
|
-
|
|
25
|
-
return !!ɵivyEnabled;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
// Ivy component definition was stored on the `ngComponentDef`
|
|
29
|
-
// property before `9.0.0-next.10`. Since `9.0.0-next.10` it was
|
|
30
|
-
// renamed to `ɵcmp`.
|
|
31
|
-
const getComponentDef = (type) => type.ngComponentDef || type.ɵcmp;
|
|
32
|
-
|
|
33
|
-
const print = (fixture, print, indent, opts, colors) => {
|
|
34
|
-
let nodes = '';
|
|
35
|
-
let componentAttrs = '';
|
|
36
|
-
let componentName = '';
|
|
37
|
-
|
|
38
|
-
if (ivyEnabled()) {
|
|
39
|
-
const componentDef = getComponentDef(fixture.componentRef.componentType);
|
|
40
|
-
componentName = componentDef.selectors[0][0];
|
|
41
|
-
nodes = Array.from(fixture.componentRef.location.nativeElement.childNodes).map(print).join('');
|
|
42
|
-
} else {
|
|
43
|
-
componentName = fixture.componentRef._elDef.element.name;
|
|
44
|
-
nodes = (fixture.componentRef._view.nodes || [])
|
|
45
|
-
// eslint-disable-next-line no-prototype-builtins
|
|
46
|
-
.filter((node) => node && node.hasOwnProperty('renderElement'))
|
|
47
|
-
.map((node) => Array.from(node.renderElement.childNodes).map(print).join(''))
|
|
48
|
-
.join(opts.edgeSpacing);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const attributes = Object.keys(fixture.componentInstance);
|
|
52
|
-
|
|
53
|
-
if (attributes.length) {
|
|
54
|
-
componentAttrs += printAttributes(fixture, attributes, print, indent, colors, opts);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return (
|
|
58
|
-
'<' +
|
|
59
|
-
componentName +
|
|
60
|
-
componentAttrs +
|
|
61
|
-
(componentAttrs.length ? '\n' : '') +
|
|
62
|
-
'>\n' +
|
|
63
|
-
indent(nodes) +
|
|
64
|
-
'\n</' +
|
|
65
|
-
componentName +
|
|
66
|
-
'>'
|
|
67
|
-
);
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const test = (val) =>
|
|
71
|
-
val !== undefined &&
|
|
72
|
-
val !== null &&
|
|
73
|
-
typeof val === 'object' &&
|
|
74
|
-
Object.prototype.hasOwnProperty.call(val, 'componentRef');
|
|
75
|
-
|
|
76
|
-
module.exports = {
|
|
77
|
-
print: print,
|
|
78
|
-
test: test,
|
|
79
|
-
};
|
package/HTMLCommentSerializer.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the BSD-style license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree. An additional grant
|
|
6
|
-
* of patent rights can be found in the PATENTS file in the same directory.
|
|
7
|
-
*
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
'use strict';
|
|
11
|
-
|
|
12
|
-
const HTML_ELEMENT_REGEXP = /Comment/;
|
|
13
|
-
const test = (value) =>
|
|
14
|
-
value !== undefined &&
|
|
15
|
-
value !== null &&
|
|
16
|
-
value.nodeType === 8 &&
|
|
17
|
-
value.constructor !== undefined &&
|
|
18
|
-
HTML_ELEMENT_REGEXP.test(value.constructor.name);
|
|
19
|
-
|
|
20
|
-
const print = () => '';
|
|
21
|
-
|
|
22
|
-
module.exports = {
|
|
23
|
-
print: print,
|
|
24
|
-
test: test,
|
|
25
|
-
};
|
package/zone-patch/README.md
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
# zone-patch
|
|
2
|
-
Enables Jest functions to be run within Zone.js context, specifically for [Angular](https://angular.io) apps.
|
|
3
|
-
|
|
4
|
-
It's crucial to run this patch here, because at this point patched functions like `test` or `describe` are available in global scope.
|
|
5
|
-
|
|
6
|
-
`zone-patch` has been included in `setupJest.js` by default.
|
package/zone-patch/index.js
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Patch Jest's describe/test/beforeEach/afterEach functions so test code
|
|
3
|
-
* always runs in a testZone (ProxyZone).
|
|
4
|
-
*/
|
|
5
|
-
/* global Zone */
|
|
6
|
-
|
|
7
|
-
if (Zone === undefined) {
|
|
8
|
-
throw new Error('Missing: Zone (zone.js)');
|
|
9
|
-
}
|
|
10
|
-
if (jest === undefined) {
|
|
11
|
-
throw new Error(
|
|
12
|
-
'Missing: jest.\n' +
|
|
13
|
-
'This patch must be included in a script called with ' +
|
|
14
|
-
'`setupTestFrameworkScriptFile` in Jest config.'
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
if (jest['__zone_patch__'] === true) {
|
|
18
|
-
throw new Error("'jest' has already been patched with 'Zone'.");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
jest['__zone_patch__'] = true;
|
|
22
|
-
const SyncTestZoneSpec = Zone['SyncTestZoneSpec'];
|
|
23
|
-
const ProxyZoneSpec = Zone['ProxyZoneSpec'];
|
|
24
|
-
|
|
25
|
-
if (SyncTestZoneSpec === undefined) {
|
|
26
|
-
throw new Error('Missing: SyncTestZoneSpec (zone.js/dist/sync-test)');
|
|
27
|
-
}
|
|
28
|
-
if (ProxyZoneSpec === undefined) {
|
|
29
|
-
throw new Error('Missing: ProxyZoneSpec (zone.js/dist/proxy.js)');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const env = global;
|
|
33
|
-
const ambientZone = Zone.current;
|
|
34
|
-
|
|
35
|
-
// Create a synchronous-only zone in which to run `describe` blocks in order to
|
|
36
|
-
// raise an error if any asynchronous operations are attempted
|
|
37
|
-
// inside of a `describe` but outside of a `beforeEach` or `it`.
|
|
38
|
-
const syncZone = ambientZone.fork(new SyncTestZoneSpec('jest.describe'));
|
|
39
|
-
function wrapDescribeInZone(describeBody) {
|
|
40
|
-
return function (...args) {
|
|
41
|
-
return syncZone.run(describeBody, null, args);
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Create a proxy zone in which to run `test` blocks so that the tests function
|
|
46
|
-
// can retroactively install different zones.
|
|
47
|
-
const testProxyZone = ambientZone.fork(new ProxyZoneSpec());
|
|
48
|
-
function wrapTestInZone(testBody) {
|
|
49
|
-
if (testBody === undefined) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const wrappedFunc = function () {
|
|
54
|
-
return testProxyZone.run(testBody, null, arguments);
|
|
55
|
-
};
|
|
56
|
-
try {
|
|
57
|
-
Object.defineProperty(wrappedFunc, 'length', {
|
|
58
|
-
configurable: true,
|
|
59
|
-
writable: true,
|
|
60
|
-
enumerable: false,
|
|
61
|
-
});
|
|
62
|
-
wrappedFunc.length = testBody.length;
|
|
63
|
-
} catch (e) {
|
|
64
|
-
return testBody.length === 0
|
|
65
|
-
? () => testProxyZone.run(testBody, null)
|
|
66
|
-
: (done) => testProxyZone.run(testBody, null, [done]);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return wrappedFunc;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* bind describe method to wrap describe.each function
|
|
74
|
-
*/
|
|
75
|
-
const bindDescribe = (originalJestFn) =>
|
|
76
|
-
function (...eachArgs) {
|
|
77
|
-
return function (...args) {
|
|
78
|
-
args[1] = wrapDescribeInZone(args[1]);
|
|
79
|
-
|
|
80
|
-
return originalJestFn.apply(this, eachArgs).apply(this, args);
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* bind test method to wrap test.each function
|
|
86
|
-
*/
|
|
87
|
-
const bindTest = (originalJestFn) =>
|
|
88
|
-
function (...eachArgs) {
|
|
89
|
-
return function (...args) {
|
|
90
|
-
args[1] = wrapTestInZone(args[1]);
|
|
91
|
-
|
|
92
|
-
return originalJestFn.apply(this, eachArgs).apply(this, args);
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
['xdescribe', 'fdescribe', 'describe'].forEach((methodName) => {
|
|
97
|
-
const originaljestFn = env[methodName];
|
|
98
|
-
env[methodName] = function (...args) {
|
|
99
|
-
args[1] = wrapDescribeInZone(args[1]);
|
|
100
|
-
|
|
101
|
-
return originaljestFn.apply(this, args);
|
|
102
|
-
};
|
|
103
|
-
env[methodName].each = bindDescribe(originaljestFn.each);
|
|
104
|
-
if (methodName === 'describe') {
|
|
105
|
-
env[methodName].only = env['fdescribe'];
|
|
106
|
-
env[methodName].skip = env['xdescribe'];
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
['xit', 'fit', 'xtest', 'test', 'it'].forEach((methodName) => {
|
|
111
|
-
const originaljestFn = env[methodName];
|
|
112
|
-
env[methodName] = function (...args) {
|
|
113
|
-
args[1] = wrapTestInZone(args[1]);
|
|
114
|
-
|
|
115
|
-
return originaljestFn.apply(this, args);
|
|
116
|
-
};
|
|
117
|
-
env[methodName].each = bindTest(originaljestFn.each);
|
|
118
|
-
|
|
119
|
-
if (methodName === 'test' || methodName === 'it') {
|
|
120
|
-
env[methodName].only = env['fit'];
|
|
121
|
-
env[methodName].skip = env['xit'];
|
|
122
|
-
|
|
123
|
-
env[methodName].todo = function (...args) {
|
|
124
|
-
return originaljestFn.todo.apply(this, args);
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
['beforeEach', 'afterEach', 'beforeAll', 'afterAll'].forEach((methodName) => {
|
|
130
|
-
const originaljestFn = env[methodName];
|
|
131
|
-
env[methodName] = function (...args) {
|
|
132
|
-
args[0] = wrapTestInZone(args[0]);
|
|
133
|
-
|
|
134
|
-
return originaljestFn.apply(this, args);
|
|
135
|
-
};
|
|
136
|
-
});
|