CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vitest--coverage-c8

C8 coverage provider for Vitest testing framework enabling comprehensive code coverage analysis using the C8 JavaScript coverage tool

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

@vitest/coverage-c8

The @vitest/coverage-c8 package provides a C8 coverage provider integration for the Vitest testing framework. It enables comprehensive code coverage analysis using the C8 JavaScript coverage tool, which leverages V8's built-in code coverage capabilities. This provider handles source map remapping for accurate coverage reporting in TypeScript and bundled code.

Package Information

  • Package Name: @vitest/coverage-c8
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @vitest/coverage-c8

Core Imports

import coverageC8 from "@vitest/coverage-c8";
// coverageC8 provides: getProvider, startCoverage, takeCoverage, stopCoverage

For CommonJS environments:

const coverageC8 = require("@vitest/coverage-c8");

Direct import of coverage functions:

import { startCoverage, takeCoverage, stopCoverage } from "@vitest/coverage-c8";

Basic Usage

Configure Vitest to use the C8 coverage provider:

// vitest.config.ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    coverage: {
      provider: 'c8',
      reporter: ['text', 'html', 'json'],
      exclude: ['node_modules/', '**/*.test.ts'],
      allowExternal: false,
      excludeNodeModules: true,
    },
  },
});

Run tests with coverage:

npx vitest run --coverage

Using coverage functions programmatically:

import { startCoverage, takeCoverage, stopCoverage } from '@vitest/coverage-c8';

// Start collecting coverage
startCoverage();

// Your test code here...

// Take a coverage snapshot
const coverage = await takeCoverage();
console.log(coverage.result.length); // Number of covered files

// Stop coverage collection
stopCoverage();

Architecture

The package is built around several key components:

  • Coverage Provider: C8CoverageProvider class extending BaseCoverageProvider and implementing Vitest's CoverageProvider interface
  • Coverage Collection: Functions (startCoverage, takeCoverage, stopCoverage) for interacting with V8 coverage data using Node.js Inspector API
  • Source Map Processing: Advanced utilities for accurate coverage reporting in transformed code (TypeScript, bundled files) with Vite helper removal
  • Report Generation: Integration with C8's reporting system for various output formats using Istanbul reporters
  • Base Provider Methods: Inherited utilities for threshold checking, reporter resolution, and threshold auto-updating

Capabilities

Coverage Provider Module

The main export provides a coverage provider module that integrates with Vitest's coverage system.

/**
 * Main module export providing coverage provider and collection functions
 */
interface CoverageProviderModule {
  /** Factory for creating a new coverage provider */
  getProvider(): Promise<C8CoverageProvider>;
  /** Start coverage collection using Node.js inspector */
  startCoverage(): void;
  /** Take coverage snapshot and return filtered results */
  takeCoverage(): Promise<{ result: Profiler.ScriptCoverage[] }>;
  /** Stop coverage collection and disconnect inspector */
  stopCoverage(): void;
}

/**
 * Default export object structure
 */
const coverageModule: CoverageProviderModule;
export default coverageModule;

Coverage Provider Implementation

Core coverage provider class that handles collection, processing, and reporting.

/**
 * C8 coverage provider implementing CoverageProvider interface
 */
class C8CoverageProvider extends BaseCoverageProvider implements CoverageProvider {
  name: string; // Always 'c8'
  ctx: Vitest;
  options: ResolvedCoverageOptions<'c8'>;
  coverages: Profiler.TakePreciseCoverageReturnType[];

  /** Initialize the provider with Vitest context and configuration */
  initialize(ctx: Vitest): void;
  
  /** Get resolved coverage options */
  resolveOptions(): ResolvedCoverageOptions<'c8'>;
  
  /** Clean coverage directory and reset coverage data */
  clean(clean?: boolean): Promise<void>;
  
  /** Collect coverage data after suite run */
  onAfterSuiteRun(meta: AfterSuiteRunMeta): void;
  
  /** Generate and write coverage reports */
  reportCoverage(reportContext?: ReportContext): Promise<void>;
  
  /** Resolve reporters from various configuration options */
  resolveReporters(configReporters: NonNullable<BaseCoverageOptions['reporter']>): ResolvedCoverageOptions['reporter'];
  
  /** Check collected coverage against configured thresholds */
  checkThresholds({ coverageMap, thresholds, perFile }: {
    coverageMap: CoverageMap;
    thresholds: Record<'lines' | 'functions' | 'statements' | 'branches', number | undefined>;
    perFile?: boolean;
  }): void;
  
  /** Update thresholds when current coverage is above configured thresholds */
  updateThresholds({ configurationFile, coverageMap, thresholds, perFile }: {
    coverageMap: CoverageMap;
    thresholds: Record<'lines' | 'functions' | 'statements' | 'branches', number | undefined>;
    perFile?: boolean;
    configurationFile?: string;
  }): void;
}

Coverage Collection Functions

Low-level functions for interacting with V8's coverage system through Node.js Inspector API.

/**
 * Start coverage collection using Node.js inspector
 * Connects to inspector and enables precise coverage tracking
 */
function startCoverage(): void;

/**
 * Take a coverage snapshot and return filtered results
 * Filters out node_modules and non-file URLs using internal filterResult function
 * Only includes files that start with 'file://' and don't contain '/node_modules/'
 * @returns Promise resolving to coverage data with filtered script coverage
 */
function takeCoverage(): Promise<{ result: Profiler.ScriptCoverage[] }>;

/**
 * Stop coverage collection and disconnect inspector
 * Disables profiler and closes inspector session
 */
