diff options
Diffstat (limited to 'node_modules/@jest/reporters/build/CoverageReporter.js')
-rw-r--r-- | node_modules/@jest/reporters/build/CoverageReporter.js | 668 |
1 files changed, 668 insertions, 0 deletions
diff --git a/node_modules/@jest/reporters/build/CoverageReporter.js b/node_modules/@jest/reporters/build/CoverageReporter.js new file mode 100644 index 0000000..4ea3f0e --- /dev/null +++ b/node_modules/@jest/reporters/build/CoverageReporter.js @@ -0,0 +1,668 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.default = void 0; + +function path() { + const data = _interopRequireWildcard(require('path')); + + path = function () { + return data; + }; + + return data; +} + +function _v8Coverage() { + const data = require('@bcoe/v8-coverage'); + + _v8Coverage = function () { + return data; + }; + + return data; +} + +function _chalk() { + const data = _interopRequireDefault(require('chalk')); + + _chalk = function () { + return data; + }; + + return data; +} + +function _glob() { + const data = _interopRequireDefault(require('glob')); + + _glob = function () { + return data; + }; + + return data; +} + +function fs() { + const data = _interopRequireWildcard(require('graceful-fs')); + + fs = function () { + return data; + }; + + return data; +} + +function _istanbulLibCoverage() { + const data = _interopRequireDefault(require('istanbul-lib-coverage')); + + _istanbulLibCoverage = function () { + return data; + }; + + return data; +} + +function _istanbulLibReport() { + const data = _interopRequireDefault(require('istanbul-lib-report')); + + _istanbulLibReport = function () { + return data; + }; + + return data; +} + +function _istanbulLibSourceMaps() { + const data = _interopRequireDefault(require('istanbul-lib-source-maps')); + + _istanbulLibSourceMaps = function () { + return data; + }; + + return data; +} + +function _istanbulReports() { + const data = _interopRequireDefault(require('istanbul-reports')); + + _istanbulReports = function () { + return data; + }; + + return data; +} + +function _v8ToIstanbul() { + const data = _interopRequireDefault(require('v8-to-istanbul')); + + _v8ToIstanbul = function () { + return data; + }; + + return data; +} + +function _jestUtil() { + const data = require('jest-util'); + + _jestUtil = function () { + return data; + }; + + return data; +} + +function _jestWorker() { + const data = require('jest-worker'); + + _jestWorker = function () { + return data; + }; + + return data; +} + +var _BaseReporter = _interopRequireDefault(require('./BaseReporter')); + +var _getWatermarks = _interopRequireDefault(require('./getWatermarks')); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : {default: obj}; +} + +function _getRequireWildcardCache(nodeInterop) { + if (typeof WeakMap !== 'function') return null; + var cacheBabelInterop = new WeakMap(); + var cacheNodeInterop = new WeakMap(); + return (_getRequireWildcardCache = function (nodeInterop) { + return nodeInterop ? cacheNodeInterop : cacheBabelInterop; + })(nodeInterop); +} + +function _interopRequireWildcard(obj, nodeInterop) { + if (!nodeInterop && obj && obj.__esModule) { + return obj; + } + if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) { + return {default: obj}; + } + var cache = _getRequireWildcardCache(nodeInterop); + if (cache && cache.has(obj)) { + return cache.get(obj); + } + var newObj = {}; + var hasPropertyDescriptor = + Object.defineProperty && Object.getOwnPropertyDescriptor; + for (var key in obj) { + if (key !== 'default' && Object.prototype.hasOwnProperty.call(obj, key)) { + var desc = hasPropertyDescriptor + ? Object.getOwnPropertyDescriptor(obj, key) + : null; + if (desc && (desc.get || desc.set)) { + Object.defineProperty(newObj, key, desc); + } else { + newObj[key] = obj[key]; + } + } + } + newObj.default = obj; + if (cache) { + cache.set(obj, newObj); + } + return newObj; +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + return obj; +} + +const FAIL_COLOR = _chalk().default.bold.red; + +const RUNNING_TEST_COLOR = _chalk().default.bold.dim; + +class CoverageReporter extends _BaseReporter.default { + constructor(globalConfig, options) { + super(); + + _defineProperty(this, '_coverageMap', void 0); + + _defineProperty(this, '_globalConfig', void 0); + + _defineProperty(this, '_sourceMapStore', void 0); + + _defineProperty(this, '_options', void 0); + + _defineProperty(this, '_v8CoverageResults', void 0); + + this._coverageMap = _istanbulLibCoverage().default.createCoverageMap({}); + this._globalConfig = globalConfig; + this._sourceMapStore = + _istanbulLibSourceMaps().default.createSourceMapStore(); + this._v8CoverageResults = []; + this._options = options || {}; + } + + onTestResult(_test, testResult) { + if (testResult.v8Coverage) { + this._v8CoverageResults.push(testResult.v8Coverage); + + return; + } + + if (testResult.coverage) { + this._coverageMap.merge(testResult.coverage); + } + } + + async onRunComplete(contexts, aggregatedResults) { + await this._addUntestedFiles(contexts); + const {map, reportContext} = await this._getCoverageResult(); + + try { + const coverageReporters = this._globalConfig.coverageReporters || []; + + if (!this._globalConfig.useStderr && coverageReporters.length < 1) { + coverageReporters.push('text-summary'); + } + + coverageReporters.forEach(reporter => { + let additionalOptions = {}; + + if (Array.isArray(reporter)) { + [reporter, additionalOptions] = reporter; + } + + _istanbulReports() + .default.create(reporter, { + maxCols: process.stdout.columns || Infinity, + ...additionalOptions + }) + .execute(reportContext); + }); + aggregatedResults.coverageMap = map; + } catch (e) { + console.error( + _chalk().default.red(` + Failed to write coverage reports: + ERROR: ${e.toString()} + STACK: ${e.stack} + `) + ); + } + + this._checkThreshold(map); + } + + async _addUntestedFiles(contexts) { + const files = []; + contexts.forEach(context => { + const config = context.config; + + if ( + this._globalConfig.collectCoverageFrom && + this._globalConfig.collectCoverageFrom.length + ) { + context.hasteFS + .matchFilesWithGlob( + this._globalConfig.collectCoverageFrom, + config.rootDir + ) + .forEach(filePath => + files.push({ + config, + path: filePath + }) + ); + } + }); + + if (!files.length) { + return; + } + + if (_jestUtil().isInteractive) { + process.stderr.write( + RUNNING_TEST_COLOR('Running coverage on untested files...') + ); + } + + let worker; + + if (this._globalConfig.maxWorkers <= 1) { + worker = require('./CoverageWorker'); + } else { + worker = new (_jestWorker().Worker)(require.resolve('./CoverageWorker'), { + exposedMethods: ['worker'], + maxRetries: 2, + numWorkers: this._globalConfig.maxWorkers + }); + } + + const instrumentation = files.map(async fileObj => { + const filename = fileObj.path; + const config = fileObj.config; + + const hasCoverageData = this._v8CoverageResults.some(v8Res => + v8Res.some(innerRes => innerRes.result.url === filename) + ); + + if ( + !hasCoverageData && + !this._coverageMap.data[filename] && + 'worker' in worker + ) { + try { + const result = await worker.worker({ + config, + globalConfig: this._globalConfig, + options: { + ...this._options, + changedFiles: + this._options.changedFiles && + Array.from(this._options.changedFiles), + sourcesRelatedToTestsInChangedFiles: + this._options.sourcesRelatedToTestsInChangedFiles && + Array.from(this._options.sourcesRelatedToTestsInChangedFiles) + }, + path: filename + }); + + if (result) { + if (result.kind === 'V8Coverage') { + this._v8CoverageResults.push([ + { + codeTransformResult: undefined, + result: result.result + } + ]); + } else { + this._coverageMap.addFileCoverage(result.coverage); + } + } + } catch (error) { + console.error( + _chalk().default.red( + [ + `Failed to collect coverage from ${filename}`, + `ERROR: ${error.message}`, + `STACK: ${error.stack}` + ].join('\n') + ) + ); + } + } + }); + + try { + await Promise.all(instrumentation); + } catch { + // Do nothing; errors were reported earlier to the console. + } + + if (_jestUtil().isInteractive) { + (0, _jestUtil().clearLine)(process.stderr); + } + + if (worker && 'end' in worker && typeof worker.end === 'function') { + await worker.end(); + } + } + + _checkThreshold(map) { + const {coverageThreshold} = this._globalConfig; + + if (coverageThreshold) { + function check(name, thresholds, actuals) { + return ['statements', 'branches', 'lines', 'functions'].reduce( + (errors, key) => { + const actual = actuals[key].pct; + const actualUncovered = actuals[key].total - actuals[key].covered; + const threshold = thresholds[key]; + + if (threshold !== undefined) { + if (threshold < 0) { + if (threshold * -1 < actualUncovered) { + errors.push( + `Jest: Uncovered count for ${key} (${actualUncovered}) ` + + `exceeds ${name} threshold (${-1 * threshold})` + ); + } + } else if (actual < threshold) { + errors.push( + `Jest: "${name}" coverage threshold for ${key} (${threshold}%) not met: ${actual}%` + ); + } + } + + return errors; + }, + [] + ); + } + + const THRESHOLD_GROUP_TYPES = { + GLOB: 'glob', + GLOBAL: 'global', + PATH: 'path' + }; + const coveredFiles = map.files(); + const thresholdGroups = Object.keys(coverageThreshold); + const groupTypeByThresholdGroup = {}; + const filesByGlob = {}; + const coveredFilesSortedIntoThresholdGroup = coveredFiles.reduce( + (files, file) => { + const pathOrGlobMatches = thresholdGroups.reduce( + (agg, thresholdGroup) => { + const absoluteThresholdGroup = path().resolve(thresholdGroup); // The threshold group might be a path: + + if (file.indexOf(absoluteThresholdGroup) === 0) { + groupTypeByThresholdGroup[thresholdGroup] = + THRESHOLD_GROUP_TYPES.PATH; + return agg.concat([[file, thresholdGroup]]); + } // If the threshold group is not a path it might be a glob: + // Note: glob.sync is slow. By memoizing the files matching each glob + // (rather than recalculating it for each covered file) we save a tonne + // of execution time. + + if (filesByGlob[absoluteThresholdGroup] === undefined) { + filesByGlob[absoluteThresholdGroup] = _glob() + .default.sync(absoluteThresholdGroup) + .map(filePath => path().resolve(filePath)); + } + + if (filesByGlob[absoluteThresholdGroup].indexOf(file) > -1) { + groupTypeByThresholdGroup[thresholdGroup] = + THRESHOLD_GROUP_TYPES.GLOB; + return agg.concat([[file, thresholdGroup]]); + } + + return agg; + }, + [] + ); + + if (pathOrGlobMatches.length > 0) { + return files.concat(pathOrGlobMatches); + } // Neither a glob or a path? Toss it in global if there's a global threshold: + + if (thresholdGroups.indexOf(THRESHOLD_GROUP_TYPES.GLOBAL) > -1) { + groupTypeByThresholdGroup[THRESHOLD_GROUP_TYPES.GLOBAL] = + THRESHOLD_GROUP_TYPES.GLOBAL; + return files.concat([[file, THRESHOLD_GROUP_TYPES.GLOBAL]]); + } // A covered file that doesn't have a threshold: + + return files.concat([[file, undefined]]); + }, + [] + ); + + const getFilesInThresholdGroup = thresholdGroup => + coveredFilesSortedIntoThresholdGroup + .filter(fileAndGroup => fileAndGroup[1] === thresholdGroup) + .map(fileAndGroup => fileAndGroup[0]); + + function combineCoverage(filePaths) { + return filePaths + .map(filePath => map.fileCoverageFor(filePath)) + .reduce((combinedCoverage, nextFileCoverage) => { + if (combinedCoverage === undefined || combinedCoverage === null) { + return nextFileCoverage.toSummary(); + } + + return combinedCoverage.merge(nextFileCoverage.toSummary()); + }, undefined); + } + + let errors = []; + thresholdGroups.forEach(thresholdGroup => { + switch (groupTypeByThresholdGroup[thresholdGroup]) { + case THRESHOLD_GROUP_TYPES.GLOBAL: { + const coverage = combineCoverage( + getFilesInThresholdGroup(THRESHOLD_GROUP_TYPES.GLOBAL) + ); + + if (coverage) { + errors = errors.concat( + check( + thresholdGroup, + coverageThreshold[thresholdGroup], + coverage + ) + ); + } + + break; + } + + case THRESHOLD_GROUP_TYPES.PATH: { + const coverage = combineCoverage( + getFilesInThresholdGroup(thresholdGroup) + ); + + if (coverage) { + errors = errors.concat( + check( + thresholdGroup, + coverageThreshold[thresholdGroup], + coverage + ) + ); + } + + break; + } + + case THRESHOLD_GROUP_TYPES.GLOB: + getFilesInThresholdGroup(thresholdGroup).forEach( + fileMatchingGlob => { + errors = errors.concat( + check( + fileMatchingGlob, + coverageThreshold[thresholdGroup], + map.fileCoverageFor(fileMatchingGlob).toSummary() + ) + ); + } + ); + break; + + default: + // If the file specified by path is not found, error is returned. + if (thresholdGroup !== THRESHOLD_GROUP_TYPES.GLOBAL) { + errors = errors.concat( + `Jest: Coverage data for ${thresholdGroup} was not found.` + ); + } + + // Sometimes all files in the coverage data are matched by + // PATH and GLOB threshold groups in which case, don't error when + // the global threshold group doesn't match any files. + } + }); + errors = errors.filter( + err => err !== undefined && err !== null && err.length > 0 + ); + + if (errors.length > 0) { + this.log(`${FAIL_COLOR(errors.join('\n'))}`); + + this._setError(new Error(errors.join('\n'))); + } + } + } + + async _getCoverageResult() { + if (this._globalConfig.coverageProvider === 'v8') { + const mergedCoverages = (0, _v8Coverage().mergeProcessCovs)( + this._v8CoverageResults.map(cov => ({ + result: cov.map(r => r.result) + })) + ); + const fileTransforms = new Map(); + + this._v8CoverageResults.forEach(res => + res.forEach(r => { + if (r.codeTransformResult && !fileTransforms.has(r.result.url)) { + fileTransforms.set(r.result.url, r.codeTransformResult); + } + }) + ); + + const transformedCoverage = await Promise.all( + mergedCoverages.result.map(async res => { + var _fileTransform$wrappe; + + const fileTransform = fileTransforms.get(res.url); + let sourcemapContent = undefined; + + if ( + fileTransform !== null && + fileTransform !== void 0 && + fileTransform.sourceMapPath && + fs().existsSync(fileTransform.sourceMapPath) + ) { + sourcemapContent = JSON.parse( + fs().readFileSync(fileTransform.sourceMapPath, 'utf8') + ); + } + + const converter = (0, _v8ToIstanbul().default)( + res.url, + (_fileTransform$wrappe = + fileTransform === null || fileTransform === void 0 + ? void 0 + : fileTransform.wrapperLength) !== null && + _fileTransform$wrappe !== void 0 + ? _fileTransform$wrappe + : 0, + fileTransform && sourcemapContent + ? { + originalSource: fileTransform.originalCode, + source: fileTransform.code, + sourceMap: { + sourcemap: { + file: res.url, + ...sourcemapContent + } + } + } + : { + source: fs().readFileSync(res.url, 'utf8') + } + ); + await converter.load(); + converter.applyCoverage(res.functions); + const istanbulData = converter.toIstanbul(); + converter.destroy(); + return istanbulData; + }) + ); + + const map = _istanbulLibCoverage().default.createCoverageMap({}); + + transformedCoverage.forEach(res => map.merge(res)); + + const reportContext = _istanbulLibReport().default.createContext({ + coverageMap: map, + dir: this._globalConfig.coverageDirectory, + watermarks: (0, _getWatermarks.default)(this._globalConfig) + }); + + return { + map, + reportContext + }; + } + + const map = await this._sourceMapStore.transformCoverage(this._coverageMap); + + const reportContext = _istanbulLibReport().default.createContext({ + coverageMap: map, + dir: this._globalConfig.coverageDirectory, + sourceFinder: this._sourceMapStore.sourceFinder, + watermarks: (0, _getWatermarks.default)(this._globalConfig) + }); + + return { + map, + reportContext + }; + } +} + +exports.default = CoverageReporter; + +_defineProperty(CoverageReporter, 'filename', __filename); |