UNPKG

orionsoft-react-scripts

Version:

Orionsoft Configuration and scripts for Create React App.

228 lines (203 loc) 7.76 kB
var path = require('path'), util = require('util'), Report = require('./index'), FileWriter = require('../util/file-writer'), TreeSummarizer = require('../util/tree-summarizer'), utils = require('../object-utils'); /** * a `Report` implementation that produces a clover-style XML file. * * Usage * ----- * * var report = require('istanbul').Report.create('clover'); * * @class CloverReport * @module report * @extends Report * @constructor * @param {Object} opts optional * @param {String} [opts.dir] the directory in which to the clover.xml will be written * @param {String} [opts.file] the file name, defaulted to config attribute or 'clover.xml' */ function CloverReport(opts) { Report.call(this); opts = opts || {}; this.projectRoot = process.cwd(); this.dir = opts.dir || this.projectRoot; this.file = opts.file || this.getDefaultConfig().file; this.opts = opts; } CloverReport.TYPE = 'clover'; util.inherits(CloverReport, Report); 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) { fileCoverage = utils.incrementIgnoredTotals(fileCoverage); var metrics = node.metrics, branchByLine = branchCoverageByLine(fileCoverage), fnMap, lines; writer.println('\t\t\t<file' + attr('name', asClassName(node)) + attr('path', node.fullPath()) + '>'); writer.println('\t\t\t\t<metrics' + attr('statements', metrics.lines.total) + attr('coveredstatements', metrics.lines.covered) + attr('conditionals', metrics.branches.total) + attr('coveredconditionals', metrics.branches.covered) + attr('methods', metrics.functions.total) + attr('coveredmethods', metrics.functions.covered) + '/>'); fnMap = fileCoverage.fnMap; lines = fileCoverage.l; Object.keys(lines).forEach(function (k) { var str = '\t\t\t\t<line' + attr('num', k) + attr('count', lines[k]), branchDetail = branchByLine[k]; if (!branchDetail) { str += ' type="stmt" '; } else { str += ' type="cond" ' + attr('truecount', branchDetail.covered) + attr('falsecount', (branchDetail.total - branchDetail.covered)); } writer.println(str + '/>'); }); writer.println('\t\t\t</file>'); } function walk(node, collector, writer, level, projectRoot) { var metrics, totalFiles = 0, totalPackages = 0, totalLines = 0, tempLines = 0; if (level === 0) { metrics = node.metrics; writer.println('<?xml version="1.0" encoding="UTF-8"?>'); writer.println('<coverage' + attr('generated', Date.now()) + 'clover="3.2.0">'); writer.println('\t<project' + attr('timestamp', Date.now()) + attr('name', 'All Files') + '>'); node.children.filter(function (child) { return child.kind === 'dir'; }). forEach(function (child) { totalPackages += 1; child.children.filter(function (child) { return child.kind !== 'dir'; }). forEach(function (child) { Object.keys(collector.fileCoverageFor(child.fullPath()).l).forEach(function (k){ tempLines = k; }); totalLines += Number(tempLines); totalFiles += 1; }); }); writer.println('\t\t<metrics' + attr('statements', metrics.lines.total) + attr('coveredstatements', metrics.lines.covered) + attr('conditionals', metrics.branches.total) + attr('coveredconditionals', metrics.branches.covered) + attr('methods', metrics.functions.total) + attr('coveredmethods', metrics.functions.covered) + attr('elements', metrics.lines.total + metrics.branches.total + metrics.functions.total) + attr('coveredelements', metrics.lines.covered + metrics.branches.covered + metrics.functions.covered) + attr('complexity', 0) + attr('packages', totalPackages) + attr('files', totalFiles) + attr('classes', totalFiles) + attr('loc', totalLines) + attr('ncloc', totalLines) + '/>'); } if (node.packageMetrics) { metrics = node.packageMetrics; writer.println('\t\t<package' + attr('name', asJavaPackage(node)) + '>'); writer.println('\t\t\t<metrics' + attr('statements', metrics.lines.total) + attr('coveredstatements', metrics.lines.covered) + attr('conditionals', metrics.branches.total) + attr('coveredconditionals', metrics.branches.covered) + attr('methods', metrics.functions.total) + attr('coveredmethods', metrics.functions.covered) + '/>'); node.children.filter(function (child) { return child.kind !== 'dir'; }). forEach(function (child) { addClassStats(child, collector.fileCoverageFor(child.fullPath()), writer); }); writer.println('\t\t</package>'); } node.children.filter(function (child) { return child.kind === 'dir'; }). forEach(function (child) { walk(child, collector, writer, level + 1, projectRoot); }); if (level === 0) { writer.println('\t</project>'); writer.println('</coverage>'); } } Report.mix(CloverReport, { synopsis: function () { return 'XML coverage report that can be consumed by the clover tool'; }, getDefaultConfig: function () { return { file: 'clover.xml' }; }, 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, that = this, tree, root; collector.files().forEach(function (key) { summarizer.addFileCoverageSummary(key, utils.summarizeFileCoverage(collector.fileCoverageFor(key))); }); tree = summarizer.getTreeSummary(); root = tree.root; writer.on('done', function () { that.emit('done'); }); writer.writeFile(outputFile, function (contentWriter) { walk(root, collector, contentWriter, 0, projectRoot); writer.done(); }); } }); module.exports = CloverReport;