Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Convert to async API #489

Merged
merged 1 commit into from
Oct 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
64 changes: 30 additions & 34 deletions packages/istanbul-lib-source-maps/lib/map-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@

const path = require('path');
const fs = require('fs');
const { promisify } = require('util');
const debug = require('debug')('istanbuljs');
const SMC = require('source-map').SourceMapConsumer;
const { SourceMapConsumer } = require('source-map');
const pathutils = require('./pathutils');
const transformer = require('./transformer');
const { SourceMapTransformer } = require('./transformer');

const readFile = promisify(fs.readFile);

/**
* Tracks source maps for registered files
Expand Down Expand Up @@ -146,45 +149,41 @@ class MapStore {
});
}

async sourceFinder(filePath) {
const content = this.sourceStore.get(filePath);
if (content !== undefined) {
return content;
}

if (path.isAbsolute(filePath)) {
return await readFile(filePath, 'utf8');
}

return await readFile(
pathutils.asAbsolute(filePath, this.baseDir),
'utf8'
);
}

/**
* Transforms the coverage map provided into one that refers to original
* sources when valid mappings have been registered with this store.
* @param {CoverageMap} coverageMap - the coverage map to transform
* @returns {Object} an object with 2 properties. `map` for the transformed
* coverage map and `sourceFinder` which is a function to return the source
* text for a file.
* @returns {Promise<CoverageMap>} the transformed coverage map
*/
transformCoverage(coverageMap) {
const sourceFinder = filePath => {
const content = this.sourceStore.get(filePath);
if (content !== undefined) {
return content;
}

if (path.isAbsolute(filePath)) {
return fs.readFileSync(filePath, 'utf8');
}

return fs.readFileSync(
pathutils.asAbsolute(filePath, this.baseDir)
);
};

async transformCoverage(coverageMap) {
const hasInputSourceMaps = coverageMap
.files()
.some(
file => coverageMap.fileCoverageFor(file).data.inputSourceMap
);

if (!hasInputSourceMaps && Object.keys(this.data).length === 0) {
return {
map: coverageMap,
sourceFinder
};
return coverageMap;
}

const mappedCoverage = transformer
.create((filePath, coverage) => {
const transformer = new SourceMapTransformer(
async (filePath, coverage) => {
try {
const obj =
coverage.data.inputSourceMap ||
Expand All @@ -193,7 +192,7 @@ class MapStore {
return null;
}

const smc = new SMC(obj);
const smc = new SourceMapConsumer(obj);
smc.sources.forEach(s => {
const content = smc.sourceContentFor(s);
if (content) {
Expand All @@ -212,13 +211,10 @@ class MapStore {

return null;
}
})
.transform(coverageMap);
}
);

return {
map: mappedCoverage,
sourceFinder
};
return await transformer.transform(coverageMap);
}

/**
Expand Down
30 changes: 16 additions & 14 deletions packages/istanbul-lib-source-maps/lib/transformer.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class SourceMapTransformer {
return changes > 0;
}

transform(coverageMap) {
async transform(coverageMap) {
const uniqueFiles = {};
const getMappedCoverage = file => {
const key = getUniqueKey(file);
Expand All @@ -103,29 +103,31 @@ class SourceMapTransformer {
return uniqueFiles[key].mappedCoverage;
};

coverageMap.files().forEach(file => {
for (const file of coverageMap.files()) {
const fc = coverageMap.fileCoverageFor(file);
const sourceMap = this.finder(file, fc);
if (!sourceMap) {
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: fc
};
return;
}

const changed = this.processFile(fc, sourceMap, getMappedCoverage);
if (!changed) {
debug(`File [${file}] ignored, nothing could be mapped`);
}
});
}

return libCoverage.createCoverageMap(getOutput(uniqueFiles));
}
}

module.exports = {
create(finder, opts) {
return new SourceMapTransformer(finder, opts);
}
SourceMapTransformer
};
8 changes: 4 additions & 4 deletions packages/istanbul-lib-source-maps/test/map-store.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ const libCoverage = require('istanbul-lib-coverage');
const MapStore = require('../lib/map-store').MapStore;

describe('map store', () => {
it('applies the inputSourceMap from the coverage object if available', () => {
it('applies the inputSourceMap from the coverage object if available', async () => {
/* shint ignore:line */
const mapStore = new MapStore({});

const coverageMap = libCoverage.createCoverageMap(coverageData);

const transformed = mapStore.transformCoverage(coverageMap);
assert.isUndefined(transformed.map.data.constructor);
const transformed = await mapStore.transformCoverage(coverageMap);
assert.isUndefined(transformed.data.constructor);

const transformedCoverage =
transformed.map.data[path.resolve('./test.ts')].data;
transformed.data[path.resolve('./test.ts')].data;

assert.deepEqual(transformedCoverage.statementMap, {
'0': {
Expand Down
22 changes: 12 additions & 10 deletions packages/istanbul-lib-source-maps/test/transformer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
const path = require('path');
const assert = require('chai').assert;
const createMap = require('istanbul-lib-coverage').createCoverageMap;
const SMC = require('source-map').SourceMapConsumer;
const createTransformer = require('../lib/transformer').create;
const { SourceMapConsumer } = require('source-map');
const { SourceMapTransformer } = require('../lib/transformer');

const coverageData = {
statementMap: {
Expand Down Expand Up @@ -51,13 +51,14 @@ const testDataBackslash = {
};

describe('transformer', () => {
it('maps statement locations', () => {
it('maps statement locations', async () => {
const coverageMap = createMap({});
coverageMap.addFileCoverage(testDataSlash.coverageData);

const mapped = createTransformer(
() => new SMC(testDataSlash.sourceMap)
).transform(coverageMap);
const transformer = new SourceMapTransformer(
() => new SourceMapConsumer(testDataSlash.sourceMap)
);
const mapped = await transformer.transform(coverageMap);

assert.deepEqual(
mapped.data[testDataSlash.coverageData.path].statementMap,
Expand All @@ -74,17 +75,18 @@ describe('transformer', () => {
);
});

it('maps each file only once, /path/to/file.js and \\path\\to\\file.js are the same file', () => {
it('maps each file only once, /path/to/file.js and \\path\\to\\file.js are the same file', async () => {
const coverageMap = createMap({});

coverageMap.addFileCoverage(testDataSlash.coverageData);
coverageMap.addFileCoverage(testDataBackslash.coverageData);

const mapped = createTransformer(file =>
const transformer = new SourceMapTransformer(file =>
file === testDataSlash.coverageData.path
? new SMC(testDataSlash.sourceMap)
? new SourceMapConsumer(testDataSlash.sourceMap)
: undefined
).transform(coverageMap);
);
const mapped = await transformer.transform(coverageMap);

assert.equal(Object.keys(mapped.data).length, 1);
assert.isDefined(mapped.data[testDataBackslash.coverageData.path]);
Expand Down