Skip to content
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

Add preliminary Cobertura support #41

Merged
merged 6 commits into from
Apr 13, 2018
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 1 addition & 3 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,4 @@ build_script:
- dotnet msbuild build.proj /p:Configuration=%CONFIGURATION%
test_script:
- ps: if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) }
- cmd: IF "%CONFIGURATION%"=="Release" ( %USERPROFILE%\.nuget\packages\coveralls.net\0.7.0\tools\csmacnz.Coveralls.exe --opencover -i test\coverlet.core.tests\coverage.xml --useRelativePaths )
cache:
- '%USERPROFILE%\.nuget\packages'
- cmd: IF "%CONFIGURATION%"=="Release" ( %USERPROFILE%\.nuget\packages\coveralls.net\0.7.0\tools\csmacnz.Coveralls.exe --opencover -i test\coverlet.core.tests\coverage.xml --useRelativePaths )
4 changes: 0 additions & 4 deletions src/coverlet.core/CoverageResult.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.IO;

using Coverlet.Core.Reporters;
using Jil;

namespace Coverlet.Core
Expand All @@ -24,8 +23,5 @@ public class CoverageResult
public Modules Modules;

internal CoverageResult() { }

public string Format(IReporter reporter)
=> reporter.Format(this);
}
}
106 changes: 106 additions & 0 deletions src/coverlet.core/Reporters/CoberturaReporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;

