Skip to content

Commit 5b84163

Browse files
authored
fix(coverage): lcov avoid double reporting for line hit (#8400)
1 parent ef62fdb commit 5b84163

File tree

3 files changed

+66
-6
lines changed

3 files changed

+66
-6
lines changed

crates/forge/src/coverage.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,9 @@ impl<'a> CoverageReporter for LcovReporter<'a> {
116116
if hits == 0 { "-".to_string() } else { hits.to_string() }
117117
)?;
118118
}
119-
// Statements are not in the LCOV format
120-
CoverageItemKind::Statement => {
121-
writeln!(self.destination, "DA:{line},{hits}")?;
122-
}
119+
// Statements are not in the LCOV format.
120+
// We don't add them in order to avoid doubling line hits.
121+
_ => {}
123122
}
124123
}
125124

crates/forge/tests/cli/coverage.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use foundry_test_utils::str;
1+
use foundry_test_utils::{assert_data_eq, str};
22

33
forgetest!(basic_coverage, |_prj, cmd| {
44
cmd.args(["coverage"]);
@@ -210,3 +210,64 @@ contract AContractTest is DSTest {
210210
211211
"#]]);
212212
});
213+
214+
forgetest!(test_line_hit_not_doubled, |prj, cmd| {
215+
prj.insert_ds_test();
216+
prj.add_source(
217+
"AContract.sol",
218+
r#"
219+
contract AContract {
220+
int public i;
221+
222+
function foo() public {
223+
i = 1;
224+
}
225+
}
226+
"#,
227+
)
228+
.unwrap();
229+
230+
prj.add_source(
231+
"AContractTest.sol",
232+
r#"
233+
import "./test.sol";
234+
import {AContract} from "./AContract.sol";
235+
236+
contract AContractTest is DSTest {
237+
function testFoo() public {
238+
AContract a = new AContract();
239+
a.foo();
240+
}
241+
}
242+
"#,
243+
)
244+
.unwrap();
245+
246+
let lcov_info = prj.root().join("lcov.info");
247+
cmd.arg("coverage").args([
248+
"--report".to_string(),
249+
"lcov".to_string(),
250+
"--report-file".to_string(),
251+
lcov_info.to_str().unwrap().to_string(),
252+
]);
253+
cmd.assert_success();
254+
assert!(lcov_info.exists());
255+
256+
// We want to make sure DA:8,1 is added only once so line hit is not doubled.
257+
assert_data_eq!(
258+
std::fs::read_to_string(lcov_info).unwrap(),
259+
str![[r#"TN:
260+
SF:src/AContract.sol
261+
FN:7,AContract.foo
262+
FNDA:1,AContract.foo
263+
DA:8,1
264+
FNF:1
265+
FNH:1
266+
LF:1
267+
LH:1
268+
BRF:0
269+
BRH:0
270+
end[..]
271+
"#]]
272+
);
273+
});

crates/test-utils/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub use script::{ScriptOutcome, ScriptTester};
2828
// re-exports for convenience
2929
pub use foundry_compilers;
3030

31-
pub use snapbox::{file, str};
31+
pub use snapbox::{assert_data_eq, file, str};
3232

3333
/// Initializes tracing for tests.
3434
pub fn init_tracing() {

0 commit comments

Comments
 (0)