CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-solidity-coverage

Code coverage for Solidity testing

Pending
Overview
Eval results
Files

core-library.mddocs/

Core Library

The core library contains the fundamental classes that power solidity-coverage's instrumentation, data collection, and reporting capabilities. These classes work together to provide comprehensive coverage analysis for Solidity smart contracts.

Capabilities

Instrumenter

The core instrumentation engine that modifies Solidity source code to inject coverage tracking calls.

/**
 * Main instrumentation class that modifies Solidity source code
 * Injects coverage tracking calls while preserving code functionality
 */
const Instrumenter = require('solidity-coverage/lib/instrumenter');

class Instrumenter {
  /**
   * Creates a new instrumenter instance
   * @param config - Configuration options for instrumentation behavior
   */
  constructor(config?: {
    viaIR?: boolean;                        // Enable Solidity viaIR compilation mode
    modifierWhitelist?: string[];           // Specific modifiers to measure
    measureStatementCoverage?: boolean;     // Enable statement coverage measurement
    measureFunctionCoverage?: boolean;      // Enable function coverage measurement  
    measureModifierCoverage?: boolean;      // Enable modifier coverage measurement
    measureBranchCoverage?: boolean;        // Enable branch coverage measurement
    measureLineCoverage?: boolean;          // Enable line coverage measurement
  });
  
  /**
   * Instruments Solidity source code for coverage tracking
   * @param source - Solidity source code to instrument
   * @param canonicalPath - Absolute path to the source file
   * @returns Instrumentation result with modified source and mapping data
   */
  instrument(source: string, canonicalPath: string): InstrumentationResult;
}

interface InstrumentationResult {
  contract: string;           // Instrumented Solidity source code
  runnableLines: number[];    // Array of line numbers that can be executed
  fnMap: object;             // Function mapping data for coverage
  branchMap: object;         // Branch mapping data for coverage
  statementMap: object;      // Statement mapping data for coverage
}

Usage Examples:

const Instrumenter = require('solidity-coverage/lib/instrumenter');

// Create instrumenter with custom configuration
const instrumenter = new Instrumenter({
  measureStatementCoverage: true,
  measureFunctionCoverage: true,
  measureBranchCoverage: true,
  viaIR: false
});

// Instrument contract source
const source = `
contract Token {
  uint256 public totalSupply;
  
  function transfer(address to, uint256 amount) public returns (bool) {
    if (balances[msg.sender] >= amount) {
      balances[msg.sender] -= amount;
      balances[to] += amount;
      return true;
    }
    return false;
  }
}`;

const result = instrumenter.instrument(source, '/contracts/Token.sol');
console.log('Instrumented contract:', result.contract);
console.log('Runnable lines:', result.runnableLines);

Coverage

Manages coverage data collection and generates Istanbul-compatible coverage reports.

/**
 * Coverage data management and report generation class
 * Converts execution data into standardized coverage reports
 */
const Coverage = require('solidity-coverage/lib/coverage');

class Coverage {
  /**
   * Creates a new coverage instance
   */
  constructor();
  
  /**
   * Adds contract instrumentation data to coverage tracking
   * @param info - Instrumentation data from Instrumenter.instrument()
   * @param contractPath - Canonical path to the contract file
   */
  addContract(info: InstrumentationResult, contractPath: string): void;
  
  /**
   * Generates final coverage data from collected execution traces
   * @param instrumentationData - Hit data collected during test execution
   */
  generate(instrumentationData: object): void;
}

Usage Examples:

const Coverage = require('solidity-coverage/lib/coverage');

// Create coverage instance
const coverage = new Coverage();

// Add instrumented contract data
coverage.addContract(instrumentationResult, '/contracts/Token.sol');

// Generate coverage report after tests complete
coverage.generate(executionData);

DataCollector

Hooks into EVM execution to collect coverage hit data during test runs.

/**
 * EVM execution hook for collecting coverage data
 * Tracks which lines, functions, and branches are executed
 */
const DataCollector = require('solidity-coverage/lib/collector');

class DataCollector {
  /**
   * Creates a new data collector instance
   * @param instrumentationData - Hit map from instrumentation (optional)
   * @param viaIR - Whether using viaIR compilation mode (optional)
   */
  constructor(instrumentationData?: object, viaIR?: boolean);
  
  /**
   * EVM step callback that processes each instruction
   * @param info - EVM execution step information
   */
  step(info: EVMStepInfo): void;
}

interface EVMStepInfo {
  pc: number;                    // Program counter
  opcode: {                      // Current opcode information
    name: string;                // Opcode name (e.g., 'SSTORE', 'CALL')
  };
  stack: any[];                  // EVM stack state
}

Usage Examples:

const DataCollector = require('solidity-coverage/lib/collector');

// Create data collector with instrumentation data
const collector = new DataCollector(instrumentationData, false);

// Hook into EVM execution (typically done by the API)
provider._node._vm.evm.events.on('step', collector.step.bind(collector));

ConfigValidator

Validates configuration objects to ensure proper setup.

/**
 * Configuration validation utility
 * Ensures coverage configuration is valid and complete
 */
const ConfigValidator = require('solidity-coverage/lib/validator');

class ConfigValidator {
  /**
   * Creates a new validator instance
   */
  constructor();
  
  /**
   * Validates a coverage configuration object
   * @param config - Configuration object to validate
   * @returns True if configuration is valid
   * @throws Error with descriptive message if invalid
   */
  validate(config: object): boolean;
}

Valid Configuration Properties:

