Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Branch Enhancements (take 2) #73

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
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