namespace Coverlet.Core.Reporters
{
public class CoberturaReporter : IReporter
{
public string Format => "cobertura";

public string Extension => "xml";

public string Report(CoverageResult result)
{
XmlDocument xml = new XmlDocument();
XmlElement coverage = xml.CreateElement("coverage");
coverage.SetAttribute("line-rate", "0");
coverage.SetAttribute("branch-rate", "0");
coverage.SetAttribute("version", "1.9");
coverage.SetAttribute("timestamp", "0");

XmlElement sources = xml.CreateElement("sources");
foreach (var src in GetSources(result.Modules))
{
XmlElement source = xml.CreateElement("source");
source.AppendChild(xml.CreateTextNode(src));
sources.AppendChild(source);
}

XmlElement packages = xml.CreateElement("packages");
foreach (var module in result.Modules)
{
XmlElement package = xml.CreateElement("package");
package.SetAttribute("line-rate", "0");
package.SetAttribute("branch-rate", "0");
package.SetAttribute("complexity", "0");

XmlElement classes = xml.CreateElement("classes");
foreach (var document in module.Value)
{
foreach (var cls in document.Value)
{
XmlElement @class = xml.CreateElement("class");
@class.SetAttribute("name", cls.Key);
@class.SetAttribute("filename", Path.GetFileName(document.Key));
@class.SetAttribute("line-rate", "0");
@class.SetAttribute("branch-rate", "0");
@class.SetAttribute("complexity", "0");

XmlElement methods = xml.CreateElement("methods");
foreach (var meth in cls.Value)
{
XmlElement method = xml.CreateElement("method");
method.SetAttribute("name", meth.Key.Split(':')[2].Split('(')[0]);
method.SetAttribute("signature", meth.Key);
method.SetAttribute("line-rate", "0");
method.SetAttribute("branch-rate", "0");

XmlElement lines = xml.CreateElement("lines");
foreach (var ln in meth.Value)
{
XmlElement line = xml.CreateElement("line");
line.SetAttribute("number", ln.Key.ToString());
line.SetAttribute("hits", ln.Value.Hits.ToString());
line.SetAttribute("branch", ln.Value.IsBranchPoint.ToString());

lines.AppendChild(line);
}

method.AppendChild(lines);
methods.AppendChild(method);
}

@class.AppendChild(methods);
classes.AppendChild(@class);
}
}

package.AppendChild(classes);
packages.AppendChild(package);
}

coverage.AppendChild(sources);
coverage.AppendChild(packages);
xml.AppendChild(coverage);

StringWriter writer = new StringWriter();
xml.Save(writer);

return writer.ToString();
}

private string[] GetSources(Modules modules)
{
List<string> sources = new List<string>();
foreach (var module in modules)
{
sources.AddRange(
module.Value.Select(d => Path.GetDirectoryName(d.Key)));
}

return sources.Distinct().ToArray();
}
}
}
4 changes: 3 additions & 1 deletion src/coverlet.core/Reporters/IReporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ namespace Coverlet.Core.Reporters
{
public interface IReporter
{
string Format(CoverageResult result);
string Format { get; }
string Extension { get; }
string Report(CoverageResult result);
}
}
6 changes: 5 additions & 1 deletion src/coverlet.core/Reporters/JsonReporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ namespace Coverlet.Core.Reporters
{
public class JsonReporter : IReporter
{
public string Format(CoverageResult result)
public string Format => "json";

public string Extension => "json";

public string Report(CoverageResult result)
{
using (var writer = new StringWriter())
{
Expand Down
6 changes: 5 additions & 1 deletion src/coverlet.core/Reporters/LcovReporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ namespace Coverlet.Core.Reporters
{
public class LcovReporter : IReporter
{
public string Format(CoverageResult result)
public string Format => "lcov";

public string Extension => "info";

public string Report(CoverageResult result)
{
List<string> lcov = new List<string>();
foreach (var module in result.Modules)
Expand Down
6 changes: 5 additions & 1 deletion src/coverlet.core/Reporters/OpenCoverReporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ private sealed class Utf8StringWriter : StringWriter
public override Encoding Encoding => Encoding.UTF8;
}

public string Format(CoverageResult result)
public string Format => "opencover";

public string Extension => "xml";

public string Report(CoverageResult result)
{
XmlDocument xml = new XmlDocument();
XmlElement coverage = xml.CreateElement("CoverageSession");
Expand Down
22 changes: 22 additions & 0 deletions src/coverlet.core/Reporters/ReporterFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Linq;

namespace Coverlet.Core.Reporters
{
public class ReporterFactory
{
private string _format;
private IReporter[] _reporters;

public ReporterFactory(string format)
{
_format = format;
_reporters = new IReporter[] {
new JsonReporter(), new LcovReporter(),
new OpenCoverReporter(), new CoberturaReporter()
};
}

public IReporter CreateReporter()
=> _reporters.FirstOrDefault(r => r.Format == _format);
}
}
22 changes: 6 additions & 16 deletions src/coverlet.msbuild.tasks/CoverageResultTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,13 @@ public override bool Execute()
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);

Console.WriteLine($" Generating report '{_filename}'");
IReporter reporter = new ReporterFactory(_format).CreateReporter();
if (reporter == null)
throw new Exception($"Specified output format '{_format}' is not supported");

IReporter reporter = default(IReporter);
switch (_format)
{
case "lcov":
reporter = new LcovReporter();
break;
case "opencover":
reporter = new OpenCoverReporter();
break;
default:
reporter = new JsonReporter();
break;
}

File.WriteAllText(_filename, result.Format(reporter));
_filename = _filename + "." + reporter.Extension;
Console.WriteLine($" Generating report '{_filename}'");
File.WriteAllText(_filename, reporter.Report(result));

int total = 0;
CoverageSummary coverageSummary = new CoverageSummary(result);
Expand Down
9 changes: 4 additions & 5 deletions src/coverlet.msbuild/coverlet.msbuild.props
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>

<CoverletOutputFormat Condition="$(CoverletOutputFormat) == ''">json</CoverletOutputFormat>
<CoverletOutputDirectory Condition="$(CoverletOutputDirectory) == ''">$(MSBuildProjectDirectory)</CoverletOutputDirectory>
<Threshold Condition="$(Threshold) == ''">0</Threshold>
<CoverletOutputExtension Condition="$(CoverletOutputFormat) == 'lcov'">.info</CoverletOutputExtension>
<CoverletOutputExtension Condition="$(CoverletOutputFormat) == 'opencover'">.xml</CoverletOutputExtension>
<CoverletOutputExtension Condition="$(CoverletOutputFormat) != 'lcov' and $(CoverletOutputFormat) != 'opencover'">.json</CoverletOutputExtension>
<CoverletOutput>$(CoverletOutputDirectory)\coverage</CoverletOutput>

<CoverletOutput>$(CoverletOutputDirectory)\coverage$(CoverletOutputExtension)</CoverletOutput>
<Threshold Condition="$(Threshold) == ''">0</Threshold>
<CollectCoverage Condition="$(CollectCoverage) == ''">false</CollectCoverage>

</PropertyGroup>

</Project>
5 changes: 2 additions & 3 deletions test/coverlet.core.tests/CoverageResultTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ public void TestFormat()
var mock = new Mock<IReporter>();

CoverageResult coverageResult = new CoverageResult();
coverageResult.Format(mock.Object);

mock.Verify(m => m.Format(coverageResult));
mock.Object.Report(coverageResult);
mock.Verify(m => m.Report(coverageResult));
}
}
}
29 changes: 29 additions & 0 deletions test/coverlet.core.tests/Reporters/CoberturaReporterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using Xunit;

namespace Coverlet.Core.Reporters.Tests
{
public class CoberturaReporterTests
{
[Fact]
public void TestFormat()
{
CoverageResult result = new CoverageResult();
result.Identifier = Guid.NewGuid().ToString();
Lines lines = new Lines();
lines.Add(1, new LineInfo { Hits = 1 });
lines.Add(2, new LineInfo { Hits = 0 });
Methods methods = new Methods();
methods.Add("System.Void Coverlet.Core.Reporters.Tests.CoberturaReporterTests::TestFormat()", lines);
Classes classes = new Classes();
classes.Add("Coverlet.Core.Reporters.Tests.CoberturaReporterTests", methods);
Documents documents = new Documents();
documents.Add("doc.cs", classes);
result.Modules = new Modules();
result.Modules.Add("module", documents);

CoberturaReporter reporter = new CoberturaReporter();
Assert.NotEqual(string.Empty, reporter.Report(result));
}
}
}
4 changes: 2 additions & 2 deletions test/coverlet.core.tests/Reporters/JsonReporterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public void TestFormat()
result.Modules.Add("module", documents);

JsonReporter reporter = new JsonReporter();
Assert.NotEqual("{\n}", reporter.Format(result));
Assert.NotEqual(string.Empty, reporter.Format(result));
Assert.NotEqual("{\n}", reporter.Report(result));
Assert.NotEqual(string.Empty, reporter.Report(result));
}
}
}
2 changes: 1 addition & 1 deletion test/coverlet.core.tests/Reporters/LcovReporterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public void TestFormat()
result.Modules.Add("module", documents);

