aboutsummaryrefslogtreecommitdiff
path: root/node_modules/istanbul-lib-report/lib/summarizer-factory.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/istanbul-lib-report/lib/summarizer-factory.js')
-rw-r--r--node_modules/istanbul-lib-report/lib/summarizer-factory.js284
1 files changed, 284 insertions, 0 deletions
diff --git a/node_modules/istanbul-lib-report/lib/summarizer-factory.js b/node_modules/istanbul-lib-report/lib/summarizer-factory.js
new file mode 100644
index 0000000..5e8acd9
--- /dev/null
+++ b/node_modules/istanbul-lib-report/lib/summarizer-factory.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';
+
+const coverage = require('istanbul-lib-coverage');
+const Path = require('./path');
+const { BaseNode, BaseTree } = require('./tree');
+
+class ReportNode extends BaseNode {
+ constructor(path, fileCoverage) {
+ super();
+
+ this.path = path;
+ this.parent = null;
+ this.fileCoverage = fileCoverage;
+ this.children = [];
+ }
+
+ static createRoot(children) {
+ const root = new ReportNode(new Path([]));
+
+ children.forEach(child => {
+ root.addChild(child);
+ });
+
+ return root;
+ }
+
+ addChild(child) {
+ child.parent = this;
+ this.children.push(child);
+ }
+
+ asRelative(p) {
+ if (p.substring(0, 1) === '/') {
+ return p.substring(1);
+ }
+ return p;
+ }
+
+ getQualifiedName() {
+ return this.asRelative(this.path.toString());
+ }
+
+ getRelativeName() {
+ const parent = this.getParent();
+ const myPath = this.path;
+ let relPath;
+ let i;
+ const 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());
+ }
+
+ getParent() {
+ return this.parent;
+ }
+
+ getChildren() {
+ return this.children;
+ }
+
+ isSummary() {
+ return !this.fileCoverage;
+ }
+
+ getFileCoverage() {
+ return this.fileCoverage;
+ }
+
+ getCoverageSummary(filesOnly) {
+ const cacheProp = `c_${filesOnly ? 'files' : 'full'}`;
+ let summary;
+
+ if (Object.prototype.hasOwnProperty.call(this, cacheProp)) {
+ return this[cacheProp];
+ }
+
+ if (!this.isSummary()) {
+ summary = this.getFileCoverage().toSummary();
+ } else {
+ let count = 0;
+ summary = coverage.createCoverageSummary();
+ this.getChildren().forEach(child => {
+ if (filesOnly && child.isSummary()) {
+ return;
+ }
+ count += 1;
+ summary.merge(child.getCoverageSummary(filesOnly));
+ });
+ if (count === 0 && filesOnly) {
+ summary = null;
+ }
+ }
+ this[cacheProp] = summary;
+ return summary;
+ }
+}
+
+class ReportTree extends BaseTree {
+ constructor(root, childPrefix) {
+ super(root);
+
+ const maybePrefix = node => {
+ if (childPrefix && !node.isRoot()) {
+ node.path.unshift(childPrefix);
+ }
+ };
+ this.visit({
+ onDetail: maybePrefix,
+ onSummary(node) {
+ maybePrefix(node);
+ node.children.sort((a, b) => {
+ const astr = a.path.toString();
+ const bstr = b.path.toString();
+ return astr < bstr
+ ? -1
+ : astr > bstr
+ ? 1
+ : /* istanbul ignore next */ 0;
+ });
+ }
+ });
+ }
+}
+
+function findCommonParent(paths) {
+ return paths.reduce(
+ (common, path) => common.commonPrefixPath(path),
+ paths[0] || new Path([])
+ );
+}
+
+function findOrCreateParent(parentPath, nodeMap, created = () => {}) {
+ let parent = nodeMap[parentPath.toString()];
+
+ if (!parent) {
+ parent = new ReportNode(parentPath);
+ nodeMap[parentPath.toString()] = parent;
+ created(parentPath, parent);
+ }
+
+ return parent;
+}
+
+function toDirParents(list) {
+ const nodeMap = Object.create(null);
+ list.forEach(o => {
+ const parent = findOrCreateParent(o.path.parent(), nodeMap);
+ parent.addChild(new ReportNode(o.path, o.fileCoverage));
+ });
+
+ return Object.values(nodeMap);
+}
+
+function addAllPaths(topPaths, nodeMap, path, node) {
+ const parent = findOrCreateParent(
+ path.parent(),
+ nodeMap,
+ (parentPath, parent) => {
+ if (parentPath.hasParent()) {
+ addAllPaths(topPaths, nodeMap, parentPath, parent);
+ } else {
+ topPaths.push(parent);
+ }
+ }
+ );
+
+ parent.addChild(node);
+}
+
+function foldIntoOneDir(node, parent) {
+ const { children } = node;
+ if (children.length === 1 && !children[0].fileCoverage) {
+ children[0].parent = parent;
+ return foldIntoOneDir(children[0], parent);
+ }
+ node.children = children.map(child => foldIntoOneDir(child, node));
+ return node;
+}
+
+function pkgSummaryPrefix(dirParents, commonParent) {
+ if (!dirParents.some(dp => dp.path.length === 0)) {
+ return;
+ }
+
+ if (commonParent.length === 0) {
+ return 'root';
+ }
+
+ return commonParent.name();
+}
+
+class SummarizerFactory {
+ constructor(coverageMap, defaultSummarizer = 'pkg') {
+ this._coverageMap = coverageMap;
+ this._defaultSummarizer = defaultSummarizer;
+ this._initialList = coverageMap.files().map(filePath => ({
+ filePath,
+ path: new Path(filePath),
+ fileCoverage: coverageMap.fileCoverageFor(filePath)
+ }));
+ this._commonParent = findCommonParent(
+ this._initialList.map(o => o.path.parent())
+ );
+ if (this._commonParent.length > 0) {
+ this._initialList.forEach(o => {
+ o.path.splice(0, this._commonParent.length);
+ });
+ }
+ }
+
+ get defaultSummarizer() {
+ return this[this._defaultSummarizer];
+ }
+
+ get flat() {
+ if (!this._flat) {
+ this._flat = new ReportTree(
+ ReportNode.createRoot(
+ this._initialList.map(
+ node => new ReportNode(node.path, node.fileCoverage)
+ )
+ )
+ );
+ }
+
+ return this._flat;
+ }
+
+ _createPkg() {
+ const dirParents = toDirParents(this._initialList);
+ if (dirParents.length === 1) {
+ return new ReportTree(dirParents[0]);
+ }
+
+ return new ReportTree(
+ ReportNode.createRoot(dirParents),
+ pkgSummaryPrefix(dirParents, this._commonParent)
+ );
+ }
+
+ get pkg() {
+ if (!this._pkg) {
+ this._pkg = this._createPkg();
+ }
+
+ return this._pkg;
+ }
+
+ _createNested() {
+ const nodeMap = Object.create(null);
+ const topPaths = [];
+ this._initialList.forEach(o => {
+ const node = new ReportNode(o.path, o.fileCoverage);
+ addAllPaths(topPaths, nodeMap, o.path, node);
+ });
+
+ const topNodes = topPaths.map(node => foldIntoOneDir(node));
+ if (topNodes.length === 1) {
+ return new ReportTree(topNodes[0]);
+ }
+
+ return new ReportTree(ReportNode.createRoot(topNodes));
+ }
+
+ get nested() {
+ if (!this._nested) {
+ this._nested = this._createNested();
+ }
+
+ return this._nested;
+ }
+}
+
+module.exports = SummarizerFactory;