CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-solidity-coverage

Code coverage for Solidity testing

Pending
Overview
Eval results
Files

utility-functions.mddocs/

Utility Functions

Helper functions for common coverage-related tasks including file discovery, configuration loading, temporary directory management, and Hardhat integration. These utilities are used internally by the plugin but can be useful for custom workflows.

Capabilities

File Discovery and Assembly

Functions for discovering and organizing contract files for instrumentation.

/**
 * Discovers and assembles contract files for instrumentation
 * Handles both single files and directory structures
 * @param config - Configuration object containing contracts directory
 * @param skipFiles - Array of file patterns to exclude from instrumentation
 * @returns Object containing targets to instrument and skipped files
 */
function assembleFiles(config: Config, skipFiles?: string[]): FileAssembly;

interface FileAssembly {
  targets: FileTarget[];    // Files to be instrumented
  skipped: FileTarget[];    // Files excluded from instrumentation
}

interface FileTarget {
  canonicalPath: string;    // Absolute path to file
  relativePath: string;     // Relative path from contracts directory
  source: string;           // File source code content
}

interface Config {
  contractsDir: string;     // Path to contracts directory
  workingDir: string;       // Project working directory
  logger?: {
    log: (message: string) => void;
  };
}

Usage Examples:

const utils = require('solidity-coverage/utils');

// Discover all contract files
const config = {
  contractsDir: './contracts',
  workingDir: process.cwd()
};

const { targets, skipped } = utils.assembleFiles(config, ['contracts/mocks/']);

console.log(`Found ${targets.length} contracts to instrument`);
console.log(`Skipped ${skipped.length} contracts`);

Target Assembly and Filtering

Lower-level functions for organizing contract targets.

/**
 * Filters contract targets and creates structured file objects
 * Separates files to instrument from files to skip
 * @param config - Configuration object
 * @param targets - Array of contract file paths
 * @param skipFiles - Array of file patterns to exclude
 * @returns Object with filtered targets and skipped files
 */
function assembleTargets(config: Config, targets?: string[], skipFiles?: string[]): FileAssembly;

/**
 * Processes skipFiles configuration including folder patterns
 * Expands folder patterns to include all files within
 * @param config - Configuration object
 * @param targets - Array of all discovered contract files
 * @param skipFiles - Array of file/folder patterns to skip
 * @returns Array of absolute paths to skip
 */
function assembleSkipped(config: Config, targets: string[], skipFiles?: string[]): string[];

Usage Examples:

// Manual target assembly
const contractPaths = [
  '/project/contracts/Token.sol',
  '/project/contracts/Crowdsale.sol',
  '/project/contracts/test/TestToken.sol'
];

const skipPatterns = ['contracts/test/'];
const skippedPaths = utils.assembleSkipped(config, contractPaths, skipPatterns);

const { targets, skipped } = utils.assembleTargets(config, contractPaths, skippedPaths);

Configuration Loading

Functions for loading and validating coverage configuration.

/**
 * Loads and validates .solcover.js configuration file
 * Merges with base configuration and applies sensible defaults
 * @param config - Base configuration object (optional)
 * @returns Merged coverage configuration object
 */
function loadSolcoverJS(config?: Config): CoverageConfig;

interface CoverageConfig {
  // File and directory settings
  skipFiles?: string[];                   // Files/folders to exclude
  cwd: string;                           // Working directory
  originalContractsDir: string;          // Original contracts directory
  
  // Report settings
  istanbulReporter?: string[];           // Report formats
  istanbulFolder?: string;               // Output directory
  
  // Coverage measurement toggles
  measureStatementCoverage?: boolean;    // Statement coverage
  measureFunctionCoverage?: boolean;     // Function coverage
  measureModifierCoverage?: boolean;     // Modifier coverage
  measureLineCoverage?: boolean;         // Line coverage
  measureBranchCoverage?: boolean;       // Branch coverage
  modifierWhitelist?: string[];          // Specific modifiers to measure
  
  // Compilation settings
  viaIR?: boolean;                       // viaIR compilation mode
  usingSolcV4?: boolean;                 // Solidity v0.4.x compatibility
  configureYulOptimizer?: boolean;       // Yul optimizer configuration
  solcOptimizerDetails?: object;         // Custom optimizer settings
  
