Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 8 additions & 19 deletions FineCodeCoverageTests/FileLineCoverage_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,24 @@ private static ILine CreateLine(int lineNumber, CoverageType coverageType = Cove
return mockLine.Object;
}

[TestCaseSource(nameof(Cases))]
public void GetLines_Test(IEnumerable<int> lineNumbers, int startLineNumber, int endLineNumber, IEnumerable<int> expectedLineNumbers)
[Test]
public void Should_Return_Distinct_Sorted_Lines()
{
var fileLineCoverage = new FileLineCoverage();
fileLineCoverage.Add("fp", lineNumbers.Select((n => CreateLine(n))));
fileLineCoverage.Add("file1", new[] { CreateLine(2), CreateLine(1), CreateLine(3),CreateLine(1) });
fileLineCoverage.Sort();

var lines = fileLineCoverage.GetLines("fp", startLineNumber, endLineNumber);
Assert.That(lines.Select(l => l.Number), Is.EqualTo(expectedLineNumbers));
var lines = fileLineCoverage.GetLines("file1");

Assert.That(lines.Select(l => l.Number), Is.EqualTo(new int[] { 1,2,3}));
}

[Test]
public void Should_Get_Empty_Lines_For_File_Not_In_Report()
{
var fileLineCoverage = new FileLineCoverage();

var lines = fileLineCoverage.GetLines("", 1, 2);
var lines = fileLineCoverage.GetLines("");

Assert.That(lines, Is.Empty);
}
Expand All @@ -50,6 +51,7 @@ public void Should_Rename_When_FileName_Changes()
var fileLineCoverage = new FileLineCoverage();
var lines = new[] { CreateLine(1), CreateLine(2) };
fileLineCoverage.Add("old", lines);
fileLineCoverage.Sort();
AssertLines("old");

fileLineCoverage.UpdateRenamed("old", "new");
Expand All @@ -62,18 +64,5 @@ void AssertLines(string fileName)
Assert.That(allLines, Is.EqualTo(lines));
}
}

static readonly object[] Cases =
{
new object[] { new int[] { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, 19, 20, new int[]{ 19,20} },
new object[] { new int[] { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, 12, 13, new int[]{ 12,13} },
new object[] { new int[] { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, 6, 7, new int[]{ 6,7} },
new object[] {Enumerable.Empty<int>(), 0, 4,Enumerable.Empty<int>() },
new object[] { new int[] { 3,2,1}, 0, 4, new int[]{ 1,2,3} },
new object[] { new int[] { 3,2,1}, 0, 3, new int[]{ 1,2,3} },
new object[] { new int[] { 3,2,1}, 1, 2, new int[]{ 1,2} },
new object[] { new int[] { 3,2,1}, 2, 2, new int[]{ 2} },
new object[] { new int[] { 3,2,1}, 4, 5, Enumerable.Empty<int>() }
};
}
}
61 changes: 41 additions & 20 deletions SharedProject/Core/Cobertura/FileLineCoverage.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,54 @@
using FineCodeCoverage.Core.Utilities;
using FineCodeCoverage.Impl;
using System;
using System;
using System.Collections.Generic;
using System.Linq;

namespace FineCodeCoverage.Engine.Model
{

internal class UniqueCoverageLines : HashSet<ILine>
{
public UniqueCoverageLines() : base(new LineComparer())
{
}

public void AddRange(IEnumerable<ILine> lines)
{
foreach (var line in lines)
Add(line);
}

private IEnumerable<ILine> sortedLines;
public IEnumerable<ILine> SortedLines => sortedLines;

public void Sort()
{
sortedLines = this.OrderBy(l => l.Number).ToList();
}

class LineComparer : IEqualityComparer<ILine>
{
public bool Equals(ILine x, ILine y)
{
return x.Number == y.Number;
}

public int GetHashCode(ILine obj)
{
return obj.Number;
}
}
}

// FileLineCoverage maps from a filename to the list of lines in the file
internal class FileLineCoverage : IFileLineCoverage
{
private readonly Dictionary<string, List<ILine>> m_coverageLines = new Dictionary<string, List<ILine>>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, UniqueCoverageLines> m_coverageLines = new Dictionary<string, UniqueCoverageLines>(StringComparer.OrdinalIgnoreCase);

public void Add(string filename, IEnumerable<ILine> lines)
{
if (!m_coverageLines.TryGetValue(filename, out var fileCoverageLines))
{
fileCoverageLines = new List<ILine>();
fileCoverageLines = new UniqueCoverageLines();
m_coverageLines.Add(filename, fileCoverageLines);
}

Expand All @@ -25,30 +58,18 @@ public void Add(string filename, IEnumerable<ILine> lines)
public void Sort()
{
foreach (var lines in m_coverageLines.Values)
lines.Sort((a, b) => a.Number - b.Number);
lines.Sort();
}

public IEnumerable<ILine> GetLines(string filePath)
{
if (!m_coverageLines.TryGetValue(filePath, out var lines))
{
lines = Enumerable.Empty<ILine>().ToList();
return Enumerable.Empty<ILine>().ToList();
}
return lines;
return lines.SortedLines;

}
public IEnumerable<ILine> GetLines(string filePath, int startLineNumber, int endLineNumber)
{
if (!m_coverageLines.TryGetValue(filePath, out var lines))
yield break;

int first = lines.LowerBound(line => startLineNumber - line.Number);
if (first != -1)
{
for (int it = first; it < lines.Count && lines[it].Number <= endLineNumber; ++it)
yield return lines[it];
}
}

public void UpdateRenamed(string oldFilePath, string newFilePath)
{
Expand Down
1 change: 0 additions & 1 deletion SharedProject/Core/Cobertura/IFileLineCoverage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ namespace FineCodeCoverage.Engine.Model
internal interface IFileLineCoverage
{
void Add(string filename, IEnumerable<ILine> line);
IEnumerable<ILine> GetLines(string filePath, int startLineNumber, int endLineNumber);
IEnumerable<ILine> GetLines(string filePath);
void Sort();
void UpdateRenamed(string oldFile, string newFile);
Expand Down