diff options
Diffstat (limited to 'node_modules/istanbul-lib-report/lib/summarizer.js')
-rw-r--r-- | node_modules/istanbul-lib-report/lib/summarizer.js | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/node_modules/istanbul-lib-report/lib/summarizer.js b/node_modules/istanbul-lib-report/lib/summarizer.js new file mode 100644 index 000000000..ee353b317 --- /dev/null +++ b/node_modules/istanbul-lib-report/lib/summarizer.js @@ -0,0 +1,284 @@ +/* + Copyright 2012-2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +"use strict"; + +var Path = require('./path'), + util = require('util'), + tree = require('./tree'), + coverage = require('istanbul-lib-coverage'), + BaseNode = tree.Node, + BaseTree = tree.Tree; + +function ReportNode(path, fileCoverage) { + this.path = path; + this.parent = null; + this.fileCoverage = fileCoverage; + this.children = []; +} + +util.inherits(ReportNode, BaseNode); + +ReportNode.prototype.addChild = function (child) { + child.parent = this; + this.children.push(child); +}; + +ReportNode.prototype.asRelative = function (p) { + /* istanbul ignore if */ + if (p.substring(0,1) === '/') { + return p.substring(1); + } + return p; +}; + +ReportNode.prototype.getQualifiedName = function () { + return this.asRelative(this.path.toString()); +}; + +ReportNode.prototype.getRelativeName = function () { + var parent = this.getParent(), + myPath = this.path, + relPath, + i, + parentPath = parent ? parent.path : new Path([]); + if (parentPath.ancestorOf(myPath)) { + relPath = new Path(myPath.elements()); + for (i = 0; i < parentPath.length; i += 1) { + relPath.shift(); + } + return this.asRelative(relPath.toString()); + } + return this.asRelative(this.path.toString()); +}; + +ReportNode.prototype.getParent = function () { + return this.parent; +}; + +ReportNode.prototype.getChildren = function () { + return this.children; +}; + +ReportNode.prototype.isSummary = function () { + return !this.fileCoverage; +}; + +ReportNode.prototype.getFileCoverage = function () { + return this.fileCoverage; +}; + +ReportNode.prototype.getCoverageSummary = function (filesOnly) { + var cacheProp = 'c_' + (filesOnly ? 'files' : 'full'), + summary; + + if (this.hasOwnProperty(cacheProp)) { + return this[cacheProp]; + } + + if (!this.isSummary()) { + summary = this.getFileCoverage().toSummary(); + } else { + var count = 0; + summary = coverage.createCoverageSummary(); + this.getChildren().forEach(function (child) { + if (filesOnly && child.isSummary()) { + return; + } + count += 1; + summary.merge(child.getCoverageSummary(filesOnly)); + }); + if (count === 0 && filesOnly) { + summary = null; + } + } + this[cacheProp] = summary; + return summary; +}; + +function treeFor(root, childPrefix) { + var tree = new BaseTree(), + visitor, + maybePrefix = function (node) { + if (childPrefix && !node.isRoot()) { + node.path.unshift(childPrefix); + } + }; + tree.getRoot = function () { + return root; + }; + visitor = { + onDetail: function (node) { + maybePrefix(node); + }, + onSummary: function (node) { + maybePrefix(node); + node.children.sort(function (a, b) { + var astr = a.path.toString(), + bstr = b.path.toString(); + return astr < bstr ? -1 : astr > bstr ? 1: /* istanbul ignore next */ 0; + }); + } + }; + tree.visit(visitor); + return tree; +} + +function findCommonParent(paths) { + if (paths.length === 0) { + return new Path([]); + } + var common = paths[0], + i; + + for (i = 1; i < paths.length; i += 1) { + common = common.commonPrefixPath(paths[i]); + if (common.length === 0) { + break; + } + } + return common; +} + +function toInitialList(coverageMap) { + var ret = [], + commonParent; + coverageMap.files().forEach(function (filePath) { + var p = new Path(filePath), + coverage = coverageMap.fileCoverageFor(filePath); + ret.push({ + filePath: filePath, + path: p, + fileCoverage: coverage + }); + }); + commonParent = findCommonParent(ret.map(function (o) { return o.path.parent(); })); + if (commonParent.length > 0) { + ret.forEach(function (o) { + o.path.splice(0, commonParent.length); + }); + } + return { + list: ret, + commonParent: commonParent + }; +} + +function toDirParents(list) { + var nodeMap = {}, + parentNodeList = []; + list.forEach(function (o) { + var node = new ReportNode(o.path, o.fileCoverage), + parentPath = o.path.parent(), + parent = nodeMap[parentPath.toString()]; + + if (!parent) { + parent = new ReportNode(parentPath); + nodeMap[parentPath.toString()] = parent; + parentNodeList.push(parent); + } + parent.addChild(node); + }); + return parentNodeList; +} + +function foldIntoParents(nodeList) { + var ret = [], i, j; + + // sort by longest length first + nodeList.sort(function (a, b) { + return -1 * Path.compare(a.path , b.path); + }); + + for (i = 0; i < nodeList.length; i += 1) { + var first = nodeList[i], + inserted = false; + + for (j = i + 1; j < nodeList.length; j += 1) { + var second = nodeList[j]; + if (second.path.ancestorOf(first.path)) { + second.addChild(first); + inserted = true; + break; + } + } + + if (!inserted) { + ret.push(first); + } + } + return ret; +} + +function createRoot() { + return new ReportNode(new Path([])); +} + +function createNestedSummary(coverageMap) { + var flattened = toInitialList(coverageMap), + dirParents = toDirParents(flattened.list), + topNodes = foldIntoParents(dirParents), + root; + + if (topNodes.length === 0) { + return treeFor(new ReportNode([])); + } + + if (topNodes.length === 1) { + return treeFor(topNodes[0]); + } + + root = createRoot(); + topNodes.forEach(function (node) { + root.addChild(node); + }); + return treeFor(root); +} + +function createPackageSummary(coverageMap) { + var flattened = toInitialList(coverageMap), + dirParents = toDirParents(flattened.list), + common = flattened.commonParent, + prefix, + root; + + if (dirParents.length === 1) { + root = dirParents[0]; + } else { + root = createRoot(); + // if one of the dirs is itself the root, + // then we need to create a top-level dir + dirParents.forEach(function (dp) { + if (dp.path.length === 0) { + prefix = 'root'; + } + }); + if (prefix && common.length > 0) { + prefix = common.elements()[common.elements().length - 1]; + } + dirParents.forEach(function (node) { + root.addChild(node); + }); + } + return treeFor(root, prefix); +} + +function createFlatSummary(coverageMap) { + var flattened = toInitialList(coverageMap), + list = flattened.list, + root; + + root = createRoot(); + list.forEach(function (o) { + var node = new ReportNode(o.path, o.fileCoverage); + root.addChild(node); + }); + return treeFor(root); +} + +module.exports = { + createNestedSummary: createNestedSummary, + createPackageSummary: createPackageSummary, + createFlatSummary: createFlatSummary +}; |