0
# Utility Functions
1
2
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.
3
4
## Capabilities
5
6
### File Discovery and Assembly
7
8
Functions for discovering and organizing contract files for instrumentation.
9
10
```javascript { .api }
11
/**
12
* Discovers and assembles contract files for instrumentation
13
* Handles both single files and directory structures
14
* @param config - Configuration object containing contracts directory
15
* @param skipFiles - Array of file patterns to exclude from instrumentation
16
* @returns Object containing targets to instrument and skipped files
17
*/
18
function assembleFiles(config: Config, skipFiles?: string[]): FileAssembly;
19
20
interface FileAssembly {
21
targets: FileTarget[]; // Files to be instrumented
22
skipped: FileTarget[]; // Files excluded from instrumentation
23
}
24
25
interface FileTarget {
26
canonicalPath: string; // Absolute path to file
27
relativePath: string; // Relative path from contracts directory
28
source: string; // File source code content
29
}
30
31
interface Config {
32
contractsDir: string; // Path to contracts directory
33
workingDir: string; // Project working directory
34
logger?: {
35
log: (message: string) => void;
36
};
37
}
38
```
39
40
**Usage Examples:**
41
42
```javascript
43
const utils = require('solidity-coverage/utils');
44
45
// Discover all contract files
46
const config = {
47
contractsDir: './contracts',
48
workingDir: process.cwd()
49
};
50
51
const { targets, skipped } = utils.assembleFiles(config, ['contracts/mocks/']);
52
53
console.log(`Found ${targets.length} contracts to instrument`);
54
console.log(`Skipped ${skipped.length} contracts`);
55
```
56
57
### Target Assembly and Filtering
58
59
Lower-level functions for organizing contract targets.
60
61
```javascript { .api }
62
/**
63
* Filters contract targets and creates structured file objects
64
* Separates files to instrument from files to skip
65
* @param config - Configuration object
66
* @param targets - Array of contract file paths
67
* @param skipFiles - Array of file patterns to exclude
68
* @returns Object with filtered targets and skipped files
69
*/
70
function assembleTargets(config: Config, targets?: string[], skipFiles?: string[]): FileAssembly;
71
72
/**
73
* Processes skipFiles configuration including folder patterns
74
* Expands folder patterns to include all files within
75
* @param config - Configuration object
76
* @param targets - Array of all discovered contract files
77
* @param skipFiles - Array of file/folder patterns to skip
78
* @returns Array of absolute paths to skip
79
*/
80
function assembleSkipped(config: Config, targets: string[], skipFiles?: string[]): string[];
81
```
82
83
**Usage Examples:**
84
85
```javascript
86
// Manual target assembly
87
const contractPaths = [
88
'/project/contracts/Token.sol',
89
'/project/contracts/Crowdsale.sol',
90
'/project/contracts/test/TestToken.sol'
91
];
92
93
const skipPatterns = ['contracts/test/'];
94
const skippedPaths = utils.assembleSkipped(config, contractPaths, skipPatterns);
95
96
const { targets, skipped } = utils.assembleTargets(config, contractPaths, skippedPaths);
97
```
98
99
### Configuration Loading
100
101
Functions for loading and validating coverage configuration.
102
103
```javascript { .api }
104
/**
105
* Loads and validates .solcover.js configuration file
106
* Merges with base configuration and applies sensible defaults
107
* @param config - Base configuration object (optional)
108
* @returns Merged coverage configuration object
109
*/
110
function loadSolcoverJS(config?: Config): CoverageConfig;
111
112
interface CoverageConfig {
113
// File and directory settings
114
skipFiles?: string[]; // Files/folders to exclude
115
cwd: string; // Working directory
116
originalContractsDir: string; // Original contracts directory
117
118
// Report settings
119
istanbulReporter?: string[]; // Report formats
120
istanbulFolder?: string; // Output directory
121
122
// Coverage measurement toggles
123
measureStatementCoverage?: boolean; // Statement coverage
124
measureFunctionCoverage?: boolean; // Function coverage
125
measureModifierCoverage?: boolean; // Modifier coverage
126
measureLineCoverage?: boolean; // Line coverage
127
measureBranchCoverage?: boolean; // Branch coverage
128
modifierWhitelist?: string[]; // Specific modifiers to measure
129
130
// Compilation settings
131
viaIR?: boolean; // viaIR compilation mode
132
usingSolcV4?: boolean; // Solidity v0.4.x compatibility
133
configureYulOptimizer?: boolean; // Yul optimizer configuration
134
solcOptimizerDetails?: object; // Custom optimizer settings
135
136
// Workflow hooks
137
onServerReady?: (config: Config) => void;
138
onCompileComplete?: (config: Config) => void;
139
onTestsComplete?: (config: Config) => void;
140
onIstanbulComplete?: (config: Config) => void;
141
onPreCompile?: (config: Config) => void;
142
143
// Test configuration
144
mocha?: object; // Mocha configuration
145
146
// Logging
147
log: (message: string) => void; // Logging function
148
}
149
```
150
151
**Usage Examples:**
152
153
```javascript
154
// Load default configuration
155
const config = utils.loadSolcoverJS();
156
157
// Load configuration with custom file
158
const customConfig = utils.loadSolcoverJS({
159
solcoverjs: '.solcover.custom.js',
160
workingDir: process.cwd()
161
});
162
163
// Example .solcover.js file:
164
module.exports = {
165
skipFiles: ['contracts/mocks/', 'contracts/test/'],
166
istanbulReporter: ['html', 'lcov', 'text'],
167
measureStatementCoverage: true,
168
measureFunctionCoverage: true,
169
onTestsComplete: () => console.log('Tests finished')
170
};
171
```
172
173
### File I/O Operations
174
175
Functions for reading source files and managing temporary directories.
176
177
```javascript { .api }
178
/**
179
* Loads Solidity source code from file path
180
* @param filePath - Absolute path to source file
181
* @returns String containing source code
182
*/
183
function loadSource(filePath: string): string;
184
185
/**
186
* Sets up temporary directories for instrumented contracts and artifacts
187
* Creates directories and cleans up any existing temporary files
188
* @param config - Configuration object
189
* @param tempContractsDir - Path for temporary instrumented contracts
190
* @param tempArtifactsDir - Path for temporary compilation artifacts
191
*/
192
function setupTempFolders(config: Config, tempContractsDir: string, tempArtifactsDir: string): void;
193
194
/**
195
* Saves instrumented contract files to temporary directory
196
* Preserves directory structure from original contracts
197
* @param targets - Array of instrumented contract objects
198
* @param originalDir - Original contracts directory path
199
* @param tempDir - Temporary contracts directory path
200
*/
201
function save(targets: InstrumentedTarget[], originalDir: string, tempDir: string): void;
202
```
203
204
**Usage Examples:**
205
206
```javascript
207
const fs = require('fs');
208
const path = require('path');
209
210
// Load source file
211
const contractSource = utils.loadSource('/project/contracts/Token.sol');
212
213
// Setup temporary directories
214
const tempContractsDir = path.join(process.cwd(), '.coverage_contracts');
215
const tempArtifactsDir = path.join(process.cwd(), '.coverage_artifacts');
216
utils.setupTempFolders(config, tempContractsDir, tempArtifactsDir);
217
218
// Save instrumented contracts
219
utils.save(instrumentedTargets, config.contractsDir, tempContractsDir);
220
```
221
222
### Directory Management
223
224
Functions for managing temporary directories and cleanup.
225
226
```javascript { .api }
227
/**
228
* Generates canonical temporary directory paths
229
* Creates consistent naming for contracts and artifacts directories
230
* @param config - Configuration object
231
* @returns Object with temporary directory paths
232
*/
233
function getTempLocations(config: Config): TempLocations;
234
235
interface TempLocations {
236
tempContractsDir: string; // Path for temporary instrumented contracts
237
tempArtifactsDir: string; // Path for temporary compilation artifacts
238
}
239
240
/**
241
* Validates contract sources exist and cleans up temporary directories
242
* Removes any existing temporary files before starting
243
* @param config - Configuration object
244
* @param tempContractsDir - Temporary contracts directory
245
* @param tempArtifactsDir - Temporary artifacts directory
246
*/
247
function checkContext(config: Config, tempContractsDir: string, tempArtifactsDir: string): void;
248
249
/**
250
* Cleanup function removing temporary directories and calling API finish
251
* Should be called after coverage analysis completes
252
* @param config - Configuration object
253
* @param api - API instance (optional)
254
* @returns Promise that resolves when cleanup is complete
255
*/
256
function finish(config: Config, api?: API): Promise<void>;
257
```
258
259
**Usage Examples:**
260
261
```javascript
262
// Get temporary directory paths
263
const { tempContractsDir, tempArtifactsDir } = utils.getTempLocations(config);
264
265
// Validate and clean up before starting
266
utils.checkContext(config, tempContractsDir, tempArtifactsDir);
267
268
// ... run coverage analysis ...
269
270
// Clean up after completion
271
await utils.finish(config, api);
272
```
273
274
### Path Utilities
275
276
Functions for working with file paths.
277
278
```javascript { .api }
279
/**
280
* Converts absolute file path to relative path
281
* @param pathToFile - Absolute path to file
282
* @param pathToParent - Absolute path to parent directory
283
* @returns Relative path from parent to file
284
*/
285
function toRelativePath(pathToFile: string, pathToParent: string): string;
286
```
287
288
**Usage Examples:**
289
290
```javascript
291
const absolutePath = '/project/contracts/token/ERC20.sol';
292
const contractsDir = '/project/contracts';
293
294
const relativePath = utils.toRelativePath(absolutePath, contractsDir);
295
// Result: 'token/ERC20.sol'
296
```
297
298
### UI and Reporting
299
300
Functions for displaying coverage information.
301
302
```javascript { .api }
303
/**
304
* Displays list of skipped contracts via console output
305
* Shows which files were excluded from coverage analysis
306
* @param config - Configuration object
307
* @param skipped - Array of skipped file objects (optional)
308
*/
309
function reportSkipped(config: Config, skipped?: FileTarget[]): void;
310
```
311
312
**Usage Examples:**
313
314
```javascript
315
// Report which files were skipped
316
const { targets, skipped } = utils.assembleFiles(config, ['contracts/mocks/']);
317
utils.reportSkipped(config, skipped);
318
319
// Console output:
320
// > Skipping instrumentation of:
321
// > contracts/mocks/MockToken.sol
322
// > contracts/mocks/MockCrowdsale.sol
323
```
324
325
### Hardhat Integration
326
327
Functions for working with Hardhat providers and networks.
328
329
```javascript { .api }
330
/**
331
* Gets account addresses from Hardhat network provider
332
* @param provider - Hardhat network provider instance
333
* @returns Promise resolving to array of account addresses
334
*/
335
function getAccountsHardhat(provider: HardhatProvider): Promise<string[]>;
336
337
/**
338
* Gets node version information from Hardhat provider
339
* @param provider - Hardhat network provider instance
340
* @returns Promise resolving to version string
341
*/
342
function getNodeInfoHardhat(provider: HardhatProvider): Promise<string>;
343
344
interface HardhatProvider {
345
send(method: string, params: any[]): Promise<any>;
346
}
347
```
348
349
### Plugin Utilities
350
351
Internal utility functions used by the Hardhat plugin.
352
353
```javascript { .api }
354
/**
355
* Parses test file paths from command line arguments
356
* @param files - File path string or glob pattern
357
* @returns Array of resolved test file paths
358
*/
359
function getTestFilePaths(files: string): string[];
360
361
/**
362
* Normalizes Hardhat configuration for coverage runs
363
* @param config - Hardhat configuration object
364
* @param args - Command line arguments (optional)
365
* @returns Normalized configuration
366
*/
367
function normalizeConfig(config: HardhatConfig, args?: object): HardhatConfig;
368
369
/**
370
* Checks if the Solidity configuration is using viaIR compilation
371
* @param solidity - Solidity configuration object
372
* @returns True if viaIR is enabled
373
*/
374
function isUsingViaIR(solidity: object): boolean;
375
376
/**
377
* Checks if the project is using Solidity v0.4.x
378
* @param solidity - Solidity configuration object
379
* @returns True if using Solidity v0.4.x
380
*/
381
function isUsingSolcV4(solidity: object): boolean;
382
383
/**
384
* Sets up Hardhat network configuration for coverage
385
* @param env - Hardhat environment
386
* @param api - API instance
387
* @param ui - UI instance
388
* @returns Promise resolving to provider
389
*/
390
function setupHardhatNetwork(env: any, api: API, ui: any): Promise<any>;
391
```
392
393
**Usage Examples:**
394
395
```javascript
396
const { ethers } = require('hardhat');
397
398
// Get available accounts
399
const accounts = await utils.getAccountsHardhat(ethers.provider);
400
console.log(`Found ${accounts.length} accounts`);
401
402
// Get node information
403
const nodeInfo = await utils.getNodeInfoHardhat(ethers.provider);
404
console.log(`Node version: ${nodeInfo}`);
405
```
406
407
### Error Handling
408
409
The utility functions provide error handling for common issues:
410
411
```javascript { .api }
412
/**
413
* Common error scenarios handled by utilities:
414
* - Missing contracts directory
415
* - Invalid .solcover.js configuration syntax
416
* - File system permission errors
417
* - Invalid file paths or patterns
418
* - Temporary directory creation failures
419
*/
420
421
// Example error handling
422
try {
423
const config = utils.loadSolcoverJS();
424
} catch (error) {
425
if (error.message.includes('solcoverjs-fail')) {
426
console.error('Invalid .solcover.js configuration:', error.message);
427
}
428
}
429
```
430
431
**Complete Workflow Example:**
432
433
```javascript
434
const utils = require('solidity-coverage/utils');
435
const API = require('solidity-coverage/api');
436
437
async function runCustomCoverage() {
438
try {
439
// Load configuration
440
const config = utils.loadSolcoverJS();
441
442
// Initialize API
443
const api = new API(config);
444
445
// Discover contract files
446
const { targets, skipped } = utils.assembleFiles(config);
447
utils.reportSkipped(config, skipped);
448
449
// Setup temporary directories
450
const { tempContractsDir, tempArtifactsDir } = utils.getTempLocations(config);
451
utils.setupTempFolders(config, tempContractsDir, tempArtifactsDir);
452
453
// Instrument contracts
454
const instrumented = api.instrument(targets);
455
utils.save(instrumented, config.contractsDir, tempContractsDir);
456
457
// ... compile and run tests ...
458
459
// Generate reports
460
await api.report();
461
462
// Clean up
463
await utils.finish(config, api);
464
465
} catch (error) {
466
console.error('Coverage failed:', error.message);
467
process.exit(1);
468
}
469
}
470
```