jest-preset-angular 7.0.0 → 8.0.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/.circleci/config.yml +10 -8
- package/.vscode/launch.json +36 -0
- package/CHANGELOG.md +31 -3
- package/README.md +48 -21
- package/build/AngularNoNgAttributesSnapshotSerializer.js +36 -0
- package/build/AngularSnapshotSerializer.js +49 -0
- package/{HTMLCommentSerializer.js → build/HTMLCommentSerializer.js} +11 -14
- package/{InlineHtmlStripStylesTransformer.js → build/InlineFilesTransformer.js} +31 -32
- package/build/StripStylesTransformer.js +122 -0
- package/build/TransformUtils.js +20 -0
- package/build/reflectMetadata.js +21 -0
- package/build/setupJest.js +12 -0
- package/build/zone-patch/index.js +95 -0
- package/greenkeeper.json +10 -0
- package/index.js +1 -1
- package/jest-preset.js +9 -5
- package/package.json +8 -6
- package/tsconfig.json +2 -2
- package/yarn-error.log +3628 -0
- package/AngularSnapshotSerializer.js +0 -67
- package/setupJest.js +0 -19
- package/zone-patch/LICENSE +0 -29
- package/zone-patch/README.md +0 -6
- package/zone-patch/index.js +0 -108
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Code is inspired by
|
|
4
|
+
* https://github.com/kulshekhar/ts-jest/blob/25e1c63dd3797793b0f46fa52fdee580b46f66ae/src/transformers/hoist-jest.ts
|
|
5
|
+
*
|
|
6
|
+
*
|
|
7
|
+
* IMPLEMENTATION DETAILS:
|
|
8
|
+
* This transformer handles one concern: removing styles.
|
|
9
|
+
*
|
|
10
|
+
* The property 'styles' inside a @Component(...) Decorator argument will
|
|
11
|
+
* be modified, even if they are not used in the context of an
|
|
12
|
+
* Angular Component.
|
|
13
|
+
*
|
|
14
|
+
* This is the required AST to trigger the transformation:
|
|
15
|
+
*
|
|
16
|
+
* ClassDeclaration
|
|
17
|
+
* Decorator
|
|
18
|
+
* CallExpression
|
|
19
|
+
* ObjectLiteralExpression
|
|
20
|
+
* PropertyAssignment
|
|
21
|
+
* Identifier
|
|
22
|
+
* StringLiteral
|
|
23
|
+
*/
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
/** Angular component decorator Styles property name */
|
|
26
|
+
var STYLES = 'styles';
|
|
27
|
+
/** Angular component decorator name */
|
|
28
|
+
var COMPONENT = 'Component';
|
|
29
|
+
/** All props to be transformed inside a decorator */
|
|
30
|
+
var TRANSFORM_IN_DECORATOR_PROPS = [STYLES];
|
|
31
|
+
/**
|
|
32
|
+
* Transformer ID
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
exports.name = 'angular-component-strip-styles';
|
|
36
|
+
// increment this each time the code is modified
|
|
37
|
+
/**
|
|
38
|
+
* Transformer Version
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
exports.version = 1;
|
|
42
|
+
/**
|
|
43
|
+
* The factory of hoisting transformer factory
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
46
|
+
function factory(cs) {
|
|
47
|
+
/**
|
|
48
|
+
* Our compiler (typescript, or a module with typescript-like interface)
|
|
49
|
+
*/
|
|
50
|
+
var ts = cs.compilerModule;
|
|
51
|
+
/**
|
|
52
|
+
* Traverses the AST down inside a decorator to a styles assignment
|
|
53
|
+
* and returns a boolean indicating if it should be transformed.
|
|
54
|
+
*/
|
|
55
|
+
function isInDecoratorPropertyAssignmentToTransform(node) {
|
|
56
|
+
return getInDecoratorPropertyAssignmentsToTransform(node).length > 0;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Traverses the AST down inside a decorator to a styles assignment
|
|
60
|
+
* returns it in an array.
|
|
61
|
+
*/
|
|
62
|
+
function getInDecoratorPropertyAssignmentsToTransform(node) {
|
|
63
|
+
if (!ts.isClassDeclaration(node) || !node.decorators) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
return node.decorators
|
|
67
|
+
.map(function (dec) { return dec.expression; })
|
|
68
|
+
.filter(ts.isCallExpression)
|
|
69
|
+
.filter(function (callExpr) {
|
|
70
|
+
return ts.isIdentifier(callExpr.expression) && callExpr.expression.getText() === COMPONENT;
|
|
71
|
+
})
|
|
72
|
+
.reduce(function (acc, nxtCallExpr) { return Array.prototype.concat.apply(acc, nxtCallExpr.arguments
|
|
73
|
+
.filter(ts.isObjectLiteralExpression)
|
|
74
|
+
.reduce(function (acc, nxtArg) { return Array.prototype.concat.apply(acc, nxtArg.properties
|
|
75
|
+
.filter(ts.isPropertyAssignment)
|
|
76
|
+
.filter(function (propAss) {
|
|
77
|
+
return ts.isIdentifier(propAss.name) &&
|
|
78
|
+
TRANSFORM_IN_DECORATOR_PROPS.includes(propAss.name.text);
|
|
79
|
+
})); }, [])); }, []);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Clones the styles assignment and manipulates it.
|
|
83
|
+
* @param node the property assignment to change
|
|
84
|
+
*/
|
|
85
|
+
function transformStylesAssignmentForJest(node) {
|
|
86
|
+
var mutableNode = ts.getMutableClone(node);
|
|
87
|
+
var assignments = getInDecoratorPropertyAssignmentsToTransform(mutableNode);
|
|
88
|
+
assignments.forEach(function (assignment) {
|
|
89
|
+
if (assignment.name.text === STYLES) {
|
|
90
|
+
// replace initializer array with empty array
|
|
91
|
+
assignment.initializer = ts.createArrayLiteral();
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
return mutableNode;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Create a source file visitor which will visit all nodes in a source file
|
|
98
|
+
* @param ctx The typescript transformation context
|
|
99
|
+
* @param _ The owning source file
|
|
100
|
+
*/
|
|
101
|
+
function createVisitor(ctx, _) {
|
|
102
|
+
/**
|
|
103
|
+
* Main visitor, which will be called recursively for each node in the source file's AST
|
|
104
|
+
* @param node The node to be visited
|
|
105
|
+
*/
|
|
106
|
+
var visitor = function (node) {
|
|
107
|
+
// before we create a deep clone to modify, we make sure that
|
|
108
|
+
// this is an assignment which we want to transform
|
|
109
|
+
if (isInDecoratorPropertyAssignmentToTransform(node)) {
|
|
110
|
+
// get transformed node with changed properties
|
|
111
|
+
return transformStylesAssignmentForJest(node);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// else look for assignments inside this node recursively
|
|
115
|
+
return ts.visitEachChild(node, visitor, ctx);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
return visitor;
|
|
119
|
+
}
|
|
120
|
+
return function (ctx) { return function (sf) { return ts.visitNode(sf, createVisitor(ctx, sf)); }; };
|
|
121
|
+
}
|
|
122
|
+
exports.factory = factory;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* returns the compiler function to create a string literal. If an old version
|
|
5
|
+
* of the TypeScript module is used, it will create a function that replaces the
|
|
6
|
+
* behavior of the `createStringLiteral` function.
|
|
7
|
+
* @param ts TypeScript compiler module
|
|
8
|
+
*/
|
|
9
|
+
function getCreateStringLiteral(ts) {
|
|
10
|
+
if (ts.createStringLiteral && typeof ts.createStringLiteral === 'function') {
|
|
11
|
+
return ts.createStringLiteral;
|
|
12
|
+
}
|
|
13
|
+
return function createStringLiteral(text) {
|
|
14
|
+
var node = (ts.createNode(ts.SyntaxKind.StringLiteral, -1, -1));
|
|
15
|
+
node.text = text;
|
|
16
|
+
node.flags |= ts.NodeFlags.Synthesized;
|
|
17
|
+
return node;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
exports.getCreateStringLiteral = getCreateStringLiteral;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var METADATA_KEY_PARAMTYPES = "design:paramtypes";
|
|
3
|
+
var CTOR_PARAMETERS_JPA = "ctorParametersJPA";
|
|
4
|
+
// weird workaround to avoid 'ReferenceError: globalThis is not defined' in node version < 11
|
|
5
|
+
global.globalThis = global.globalThis || undefined;
|
|
6
|
+
var _global = globalThis || global; // globalThis available since node v12/TS v3.4
|
|
7
|
+
var reflect = _global["Reflect"]; // reflect type in global has not these methods
|
|
8
|
+
// let's not blindly override, maybe there is already a reflect lib in use
|
|
9
|
+
// but just overriding one of the two functions does not serve any purpose
|
|
10
|
+
if (!reflect.metadata && !reflect.getOwnMetadata) {
|
|
11
|
+
reflect.metadata = function (metadataKey, metadataValue) { return function (target, key) {
|
|
12
|
+
if (metadataKey === METADATA_KEY_PARAMTYPES && key === undefined) { // key undefined is ctor
|
|
13
|
+
target[CTOR_PARAMETERS_JPA] = metadataValue;
|
|
14
|
+
}
|
|
15
|
+
}; };
|
|
16
|
+
reflect.getOwnMetadata = function (metadata, target, key) {
|
|
17
|
+
if (metadata === METADATA_KEY_PARAMTYPES && key === undefined) { // key undefined is ctor
|
|
18
|
+
return target[CTOR_PARAMETERS_JPA];
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
require('./reflectMetadata');
|
|
3
|
+
require('zone.js/dist/zone.js');
|
|
4
|
+
require('zone.js/dist/proxy.js');
|
|
5
|
+
require('zone.js/dist/sync-test');
|
|
6
|
+
require('zone.js/dist/async-test');
|
|
7
|
+
require('zone.js/dist/fake-async-test');
|
|
8
|
+
require('./zone-patch');
|
|
9
|
+
var getTestBed = require('@angular/core/testing').getTestBed;
|
|
10
|
+
var BrowserDynamicTestingModule = require('@angular/platform-browser-dynamic/testing').BrowserDynamicTestingModule;
|
|
11
|
+
var platformBrowserDynamicTesting = require('@angular/platform-browser-dynamic/testing').platformBrowserDynamicTesting;
|
|
12
|
+
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Patch Jest's describe/test/beforeEach/afterEach functions so test code
|
|
4
|
+
* always runs in a testZone (ProxyZone).
|
|
5
|
+
*/
|
|
6
|
+
if (Zone === undefined) {
|
|
7
|
+
throw new Error('Missing: Zone (zone.js)');
|
|
8
|
+
}
|
|
9
|
+
if (jest === undefined) {
|
|
10
|
+
throw new Error('Missing: jest.\n' +
|
|
11
|
+
'This patch must be included in a script called with ' +
|
|
12
|
+
'`setupTestFrameworkScriptFile` in Jest config.');
|
|
13
|
+
}
|
|
14
|
+
if (jest['__zone_patch__'] === true) {
|
|
15
|
+
throw new Error("'jest' has already been patched with 'Zone'.");
|
|
16
|
+
}
|
|
17
|
+
jest['__zone_patch__'] = true;
|
|
18
|
+
var SyncTestZoneSpec = Zone['SyncTestZoneSpec'];
|
|
19
|
+
var ProxyZoneSpec = Zone['ProxyZoneSpec'];
|
|
20
|
+
if (SyncTestZoneSpec === undefined) {
|
|
21
|
+
throw new Error('Missing: SyncTestZoneSpec (zone.js/dist/sync-test)');
|
|
22
|
+
}
|
|
23
|
+
if (ProxyZoneSpec === undefined) {
|
|
24
|
+
throw new Error('Missing: ProxyZoneSpec (zone.js/dist/proxy.js)');
|
|
25
|
+
}
|
|
26
|
+
var env = global;
|
|
27
|
+
var ambientZone = Zone.current;
|
|
28
|
+
// Create a synchronous-only zone in which to run `describe` blocks in order to
|
|
29
|
+
// raise an error if any asynchronous operations are attempted
|
|
30
|
+
// inside of a `describe` but outside of a `beforeEach` or `it`.
|
|
31
|
+
var syncZone = ambientZone.fork(new SyncTestZoneSpec('jest.describe'));
|
|
32
|
+
function wrapDescribeInZone(describeBody) {
|
|
33
|
+
return function () {
|
|
34
|
+
return syncZone.run(describeBody, null, arguments);
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// Create a proxy zone in which to run `test` blocks so that the tests function
|
|
38
|
+
// can retroactively install different zones.
|
|
39
|
+
var testProxyZone = ambientZone.fork(new ProxyZoneSpec());
|
|
40
|
+
function wrapTestInZone(testBody) {
|
|
41
|
+
if (testBody === undefined) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
return testBody.length === 0
|
|
45
|
+
? function () { return testProxyZone.run(testBody, null); }
|
|
46
|
+
: function (done) { return testProxyZone.run(testBody, null, [done]); };
|
|
47
|
+
}
|
|
48
|
+
var bindDescribe = function (originalJestFn) {
|
|
49
|
+
return function () {
|
|
50
|
+
var eachArguments = arguments;
|
|
51
|
+
return function (description, specDefinitions, timeout) {
|
|
52
|
+
arguments[1] = wrapDescribeInZone(specDefinitions);
|
|
53
|
+
return originalJestFn.apply(this, eachArguments).apply(this, arguments);
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
['xdescribe', 'fdescribe', 'describe'].forEach(function (methodName) {
|
|
58
|
+
var originaljestFn = env[methodName];
|
|
59
|
+
env[methodName] = function (description, specDefinitions, timeout) {
|
|
60
|
+
arguments[1] = wrapDescribeInZone(specDefinitions);
|
|
61
|
+
return originaljestFn.apply(this, arguments);
|
|
62
|
+
};
|
|
63
|
+
env[methodName].each = bindDescribe(originaljestFn.each);
|
|
64
|
+
if (methodName === 'describe') {
|
|
65
|
+
env[methodName].only = env['fdescribe'];
|
|
66
|
+
env[methodName].skip = env['xdescribe'];
|
|
67
|
+
env[methodName].only.each = bindDescribe(originaljestFn.only.each);
|
|
68
|
+
env[methodName].skip.each = bindDescribe(originaljestFn.skip.each);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
['xit', 'fit', 'xtest', 'test', 'it'].forEach(function (methodName) {
|
|
72
|
+
var originaljestFn = env[methodName];
|
|
73
|
+
env[methodName] = function (description, specDefinitions, timeout) {
|
|
74
|
+
arguments[1] = wrapTestInZone(specDefinitions);
|
|
75
|
+
return originaljestFn.apply(this, arguments);
|
|
76
|
+
};
|
|
77
|
+
// The revised method will be populated to the final each method, so we only declare the method that in the new globals
|
|
78
|
+
env[methodName].each = originaljestFn.each;
|
|
79
|
+
if (methodName === 'test' || methodName === 'it') {
|
|
80
|
+
env[methodName].only = env['fit'];
|
|
81
|
+
env[methodName].only.each = originaljestFn.only.each;
|
|
82
|
+
env[methodName].skip = env['xit'];
|
|
83
|
+
env[methodName].skip.each = originaljestFn.skip.each;
|
|
84
|
+
env[methodName].todo = function (description) {
|
|
85
|
+
return originaljestFn.todo.apply(this, arguments);
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
['beforeEach', 'afterEach', 'beforeAll', 'afterAll'].forEach(function (methodName) {
|
|
90
|
+
var originaljestFn = env[methodName];
|
|
91
|
+
env[methodName] = function (specDefinitions, timeout) {
|
|
92
|
+
arguments[0] = wrapTestInZone(specDefinitions);
|
|
93
|
+
return originaljestFn.apply(this, arguments);
|
|
94
|
+
};
|
|
95
|
+
});
|
package/greenkeeper.json
ADDED
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = require('./setupJest.js');
|
|
1
|
+
module.exports = require('./build/setupJest.js');
|
package/jest-preset.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
globals: {
|
|
3
3
|
'ts-jest': {
|
|
4
|
-
tsConfig: '<rootDir>/
|
|
4
|
+
tsConfig: '<rootDir>/tsconfig.spec.json',
|
|
5
5
|
stringifyContentPathRegex: '\\.html$',
|
|
6
|
-
astTransformers: [
|
|
6
|
+
astTransformers: [
|
|
7
|
+
'jest-preset-angular/build/InlineFilesTransformer',
|
|
8
|
+
'jest-preset-angular/build/StripStylesTransformer',
|
|
9
|
+
],
|
|
7
10
|
},
|
|
8
11
|
},
|
|
9
12
|
transform: {
|
|
10
13
|
'^.+\\.(ts|js|html)$': 'ts-jest',
|
|
11
14
|
},
|
|
12
|
-
testEnvironment: 'jest-environment-jsdom-
|
|
15
|
+
testEnvironment: 'jest-environment-jsdom-fifteen',
|
|
13
16
|
moduleFileExtensions: ['ts', 'html', 'js', 'json'],
|
|
14
17
|
moduleNameMapper: {
|
|
15
18
|
'^src/(.*)$': '<rootDir>/src/$1',
|
|
@@ -19,7 +22,8 @@ module.exports = {
|
|
|
19
22
|
},
|
|
20
23
|
transformIgnorePatterns: ['node_modules/(?!@ngrx)'],
|
|
21
24
|
snapshotSerializers: [
|
|
22
|
-
'jest-preset-angular/
|
|
23
|
-
'jest-preset-angular/
|
|
25
|
+
'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
|
|
26
|
+
'jest-preset-angular/build/AngularSnapshotSerializer.js',
|
|
27
|
+
'jest-preset-angular/build/HTMLCommentSerializer.js',
|
|
24
28
|
],
|
|
25
29
|
};
|
package/package.json
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jest-preset-angular",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.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
|
+
"homepage": "https://github.com/thymikee/jest-preset-angular",
|
|
7
8
|
"author": "Michał Pierzchała <thymikee@gmail.com>",
|
|
8
9
|
"license": "MIT",
|
|
9
10
|
"dependencies": {
|
|
10
|
-
"jest-environment-jsdom-
|
|
11
|
+
"jest-environment-jsdom-fifteen": "^1.0.0",
|
|
12
|
+
"pretty-format": "^24.0.0",
|
|
11
13
|
"ts-jest": "^24.0.0"
|
|
12
14
|
},
|
|
13
15
|
"devDependencies": {
|
|
14
|
-
"@types/jest": "^24.0.
|
|
15
|
-
"@types/node": "^11.
|
|
16
|
+
"@types/jest": "^24.0.11",
|
|
17
|
+
"@types/node": "^11.11.5",
|
|
16
18
|
"jest": "^24.0.0",
|
|
17
|
-
"typescript": "^3.
|
|
19
|
+
"typescript": "^3.6.3"
|
|
18
20
|
},
|
|
19
21
|
"peerDependencies": {
|
|
20
22
|
"@angular/core": ">=2.0.0",
|
|
@@ -28,7 +30,7 @@
|
|
|
28
30
|
"tsConfig": "<rootDir>/tsconfig.spec.json"
|
|
29
31
|
}
|
|
30
32
|
},
|
|
31
|
-
"rootDir": "__tests__"
|
|
33
|
+
"rootDir": "src/__tests__"
|
|
32
34
|
},
|
|
33
35
|
"scripts": {
|
|
34
36
|
"build": "tsc",
|
package/tsconfig.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"target": "es5",
|
|
4
4
|
"module": "commonjs",
|
|
5
|
-
"outDir": "
|
|
5
|
+
"outDir": "./build",
|
|
6
6
|
"strict": true,
|
|
7
7
|
"lib": ["esnext"],
|
|
8
8
|
"allowSyntheticDefaultImports": true,
|
|
@@ -11,5 +11,5 @@
|
|
|
11
11
|
"types": ["node"]
|
|
12
12
|
},
|
|
13
13
|
"include": ["src"],
|
|
14
|
-
"exclude": []
|
|
14
|
+
"exclude": ["**/__tests__"]
|
|
15
15
|
}
|