index.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. Copyright 2012-2015, Yahoo Inc.
  3. Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
  4. */
  5. var path = require('path');
  6. function CoberturaReport(opts) {
  7. this.cw = null;
  8. this.xml = null;
  9. this.projectRoot = opts.projectRoot || process.cwd();
  10. this.file = opts.file || 'cobertura-coverage.xml';
  11. }
  12. function asJavaPackage(node) {
  13. return node.getRelativeName().
  14. replace(/\//g, '.').
  15. replace(/\\/g, '.').
  16. replace(/\.$/, '');
  17. }
  18. function asClassName(node) {
  19. return node.getRelativeName().replace(/.*[\\\/]/, '');
  20. }
  21. CoberturaReport.prototype.onStart = function (root, context) {
  22. this.cw = context.writer.writeFile(this.file);
  23. this.xml = context.getXMLWriter(this.cw);
  24. this.writeRootStats(root);
  25. };
  26. CoberturaReport.prototype.onEnd = function () {
  27. this.xml.closeAll();
  28. this.cw.close();
  29. };
  30. CoberturaReport.prototype.writeRootStats = function (node) {
  31. var metrics = node.getCoverageSummary();
  32. this.cw.println('<?xml version="1.0" ?>');
  33. this.cw.println('<!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">');
  34. this.xml.openTag('coverage', {
  35. 'lines-valid': metrics.lines.total,
  36. 'lines-covered': metrics.lines.covered,
  37. 'line-rate': metrics.lines.pct / 100.0,
  38. 'branches-valid': metrics.branches.total,
  39. 'branches-covered': metrics.branches.covered,
  40. 'branch-rate': metrics.branches.pct / 100.0,
  41. timestamp: Date.now().toString(),
  42. complexity: '0',
  43. version: '0.1'
  44. });
  45. this.xml.openTag('sources');
  46. this.xml.inlineTag('source', null, this.projectRoot);
  47. this.xml.closeTag('sources');
  48. this.xml.openTag('packages');
  49. };
  50. CoberturaReport.prototype.onSummary = function (node) {
  51. if (node.isRoot()) {
  52. return;
  53. }
  54. var metrics = node.getCoverageSummary(true);
  55. if (!metrics) {
  56. return;
  57. }
  58. this.xml.openTag('package', {
  59. name: asJavaPackage(node),
  60. 'line-rate': metrics.lines.pct / 100.0,
  61. 'branch-rate': metrics.branches.pct / 100.0
  62. });
  63. this.xml.openTag('classes');
  64. };
  65. CoberturaReport.prototype.onSummaryEnd = function (node) {
  66. if (node.isRoot()) {
  67. return;
  68. }
  69. this.xml.closeTag('classes');
  70. this.xml.closeTag('package');
  71. };
  72. CoberturaReport.prototype.onDetail = function (node) {
  73. var that = this,
  74. fileCoverage = node.getFileCoverage(),
  75. metrics = node.getCoverageSummary(),
  76. branchByLine = fileCoverage.getBranchCoverageByLine(),
  77. fnMap,
  78. lines;
  79. this.xml.openTag('class', {
  80. name: asClassName(node),
  81. filename: path.relative(this.projectRoot, fileCoverage.path),
  82. 'line-rate': metrics.lines.pct / 100.0,
  83. 'branch-rate': metrics.branches.pct / 100.0
  84. });
  85. this.xml.openTag('methods');
  86. fnMap = fileCoverage.fnMap;
  87. Object.keys(fnMap).forEach(function (k) {
  88. var name = fnMap[k].name,
  89. hits = fileCoverage.f[k];
  90. that.xml.openTag('method', {
  91. name: name,
  92. hits: hits,
  93. signature: '()V' //fake out a no-args void return
  94. });
  95. that.xml.openTag('lines');
  96. //Add the function definition line and hits so that jenkins cobertura plugin records method hits
  97. that.xml.inlineTag('line', {
  98. number: fnMap[k].decl.start.line,
  99. hits: hits
  100. });
  101. that.xml.closeTag('lines');
  102. that.xml.closeTag('method');
  103. });
  104. this.xml.closeTag('methods');
  105. this.xml.openTag('lines');
  106. lines = fileCoverage.getLineCoverage();
  107. Object.keys(lines).forEach(function (k) {
  108. var attrs = {
  109. number: k,
  110. hits: lines[k],
  111. branch: 'false'
  112. },
  113. branchDetail = branchByLine[k];
  114. if (branchDetail) {
  115. attrs.branch = true;
  116. attrs['condition-coverage'] = branchDetail.coverage +
  117. '% (' + branchDetail.covered + '/' + branchDetail.total + ')';
  118. }
  119. that.xml.inlineTag('line', attrs);
  120. });
  121. this.xml.closeTag('lines');
  122. this.xml.closeTag('class');
  123. };
  124. module.exports = CoberturaReport;