Skip to content

Commit

Permalink
#497: Added coverage date to summary reports (for Cobertura and JaCoC…
Browse files Browse the repository at this point in the history
…o coverage files)
  • Loading branch information
danielpalme committed Mar 10, 2022
1 parent f99a1f2 commit 4bc9f98
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ CHANGELOG
* New: #433: Added report types Html_Light, Html_Dark and HtmlInline_AzurePipelines_Light
* New: HTML reports: Replaced tabular data with cards
* New: Added method coverage to summary table (PRO version only)
* New: #497: Added coverage date to summary reports (for Cobertura and JaCoCo coverage files)
* New: #494: Fixed MSBuild task

5.0.4.0

Expand Down
38 changes: 38 additions & 0 deletions src/ReportGenerator.Core/Parser/Analysis/SummaryResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public class SummaryResult
public SummaryResult(ParserResult parserResult)
: this(parserResult.Assemblies, parserResult.ParserName, parserResult.SupportsBranchCoverage, parserResult.SourceDirectories)
{
this.MinimumTimeStamp = parserResult.MinimumTimeStamp;
this.MaximumTimeStamp = parserResult.MaximumTimeStamp;
}

/// <summary>
Expand Down Expand Up @@ -65,6 +67,16 @@ public SummaryResult(IReadOnlyCollection<Assembly> assemblies, string usedParser
/// </value>
public IReadOnlyCollection<string> SourceDirectories { get; }

/// <summary>
/// Gets the timestamp on which the coverage report was generated.
/// </summary>
public DateTime? MinimumTimeStamp { get; }

/// <summary>
/// Gets the timestamp on which the coverage report was generated.
/// </summary>
public DateTime? MaximumTimeStamp { get; }

/// <summary>
/// Gets the number of covered lines.
/// </summary>
Expand Down Expand Up @@ -171,5 +183,31 @@ public SummaryResult(IReadOnlyCollection<Assembly> assemblies, string usedParser
.GroupBy(m => m.Name)
.Select(g => new Metric(g.Key, g.First().ExplanationUrl, MetricType.CoverageAbsolute, g.Sum(m => m.Value)))
.ToList();

/// <summary>
/// Get the coverage date(s) based on the minimum and maximum timestamp.
/// </summary>
/// <returns> The coverage date(s).</returns>
public string CoverageDate()
{
string value = null;

if (this.MinimumTimeStamp.HasValue)
{
value = $"{this.MinimumTimeStamp.Value.ToShortDateString()} - {this.MinimumTimeStamp.Value.ToLongTimeString()}";

if (this.MaximumTimeStamp.HasValue
&& !this.MinimumTimeStamp.Value.Equals(this.MaximumTimeStamp.Value))
{
value += $" - {this.MaximumTimeStamp.Value.ToShortDateString()} - {this.MaximumTimeStamp.Value.ToLongTimeString()}";
}
}
else if (this.MaximumTimeStamp.HasValue)
{
value = $"{this.MaximumTimeStamp.Value.ToShortDateString()} - {this.MaximumTimeStamp.Value.ToLongTimeString()}";
}

return value;
}
}
}
16 changes: 16 additions & 0 deletions src/ReportGenerator.Core/Parser/CoberturaParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,22 @@ public ParserResult Parse(XContainer report)
result.AddSourceDirectory(sourceElement.Value);
}

if (report.Element("sources").Parent.Attribute("timestamp") != null)
{
try
{
DateTime timeStamp = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
timeStamp = timeStamp.AddSeconds(double.Parse(report.Element("sources").Parent.Attribute("timestamp").Value)).ToLocalTime();

result.MinimumTimeStamp = timeStamp;
result.MaximumTimeStamp = timeStamp;
}
catch (Exception)
{
// Ignore since timestamp is not relevant. If timestamp is missing or in wrong format the information is just missing in the report(s)
}
}

return result;
}

Expand Down
17 changes: 17 additions & 0 deletions src/ReportGenerator.Core/Parser/JaCoCoParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,23 @@ public ParserResult Parse(XContainer report)
}

var result = new ParserResult(assemblies.OrderBy(a => a.Name).ToList(), true, this.ToString());

if (report.Element("sessioninfo")?.Attribute("start") != null)
{
try
{
DateTime timeStamp = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
timeStamp = timeStamp.AddMilliseconds(double.Parse(report.Element("sessioninfo").Attribute("start").Value)).ToLocalTime();

result.MinimumTimeStamp = timeStamp;
result.MaximumTimeStamp = timeStamp;
}
catch (Exception)
{
// Ignore since timestamp is not relevant. If timestamp is missing or in wrong format the information is just missing in the report(s)
}
}

return result;
}

Expand Down
70 changes: 70 additions & 0 deletions src/ReportGenerator.Core/Parser/ParserResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ public ParserResult(List<Assembly> assemblies, bool supportsBranchCoverage, stri
/// </value>
public bool SupportsBranchCoverage { get; private set; }

/// <summary>
/// Gets the timestamp on which the coverage report was generated.
/// </summary>
public DateTime? MinimumTimeStamp { get; internal set; }

/// <summary>
/// Gets the timestamp on which the coverage report was generated.
/// </summary>
public DateTime? MaximumTimeStamp { get; internal set; }

/// <summary>
/// Gets the names of the parsers.
/// </summary>
Expand Down Expand Up @@ -147,6 +157,66 @@ internal void Merge(ParserResult parserResult)

this.SupportsBranchCoverage |= parserResult.SupportsBranchCoverage;
this.parserNames.AddRange(parserResult.parserNames);

if (this.MinimumTimeStamp.HasValue)
{
if (parserResult.MinimumTimeStamp.HasValue)
{
this.MinimumTimeStamp = Min(this.MinimumTimeStamp.Value, parserResult.MinimumTimeStamp.Value);
}
}
else
{
this.MinimumTimeStamp = parserResult.MinimumTimeStamp;
}

if (this.MaximumTimeStamp.HasValue)
{
if (parserResult.MaximumTimeStamp.HasValue)
{
this.MaximumTimeStamp = Max(this.MaximumTimeStamp.Value, parserResult.MaximumTimeStamp.Value);
}
}
else
{
this.MaximumTimeStamp = parserResult.MaximumTimeStamp;
}
}

