Skip to content

Commit

Permalink
#441: Added method coverage to reports
Browse files Browse the repository at this point in the history
  • Loading branch information
danielpalme committed Sep 21, 2021
1 parent d03a79f commit 88ee3a8
Show file tree
Hide file tree
Showing 13 changed files with 166 additions and 39 deletions.
1 change: 1 addition & 0 deletions src/Readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ CHANGELOG

4.8.13.0

* New: #441: Added method coverage to reports
* New: #445: Added support for better custom logging
* Fix: #450: Conditional file numbers in class report

Expand Down
6 changes: 6 additions & 0 deletions src/ReportGenerator.Core/Parser/Analysis/Assembly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ public string ShortName
/// </value>
public int TotalCodeElements => this.classes.Sum(f => f.TotalCodeElements);

/// <summary>
/// Gets the code elements coverage quota.
/// </summary>
/// <value>The code elements coverage quota.</value>
public decimal? CodeElementCoverageQuota => (this.TotalCodeElements == 0) ? (decimal?)null : (decimal)Math.Truncate(1000 * (double)this.CoveredCodeElements / (double)this.TotalCodeElements) / 10;

/// <summary>
/// Returns a <see cref="string" /> that represents this instance.
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions src/ReportGenerator.Core/Parser/Analysis/Class.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ internal Class(string name, Assembly assembly)
/// </value>
public int TotalCodeElements => this.files.Sum(f => f.TotalCodeElements);

/// <summary>
/// Gets the code elements coverage quota.
/// </summary>
/// <value>The code elements coverage quota.</value>
public decimal? CodeElementCoverageQuota => (this.TotalCodeElements == 0) ? (decimal?)null : (decimal)Math.Truncate(1000 * (double)this.CoveredCodeElements / (double)this.TotalCodeElements) / 10;

/// <summary>
/// Returns a <see cref="string" /> that represents this instance.
/// </summary>
Expand Down
38 changes: 19 additions & 19 deletions src/ReportGenerator.Core/Parser/Analysis/CodeFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,25 @@ internal CodeFile(string path, int[] lineCoverage, LineVisitStatus[] lineVisitSt
}
}

/// <summary>
/// Gets the number of total branches.
/// </summary>
/// <value>
/// The number of total branches.
/// </value>
public int? TotalBranches
{
get
{
if (this.branches == null)
{
return null;
}

return this.branches.Sum(l => l.Value.Count);
}
}

/// <summary>
/// Gets the number of covered code elements.
/// </summary>
Expand All @@ -196,25 +215,6 @@ public int CoveredCodeElements
/// </value>
public int TotalCodeElements => this.codeElements.Count;

/// <summary>
/// Gets the number of total branches.
/// </summary>
/// <value>
/// The number of total branches.
/// </value>
public int? TotalBranches
{
get
{
if (this.branches == null)
{
return null;
}

return this.branches.Sum(l => l.Value.Count);
}
}

