CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-istanbul-lib-instrument

Core istanbul API for JS code coverage instrumentation and analysis

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

coverage-reading.mddocs/

Coverage Data Reading

Utility functionality for extracting existing coverage data from already instrumented JavaScript code. This enables coverage analysis of pre-instrumented files and recovery of coverage metadata.

Capabilities

Read Initial Coverage

Extracts coverage data from JavaScript code that has already been instrumented with coverage tracking.

/**
 * Reads existing coverage data from already instrumented code
 * @param code - The instrumented code (string) or parsed AST object
 * @returns Coverage data object if found, null if no coverage data exists
 */
function readInitialCoverage(code: string | object): CoverageData | null;

interface CoverageData {
  /** File path that the coverage data tracks */
  path: string;
  /** Hash of the original source code */
  hash: string;
  /** Global coverage variable name */
  gcv: string;
  /** The actual coverage tracking data structure */
  coverageData: object;
}

Usage Examples:

const { readInitialCoverage } = require("istanbul-lib-instrument");

// Read coverage from instrumented code string
const instrumentedCode = `
var cov_1a2b3c = function () {
  var path = '/path/to/original/file.js';
  var hash = 'abc123def456';
  var gcv = '__coverage__';
  var coverageData = {
    path: '/path/to/original/file.js',
    statementMap: { /* ... */ },
    fnMap: { /* ... */ },
    branchMap: { /* ... */ },
    s: {},
    f: {},
    b: {}
  };
  return coverageData;
}();

function add(a, b) {
  cov_1a2b3c.s[0]++;
  return a + b;
}
`;

const coverage = readInitialCoverage(instrumentedCode);
if (coverage) {
  console.log('Original file path:', coverage.path);
  console.log('Source hash:', coverage.hash);
  console.log('Coverage variable:', coverage.gcv);
  console.log('Statement map:', coverage.coverageData.statementMap);
}

AST-based Coverage Reading

Reading coverage data from pre-parsed AST objects instead of code strings.

// Reading from Babel AST
const { parseSync } = require("@babel/core");
const { readInitialCoverage } = require("istanbul-lib-instrument");

const ast = parseSync(instrumentedCode, {
  sourceType: 'script',
  plugins: ['jsx', 'typescript']
});

const coverage = readInitialCoverage(ast);

Usage Examples:

const { parseSync } = require("@babel/core");
const { readInitialCoverage } = require("istanbul-lib-instrument");

// Parse instrumented code to AST
const instrumentedCode = '/* instrumented code */';
const ast = parseSync(instrumentedCode, {
  sourceType: 'unambiguous',
  allowImportExportEverywhere: true,
  allowReturnOutsideFunction: true
});

// Extract coverage from AST
const coverage = readInitialCoverage(ast);
if (coverage) {
  console.log('Found coverage data for:', coverage.path);
  
  // Access detailed coverage information
  const { coverageData } = coverage;
  console.log('Functions tracked:', Object.keys(coverageData.fnMap).length);
  console.log('Statements tracked:', Object.keys(coverageData.statementMap).length);
  console.log('Branches tracked:', Object.keys(coverageData.branchMap).length);
}

Coverage Data Structure

Understanding the structure of returned coverage data for analysis and reporting.

interface DetailedCoverageData {
  /** File path being tracked */
  path: string;
  /** Statement location mapping */
  statementMap: { [key: string]: Location };
  /** Function location mapping */
  fnMap: { [key: string]: FunctionMapping };
  /** Branch location mapping */
  branchMap: { [key: string]: BranchMapping };
  /** Statement execution counts */
  s: { [key: string]: number };
  /** Function execution counts */
  f: { [key: string]: number };
  /** Branch execution counts */
  b: { [key: string]: number[] };
}

interface Location {
  start: { line: number; column: number };
  end: { line: number; column: number };
}

interface FunctionMapping {
  name: string;
  decl: Location;
  loc: Location;
  line: number;
}

interface BranchMapping {
  loc: Location;
  type: 'if' | 'switch' | 'cond-expr' | 'logical-expr';
  locations: Location[];
  line: number;
}

Usage Examples:

const { readInitialCoverage } = require("istanbul-lib-instrument");

