hardhat 3.1.3 → 3.1.4
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/CHANGELOG.md +8 -0
- package/dist/src/internal/builtin-plugins/coverage/coverage-manager.d.ts +14 -14
- package/dist/src/internal/builtin-plugins/coverage/coverage-manager.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/coverage/coverage-manager.js +66 -110
- package/dist/src/internal/builtin-plugins/coverage/coverage-manager.js.map +1 -1
- package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.js +13 -6
- package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.js.map +1 -1
- package/dist/src/internal/builtin-plugins/coverage/process-coverage.d.ts +21 -0
- package/dist/src/internal/builtin-plugins/coverage/process-coverage.d.ts.map +1 -0
- package/dist/src/internal/builtin-plugins/coverage/process-coverage.js +291 -0
- package/dist/src/internal/builtin-plugins/coverage/process-coverage.js.map +1 -0
- package/dist/src/internal/builtin-plugins/coverage/reports/html.d.ts +3 -0
- package/dist/src/internal/builtin-plugins/coverage/reports/html.d.ts.map +1 -0
- package/dist/src/internal/builtin-plugins/coverage/reports/html.js +37 -0
- package/dist/src/internal/builtin-plugins/coverage/reports/html.js.map +1 -0
- package/dist/src/internal/builtin-plugins/coverage/types.d.ts +9 -3
- package/dist/src/internal/builtin-plugins/coverage/types.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/internal/builtin-plugins/coverage/coverage-manager.ts +121 -176
- package/src/internal/builtin-plugins/coverage/hook-handlers/solidity.ts +19 -8
- package/src/internal/builtin-plugins/coverage/process-coverage.ts +442 -0
- package/src/internal/builtin-plugins/coverage/reports/html.ts +56 -0
- package/src/internal/builtin-plugins/coverage/types.ts +8 -3
- package/templates/hardhat-3/01-node-test-runner-viem/package.json +1 -1
- package/templates/hardhat-3/02-mocha-ethers/package.json +1 -1
- package/templates/hardhat-3/03-minimal/package.json +1 -1
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
// Use constants for the Uint8Array to improve memory usage (1 byte vs 8 bytes per item)
|
|
3
|
+
const STATUS_NOT_EXECUTED = 0; // equivalent to false
|
|
4
|
+
const STATUS_EXECUTED = 1; // equivalent to true
|
|
5
|
+
const STATUS_IGNORED = 2; // equivalent to null
|
|
6
|
+
/**
|
|
7
|
+
* Processes the raw EDR coverage information for a file and returns the executed and
|
|
8
|
+
* non-executed statements and lines.
|
|
9
|
+
*
|
|
10
|
+
* @param fileContent The original file content being analyzed
|
|
11
|
+
* @param metadata Coverage metadata received from EDR for this file
|
|
12
|
+
* @param hitTags The coverage tags recorded as executed during the test run
|
|
13
|
+
* for this specific file.
|
|
14
|
+
*
|
|
15
|
+
* @returns An object containing:
|
|
16
|
+
* - statements: the executed and not-executed statements
|
|
17
|
+
* - lines: the executed and not-executed line numbers
|
|
18
|
+
*/
|
|
19
|
+
export function getProcessedCoverageInfo(fileContent, metadata, hitTags) {
|
|
20
|
+
const statementsByExecution = partitionStatementsByExecution(metadata, hitTags);
|
|
21
|
+
const { start, end } = getCoverageBounds(statementsByExecution, fileContent.length);
|
|
22
|
+
const characterCoverage = buildCharacterCoverage(fileContent, start, end, statementsByExecution.unexecuted);
|
|
23
|
+
// printStatementsForDebugging(fileContent, statementsByExecution);
|
|
24
|
+
// printCharacterCoverageForDebugging(fileContent, characterCoverage);
|
|
25
|
+
return {
|
|
26
|
+
lines: partitionLinesByExecution(fileContent, characterCoverage),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function partitionStatementsByExecution(metadata, hitTags) {
|
|
30
|
+
const executed = [];
|
|
31
|
+
const unexecuted = [];
|
|
32
|
+
for (const node of metadata) {
|
|
33
|
+
if (hitTags.has(node.tag)) {
|
|
34
|
+
executed.push(node);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
unexecuted.push(node);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
executed,
|
|
42
|
+
unexecuted,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// Determine the minimum and maximum character indexes that define the range
|
|
46
|
+
// where coverage should be calculated, excluding parts that the tests never
|
|
47
|
+
// reach. This removes irrelevant sections from coverage analysis, such as the
|
|
48
|
+
// beginning or end of each Solidity file.
|
|
49
|
+
// Example:
|
|
50
|
+
// // SPDX-License-Identifier: MIT
|
|
51
|
+
// pragma solidity ^0.8.0;
|
|
52
|
+
function getCoverageBounds(statementsByExecution, fileLength) {
|
|
53
|
+
let start = fileLength;
|
|
54
|
+
let end = 0;
|
|
55
|
+
const { executed, unexecuted } = statementsByExecution;
|
|
56
|
+
for (const s of [...executed, ...unexecuted]) {
|
|
57
|
+
if (s.startUtf16 < start) {
|
|
58
|
+
start = s.startUtf16;
|
|
59
|
+
}
|
|
60
|
+
if (s.endUtf16 > end) {
|
|
61
|
+
end = s.endUtf16;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { start, end };
|
|
65
|
+
}
|
|
66
|
+
// Return an array with the same length as the file content. Each position in
|
|
67
|
+
// the array corresponds to a character in the file. The value at each position
|
|
68
|
+
// indicates whether that character was executed during tests (STATUS_EXECUTED),
|
|
69
|
+
// not executed (STATUS_NOT_EXECUTED), or not relevant for coverage
|
|
70
|
+
// (STATUS_IGNORED). STATUS_IGNORED is used to indicate characters that are not
|
|
71
|
+
// executed during test, such as those found at the start or end of every Solidity file.
|
|
72
|
+
// Example:
|
|
73
|
+
// // SPDX-License-Identifier: MIT
|
|
74
|
+
// pragma solidity ^0.8.0;
|
|
75
|
+
function buildCharacterCoverage(fileContent, start, end, unexecutedStatements) {
|
|
76
|
+
// Use Uint8Array instead of Array<null | boolean> for memory efficiency.
|
|
77
|
+
// We initialize with STATUS_IGNORED (equivalent to filling with null)
|
|
78
|
+
const characterCoverage = new Uint8Array(fileContent.length).fill(STATUS_IGNORED);
|
|
79
|
+
// Initially mark all characters that may be executed during the tests as
|
|
80
|
+
// STATUS_EXECUTED. They will be set to false later if they are not executed.
|
|
81
|
+
// The coverage statement received from EDR will provide this information.
|
|
82
|
+
// Setting everything to true first simplifies the logic for extracting
|
|
83
|
+
// coverage data. Starting with false and toggling only covered characters
|
|
84
|
+
// would make statement processing more complex.
|
|
85
|
+
for (let i = start; i < end; i++) {
|
|
86
|
+
if (charMustBeIgnored(fileContent[i])) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
characterCoverage[i] = STATUS_EXECUTED;
|
|
90
|
+
}
|
|
91
|
+
for (const statement of unexecutedStatements) {
|
|
92
|
+
for (let i = statement.startUtf16; i < statement.endUtf16; i++) {
|
|
93
|
+
if (characterCoverage[i] === STATUS_IGNORED) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
characterCoverage[i] = STATUS_NOT_EXECUTED;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
markNonExecutablePatterns(fileContent, characterCoverage);
|
|
100
|
+
return characterCoverage;
|
|
101
|
+
}
|
|
102
|
+
// The following characters are not relevant for the code coverage, so they
|
|
103
|
+
// must be ignored when marking characters as executed (true) or not executed (false)
|
|
104
|
+
function charMustBeIgnored(char) {
|
|
105
|
+
const code = char.charCodeAt(0);
|
|
106
|
+
return (code === 32 || // Space
|
|
107
|
+
(code >= 9 && code <= 13) || // \t (9), \n (10), \v (11), \f (12), \r (13)
|
|
108
|
+
code === 123 || // {
|
|
109
|
+
code === 125 // }
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
// Mark different types of substrings as not relevant for code coverage (set them to STATUS_IGNORED).
|
|
113
|
+
// For example, all "else" substrings or comments are not relevant for code coverage.
|
|
114
|
+
function markNonExecutablePatterns(fileContent, characterCoverage) {
|
|
115
|
+
// Comments that start with //
|
|
116
|
+
markMatchingCharsWithIgnored(fileContent, characterCoverage, /\/\/.*?(?=\n|$)/g);
|
|
117
|
+
// Comments wrapped between /* and */
|
|
118
|
+
markMatchingCharsWithIgnored(fileContent, characterCoverage, /\/\*[\s\S]*?\*\//g);
|
|
119
|
+
// Lines containing `else`, since they do not represent executable code by themselves.
|
|
120
|
+
// Keep in mind that `else` is preceded by a closing brace and followed by an opening brace.
|
|
121
|
+
// This can span multiple lines.
|
|
122
|
+
markMatchingCharsWithIgnored(fileContent, characterCoverage, /\}\s*\belse\b\s*\{/g);
|
|
123
|
+
// Lines containing the function signature. This can span multiple lines
|
|
124
|
+
markMatchingCharsWithIgnored(fileContent, characterCoverage, /^\s*(function\s+[A-Za-z_$][A-Za-z0-9_$]*\s*\([\s\S]*?\)[^{]*?)(?=\s*\{)/gm);
|
|
125
|
+
// Lines containing the catch signature. This can span multiple lines.
|
|
126
|
+
markMatchingCharsWithIgnored(fileContent, characterCoverage, /\bcatch\b(?:\s+[A-Za-z_][A-Za-z0-9_]*)?\s*(?:\([\s\S]*?\))?(?=\s*\{)/g);
|
|
127
|
+
}
|
|
128
|
+
function markMatchingCharsWithIgnored(fileContent, characterCoverage, regex) {
|
|
129
|
+
for (const match of fileContent.matchAll(regex)) {
|
|
130
|
+
for (let i = match.index; i < match.index + match[0].length; i++) {
|
|
131
|
+
characterCoverage[i] = STATUS_IGNORED;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Generate non overlapping coverage statements. Every character between the start
|
|
136
|
+
// and end indexes is guaranteed to be either executed or not executed.
|
|
137
|
+
// Unlike the statements received from EDR, which may include nested sub
|
|
138
|
+
// statements, these are processed and have no sub statements or overlapping statements.
|
|
139
|
+
// Example:
|
|
140
|
+
// [
|
|
141
|
+
// { start: 12, end: 20, executed: true },
|
|
142
|
+
// { start: 15, end: 17, executed: true }
|
|
143
|
+
// ]
|
|
144
|
+
// ->
|
|
145
|
+
// [
|
|
146
|
+
// { start: 12, end: 20, executed: true }
|
|
147
|
+
// ]
|
|
148
|
+
/* eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
149
|
+
-- currently not used, but it will be used to create more detailed.
|
|
150
|
+
It will be used to return statements from the function `getProcessedCoverageInfo` */
|
|
151
|
+
function getProcessedExecutedStatements(characterCoverage) {
|
|
152
|
+
const executed = generateProcessedStatements(characterCoverage, STATUS_EXECUTED);
|
|
153
|
+
const unexecuted = generateProcessedStatements(characterCoverage, STATUS_NOT_EXECUTED);
|
|
154
|
+
return {
|
|
155
|
+
executed,
|
|
156
|
+
unexecuted,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// Based on the marked file, where each character is marked as either
|
|
160
|
+
// executed (STATUS_EXECUTED) or not executed (STATUS_NOT_EXECUTED),
|
|
161
|
+
// generate non-overlapping statements that indicate the start and
|
|
162
|
+
// end indices, along with whether they were executed or not.
|
|
163
|
+
function generateProcessedStatements(characterCoverage, targetStatus) {
|
|
164
|
+
const ranges = [];
|
|
165
|
+
const fileLength = characterCoverage.length;
|
|
166
|
+
let start = -1;
|
|
167
|
+
for (let i = 0; i < fileLength; i++) {
|
|
168
|
+
if (characterCoverage[i] === targetStatus) {
|
|
169
|
+
if (start === -1) {
|
|
170
|
+
start = i; // begin new range
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
if (start !== -1) {
|
|
175
|
+
// Map back to boolean for the output object
|
|
176
|
+
ranges.push({
|
|
177
|
+
startUtf16: start,
|
|
178
|
+
endUtf16: i - 1,
|
|
179
|
+
executed: targetStatus === STATUS_EXECUTED,
|
|
180
|
+
});
|
|
181
|
+
start = -1;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// close last range if file ends inside a run
|
|
186
|
+
if (start !== -1) {
|
|
187
|
+
ranges.push({
|
|
188
|
+
startUtf16: start,
|
|
189
|
+
endUtf16: fileLength - 1,
|
|
190
|
+
executed: targetStatus === STATUS_EXECUTED,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return ranges;
|
|
194
|
+
}
|
|
195
|
+
// Return the executed and non executed lines based on the marked file.
|
|
196
|
+
// Some lines are excluded from the execution count, for example, comments.
|
|
197
|
+
function partitionLinesByExecution(fileContent, characterCoverage) {
|
|
198
|
+
const executed = new Map();
|
|
199
|
+
const unexecuted = new Map();
|
|
200
|
+
let lineStart = 0;
|
|
201
|
+
let isLineIgnored = true;
|
|
202
|
+
let isLineExecutedOrIgnored = true;
|
|
203
|
+
let lineNumber = 1; // File lines start at 1
|
|
204
|
+
// Helper to process a line and push to correct map
|
|
205
|
+
const processLine = (endIndex) => {
|
|
206
|
+
// Only process if the line isn't entirely ignored
|
|
207
|
+
if (!isLineIgnored) {
|
|
208
|
+
const lineText = fileContent.slice(lineStart, endIndex);
|
|
209
|
+
if (isLineExecutedOrIgnored) {
|
|
210
|
+
executed.set(lineNumber, lineText);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
unexecuted.set(lineNumber, lineText);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Reset state for the next line
|
|
217
|
+
lineStart = endIndex + 1;
|
|
218
|
+
isLineIgnored = true;
|
|
219
|
+
isLineExecutedOrIgnored = true;
|
|
220
|
+
lineNumber++;
|
|
221
|
+
};
|
|
222
|
+
for (let i = 0; i < fileContent.length; i++) {
|
|
223
|
+
const char = fileContent[i];
|
|
224
|
+
const status = characterCoverage[i];
|
|
225
|
+
if (status !== STATUS_IGNORED) {
|
|
226
|
+
isLineIgnored = false;
|
|
227
|
+
}
|
|
228
|
+
if (status === STATUS_NOT_EXECUTED) {
|
|
229
|
+
isLineExecutedOrIgnored = false;
|
|
230
|
+
}
|
|
231
|
+
if (char === "\n") {
|
|
232
|
+
processLine(i);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// Handle the final line if the file doesn't end in a newline
|
|
236
|
+
if (lineStart < fileContent.length) {
|
|
237
|
+
processLine(fileContent.length);
|
|
238
|
+
}
|
|
239
|
+
return { executed, unexecuted };
|
|
240
|
+
}
|
|
241
|
+
// Enable this function while debugging to display the coverage for a file.
|
|
242
|
+
// The file will be printed with green characters when they are executed,
|
|
243
|
+
// red characters when they are not executed,
|
|
244
|
+
// and gray characters when they are irrelevant for code coverage.
|
|
245
|
+
/* eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
246
|
+
-- this function can be enabled for debugging purposes */
|
|
247
|
+
function printStatementsForDebugging(fileContent, statementsByExecution) {
|
|
248
|
+
const relativePath = statementsByExecution.executed.length > 0
|
|
249
|
+
? statementsByExecution.executed[0].relativePath
|
|
250
|
+
: statementsByExecution.unexecuted[0].relativePath;
|
|
251
|
+
console.debug("Statements for file: " + relativePath);
|
|
252
|
+
console.debug("Executed statements:");
|
|
253
|
+
let counter = 0;
|
|
254
|
+
for (const statement of statementsByExecution.executed) {
|
|
255
|
+
console.debug(counter++ + " ---");
|
|
256
|
+
for (let i = statement.startUtf16; i < statement.endUtf16; i++) {
|
|
257
|
+
process.stdout.write(chalk.gray(fileContent[i]));
|
|
258
|
+
}
|
|
259
|
+
console.debug();
|
|
260
|
+
}
|
|
261
|
+
console.debug();
|
|
262
|
+
console.debug("Unexecuted statements:");
|
|
263
|
+
counter = 0;
|
|
264
|
+
for (const statement of statementsByExecution.unexecuted) {
|
|
265
|
+
console.debug(counter++ + " ---");
|
|
266
|
+
for (let i = statement.startUtf16; i < statement.endUtf16; i++) {
|
|
267
|
+
process.stdout.write(chalk.gray(fileContent[i]));
|
|
268
|
+
}
|
|
269
|
+
console.debug();
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// Enable this function while debugging to display the coverage for a file.
|
|
273
|
+
// The file will be printed with green characters when they are executed,
|
|
274
|
+
// red characters when they are not executed,
|
|
275
|
+
// and gray characters when they are irrelevant for code coverage.
|
|
276
|
+
/* eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
277
|
+
-- this function can be enabled for debugging purposes */
|
|
278
|
+
function printCharacterCoverageForDebugging(fileContent, characterCoverage) {
|
|
279
|
+
for (let i = 0; i < characterCoverage.length; i++) {
|
|
280
|
+
if (characterCoverage[i] === STATUS_IGNORED) {
|
|
281
|
+
process.stdout.write(chalk.gray(fileContent[i]));
|
|
282
|
+
}
|
|
283
|
+
else if (characterCoverage[i] === STATUS_EXECUTED) {
|
|
284
|
+
process.stdout.write(chalk.green(fileContent[i]));
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
process.stdout.write(chalk.red(fileContent[i]));
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=process-coverage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-coverage.js","sourceRoot":"","sources":["../../../../../src/internal/builtin-plugins/coverage/process-coverage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/builtin-plugins/coverage/reports/html.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAYrD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAwCf"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { mkdir } from "@nomicfoundation/hardhat-utils/fs";
|
|
3
|
+
import { istanbulLibCoverage, istanbulLibReport, istanbulReports, } from "@nomicfoundation/hardhat-vendored/coverage";
|
|
4
|
+
export async function generateHtmlReport(report, htmlReportPath) {
|
|
5
|
+
const baseDir = process.cwd();
|
|
6
|
+
const coverageMap = istanbulLibCoverage.createCoverageMap({});
|
|
7
|
+
await mkdir(htmlReportPath);
|
|
8
|
+
// Construct coverage data for each tested file,
|
|
9
|
+
// detailing whether each line was executed or not.
|
|
10
|
+
for (const [p, coverageInfo] of Object.entries(report)) {
|
|
11
|
+
const testedFilePath = path.join(baseDir, p);
|
|
12
|
+
const fc = {
|
|
13
|
+
path: testedFilePath,
|
|
14
|
+
statementMap: {},
|
|
15
|
+
fnMap: {}, // Cannot be derived from current report data
|
|
16
|
+
branchMap: {}, // Cannot be derived from current report data
|
|
17
|
+
s: {},
|
|
18
|
+
f: {}, // Cannot be derived from current report data
|
|
19
|
+
b: {},
|
|
20
|
+
};
|
|
21
|
+
for (const [line, count] of coverageInfo.lineExecutionCounts) {
|
|
22
|
+
fc.statementMap[line] = {
|
|
23
|
+
start: { line, column: 0 },
|
|
24
|
+
end: { line, column: 0 },
|
|
25
|
+
};
|
|
26
|
+
// TODO: currently EDR does not provide per-statement coverage counts
|
|
27
|
+
fc.s[line] = count > 0 ? 1 : 0; // mark as covered if hit at least once
|
|
28
|
+
}
|
|
29
|
+
coverageMap.addFileCoverage(fc);
|
|
30
|
+
}
|
|
31
|
+
const context = istanbulLibReport.createContext({
|
|
32
|
+
dir: htmlReportPath,
|
|
33
|
+
coverageMap,
|
|
34
|
+
});
|
|
35
|
+
istanbulReports.create("html", undefined).execute(context);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../../../../../src/internal/builtin-plugins/coverage/reports/html.ts"],"names":[],"mappings":"AAGA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAC1D,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,GAChB,MAAM,4CAA4C,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAc,EACd,cAAsB;IAEtB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAE9D,MAAM,KAAK,CAAC,cAAc,CAAC,CAAC;IAE5B,gDAAgD;IAChD,mDAAmD;IACnD,KAAK,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACvD,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAE7C,MAAM,EAAE,GAAqB;YAC3B,IAAI,EAAE,cAAc;YACpB,YAAY,EAAE,EAAE;YAChB,KAAK,EAAE,EAAE,EAAE,6CAA6C;YACxD,SAAS,EAAE,EAAE,EAAE,6CAA6C;YAC5D,CAAC,EAAE,EAAE;YACL,CAAC,EAAE,EAAE,EAAE,6CAA6C;YACpD,CAAC,EAAE,EAAE;SACN,CAAC;QAEF,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,YAAY,CAAC,mBAAmB,EAAE,CAAC;YAC7D,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG;gBACtB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE;gBAC1B,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE;aACzB,CAAC;YAEF,qEAAqE;YACrE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,uCAAuC;QACzE,CAAC;QAED,WAAW,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,OAAO,GAAG,iBAAiB,CAAC,aAAa,CAAC;QAC9C,GAAG,EAAE,cAAc;QACnB,WAAW;KACZ,CAAC,CAAC;IAEH,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
type Tag = string;
|
|
2
2
|
export interface Statement {
|
|
3
3
|
relativePath: string;
|
|
4
4
|
tag: Tag;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
startUtf16: number;
|
|
6
|
+
endUtf16: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ReportCoverageStatement {
|
|
9
|
+
startUtf16: number;
|
|
10
|
+
endUtf16: number;
|
|
11
|
+
executed: boolean;
|
|
7
12
|
}
|
|
8
13
|
export type CoverageMetadata = Statement[];
|
|
9
14
|
export type CoverageData = Tag[];
|
|
@@ -16,4 +21,5 @@ export interface CoverageManager {
|
|
|
16
21
|
enableReport(): void;
|
|
17
22
|
disableReport(): void;
|
|
18
23
|
}
|
|
24
|
+
export {};
|
|
19
25
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/internal/builtin-plugins/coverage/types.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/internal/builtin-plugins/coverage/types.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,CAAC;AAClB,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,GAAG,CAAC;IACT,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AACD,MAAM,MAAM,gBAAgB,GAAG,SAAS,EAAE,CAAC;AAC3C,MAAM,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC;AACjC,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpC,MAAM,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC,YAAY,IAAI,IAAI,CAAC;IACrB,aAAa,IAAI,IAAI,CAAC;CACvB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hardhat",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.4",
|
|
4
4
|
"description": "Hardhat is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.",
|
|
5
5
|
"homepage": "https://github.com/nomicfoundation/hardhat/tree/v-next/v-next/hardhat",
|
|
6
6
|
"repository": {
|
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
"@nomicfoundation/edr": "0.12.0-next.22",
|
|
75
75
|
"@nomicfoundation/hardhat-errors": "^3.0.6",
|
|
76
76
|
"@nomicfoundation/hardhat-utils": "^3.0.5",
|
|
77
|
+
"@nomicfoundation/hardhat-vendored": "^3.0.0",
|
|
77
78
|
"@nomicfoundation/hardhat-zod-utils": "^3.0.1",
|
|
78
79
|
"@nomicfoundation/solidity-analyzer": "^0.1.1",
|
|
79
80
|
"@sentry/core": "^9.4.0",
|