/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ const minimatch = require('minimatch'); const fs = require('fs'); const path = require('path'); const iLibInstrument = require('istanbul-lib-instrument'); const iLibCoverage = require('istanbul-lib-coverage'); const iLibSourceMaps = require('istanbul-lib-source-maps'); const iLibReport = require('istanbul-lib-report'); const iReports = require('istanbul-reports'); const REPO_PATH = toUpperDriveLetter(path.join(__dirname, '../../')); exports.initialize = function (loaderConfig) { const instrumenter = iLibInstrument.createInstrumenter(); loaderConfig.nodeInstrumenter = function (contents, source) { if (minimatch(source, '**/test/**')) { // tests don't get instrumented return contents; } // Try to find a .map file let map = undefined; try { map = JSON.parse(fs.readFileSync(`${source}.map`).toString()); } catch (err) { // missing source map... } try { return instrumenter.instrumentSync(contents, source, map); } catch (e) { console.error(`Error instrumenting ${source}: ${e}`); throw e; } }; }; exports.createReport = function (isSingle, coveragePath, formats) { const mapStore = iLibSourceMaps.createSourceMapStore(); const coverageMap = iLibCoverage.createCoverageMap(global.__coverage__); return mapStore.transformCoverage(coverageMap).then((transformed) => { // Paths come out all broken const newData = Object.create(null); Object.keys(transformed.data).forEach((file) => { const entry = transformed.data[file]; const fixedPath = fixPath(entry.path); entry.data.path = fixedPath; newData[fixedPath] = entry; }); transformed.data = newData; const context = iLibReport.createContext({ dir: coveragePath || path.join(REPO_PATH, `.build/coverage${isSingle ? '-single' : ''}`), coverageMap: transformed }); const tree = context.getTree('flat'); const reports = []; if (formats) { if (typeof formats === 'string') { formats = [formats]; } formats.forEach(format => { reports.push(iReports.create(format)); }); } else if (isSingle) { reports.push(iReports.create('lcovonly')); } else { reports.push(iReports.create('json')); reports.push(iReports.create('lcov')); reports.push(iReports.create('html')); } reports.forEach(report => tree.visit(report, context)); }); }; function toUpperDriveLetter(str) { if (/^[a-z]:/.test(str)) { return str.charAt(0).toUpperCase() + str.substr(1); } return str; } function toLowerDriveLetter(str) { if (/^[A-Z]:/.test(str)) { return str.charAt(0).toLowerCase() + str.substr(1); } return str; } function fixPath(brokenPath) { const startIndex = brokenPath.lastIndexOf(REPO_PATH); if (startIndex === -1) { return toLowerDriveLetter(brokenPath); } return toLowerDriveLetter(brokenPath.substr(startIndex)); }