Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / istanbul / lib / util / tree-summarizer.js
1 /*
2  Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
3  Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
4  */
5
6 var path = require('path'),
7     SEP = path.sep || '/',
8     utils = require('../object-utils');
9
10 function commonArrayPrefix(first, second) {
11     var len = first.length < second.length ? first.length : second.length,
12         i,
13         ret = [];
14     for (i = 0; i < len; i += 1) {
15         if (first[i] === second[i]) {
16             ret.push(first[i]);
17         } else {
18             break;
19         }
20     }
21     return ret;
22 }
23
24 function findCommonArrayPrefix(args) {
25     if (args.length === 0) {
26         return [];
27     }
28
29     var separated = args.map(function (arg) { return arg.split(SEP); }),
30         ret = separated.pop();
31
32     if (separated.length === 0) {
33         return ret.slice(0, ret.length - 1);
34     } else {
35         return separated.reduce(commonArrayPrefix, ret);
36     }
37 }
38
39 function Node(fullName, kind, metrics) {
40     this.name = fullName;
41     this.fullName = fullName;
42     this.kind = kind;
43     this.metrics = metrics || null;
44     this.parent = null;
45     this.children = [];
46 }
47
48 Node.prototype = {
49     displayShortName: function () {
50         return this.relativeName;
51     },
52     fullPath: function () {
53         return this.fullName;
54     },
55     addChild: function (child) {
56         this.children.push(child);
57         child.parent = this;
58     },
59     toJSON: function () {
60         return {
61             name: this.name,
62             relativeName: this.relativeName,
63             fullName: this.fullName,
64             kind: this.kind,
65             metrics: this.metrics,
66             parent: this.parent === null ? null : this.parent.name,
67             children: this.children.map(function (node) { return node.toJSON(); })
68         };
69     }
70 };
71
72 function TreeSummary(summaryMap, commonPrefix) {
73     this.prefix = commonPrefix;
74     this.convertToTree(summaryMap, commonPrefix);
75 }
76
77 TreeSummary.prototype = {
78     getNode: function (shortName) {
79         return this.map[shortName];
80     },
81     convertToTree: function (summaryMap, arrayPrefix) {
82         var nodes = [],
83             rootPath = arrayPrefix.join(SEP) + SEP,
84             root = new Node(rootPath, 'dir'),
85             tmp,
86             tmpChildren,
87             seen = {},
88             filesUnderRoot = false;
89
90         seen[rootPath] = root;
91         Object.keys(summaryMap).forEach(function (key) {
92             var metrics = summaryMap[key],
93                 node,
94                 parentPath,
95                 parent;
96             node = new Node(key, 'file', metrics);
97             seen[key] = node;
98             nodes.push(node);
99             parentPath = path.dirname(key) + SEP;
100             if (parentPath === SEP + SEP || parentPath === '.' + SEP) {
101                 parentPath = SEP + '__root__' + SEP;
102             }
103             parent = seen[parentPath];
104             if (!parent) {
105                 parent = new Node(parentPath, 'dir');
106                 root.addChild(parent);
107                 seen[parentPath] = parent;
108             }
109             parent.addChild(node);
110             if (parent === root) { filesUnderRoot = true; }
111         });
112
113         if (filesUnderRoot && arrayPrefix.length > 0) {
114             arrayPrefix.pop(); //start at one level above
115             tmp = root;
116             tmpChildren = tmp.children;
117             tmp.children = [];
118             root = new Node(arrayPrefix.join(SEP) + SEP, 'dir');
119             root.addChild(tmp);
120             tmpChildren.forEach(function (child) {
121                 if (child.kind === 'dir') {
122                     root.addChild(child);
123                 } else {
124                     tmp.addChild(child);
125                 }
126             });
127         }
128         this.fixupNodes(root, arrayPrefix.join(SEP) + SEP);
129         this.calculateMetrics(root);
130         this.root = root;
131         this.map = {};
132         this.indexAndSortTree(root, this.map);
133     },
134
135     fixupNodes: function (node, prefix, parent) {
136         var that = this;
137         if (node.name.indexOf(prefix) === 0) {
138             node.name = node.name.substring(prefix.length);
139         }
140         if (node.name.charAt(0) === SEP) {
141             node.name = node.name.substring(1);
142         }
143         if (parent) {
144             if (parent.name !== '__root__' + SEP) {
145                 node.relativeName = node.name.substring(parent.name.length);
146             } else {
147                 node.relativeName = node.name;
148             }
149         } else {
150             node.relativeName = node.name.substring(prefix.length);
151         }
152         node.children.forEach(function (child) {
153             that.fixupNodes(child, prefix, node);
154         });
155     },
156     calculateMetrics: function (entry) {
157         var that = this,
158             fileChildren;
159         if (entry.kind !== 'dir') {return; }
160         entry.children.forEach(function (child) {
161             that.calculateMetrics(child);
162         });
163         entry.metrics = utils.mergeSummaryObjects.apply(
164             null,
165             entry.children.map(function (child) { return child.metrics; })
166         );
167         // calclulate "java-style" package metrics where there is no hierarchy
168         // across packages
169         fileChildren = entry.children.filter(function (n) { return n.kind !== 'dir'; });
170         if (fileChildren.length > 0) {
171             entry.packageMetrics = utils.mergeSummaryObjects.apply(
172                 null,
173                 fileChildren.map(function (child) { return child.metrics; })
174             );
175         } else {
176             entry.packageMetrics = null;
177         }
178     },
179     indexAndSortTree: function (node, map) {
180         var that = this;
181         map[node.name] = node;
182         node.children.sort(function (a, b) {
183             a = a.relativeName;
184             b = b.relativeName;
185             return a < b ? -1 : a > b ? 1 : 0;
186         });
187         node.children.forEach(function (child) {
188             that.indexAndSortTree(child, map);
189         });
190     },
191     toJSON: function () {
192         return {
193             prefix: this.prefix,
194             root: this.root.toJSON()
195         };
196     }
197 };
198
199 function TreeSummarizer() {
200     this.summaryMap = {};
201 }
202
203 TreeSummarizer.prototype = {
204     addFileCoverageSummary: function (filePath, metrics) {
205         this.summaryMap[filePath] = metrics;
206     },
207     getTreeSummary: function () {
208         var commonArrayPrefix = findCommonArrayPrefix(Object.keys(this.summaryMap));
209         return new TreeSummary(this.summaryMap, commonArrayPrefix);
210     }
211 };
212
213 module.exports = TreeSummarizer;