Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@vitest/coverage-istanbul

Package Overview
Dependencies
Maintainers
3
Versions
119
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vitest/coverage-istanbul - npm Package Compare versions

Comparing version 1.0.0-beta.6 to 1.0.0

17

dist/provider.d.ts
import { CoverageProvider, Vitest, AfterSuiteRunMeta, ReportContext, ResolvedCoverageOptions } from 'vitest';
import { BaseCoverageProvider } from 'vitest/coverage';
import { CoverageMapData } from 'istanbul-lib-coverage';
import { CoverageMap } from 'istanbul-lib-coverage';
import { Instrumenter } from 'istanbul-lib-instrument';
type Options = ResolvedCoverageOptions<'istanbul'>;
type CoverageByTransformMode = Record<AfterSuiteRunMeta['transformMode'], CoverageMapData[]>;
type Filename = string;
type CoverageFilesByTransformMode = Record<AfterSuiteRunMeta['transformMode'], Filename[]>;
type ProjectName = NonNullable<AfterSuiteRunMeta['projectName']> | typeof DEFAULT_PROJECT;

@@ -29,9 +30,5 @@ interface TestExclude {

testExclude: InstanceType<TestExclude>;
/**
* Coverage objects collected from workers.
* Some istanbul utilizers write these into file system instead of storing in memory.
* If storing in memory causes issues, we can simply write these into fs in `onAfterSuiteRun`
* and read them back when merging coverage objects in `onAfterAllFilesRun`.
*/
coverages: Map<ProjectName, CoverageByTransformMode>;
coverageFiles: Map<ProjectName, CoverageFilesByTransformMode>;
coverageFilesDirectory: string;
pendingPromises: Promise<void>[];
initialize(ctx: Vitest): void;

@@ -46,5 +43,5 @@ resolveOptions(): Options;

reportCoverage({ allTestsRun }?: ReportContext): Promise<void>;
getCoverageMapForUncoveredFiles(coveredFiles: string[]): Promise<CoverageMapData>;
getCoverageMapForUncoveredFiles(coveredFiles: string[]): Promise<CoverageMap>;
}
export { IstanbulCoverageProvider };

@@ -1,2 +0,2 @@

import { existsSync, promises, writeFileSync } from 'node:fs';
import { promises, existsSync, writeFileSync } from 'node:fs';
import { coverageConfigDefaults, defaultExclude, defaultInclude } from 'vitest/config';

@@ -6,2 +6,3 @@ import { BaseCoverageProvider } from 'vitest/coverage';

import { parseModule } from 'magicast';
import createDebug from 'debug';
import libReport from 'istanbul-lib-report';

@@ -110,2 +111,4 @@ import reports from 'istanbul-reports';

const DEFAULT_PROJECT = Symbol.for("default-project");
const debug = createDebug("vitest:coverage");
let uniqueId = 0;
class IstanbulCoverageProvider extends BaseCoverageProvider {

@@ -117,9 +120,5 @@ name = "istanbul";

testExclude;
/**
* Coverage objects collected from workers.
* Some istanbul utilizers write these into file system instead of storing in memory.
* If storing in memory causes issues, we can simply write these into fs in `onAfterSuiteRun`
* and read them back when merging coverage objects in `onAfterAllFilesRun`.
*/
coverages = /* @__PURE__ */ new Map();
coverageFiles = /* @__PURE__ */ new Map();
coverageFilesDirectory;
pendingPromises = [];
initialize(ctx) {

@@ -163,2 +162,3 @@ const config = ctx.config.coverage;

});
this.coverageFilesDirectory = resolve(this.options.reportsDirectory, ".tmp");
}

