/* Copyright (c) 2012, Yahoo! Inc. All rights reserved. Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. */ var path = require('path'), Report = require('./index'), FileWriter = require('../util/file-writer'), TreeSummarizer = require('../util/tree-summarizer'), utils = require('../object-utils'); /** * a `Report` implementation that produces a cobertura-style XML file that conforms to the * http://cobertura.sourceforge.net/xml/coverage-04.dtd DTD. * * Usage * ----- * * var report = require('istanbul').Report.create('cobertura'); * * @class CoberturaReport * @extends Report * @constructor * @param {Object} opts optional * @param {String} [opts.dir] the directory in which to the cobertura-coverage.xml will be written */ function CoberturaReport(opts) { Report.call(this); opts = opts || {}; this.projectRoot = process.cwd(); this.dir = opts.dir || this.projectRoot; this.file = opts.file || 'cobertura-coverage.xml'; this.opts = opts; } CoberturaReport.TYPE = 'cobertura'; function asJavaPackage(node) { return node.displayShortName(). replace(/\//g, '.'). replace(/\\/g, '.'). replace(/\.$/, ''); } function asClassName(node) { /*jslint regexp: true */ return node.fullPath().replace(/.*[\\\/]/, ''); } function quote(thing) { return '"' + thing + '"'; } function attr(n, v) { return ' ' + n + '=' + quote(v) + ' '; } function branchCoverageByLine(fileCoverage) { var branchMap = fileCoverage.branchMap, branches = fileCoverage.b, ret = {}; Object.keys(branchMap).forEach(function (k) { var line = branchMap[k].line, branchData = branches[k]; ret[line] = ret[line] || []; ret[line].push.apply(ret[line], branchData); }); Object.keys(ret).forEach(function (k) { var dataArray = ret[k], covered = dataArray.filter(function (item) { return item > 0; }), coverage = covered.length / dataArray.length * 100; ret[k] = { covered: covered.length, total: dataArray.length, coverage: coverage }; }); return ret; } function addClassStats(node, fileCoverage, writer, projectRoot) { var metrics = node.metrics, branchByLine = branchCoverageByLine(fileCoverage), fnMap, lines; writer.println('\t\t'); writer.println('\t\t'); fnMap = fileCoverage.fnMap; Object.keys(fnMap).forEach(function (k) { var name = fnMap[k].name, hits = fileCoverage.f[k]; writer.println( '\t\t\t' ); //Add the function definition line and hits so that jenkins cobertura plugin records method hits writer.println( '\t\t\t\t' + '' + '' ); writer.println('\t\t\t'); }); writer.println('\t\t'); writer.println('\t\t'); lines = fileCoverage.l; Object.keys(lines).forEach(function (k) { var str = '\t\t\t'); }); writer.println('\t\t'); writer.println('\t\t'); } function walk(node, collector, writer, level, projectRoot) { var metrics; if (level === 0) { metrics = node.metrics; writer.println(''); writer.println(''); writer.println(''); writer.println(''); writer.println('\t' + projectRoot + ''); writer.println(''); writer.println(''); } if (node.packageMetrics) { metrics = node.packageMetrics; writer.println('\t'); writer.println('\t'); node.children.filter(function (child) { return child.kind !== 'dir'; }). forEach(function (child) { addClassStats(child, collector.fileCoverageFor(child.fullPath()), writer, projectRoot); }); writer.println('\t'); writer.println('\t'); } node.children.filter(function (child) { return child.kind === 'dir'; }). forEach(function (child) { walk(child, collector, writer, level + 1, projectRoot); }); if (level === 0) { writer.println(''); writer.println(''); } } Report.mix(CoberturaReport, { writeReport: function (collector, sync) { var summarizer = new TreeSummarizer(), outputFile = path.join(this.dir, this.file), writer = this.opts.writer || new FileWriter(sync), projectRoot = this.projectRoot, tree, root; collector.files().forEach(function (key) { summarizer.addFileCoverageSummary(key, utils.summarizeFileCoverage(collector.fileCoverageFor(key))); }); tree = summarizer.getTreeSummary(); root = tree.root; writer.writeFile(outputFile, function (contentWriter) { walk(root, collector, contentWriter, 0, projectRoot); }); } }); module.exports = CoberturaReport;