@diamondslab/diamonds-hardhat-foundry 2.2.3 โ 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -1
- package/dist/framework/ForgeCoverageFramework.d.ts +70 -0
- package/dist/framework/ForgeCoverageFramework.d.ts.map +1 -0
- package/dist/framework/ForgeCoverageFramework.js +306 -0
- package/dist/framework/ForgeCoverageFramework.js.map +1 -0
- package/dist/framework/ForgeCoverageFramework.old.d.ts +61 -0
- package/dist/framework/ForgeCoverageFramework.old.d.ts.map +1 -0
- package/dist/framework/ForgeCoverageFramework.old.js +238 -0
- package/dist/framework/ForgeCoverageFramework.old.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/tasks/coverage.d.ts +2 -0
- package/dist/tasks/coverage.d.ts.map +1 -0
- package/dist/tasks/coverage.js +154 -0
- package/dist/tasks/coverage.js.map +1 -0
- package/dist/tasks/coverage.old.d.ts +2 -0
- package/dist/tasks/coverage.old.d.ts.map +1 -0
- package/dist/tasks/coverage.old.js +173 -0
- package/dist/tasks/coverage.old.js.map +1 -0
- package/dist/types/config.d.ts +91 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js.map +1 -1
- package/package.json +3 -3
- package/src/framework/ForgeCoverageFramework.ts +390 -0
- package/src/index.ts +7 -6
- package/src/tasks/coverage.ts +258 -0
- package/src/types/config.ts +107 -0
- package/CHANGELOG.md +0 -321
package/README.md
CHANGED
|
@@ -14,7 +14,8 @@ Hardhat plugin that seamlessly integrates Foundry testing with [ERC-2535 Diamond
|
|
|
14
14
|
- ๐ **Automated Diamond Deployment** - Deploy Diamond contracts with a single command
|
|
15
15
|
- ๐ **Helper Generation** - Automatically generate Solidity helpers with deployment data
|
|
16
16
|
- ๐งช **Test Scaffolding** - Create unit, integration, and fuzz test templates
|
|
17
|
-
-
|
|
17
|
+
- ๏ฟฝ **Coverage Testing** - Run forge coverage with full Diamond integration and multiple report formats
|
|
18
|
+
- ๐ง **Hardhat Tasks** - CLI tasks for init, deploy, generate, test, and coverage workflows
|
|
18
19
|
- ๐ฏ **Programmatic API** - Use framework classes directly in scripts
|
|
19
20
|
- ๐ **Base Contracts** - Reusable Solidity utilities and test base classes
|
|
20
21
|
- โก **Foundry Integration** - Leverage Forge's speed and fuzzing capabilities
|
|
@@ -342,6 +343,80 @@ npx hardhat diamonds-forge:test --match-test "testOwnership" --verbosity 4
|
|
|
342
343
|
npx hardhat diamonds-forge:test --skip-deployment --match-contract "MyTest"
|
|
343
344
|
```
|
|
344
345
|
|
|
346
|
+
### `diamonds-forge:coverage`
|
|
347
|
+
|
|
348
|
+
Run forge coverage for your Diamond contracts with full integration support.
|
|
349
|
+
|
|
350
|
+
**Important:** Coverage requires a deployed Diamond on a persistent network (like localhost). See workflow below.
|
|
351
|
+
|
|
352
|
+
**Options:**
|
|
353
|
+
|
|
354
|
+
- `--diamond-name <name>` - Diamond to analyze (default: from config)
|
|
355
|
+
- `--network <name>` - Network for deployment (default: from config)
|
|
356
|
+
- `--report <format>` - Report format: summary, lcov, debug, bytecode (default: summary)
|
|
357
|
+
- `--report-file <path>` - Output file for coverage report
|
|
358
|
+
- `--lcov-version <version>` - LCOV version for LCOV reports (default: v1)
|
|
359
|
+
- `--match-test <pattern>` - Run tests matching pattern
|
|
360
|
+
- `--match-contract <pattern>` - Run tests in matching contracts
|
|
361
|
+
- `--match-path <glob>` - Run tests in files matching glob
|
|
362
|
+
- `--no-match-test <pattern>` - Skip tests matching pattern
|
|
363
|
+
- `--no-match-contract <pattern>` - Skip tests in matching contracts
|
|
364
|
+
- `--no-match-path <glob>` - Skip tests in files matching glob
|
|
365
|
+
- `--no-match-coverage <pattern>` - Exclude contracts from coverage
|
|
366
|
+
- `--verbosity <level>` - Verbosity level: 0-5 (default: 0)
|
|
367
|
+
- `--color <mode>` - Color output: auto, always, never (default: auto)
|
|
368
|
+
- And many more options for filtering, optimization, and EVM configuration
|
|
369
|
+
|
|
370
|
+
**Workflow (Required):**
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
# Step 1: Start Hardhat node (persistent network)
|
|
374
|
+
npx hardhat node
|
|
375
|
+
|
|
376
|
+
# Step 2: Deploy Diamond to localhost network (in another terminal)
|
|
377
|
+
npx hardhat diamonds-forge:deploy --diamond-name MyDiamond --network localhost
|
|
378
|
+
|
|
379
|
+
# Step 3: Run coverage against deployed Diamond
|
|
380
|
+
npx hardhat diamonds-forge:coverage --diamond-name MyDiamond --network localhost
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
**Examples:**
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
# Basic coverage with default summary
|
|
387
|
+
npx hardhat diamonds-forge:coverage --diamond-name MyDiamond --network localhost
|
|
388
|
+
|
|
389
|
+
# Generate LCOV report for CI/CD
|
|
390
|
+
npx hardhat diamonds-forge:coverage \
|
|
391
|
+
--diamond-name MyDiamond \
|
|
392
|
+
--network localhost \
|
|
393
|
+
--report lcov \
|
|
394
|
+
--report-file coverage/lcov.info
|
|
395
|
+
|
|
396
|
+
# Coverage for specific test patterns
|
|
397
|
+
npx hardhat diamonds-forge:coverage \
|
|
398
|
+
--diamond-name MyDiamond \
|
|
399
|
+
--network localhost \
|
|
400
|
+
--match-contract "Unit" \
|
|
401
|
+
--verbosity 2
|
|
402
|
+
|
|
403
|
+
# Multiple report formats
|
|
404
|
+
npx hardhat diamonds-forge:coverage \
|
|
405
|
+
--diamond-name MyDiamond \
|
|
406
|
+
--network localhost \
|
|
407
|
+
--report summary \
|
|
408
|
+
--report lcov \
|
|
409
|
+
--report debug
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
**Important Notes:**
|
|
413
|
+
- Always specify `--network localhost` (coverage needs deployed contracts)
|
|
414
|
+
- Cannot use `--network hardhat` (ephemeral in-memory network)
|
|
415
|
+
- Diamond must be deployed before running coverage
|
|
416
|
+
- Same workflow as `diamonds-forge:test` - both require persistent network
|
|
417
|
+
|
|
418
|
+
**See the [Coverage Guide](../../docs/FOUNDRY_FORGE_DIAMONDS_COVERAGE.md) for complete documentation, CI/CD integration examples, and best practices.**
|
|
419
|
+
|
|
345
420
|
## Dynamic Helper Generation
|
|
346
421
|
|
|
347
422
|
Version 2.0.0+ introduces **dynamic helper generation** that creates deployment-specific Solidity helpers without hardcoded addresses.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types";
|
|
2
|
+
import { CoverageOptions } from "../types/config";
|
|
3
|
+
/**
|
|
4
|
+
* ForgeCoverageFramework - Main orchestration class for Forge coverage with Diamonds
|
|
5
|
+
*
|
|
6
|
+
* Coordinates:
|
|
7
|
+
* 1. Diamond deployment via DeploymentManager
|
|
8
|
+
* 2. Helper generation via HelperGenerator
|
|
9
|
+
* 3. Forge coverage execution
|
|
10
|
+
*
|
|
11
|
+
* Mirrors ForgeFuzzingFramework design for consistency and code reuse
|
|
12
|
+
*/
|
|
13
|
+
export declare class ForgeCoverageFramework {
|
|
14
|
+
private hre;
|
|
15
|
+
private deploymentManager;
|
|
16
|
+
private helperGenerator;
|
|
17
|
+
constructor(hre: HardhatRuntimeEnvironment);
|
|
18
|
+
/**
|
|
19
|
+
* Run complete Forge coverage workflow
|
|
20
|
+
*
|
|
21
|
+
* Workflow:
|
|
22
|
+
* 1. Validate Foundry installation
|
|
23
|
+
* 2. Deploy or reuse Diamond
|
|
24
|
+
* 3. Generate Solidity helpers
|
|
25
|
+
* 4. Run forge coverage with options
|
|
26
|
+
*
|
|
27
|
+
* @param options - Coverage execution options
|
|
28
|
+
* @returns Promise<boolean> - true if coverage succeeds
|
|
29
|
+
*/
|
|
30
|
+
runCoverage(options?: CoverageOptions): Promise<boolean>;
|
|
31
|
+
/**
|
|
32
|
+
* Build complete forge coverage command arguments
|
|
33
|
+
*
|
|
34
|
+
* @param options - Coverage options
|
|
35
|
+
* @returns Array of command arguments
|
|
36
|
+
*/
|
|
37
|
+
private buildCoverageCommand;
|
|
38
|
+
/**
|
|
39
|
+
* Build report-related options
|
|
40
|
+
*/
|
|
41
|
+
private buildReportOptions;
|
|
42
|
+
/**
|
|
43
|
+
* Build test filtering options
|
|
44
|
+
*/
|
|
45
|
+
private buildFilterOptions;
|
|
46
|
+
/**
|
|
47
|
+
* Build display options
|
|
48
|
+
*/
|
|
49
|
+
private buildDisplayOptions;
|
|
50
|
+
/**
|
|
51
|
+
* Build test execution options
|
|
52
|
+
*/
|
|
53
|
+
private buildTestOptions;
|
|
54
|
+
/**
|
|
55
|
+
* Build EVM options
|
|
56
|
+
*/
|
|
57
|
+
private buildEvmOptions;
|
|
58
|
+
/**
|
|
59
|
+
* Build build options
|
|
60
|
+
*/
|
|
61
|
+
private buildBuildOptions;
|
|
62
|
+
/**
|
|
63
|
+
* Execute forge coverage command and stream output
|
|
64
|
+
*
|
|
65
|
+
* @param args - Command arguments
|
|
66
|
+
* @returns Promise<boolean> - true if command succeeds
|
|
67
|
+
*/
|
|
68
|
+
private executeForge;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=ForgeCoverageFramework.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ForgeCoverageFramework.d.ts","sourceRoot":"","sources":["../../src/framework/ForgeCoverageFramework.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAMlD;;;;;;;;;GASG;AACH,qBAAa,sBAAsB;IAIrB,OAAO,CAAC,GAAG;IAHvB,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,eAAe,CAAkB;gBAErB,GAAG,EAAE,yBAAyB;IAKlD;;;;;;;;;;;OAWG;IACG,WAAW,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IA+GlE;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAmB5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiC1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkC1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA0BxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAsBvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA0BzB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;CAsBrB"}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ForgeCoverageFramework = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const foundry_1 = require("../utils/foundry");
|
|
6
|
+
const logger_1 = require("../utils/logger");
|
|
7
|
+
const DeploymentManager_1 = require("./DeploymentManager");
|
|
8
|
+
const HelperGenerator_1 = require("./HelperGenerator");
|
|
9
|
+
/**
|
|
10
|
+
* ForgeCoverageFramework - Main orchestration class for Forge coverage with Diamonds
|
|
11
|
+
*
|
|
12
|
+
* Coordinates:
|
|
13
|
+
* 1. Diamond deployment via DeploymentManager
|
|
14
|
+
* 2. Helper generation via HelperGenerator
|
|
15
|
+
* 3. Forge coverage execution
|
|
16
|
+
*
|
|
17
|
+
* Mirrors ForgeFuzzingFramework design for consistency and code reuse
|
|
18
|
+
*/
|
|
19
|
+
class ForgeCoverageFramework {
|
|
20
|
+
hre;
|
|
21
|
+
deploymentManager;
|
|
22
|
+
helperGenerator;
|
|
23
|
+
constructor(hre) {
|
|
24
|
+
this.hre = hre;
|
|
25
|
+
this.deploymentManager = new DeploymentManager_1.DeploymentManager(hre);
|
|
26
|
+
this.helperGenerator = new HelperGenerator_1.HelperGenerator(hre);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Run complete Forge coverage workflow
|
|
30
|
+
*
|
|
31
|
+
* Workflow:
|
|
32
|
+
* 1. Validate Foundry installation
|
|
33
|
+
* 2. Deploy or reuse Diamond
|
|
34
|
+
* 3. Generate Solidity helpers
|
|
35
|
+
* 4. Run forge coverage with options
|
|
36
|
+
*
|
|
37
|
+
* @param options - Coverage execution options
|
|
38
|
+
* @returns Promise<boolean> - true if coverage succeeds
|
|
39
|
+
*/
|
|
40
|
+
async runCoverage(options = {}) {
|
|
41
|
+
const { diamondName = "ExampleDiamond", networkName = "hardhat", force = false, skipDeployment = false, skipHelpers = false, writeDeployedDiamondData = false, } = options;
|
|
42
|
+
logger_1.Logger.section("Running Forge Coverage with Diamond");
|
|
43
|
+
// Step 1: Validate Foundry
|
|
44
|
+
if (!(0, foundry_1.isFoundryInstalled)()) {
|
|
45
|
+
logger_1.Logger.error("Foundry is not installed. Please install it: https://book.getfoundry.sh/getting-started/installation");
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
// Step 2: Ensure Diamond deployment
|
|
50
|
+
if (!skipDeployment) {
|
|
51
|
+
logger_1.Logger.section("Step 1/3: Ensuring Diamond Deployment");
|
|
52
|
+
await this.deploymentManager.ensureDeployment(diamondName, networkName, force, writeDeployedDiamondData);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
logger_1.Logger.info("Skipping deployment (using existing)");
|
|
56
|
+
}
|
|
57
|
+
// Step 3: Generate helpers
|
|
58
|
+
if (!skipHelpers) {
|
|
59
|
+
logger_1.Logger.section("Step 2/3: Generating Solidity Helpers");
|
|
60
|
+
const deployment = await this.deploymentManager.getDeployment(diamondName, networkName);
|
|
61
|
+
if (!deployment) {
|
|
62
|
+
logger_1.Logger.warn("โ No deployment record found");
|
|
63
|
+
if (!skipDeployment) {
|
|
64
|
+
logger_1.Logger.info("โน Using cached deployment (ephemeral)");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
logger_1.Logger.info("Using deployment record");
|
|
69
|
+
}
|
|
70
|
+
const provider = this.hre.ethers.provider;
|
|
71
|
+
const network = await provider.getNetwork();
|
|
72
|
+
const chainId = Number(network.chainId);
|
|
73
|
+
const deploymentData = deployment
|
|
74
|
+
? deployment.getDeployedDiamondData()
|
|
75
|
+
: await this.deploymentManager
|
|
76
|
+
.ensureDeployment(diamondName, networkName, false, false)
|
|
77
|
+
.then((d) => d.getDeployedDiamondData());
|
|
78
|
+
await this.helperGenerator.generateDeploymentHelpers(diamondName, networkName, chainId, deploymentData, deployment || undefined);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
logger_1.Logger.info("Skipping helper generation");
|
|
82
|
+
}
|
|
83
|
+
// Step 4: Run coverage
|
|
84
|
+
logger_1.Logger.section("Step 3/3: Running Forge Coverage");
|
|
85
|
+
// Get fork URL for network (same pattern as ForgeFuzzingFramework)
|
|
86
|
+
const provider = this.hre.ethers.provider;
|
|
87
|
+
let forkUrl;
|
|
88
|
+
if (networkName !== "hardhat") {
|
|
89
|
+
forkUrl = provider.connection?.url || "http://127.0.0.1:8545";
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
forkUrl = "http://127.0.0.1:8545";
|
|
93
|
+
logger_1.Logger.warn("โ ๏ธ Network is \"hardhat\" - defaulting to localhost fork: http://127.0.0.1:8545");
|
|
94
|
+
logger_1.Logger.warn("๐ก Make sure Hardhat node is running: npx hardhat node");
|
|
95
|
+
logger_1.Logger.warn("๐ก Or specify network explicitly: --network localhost");
|
|
96
|
+
}
|
|
97
|
+
const args = this.buildCoverageCommand({ ...options, forkUrl });
|
|
98
|
+
logger_1.Logger.info(`Executing: forge coverage ${args.join(" ")}`);
|
|
99
|
+
logger_1.Logger.info("โณ Running coverage analysis (this may take a while)...");
|
|
100
|
+
const success = await this.executeForge(args);
|
|
101
|
+
if (success) {
|
|
102
|
+
logger_1.Logger.success("โ
Coverage analysis completed successfully");
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
logger_1.Logger.error("โ Coverage analysis failed");
|
|
106
|
+
}
|
|
107
|
+
return success;
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
logger_1.Logger.error(`Coverage execution failed: ${error.message}`);
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Build complete forge coverage command arguments
|
|
116
|
+
*
|
|
117
|
+
* @param options - Coverage options
|
|
118
|
+
* @returns Array of command arguments
|
|
119
|
+
*/
|
|
120
|
+
buildCoverageCommand(options) {
|
|
121
|
+
const args = [];
|
|
122
|
+
// Add fork URL if provided
|
|
123
|
+
if (options.forkUrl) {
|
|
124
|
+
args.push("--fork-url", options.forkUrl);
|
|
125
|
+
}
|
|
126
|
+
// Add all option groups
|
|
127
|
+
args.push(...this.buildReportOptions(options));
|
|
128
|
+
args.push(...this.buildFilterOptions(options));
|
|
129
|
+
args.push(...this.buildDisplayOptions(options));
|
|
130
|
+
args.push(...this.buildTestOptions(options));
|
|
131
|
+
args.push(...this.buildEvmOptions(options));
|
|
132
|
+
args.push(...this.buildBuildOptions(options));
|
|
133
|
+
return args.filter((arg) => arg !== "");
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Build report-related options
|
|
137
|
+
*/
|
|
138
|
+
buildReportOptions(options) {
|
|
139
|
+
const args = [];
|
|
140
|
+
// Multiple --report flags
|
|
141
|
+
if (options.report && options.report.length > 0) {
|
|
142
|
+
for (const reportType of options.report) {
|
|
143
|
+
args.push("--report", reportType);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (options.reportFile) {
|
|
147
|
+
args.push("--report-file", options.reportFile);
|
|
148
|
+
}
|
|
149
|
+
if (options.lcovVersion) {
|
|
150
|
+
args.push("--lcov-version", options.lcovVersion);
|
|
151
|
+
}
|
|
152
|
+
if (options.includeLibs) {
|
|
153
|
+
args.push("--include-libs");
|
|
154
|
+
}
|
|
155
|
+
if (options.excludeTests) {
|
|
156
|
+
args.push("--exclude-tests");
|
|
157
|
+
}
|
|
158
|
+
if (options.irMinimum) {
|
|
159
|
+
args.push("--ir-minimum");
|
|
160
|
+
}
|
|
161
|
+
return args;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Build test filtering options
|
|
165
|
+
*/
|
|
166
|
+
buildFilterOptions(options) {
|
|
167
|
+
const args = [];
|
|
168
|
+
if (options.matchTest) {
|
|
169
|
+
args.push("--match-test", options.matchTest);
|
|
170
|
+
}
|
|
171
|
+
if (options.noMatchTest) {
|
|
172
|
+
args.push("--no-match-test", options.noMatchTest);
|
|
173
|
+
}
|
|
174
|
+
if (options.matchContract) {
|
|
175
|
+
args.push("--match-contract", options.matchContract);
|
|
176
|
+
}
|
|
177
|
+
if (options.noMatchContract) {
|
|
178
|
+
args.push("--no-match-contract", options.noMatchContract);
|
|
179
|
+
}
|
|
180
|
+
if (options.matchPath) {
|
|
181
|
+
args.push("--match-path", options.matchPath);
|
|
182
|
+
}
|
|
183
|
+
if (options.noMatchPath) {
|
|
184
|
+
args.push("--no-match-path", options.noMatchPath);
|
|
185
|
+
}
|
|
186
|
+
if (options.noMatchCoverage) {
|
|
187
|
+
args.push("--no-match-coverage", options.noMatchCoverage);
|
|
188
|
+
}
|
|
189
|
+
return args;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Build display options
|
|
193
|
+
*/
|
|
194
|
+
buildDisplayOptions(options) {
|
|
195
|
+
const args = [];
|
|
196
|
+
// Verbosity (-v, -vv, -vvv, etc.)
|
|
197
|
+
if (options.verbosity && options.verbosity > 0) {
|
|
198
|
+
args.push("-" + "v".repeat(options.verbosity));
|
|
199
|
+
}
|
|
200
|
+
if (options.quiet) {
|
|
201
|
+
args.push("--quiet");
|
|
202
|
+
}
|
|
203
|
+
if (options.json) {
|
|
204
|
+
args.push("--json");
|
|
205
|
+
}
|
|
206
|
+
if (options.md) {
|
|
207
|
+
args.push("--md");
|
|
208
|
+
}
|
|
209
|
+
if (options.color) {
|
|
210
|
+
args.push("--color", options.color);
|
|
211
|
+
}
|
|
212
|
+
return args;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Build test execution options
|
|
216
|
+
*/
|
|
217
|
+
buildTestOptions(options) {
|
|
218
|
+
const args = [];
|
|
219
|
+
if (options.threads !== undefined) {
|
|
220
|
+
args.push("--threads", options.threads.toString());
|
|
221
|
+
}
|
|
222
|
+
if (options.fuzzRuns !== undefined) {
|
|
223
|
+
args.push("--fuzz-runs", options.fuzzRuns.toString());
|
|
224
|
+
}
|
|
225
|
+
if (options.fuzzSeed) {
|
|
226
|
+
args.push("--fuzz-seed", options.fuzzSeed);
|
|
227
|
+
}
|
|
228
|
+
if (options.failFast) {
|
|
229
|
+
args.push("--fail-fast");
|
|
230
|
+
}
|
|
231
|
+
if (options.allowFailure) {
|
|
232
|
+
args.push("--allow-failure");
|
|
233
|
+
}
|
|
234
|
+
return args;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Build EVM options
|
|
238
|
+
*/
|
|
239
|
+
buildEvmOptions(options) {
|
|
240
|
+
const args = [];
|
|
241
|
+
if (options.forkBlockNumber !== undefined) {
|
|
242
|
+
args.push("--fork-block-number", options.forkBlockNumber.toString());
|
|
243
|
+
}
|
|
244
|
+
if (options.initialBalance) {
|
|
245
|
+
args.push("--initial-balance", options.initialBalance);
|
|
246
|
+
}
|
|
247
|
+
if (options.sender) {
|
|
248
|
+
args.push("--sender", options.sender);
|
|
249
|
+
}
|
|
250
|
+
if (options.ffi) {
|
|
251
|
+
args.push("--ffi");
|
|
252
|
+
}
|
|
253
|
+
return args;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Build build options
|
|
257
|
+
*/
|
|
258
|
+
buildBuildOptions(options) {
|
|
259
|
+
const args = [];
|
|
260
|
+
if (options.force) {
|
|
261
|
+
args.push("--force");
|
|
262
|
+
}
|
|
263
|
+
if (options.noCache) {
|
|
264
|
+
args.push("--no-cache");
|
|
265
|
+
}
|
|
266
|
+
if (options.optimize) {
|
|
267
|
+
args.push("--optimize");
|
|
268
|
+
}
|
|
269
|
+
if (options.optimizerRuns !== undefined) {
|
|
270
|
+
args.push("--optimizer-runs", options.optimizerRuns.toString());
|
|
271
|
+
}
|
|
272
|
+
if (options.viaIr) {
|
|
273
|
+
args.push("--via-ir");
|
|
274
|
+
}
|
|
275
|
+
return args;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Execute forge coverage command and stream output
|
|
279
|
+
*
|
|
280
|
+
* @param args - Command arguments
|
|
281
|
+
* @returns Promise<boolean> - true if command succeeds
|
|
282
|
+
*/
|
|
283
|
+
executeForge(args) {
|
|
284
|
+
return new Promise((resolve, reject) => {
|
|
285
|
+
const forge = (0, child_process_1.spawn)("forge", ["coverage", ...args], {
|
|
286
|
+
cwd: this.hre.config.paths.root,
|
|
287
|
+
stdio: "inherit",
|
|
288
|
+
shell: true,
|
|
289
|
+
});
|
|
290
|
+
forge.on("close", (code) => {
|
|
291
|
+
if (code === 0) {
|
|
292
|
+
resolve(true);
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
resolve(false);
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
forge.on("error", (error) => {
|
|
299
|
+
logger_1.Logger.error(`Failed to execute forge: ${error.message}`);
|
|
300
|
+
reject(error);
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
exports.ForgeCoverageFramework = ForgeCoverageFramework;
|
|
306
|
+
//# sourceMappingURL=ForgeCoverageFramework.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ForgeCoverageFramework.js","sourceRoot":"","sources":["../../src/framework/ForgeCoverageFramework.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"child_process\";\nimport { HardhatRuntimeEnvironment } from \"hardhat/types\";\nimport { CoverageOptions } from \"../types/config\";\nimport { isFoundryInstalled } from \"../utils/foundry\";\nimport { Logger } from \"../utils/logger\";\nimport { DeploymentManager } from \"./DeploymentManager\";\nimport { HelperGenerator } from \"./HelperGenerator\";\n\n/**\n * ForgeCoverageFramework - Main orchestration class for Forge coverage with Diamonds\n *\n * Coordinates:\n * 1. Diamond deployment via DeploymentManager\n * 2. Helper generation via HelperGenerator\n * 3. Forge coverage execution\n *\n * Mirrors ForgeFuzzingFramework design for consistency and code reuse\n */\nexport class ForgeCoverageFramework {\n private deploymentManager: DeploymentManager;\n private helperGenerator: HelperGenerator;\n\n constructor(private hre: HardhatRuntimeEnvironment) {\n this.deploymentManager = new DeploymentManager(hre);\n this.helperGenerator = new HelperGenerator(hre);\n }\n\n /**\n * Run complete Forge coverage workflow\n *\n * Workflow:\n * 1. Validate Foundry installation\n * 2. Deploy or reuse Diamond\n * 3. Generate Solidity helpers\n * 4. Run forge coverage with options\n *\n * @param options - Coverage execution options\n * @returns Promise<boolean> - true if coverage succeeds\n */\n async runCoverage(options: CoverageOptions = {}): Promise<boolean> {\n const {\n diamondName = \"ExampleDiamond\",\n networkName = \"hardhat\",\n force = false,\n skipDeployment = false,\n skipHelpers = false,\n writeDeployedDiamondData = false,\n } = options;\n\n Logger.section(\"Running Forge Coverage with Diamond\");\n\n // Step 1: Validate Foundry\n if (!isFoundryInstalled()) {\n Logger.error(\n \"Foundry is not installed. Please install it: https://book.getfoundry.sh/getting-started/installation\"\n );\n return false;\n }\n\n try {\n // Step 2: Ensure Diamond deployment\n if (!skipDeployment) {\n Logger.section(\"Step 1/3: Ensuring Diamond Deployment\");\n await this.deploymentManager.ensureDeployment(\n diamondName,\n networkName,\n force,\n writeDeployedDiamondData\n );\n } else {\n Logger.info(\"Skipping deployment (using existing)\");\n }\n\n // Step 3: Generate helpers\n if (!skipHelpers) {\n Logger.section(\"Step 2/3: Generating Solidity Helpers\");\n\n const deployment = await this.deploymentManager.getDeployment(\n diamondName,\n networkName\n );\n\n if (!deployment) {\n Logger.warn(\"โ No deployment record found\");\n if (!skipDeployment) {\n Logger.info(\"โน Using cached deployment (ephemeral)\");\n }\n } else {\n Logger.info(\"Using deployment record\");\n }\n\n const provider = this.hre.ethers.provider;\n const network = await provider.getNetwork();\n const chainId = Number(network.chainId);\n\n const deploymentData = deployment\n ? deployment.getDeployedDiamondData()\n : await this.deploymentManager\n .ensureDeployment(diamondName, networkName, false, false)\n .then((d) => d.getDeployedDiamondData());\n\n await this.helperGenerator.generateDeploymentHelpers(\n diamondName,\n networkName,\n chainId,\n deploymentData,\n deployment || undefined\n );\n } else {\n Logger.info(\"Skipping helper generation\");\n }\n\n // Step 4: Run coverage\n Logger.section(\"Step 3/3: Running Forge Coverage\");\n\n // Get fork URL for network (same pattern as ForgeFuzzingFramework)\n const provider = this.hre.ethers.provider;\n let forkUrl: string;\n\n if (networkName !== \"hardhat\") {\n forkUrl = (provider as any).connection?.url || \"http://127.0.0.1:8545\";\n } else {\n forkUrl = \"http://127.0.0.1:8545\";\n Logger.warn(\n \"โ ๏ธ Network is \\\"hardhat\\\" - defaulting to localhost fork: http://127.0.0.1:8545\"\n );\n Logger.warn(\"๐ก Make sure Hardhat node is running: npx hardhat node\");\n Logger.warn(\"๐ก Or specify network explicitly: --network localhost\");\n }\n\n const args = this.buildCoverageCommand({ ...options, forkUrl });\n\n Logger.info(`Executing: forge coverage ${args.join(\" \")}`);\n Logger.info(\"โณ Running coverage analysis (this may take a while)...\");\n\n const success = await this.executeForge(args);\n\n if (success) {\n Logger.success(\"โ
Coverage analysis completed successfully\");\n } else {\n Logger.error(\"โ Coverage analysis failed\");\n }\n\n return success;\n } catch (error: any) {\n Logger.error(`Coverage execution failed: ${error.message}`);\n return false;\n }\n }\n\n /**\n * Build complete forge coverage command arguments\n *\n * @param options - Coverage options\n * @returns Array of command arguments\n */\n private buildCoverageCommand(options: CoverageOptions): string[] {\n const args: string[] = [];\n\n // Add fork URL if provided\n if (options.forkUrl) {\n args.push(\"--fork-url\", options.forkUrl);\n }\n\n // Add all option groups\n args.push(...this.buildReportOptions(options));\n args.push(...this.buildFilterOptions(options));\n args.push(...this.buildDisplayOptions(options));\n args.push(...this.buildTestOptions(options));\n args.push(...this.buildEvmOptions(options));\n args.push(...this.buildBuildOptions(options));\n\n return args.filter((arg) => arg !== \"\");\n }\n\n /**\n * Build report-related options\n */\n private buildReportOptions(options: CoverageOptions): string[] {\n const args: string[] = [];\n\n // Multiple --report flags\n if (options.report && options.report.length > 0) {\n for (const reportType of options.report) {\n args.push(\"--report\", reportType);\n }\n }\n\n if (options.reportFile) {\n args.push(\"--report-file\", options.reportFile);\n }\n\n if (options.lcovVersion) {\n args.push(\"--lcov-version\", options.lcovVersion);\n }\n\n if (options.includeLibs) {\n args.push(\"--include-libs\");\n }\n\n if (options.excludeTests) {\n args.push(\"--exclude-tests\");\n }\n\n if (options.irMinimum) {\n args.push(\"--ir-minimum\");\n }\n\n return args;\n }\n\n /**\n * Build test filtering options\n */\n private buildFilterOptions(options: CoverageOptions): string[] {\n const args: string[] = [];\n\n if (options.matchTest) {\n args.push(\"--match-test\", options.matchTest);\n }\n\n if (options.noMatchTest) {\n args.push(\"--no-match-test\", options.noMatchTest);\n }\n\n if (options.matchContract) {\n args.push(\"--match-contract\", options.matchContract);\n }\n\n if (options.noMatchContract) {\n args.push(\"--no-match-contract\", options.noMatchContract);\n }\n\n if (options.matchPath) {\n args.push(\"--match-path\", options.matchPath);\n }\n\n if (options.noMatchPath) {\n args.push(\"--no-match-path\", options.noMatchPath);\n }\n\n if (options.noMatchCoverage) {\n args.push(\"--no-match-coverage\", options.noMatchCoverage);\n }\n\n return args;\n }\n\n /**\n * Build display options\n */\n private buildDisplayOptions(options: CoverageOptions): string[] {\n const args: string[] = [];\n\n // Verbosity (-v, -vv, -vvv, etc.)\n if (options.verbosity && options.verbosity > 0) {\n args.push(\"-\" + \"v\".repeat(options.verbosity));\n }\n\n if (options.quiet) {\n args.push(\"--quiet\");\n }\n\n if (options.json) {\n args.push(\"--json\");\n }\n\n if (options.md) {\n args.push(\"--md\");\n }\n\n if (options.color) {\n args.push(\"--color\", options.color);\n }\n\n return args;\n }\n\n /**\n * Build test execution options\n */\n private buildTestOptions(options: CoverageOptions): string[] {\n const args: string[] = [];\n\n if (options.threads !== undefined) {\n args.push(\"--threads\", options.threads.toString());\n }\n\n if (options.fuzzRuns !== undefined) {\n args.push(\"--fuzz-runs\", options.fuzzRuns.toString());\n }\n\n if (options.fuzzSeed) {\n args.push(\"--fuzz-seed\", options.fuzzSeed);\n }\n\n if (options.failFast) {\n args.push(\"--fail-fast\");\n }\n\n if (options.allowFailure) {\n args.push(\"--allow-failure\");\n }\n\n return args;\n }\n\n /**\n * Build EVM options\n */\n private buildEvmOptions(options: CoverageOptions): string[] {\n const args: string[] = [];\n\n if (options.forkBlockNumber !== undefined) {\n args.push(\"--fork-block-number\", options.forkBlockNumber.toString());\n }\n\n if (options.initialBalance) {\n args.push(\"--initial-balance\", options.initialBalance);\n }\n\n if (options.sender) {\n args.push(\"--sender\", options.sender);\n }\n\n if (options.ffi) {\n args.push(\"--ffi\");\n }\n\n return args;\n }\n\n /**\n * Build build options\n */\n private buildBuildOptions(options: CoverageOptions): string[] {\n const args: string[] = [];\n\n if (options.force) {\n args.push(\"--force\");\n }\n\n if (options.noCache) {\n args.push(\"--no-cache\");\n }\n\n if (options.optimize) {\n args.push(\"--optimize\");\n }\n\n if (options.optimizerRuns !== undefined) {\n args.push(\"--optimizer-runs\", options.optimizerRuns.toString());\n }\n\n if (options.viaIr) {\n args.push(\"--via-ir\");\n }\n\n return args;\n }\n\n /**\n * Execute forge coverage command and stream output\n *\n * @param args - Command arguments\n * @returns Promise<boolean> - true if command succeeds\n */\n private executeForge(args: string[]): Promise<boolean> {\n return new Promise((resolve, reject) => {\n const forge = spawn(\"forge\", [\"coverage\", ...args], {\n cwd: this.hre.config.paths.root,\n stdio: \"inherit\",\n shell: true,\n });\n\n forge.on(\"close\", (code) => {\n if (code === 0) {\n resolve(true);\n } else {\n resolve(false);\n }\n });\n\n forge.on(\"error\", (error) => {\n Logger.error(`Failed to execute forge: ${error.message}`);\n reject(error);\n });\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types";
|
|
2
|
+
import { CoverageOptions } from "../types/config";
|
|
3
|
+
/**
|
|
4
|
+
* ForgeCoverageFramework - Orchestrates forge coverage execution for Diamond contracts
|
|
5
|
+
*
|
|
6
|
+
* Responsibilities:
|
|
7
|
+
* 1. Build forge coverage command with all options
|
|
8
|
+
* 2. Execute forge coverage with proper fork URL
|
|
9
|
+
* 3. Stream output to terminal
|
|
10
|
+
* 4. Handle errors appropriately
|
|
11
|
+
*/
|
|
12
|
+
export declare class ForgeCoverageFramework {
|
|
13
|
+
private hre;
|
|
14
|
+
constructor(hre: HardhatRuntimeEnvironment);
|
|
15
|
+
/**
|
|
16
|
+
* Run forge coverage with provided options
|
|
17
|
+
*
|
|
18
|
+
* @param options - Coverage execution options
|
|
19
|
+
* @returns Promise<boolean> - true if coverage succeeds, false otherwise
|
|
20
|
+
*/
|
|
21
|
+
runCoverage(options?: CoverageOptions): Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* Build complete forge coverage command arguments
|
|
24
|
+
*
|
|
25
|
+
* @param options - Coverage options
|
|
26
|
+
* @returns Array of command arguments
|
|
27
|
+
*/
|
|
28
|
+
private buildCoverageCommand;
|
|
29
|
+
/**
|
|
30
|
+
* Build report-related options
|
|
31
|
+
*/
|
|
32
|
+
private buildReportOptions;
|
|
33
|
+
/**
|
|
34
|
+
* Build test filtering options
|
|
35
|
+
*/
|
|
36
|
+
private buildFilterOptions;
|
|
37
|
+
/**
|
|
38
|
+
* Build display options
|
|
39
|
+
*/
|
|
40
|
+
private buildDisplayOptions;
|
|
41
|
+
/**
|
|
42
|
+
* Build test execution options
|
|
43
|
+
*/
|
|
44
|
+
private buildTestOptions;
|
|
45
|
+
/**
|
|
46
|
+
* Build EVM options
|
|
47
|
+
*/
|
|
48
|
+
private buildEvmOptions;
|
|
49
|
+
/**
|
|
50
|
+
* Build build options
|
|
51
|
+
*/
|
|
52
|
+
private buildBuildOptions;
|
|
53
|
+
/**
|
|
54
|
+
* Execute forge coverage command and stream output
|
|
55
|
+
*
|
|
56
|
+
* @param args - Command arguments
|
|
57
|
+
* @returns Promise<boolean> - true if command succeeds
|
|
58
|
+
*/
|
|
59
|
+
private executeForge;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=ForgeCoverageFramework.old.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ForgeCoverageFramework.old.d.ts","sourceRoot":"","sources":["../../src/framework/ForgeCoverageFramework.old.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlD;;;;;;;;GAQG;AACH,qBAAa,sBAAsB;IACrB,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,yBAAyB;IAElD;;;;;OAKG;IACG,WAAW,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IA0BlE;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAmB5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiC1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkC1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA0BxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAsBvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA0BzB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;CAoBrB"}
|