Permalink
Browse files

Merge branch 'cov'

  • Loading branch information...
2 parents 62c5653 + ace791f commit 725d8c849e2de3da7667ef6aa087553b32660e37 @isaacs isaacs committed Dec 6, 2011
View
@@ -1 +1,3 @@
-node_modules/*
+node_modules/
+coverage/
+coverage-example/coverage/
View
@@ -44,7 +44,7 @@ For extra special bonus points, you can do something like this:
t.end() // but it must match the plan!
})
-Node-tap is actually a collection of several packages, any of which may be
+Node-tap is actually a collection of several modules, any of which may be
mixed and matched however you please.
If you don't like this test framework, and think you can do much much
@@ -53,8 +53,6 @@ however, at least to output TAP-compliant results when `process.env.TAP`
is set, then the data coming out of your framework will be much more
consumable by machines.
-That matters. Or rather, it will, very soon.
-
You can also use this to build programs that *consume* the TAP data, so
this is very useful for CI systems and such.
@@ -74,5 +72,11 @@ this is very useful for CI systems and such.
* tap-global-harness: A default harness that provides the top-level
support for running TAP tests.
-More docs coming soon, hopefully.
+## Experimental Code Coverage with runforcover & bunker:
+
+```
+TAP_COV=1 tap ./tests [--cover=./lib,foo.js] [--cover-dir=./coverage]
+```
+This feature is experimental, and will most likely change somewhat
+before being finalized. Feedback welcome.
View
@@ -12,7 +12,7 @@ if (process.env.TAP || process.env.TAP_DIAG) {
r.on("file", function (file, results, details) {
var s = (details.ok ? "" : "not ") + "ok "+results.name
, n = details.pass + "/" + details.testsTotal
- , dots = new Array(Math.max(1, 40 - s.length - n.length)).join(".")
+ , dots = new Array(Math.max(1, 60 - s.length - n.length)).join(".")
console.log("%s %s %s", s, dots, n)
if (details.ok) {
if (details.skip) {
@@ -29,9 +29,13 @@ if (process.env.TAP || process.env.TAP_DIAG) {
//console.log(r)
var s = "total"
, n = r.results.pass + "/" + r.results.testsTotal
- , dots = new Array(40 - s.length - n.length).join(".")
+ , dots = new Array(60 - s.length - n.length).join(".")
, ok = r.results.ok ? "ok" : "not ok"
console.log("%s %s %s\n\n%s", s, dots, n, ok)
+ if (r.doCoverage) {
+ console.error( "\nCoverage: %s\n"
+ , path.resolve(r.coverageOutDir, "index.html") )
+ }
// process.stdout.flush()
})
}
@@ -0,0 +1,15 @@
+var Bar = module.exports = function(str) {
+ this.bar = str;
+ this.str = str;
+};
+
+Bar.prototype.foo = function() {
+ var self = this;
+ return self.bar;
+};
+
+Bar.prototype.baz = function() {
+ var self = this;
+ return self.str;
+};
+
@@ -0,0 +1,15 @@
+var Foo = module.exports = function(str) {
+ this.foo = str;
+ this.str = str;
+};
+
+Foo.prototype.bar = function() {
+ var self = this;
+ return self.foo;
+};
+
+Foo.prototype.baz = function() {
+ var self = this;
+ return self.str;
+};
+

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -0,0 +1,20 @@
+var test = require('tap').test,
+ Bar = require('../lib/bar'),
+ bar;
+
+test('setup', function(t) {
+ bar = new Bar('baz');
+ t.ok(bar);
+ t.end();
+});
+
+test('bar', function(t) {
+ t.equal('baz', bar.foo());
+ t.end();
+});
+
+test('teardown', function(t) {
+ t.ok(true);
+ t.end();
+});
+
@@ -0,0 +1,29 @@
+var test = require('tap').test,
+ Foo = require('../lib/foo'),
+ Bar = require('../lib/bar'),
+ foo, bar;
+
+test('setup', function(t) {
+ foo = new Foo('baz');
+ t.ok(foo);
+ bar = new Bar('baz');
+ t.ok(bar);
+ t.end();
+});
+
+test('baz from Foo', function(t) {
+ t.equal('baz', foo.baz());
+ t.end();
+});
+
+test('baz from Bar', function(t) {
+ t.equal('baz', bar.baz());
+ t.end();
+});
+
+
+test('teardown', function(t) {
+ t.ok(true);
+ t.end();
+});
+
@@ -0,0 +1,20 @@
+var test = require('tap').test,
+ Foo = require('../lib/foo'),
+ foo;
+
+test('setup', function(t) {
+ foo = new Foo('baz');
+ t.ok(foo);
+ t.end();
+});
+
+test('bar', function(t) {
+ t.equal('baz', foo.bar());
+ t.end();
+});
+
+test('teardown', function(t) {
+ t.ok(true);
+ t.end();
+});
+
View
@@ -0,0 +1,78 @@
+var fs = require('fs'),
+ path = require('path'),
+ asyncMap = require("slide").asyncMap,
+ util = require('util');
+
+var CovHtml = module.exports = function(cov_stats, cov_dir, cb) {
+ var index = [];
+
+ asyncMap(
+ Object.keys(cov_stats),
+ function(f, cb) {
+ var st = cov_stats[f],
+ missing_lines = st.missing.map(function(l) {
+ return l.number;
+ }),
+ out = '<!doctype html>\n<html lang="en">\n<head>\n ' +
+ '<meta charset="utf-8">\n <title>' +
+
+ f + ' (' + st.loc + ')</title>\n' +
+ '<style type="text/css">\n' +
+ 'li {\n' +
+ ' font-family: monospace;\n' +
+ ' white-space: pre;\n' +
+ '}\n' +
+ '</style>\n' +
+ '</head>\n<body>\n' +
+ '<h1>' + f + ' (' + st.loc + ')' + '</h1>' +
+ '<h2>Run: ' + (st.missing.length ? st.loc - st.missing.length : st.loc) + ', Missing: ' +
+ st.missing.length + ', Percentage: ' + st.percentage + '</h2>' +
+ '<h2>Source:</h2>\n' +
+ '<ol>\n' +
+ st.lines.map(function(line) {
+ var number = line.number,
+ color = (missing_lines.indexOf(number) !== -1) ? '#fcc' : '#cfc';
+ return '<li id="L' + line.number + '" style="background-color: ' + color +
+ ';">' + line.source.replace(/</g, "&lt;") + '</li>';
+ }).join('\n') +
+ '</ol>\n' +
+ '<h2>Data</h2>\n'+
+ '<pre>' + util.inspect(st, true, Infinity, false).replace(/</g, "&lt;") + '</pre></body>\n</html>';
+
+ fs.writeFile(
+ cov_dir + '/' +
+ f.replace(process.cwd() + '/', '').replace(/\//g, '+') + '.html',
+ out,
+ 'utf8',
+ function(err) {
+ if (err) {
+ throw err;
+ }
+ index.push(f);
+ cb();
+ });
+ },
+ function(err) {
+ if (err) {
+ throw err;
+ }
+ var out = '<!doctype html>\n<html lang="en">\n<head>\n ' +
+ '<meta charset="utf-8">\n <title>Coverage Index</title>\n</head>\n' +
+ '<body>\n<h1>Code Coverage Information</h1>\n<ul>' +
+ index.map(function(fname) {
+ return '<li><a href="' +
+ fname.replace(process.cwd() + '/', '').replace(/\//g, '+') + '.html' +
+ '">' + fname + '</a></li>';
+ }).join('\n') + '</ul>\n</body>\n</html>';
+
+ fs.writeFile(cov_dir + '/index.html', out, 'utf8', function(err) {
+ if (err) {
+ throw err;
+ }
+ cb();
+ });
+ }
+ );
+};
+
+
View
@@ -88,11 +88,18 @@ Harness.prototype.process = function () {
//console.error("_plan", this._plan, this.constructor.name)
} else {
//console.error("Harness process: no more left. ending")
- this.end()
+ if (this._endNice) {
+ this._endNice()
+ } else {
+ this.end()
+ }
}
}
Harness.prototype.end = function () {
+ if (this._children.length) {
+ return this.process()
+ }
//console.error("harness end", this.constructor.name)
if (this._bailedOut) return
Oops, something went wrong.

0 comments on commit 725d8c8

Please sign in to comment.