  // Workflow hooks
  onServerReady?: (config: Config) => void;
  onCompileComplete?: (config: Config) => void;
  onTestsComplete?: (config: Config) => void;
  onIstanbulComplete?: (config: Config) => void;
  onPreCompile?: (config: Config) => void;
  
  // Test configuration
  mocha?: object;                        // Mocha configuration
  
  // Logging
  log: (message: string) => void;        // Logging function
}

Usage Examples:

// Load default configuration
const config = utils.loadSolcoverJS();

// Load configuration with custom file
const customConfig = utils.loadSolcoverJS({
  solcoverjs: '.solcover.custom.js',
  workingDir: process.cwd()
});

// Example .solcover.js file:
module.exports = {
  skipFiles: ['contracts/mocks/', 'contracts/test/'],
  istanbulReporter: ['html', 'lcov', 'text'],
  measureStatementCoverage: true,
  measureFunctionCoverage: true,
  onTestsComplete: () => console.log('Tests finished')
};

File I/O Operations

Functions for reading source files and managing temporary directories.

/**
 * Loads Solidity source code from file path
 * @param filePath - Absolute path to source file
 * @returns String containing source code
 */
function loadSource(filePath: string): string;

/**
 * Sets up temporary directories for instrumented contracts and artifacts
 * Creates directories and cleans up any existing temporary files
 * @param config - Configuration object
 * @param tempContractsDir - Path for temporary instrumented contracts
 * @param tempArtifactsDir - Path for temporary compilation artifacts
 */
function setupTempFolders(config: Config, tempContractsDir: string, tempArtifactsDir: string): void;

/**
 * Saves instrumented contract files to temporary directory
 * Preserves directory structure from original contracts
 * @param targets - Array of instrumented contract objects
 * @param originalDir - Original contracts directory path
 * @param tempDir - Temporary contracts directory path
 */
function save(targets: InstrumentedTarget[], originalDir: string, tempDir: string): void;

Usage Examples:

const fs = require('fs');
const path = require('path');

// Load source file
const contractSource = utils.loadSource('/project/contracts/Token.sol');

// Setup temporary directories
const tempContractsDir = path.join(process.cwd(), '.coverage_contracts');
const tempArtifactsDir = path.join(process.cwd(), '.coverage_artifacts');
utils.setupTempFolders(config, tempContractsDir, tempArtifactsDir);

// Save instrumented contracts
utils.save(instrumentedTargets, config.contractsDir, tempContractsDir);

Directory Management

Functions for managing temporary directories and cleanup.

/**
 * Generates canonical temporary directory paths
 * Creates consistent naming for contracts and artifacts directories
 * @param config - Configuration object
 * @returns Object with temporary directory paths
 */
function getTempLocations(config: Config): TempLocations;

interface TempLocations {
  tempContractsDir: string;    // Path for temporary instrumented contracts
  tempArtifactsDir: string;    // Path for temporary compilation artifacts
}

/**
 * Validates contract sources exist and cleans up temporary directories
 * Removes any existing temporary files before starting
 * @param config - Configuration object
 * @param tempContractsDir - Temporary contracts directory
 * @param tempArtifactsDir - Temporary artifacts directory
 */
function checkContext(config: Config, tempContractsDir: string, tempArtifactsDir: string): void;

/**
 * Cleanup function removing temporary directories and calling API finish
 * Should be called after coverage analysis completes
 * @param config - Configuration object
 * @param api - API instance (optional)
 * @returns Promise that resolves when cleanup is complete
 */
function finish(config: Config, api?: API): Promise<void>;

Usage Examples:

// Get temporary directory paths
const { tempContractsDir, tempArtifactsDir } = utils.getTempLocations(config);

// Validate and clean up before starting
utils.checkContext(config, tempContractsDir, tempArtifactsDir);

// ... run coverage analysis ...

// Clean up after completion
await utils.finish(config, api);

Path Utilities

Functions for working with file paths.

/**
 * Converts absolute file path to relative path
 * @param pathToFile - Absolute path to file
 * @param pathToParent - Absolute path to parent directory
 * @returns Relative path from parent to file
 */
function toRelativePath(pathToFile: string, pathToParent: string): string;

Usage Examples:

const absolutePath = '/project/contracts/token/ERC20.sol';
const contractsDir = '/project/contracts';

const relativePath = utils.toRelativePath(absolutePath, contractsDir);
// Result: 'token/ERC20.sol'

