Skip to content

Commit

Permalink
Merge pull request coverlet-coverage#73 from hunterjm/feature/branchE…
Browse files Browse the repository at this point in the history
…nhancements

Branch Enhancements (take 2)
  • Loading branch information
tonerdo committed May 5, 2018
2 parents 6fdca0f + 6e9b501 commit ac529fb
Show file tree
Hide file tree
Showing 25 changed files with 1,290 additions and 272 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -118,6 +118,7 @@ _TeamCity*
# Visual Studio code coverage results
*.coverage
*.coveragexml
lcov.info

# NCrunch
_NCrunch_*
Expand Down
104 changes: 84 additions & 20 deletions src/coverlet.core/Coverage.cs
Expand Up @@ -49,35 +49,90 @@ public CoverageResult GetCoverageResult()
Documents documents = new Documents();
foreach (var doc in result.Documents)
{
// Construct Line Results
foreach (var line in doc.Lines)
{
if (documents.TryGetValue(doc.Path, out Classes classes))
{
if (classes.TryGetValue(line.Class, out Methods methods))
{
if (methods.TryGetValue(line.Method, out Lines lines))
if (methods.TryGetValue(line.Method, out Method method))
{
documents[doc.Path][line.Class][line.Method].Add(line.Number, new LineInfo { Hits = line.Hits, IsBranchPoint = line.IsBranchTarget });
documents[doc.Path][line.Class][line.Method].Lines.Add(line.Number, new LineInfo { Hits = line.Hits });
}
else
{
documents[doc.Path][line.Class].Add(line.Method, new Lines());
documents[doc.Path][line.Class][line.Method].Add(line.Number, new LineInfo { Hits = line.Hits, IsBranchPoint = line.IsBranchTarget });
documents[doc.Path][line.Class].Add(line.Method, new Method());
documents[doc.Path][line.Class][line.Method].Lines.Add(line.Number, new LineInfo { Hits = line.Hits });
}
}
else
{
documents[doc.Path].Add(line.Class, new Methods());
documents[doc.Path][line.Class].Add(line.Method, new Lines());
documents[doc.Path][line.Class][line.Method].Add(line.Number, new LineInfo { Hits = line.Hits, IsBranchPoint = line.IsBranchTarget });
documents[doc.Path][line.Class].Add(line.Method, new Method());
documents[doc.Path][line.Class][line.Method].Lines.Add(line.Number, new LineInfo { Hits = line.Hits });
}
}
else
{
documents.Add(doc.Path, new Classes());
documents[doc.Path].Add(line.Class, new Methods());
documents[doc.Path][line.Class].Add(line.Method, new Lines());
documents[doc.Path][line.Class][line.Method].Add(line.Number, new LineInfo { Hits = line.Hits, IsBranchPoint = line.IsBranchTarget });
documents[doc.Path][line.Class].Add(line.Method, new Method());
documents[doc.Path][line.Class][line.Method].Lines.Add(line.Number, new LineInfo { Hits = line.Hits });
}
}

// Construct Branch Results
foreach (var branch in doc.Branches)
{
if (documents.TryGetValue(doc.Path, out Classes classes))
{
if (classes.TryGetValue(branch.Class, out Methods methods))
{
if (methods.TryGetValue(branch.Method, out Method method))
{
if (method.Branches.TryGetValue(branch.Number, out List<BranchInfo> branchInfo))
{
documents[doc.Path][branch.Class][branch.Method].Branches[branch.Number].Add(new BranchInfo
{ Hits = branch.Hits, Offset = branch.Offset, EndOffset = branch.EndOffset, Path = branch.Path, Ordinal = branch.Ordinal }
);
}
else
{
documents[doc.Path][branch.Class][branch.Method].Branches.Add(branch.Number, new List<BranchInfo>());
documents[doc.Path][branch.Class][branch.Method].Branches[branch.Number].Add(new BranchInfo
{ Hits = branch.Hits, Offset = branch.Offset, EndOffset = branch.EndOffset, Path = branch.Path, Ordinal = branch.Ordinal }
);
}
}
else
{
documents[doc.Path][branch.Class].Add(branch.Method, new Method());
documents[doc.Path][branch.Class][branch.Method].Branches.Add(branch.Number, new List<BranchInfo>());
documents[doc.Path][branch.Class][branch.Method].Branches[branch.Number].Add(new BranchInfo
{ Hits = branch.Hits, Offset = branch.Offset, EndOffset = branch.EndOffset, Path = branch.Path, Ordinal = branch.Ordinal }
);
}
}
else
{
documents[doc.Path].Add(branch.Class, new Methods());
documents[doc.Path][branch.Class].Add(branch.Method, new Method());
documents[doc.Path][branch.Class][branch.Method].Branches.Add(branch.Number, new List<BranchInfo>());
documents[doc.Path][branch.Class][branch.Method].Branches[branch.Number].Add(new BranchInfo
{ Hits = branch.Hits, Offset = branch.Offset, EndOffset = branch.EndOffset, Path = branch.Path, Ordinal = branch.Ordinal }
);
}
}
else
{
documents.Add(doc.Path, new Classes());
documents[doc.Path].Add(branch.Class, new Methods());
documents[doc.Path][branch.Class].Add(branch.Method, new Method());
documents[doc.Path][branch.Class][branch.Method].Branches.Add(branch.Number, new List<BranchInfo>());
documents[doc.Path][branch.Class][branch.Method].Branches[branch.Number].Add(new BranchInfo
{ Hits = branch.Hits, Offset = branch.Offset, EndOffset = branch.EndOffset, Path = branch.Path, Ordinal = branch.Ordinal }
);
}
}
}
Expand All @@ -99,28 +154,37 @@ private void CalculateCoverage()
{
if (!File.Exists(result.HitsFilePath)) { continue; }
var lines = InstrumentationHelper.ReadHitsFile(result.HitsFilePath);
foreach (var line in lines)
foreach (var row in lines)
{
var info = line.Split(',');
var info = row.Split(',');
// Ignore malformed lines
if (info.Length != 4)
continue;

var document = result.Documents.FirstOrDefault(d => d.Path == info[0]);
bool isBranch = info[0] == "B";

var document = result.Documents.FirstOrDefault(d => d.Path == info[1]);
if (document == null)
continue;

int start = int.Parse(info[1]);
int end = int.Parse(info[2]);
bool target = info[3] == "B";
int start = int.Parse(info[2]);

for (int j = start; j <= end; j++)
if (isBranch)
{
var subLine = document.Lines.First(l => l.Number == j);
subLine.Hits = subLine.Hits + 1;

if (j == start)
subLine.IsBranchTarget = target;
uint ordinal = uint.Parse(info[3]);
var branch = document.Branches.First(b => b.Number == start && b.Ordinal == ordinal);
if (branch.Hits != int.MaxValue)
branch.Hits += branch.Hits + 1;
}
else
{
int end = int.Parse(info[3]);
for (int j = start; j <= end; j++)
{
var line = document.Lines.First(l => l.Number == j);
if (line.Hits != int.MaxValue)
line.Hits = line.Hits + 1;
}
}
}

Expand Down
14 changes: 14 additions & 0 deletions src/coverlet.core/CoverageDetails.cs
@@ -0,0 +1,14 @@
using System;

namespace Coverlet.Core
{
public class CoverageDetails
{
public double Covered { get; internal set; }
public int Total { get; internal set; }
public double Percent
{
get => Math.Round(Total == 0 ? Total : Covered / Total, 3);
}
}
}
22 changes: 20 additions & 2 deletions src/coverlet.core/CoverageResult.cs
Expand Up @@ -8,11 +8,29 @@ namespace Coverlet.Core
public class LineInfo
{
public int Hits { get; set; }
public bool IsBranchPoint { get; set; }
}

public class BranchInfo : LineInfo
{
public int Offset { get; set; }
public int EndOffset { get; set; }
public int Path { get; set; }
public uint Ordinal { get; set; }
}

public class Lines : SortedDictionary<int, LineInfo> { }
public class Methods : Dictionary<string, Lines> { }
public class Branches : SortedDictionary<int, List<BranchInfo>> { }
public class Method
{
internal Method()
{
Lines = new Lines();
Branches = new Branches();
}
public Lines Lines;
public Branches Branches;
}
public class Methods : Dictionary<string, Method> { }
public class Classes : Dictionary<string, Methods> { }
public class Documents : Dictionary<string, Classes> { }
public class Modules : Dictionary<string, Documents> { }
Expand Down

0 comments on commit ac529fb

Please sign in to comment.