/// <summary>
/// Returns a <see cref="string" /> that represents this instance.
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions src/ReportGenerator.Core/Parser/Analysis/SummaryResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ public SummaryResult(IReadOnlyCollection<Assembly> assemblies, string usedParser
/// </value>
public int TotalCodeElements => this.Assemblies.Sum(f => f.TotalCodeElements);

/// <summary>
/// Gets the code elements coverage quota.
/// </summary>
/// <value>The code elements coverage quota.</value>
public decimal? CodeElementCoverageQuota => (this.TotalCodeElements == 0) ? (decimal?)null : (decimal)Math.Truncate(1000 * (double)this.CoveredCodeElements / (double)this.TotalCodeElements) / 10;

/// <summary>
/// Gets all sumable metrics.
/// </summary>
Expand Down
36 changes: 36 additions & 0 deletions src/ReportGenerator.Core/Properties/ReportResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions src/ReportGenerator.Core/Properties/ReportResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -348,4 +348,16 @@
<data name="File" xml:space="preserve">
<value>File</value>
</data>
<data name="CodeElementCoverageQuota" xml:space="preserve">
<value>Method coverage</value>
</data>
<data name="CodeElementCoverageQuota2" xml:space="preserve">
<value>Method coverage:</value>
</data>
<data name="CoveredCodeElements" xml:space="preserve">
<value>Covered methods:</value>
</data>
<data name="TotalCodeElements" xml:space="preserve">
<value>Total methods:</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -92,26 +92,36 @@ public void CreateSummaryReport(SummaryResult summaryResult)

if (summaryResult.CoverageQuota.HasValue)
{
reportTextWriter.Write($" \"linecoverage\": {summaryResult.CoverageQuota.Value.ToString(CultureInfo.InvariantCulture)}");
reportTextWriter.WriteLine($" \"linecoverage\": {summaryResult.CoverageQuota.Value.ToString(CultureInfo.InvariantCulture)},");
}
else
{
reportTextWriter.Write($" \"linecoverage\": null");
reportTextWriter.WriteLine($" \"linecoverage\": null,");
}

if (summaryResult.CoveredBranches.HasValue && summaryResult.TotalBranches.HasValue)
{
reportTextWriter.WriteLine(",");
reportTextWriter.WriteLine($" \"coveredbranches\": {summaryResult.CoveredBranches.GetValueOrDefault().ToString(CultureInfo.InvariantCulture)},");
reportTextWriter.Write($" \"totalbranches\": {summaryResult.TotalBranches.GetValueOrDefault().ToString(CultureInfo.InvariantCulture)}");
reportTextWriter.WriteLine($" \"totalbranches\": {summaryResult.TotalBranches.GetValueOrDefault().ToString(CultureInfo.InvariantCulture)},");

if (summaryResult.BranchCoverageQuota.HasValue)
{
reportTextWriter.WriteLine(",");
reportTextWriter.Write($" \"branchcoverage\": {summaryResult.BranchCoverageQuota.Value.ToString(CultureInfo.InvariantCulture)}");
reportTextWriter.WriteLine($" \"branchcoverage\": {summaryResult.BranchCoverageQuota.Value.ToString(CultureInfo.InvariantCulture)},");
}
}

reportTextWriter.WriteLine($" \"coveredmethods\": {summaryResult.CoveredCodeElements.ToString(CultureInfo.InvariantCulture)},");
reportTextWriter.WriteLine($" \"totalmethods\": {summaryResult.TotalCodeElements.ToString(CultureInfo.InvariantCulture)},");

if (summaryResult.CodeElementCoverageQuota.HasValue)
{
reportTextWriter.WriteLine($" \"methodcoverage\": {summaryResult.CodeElementCoverageQuota.Value.ToString(CultureInfo.InvariantCulture)}");
}
else
{
reportTextWriter.WriteLine($" \"methodcoverage\": null");
}

reportTextWriter.WriteLine(" },");

var sumableMetrics = summaryResult.SumableMetrics;
Expand Down Expand Up @@ -157,7 +167,7 @@ public void CreateSummaryReport(SummaryResult summaryResult)
reportTextWriter.WriteLine(",");
}

reportTextWriter.WriteLine($" {{ \"name\": \"{JsonSerializer.EscapeString(assembly.Name)}\", \"classes\": {assembly.Classes.Count().ToString(CultureInfo.InvariantCulture)}, \"coverage\": {(assembly.CoverageQuota.HasValue ? assembly.CoverageQuota.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"coveredlines\": {assembly.CoveredLines.ToString(CultureInfo.InvariantCulture)}, \"coverablelines\": {assembly.CoverableLines.ToString(CultureInfo.InvariantCulture)}, \"totallines\": {(assembly.TotalLines.HasValue ? assembly.TotalLines.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"branchcoverage\": {(assembly.BranchCoverageQuota.HasValue ? assembly.BranchCoverageQuota.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"coveredbranches\": {(assembly.CoveredBranches.HasValue ? assembly.CoveredBranches.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"totalbranches\": {(assembly.TotalBranches.HasValue ? assembly.TotalBranches.Value.ToString(CultureInfo.InvariantCulture) : null)}, \"classesinassembly\": [");
reportTextWriter.WriteLine($" {{ \"name\": \"{JsonSerializer.EscapeString(assembly.Name)}\", \"classes\": {assembly.Classes.Count().ToString(CultureInfo.InvariantCulture)}, \"coverage\": {(assembly.CoverageQuota.HasValue ? assembly.CoverageQuota.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"coveredlines\": {assembly.CoveredLines.ToString(CultureInfo.InvariantCulture)}, \"coverablelines\": {assembly.CoverableLines.ToString(CultureInfo.InvariantCulture)}, \"totallines\": {(assembly.TotalLines.HasValue ? assembly.TotalLines.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"branchcoverage\": {(assembly.BranchCoverageQuota.HasValue ? assembly.BranchCoverageQuota.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"coveredbranches\": {(assembly.CoveredBranches.HasValue ? assembly.CoveredBranches.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"totalbranches\": {(assembly.TotalBranches.HasValue ? assembly.TotalBranches.Value.ToString(CultureInfo.InvariantCulture) : null)}, \"methodcoverage\": {(assembly.CodeElementCoverageQuota.HasValue ? assembly.CodeElementCoverageQuota.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"coveredmethods\": {assembly.CoveredCodeElements.ToString(CultureInfo.InvariantCulture)}, \"totalmethods\": {assembly.TotalCodeElements.ToString(CultureInfo.InvariantCulture)}, \"classesinassembly\": [");

