Skip to content

Commit 45bc5bc

Browse files
committed
add support for merging coverage results
1 parent 735daa4 commit 45bc5bc

File tree

6 files changed

+91
-7
lines changed

6 files changed

+91
-7
lines changed

src/coverlet.core/Coverage.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using Coverlet.Core.Helpers;
77
using Coverlet.Core.Instrumentation;
88

9+
using Newtonsoft.Json;
10+
911
namespace Coverlet.Core
1012
{
1113
public class Coverage
@@ -15,19 +17,22 @@ public class Coverage
1517
private string[] _excludeFilters;
1618
private string[] _includeFilters;
1719
private string[] _excludedSourceFiles;
20+
private string _mergeWith;
1821
private List<InstrumenterResult> _results;
1922

2023
public string Identifier
2124
{
2225
get { return _identifier; }
2326
}
2427

25-
public Coverage(string module, string[] excludeFilters, string[] includeFilters, string[] excludedSourceFiles)
28+
public Coverage(string module, string[] excludeFilters, string[] includeFilters, string[] excludedSourceFiles, string mergeWith)
2629
{
2730
_module = module;
2831
_excludeFilters = excludeFilters;
2932
_includeFilters = includeFilters;
3033
_excludedSourceFiles = excludedSourceFiles;
34+
_mergeWith = mergeWith;
35+
3136
_identifier = Guid.NewGuid().ToString();
3237
_results = new List<InstrumenterResult>();
3338
}
@@ -144,11 +149,14 @@ public CoverageResult GetCoverageResult()
144149
InstrumentationHelper.RestoreOriginalModule(result.ModulePath, _identifier);
145150
}
146151

147-
return new CoverageResult
152+
var coverageResult = new CoverageResult { Identifier = _identifier, Modules = modules };
153+
if (!string.IsNullOrEmpty(_mergeWith) && !string.IsNullOrWhiteSpace(_mergeWith))
148154
{
149-
Identifier = _identifier,
150-
Modules = modules
151-
};
155+
string json = File.ReadAllText(_mergeWith);
156+
coverageResult.Merge(JsonConvert.DeserializeObject<Modules>(json));
157+
}
158+
159+
return coverageResult;
152160
}
153161

154162
private void CalculateCoverage()

src/coverlet.core/CoverageResult.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.IO;
3+
using System.Linq;
34

45
namespace Coverlet.Core
56
{
@@ -38,5 +39,70 @@ public class CoverageResult
3839
public Modules Modules;
3940

4041
internal CoverageResult() { }
42+
43+
internal void Merge(Modules modules)
44+
{
45+
foreach (var module in modules)
46+
{
47+
if (!this.Modules.ContainsKey(module.Key))
48+
{
49+
this.Modules.Add(module.Key, module.Value);
50+
}
51+
else
52+
{
53+
foreach (var document in module.Value)
54+
{
55+
if (!this.Modules[module.Key].ContainsKey(document.Key))
56+
{
57+
this.Modules[module.Key].Add(document.Key, document.Value);
58+
}
59+
else
60+
{
61+
foreach (var @class in document.Value)
62+
{
63+
if (!this.Modules[module.Key][document.Key].ContainsKey(@class.Key))
64+
{
65+
this.Modules[module.Key][document.Key].Add(@class.Key, @class.Value);
66+
}
67+
else
68+
{
69+
foreach (var method in @class.Value)
70+
{
71+
if (!this.Modules[module.Key][document.Key][@class.Key].ContainsKey(method.Key))
72+
{
73+
this.Modules[module.Key][document.Key][@class.Key].Add(method.Key, method.Value);
74+
}
75+
else
76+
{
77+
foreach (var line in method.Value.Lines)
78+
{
79+
if (!this.Modules[module.Key][document.Key][@class.Key][method.Key].Lines.ContainsKey(line.Key))
80+
{
81+
this.Modules[module.Key][document.Key][@class.Key][method.Key].Lines.Add(line.Key, line.Value);
82+
}
83+
else
84+
{
85+
this.Modules[module.Key][document.Key][@class.Key][method.Key].Lines[line.Key] += line.Value;
86+
}
87+
}
88+
89+
foreach (var branch in method.Value.Branches)
90+
{
91+
var branches = this.Modules[module.Key][document.Key][@class.Key][method.Key].Branches;
92+
var branchInfo = branches.FirstOrDefault(b => b.EndOffset == branch.EndOffset && b.Line == branch.Line && b.Offset == branch.Offset && b.Ordinal == branch.Ordinal && b.Path == branch.Path);
93+
if (branchInfo == null)
94+
branches.Add(branch);
95+
else
96+
branchInfo.Hits += branch.Hits;
97+
}
98+
}
99+
}
100+
}
101+
}
102+
}
103+
}
104+
}
105+
}
106+
}
41107
}
42108
}

