123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- /**
- * Module dependencies.
- */
- var Base = require('./base');
- /**
- * Expose `JSONCov`.
- */
- exports = module.exports = JSONCov;
- /**
- * Initialize a new `JsCoverage` reporter.
- *
- * @api public
- * @param {Runner} runner
- * @param {boolean} output
- */
- function JSONCov(runner, output) {
- Base.call(this, runner);
- output = arguments.length === 1 || output;
- var self = this;
- var tests = [];
- var failures = [];
- var passes = [];
- runner.on('test end', function(test) {
- tests.push(test);
- });
- runner.on('pass', function(test) {
- passes.push(test);
- });
- runner.on('fail', function(test) {
- failures.push(test);
- });
- runner.on('end', function() {
- var cov = global._$jscoverage || {};
- var result = self.cov = map(cov);
- result.stats = self.stats;
- result.tests = tests.map(clean);
- result.failures = failures.map(clean);
- result.passes = passes.map(clean);
- if (!output) {
- return;
- }
- process.stdout.write(JSON.stringify(result, null, 2));
- });
- }
- /**
- * Map jscoverage data to a JSON structure
- * suitable for reporting.
- *
- * @api private
- * @param {Object} cov
- * @return {Object}
- */
- function map(cov) {
- var ret = {
- instrumentation: 'node-jscoverage',
- sloc: 0,
- hits: 0,
- misses: 0,
- coverage: 0,
- files: []
- };
- for (var filename in cov) {
- if (Object.prototype.hasOwnProperty.call(cov, filename)) {
- var data = coverage(filename, cov[filename]);
- ret.files.push(data);
- ret.hits += data.hits;
- ret.misses += data.misses;
- ret.sloc += data.sloc;
- }
- }
- ret.files.sort(function(a, b) {
- return a.filename.localeCompare(b.filename);
- });
- if (ret.sloc > 0) {
- ret.coverage = (ret.hits / ret.sloc) * 100;
- }
- return ret;
- }
- /**
- * Map jscoverage data for a single source file
- * to a JSON structure suitable for reporting.
- *
- * @api private
- * @param {string} filename name of the source file
- * @param {Object} data jscoverage coverage data
- * @return {Object}
- */
- function coverage(filename, data) {
- var ret = {
- filename: filename,
- coverage: 0,
- hits: 0,
- misses: 0,
- sloc: 0,
- source: {}
- };
- data.source.forEach(function(line, num) {
- num++;
- if (data[num] === 0) {
- ret.misses++;
- ret.sloc++;
- } else if (data[num] !== undefined) {
- ret.hits++;
- ret.sloc++;
- }
- ret.source[num] = {
- source: line,
- coverage: data[num] === undefined ? '' : data[num]
- };
- });
- ret.coverage = ret.hits / ret.sloc * 100;
- return ret;
- }
- /**
- * Return a plain-object representation of `test`
- * free of cyclic properties etc.
- *
- * @api private
- * @param {Object} test
- * @return {Object}
- */
- function clean(test) {
- return {
- duration: test.duration,
- currentRetry: test.currentRetry(),
- fullTitle: test.fullTitle(),
- title: test.title
- };
- }
|