int classCounter = 0;

Expand All @@ -168,7 +178,7 @@ public void CreateSummaryReport(SummaryResult summaryResult)
reportTextWriter.WriteLine(",");
}

reportTextWriter.Write($" {{ \"name\": \"{JsonSerializer.EscapeString(@class.Name)}\", \"coverage\": {(@class.CoverageQuota.HasValue ? @class.CoverageQuota.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"coveredlines\": {@class.CoveredLines.ToString(CultureInfo.InvariantCulture)}, \"coverablelines\": {@class.CoverableLines.ToString(CultureInfo.InvariantCulture)}, \"totallines\": {(@class.TotalLines.HasValue ? @class.TotalLines.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"branchcoverage\": {(@class.BranchCoverageQuota.HasValue ? @class.BranchCoverageQuota.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"coveredbranches\": {(@class.CoveredBranches.HasValue ? @class.CoveredBranches.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"totalbranches\": {(@class.TotalBranches.HasValue ? @class.TotalBranches.Value.ToString(CultureInfo.InvariantCulture) : null)} }}");
reportTextWriter.Write($" {{ \"name\": \"{JsonSerializer.EscapeString(@class.Name)}\", \"coverage\": {(@class.CoverageQuota.HasValue ? @class.CoverageQuota.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"coveredlines\": {@class.CoveredLines.ToString(CultureInfo.InvariantCulture)}, \"coverablelines\": {@class.CoverableLines.ToString(CultureInfo.InvariantCulture)}, \"totallines\": {(@class.TotalLines.HasValue ? @class.TotalLines.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"branchcoverage\": {(@class.BranchCoverageQuota.HasValue ? @class.BranchCoverageQuota.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"coveredbranches\": {(@class.CoveredBranches.HasValue ? @class.CoveredBranches.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"totalbranches\": {(@class.TotalBranches.HasValue ? @class.TotalBranches.Value.ToString(CultureInfo.InvariantCulture) : null)}, \"methodcoverage\": {(@class.CodeElementCoverageQuota.HasValue ? @class.CodeElementCoverageQuota.Value.ToString(CultureInfo.InvariantCulture) : "null")}, \"coveredmethods\": {@class.CoveredCodeElements.ToString(CultureInfo.InvariantCulture)}, \"totalmethods\": {@class.TotalCodeElements.ToString(CultureInfo.InvariantCulture)} }}");

classCounter++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ public void CreateSummaryReport(SummaryResult summaryResult)
}
}

reportTextWriter.WriteLine("| {0} | {1} |", ReportResources.CoveredCodeElements, summaryResult.CoveredCodeElements.ToString(CultureInfo.InvariantCulture));
reportTextWriter.WriteLine("| {0} | {1} |", ReportResources.TotalCodeElements, summaryResult.TotalCodeElements.ToString(CultureInfo.InvariantCulture));
reportTextWriter.WriteLine("| {0} | {1} |", ReportResources.CodeElementCoverageQuota2, summaryResult.CodeElementCoverageQuota.HasValue ? $"{summaryResult.CodeElementCoverageQuota.Value.ToString(CultureInfo.InvariantCulture)}% ({summaryResult.CoveredCodeElements.ToString(CultureInfo.InvariantCulture)} {ReportResources.Of} {summaryResult.TotalCodeElements.ToString(CultureInfo.InvariantCulture)})" : string.Empty);