src/coverlet.msbuild.tasks/InstrumentationTask.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class InstrumentationTask : Task
1212
private string _exclude;
1313
private string _include;
1414
private string _excludeByFile;
15+
private string _mergeWith;
1516

1617
internal static Coverage Coverage
1718
{
@@ -43,6 +44,12 @@ public string ExcludeByFile
4344
set { _excludeByFile = value; }
4445
}
4546

47+
public string MergeWith
48+
{
49+
get { return _mergeWith; }
50+
set { _mergeWith = value; }
51+
}
52+
4653
public override bool Execute()
4754
{
4855
try
@@ -51,7 +58,7 @@ public override bool Execute()
5158
var excludeFilters = _exclude?.Split(',');
5259
var includeFilters = _include?.Split(',');
5360

54-
_coverage = new Coverage(_path, excludeFilters, includeFilters, excludedSourceFiles);
61+
_coverage = new Coverage(_path, excludeFilters, includeFilters, excludedSourceFiles, _mergeWith);
5562
_coverage.PrepareModules();
5663
}
5764
catch (Exception ex)

src/coverlet.msbuild/coverlet.msbuild.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<CoverletOutput Condition="$(CoverletOutput) == ''">$([MSBuild]::EnsureTrailingSlash('$(MSBuildProjectDirectory)'))</CoverletOutput>
66
<Exclude Condition="$(Exclude) == ''"></Exclude>
77
<ExcludeByFile Condition="$(ExcludeByFile) == ''"></ExcludeByFile>
8+
<MergeWith Condition="$(MergeWith) == ''"></MergeWith>
89
<Threshold Condition="$(Threshold) == ''">0</Threshold>
910
<ThresholdType Condition="$(ThresholdType) == ''">line,branch,method</ThresholdType>
1011
</PropertyGroup>

src/coverlet.msbuild/coverlet.msbuild.targets

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
Condition="'$(VSTestNoBuild)' == 'true' and $(CollectCoverage) == 'true'"
99
Exclude="$(Exclude)"
1010
ExcludeByFile="$(ExcludeByFile)"
11+
MergeWith="$(MergeWith)"
1112
Path="$(TargetPath)" />
1213
</Target>
1314

@@ -16,6 +17,7 @@
1617
Condition="'$(VSTestNoBuild)' != 'true' and $(CollectCoverage) == 'true'"
1718
Exclude="$(Exclude)"
1819
ExcludeByFile="$(ExcludeByFile)"
20+
MergeWith="$(MergeWith)"
1921
Path="$(TargetPath)" />
2022
</Target>
2123

test/coverlet.core.tests/CoverageTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public void TestCoverage()
2727
// Since Coverage only instruments dependancies, we need a fake module here
2828
var testModule = Path.Combine(directory.FullName, "test.module.dll");
2929

30-
var coverage = new Coverage(testModule, Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>());
30+
var coverage = new Coverage(testModule, Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), string.Empty);
3131
coverage.PrepareModules();
3232

3333
var result = coverage.GetCoverageResult();

0 commit comments

Comments
 (0)