|
|
/* Copyright 2015, Yahoo Inc. Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. */ 'use strict';
const debug = require('debug')('istanbuljs'); const libCoverage = require('istanbul-lib-coverage'); const { MappedCoverage } = require('./mapped'); const getMapping = require('./get-mapping'); const { getUniqueKey, getOutput } = require('./transform-utils');
class SourceMapTransformer { constructor(finder, opts = {}) { this.finder = finder; this.baseDir = opts.baseDir || process.cwd(); }
processFile(fc, sourceMap, coverageMapper) { let changes = 0;
Object.entries(fc.statementMap).forEach(([s, loc]) => { const hits = fc.s[s]; const mapping = getMapping(sourceMap, loc, fc.path);
if (mapping) { changes += 1; const mappedCoverage = coverageMapper(mapping.source); mappedCoverage.addStatement(mapping.loc, hits); } });
Object.entries(fc.fnMap).forEach(([f, fnMeta]) => { const hits = fc.f[f]; const mapping = getMapping(sourceMap, fnMeta.decl, fc.path); const spanMapping = getMapping(sourceMap, fnMeta.loc, fc.path);
if ( mapping && spanMapping && mapping.source === spanMapping.source ) { changes += 1; const mappedCoverage = coverageMapper(mapping.source); mappedCoverage.addFunction( fnMeta.name, mapping.loc, spanMapping.loc, hits ); } });
Object.entries(fc.branchMap).forEach(([b, branchMeta]) => { const hits = fc.b[b]; const locs = []; const mappedHits = []; let source; let skip;
branchMeta.locations.forEach((loc, i) => { const mapping = getMapping(sourceMap, loc, fc.path); if (mapping) { if (!source) { source = mapping.source; }
if (mapping.source !== source) { skip = true; }
locs.push(mapping.loc); mappedHits.push(hits[i]); } });
if (!skip && locs.length > 0) { changes += 1; const mappedCoverage = coverageMapper(source); mappedCoverage.addBranch( branchMeta.type, locs[0] /* XXX */, locs, mappedHits ); } });
return changes > 0; }
async transform(coverageMap) { const uniqueFiles = {}; const getMappedCoverage = file => { const key = getUniqueKey(file); if (!uniqueFiles[key]) { uniqueFiles[key] = { file, mappedCoverage: new MappedCoverage(file) }; }
return uniqueFiles[key].mappedCoverage; };
for (const file of coverageMap.files()) { const fc = coverageMap.fileCoverageFor(file); const sourceMap = await this.finder(file, fc);
if (sourceMap) { const changed = this.processFile( fc, sourceMap, getMappedCoverage ); if (!changed) { debug(`File [${file}] ignored, nothing could be mapped`); } } else { uniqueFiles[getUniqueKey(file)] = { file, mappedCoverage: new MappedCoverage(fc) }; } }
return libCoverage.createCoverageMap(getOutput(uniqueFiles)); } }
module.exports = { SourceMapTransformer };
|