Add support for include library and code-coverage #108

Closed
wants to merge 9 commits into
from
View
@@ -3,6 +3,7 @@
var path = require('path'),
fs = require('fs'),
util = require('util'),
+ childProcess = require('child_process'),
events = require('events');
//
@@ -59,6 +60,7 @@ var help = [
" --cover-plain Print plain coverage map if detected",
" --cover-html Write coverage map to \"coverage.html\"",
" --cover-json Write unified coverage map to \"coverage.json\"",
+ " --cover-emma Write unified coverage map to \"coverage.emma\"",
//" --no-color Don't use terminal colors",
" --version Show version",
" -h, --help You're staring at it"
@@ -105,6 +107,13 @@ while (arg = argv.shift()) {
options[arg] = true;
} else {
switch (arg) {
+ case 'include':
+ if (arg = argv.shift()) {
+ require.paths.unshift(arg);
+ } else {
+ throw new Error('--include requires a path');
+ }
+ break;
case 'json':
_reporter = require('../lib/vows/reporters/json');
break;
@@ -133,6 +142,10 @@ while (arg = argv.shift()) {
options.coverage = true;
_coverage = require('../lib/vows/coverage/report-json');
break;
+ case 'cover-emma':
+ options.coverage = true;
+ _coverage = require('../lib/vows/coverage/report-emma');
+ break;
case 'verbose':
case 'v':
options.verbose = true;
@@ -233,32 +246,51 @@ if (! options.watch) {
? path.join(process.cwd(), a.replace(fileExt, ''))
: a.replace(fileExt, '');
});
-
- runSuites(importSuites(files), function (results) {
- var status = results.errored ? 2 : (results.broken ? 1 : 0);
-
- !options.verbose && _reporter.print('\n');
- msg('runner', 'finish');
- _reporter.report(['finish', results], {
- write: function (str) {
- util.print(str.replace(/^\n\n/, '\n'));
- }
- });
- try {
- if (options.coverage === true && _$jscoverage !== undefined) {
- _coverage.report(_$jscoverage);
- }
- } catch (err) {
- // ignore the undefined jscoverage
- }
- if (process.stdout.write('')) { // Check if stdout is drained
- process.exit(status);
- } else {
- process.stdout.on('drain', function () {
- process.exit(status);
- });
- }
- });
+
+ var allTests = function() {
+
+ runSuites(importSuites(files), function (results) {
+ var status = results.errored ? 2 : (results.broken ? 1 : 0);
+
+ !options.verbose && _reporter.print('\n');
+ msg('runner', 'finish');
+ _reporter.report(['finish', results], {
+ write: function (str) {
+ util.print(str.replace(/^\n\n/, '\n'));
+ }
+ });
+ try {
+ if (options.coverage === true && _$jscoverage !== undefined) {
+ _coverage.report(_$jscoverage);
+ }
+ } catch (err) {
+ // ignore the undefined jscoverage
+ }
+ if (process.stdout.write('')) { // Check if stdout is drained
+ if (options.coverage === true && _$jscoverage !== undefined) {
+ _coverage.report(_$jscoverage);
+ }
+ if (process.stdout.write('')) { // Check if stdout is drained
+ process.exit(status);
+ } else {
+ process.stdout.on('drain', function () {
+ process.exit(status);
+ });
+ }
+ }
+ });
+ };
+
+
+ if (options.coverage === true ) {
+ childProcess.exec('rm -fr lib-cov && jscoverage lib lib-cov', function(err){
+ if (err) throw err;
+ require.paths.unshift('lib-cov');
+ allTests();
+ })
+ } else {
+ allTests();
+ }
} else {
//
// Watch mode
@@ -0,0 +1,147 @@
+var sys = require('sys'),
+ fs = require('fs'),
+ file = require('./file');
+
+this.name = 'coverage-report-emma';
+
+function xmlEnc(value) {
+ return !value ? value : String(value).replace(/&/g, "&")
+ .replace(/>/g, ">")
+ .replace(/</g, "&lt;")
+ .replace(/"/g, "&quot;")
+ .replace(/\u001b\[\d{1,2}m/g, '');
+}
+
+function tag(name, attribs, single, content) {
+ var strAttr = [], t, end = '>';
+ for (var attr in attribs) {
+ if (attribs.hasOwnProperty(attr)) {
+ strAttr.push(attr + '="' + xmlEnc(attribs[attr]) + '"');
+ }
+ }
+ if (single) {
+ end = ' />';
+ }
+ if (strAttr.length) {
+ t = '<' + name + ' ' + strAttr.join(' ') + end;
+ } else {
+ t = '<' + name + end;
+ }
+ if (typeof content !== 'undefined') {
+ return t + content + '</' + name + end;
+ }
+ return t;
+}
+
+function end(name) {
+ return '</' + name + '>';
+}
+
+function cdata(data) {
+ return '<![CDATA[' + xmlEnc(data) + ']]>';
+}
+
+/**
+ * coverageMap coverage info for each file
+ */
+this.report = function (coverageMap) {
+ var output = {
+ meta: {
+ "generator": "vowsjs",
+ "generated": new Date().toString(),
+ "instrumentation": "node-jscoverage",
+ "file-version": "1.0"
+ },
+ files: [ ],
+ coverage: [ ]
+ };
+
+ for (var filename in coverageMap) {
+ if (coverageMap.hasOwnProperty(filename)) {
+ // get data for the file
+ var data = file.coverage(filename, coverageMap[filename]);
+
+ var coverage = {
+ file: filename,
+ coverage: data.coverage.toFixed(2),
+ hits: data.hits,
+ misses: data.misses,
+ sloc: data.sloc,
+ source: { }
+ };
+
+ for (var i = 0; i < data.source.length; i++) {
+ coverage.source[i + 1] = {
+ line: data.source[i].line,
+ coverage: data.source[i].coverage
+ };
+ }
+
+ output.coverage.push(coverage);
+
+ output.files.push(filename);
+ }
+ }
+ var totalsloc = 0;
+ var totalhits = 0;
+ for ( var i = 0; i < output.coverage.length; i++) {
+ totalsloc += output.coverage[i].sloc;
+ totalhits += output.coverage[i].hits;
+ }
+
+ var buffer = [];
+ buffer.push(tag('report', {}, false));
+ buffer.push(tag('stats', {}, false));
+ buffer.push(tag('packages', { value: 1 }, true));
+ buffer.push(tag('classes', { value: 1 }, true));
+ buffer.push(tag('srcfiles', { value: output.files.length }, true));
+ buffer.push(tag('srclines', { value: totalsloc }, true));
+ buffer.push(end('stats'));
+
+ buffer.push(tag('data', {}, false));
+ // all
+ buffer.push(tag('all', { name : 'all classes'}, false));
+ buffer.push(tag('coverage', { type : 'class, %', value : '100% (1/1)'}, true) );
+ buffer.push(tag('coverage', { type : 'method, %', value : '100% (1/1)'}, true) );
+ buffer.push(tag('coverage', { type : 'block, %', value : '100% (1/1)'}, true) );
+ buffer.push(tag('coverage', { type : 'line, %', value : (totalhits*1.0/totalsloc * 100.0).toFixed(2) + '% ('+totalhits+'/'+totalsloc+')'}, true) );
+
+ // package
+ buffer.push(tag('package', {name: '{root}'}, false));
+ buffer.push(tag('coverage', { type : 'class, %', value : '100% (1/1)'}, true) );
+ buffer.push(tag('coverage', { type : 'method, %', value : '100% (1/1)'}, true) );
+ buffer.push(tag('coverage', { type : 'block, %', value : '100% (1/1)'}, true) );
+ buffer.push(tag('coverage', { type : 'line, %', value : (totalhits*1.0/totalsloc * 100.0).toFixed(2) + '% ('+totalhits+'/'+totalsloc+')'}, true) );
+
+ for ( var i = 0; i < output.coverage.length; i++) {
+ var sloc = output.coverage[i].sloc;
+ var hits = output.coverage[i].hits;
+ var filename = output.coverage[i].file;
+
+ buffer.push(tag('srcfile', { name : filename }, false) );
+ buffer.push(tag('coverage', { type : 'class, %', value : '100% (1/1)'}, true) );
+ buffer.push(tag('coverage', { type : 'method, %', value : '100% (1/1)'}, true) );
+ buffer.push(tag('coverage', { type : 'block, %', value : '100% (1/1)'}, true) );
+ buffer.push(tag('coverage', { type : 'line, %', value : (hits*1.0/sloc * 100.0).toFixed(2) + '% ('+hits+'/'+sloc+')'}, true) );
+ buffer.push(end('srcfile'));
+ }
+
+ buffer.push(end('package'));
+
+ buffer.push(end('all'));
+ buffer.push(end('data'));
+
+
+ buffer.push(end('report'));
+
+ buffer.unshift('<!-- EMMA v2.0.4015 (stable) report, generated '+ output.meta.generated + ' by ' + output.meta.generator + ' -->');
+
+ try {
+ out = fs.openSync("coverage.emma", "w");
+ fs.writeSync(out, buffer.join('\n'));
+ fs.close(out);
+ } catch (error) {
+ sys.print("Error: Unable to write to file coverage.emma\n");
+ return;
+ }
+};
View
@@ -1,14 +1,32 @@
{
- "name" : "vows",
- "description" : "Asynchronous BDD & continuous integration for node.js",
- "url" : "http://vowsjs.org",
- "keywords" : ["testing", "spec", "test", "BDD"],
- "author" : "Alexis Sellier <self@cloudhead.net>",
- "contributors" : [{ "name": "Charlie Robbins", "email": "charlie.robbins@gmail.com" }],
- "dependencies" : {"eyes": ">=0.1.6"},
- "main" : "./lib/vows",
- "bin" : { "vows": "./bin/vows" },
- "directories" : { "test": "./test", "bin": "./bin" },
- "version" : "0.5.11",
- "engines" : {"node": ">=0.2.6"}
+ "name": "vows",
+ "description": "Asynchronous BDD & continuous integration for node.js",
+ "url": "http://vowsjs.org",
+ "keywords": [
+ "testing",
+ "spec",
+ "test",
+ "BDD"
+ ],
+ "author": "Alexis Sellier <self@cloudhead.net>",
+ "contributors": [],
+ "dependencies": {
+ "eyes": ">=0.1.6"
+ },
+ "devDependencies": {
+ "flags": ">=0.1.0",
+ "knox": ">=0.0.9"
+ },
+ "main": "./lib/vows",
+ "bin": {
+ "vows": "./bin/vows"
+ },
+ "directories": {
+ "test": "./test",
+ "bin": "./bin"
+ },
+ "version": "0.5.9",
+ "engines": {
+ "node": ">=0.2.6"
+ }
}