all files / src/ CoverageTransformer.js

100% Statements 55/55
100% Branches 14/14
100% Functions 9/9
100% Lines 52/52
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105                   15× 15× 26× 15×     15× 15×     14× 14×   14×             12× 107× 107×   107×   107× 50×       12× 79× 79×   79×   79× 56×       12× 370× 370×   370×   370× 276×         13× 13×   15×     14× 14×       13× 13×   13×   13× 14×   14× 14×       13×   13×        
const path = require('path');
const minimatch = require('minimatch');
 
const { Collector } = require('istanbul');
 
const { SparceCoverageCollector } = require('./SparceCoverageCollector');
 
const remapFunction = require('./remapFunction');
const remapBranch = require('./remapBranch');
 
const { MappingProvider } = require('./MappingProvider');
 
class CoverageTransformer {
  constructor(options) {
    this.warn = options.warn || console.warn;
    this.exclude = () => false;
    if (options.exclude) {
      this.exclude = (fileName) => minimatch(fileName, options.exclude);
    }
 
    this.sparceCoverageCollector = new SparceCoverageCollector();
    this.mappingProvider = new MappingProvider(options, this.sparceCoverageCollector);
  }
 
  addFileCoverage(filePath, fileCoverage) {
    const getMappingResolved = this.mappingProvider.getMappingResolver(filePath, fileCoverage.code);
 
    if (!getMappingResolved) {
      /* We couldn't find a source map, so will copy coverage after warning. */
      this.warn(new Error(`Could not find source map for: "${filePath}"`));
      this.sparceCoverageCollector.setCoverage(
        path.resolve(process.cwd(), filePath),
        fileCoverage
      );
      return;
    }
 
    Object.keys(fileCoverage.branchMap).forEach((index) => {
      const genItem = fileCoverage.branchMap[index];
      const hits = fileCoverage.b[index];
 
      const info = remapBranch(genItem, getMappingResolved);
 
      if (info) {
        this.sparceCoverageCollector.updateBranch(info.source, info.srcItem, hits);
      }
    });
 
    Object.keys(fileCoverage.fnMap).forEach((index) => {
      const genItem = fileCoverage.fnMap[index];
      const hits = fileCoverage.f[index];
 
      const info = remapFunction(genItem, getMappingResolved);
 
      if (info) {
        this.sparceCoverageCollector.updateFunction(info.source, info.srcItem, hits);
      }
    });
 
    Object.keys(fileCoverage.statementMap).forEach((index) => {
      const genItem = fileCoverage.statementMap[index];
      const hits = fileCoverage.s[index];
 
      const mapping = getMappingResolved(genItem);
 
      if (mapping) {
        this.sparceCoverageCollector.updateStatement(mapping.source, mapping.loc, hits);
      }
    });
  }
 
  addCoverage(item) {
    Object.keys(item)
      .forEach((filePath) => {
        if (this.exclude(filePath)) {
          this.warn(`Excluding: "${filePath}"`);
          return;
        }
 
        const fileCoverage = item[filePath];
        this.addFileCoverage(filePath, fileCoverage);
      });
  }
 
  getFinalCoverage() {
    const collector = new Collector();
 
    const srcCoverage = this.sparceCoverageCollector.getFinalCoverage();
 
    collector.add(Object.keys(srcCoverage)
      .filter((filePath) => !this.exclude(filePath))
      .reduce((obj, name) => {
        obj[name] = srcCoverage[name];
        return obj;
      }, {}));
 
    /* refreshes the line counts for reports */
    collector.getFinalCoverage();
 
    return collector;
  }
}
 
module.exports.CoverageTransformer = CoverageTransformer;