coverage-map.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. Copyright 2012-2015, Yahoo Inc.
  3. Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
  4. */
  5. 'use strict';
  6. const FileCoverage = require('./file').FileCoverage;
  7. const CoverageSummary = require('./file').CoverageSummary;
  8. function loadMap(source) {
  9. const data = Object.create(null);
  10. Object.keys(source).forEach(k => {
  11. const cov = source[k];
  12. if (cov instanceof FileCoverage) {
  13. data[k] = cov;
  14. } else {
  15. data[k] = new FileCoverage(cov);
  16. }
  17. });
  18. return data;
  19. }
  20. /**
  21. * CoverageMap is a map of `FileCoverage` objects keyed by file paths.
  22. * @param {Object} [obj=undefined] obj A coverage map from which to initialize this
  23. * map's contents. This can be the raw global coverage object.
  24. * @constructor
  25. */
  26. function CoverageMap(obj) {
  27. if (!obj) {
  28. this.data = Object.create(null);
  29. } else if (obj instanceof CoverageMap) {
  30. this.data = obj.data;
  31. } else {
  32. this.data = loadMap(obj);
  33. }
  34. }
  35. /**
  36. * merges a second coverage map into this one
  37. * @param {CoverageMap} obj - a CoverageMap or its raw data. Coverage is merged
  38. * correctly for the same files and additional file coverage keys are created
  39. * as needed.
  40. */
  41. CoverageMap.prototype.merge = function(obj) {
  42. let other;
  43. if (obj instanceof CoverageMap) {
  44. other = obj;
  45. } else {
  46. other = new CoverageMap(obj);
  47. }
  48. Object.keys(other.data).forEach(k => {
  49. const fc = other.data[k];
  50. if (this.data[k]) {
  51. this.data[k].merge(fc);
  52. } else {
  53. this.data[k] = fc;
  54. }
  55. });
  56. };
  57. /**
  58. * filter the coveragemap based on the callback provided
  59. * @param {Function (filename)} callback - Returns true if the path
  60. * should be included in the coveragemap. False if it should be
  61. * removed.
  62. */
  63. CoverageMap.prototype.filter = function(callback) {
  64. Object.keys(this.data).forEach(k => {
  65. if (!callback(k)) {
  66. delete this.data[k];
  67. }
  68. });
  69. };
  70. /**
  71. * returns a JSON-serializable POJO for this coverage map
  72. * @returns {Object}
  73. */
  74. CoverageMap.prototype.toJSON = function() {
  75. return this.data;
  76. };
  77. /**
  78. * returns an array for file paths for which this map has coverage
  79. * @returns {Array{string}} - array of files
  80. */
  81. CoverageMap.prototype.files = function() {
  82. return Object.keys(this.data);
  83. };
  84. /**
  85. * returns the file coverage for the specified file.
  86. * @param {String} file
  87. * @returns {FileCoverage}
  88. */
  89. CoverageMap.prototype.fileCoverageFor = function(file) {
  90. const fc = this.data[file];
  91. if (!fc) {
  92. throw new Error('No file coverage available for: ' + file);
  93. }
  94. return fc;
  95. };
  96. /**
  97. * adds a file coverage object to this map. If the path for the object,
  98. * already exists in the map, it is merged with the existing coverage
  99. * otherwise a new key is added to the map.
  100. * @param {FileCoverage} fc the file coverage to add
  101. */
  102. CoverageMap.prototype.addFileCoverage = function(fc) {
  103. const cov = new FileCoverage(fc);
  104. const path = cov.path;
  105. if (this.data[path]) {
  106. this.data[path].merge(cov);
  107. } else {
  108. this.data[path] = cov;
  109. }
  110. };
  111. /**
  112. * returns the coverage summary for all the file coverage objects in this map.
  113. * @returns {CoverageSummary}
  114. */
  115. CoverageMap.prototype.getCoverageSummary = function() {
  116. const ret = new CoverageSummary();
  117. this.files().forEach(key => {
  118. ret.merge(this.fileCoverageFor(key).toSummary());
  119. });
  120. return ret;
  121. };
  122. module.exports = {
  123. CoverageMap
  124. };