From f73021b0816256294703c366fb2efed9044632c2 Mon Sep 17 00:00:00 2001 From: "Benjamin W. Zale" Date: Sat, 16 Jan 2021 15:00:29 -0500 Subject: [PATCH 1/2] Implementation of Npath complexity for the OpenCover reports --- src/coverlet.core/CoverageSummary.cs | 33 +++++++++++++++++++ .../Reporters/OpenCoverReporter.cs | 3 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/coverlet.core/CoverageSummary.cs b/src/coverlet.core/CoverageSummary.cs index 5a64e0b93..c96651352 100644 --- a/src/coverlet.core/CoverageSummary.cs +++ b/src/coverlet.core/CoverageSummary.cs @@ -73,6 +73,39 @@ public CoverageDetails CalculateBranchCoverage(IList branches) return details; } + public int CalculateNpathComplexity(IList branches) + { + // Adapted from OpenCover see https://github.com/OpenCover/opencover/blob/master/main/OpenCover.Framework/Persistance/BasePersistance.cs#L419 + if (!branches.Any()) + { + return 0; + } + + var paths = new Dictionary(); + foreach (var branch in branches) + { + if (!paths.TryGetValue(branch.Offset, out int count)) + { + count = 0; + } + paths[branch.Offset] = count++; + } + + int npath = 1; + foreach (var branchPoints in paths.Values) + { + try + { + npath = checked(npath * branchPoints); + } + catch (OverflowException) + { + npath = int.MaxValue; + } + } + return npath; + } + public int CalculateCyclomaticComplexity(IList branches) { return Math.Max(1, branches.Count); diff --git a/src/coverlet.core/Reporters/OpenCoverReporter.cs b/src/coverlet.core/Reporters/OpenCoverReporter.cs index 3c4c66b45..c4135d7a0 100644 --- a/src/coverlet.core/Reporters/OpenCoverReporter.cs +++ b/src/coverlet.core/Reporters/OpenCoverReporter.cs @@ -71,11 +71,12 @@ public string Report(CoverageResult result) var methLineCoverage = summary.CalculateLineCoverage(meth.Value.Lines); var methBranchCoverage = summary.CalculateBranchCoverage(meth.Value.Branches); var methCyclomaticComplexity = summary.CalculateCyclomaticComplexity(meth.Value.Branches); + var methNpathComplexity = summary.CalculateNpathComplexity(meth.Value.Branches); XElement method = new XElement("Method"); method.Add(new XAttribute("cyclomaticComplexity", methCyclomaticComplexity.ToString())); - method.Add(new XAttribute("nPathComplexity", "0")); + method.Add(new XAttribute("nPathComplexity", methCyclomaticComplexity.ToString())); method.Add(new XAttribute("sequenceCoverage", methLineCoverage.Percent.ToString("G", CultureInfo.InvariantCulture))); method.Add(new XAttribute("branchCoverage", methBranchCoverage.Percent.ToString("G", CultureInfo.InvariantCulture))); method.Add(new XAttribute("isConstructor", meth.Key.Contains("ctor").ToString())); From e3bb9c6b5e8049ad77556f70b755a7800f0bd24e Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Sun, 14 Mar 2021 17:29:54 +0100 Subject: [PATCH 2/2] add test --- src/coverlet.core/CoverageSummary.cs | 3 ++- test/coverlet.core.tests/Reporters/OpenCoverReporterTests.cs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coverlet.core/CoverageSummary.cs b/src/coverlet.core/CoverageSummary.cs index c96651352..188e204d5 100644 --- a/src/coverlet.core/CoverageSummary.cs +++ b/src/coverlet.core/CoverageSummary.cs @@ -88,7 +88,7 @@ public int CalculateNpathComplexity(IList branches) { count = 0; } - paths[branch.Offset] = count++; + paths[branch.Offset] = ++count; } int npath = 1; @@ -101,6 +101,7 @@ public int CalculateNpathComplexity(IList branches) catch (OverflowException) { npath = int.MaxValue; + break; } } return npath; diff --git a/test/coverlet.core.tests/Reporters/OpenCoverReporterTests.cs b/test/coverlet.core.tests/Reporters/OpenCoverReporterTests.cs index f614d72b4..ee4a90b5a 100644 --- a/test/coverlet.core.tests/Reporters/OpenCoverReporterTests.cs +++ b/test/coverlet.core.tests/Reporters/OpenCoverReporterTests.cs @@ -24,6 +24,7 @@ public void TestReport() XDocument doc = XDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(report))); Assert.Empty(doc.Descendants().Attributes("sequenceCoverage").Where(v => v.Value != "33.33")); Assert.Empty(doc.Descendants().Attributes("branchCoverage").Where(v => v.Value != "25")); + Assert.Empty(doc.Descendants().Attributes("nPathComplexity").Where(v => v.Value != "4")); } [Fact]