Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / istanbul / lib / report / text.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     mkdirp = require('mkdirp'),
8     util = require('util'),
9     fs = require('fs'),
10     defaults = require('./common/defaults'),
11     Report = require('./index'),
12     TreeSummarizer = require('../util/tree-summarizer'),
13     utils = require('../object-utils'),
14     PCT_COLS = 9,
15     MISSING_COL = 15,
16     TAB_SIZE = 1,
17     DELIM = ' |',
18     COL_DELIM = '-|';
19
20 /**
21  * a `Report` implementation that produces text output in a detailed table.
22  *
23  * Usage
24  * -----
25  *
26  *      var report = require('istanbul').Report.create('text');
27  *
28  * @class TextReport
29  * @extends Report
30  * @module report
31  * @constructor
32  * @param {Object} opts optional
33  * @param {String} [opts.dir] the directory in which to the text coverage report will be written, when writing to a file
34  * @param {String} [opts.file] the filename for the report. When omitted, the report is written to console
35  * @param {Number} [opts.maxCols] the max column width of the report. By default, the width of the report is adjusted based on the length of the paths
36  *              to be reported.
37  */
38 function TextReport(opts) {
39     Report.call(this);
40     opts = opts || {};
41     this.dir = opts.dir || process.cwd();
42     this.file = opts.file;
43     this.summary = opts.summary;
44     this.maxCols = opts.maxCols || 0;
45     this.watermarks = opts.watermarks || defaults.watermarks();
46 }
47
48 TextReport.TYPE = 'text';
49 util.inherits(TextReport, Report);
50
51 function padding(num, ch) {
52     var str = '',
53         i;
54     ch = ch || ' ';
55     for (i = 0; i < num; i += 1) {
56         str += ch;
57     }
58     return str;
59 }
60
61 function fill(str, width, right, tabs, clazz) {
62     tabs = tabs || 0;
63     str = String(str);
64
65     var leadingSpaces = tabs * TAB_SIZE,
66         remaining = width - leadingSpaces,
67         leader = padding(leadingSpaces),
68         fmtStr = '',
69         fillStr,
70         strlen = str.length;
71
72     if (remaining > 0) {
73         if (remaining >= strlen) {
74             fillStr = padding(remaining - strlen);
75             fmtStr = right ? fillStr + str : str + fillStr;
76         } else {
77             fmtStr = str.substring(strlen - remaining);
78             fmtStr = '... ' + fmtStr.substring(4);
79         }
80     }
81
82     fmtStr = defaults.colorize(fmtStr, clazz);
83     return leader + fmtStr;
84 }
85
86 function formatName(name, maxCols, level, clazz) {
87     return fill(name, maxCols, false, level, clazz);
88 }
89
90 function formatPct(pct, clazz, width) {
91     return fill(pct, width || PCT_COLS, true, 0, clazz);
92 }
93
94 function nodeName(node) {
95     return node.displayShortName() || 'All files';
96 }
97
98 function tableHeader(maxNameCols) {
99     var elements = [];
100     elements.push(formatName('File', maxNameCols, 0));
101     elements.push(formatPct('% Stmts'));
102     elements.push(formatPct('% Branch'));
103     elements.push(formatPct('% Funcs'));
104     elements.push(formatPct('% Lines'));
105     elements.push(formatPct('Uncovered Lines', undefined, MISSING_COL));
106     return elements.join(' |') + ' |';
107 }
108
109 function collectMissingLines(kind, linesCovered) {
110   var missingLines = [];
111
112   if (kind !== 'file') {
113       return [];
114   }
115
116   Object.keys(linesCovered).forEach(function (key) {
117       if (!linesCovered[key]) {
118           missingLines.push(key);
119       }
120   });
121
122   return missingLines;
123 }
124
125 function tableRow(node, maxNameCols, level, watermarks) {
126     var name = nodeName(node),
127         statements = node.metrics.statements.pct,
128         branches = node.metrics.branches.pct,
129         functions = node.metrics.functions.pct,
130         lines = node.metrics.lines.pct,
131         missingLines = collectMissingLines(node.kind, node.metrics.linesCovered),
132         elements = [];
133
134     elements.push(formatName(name, maxNameCols, level, defaults.classFor('statements', node.metrics, watermarks)));
135     elements.push(formatPct(statements, defaults.classFor('statements', node.metrics, watermarks)));
136     elements.push(formatPct(branches, defaults.classFor('branches', node.metrics, watermarks)));
137     elements.push(formatPct(functions, defaults.classFor('functions', node.metrics, watermarks)));
138     elements.push(formatPct(lines, defaults.classFor('lines', node.metrics, watermarks)));
139     elements.push(formatPct(missingLines.join(','), 'low', MISSING_COL));
140
141     return elements.join(DELIM) + DELIM;
142 }
143
144 function findNameWidth(node, level, last) {
145     last = last || 0;
146     level = level || 0;
147     var idealWidth = TAB_SIZE * level + nodeName(node).length;
148     if (idealWidth > last) {
149         last = idealWidth;
150     }
151     node.children.forEach(function (child) {
152         last = findNameWidth(child, level + 1, last);
153     });
154     return last;
155 }
156
157 function makeLine(nameWidth) {
158     var name = padding(nameWidth, '-'),
159         pct = padding(PCT_COLS, '-'),
160         elements = [];
161
162     elements.push(name);
163     elements.push(pct);
164     elements.push(pct);
165     elements.push(pct);
166     elements.push(pct);
167     elements.push(padding(MISSING_COL, '-'));
168     return elements.join(COL_DELIM) + COL_DELIM;
169 }
170
171 function walk(node, nameWidth, array, level, watermarks) {
172     var line;
173     if (level === 0) {
174         line = makeLine(nameWidth);
175         array.push(line);
176         array.push(tableHeader(nameWidth));
177         array.push(line);
178     } else {
179         array.push(tableRow(node, nameWidth, level, watermarks));
180     }
181     node.children.forEach(function (child) {
182         walk(child, nameWidth, array, level + 1, watermarks);
183     });
184     if (level === 0) {
185         array.push(line);
186         array.push(tableRow(node, nameWidth, level, watermarks));
187         array.push(line);
188     }
189 }
190
191 Report.mix(TextReport, {
192     synopsis: function () {
193         return 'text report that prints a coverage line for every file, typically to console';
194     },
195     getDefaultConfig: function () {
196         return { file: null, maxCols: 0 };
197     },
198     writeReport: function (collector /*, sync */) {
199         var summarizer = new TreeSummarizer(),
200             tree,
201             root,
202             nameWidth,
203             statsWidth = 4 * (PCT_COLS + 2) + MISSING_COL,
204             maxRemaining,
205             strings = [],
206             text;
207
208         collector.files().forEach(function (key) {
209             summarizer.addFileCoverageSummary(key, utils.summarizeFileCoverage(
210                 collector.fileCoverageFor(key)
211             ));
212         });
213         tree = summarizer.getTreeSummary();
214         root = tree.root;
215         nameWidth = findNameWidth(root);
216         if (this.maxCols > 0) {
217             maxRemaining = this.maxCols - statsWidth - 2;
218             if (nameWidth > maxRemaining) {
219                 nameWidth = maxRemaining;
220             }
221         }
222         walk(root, nameWidth, strings, 0, this.watermarks);
223         text = strings.join('\n') + '\n';
224         if (this.file) {
225             mkdirp.sync(this.dir);
226             fs.writeFileSync(path.join(this.dir, this.file), text, 'utf8');
227         } else {
228             console.log(text);
229         }
230         this.emit('done');
231     }
232 });
233
234 module.exports = TextReport;