Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions crates/forge/src/cmd/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ foundry_config::impl_figment_convert!(CoverageArgs, test);
/// option in `foundry.toml`. CLI flags take precedence over config; the helper
/// `resolve_with` merges them after the config is loaded.
#[derive(Parser)]
#[command(after_long_help = r#"Compatibility:
#[command(after_long_help = r#"Source attribution:
Coverage follows compiler source maps. Inherited modifier code is reported under the
source where the modifier is declared. Dependency sources are excluded by default;
use `--include-libs` to include their coverage.

Compatibility:
`forge coverage` supports test filters and `--watch`, but not test-only output or
execution modes such as `--json`, `--junit`, `--list`, `--debug`, flame profiles,
symbolic artifact replay, showmap replay, brutalization, or mutation testing. Use
Expand Down Expand Up @@ -91,7 +96,7 @@ pub struct CoverageArgs {
)]
report_file: Option<PathBuf>,

/// Whether to include libraries in the coverage report.
/// Include dependency sources in the coverage report.
#[arg(long)]
include_libs: bool,

Expand Down
33 changes: 22 additions & 11 deletions crates/forge/src/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,31 @@ impl CoverageReporter for CoverageSummaryReporter {
}

fn format_cell(hits: usize, total: usize) -> Cell {
let percentage = if total == 0 { 1. } else { hits as f64 / total as f64 };
if total == 0 {
return Cell::new(format!("N/A ({hits}/{total})"))
.fg(Color::Grey)
.add_attribute(Attribute::Dim);
}

let mut cell =
Cell::new(format!("{:.2}% ({hits}/{total})", percentage * 100.)).fg(match percentage {
_ if total == 0 => Color::Grey,
_ if percentage < 0.5 => Color::Red,
_ if percentage < 0.75 => Color::Yellow,
_ => Color::Green,
});
let percentage = hits as f64 / total as f64;
Cell::new(format!("{:.2}% ({hits}/{total})", percentage * 100.)).fg(match percentage {
_ if percentage < 0.5 => Color::Red,
_ if percentage < 0.75 => Color::Yellow,
_ => Color::Green,
})
}

if total == 0 {
cell = cell.add_attribute(Attribute::Dim);
#[cfg(test)]
mod tests {
use super::*;

#[test]
fn empty_summary_cell_is_not_applicable() {
assert_eq!(
format_cell(0, 0),
Cell::new("N/A (0/0)").fg(Color::Grey).add_attribute(Attribute::Dim)
);
}
cell
}

/// Writes the coverage report in [LCOV]'s [tracefile format].
Expand Down
Loading
Loading