Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / istanbul / lib / report / cobertura.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     util = require('util'),
8     Report = require('./index'),
9     FileWriter = require('../util/file-writer'),
10     TreeSummarizer = require('../util/tree-summarizer'),
11     utils = require('../object-utils');
12
13 /**
14  * a `Report` implementation that produces a cobertura-style XML file that conforms to the
15  * http://cobertura.sourceforge.net/xml/coverage-04.dtd DTD.
16  *
17  * Usage
18  * -----
19  *
20  *      var report = require('istanbul').Report.create('cobertura');
21  *
22  * @class CoberturaReport
23  * @module report
24  * @extends Report
25  * @constructor
26  * @param {Object} opts optional
27  * @param {String} [opts.dir] the directory in which to the cobertura-coverage.xml will be written
28  */
29 function CoberturaReport(opts) {
30     Report.call(this);
31     opts = opts || {};
32     this.projectRoot = process.cwd();
33     this.dir = opts.dir || this.projectRoot;
34     this.file = opts.file || this.getDefaultConfig().file;
35     this.opts = opts;
36 }
37
38 CoberturaReport.TYPE = 'cobertura';
39 util.inherits(CoberturaReport, Report);
40
41 function asJavaPackage(node) {
42     return node.displayShortName().
43         replace(/\//g, '.').
44         replace(/\\/g, '.').
45         replace(/\.$/, '');
46 }
47
48 function asClassName(node) {
49     /*jslint regexp: true */
50     return node.fullPath().replace(/.*[\\\/]/, '');
51 }
52
53 function quote(thing) {
54     return '"' + thing + '"';
55 }
56
57 function attr(n, v) {
58     return ' ' + n + '=' + quote(v) + ' ';
59 }
60
61 function branchCoverageByLine(fileCoverage) {
62     var branchMap = fileCoverage.branchMap,
63         branches = fileCoverage.b,
64         ret = {};
65     Object.keys(branchMap).forEach(function (k) {
66         var line = branchMap[k].line,
67             branchData = branches[k];
68         ret[line] = ret[line] || [];
69         ret[line].push.apply(ret[line], branchData);
70     });
71     Object.keys(ret).forEach(function (k) {
72         var dataArray = ret[k],
73             covered = dataArray.filter(function (item) { return item > 0; }),
74             coverage = covered.length / dataArray.length * 100;
75         ret[k] = { covered: covered.length, total: dataArray.length, coverage: coverage };
76     });
77     return ret;
78 }
79
80 function addClassStats(node, fileCoverage, writer, projectRoot) {
81     fileCoverage = utils.incrementIgnoredTotals(fileCoverage);
82
83     var metrics = node.metrics,
84         branchByLine = branchCoverageByLine(fileCoverage),
85         fnMap,
86         lines;
87
88     writer.println('\t\t<class' +
89         attr('name', asClassName(node)) +
90         attr('filename', path.relative(projectRoot, node.fullPath())) +
91         attr('line-rate', metrics.lines.pct / 100.0) +
92         attr('branch-rate', metrics.branches.pct / 100.0) +
93         '>');
94
95     writer.println('\t\t<methods>');
96     fnMap = fileCoverage.fnMap;
97     Object.keys(fnMap).forEach(function (k) {
98         var name = fnMap[k].name,
99             hits = fileCoverage.f[k];
100
101         writer.println(
102             '\t\t\t<method' +
103             attr('name', name) +
104             attr('hits', hits) +
105             attr('signature', '()V') + //fake out a no-args void return
106             '>'
107         );
108
109         //Add the function definition line and hits so that jenkins cobertura plugin records method hits
110         writer.println(
111             '\t\t\t\t<lines>' +
112              '<line' +
113             attr('number', fnMap[k].line) +
114             attr('hits', fileCoverage.f[k]) +
115             '/>' +
116             '</lines>'
117         );
118
119         writer.println('\t\t\t</method>');
120
121     });
122     writer.println('\t\t</methods>');
123
124     writer.println('\t\t<lines>');
125     lines = fileCoverage.l;
126     Object.keys(lines).forEach(function (k) {
127         var str = '\t\t\t<line' +
128             attr('number', k) +
129             attr('hits', lines[k]),
130             branchDetail = branchByLine[k];
131
132         if (!branchDetail) {
133             str += attr('branch', false);
134         } else {
135             str += attr('branch', true) +
136                 attr('condition-coverage', branchDetail.coverage +
137                     '% (' + branchDetail.covered + '/' + branchDetail.total + ')');
138         }
139         writer.println(str + '/>');
140     });
141     writer.println('\t\t</lines>');
142
143     writer.println('\t\t</class>');
144 }
145
146 function walk(node, collector, writer, level, projectRoot) {
147     var metrics;
148     if (level === 0) {
149         metrics = node.metrics;
150         writer.println('<?xml version="1.0" ?>');
151         writer.println('<!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">');
152         writer.println('<coverage' +
153             attr('lines-valid', metrics.lines.total) +
154             attr('lines-covered', metrics.lines.covered) +
155             attr('line-rate', metrics.lines.pct / 100.0) +
156             attr('branches-valid', metrics.branches.total) +
157             attr('branches-covered', metrics.branches.covered) +
158             attr('branch-rate', metrics.branches.pct / 100.0) +
159             attr('timestamp', Date.now()) +
160             'complexity="0" version="0.1">');
161         writer.println('<sources>');
162         writer.println('\t<source>' + projectRoot + '</source>');
163         writer.println('</sources>');
164         writer.println('<packages>');
165     }
166     if (node.packageMetrics) {
167         metrics = node.packageMetrics;
168         writer.println('\t<package' +
169             attr('name', asJavaPackage(node)) +
170             attr('line-rate', metrics.lines.pct / 100.0) +
171             attr('branch-rate', metrics.branches.pct / 100.0) +
172             '>');
173         writer.println('\t<classes>');
174         node.children.filter(function (child) { return child.kind !== 'dir'; }).
175             forEach(function (child) {
176                 addClassStats(child, collector.fileCoverageFor(child.fullPath()), writer, projectRoot);
177             });
178         writer.println('\t</classes>');
179         writer.println('\t</package>');
180     }
181     node.children.filter(function (child) { return child.kind === 'dir'; }).
182         forEach(function (child) {
183             walk(child, collector, writer, level + 1, projectRoot);
184         });
185
186     if (level === 0) {
187         writer.println('</packages>');
188         writer.println('</coverage>');
189     }
190 }
191
192 Report.mix(CoberturaReport, {
193     synopsis: function () {
194         return 'XML coverage report that can be consumed by the cobertura tool';
195     },
196     getDefaultConfig: function () {
197         return { file: 'cobertura-coverage.xml' };
198     },
199     writeReport: function (collector, sync) {
200         var summarizer = new TreeSummarizer(),
201             outputFile = path.join(this.dir, this.file),
202             writer = this.opts.writer || new FileWriter(sync),
203             projectRoot = this.projectRoot,
204             that = this,
205             tree,
206             root;
207
208         collector.files().forEach(function (key) {
209             summarizer.addFileCoverageSummary(key, utils.summarizeFileCoverage(collector.fileCoverageFor(key)));
210         });
211         tree = summarizer.getTreeSummary();
212         root = tree.root;
213         writer.on('done', function () { that.emit('done'); });
214         writer.writeFile(outputFile, function (contentWriter) {
215             walk(root, collector, contentWriter, 0, projectRoot);
216             writer.done();
217         });
218     }
219 });
220
221 module.exports = CoberturaReport;