escover 1.10.0 → 1.14.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 +28 -0
- package/README.md +14 -1
- package/bin/escover.js +4 -2
- package/lib/cli/cli.js +2 -2
- package/lib/coverage-file/coverage-file.js +15 -14
- package/lib/coverage-file/lcov.js +52 -0
- package/lib/exit.js +2 -2
- package/lib/formatters/files.js +2 -0
- package/lib/formatters/lines.js +2 -6
- package/lib/instrument/index.js +0 -1
- package/lib/instrument/plugin-mark/{return.js → argument.js} +1 -1
- package/lib/instrument/plugin-mark/index.js +50 -30
- package/package.json +3 -1
- package/lib/instrument/plugin-mark/throw.js +0 -17
package/ChangeLog
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
2022.01.21, v1.14.0
|
|
2
|
+
|
|
3
|
+
feature:
|
|
4
|
+
- escover: instrument: integrate with putout with crawling enabled
|
|
5
|
+
- escover: format: files: add align center
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
2022.01.20, v1.13.0
|
|
9
|
+
|
|
10
|
+
feature:
|
|
11
|
+
- escover: add ability to read lcov
|
|
12
|
+
- coverage-file: add ability to parse lcov
|
|
13
|
+
- escover: mark: add support of break
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
2022.01.19, v1.12.0
|
|
17
|
+
|
|
18
|
+
feature:
|
|
19
|
+
- escover: add lcov support
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
2022.01.19, v1.11.0
|
|
23
|
+
|
|
24
|
+
feature:
|
|
25
|
+
- escover: mark: add support of continue
|
|
26
|
+
- escover: coverage-file: read -> readCoverage
|
|
27
|
+
|
|
28
|
+
|
|
1
29
|
2022.01.19, v1.10.0
|
|
2
30
|
|
|
3
31
|
feature:
|
package/README.md
CHANGED
|
@@ -31,7 +31,11 @@ which are needed to load module again, and apply mocks.
|
|
|
31
31
|
|
|
32
32
|
### 🤷 How to get coverage when mocks are used?
|
|
33
33
|
|
|
34
|
-
☝️ Use
|
|
34
|
+
☝️ Use 🎩`ESCover`! It supports loaders, `ESM` and collects coverage as a loader!
|
|
35
|
+
|
|
36
|
+
### 🤷 What with [`coveralls`](https://coveralls.io/)? Does [`lcov`](https://github.com/StevenLooman/mocha-lcov-reporter) supported?
|
|
37
|
+
|
|
38
|
+
☝️ Sure! `coverage/lcov.info` is main coverage file for 🎩`ESCover`.
|
|
35
39
|
|
|
36
40
|
## Install
|
|
37
41
|
|
|
@@ -55,6 +59,15 @@ When everything is covered:
|
|
|
55
59
|
|
|
56
60
|

|
|
57
61
|
|
|
62
|
+
## What formatters exists?
|
|
63
|
+
|
|
64
|
+
There is two types of formatters:
|
|
65
|
+
|
|
66
|
+
- `lines` adds links to each line;
|
|
67
|
+
- `files` shows information in table;
|
|
68
|
+
|
|
69
|
+
You can choose formatter with `ESCOVER_FORMAT` env variable.
|
|
70
|
+
|
|
58
71
|
## What if I want to use 🎩`ESCover` with `mock-import`?
|
|
59
72
|
|
|
60
73
|
Experimental `loaders` supports only one, for now. So [zenload](https://github.com/coderaiser/zenload) should be used.
|
package/bin/escover.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import {cli} from '../lib/cli/cli.js';
|
|
4
|
-
import {
|
|
4
|
+
import {readCoverage} from '../lib/coverage-file/coverage-file.js';
|
|
5
|
+
import {readConfig} from '../lib/config.js';
|
|
5
6
|
|
|
6
7
|
cli({
|
|
7
8
|
argv: process.argv,
|
|
8
9
|
exit: process.exit,
|
|
9
|
-
|
|
10
|
+
readCoverage,
|
|
11
|
+
readConfig,
|
|
10
12
|
});
|
|
11
13
|
|
package/lib/cli/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import reportFiles from '../formatters/files.js';
|
|
|
8
8
|
|
|
9
9
|
const {ESCOVER_FORMAT, NODE_OPTIONS = ''} = process.env;
|
|
10
10
|
|
|
11
|
-
export const cli = ({argv, exit,
|
|
11
|
+
export const cli = ({argv, exit, readCoverage}) => {
|
|
12
12
|
const args = yargsParser(argv.slice(2), {
|
|
13
13
|
string: [
|
|
14
14
|
'format',
|
|
@@ -36,7 +36,7 @@ export const cli = ({argv, exit, read}) => {
|
|
|
36
36
|
execute('"' + cmd.join(`" "`) + '"', exit);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
const coverage =
|
|
39
|
+
const coverage = readCoverage();
|
|
40
40
|
|
|
41
41
|
let output = '';
|
|
42
42
|
|
|
@@ -3,46 +3,47 @@ import {
|
|
|
3
3
|
readFileSync,
|
|
4
4
|
} from 'fs';
|
|
5
5
|
import tryCatch from 'try-catch';
|
|
6
|
+
import {join} from 'path';
|
|
6
7
|
import {getFileEntries} from '../c4.js';
|
|
7
8
|
import {transform} from '../transform.js';
|
|
8
9
|
import {merge} from '../merge.js';
|
|
9
10
|
import {findCacheDir} from './find-cache-dir.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} = JSON;
|
|
11
|
+
import {
|
|
12
|
+
generateLcov,
|
|
13
|
+
parseLcov,
|
|
14
|
+
} from './lcov.js';
|
|
15
15
|
|
|
16
16
|
const NAME = 'escover';
|
|
17
|
-
const
|
|
17
|
+
const LCOV = 'lcov.info';
|
|
18
18
|
|
|
19
|
-
export const
|
|
19
|
+
export const writeCoverage = () => {
|
|
20
20
|
const files = getFileEntries();
|
|
21
21
|
|
|
22
22
|
if (!files.size)
|
|
23
23
|
return;
|
|
24
24
|
|
|
25
25
|
const parsed = transform(files);
|
|
26
|
-
|
|
27
26
|
const merged = merge(parsed);
|
|
28
|
-
const
|
|
27
|
+
const lcov = generateLcov(merged);
|
|
28
|
+
|
|
29
|
+
const dir = findCacheDir({
|
|
29
30
|
name: NAME,
|
|
30
31
|
create: true,
|
|
31
32
|
});
|
|
32
33
|
|
|
33
|
-
writeFileSync(
|
|
34
|
+
writeFileSync(join(dir, LCOV), lcov);
|
|
34
35
|
};
|
|
35
36
|
|
|
36
|
-
export const
|
|
37
|
-
const
|
|
37
|
+
export const readCoverage = () => {
|
|
38
|
+
const dir = findCacheDir({
|
|
38
39
|
name: NAME,
|
|
39
40
|
});
|
|
40
41
|
|
|
41
|
-
const [error, data] = tryCatch(readFileSync,
|
|
42
|
+
const [error, data] = tryCatch(readFileSync, join(dir, LCOV), 'utf8');
|
|
42
43
|
|
|
43
44
|
if (error)
|
|
44
45
|
return [];
|
|
45
46
|
|
|
46
|
-
return
|
|
47
|
+
return parseLcov(data);
|
|
47
48
|
};
|
|
48
49
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const {entries} = Object;
|
|
2
|
+
|
|
3
|
+
export const generateLcov = (files) => {
|
|
4
|
+
const result = [];
|
|
5
|
+
|
|
6
|
+
for (const {name, lines} of files) {
|
|
7
|
+
result.push(`SF:${name}`);
|
|
8
|
+
for (const [line, covered] of entries(lines)) {
|
|
9
|
+
const count = covered ? 1 : 0;
|
|
10
|
+
result.push(`DA:${line},${count}`);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
result.push('end_of_record');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return result.join('\n');
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const isEnd = (a) => a === 'end_of_record';
|
|
20
|
+
|
|
21
|
+
export const parseLcov = (lcov) => {
|
|
22
|
+
const files = [];
|
|
23
|
+
let name = '';
|
|
24
|
+
let lines = {};
|
|
25
|
+
|
|
26
|
+
for (const current of lcov.split('\n')) {
|
|
27
|
+
const [cmd, arg] = current.split(':');
|
|
28
|
+
|
|
29
|
+
if (cmd === 'SF') {
|
|
30
|
+
name = arg;
|
|
31
|
+
lines = {};
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (cmd === 'DA') {
|
|
36
|
+
const [line, covered] = arg.split(',');
|
|
37
|
+
lines[line] = Boolean(Number(covered));
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (isEnd(cmd)) {
|
|
42
|
+
files.push({
|
|
43
|
+
name,
|
|
44
|
+
lines,
|
|
45
|
+
});
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return files;
|
|
51
|
+
};
|
|
52
|
+
|
package/lib/exit.js
CHANGED
package/lib/formatters/files.js
CHANGED
package/lib/formatters/lines.js
CHANGED
|
@@ -56,19 +56,15 @@ export default (coverageFile) => {
|
|
|
56
56
|
out(`1..${files.length}`);
|
|
57
57
|
out(`# files: ${files.length}`);
|
|
58
58
|
out(`# covered: ${coverage.coveredCount}`);
|
|
59
|
-
|
|
60
59
|
out('');
|
|
61
60
|
|
|
62
|
-
if (!coverage.uncoveredCount)
|
|
61
|
+
if (!coverage.uncoveredCount)
|
|
63
62
|
out('#️ 🌴 ok');
|
|
64
|
-
}
|
|
65
63
|
|
|
66
|
-
if (coverage.uncoveredCount)
|
|
64
|
+
if (coverage.uncoveredCount)
|
|
67
65
|
out(`# 🧨 fail: ${coverage.uncoveredCount}`);
|
|
68
|
-
}
|
|
69
66
|
|
|
70
67
|
out('');
|
|
71
68
|
|
|
72
69
|
return output.join('\n');
|
|
73
70
|
};
|
|
74
|
-
|
package/lib/instrument/index.js
CHANGED
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
types,
|
|
4
4
|
operator,
|
|
5
5
|
} from 'putout';
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
import {addMarkToArgument} from './argument.js';
|
|
7
8
|
import {addMarkToArrowFunction} from './arrow.js';
|
|
8
|
-
import {addMarkToThrow} from './throw.js';
|
|
9
9
|
|
|
10
10
|
const {
|
|
11
11
|
NumericLiteral,
|
|
@@ -16,6 +16,8 @@ const {
|
|
|
16
16
|
const {
|
|
17
17
|
replaceWith,
|
|
18
18
|
compareAny,
|
|
19
|
+
compare,
|
|
20
|
+
replaceWithMultiple,
|
|
19
21
|
} = operator;
|
|
20
22
|
|
|
21
23
|
const LINE = `__c4['🧨'](__l, __c)`;
|
|
@@ -36,12 +38,10 @@ export const report = () => 'Mark line';
|
|
|
36
38
|
|
|
37
39
|
export const fix = (path, {options}) => {
|
|
38
40
|
const {node} = path;
|
|
39
|
-
|
|
40
41
|
const {start} = path.node.loc;
|
|
41
42
|
|
|
42
43
|
const {
|
|
43
44
|
c4 = {
|
|
44
|
-
mark: () => {},
|
|
45
45
|
init: () => {},
|
|
46
46
|
},
|
|
47
47
|
} = options;
|
|
@@ -53,8 +53,9 @@ export const fix = (path, {options}) => {
|
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
if (path.isCallExpression()) {
|
|
56
|
+
if (path.isCallExpression() || path.isNewExpression()) {
|
|
57
57
|
const {node} = path;
|
|
58
|
+
|
|
58
59
|
replaceWith(path, SequenceExpression([
|
|
59
60
|
lineNode.expression,
|
|
60
61
|
node,
|
|
@@ -82,24 +83,19 @@ export const fix = (path, {options}) => {
|
|
|
82
83
|
return;
|
|
83
84
|
}
|
|
84
85
|
|
|
85
|
-
if (path.
|
|
86
|
-
|
|
87
|
-
lineNode.expression,
|
|
88
|
-
node,
|
|
89
|
-
]));
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
86
|
+
if (path.isArrowFunctionExpression())
|
|
87
|
+
return addMarkToArrowFunction(path, lineNode);
|
|
92
88
|
|
|
93
|
-
if (path.isReturnStatement())
|
|
94
|
-
return
|
|
89
|
+
if (path.isReturnStatement() || path.isThrowStatement())
|
|
90
|
+
return addMarkToArgument(path, lineNode);
|
|
95
91
|
|
|
96
|
-
if (path.
|
|
97
|
-
return
|
|
92
|
+
if (path.isContinueStatement() || path.isBreakStatement()) {
|
|
93
|
+
return replaceWithMultiple(path, [
|
|
94
|
+
lineNode,
|
|
95
|
+
path.node,
|
|
96
|
+
]);
|
|
98
97
|
}
|
|
99
98
|
|
|
100
|
-
if (path.isThrowStatement())
|
|
101
|
-
return addMarkToThrow(path, lineNode);
|
|
102
|
-
|
|
103
99
|
replaceWith(path, BlockStatement([
|
|
104
100
|
node,
|
|
105
101
|
]));
|
|
@@ -107,24 +103,39 @@ export const fix = (path, {options}) => {
|
|
|
107
103
|
|
|
108
104
|
const EXCLUDE = [
|
|
109
105
|
LINE,
|
|
110
|
-
`(${LINE}, __z)`,
|
|
111
106
|
`return (${LINE}, __z)`,
|
|
112
107
|
`return ${LINE}`,
|
|
113
108
|
`throw (${LINE}, __z)`,
|
|
114
109
|
];
|
|
115
110
|
|
|
116
|
-
|
|
111
|
+
const SEQUENCE = `(${LINE}, __z)`;
|
|
112
|
+
const isExclude = (node) => {
|
|
113
|
+
return compareAny(node, [
|
|
114
|
+
...EXCLUDE,
|
|
115
|
+
SEQUENCE,
|
|
116
|
+
]);
|
|
117
|
+
};
|
|
117
118
|
|
|
118
|
-
export const
|
|
119
|
-
'CallExpression',
|
|
120
|
-
'NewExpression',
|
|
121
|
-
'ReturnStatement',
|
|
122
|
-
'ThrowStatement',
|
|
123
|
-
];
|
|
119
|
+
export const exclude = () => EXCLUDE;
|
|
124
120
|
|
|
125
121
|
export const traverse = ({push}) => ({
|
|
122
|
+
'ThrowStatement|ReturnStatement'(path) {
|
|
123
|
+
push(path);
|
|
124
|
+
},
|
|
125
|
+
CallExpression(path) {
|
|
126
|
+
if (compare(path.parentPath.node, SEQUENCE))
|
|
127
|
+
return;
|
|
128
|
+
|
|
129
|
+
push(path);
|
|
130
|
+
},
|
|
131
|
+
'CallExpression|NewExpression'(path) {
|
|
132
|
+
if (compare(path.parentPath.node, SEQUENCE))
|
|
133
|
+
return;
|
|
134
|
+
|
|
135
|
+
push(path);
|
|
136
|
+
},
|
|
126
137
|
'AssignmentPattern|AssignmentExpression'(path) {
|
|
127
|
-
if (
|
|
138
|
+
if (isExclude(path.get('right')))
|
|
128
139
|
return;
|
|
129
140
|
|
|
130
141
|
push(path);
|
|
@@ -135,8 +146,14 @@ export const traverse = ({push}) => ({
|
|
|
135
146
|
|
|
136
147
|
push(path);
|
|
137
148
|
},
|
|
149
|
+
'ContinueStatement|BreakStatement'(path) {
|
|
150
|
+
if (compare(path.getPrevSibling(), LINE))
|
|
151
|
+
return;
|
|
152
|
+
|
|
153
|
+
push(path);
|
|
154
|
+
},
|
|
138
155
|
LogicalExpression(path) {
|
|
139
|
-
if (
|
|
156
|
+
if (isExclude(path.get('left')))
|
|
140
157
|
return;
|
|
141
158
|
|
|
142
159
|
push(path);
|
|
@@ -148,6 +165,9 @@ export const traverse = ({push}) => ({
|
|
|
148
165
|
push(path);
|
|
149
166
|
},
|
|
150
167
|
SequenceExpression(path) {
|
|
168
|
+
if (compare(path, `(${LINE}, __z)`))
|
|
169
|
+
return;
|
|
170
|
+
|
|
151
171
|
const expressions = path.get('expressions');
|
|
152
172
|
|
|
153
173
|
for (const expPath of expressions) {
|
|
@@ -161,7 +181,7 @@ export const traverse = ({push}) => ({
|
|
|
161
181
|
const consequentPath = path.get('consequent');
|
|
162
182
|
const alternatePath = path.get('alternate');
|
|
163
183
|
|
|
164
|
-
if (!consequentPath.isBlockStatement() && !
|
|
184
|
+
if (!consequentPath.isBlockStatement() && !isExclude(consequentPath))
|
|
165
185
|
push(consequentPath);
|
|
166
186
|
|
|
167
187
|
if (!alternatePath.node)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "escover",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
|
|
5
5
|
"description": "Coverage for EcmaScript Modules",
|
|
6
6
|
"main": "lib/escover.js",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"fix:lint": "madrun fix:lint",
|
|
28
28
|
"report": "madrun report",
|
|
29
29
|
"watcher": "madrun watcher",
|
|
30
|
+
"watch:test": "madrun watch:test",
|
|
30
31
|
"watch:lint": "madrun watch:lint",
|
|
31
32
|
"watch:tape": "madrun watch:tape",
|
|
32
33
|
"prewisdom": "madrun prewisdom"
|
|
@@ -40,6 +41,7 @@
|
|
|
40
41
|
"once": "^1.4.0",
|
|
41
42
|
"picomatch": "^2.3.1",
|
|
42
43
|
"putout": "^24.0.2",
|
|
44
|
+
"strip-ansi": "^7.0.1",
|
|
43
45
|
"table": "^6.8.0",
|
|
44
46
|
"try-catch": "^3.0.0",
|
|
45
47
|
"yargs-parser": "^21.0.0",
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
types,
|
|
3
|
-
operator,
|
|
4
|
-
} from 'putout';
|
|
5
|
-
const {SequenceExpression} = types;
|
|
6
|
-
|
|
7
|
-
const {replaceWith} = operator;
|
|
8
|
-
|
|
9
|
-
export const addMarkToThrow = (path, lineNode) => {
|
|
10
|
-
const argumentPath = path.get('argument');
|
|
11
|
-
|
|
12
|
-
return replaceWith(argumentPath, SequenceExpression([
|
|
13
|
-
lineNode.expression,
|
|
14
|
-
argumentPath.node,
|
|
15
|
-
]));
|
|
16
|
-
};
|
|
17
|
-
|