Skip to content

Commit ec180b2

Browse files
Add support for line branch coverage for OpenCover (#772)
Fixes #769
1 parent 8ddbb6f commit ec180b2

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

src/coverlet.core/Reporters/OpenCoverReporter.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Globalization;
43
using System.IO;
54
using System.Linq;
@@ -113,6 +112,9 @@ public string Report(CoverageResult result)
113112

114113
foreach (var lines in meth.Value.Lines)
115114
{
115+
var lineBranches = meth.Value.Branches.Where(branchInfo => branchInfo.Line == lines.Key).ToArray();
116+
var branchCoverage = summary.CalculateBranchCoverage(lineBranches);
117+
116118
XElement sequencePoint = new XElement("SequencePoint");
117119
sequencePoint.Add(new XAttribute("vc", lines.Value.ToString()));
118120
sequencePoint.Add(new XAttribute("uspid", lines.Key.ToString()));
@@ -121,8 +123,8 @@ public string Report(CoverageResult result)
121123
sequencePoint.Add(new XAttribute("sc", "1"));
122124
sequencePoint.Add(new XAttribute("el", lines.Key.ToString()));
123125
sequencePoint.Add(new XAttribute("ec", "2"));
124-
sequencePoint.Add(new XAttribute("bec", "0"));
125-
sequencePoint.Add(new XAttribute("bev", "0"));
126+
sequencePoint.Add(new XAttribute("bec", branchCoverage.Total));
127+
sequencePoint.Add(new XAttribute("bev", branchCoverage.Covered));
126128
sequencePoint.Add(new XAttribute("fileid", i.ToString()));
127129
sequencePoints.Add(sequencePoint);
128130

test/coverlet.core.tests/Reporters/OpenCoverReporterTests.cs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.IO;
43
using System.Linq;
54
using System.Text;
@@ -45,6 +44,30 @@ public void TestFilesHaveUniqueIdsOverMultipleModules()
4544
Assert.Contains(@"<FileRef uid=""2"" />", xml);
4645
}
4746

47+
[Fact]
48+
public void TestLineBranchCoverage()
49+
{
50+
var result = new CoverageResult
51+
{
52+
Identifier = Guid.NewGuid().ToString(),
53+
Modules = new Modules { {"Coverlet.Core.Reporters.Tests", CreateBranchCoverageDocuments()} }
54+
};
55+
56+
var xml = new OpenCoverReporter().Report(result);
57+
58+
// Line 1: Two branches, no coverage (bec = 2, bev = 0)
59+
Assert.Contains(@"<SequencePoint vc=""1"" uspid=""1"" ordinal=""0"" sl=""1"" sc=""1"" el=""1"" ec=""2"" bec=""2"" bev=""0"" fileid=""1"" />", xml);
60+
61+
// Line 2: Two branches, one covered (bec = 2, bev = 1)
62+
Assert.Contains(@"<SequencePoint vc=""1"" uspid=""2"" ordinal=""1"" sl=""2"" sc=""1"" el=""2"" ec=""2"" bec=""2"" bev=""1"" fileid=""1"" />", xml);
63+
64+
// Line 3: Two branches, all covered (bec = 2, bev = 2)
65+
Assert.Contains(@"<SequencePoint vc=""1"" uspid=""3"" ordinal=""2"" sl=""3"" sc=""1"" el=""3"" ec=""2"" bec=""2"" bev=""2"" fileid=""1"" />", xml);
66+
67+
// Line 4: Three branches, two covered (bec = 3, bev = 2)
68+
Assert.Contains(@"<SequencePoint vc=""1"" uspid=""4"" ordinal=""3"" sl=""4"" sc=""1"" el=""4"" ec=""2"" bec=""3"" bev=""2"" fileid=""1"" />", xml);
69+
}
70+
4871
private static Documents CreateFirstDocuments()
4972
{
5073
Lines lines = new Lines();
@@ -92,5 +115,47 @@ private static Documents CreateSecondDocuments()
92115

93116
return documents;
94117
}
118+
119+
private static Documents CreateBranchCoverageDocuments()
120+
{
121+
var lines = new Lines
122+
{
123+
{1, 1},
124+
{2, 1},
125+
{3, 1},
126+
{4, 1},
127+
};
128+
129+
var branches = new Branches
130+
{
131+
// Two branches, no coverage
132+
new BranchInfo {Line = 1, Hits = 0, Offset = 23, EndOffset = 24, Path = 0, Ordinal = 1},
133+
new BranchInfo {Line = 1, Hits = 0, Offset = 23, EndOffset = 27, Path = 1, Ordinal = 2},
134+
135+
// Two branches, one covered
136+
new BranchInfo {Line = 2, Hits = 1, Offset = 40, EndOffset = 41, Path = 0, Ordinal = 3},
137+
new BranchInfo {Line = 2, Hits = 0, Offset = 40, EndOffset = 44, Path = 1, Ordinal = 4},
138+
139+
// Two branches, all covered
140+
new BranchInfo {Line = 3, Hits = 1, Offset = 40, EndOffset = 41, Path = 0, Ordinal = 3},
141+
new BranchInfo {Line = 3, Hits = 3, Offset = 40, EndOffset = 44, Path = 1, Ordinal = 4},
142+
143+
// Three branches, two covered
144+
new BranchInfo {Line = 4, Hits = 5, Offset = 40, EndOffset = 44, Path = 1, Ordinal = 4},
145+
new BranchInfo {Line = 4, Hits = 2, Offset = 40, EndOffset = 44, Path = 1, Ordinal = 4},
146+
new BranchInfo {Line = 4, Hits = 0, Offset = 40, EndOffset = 44, Path = 1, Ordinal = 4}
147+
};
148+
149+
const string methodString = "System.Void Coverlet.Core.Reporters.Tests.OpenCoverReporterTests.TestReport()";
150+
var methods = new Methods
151+
{
152+
{methodString, new Method { Lines = lines, Branches = branches}}
153+
};
154+
155+
return new Documents
156+
{
157+
{"doc.cs", new Classes {{"Coverlet.Core.Reporters.Tests.OpenCoverReporterTests", methods}}}
158+
};
159+
}
95160
}
96161
}

0 commit comments

Comments
 (0)