Skip to content

Commit 6f2b75e

Browse files
jwbayskovhus
authored andcommitted
Map code coverage from transformers (jestjs#2290)
* source map support for coverage * be less dangerous only enforce files in src/ having @flow since everything else may not be run through babel * lazy require for istanbul-lib-source-maps * add documentation for mapCoverage config option * store source maps on disk instead of in worker process memory * add mapCoverage to CLI, switch off by default * move source map info from coverage object to jest-runtime * tweak docs, fix a test
1 parent d081850 commit 6f2b75e

28 files changed

+770
-57
lines changed

dangerfile.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ const raiseIssueAboutPaths = (
5151
};
5252

5353
const newJsFiles = danger.git.created_files.filter(path => path.endsWith('js'));
54-
const isNotInTestFiles = path => !(includes(path, '__tests__')
55-
|| includes(path, '__mocks__'));
54+
const isSourceFile = path =>
55+
includes(path, '/src/') &&
56+
!includes(path, '__tests__');
5657

5758
// New JS files should have the FB copyright header + flow
5859
const facebookLicenseHeaderComponents = [
@@ -80,7 +81,7 @@ if (noFBCopyrightFiles.length > 0) {
8081
// Ensure the majority of all files use Flow
8182
// Does not run for test files, and also offers a warning not an error.
8283
const noFlowFiles = newJsFiles
83-
.filter(isNotInTestFiles)
84+
.filter(isSourceFile)
8485
.filter(filepath => {
8586
const content = fs.readFileSync(filepath).toString();
8687
return !includes(content, '@flow');

docs/Configuration.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,23 @@ For example, the following would create a global `__DEV__` variable set to `true
150150

151151
Note that, if you specify a global reference value (like an object or array) here, and some code mutates that value in the midst of running a test, that mutation will *not* be persisted across test runs for other test files.
152152

153+
### `mapCoverage` [boolean]
154+
155+
##### available in Jest **20.0.0+**
156+
157+
Default: `false`
158+
159+
If you have [transformers](#transform-object-string-string) configured that emit source maps, Jest will use them to try and map code coverage against the original source code when writing [reports](#coveragereporters-array-string) and checking [thresholds](#coveragethreshold-object). This is done on a best-effort basis as some compile-to-JavaScript languages may provide more accurate source maps than others. This can also be resource-intensive. If Jest is taking a long time to calculate coverage at the end of a test run, try setting this option to `false`.
160+
161+
Both inline source maps and source maps returned directly from a transformer are supported. Source map URLs are not supported because Jest may not be able to locate them. To return source maps from a transformer, the `process` function can return an object like the following. The `map` property may either be the source map object, or the source map object as a JSON string.
162+
163+
```js
164+
return {
165+
code: 'the code',
166+
map: 'the source map',
167+
};
168+
```
169+
153170
### `moduleFileExtensions` [array<string>]
154171
Default: `["js", "json", "jsx", "node"]`
155172

Lines changed: 348 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,348 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`maps code coverage against original source 1`] = `
4+
Object {
5+
"covered.ts": Object {
6+
"b": Object {
7+
"0": Array [
8+
1,
9+
0,
10+
],
11+
"1": Array [
12+
1,
13+
0,
14+
],
15+
"2": Array [
16+
1,
17+
0,
18+
0,
19+
],
20+
"3": Array [
21+
1,
22+
0,
23+
],
24+
},
25+
"branchMap": Object {
26+
"0": Object {
27+
"loc": Object {
28+
"end": Object {
29+
"column": 9,
30+
"line": 5,
31+
},
32+
"start": Object {
33+
"column": 8,
34+
"line": 5,
35+
},
36+
},
37+
"locations": Array [
38+
Object {
39+
"end": Object {
40+
"column": 9,
41+
"line": 5,
42+
},
43+
"start": Object {
44+
"column": 8,
45+
"line": 5,
46+
},
47+
},
48+
Object {
49+
"end": Object {
50+
"column": 9,
51+
"line": 6,
52+
},
53+
"start": Object {
54+
"column": 8,
55+
"line": 6,
56+
},
57+
},
58+
],
59+
"type": "cond-expr",
60+
},
61+
"1": Object {
62+
"loc": Object {
63+
"end": Object {
64+
"column": 37,
65+
"line": 7,
66+
},
67+
"start": Object {
68+
"column": 36,
69+
"line": 7,
70+
},
71+
},
72+
"locations": Array [
73+
Object {
74+
"end": Object {
75+
"column": 37,
76+
"line": 7,
77+
},
78+
"start": Object {
79+
"column": 36,
80+
"line": 7,
81+
},
82+
},
83+
Object {
84+
"end": Object {
85+
"column": 41,
86+
"line": 7,
87+
},
88+
"start": Object {
89+
"column": 40,
90+
"line": 7,
91+
},
92+
},
93+
],
94+
"type": "cond-expr",
95+
},
96+
"2": Object {
97+
"loc": Object {
98+
"end": Object {
99+
"column": 33,
100+
"line": 8,
101+
},
102+
"start": Object {
103+
"column": 29,
104+
"line": 8,
105+
},
106+
},
107+
"locations": Array [
108+
Object {
109+
"end": Object {
110+
"column": 33,
111+
"line": 8,
112+
},
113+
"start": Object {
114+
"column": 29,
115+
"line": 8,
116+
},
117+
},
118+
Object {
119+
"end": Object {
120+
"column": 41,
121+
"line": 8,
122+
},
123+
"start": Object {
124+
"column": 37,
125+
"line": 8,
126+
},
127+
},
128+
Object {
129+
"end": Object {
130+
"column": 50,
131+
"line": 8,
132+
},
133+
"start": Object {
134+
"column": 45,
135+
"line": 8,
136+
},
137+
},
138+
],
139+
"type": "binary-expr",
140+
},
141+
"3": Object {
142+
"loc": Object {
143+
"end": Object {
144+
"column": 42,
145+
"line": 9,
146+
},
147+
"start": Object {
148+
"column": 32,
149+
"line": 9,
150+
},
151+
},
152+
"locations": Array [
153+
Object {
154+
"end": Object {
155+
"column": 42,
156+
"line": 9,
157+
},
158+
"start": Object {
159+
"column": 32,
160+
"line": 9,
161+
},
162+
},
163+
Object {
164+
"end": Object {
165+
"column": 55,
166+
"line": 9,
167+
},
168+
"start": Object {
169+
"column": 45,
170+
"line": 9,
171+
},
172+
},
173+
],
174+
"type": "cond-expr",
175+
},
176+
},
177+
"f": Object {
178+
"0": 1,
179+
"1": 0,
180+
"2": 0,
181+
},
182+
"fnMap": Object {
183+
"0": Object {
184+
"decl": Object {
185+
"end": Object {
186+
"column": 28,
187+
"line": 3,
188+
},
189+
"start": Object {
190+
"column": 9,
191+
"line": 3,
192+
},
193+
},
194+
"loc": Object {
195+
"end": Object {
196+
"column": 1,
197+
"line": 12,
198+
},
199+
"start": Object {
200+
"column": 49,
201+
"line": 3,
202+
},
203+
},
204+
"name": "difference",
205+
},
206+
"1": Object {
207+
"decl": Object {
208+
"end": Object {
209+
"column": 37,
210+
"line": 9,
211+
},
212+
"start": Object {
213+
"column": 32,
214+
"line": 9,
215+
},
216+
},
217+
"loc": Object {
218+
"end": Object {
219+
"column": 42,
220+
"line": 9,
221+
},
222+
"start": Object {
223+
"column": 32,
224+
"line": 9,
225+
},
226+
},
227+
"name": "(anonymous_1)",
228+
},
229+
"2": Object {
230+
"decl": Object {
231+
"end": Object {
232+
"column": 50,
233+
"line": 9,
234+
},
235+
"start": Object {
236+
"column": 45,
237+
"line": 9,
238+
},
239+
},
240+
"loc": Object {
241+
"end": Object {
242+
"column": 55,
243+
"line": 9,
244+
},
245+
"start": Object {
246+
"column": 45,
247+
"line": 9,
248+
},
249+
},
250+
"name": "(anonymous_2)",
251+
},
252+
},
253+
"path": "covered.ts",
254+
"s": Object {
255+
"0": 1,
256+
"1": 1,
257+
"2": 1,
258+
"3": 1,
259+
"4": 1,
260+
"5": 0,
261+
"6": 0,
262+
"7": 1,
263+
},
264+
"statementMap": Object {
265+
"0": Object {
266+
"end": Object {
267+
"column": 1,
268+
"line": 12,
269+
},
270+
"start": Object {
271+
"column": 0,
272+
"line": 3,
273+
},
274+
},
275+
"1": Object {
276+
"end": Object {
277+
"column": 9,
278+
"line": 6,
279+
},
280+
"start": Object {
281+
"column": 29,
282+
"line": 4,
283+
},
284+
},
285+
"2": Object {
286+
"end": Object {
287+
"column": 41,
288+
"line": 7,
289+
},
290+
"start": Object {
291+
"column": 29,
292+
"line": 7,
293+
},
294+
},
295+
"3": Object {
296+
"end": Object {
297+
"column": 50,
298+
"line": 8,
299+
},
300+
"start": Object {
301+
"column": 29,
302+
"line": 8,
303+
},
304+
},
305+
"4": Object {
306+
"end": Object {
307+
"column": 55,
308+
"line": 9,
309+
},
310+
"start": Object {
311+
"column": 25,
312+
"line": 9,
313+
},
314+
},
315+
"5": Object {
316+
"end": Object {
317+
"column": 42,
318+
"line": 9,
319+
},
320+
"start": Object {
321+
"column": 38,
322+
"line": 9,
323+
},
324+
},
325+
"6": Object {
326+
"end": Object {
327+
"column": 55,
328+
"line": 9,
329+
},
330+
"start": Object {
331+
"column": 51,
332+
"line": 9,
333+
},
334+
},
335+
"7": Object {
336+
"end": Object {
337+
"column": 17,
338+
"line": 11,
339+
},
340+
"start": Object {
341+
"column": 4,
342+
"line": 11,
343+
},
344+
},
345+
},
346+
},
347+
}
348+
`;

0 commit comments

Comments
 (0)