function stopCoverage(): void;

Configuration Options

C8-specific coverage configuration options extending base coverage options.

/**
 * Configuration options specific to C8 coverage provider
 */
interface CoverageC8Options extends BaseCoverageOptions {
  /** Allow files from outside of current working directory */
  allowExternal?: boolean; // default: false
  
  /** Exclude coverage under /node_modules/ */
  excludeNodeModules?: boolean; // default: true
  
  /** Directories used when --all is enabled */
  src?: string[];
  
  /** Shortcut for 100% coverage thresholds on all metrics */
  100?: boolean; // default: false
  
  /** Watermarks for statements, lines, branches and functions */
  watermarks?: {
    statements?: [number, number];
    functions?: [number, number];
    branches?: [number, number];
    lines?: [number, number];
  };
}

/**
 * Base coverage options shared across all providers
 */
interface BaseCoverageOptions {
  /** Enable coverage collection */
  enabled?: boolean; // default: false
  
  /** Files included in coverage as glob patterns */
  include?: string[]; // default: ['**']
  
  /** File extensions to include in coverage */
  extension?: string | string[]; // default: ['.js', '.cjs', '.mjs', '.ts', '.tsx', '.jsx', '.vue', '.svelte']
  
  /** Files excluded from coverage as glob patterns */
  exclude?: string[];
  
  /** Include all files, including untested ones */
  all?: boolean; // default: false
  
  /** Clean coverage results before running tests */
  clean?: boolean; // default: true
  
  /** Clean coverage report on watch rerun */
  cleanOnRerun?: boolean; // default: true
  
  /** Directory to write coverage report to */
  reportsDirectory?: string;
  
  /** Coverage reporters to use */
  reporter?: CoverageReporter | CoverageReporter[] | CoverageReporterWithOptions[];
  
  /** Skip files with 100% coverage in reports */
  skipFull?: boolean; // default: false
  
  /** Check thresholds per file */
  perFile?: boolean; // default: false
  
  /** Coverage thresholds */
  lines?: number;
  functions?: number;
  branches?: number;
  statements?: number;
  
  /** Update thresholds automatically when coverage is higher */
  thresholdAutoUpdate?: boolean; // default: false
  
  /** Generate coverage report even when tests fail */
  reportOnFailure?: boolean; // default: true
}

Coverage Reporter Types

Available coverage report formats and their configuration.

/**
 * Available coverage reporters from Istanbul
 */
type CoverageReporter = 
  | 'clover'
  | 'cobertura'
  | 'html'
  | 'html-spa'
  | 'json'
  | 'json-summary'
  | 'lcov'
  | 'lcovonly'
  | 'none'
  | 'teamcity'
  | 'text'
  | 'text-lcov'
  | 'text-summary';

/**
 * Reporter with configuration options
 */
type CoverageReporterWithOptions = [CoverageReporter, object];

Coverage Metadata Types

Types for coverage collection and reporting context.

/**
 * Context passed to reportCoverage method
 */
interface ReportContext {
  /** Indicates whether all tests were run (false for selective test runs) */
  allTestsRun?: boolean;
}

/**
 * Metadata from suite run containing coverage data
 */
interface AfterSuiteRunMeta {
  /** Coverage data collected during suite execution */
  coverage: Profiler.TakePreciseCoverageReturnType;
}

/**
 * Coverage map from Istanbul library
 */
interface CoverageMap {
  files(): string[];
  fileCoverageFor(filename: string): FileCoverage;
  getCoverageSummary(): CoverageSummary;
}

/**
 * Coverage summary with metrics
 */
interface CoverageSummary {
  data: {
    lines: { pct: number };
    functions: { pct: number };
    statements: { pct: number };
    branches: { pct: number };
  };
  lines: { pct: number };
  functions: { pct: number };
  statements: { pct: number };
  branches: { pct: number };
}

/**
 * File coverage information
 */
interface FileCoverage {
  toSummary(): CoverageSummary;
}

/**
 * V8 profiler types from Node.js inspector
 */
namespace Profiler {
  interface TakePreciseCoverageReturnType {
    result: ScriptCoverage[];
  }
  
  interface ScriptCoverage {
    scriptId: string;
    url: string;
    functions: FunctionCoverage[];
  }
  
  interface FunctionCoverage {
    functionName: string;
    ranges: CoverageRange[];
    isBlockCoverage: boolean;
  }
  
  interface CoverageRange {
    startOffset: number;
    endOffset: number;
    count: number;
  }
}

Error Handling

The package handles several error scenarios:

  • Stackblitz Environment: Gracefully handles Stackblitz limitations by returning empty coverage and logging appropriate messages
  • File System Errors: Robust error handling for report directory operations with retry logic (maxRetries: 10)
  • Inspector API Errors: Proper error handling in coverage collection functions with promise rejection
  • Source Map Processing: Fallback behavior when source maps are unavailable or malformed
  • Configuration File Updates: Error handling for threshold auto-update when configuration file is missing

Deprecation Notice

Important: This package is deprecated and being replaced by @vitest/coverage-v8. The provider automatically displays a deprecation warning when initialized:

DEPRECATION @vitest/coverage-c8 is being replaced by @vitest/coverage-v8.
            See https://github.com/vitest-dev/vitest/pull/3339 for more information.

Users should migrate to the newer V8 coverage provider for better performance and maintainability.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@vitest/coverage-c8@0.33.x
Publish Source
CLI
Badge
tessl/npm-vitest--coverage-c8 badge