Skip to content

Commit 3d15f5a

Browse files
committed
Populate condition-coverage field in cobertura xml reports
Some parsers require the presence of the `condition-coverage` field on the `line` elements in the report. This change adds and populates this field based on the available `Conditions` data. See: https://github.com/cobertura/cobertura/blob/master/cobertura/src/site/htdocs/xml/coverage-03.dtd Implements #1029
1 parent c66bba1 commit 3d15f5a

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/cobertura.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,11 @@ fn write_lines(writer: &mut Writer<Cursor<Vec<u8>>>, lines: &[Line]) {
530530
l.push_attribute(("number", number.to_string().as_ref()));
531531
l.push_attribute(("hits", hits.to_string().as_ref()));
532532
l.push_attribute(("branch", "true"));
533+
l.push_attribute((
534+
"condition-coverage",
535+
format_condition_coverage(conditions).as_ref(),
536+
));
537+
533538
writer.write_event(Event::Start(l)).unwrap();
534539

535540
let conditions_tag = "conditions";
@@ -562,6 +567,23 @@ fn write_lines(writer: &mut Writer<Cursor<Vec<u8>>>, lines: &[Line]) {
562567
.unwrap();
563568
}
564569

570+
fn format_condition_coverage(conditions: &[Condition]) -> String {
571+
let conditions_hit: f64 = conditions.iter().map(|c| c.coverage).sum();
572+
let num_conditions = conditions.len();
573+
if num_conditions > 0 {
574+
format!(
575+
"{:.0}% ({:.0}/{})",
576+
100.0 * conditions_hit / num_conditions as f64,
577+
conditions_hit,
578+
num_conditions
579+
)
580+
} else {
581+
// What is the sensible string to put here,
582+
// when a branch has no conditions?
583+
"0% (0/0)".to_owned()
584+
}
585+
}
586+
565587
#[cfg(test)]
566588
mod tests {
567589
use super::*;
@@ -860,4 +882,26 @@ mod tests {
860882
assert!(results.contains(r#"<source>src</source>"#));
861883
assert!(results.contains(r#"package name="main.rs""#));
862884
}
885+
886+
#[test]
887+
fn test_condition_coverage() {
888+
const HIT: Condition = Condition {
889+
coverage: 1.0,
890+
number: 0,
891+
cond_type: ConditionType::Jump,
892+
};
893+
const MISS: Condition = Condition {
894+
coverage: 0.0,
895+
number: 0,
896+
cond_type: ConditionType::Jump,
897+
};
898+
899+
assert_eq!("100% (1/1)", format_condition_coverage(&[HIT]));
900+
assert_eq!("0% (0/1)", format_condition_coverage(&[MISS]));
901+
assert_eq!("50% (1/2)", format_condition_coverage(&[HIT, MISS]));
902+
assert_eq!("33% (1/3)", format_condition_coverage(&[HIT, MISS, MISS]));
903+
assert_eq!("67% (2/3)", format_condition_coverage(&[HIT, HIT, MISS]));
904+
905+
assert_eq!("0% (0/0)", format_condition_coverage(&[]));
906+
}
863907
}

0 commit comments

Comments
 (0)