Skip to content

Commit 08f6305

Browse files
authored
Merge branch 'master' into adding_support_etherscan_v2
2 parents 5580f96 + 33cb8d2 commit 08f6305

File tree

4 files changed

+104
-8
lines changed

4 files changed

+104
-8
lines changed

crates/cast/src/args.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,19 @@ pub async fn run_command(args: CastArgs) -> Result<()> {
195195
let tokens = SimpleCast::calldata_decode(&sig, &calldata, true)?;
196196
print_tokens(&tokens);
197197
}
198-
CastSubcommand::CalldataEncode { sig, args } => {
199-
sh_println!("{}", SimpleCast::calldata_encode(sig, &args)?)?;
198+
CastSubcommand::CalldataEncode { sig, args, file } => {
199+
let final_args = if let Some(file_path) = file {
200+
let contents = fs::read_to_string(file_path)?;
201+
contents
202+
.lines()
203+
.map(str::trim)
204+
.filter(|line| !line.is_empty())
205+
.map(String::from)
206+
.collect()
207+
} else {
208+
args
209+
};
210+
sh_println!("{}", SimpleCast::calldata_encode(sig, &final_args)?)?;
200211
}
201212
CastSubcommand::DecodeString { data } => {
202213
let tokens = SimpleCast::calldata_decode("Any(string)", &data, true)?;

crates/cast/src/opts.rs

+17
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,10 @@ pub enum CastSubcommand {
391391
/// The arguments to encode.
392392
#[arg(allow_hyphen_values = true)]
393393
args: Vec<String>,
394+
395+
// Path to file containing arguments to encode.
396+
#[arg(long, value_name = "PATH")]
397+
file: Option<PathBuf>,
394398
},
395399

396400
/// Get the symbolic name of the current chain.
@@ -1147,6 +1151,19 @@ mod tests {
11471151
};
11481152
}
11491153

1154+
#[test]
1155+
fn parse_call_data_with_file() {
1156+
let args: Cast = Cast::parse_from(["foundry-cli", "calldata", "f()", "--file", "test.txt"]);
1157+
match args.cmd {
1158+
CastSubcommand::CalldataEncode { sig, file, args } => {
1159+
assert_eq!(sig, "f()".to_string());
1160+
assert_eq!(file, Some(PathBuf::from("test.txt")));
1161+
assert!(args.is_empty());
1162+
}
1163+
_ => unreachable!(),
1164+
};
1165+
}
1166+
11501167
// <https://github.com/foundry-rs/book/issues/1019>
11511168
#[test]
11521169
fn parse_signature() {

crates/forge/src/coverage.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Coverage reports.
22
3-
use alloy_primitives::map::HashMap;
3+
use alloy_primitives::map::{HashMap, HashSet};
44
use comfy_table::{modifiers::UTF8_ROUND_CORNERS, Attribute, Cell, Color, Row, Table};
55
use evm_disassembler::disassemble_bytes;
66
use foundry_common::fs;
@@ -118,6 +118,8 @@ impl CoverageReporter for LcovReporter {
118118
writeln!(out, "TN:")?;
119119
writeln!(out, "SF:{}", path.display())?;
120120

121+
let mut recorded_lines = HashSet::new();
122+
121123
for item in items {
122124
let line = item.loc.lines.start;
123125
// `lines` is half-open, so we need to subtract 1 to get the last included line.
@@ -140,8 +142,11 @@ impl CoverageReporter for LcovReporter {
140142
writeln!(out, "FNDA:{hits},{name}")?;
141143
}
142144
}
143-
CoverageItemKind::Line => {
144-
writeln!(out, "DA:{line},{hits}")?;
145+
// Add lines / statement hits only once.
146+
CoverageItemKind::Line | CoverageItemKind::Statement => {
147+
if recorded_lines.insert(line) {
148+
writeln!(out, "DA:{line},{hits}")?;
149+
}
145150
}
146151
CoverageItemKind::Branch { branch_id, path_id, .. } => {
147152
writeln!(
@@ -150,9 +155,6 @@ impl CoverageReporter for LcovReporter {
150155
if hits == 0 { "-".to_string() } else { hits.to_string() }
151156
)?;
152157
}
153-
// Statements are not in the LCOV format.
154-
// We don't add them in order to avoid doubling line hits.
155-
CoverageItemKind::Statement => {}
156158
}
157159
}
158160

crates/forge/tests/cli/coverage.rs

+66
Original file line numberDiff line numberDiff line change
@@ -1845,6 +1845,72 @@ contract ArrayConditionTest is DSTest {
18451845
"#]]);
18461846
});
18471847

1848+
// <https://github.com/foundry-rs/foundry/issues/10422>
1849+
// Test that line hits are properly recorded in lcov report.
1850+
forgetest!(do_while_lcov, |prj, cmd| {
1851+
prj.insert_ds_test();
1852+
prj.add_source(
1853+
"Counter.sol",
1854+
r#"
1855+
contract Counter {
1856+
uint256 public number = 21;
1857+
1858+
function increment() public {
1859+
uint256 i = 0;
1860+
do {
1861+
number++;
1862+
if (number > 20) {
1863+
number -= 2;
1864+
}
1865+
} while (++i < 10);
1866+
}
1867+
}
1868+
"#,
1869+
)
1870+
.unwrap();
1871+
1872+
prj.add_source(
1873+
"Counter.t.sol",
1874+
r#"
1875+
import "./test.sol";
1876+
import "./Counter.sol";
1877+
1878+
contract CounterTest is DSTest {
1879+
function test_do_while() public {
1880+
Counter counter = new Counter();
1881+
counter.increment();
1882+
}
1883+
}
1884+
"#,
1885+
)
1886+
.unwrap();
1887+
1888+
assert_lcov(
1889+
cmd.arg("coverage"),
1890+
str![[r#"
1891+
TN:
1892+
SF:src/Counter.sol
1893+
DA:7,1
1894+
FN:7,Counter.increment
1895+
FNDA:1,Counter.increment
1896+
DA:8,1
1897+
DA:14,10
1898+
DA:10,10
1899+
DA:11,10
1900+
BRDA:11,0,0,6
1901+
DA:12,6
1902+
FNF:1
1903+
FNH:1
1904+
LF:3
1905+
LH:3
1906+
BRF:1
1907+
BRH:1
1908+
end_of_record
1909+
1910+
"#]],
1911+
);
1912+
});
1913+
18481914
#[track_caller]
18491915
fn assert_lcov(cmd: &mut TestCommand, data: impl IntoData) {
18501916
cmd.args(["--report=lcov", "--report-file"]).assert_file(data.into_data());

0 commit comments

Comments
 (0)