UI and Reporting

Functions for displaying coverage information.

/**
 * Displays list of skipped contracts via console output
 * Shows which files were excluded from coverage analysis
 * @param config - Configuration object
 * @param skipped - Array of skipped file objects (optional)
 */
function reportSkipped(config: Config, skipped?: FileTarget[]): void;

Usage Examples:

// Report which files were skipped
const { targets, skipped } = utils.assembleFiles(config, ['contracts/mocks/']);
utils.reportSkipped(config, skipped);

// Console output:
// > Skipping instrumentation of:
// > contracts/mocks/MockToken.sol
// > contracts/mocks/MockCrowdsale.sol

Hardhat Integration

Functions for working with Hardhat providers and networks.

/**
 * Gets account addresses from Hardhat network provider
 * @param provider - Hardhat network provider instance
 * @returns Promise resolving to array of account addresses
 */
function getAccountsHardhat(provider: HardhatProvider): Promise<string[]>;

/**
 * Gets node version information from Hardhat provider
 * @param provider - Hardhat network provider instance
 * @returns Promise resolving to version string
 */
function getNodeInfoHardhat(provider: HardhatProvider): Promise<string>;

interface HardhatProvider {
  send(method: string, params: any[]): Promise<any>;
}

Plugin Utilities

Internal utility functions used by the Hardhat plugin.

/**
 * Parses test file paths from command line arguments
 * @param files - File path string or glob pattern
 * @returns Array of resolved test file paths
 */
function getTestFilePaths(files: string): string[];

/**
 * Normalizes Hardhat configuration for coverage runs
 * @param config - Hardhat configuration object
 * @param args - Command line arguments (optional)
 * @returns Normalized configuration
 */
function normalizeConfig(config: HardhatConfig, args?: object): HardhatConfig;

/**
 * Checks if the Solidity configuration is using viaIR compilation
 * @param solidity - Solidity configuration object
 * @returns True if viaIR is enabled
 */
function isUsingViaIR(solidity: object): boolean;

/**
 * Checks if the project is using Solidity v0.4.x
 * @param solidity - Solidity configuration object
 * @returns True if using Solidity v0.4.x
 */
function isUsingSolcV4(solidity: object): boolean;

/**
 * Sets up Hardhat network configuration for coverage
 * @param env - Hardhat environment
 * @param api - API instance
 * @param ui - UI instance
 * @returns Promise resolving to provider
 */
function setupHardhatNetwork(env: any, api: API, ui: any): Promise<any>;

Usage Examples:

const { ethers } = require('hardhat');

// Get available accounts
const accounts = await utils.getAccountsHardhat(ethers.provider);
console.log(`Found ${accounts.length} accounts`);

// Get node information
const nodeInfo = await utils.getNodeInfoHardhat(ethers.provider);
console.log(`Node version: ${nodeInfo}`);

Error Handling

The utility functions provide error handling for common issues:

/**
 * Common error scenarios handled by utilities:
 * - Missing contracts directory
 * - Invalid .solcover.js configuration syntax
 * - File system permission errors
 * - Invalid file paths or patterns
 * - Temporary directory creation failures
 */

// Example error handling
try {
  const config = utils.loadSolcoverJS();
} catch (error) {
  if (error.message.includes('solcoverjs-fail')) {
    console.error('Invalid .solcover.js configuration:', error.message);
  }
}

Complete Workflow Example:

const utils = require('solidity-coverage/utils');
const API = require('solidity-coverage/api');

async function runCustomCoverage() {
  try {
    // Load configuration
    const config = utils.loadSolcoverJS();
    
    // Initialize API
    const api = new API(config);
    
    // Discover contract files
    const { targets, skipped } = utils.assembleFiles(config);
    utils.reportSkipped(config, skipped);
    
    // Setup temporary directories
    const { tempContractsDir, tempArtifactsDir } = utils.getTempLocations(config);
    utils.setupTempFolders(config, tempContractsDir, tempArtifactsDir);
    
    // Instrument contracts
    const instrumented = api.instrument(targets);
    utils.save(instrumented, config.contractsDir, tempContractsDir);
    
    // ... compile and run tests ...
    
    // Generate reports
    await api.report();
    
    // Clean up
    await utils.finish(config, api);
    
  } catch (error) {
    console.error('Coverage failed:', error.message);
    process.exit(1);
  }
}

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