LcovReporter reporter = new LcovReporter();
Assert.NotEqual(string.Empty, reporter.Format(result));
Assert.NotEqual(string.Empty, reporter.Report(result));
}
}
}
4 changes: 2 additions & 2 deletions test/coverlet.core.tests/Reporters/OpenCoverReporterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public void TestFormat()
result.Modules.Add("Coverlet.Core.Reporters.Tests", CreateFirstDocuments());

OpenCoverReporter reporter = new OpenCoverReporter();
Assert.NotEqual(string.Empty, reporter.Format(result));
Assert.NotEqual(string.Empty, reporter.Report(result));
}

[Fact]
Expand All @@ -29,7 +29,7 @@ public void TestFilesHaveUniqueIdsOverMultipleModules()
result.Modules.Add("Some.Other.Module", CreateSecondDocuments());

OpenCoverReporter reporter = new OpenCoverReporter();
var xml = reporter.Format(result);
var xml = reporter.Report(result);
Assert.NotEqual(string.Empty, xml);

Assert.Contains(@"<FileRef uid=""1"" />", xml);
Expand Down
18 changes: 18 additions & 0 deletions test/coverlet.core.tests/Reporters/ReporterFactoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using Xunit;

namespace Coverlet.Core.Reporters.Tests
{
public class ReporterFactoryTests
{
[Fact]
public void TestCreateReporter()
{
Assert.Equal(typeof(JsonReporter), new ReporterFactory("json").CreateReporter().GetType());
Assert.Equal(typeof(LcovReporter), new ReporterFactory("lcov").CreateReporter().GetType());
Assert.Equal(typeof(OpenCoverReporter), new ReporterFactory("opencover").CreateReporter().GetType());
Assert.Equal(typeof(CoberturaReporter), new ReporterFactory("cobertura").CreateReporter().GetType());
Assert.Null(new ReporterFactory("").CreateReporter());
}
}
}