The validator accepts these configuration properties:

  • client, cwd, host, port, abiOutputPath, matrixOutputPath
  • matrixReporterPath, providerOptions, silent, autoLaunchServer
  • istanbulFolder, measureStatementCoverage, measureFunctionCoverage
  • measureModifierCoverage, measureLineCoverage, measureBranchCoverage
  • onServerReady, onCompileComplete, onTestComplete, onIstanbulComplete
  • skipFiles, istanbulReporter, modifierWhitelist

Usage Examples:

const ConfigValidator = require('solidity-coverage/lib/validator');

const validator = new ConfigValidator();

const config = {
  skipFiles: ['contracts/mocks/'],
  istanbulReporter: ['html', 'lcov'],
  measureStatementCoverage: true,
  measureFunctionCoverage: true
};

try {
  const isValid = validator.validate(config);
  console.log('Configuration is valid:', isValid);
} catch (error) {
  console.error('Invalid configuration:', error.message);
}

AbiUtils

Utilities for working with contract ABI data and generating human-readable reports.

/**
 * ABI analysis and comparison utilities
 * Generates human-readable ABI information and diffs
 */
const AbiUtils = require('solidity-coverage/lib/abi');

class AbiUtils {
  /**
   * Compares two ABI objects and generates a unified diff
   * @param original - Original ABI object (optional)
   * @param current - Current ABI object (optional)
   * @returns Diff result with statistics and unified diff lines
   */
  diff(original?: object, current?: object): AbiDiffResult;
  
  /**
   * Converts contract ABI to human-readable function signatures
   * @param contract - Contract object with ABI property
   * @returns Array of human-readable function signature strings
   */
  toHumanReadableFunctions(contract: {abi: any[]}): string[];
}

interface AbiDiffResult {
  plus: number;              // Number of additions
  minus: number;             // Number of deletions  
  unifiedDiff: string[];     // Array of diff lines
}

Usage Examples:

const AbiUtils = require('solidity-coverage/lib/abi');

const abiUtils = new AbiUtils();

// Generate human-readable function signatures
const contract = {
  abi: [
    {
      "name": "transfer",
      "type": "function",
      "inputs": [
        {"name": "to", "type": "address"},
        {"name": "amount", "type": "uint256"}
      ],
      "outputs": [{"type": "bool"}]
    }
  ]
};

const signatures = abiUtils.toHumanReadableFunctions(contract);
console.log('Function signatures:', signatures);
// Output: ['function transfer(address to, uint256 amount) returns (bool)']

// Compare ABI changes
const oldAbi = { /* previous ABI */ };
const newAbi = { /* current ABI */ };
const diff = abiUtils.diff(oldAbi, newAbi);
console.log(`ABI changes: +${diff.plus} -${diff.minus}`);

UI Classes

User interface classes for different output formats and environments.

/**
 * Base UI class for coverage output formatting
 */
const UI = require('solidity-coverage/lib/ui');

class UI {
  /**
   * Creates a new UI instance
   * @param log - Optional logging function
   */
  constructor(log?: (message: string) => void);
  
  /**
   * Reports a message using the specified kind and arguments
   * @param kind - Message type/template identifier
   * @param args - Arguments for message formatting (optional)
   */
  report(kind: string, args?: string[]): void;
  
  /**
   * Generates a formatted message string
   * @param kind - Message type/template identifier  
   * @param args - Arguments for message formatting (optional)
   * @returns Formatted message string
   */
  generate(kind: string, args?: string[]): string;
}

/**
 * Application-specific UI class with enhanced formatting
 */
class AppUI extends UI {
  constructor(log?: (message: string) => void);
  report(kind: string, args?: string[]): void;
  generate(kind: string, args?: string[]): string;
}

/**
 * Plugin-specific UI class for Hardhat integration
 */
class PluginUI extends UI {
  constructor(log?: (message: string) => void);
  
  flags: {
    testfiles: string;      // Test files flag description
    testMatrix: string;     // Test matrix flag description
    abi: string;           // ABI flag description
    solcoverjs: string;    // Config file flag description
    temp: string;          // Temp directory flag description
  };
}

Usage Examples:

const { UI, AppUI, PluginUI } = require('solidity-coverage/lib/ui');

// Basic UI usage
const ui = new UI(console.log);
ui.report('coverage-starts');

// Plugin UI with command flags
const pluginUI = new PluginUI();
console.log('Available flags:', pluginUI.flags);

Integration Patterns

Complete Workflow Example

const API = require('solidity-coverage/api');
const Instrumenter = require('solidity-coverage/lib/instrumenter');
const Coverage = require('solidity-coverage/lib/coverage');
const DataCollector = require('solidity-coverage/lib/collector');

async function runCoverageAnalysis() {
  // Initialize components
  const instrumenter = new Instrumenter({ measureStatementCoverage: true });
  const coverage = new Coverage();
  
  // Instrument contracts
  const targets = [{ source: contractSource, canonicalPath: '/contracts/Token.sol' }];
  const instrumented = targets.map(target => ({
    ...target,
    ...instrumenter.instrument(target.source, target.canonicalPath)
  }));
  
  // Add contracts to coverage tracking
  instrumented.forEach(target => {
    coverage.addContract(target, target.canonicalPath);
  });
  
  // Set up data collection
  const collector = new DataCollector(api.getInstrumentationData());
  provider._node._vm.evm.events.on('step', collector.step.bind(collector));
  
  // Run tests (instrumented contracts will be executed)
  // ... test execution ...
  
  // Generate coverage reports
  coverage.generate(collector.data);
}

This comprehensive core library documentation covers all the fundamental classes that developers may need to access when building custom coverage solutions or integrating with solidity-coverage at a lower level than the high-level API.

Install with Tessl CLI

npx tessl i tessl/npm-solidity-coverage

docs

core-library.md

hardhat-plugin.md

index.md

programmatic-api.md

utility-functions.md

tile.json