-
Notifications
You must be signed in to change notification settings - Fork 11
/
index.js
112 lines (100 loc) · 2.96 KB
/
index.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
'use strict';
var resolve = require('resolve');
var through = require('through2');
var minimatch = require('minimatch');
var combine = require('stream-combiner2');
var split = require('split2');
var _ = require('lodash');
function filterFiles(options, files) {
var excludePattern = options.exclude ? [].concat(options.exclude) : [''];
return function (file) {
// If if doesnt match the pattern dont instrument it
var matchResult = _.compact(_.map(excludePattern, function (pattern) {
return minimatch(file, pattern);
}));
if (!matchResult.length) {
files[file] = true;
}
return through();
};
}
function instrument(options, files) {
var Instrumenter = require(resolve.sync(options.instrumenter, {basedir: __dirname}));
var instrumenter = new Instrumenter.Instrumenter();
var captured = false;
return through.obj(function(row, enc, next) {
if (!files[row.file]) {
this.push(row);
next();
return;
}
var self = this;
instrumenter.instrument(row.source, row.file, function(err, code) {
if (err) {
self.emit('error', err);
next();
return;
}
row.source = code;
// Inject __converage__ var
if (!captured) {
captured = true;
row.source += 'after(function(){console.log("__coverage__=\'" + JSON.stringify(__coverage__) + "\';");});';
}
self.push(row);
next();
});
});
}
var report = [];
function writeReports(options) {
var Instrumenter = require(resolve.sync(options.instrumenter, {basedir: __dirname}));
var collector = new Instrumenter.Collector();
if (options.report) {
report = options.report;
delete options.report;
}
var data = '';
var coverageRe = /__coverage__='([^;]*)';/gi;
var skippedPreviousLine = false;
var extractCoverage = through(function(buf, enc, next) {
data += buf;
if (!coverageRe.test(buf.toString())) {
if (!skippedPreviousLine) this.push(buf);
skippedPreviousLine = false;
} else {
skippedPreviousLine = true;
}
next();
}, function(next) {
var re = /__coverage__='([^;]*)';(\r\n?|\n)/gi;
var match;
// capture all the matches, there might be multiple
while (match = re.exec(data)) {
// match[1] contains JSON.stringify(__coverage__)
collector.add(JSON.parse(match[1]));
}
// Add report
[].concat(report).forEach(function (reportType) {
Instrumenter.Report
.create(reportType, _.clone(options))
.writeReport(collector, true);
});
next();
});
return combine(split(/(\r?\n)/), extractCoverage);
}
module.exports = function (b, opts) {
opts = _.extend({
instrumenter: 'istanbul',
}, opts);
var reporterOptions = _.omit(opts, 'exclude');
var files = {};
function apply() {
b.pipeline.get('pack').unshift(instrument(opts, files));
b.pipeline.get('wrap').push(writeReports(reporterOptions));
}
b.transform(filterFiles(opts, files));
b.on('reset', apply);
apply();
};