Skip to content

Commit 7de2eb3

Browse files
committed
implement istanbul, based on @gotwarlost PR
1 parent a2fe981 commit 7de2eb3

5 files changed

Lines changed: 61 additions & 48 deletions

File tree

lib/child.js

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,6 @@ function _require(res, addToGlobal) {
5555
QUnit.start();
5656
}
5757

58-
/**
59-
* Calculate coverage stats using bunker
60-
*/
61-
function calcCoverage() {
62-
63-
}
64-
6558
/**
6659
* Callback for each started test.
6760
* @param {Object} test
@@ -105,9 +98,7 @@ QUnit.testDone(function(data) {
10598
* @param {Object} res
10699
*/
107100
QUnit.done(_.debounce(function(data) {
108-
if (options.coverage) {
109-
data.coverage = calcCoverage();
110-
}
101+
data.coverage = global.__coverage__;
111102

112103
process.send({
113104
event: 'done',
@@ -128,15 +119,19 @@ console.error = function(obj) {
128119
return error.apply(this, arguments);
129120
};
130121

131-
// require deps
132-
options.deps.forEach(function(dep) {
133-
_require(dep, true);
134-
});
122+
function run() {
123+
// require deps
124+
options.deps.forEach(function(dep) {
125+
_require(dep, true);
126+
});
135127

136-
// require code
137-
_require(options.code, true);
128+
// require code
129+
_require(options.code, true);
138130

139-
// require tests
140-
options.tests.forEach(function(res) {
141-
_require(res, false);
142-
});
131+
// require tests
132+
options.tests.forEach(function(res) {
133+
_require(res, false);
134+
});
135+
}
136+
137+
options.coverage ? require('./coverage').cover(options, run) : run();

lib/coverage.js

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,54 @@
1-
var fs = require('fs'),
1+
var path = require('path'),
22
util = require('util'),
3-
_ = require('underscore'),
4-
bunker;
3+
_ = require('underscore');
54

6-
try {
7-
bunker = require('bunker');
8-
} catch (err) {}
5+
var istanbul, collector;
96

10-
exports.instrument = function(path) {
11-
var src = fs.readFileSync(path, 'utf-8'),
12-
newSrc = bunker(src).compile();
7+
try { istanbul = require('istanbul'); }
8+
catch (e) {}
139

14-
fs.renameSync(src, '__' + src);
15-
fs.writeFileSync(path, newSrc, 'utf-8');
10+
exports.setup = function() {
11+
collector = new istanbul.Collector();
1612
};
1713

14+
exports.append = function(coverage) {
15+
collector && coverage && collector.add(coverage);
16+
};
1817

19-
exports.restore = function(path) {
20-
// do it only if the original file exist
21-
if (fs.statSync('__' + path).isFile()) {
22-
fs.unlinkSync(path);
23-
fs.renameSync('__' + path, path);
18+
exports.report = function() {
19+
if (collector) {
20+
var opts = { dir: path.resolve('coverage') },
21+
Report = istanbul.Report,
22+
reports = [ Report.create('lcov', opts), Report.create('json', opts), Report.create('text-summary', opts) ];
23+
reports.forEach(function (rep) {
24+
rep.writeReport(collector, true);
25+
});
2426
}
27+
};
28+
29+
function resolvePaths(files) {
30+
if (Array.isArray(files)) return files.map(function (file) {
31+
return file.path;
32+
});
33+
return [files.path];
34+
}
2535

36+
exports.cover = function(options, run) {
37+
istanbul.matcherFor({
38+
includes: resolvePaths(options.code),
39+
excludes: resolvePaths(options.tests)
40+
}, function (err, matcher) {
41+
if (err) { throw err; }
42+
var instrumenter = new istanbul.Instrumenter();
43+
istanbul.hook.hookRequire(matcher, instrumenter.instrumentSync.bind(instrumenter));
44+
run();
45+
});
2646
};
2747

28-
if (!bunker) {
48+
if (!istanbul) {
2949
_.each(exports, function(fn, name) {
3050
exports[name] = function() {
31-
util.error('Module "bunker" is not installed.'.red);
51+
util.error('Module "istanbul" is not installed.'.red);
3252
process.exit(1);
3353
};
3454
});

lib/testrunner.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ exports.run = function(files, callback) {
138138
files = [files];
139139
}
140140

141+
options.coverage && coverage.setup();
142+
141143
files.forEach(function(file) {
142144
var opts = _.extend({}, options, file);
143145

@@ -150,6 +152,7 @@ exports.run = function(files, callback) {
150152
if (err) {
151153
return callback(err, log.stats());
152154
}
155+
stat && coverage.append(stat.coverage);
153156

154157
filesCount++;
155158

@@ -158,17 +161,13 @@ exports.run = function(files, callback) {
158161
if (val && log.print[name]) {
159162
log.print[name]();
160163
}
161-
})
164+
});
162165

166+
coverage.report();
163167
callback(null, log.stats());
164168
}
165169
}
166-
167-
if (opts.coverage) {
168-
coverage.instrument(opts.code);
169-
} else {
170-
runOne(opts, done);
171-
}
170+
runOne(opts, done);
172171
});
173172
};
174173

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"timekeeper": "0.0.2"
2929
},
3030
"optionalDependencies": {
31-
"bunker": "0.1.2"
31+
"istanbul": "0.2.4"
3232
},
3333
"licenses": [
3434
{

readme.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,5 +233,4 @@ Some tests examples
233233

234234
### Coverage
235235

236-
Jscoverage is removed due to a lot of installation problems and bad api,
237-
node-bunker is planned to use but not implemented yet.
236+
Code coverage via Istanbul. To utilize, install `istanbul` and set `coverage: true`. Coverage based on code and tests passed to `node-qunit`.

0 commit comments

Comments
 (0)