@@ -183,10 +183,15 @@ resolveOptions() {

onAfterSuiteRun({ coverage, transformMode, projectName }) {
if (!coverage)
return;
if (transformMode !== "web" && transformMode !== "ssr")
throw new Error(`Invalid transform mode: ${transformMode}`);
let entry = this.coverages.get(projectName || DEFAULT_PROJECT);
let entry = this.coverageFiles.get(projectName || DEFAULT_PROJECT);
if (!entry) {
entry = { web: [], ssr: [] };
this.coverages.set(projectName || DEFAULT_PROJECT, entry);
this.coverageFiles.set(projectName || DEFAULT_PROJECT, entry);
}
entry[transformMode].push(coverage);
const filename = resolve(this.coverageFilesDirectory, `coverage-${uniqueId++}.json`);
entry[transformMode].push(filename);
const promise = promises.writeFile(filename, JSON.stringify(coverage), "utf-8");
this.pendingPromises.push(promise);
}

@@ -196,17 +201,37 @@ async clean(clean = true) {

await promises.rm(this.options.reportsDirectory, { recursive: true, force: true, maxRetries: 10 });
this.coverages = /* @__PURE__ */ new Map();
if (existsSync(this.coverageFilesDirectory))
await promises.rm(this.coverageFilesDirectory, { recursive: true, force: true, maxRetries: 10 });
await promises.mkdir(this.coverageFilesDirectory, { recursive: true });
this.coverageFiles = /* @__PURE__ */ new Map();
this.pendingPromises = [];
}
async reportCoverage({ allTestsRun } = {}) {
const coverageMaps = await Promise.all(
Array.from(this.coverages.values()).map((coverages) => [
mergeAndTransformCoverage(coverages.ssr),
mergeAndTransformCoverage(coverages.web)
]).flat()
);
const coverageMap = libCoverage.createCoverageMap({});
let index = 0;
const total = this.pendingPromises.length;
await Promise.all(this.pendingPromises);
this.pendingPromises = [];
for (const coveragePerProject of this.coverageFiles.values()) {
for (const filenames of [coveragePerProject.ssr, coveragePerProject.web]) {
const coverageMapByTransformMode = libCoverage.createCoverageMap({});
for (const chunk of toSlices(filenames, this.options.processingConcurrency)) {
if (debug.enabled) {
index += chunk.length;
debug("Covered files %d/%d", index, total);
}
await Promise.all(chunk.map(async (filename) => {
const contents = await promises.readFile(filename, "utf-8");
const coverage = JSON.parse(contents);
coverageMapByTransformMode.merge(coverage);
}));
}
const transformedCoverage = await transformCoverage(coverageMapByTransformMode);
coverageMap.merge(transformedCoverage);
}
}
if (this.options.all && allTestsRun) {
const coveredFiles = coverageMaps.map((map) => map.files()).flat();
const coveredFiles = coverageMap.files();
const uncoveredCoverage = await this.getCoverageMapForUncoveredFiles(coveredFiles);
coverageMaps.push(await mergeAndTransformCoverage([uncoveredCoverage]));
coverageMap.merge(await transformCoverage(uncoveredCoverage));
}
const coverageMap = mergeCoverageMaps(...coverageMaps);
const context = libReport.createContext({

@@ -251,2 +276,4 @@ dir: this.options.reportsDirectory,

}
await promises.rm(this.coverageFilesDirectory, { recursive: true });
this.coverageFiles = /* @__PURE__ */ new Map();
}

@@ -257,3 +284,6 @@ async getCoverageMapForUncoveredFiles(coveredFiles) {

const coverageMap = libCoverage.createCoverageMap({});
for (const filename of uncoveredFiles) {
for (const [index, filename] of uncoveredFiles.entries()) {
debug("Uncovered file %s %d/%d", filename, index, uncoveredFiles.length);
if (this.ctx.vitenode.fetchCache.has(filename))
this.ctx.vitenode.fetchCache.delete(filename);
await this.ctx.vitenode.transformRequest(filename);

@@ -263,18 +293,10 @@ const lastCoverage = this.instrumenter.lastFileCoverage();

}
return coverageMap.data;
return coverageMap;
}
}
async function mergeAndTransformCoverage(coverages) {
const mergedCoverage = mergeCoverageMaps(...coverages);
includeImplicitElseBranches(mergedCoverage);
async function transformCoverage(coverageMap) {
includeImplicitElseBranches(coverageMap);
const sourceMapStore = libSourceMaps.createSourceMapStore();
return await sourceMapStore.transformCoverage(mergedCoverage);
return await sourceMapStore.transformCoverage(coverageMap);
}
function mergeCoverageMaps(...coverageMaps) {
return coverageMaps.reduce((coverage, previousCoverageMap) => {
const map = libCoverage.createCoverageMap(coverage);
map.merge(previousCoverageMap);
return map;
}, libCoverage.createCoverageMap({}));
}
function removeQueryParameters(filename) {

@@ -307,3 +329,15 @@ return filename.split("?")[0];

}
function toSlices(array, size) {
return array.reduce((chunks, item) => {
const index = Math.max(0, chunks.length - 1);
const lastChunk = chunks[index] || [];
chunks[index] = lastChunk;
if (lastChunk.length >= size)
chunks.push([item]);
else
lastChunk.push(item);
return chunks;
}, []);
}
export { IstanbulCoverageProvider };
{
"name": "@vitest/coverage-istanbul",
"type": "module",
"version": "1.0.0-beta.6",
"version": "1.0.0",
"description": "Istanbul coverage provider for Vitest",

@@ -43,2 +43,3 @@ "author": "Anthony Fu <anthonyfu117@hotmail.com>",

"dependencies": {
"debug": "^4.3.4",
"istanbul-lib-coverage": "^3.2.2",

@@ -54,2 +55,3 @@ "istanbul-lib-instrument": "^6.0.1",

"devDependencies": {
"@types/debug": "^4.1.12",
"@types/istanbul-lib-coverage": "^2.0.6",

@@ -61,3 +63,3 @@ "@types/istanbul-lib-instrument": "^1.7.7",

"pathe": "^1.1.1",
"vitest": "1.0.0-beta.6"
"vitest": "1.0.0"
},

@@ -64,0 +66,0 @@ "scripts": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc