-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bd3cd31
commit cf96382
Showing
15 changed files
with
310 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -223,3 +223,4 @@ coverage-hits | |
opencovercoverage.xml | ||
clover.xml | ||
coveralls.json | ||
cobertura.xml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
src/MiniCover/CommandLine/Commands/CoberturaReportCommand.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using System.Threading.Tasks; | ||
using MiniCover.CommandLine.Options; | ||
using MiniCover.Reports; | ||
using MiniCover.Utils; | ||
|
||
namespace MiniCover.CommandLine.Commands | ||
{ | ||
class CoberturaReportCommand : BaseCommand | ||
{ | ||
private const string _name = "coberturareport"; | ||
private const string _description = "Write a Cobertura-formatted XML report to file"; | ||
|
||
private readonly CoverageLoadedFileOption _coverageLoadedFileOption; | ||
private readonly CoberturaOutputOption _coberturaOutputOption; | ||
private readonly ThresholdOption _thresholdOption; | ||
|
||
public CoberturaReportCommand( | ||
WorkingDirectoryOption workingDirectoryOption, | ||
CoverageLoadedFileOption coverageLoadedFileOption, | ||
CoberturaOutputOption coberturaOutputOption, | ||
ThresholdOption thresholdOption) | ||
: base(_name, _description) | ||
{ | ||
_coverageLoadedFileOption = coverageLoadedFileOption; | ||
_thresholdOption = thresholdOption; | ||
_coberturaOutputOption = coberturaOutputOption; | ||
|
||
Options = new IOption[] | ||
{ | ||
workingDirectoryOption, | ||
_coverageLoadedFileOption, | ||
_thresholdOption, | ||
_coberturaOutputOption | ||
}; | ||
} | ||
|
||
protected override Task<int> Execute() | ||
{ | ||
new CoberturaReport().Execute(_coverageLoadedFileOption.Result, _coberturaOutputOption.Value); | ||
var result = CalcUtils.IsHigherThanThreshold(_coverageLoadedFileOption.Result, _thresholdOption.Value); | ||
return Task.FromResult(result); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
src/MiniCover/CommandLine/Options/CoberturaOutputOption.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
namespace MiniCover.CommandLine.Options | ||
{ | ||
class CoberturaOutputOption : FileOption | ||
{ | ||
private const string _defaultValue = "./cobertura.xml"; | ||
private const string _template = "--output"; | ||
private static readonly string _description = $"Output file for cobertura report [default: {_defaultValue}]"; | ||
|
||
public CoberturaOutputOption() | ||
: base(_template, _description) | ||
{ | ||
} | ||
|
||
protected override string GetDefaultValue() | ||
{ | ||
return _defaultValue; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace MiniCover.Extensions | ||
{ | ||
public static class EnumerableExtensions | ||
{ | ||
public static IEnumerable<IGrouping<TKey, T>> GroupByMany<T, TKey>(this IEnumerable<T> source, Func<T, IEnumerable<TKey>> keysSelector) | ||
{ | ||
return source.SelectMany(x => keysSelector(x), (x, k) => new { x, k }) | ||
.GroupBy(j => j.k, j => j.x); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Xml; | ||
using System.Xml.Linq; | ||
using MiniCover.Extensions; | ||
using MiniCover.Model; | ||
|
||
namespace MiniCover.Reports | ||
{ | ||
public class CoberturaReport | ||
{ | ||
public void Execute(InstrumentationResult result, FileInfo output) | ||
{ | ||
var hits = HitsInfo.TryReadFromDirectory(result.HitsPath); | ||
|
||
var document = new XDocument( | ||
new XDeclaration("1.0", "utf-8", null), | ||
new XDocumentType("coverage", null, "http://cobertura.sourceforge.net/xml/coverage-04.dtd", null), | ||
CreateCoverageElement(result, hits) | ||
); | ||
|
||
var xmlWriterSettings = new XmlWriterSettings | ||
{ | ||
Indent = true | ||
}; | ||
|
||
output.Directory.Create(); | ||
|
||
using (var sw = output.CreateText()) | ||
using (var writer = XmlWriter.Create(sw, xmlWriterSettings)) | ||
{ | ||
document.WriteTo(writer); | ||
} | ||
} | ||
|
||
private static XElement CreateCoverageElement(InstrumentationResult result, HitsInfo hitsInfo) | ||
{ | ||
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); | ||
|
||
var linesValid = result.GetSourceFiles() | ||
.SelectMany(kvFile => kvFile.Value.Instructions) | ||
.SelectMany(i => i.GetLines()) | ||
.Distinct() | ||
.Count(); | ||
|
||
var coveredLines = result.GetSourceFiles() | ||
.SelectMany(kvFile => kvFile.Value.Instructions) | ||
.Where(h => hitsInfo.IsInstructionHit(h.Id)) | ||
.SelectMany(i => i.GetLines()) | ||
.Distinct() | ||
.Count(); | ||
|
||
var linesRate = linesValid == 0 ? 0d : (double)coveredLines / (double)linesValid; | ||
|
||
return new XElement( | ||
XName.Get("coverage"), | ||
new XAttribute(XName.Get("lines-valid"), linesValid), | ||
new XAttribute(XName.Get("lines-covered"), coveredLines), | ||
new XAttribute(XName.Get("line-rate"), linesRate), | ||
new XAttribute(XName.Get("timestamp"), timestamp), | ||
new XAttribute(XName.Get("version"), "1.0"), | ||
CrateSourcesElement(result, hitsInfo), | ||
CratePackagesElement(result, hitsInfo) | ||
); | ||
} | ||
|
||
private static XElement CrateSourcesElement(InstrumentationResult result, HitsInfo hitsInfo) | ||
{ | ||
return new XElement( | ||
XName.Get("sources"), | ||
new XElement("source", | ||
new XText(result.SourcePath) | ||
) | ||
); | ||
} | ||
|
||
private static XElement CratePackagesElement(InstrumentationResult result, HitsInfo hitsInfo) | ||
{ | ||
return new XElement( | ||
XName.Get("packages"), | ||
result.Assemblies | ||
.Where(a => a.SourceFiles.Count > 0) | ||
.Select(a => CreatePackageElement(a, hitsInfo)) | ||
); | ||
} | ||
|
||
private static XElement CreatePackageElement(InstrumentedAssembly assembly, HitsInfo hitsInfo) | ||
{ | ||
var linesValid = assembly.SourceFiles | ||
.SelectMany(kvFile => kvFile.Value.Instructions) | ||
.SelectMany(i => i.GetLines()) | ||
.Distinct() | ||
.Count(); | ||
|
||
var coveredLines = assembly.SourceFiles | ||
.SelectMany(kvFile => kvFile.Value.Instructions) | ||
.Where(h => hitsInfo.IsInstructionHit(h.Id)) | ||
.SelectMany(i => i.GetLines()) | ||
.Distinct() | ||
.Count(); | ||
|
||
var linesRate = linesValid == 0 ? 0d : (double)coveredLines / (double)linesValid; | ||
|
||
return new XElement( | ||
XName.Get("package"), | ||
new XAttribute(XName.Get("name"), assembly.Name), | ||
new XAttribute(XName.Get("line-rate"), linesRate), | ||
CreateClassesElement(assembly, hitsInfo) | ||
); | ||
} | ||
|
||
private static XElement CreateClassesElement(InstrumentedAssembly assembly, HitsInfo hitsInfo) | ||
{ | ||
return new XElement( | ||
XName.Get("classes"), | ||
assembly.SourceFiles | ||
.Select(kv => CreateClassElement(kv.Key, kv.Value, hitsInfo)) | ||
); | ||
} | ||
|
||
private static XElement CreateClassElement(string fileName, SourceFile sourceFile, HitsInfo hitsInfo) | ||
{ | ||
var linesValid = sourceFile.Instructions | ||
.SelectMany(i => i.GetLines()) | ||
.Distinct() | ||
.Count(); | ||
|
||
var coveredLines = sourceFile.Instructions | ||
.Where(h => hitsInfo.IsInstructionHit(h.Id)) | ||
.SelectMany(i => i.GetLines()) | ||
.Distinct() | ||
.Count(); | ||
|
||
var linesRate = (double)coveredLines / (double)linesValid; | ||
|
||
return new XElement( | ||
|
||
XName.Get("class"), | ||
new XAttribute(XName.Get("name"), fileName), | ||
new XAttribute(XName.Get("filename"), fileName), | ||
new XAttribute(XName.Get("line-rate"), linesRate), | ||
CreateMethodsElement(sourceFile, hitsInfo), | ||
CreateLinesElement(sourceFile.Instructions, hitsInfo) | ||
); | ||
} | ||
|
||
private static XElement CreateMethodsElement(SourceFile sourceFile, HitsInfo hitsInfo) | ||
{ | ||
return new XElement( | ||
XName.Get("methods"), | ||
sourceFile.Instructions | ||
.GroupBy(i => i.Method) | ||
.Select(g => CreateMethodElement(g.Key, g, hitsInfo)) | ||
); | ||
} | ||
|
||
private static XElement CreateMethodElement(InstrumentedMethod method, IEnumerable<InstrumentedInstruction> instructions, HitsInfo hitsInfo) | ||
{ | ||
var hits = instructions.Sum(i => hitsInfo.GetInstructionHitCount(i.Id)); | ||
|
||
var openParametersIndex = method.FullName.IndexOf("("); | ||
var signature = method.FullName.Substring(openParametersIndex); | ||
|
||
return new XElement( | ||
XName.Get("method"), | ||
new XAttribute(XName.Get("name"), method.Name), | ||
new XAttribute(XName.Get("signature"), signature), | ||
new XAttribute(XName.Get("hits"), hits), | ||
CreateLinesElement(instructions, hitsInfo) | ||
); | ||
} | ||
|
||
private static XElement CreateLinesElement(IEnumerable<InstrumentedInstruction> instructions, HitsInfo hitsInfo) | ||
{ | ||
return new XElement( | ||
XName.Get("lines"), | ||
instructions | ||
.GroupByMany(i => i.GetLines()) | ||
.OrderBy(g => g.Key) | ||
.Select(g => CreateLineElement(g.Key, g, hitsInfo)) | ||
); | ||
} | ||
|
||
private static object CreateLineElement(int line, IEnumerable<InstrumentedInstruction> instructions, HitsInfo hitsInfo) | ||
{ | ||
var hits = instructions.Sum(i => hitsInfo.GetInstructionHitCount(i.Id)); | ||
|
||
return new XElement( | ||
XName.Get("line"), | ||
new XAttribute(XName.Get("number"), line), | ||
new XAttribute(XName.Get("hits"), hits) | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.