/// <summary>
/// Returns the minimum date.
/// </summary>
/// <param name="first">The first date.</param>
/// <param name="second">The second date.</param>
/// <returns>The minimum of the two dates.</returns>
private static DateTime Min(DateTime first, DateTime second)
{
if (first < second)
{
return first;
}
else
{
return second;
}
}

/// <summary>
/// Returns the maximum date.
/// </summary>
/// <param name="first">The first date.</param>
/// <param name="second">The second date.</param>
/// <returns>The maximum of the two dates.</returns>
private static DateTime Max(DateTime first, DateTime second)
{
if (first > second)
{
return first;
}
else
{
return second;
}
}
}
}

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

3 changes: 3 additions & 0 deletions src/ReportGenerator.Core/Properties/ReportResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -381,4 +381,7 @@
<data name="MethodCoverageProVersion" xml:space="preserve">
<value>Method coverage is only available for sponsors.</value>
</data>
<data name="CoverageDate" xml:space="preserve">
<value>Coverage date:</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,11 @@ public virtual void CreateSummaryReport(IHtmlRenderer reportRenderer, SummaryRes
infoCardItems.Add(new CardLineItem(ReportResources.Tag, this.ReportContext.ReportConfiguration.Tag, null, CardLineItemAlignment.Left));
}

if (summaryResult.MinimumTimeStamp.HasValue || summaryResult.MaximumTimeStamp.HasValue)
{
infoCardItems.Add(new CardLineItem(ReportResources.CoverageDate, summaryResult.CoverageDate(), null, CardLineItemAlignment.Left));
}

var cards = new List<Card>()
{
new Card(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ public virtual void CreateSummaryReport(ILatexRenderer reportRenderer, SummaryRe

reportRenderer.BeginKeyValueTable();
reportRenderer.KeyValueRow(ReportResources.GeneratedOn, DateTime.Now.ToShortDateString() + " - " + DateTime.Now.ToLongTimeString());

if (summaryResult.MinimumTimeStamp.HasValue || summaryResult.MaximumTimeStamp.HasValue)
{
reportRenderer.KeyValueRow(ReportResources.CoverageDate, summaryResult.CoverageDate());
}

reportRenderer.KeyValueRow(ReportResources.Parser, summaryResult.UsedParser);
reportRenderer.KeyValueRow(ReportResources.Assemblies2, summaryResult.Assemblies.Count().ToString(CultureInfo.InvariantCulture));
reportRenderer.KeyValueRow(ReportResources.Classes, summaryResult.Assemblies.SelectMany(a => a.Classes).Count().ToString(CultureInfo.InvariantCulture));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ public void CreateSummaryReport(SummaryResult summaryResult)
reportTextWriter.WriteLine("|||");
reportTextWriter.WriteLine("|:---|:---|");
reportTextWriter.WriteLine("| {0} | {1} |", ReportResources.GeneratedOn, DateTime.Now.ToShortDateString() + " - " + DateTime.Now.ToLongTimeString());

if (summaryResult.MinimumTimeStamp.HasValue || summaryResult.MaximumTimeStamp.HasValue)
{
reportTextWriter.WriteLine("| {0} | {1} |", ReportResources.CoverageDate, summaryResult.CoverageDate());
}

reportTextWriter.WriteLine("| {0} | {1} |", ReportResources.Parser, summaryResult.UsedParser);
reportTextWriter.WriteLine("| {0} | {1} |", ReportResources.Assemblies2, summaryResult.Assemblies.Count().ToString(CultureInfo.InvariantCulture));
reportTextWriter.WriteLine("| {0} | {1} |", ReportResources.Classes, summaryResult.Assemblies.SelectMany(a => a.Classes).Count().ToString(CultureInfo.InvariantCulture));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ public void CreateSummaryReport(SummaryResult summaryResult)
{
reportTextWriter.WriteLine(ReportResources.Summary);
reportTextWriter.WriteLine(" {0} {1}", ReportResources.GeneratedOn, DateTime.Now.ToShortDateString() + " - " + DateTime.Now.ToLongTimeString());

if (summaryResult.MinimumTimeStamp.HasValue || summaryResult.MaximumTimeStamp.HasValue)
{
reportTextWriter.WriteLine(" {0} {1}", ReportResources.CoverageDate, summaryResult.CoverageDate());
}

reportTextWriter.WriteLine(" {0} {1}", ReportResources.Parser, summaryResult.UsedParser);
reportTextWriter.WriteLine(" {0} {1}", ReportResources.Assemblies2, summaryResult.Assemblies.Count().ToString(CultureInfo.InvariantCulture));
reportTextWriter.WriteLine(" {0} {1}", ReportResources.Classes, summaryResult.Assemblies.SelectMany(a => a.Classes).Count().ToString(CultureInfo.InvariantCulture));
Expand Down

0 comments on commit 4bc9f98

Please sign in to comment.