Skip to content

[Bug fix]Fix culture for cobertura xml report #464

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 17, 2019
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
37 changes: 18 additions & 19 deletions src/coverlet.core/Reporters/CoberturaReporter.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace Coverlet.Core.Reporters
Expand All @@ -25,10 +24,10 @@ public string Report(CoverageResult result)

XDocument xml = new XDocument();
XElement coverage = new XElement("coverage");
coverage.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(result.Modules).Percent / 100).ToString()));
coverage.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(result.Modules).Percent / 100).ToString()));
coverage.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(result.Modules).Percent / 100).ToString(CultureInfo.InvariantCulture)));
coverage.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(result.Modules).Percent / 100).ToString(CultureInfo.InvariantCulture)));
coverage.Add(new XAttribute("version", "1.9"));
coverage.Add(new XAttribute("timestamp", ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds).ToString()));
coverage.Add(new XAttribute("timestamp", (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds));

XElement sources = new XElement("sources");
sources.Add(new XElement("source", string.Empty));
Expand All @@ -38,9 +37,9 @@ public string Report(CoverageResult result)
{
XElement package = new XElement("package");
package.Add(new XAttribute("name", Path.GetFileNameWithoutExtension(module.Key)));
package.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(module.Value).Percent / 100).ToString()));
package.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(module.Value).Percent / 100).ToString()));
package.Add(new XAttribute("complexity", summary.CalculateCyclomaticComplexity(module.Value).ToString()));
package.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(module.Value).Percent / 100).ToString(CultureInfo.InvariantCulture)));
package.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(module.Value).Percent / 100).ToString(CultureInfo.InvariantCulture)));
package.Add(new XAttribute("complexity", summary.CalculateCyclomaticComplexity(module.Value)));

XElement classes = new XElement("classes");
foreach (var document in module.Value)
Expand All @@ -50,9 +49,9 @@ public string Report(CoverageResult result)
XElement @class = new XElement("class");
@class.Add(new XAttribute("name", cls.Key));
@class.Add(new XAttribute("filename", document.Key));
@class.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(cls.Value).Percent / 100).ToString()));
@class.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(cls.Value).Percent / 100).ToString()));
@class.Add(new XAttribute("complexity", summary.CalculateCyclomaticComplexity(cls.Value).ToString()));
@class.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(cls.Value).Percent / 100).ToString(CultureInfo.InvariantCulture)));
@class.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(cls.Value).Percent / 100).ToString(CultureInfo.InvariantCulture)));
@class.Add(new XAttribute("complexity", summary.CalculateCyclomaticComplexity(cls.Value)));

XElement classLines = new XElement("lines");
XElement methods = new XElement("methods");
Expand All @@ -66,8 +65,8 @@ public string Report(CoverageResult result)
XElement method = new XElement("method");
method.Add(new XAttribute("name", meth.Key.Split(':')[2].Split('(')[0]));
method.Add(new XAttribute("signature", "(" + meth.Key.Split(':')[2].Split('(')[1]));
method.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(meth.Value.Lines).Percent / 100).ToString()));
method.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(meth.Value.Branches).Percent / 100).ToString()));
method.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(meth.Value.Lines).Percent / 100).ToString(CultureInfo.InvariantCulture)));
method.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(meth.Value.Branches).Percent / 100).ToString(CultureInfo.InvariantCulture)));

XElement lines = new XElement("lines");
foreach (var ln in meth.Value.Lines)
Expand All @@ -82,15 +81,15 @@ public string Report(CoverageResult result)
{
var branches = meth.Value.Branches.Where(b => b.Line == ln.Key).ToList();
var branchInfoCoverage = summary.CalculateBranchCoverage(branches);
line.Add(new XAttribute("condition-coverage", $"{branchInfoCoverage.Percent}% ({branchInfoCoverage.Covered}/{branchInfoCoverage.Total})"));
line.Add(new XAttribute("condition-coverage", $"{branchInfoCoverage.Percent.ToString(CultureInfo.InvariantCulture)}% ({branchInfoCoverage.Covered.ToString(CultureInfo.InvariantCulture)}/{branchInfoCoverage.Total.ToString(CultureInfo.InvariantCulture)})"));
XElement conditions = new XElement("conditions");
var byOffset = branches.GroupBy(b => b.Offset).ToDictionary(b => b.Key, b => b.ToList());
foreach (var entry in byOffset)
{
XElement condition = new XElement("condition");
condition.Add(new XAttribute("number", entry.Key));
condition.Add(new XAttribute("type", entry.Value.Count() > 2 ? "switch" : "jump")); // Just guessing here
condition.Add(new XAttribute("coverage", $"{summary.CalculateBranchCoverage(entry.Value).Percent}%"));
condition.Add(new XAttribute("coverage", $"{summary.CalculateBranchCoverage(entry.Value).Percent.ToString(CultureInfo.InvariantCulture)}%"));
conditions.Add(condition);
}

Expand All @@ -116,10 +115,10 @@ public string Report(CoverageResult result)
packages.Add(package);
}

coverage.Add(new XAttribute("lines-covered", lineCoverage.Covered.ToString()));
coverage.Add(new XAttribute("lines-valid", lineCoverage.Total.ToString()));
coverage.Add(new XAttribute("branches-covered", branchCoverage.Covered.ToString()));
coverage.Add(new XAttribute("branches-valid", branchCoverage.Total.ToString()));
coverage.Add(new XAttribute("lines-covered", lineCoverage.Covered.ToString(CultureInfo.InvariantCulture)));
coverage.Add(new XAttribute("lines-valid", lineCoverage.Total.ToString(CultureInfo.InvariantCulture)));
coverage.Add(new XAttribute("branches-covered", branchCoverage.Covered.ToString(CultureInfo.InvariantCulture)));
coverage.Add(new XAttribute("branches-valid", branchCoverage.Total.ToString(CultureInfo.InvariantCulture)));

coverage.Add(sources);
coverage.Add(packages);
Expand Down
35 changes: 33 additions & 2 deletions test/coverlet.core.tests/Reporters/CoberturaReporterTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Linq;
using Xunit;

namespace Coverlet.Core.Reporters.Tests
Expand Down Expand Up @@ -35,8 +42,32 @@ public void TestReport()
result.Modules = new Modules();
result.Modules.Add("module", documents);

CoberturaReporter reporter = new CoberturaReporter();
Assert.NotEqual(string.Empty, reporter.Report(result));
CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("it-IT");
try
{
// Assert conversion behaviour to be sure to be in a Italian culture context
// where decimal char is comma.
Assert.Equal("1,5", (1.5).ToString());

CoberturaReporter reporter = new CoberturaReporter();
string report = reporter.Report(result);

Assert.NotEmpty(report);

var doc = XDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(report)));
Assert.All(doc.Descendants().Attributes().Where(attr => attr.Name.LocalName.EndsWith("-rate")).Select(attr => attr.Value),
value =>
{
Assert.DoesNotContain(",", value);
Assert.Contains(".", value);
Assert.Equal(0.5, double.Parse(value, CultureInfo.InvariantCulture));
});
}
finally
{
Thread.CurrentThread.CurrentCulture = currentCulture;
}
}
}
}