From dce078f19730f7c11c3877b192564e39560ff245 Mon Sep 17 00:00:00 2001 From: Tony Hallett Date: Sat, 29 Jun 2024 12:10:34 +0100 Subject: [PATCH] remove duplicate coverage lines --- .../FileLineCoverage_Tests.cs | 27 +++----- .../Core/Cobertura/FileLineCoverage.cs | 61 +++++++++++++------ .../Core/Cobertura/IFileLineCoverage.cs | 1 - 3 files changed, 49 insertions(+), 40 deletions(-) diff --git a/FineCodeCoverageTests/FileLineCoverage_Tests.cs b/FineCodeCoverageTests/FileLineCoverage_Tests.cs index 3cc6ea46..03c1e8c3 100644 --- a/FineCodeCoverageTests/FileLineCoverage_Tests.cs +++ b/FineCodeCoverageTests/FileLineCoverage_Tests.cs @@ -16,15 +16,16 @@ private static ILine CreateLine(int lineNumber, CoverageType coverageType = Cove return mockLine.Object; } - [TestCaseSource(nameof(Cases))] - public void GetLines_Test(IEnumerable lineNumbers, int startLineNumber, int endLineNumber, IEnumerable 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] @@ -32,7 +33,7 @@ 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); } @@ -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"); @@ -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(), 0, 4,Enumerable.Empty() }, - 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() } - }; } } diff --git a/SharedProject/Core/Cobertura/FileLineCoverage.cs b/SharedProject/Core/Cobertura/FileLineCoverage.cs index 822b1c97..5a828332 100644 --- a/SharedProject/Core/Cobertura/FileLineCoverage.cs +++ b/SharedProject/Core/Cobertura/FileLineCoverage.cs @@ -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 + { + public UniqueCoverageLines() : base(new LineComparer()) + { + } + + public void AddRange(IEnumerable lines) + { + foreach (var line in lines) + Add(line); + } + + private IEnumerable sortedLines; + public IEnumerable SortedLines => sortedLines; + + public void Sort() + { + sortedLines = this.OrderBy(l => l.Number).ToList(); + } + + class LineComparer : IEqualityComparer + { + 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> m_coverageLines = new Dictionary>(StringComparer.OrdinalIgnoreCase); + private readonly Dictionary m_coverageLines = new Dictionary(StringComparer.OrdinalIgnoreCase); public void Add(string filename, IEnumerable lines) { if (!m_coverageLines.TryGetValue(filename, out var fileCoverageLines)) { - fileCoverageLines = new List(); + fileCoverageLines = new UniqueCoverageLines(); m_coverageLines.Add(filename, fileCoverageLines); } @@ -25,30 +58,18 @@ public void Add(string filename, IEnumerable lines) public void Sort() { foreach (var lines in m_coverageLines.Values) - lines.Sort((a, b) => a.Number - b.Number); + lines.Sort(); } public IEnumerable GetLines(string filePath) { if (!m_coverageLines.TryGetValue(filePath, out var lines)) { - lines = Enumerable.Empty().ToList(); + return Enumerable.Empty().ToList(); } - return lines; + return lines.SortedLines; } - public IEnumerable 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) { diff --git a/SharedProject/Core/Cobertura/IFileLineCoverage.cs b/SharedProject/Core/Cobertura/IFileLineCoverage.cs index b9eafc7d..4e9e86b0 100644 --- a/SharedProject/Core/Cobertura/IFileLineCoverage.cs +++ b/SharedProject/Core/Cobertura/IFileLineCoverage.cs @@ -5,7 +5,6 @@ namespace FineCodeCoverage.Engine.Model internal interface IFileLineCoverage { void Add(string filename, IEnumerable line); - IEnumerable GetLines(string filePath, int startLineNumber, int endLineNumber); IEnumerable GetLines(string filePath); void Sort(); void UpdateRenamed(string oldFile, string newFile);