forked from graphql/graphql-js
/
check-cover.js
87 lines (75 loc) · 2.02 KB
/
check-cover.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
'use strict';
const fs = require('fs');
const path = require('path');
const {
exec,
execAsync,
rmdirRecursive,
readdirRecursive,
} = require('./utils');
rmdirRecursive('./coverage/flow');
getFullCoverage()
.then((fullCoverage) => {
fs.mkdirSync('./coverage/flow', { recursive: true });
fs.writeFileSync(
'./coverage/flow/full-coverage.json',
JSON.stringify(fullCoverage),
);
})
.catch((error) => {
console.error(error.stack);
process.exit(1);
});
async function getFullCoverage() {
const fullCoverage = {};
exec('flow start --quiet');
try {
exec('flow check', { stdio: 'inherit' });
// TODO: measure coverage for all files. ATM missing types for chai & mocha
const files = readdirRecursive('./src', { ignoreDir: /^__.*__$/ })
.filter((filepath) => filepath.endsWith('.js'))
.map((filepath) => path.join('src/', filepath));
await Promise.all(files.map(getCoverage)).then((coverages) => {
for (const coverage of coverages) {
fullCoverage[coverage.path] = coverage;
}
});
} finally {
exec('flow stop --quiet');
}
return fullCoverage;
}
async function getCoverage(filepath) {
const json = await execAsync(`flow coverage --json ${filepath}`);
const flowExpressions = JSON.parse(json).expressions;
const s = {};
const statementMap = {};
let id = 0;
for (const coveredExp of flowExpressions.covered_locs) {
s[id] = 1;
statementMap[id] = covertLocation(coveredExp);
++id;
}
for (const uncoveredExp of flowExpressions.uncovered_locs) {
s[id] = 0;
statementMap[id] = covertLocation(uncoveredExp);
++id;
}
// istanbul format, see:
// https://github.com/gotwarlost/istanbul/blob/master/coverage.json.md
return {
path: filepath,
b: {},
branchMap: {},
f: {},
fnMap: {},
s,
statementMap,
};
}
function covertLocation(flow) {
return {
start: { line: flow.start.line, column: flow.start.column - 1 },
end: { line: flow.end.line, column: flow.end.column - 1 },
};
}