function analyzeCoverage(instrumentedCode) {
  const coverage = readInitialCoverage(instrumentedCode);
  
  if (!coverage) {
    console.log('No coverage data found');
    return;
  }
  
  const { coverageData } = coverage;
  
  // Analyze statement coverage
  const statements = Object.keys(coverageData.statementMap);
  const executedStatements = statements.filter(id => coverageData.s[id] > 0);
  console.log(`Statement coverage: ${executedStatements.length}/${statements.length}`);
  
  // Analyze function coverage
  const functions = Object.keys(coverageData.fnMap);
  const executedFunctions = functions.filter(id => coverageData.f[id] > 0);
  console.log(`Function coverage: ${executedFunctions.length}/${functions.length}`);
  
  // Analyze branch coverage
  const branches = Object.keys(coverageData.branchMap);
  let totalBranches = 0;
  let executedBranches = 0;
  
  branches.forEach(branchId => {
    const branchData = coverageData.b[branchId];
    totalBranches += branchData.length;
    executedBranches += branchData.filter(count => count > 0).length;
  });
  
  console.log(`Branch coverage: ${executedBranches}/${totalBranches}`);
}

Error Handling and Validation

Handling cases where coverage data is missing, malformed, or partially available.

function safeCoverageReading(code) {
  try {
    const coverage = readInitialCoverage(code);
    
    if (!coverage) {
      console.log('No coverage data found in code');
      return null;
    }
    
    // Validate coverage data structure
    if (!coverage.coverageData || !coverage.path) {
      console.warn('Incomplete coverage data structure');
      return null;
    }
    
    return coverage;
    
  } catch (error) {
    console.error('Failed to read coverage data:', error.message);
    return null;
  }
}

Usage Examples:

const { readInitialCoverage } = require("istanbul-lib-instrument");
const fs = require('fs');

// Read coverage from multiple files
function analyzeCoverageFiles(filePaths) {
  const results = [];
  
  for (const filePath of filePaths) {
    try {
      const code = fs.readFileSync(filePath, 'utf8');
      const coverage = readInitialCoverage(code);
      
      if (coverage) {
        results.push({
          file: filePath,
          originalPath: coverage.path,
          hash: coverage.hash,
          hasStatements: Object.keys(coverage.coverageData.statementMap).length > 0,
          hasFunctions: Object.keys(coverage.coverageData.fnMap).length > 0,
          hasBranches: Object.keys(coverage.coverageData.branchMap).length > 0
        });
      }
    } catch (error) {
      console.warn(`Failed to analyze ${filePath}:`, error.message);
    }
  }
  
  return results;
}

// Usage
const coverageFiles = [
  'dist/instrumented/app.js',
  'dist/instrumented/utils.js',
  'dist/instrumented/components.js'
];

const analysis = analyzeCoverageFiles(coverageFiles);
analysis.forEach(result => {
  console.log(`${result.file} -> ${result.originalPath}`);
  console.log(`  Hash: ${result.hash}`);
  console.log(`  Coverage types: ${[
    result.hasStatements && 'statements',
    result.hasFunctions && 'functions', 
    result.hasBranches && 'branches'
  ].filter(Boolean).join(', ')}`);
});

Use Cases

Pre-Instrumented Code Analysis

Analyzing code that was instrumented in a previous build step or by a different tool.

const { readInitialCoverage } = require("istanbul-lib-instrument");

// Check if code is already instrumented before re-instrumenting
function isAlreadyInstrumented(code) {
  const coverage = readInitialCoverage(code);
  return coverage !== null;
}

// Extract original file path from instrumented code
function getOriginalPath(instrumentedCode) {
  const coverage = readInitialCoverage(instrumentedCode);
  return coverage ? coverage.path : null;
}

Coverage Data Recovery

Recovering coverage data from build artifacts or distributed code.

// Recover coverage metadata from production builds
function recoverCoverageMetadata(buildArtifacts) {
  const metadata = [];
  
  for (const artifact of buildArtifacts) {
    const coverage = readInitialCoverage(artifact.code);
    if (coverage) {
      metadata.push({
        buildFile: artifact.path,
        originalFile: coverage.path,
        sourceHash: coverage.hash,
        instrumentationVariable: coverage.gcv
      });
    }
  }
  
  return metadata;
}

Development Tool Integration

Integration with development tools that need to understand existing coverage instrumentation.

// IDE or editor plugin to detect instrumented files
function detectInstrumentedFiles(projectFiles) {
  return projectFiles
    .map(filePath => {
      const code = fs.readFileSync(filePath, 'utf8');
      const coverage = readInitialCoverage(code);
      
      return {
        path: filePath,
        isInstrumented: coverage !== null,
        originalSource: coverage ? coverage.path : filePath,
        coverageVariable: coverage ? coverage.gcv : null
      };
    })
    .filter(file => file.isInstrumented);
}

docs

babel-integration.md

coverage-reading.md

index.md

instrumentation.md

tile.json