if (this.ReportContext.ReportConfiguration.Tag != null)
{
reportTextWriter.WriteLine("| {0} | {1} |", ReportResources.Tag, this.ReportContext.ReportConfiguration.Tag);
Expand All @@ -122,11 +126,6 @@ public void CreateSummaryReport(SummaryResult summaryResult)

if (summaryResult.Assemblies.Any())
{
var maximumNameLength = summaryResult.Assemblies
.SelectMany(a => a.Classes).Select(c => c.DisplayName)
.Union(summaryResult.Assemblies.Select(a => a.Name))
.Max(n => n.Length);

reportTextWriter.Write(
"|**{0}**|**{1}**|**{2}**|**{3}**|**{4}**|**{5}**|",
ReportResources.Name,
Expand All @@ -139,25 +138,32 @@ public void CreateSummaryReport(SummaryResult summaryResult)
if (summaryResult.SupportsBranchCoverage)
{
reportTextWriter.WriteLine(
"**{0}**|**{1}**|**{2}**|",
"**{0}**|**{1}**|**{2}**|**{3}**|**{4}**|**{5}**|",
ReportResources.Covered,
ReportResources.Total,
ReportResources.BranchCoverage);
ReportResources.BranchCoverage,
ReportResources.Covered,
ReportResources.Total,
ReportResources.CodeElementCoverageQuota);
}
else
{
reportTextWriter.WriteLine(string.Empty);
reportTextWriter.WriteLine(
"**{0}**|**{1}**|**{2}**|",
ReportResources.Covered,
ReportResources.Total,
ReportResources.CodeElementCoverageQuota);
}

reportTextWriter.Write("|:---|---:|---:|---:|---:|---:|");

if (summaryResult.SupportsBranchCoverage)
{
reportTextWriter.WriteLine("---:|---:|---:|");
reportTextWriter.WriteLine("---:|---:|---:|---:|---:|---:|");
}
else
{
reportTextWriter.WriteLine(string.Empty);
reportTextWriter.WriteLine("---:|---:|---:|");
}

foreach (var assembly in summaryResult.Assemblies)
Expand All @@ -176,6 +182,10 @@ public void CreateSummaryReport(SummaryResult summaryResult)
reportTextWriter.Write("|**{0}**", assembly.BranchCoverageQuota.HasValue ? assembly.BranchCoverageQuota.Value.ToString(CultureInfo.InvariantCulture) + "%" : string.Empty);
}

reportTextWriter.Write("|**{0}**", assembly.CoveredCodeElements);
reportTextWriter.Write("|**{0}**", assembly.TotalCodeElements);
reportTextWriter.Write("|**{0}**", assembly.CodeElementCoverageQuota.HasValue ? assembly.CodeElementCoverageQuota.Value.ToString(CultureInfo.InvariantCulture) + "%" : string.Empty);

reportTextWriter.WriteLine("|");

foreach (var @class in assembly.Classes)
Expand All @@ -194,6 +204,10 @@ public void CreateSummaryReport(SummaryResult summaryResult)
reportTextWriter.Write("|{0}", @class.BranchCoverageQuota.HasValue ? @class.BranchCoverageQuota.Value.ToString(CultureInfo.InvariantCulture) + "%" : string.Empty);
}

reportTextWriter.Write("|{0}", @class.CoveredCodeElements);
reportTextWriter.Write("|{0}", @class.TotalCodeElements);
reportTextWriter.Write("|{0}", @class.CodeElementCoverageQuota.HasValue ? @class.CodeElementCoverageQuota.Value.ToString(CultureInfo.InvariantCulture) + "%" : string.Empty);

reportTextWriter.WriteLine("|");
}
}
Expand Down
Loading

0 comments on commit 88ee3a8

Please sign in to comment.