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