Files
coverlet/src/coverlet.core/Reporters/OpenCoverReporter.cs
T
2018-04-08 10:50:38 +01:00

216 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
namespace Coverlet.Core.Reporters
{
public class OpenCoverReporter : IReporter
{
private sealed class Utf8StringWriter : StringWriter
{
public override Encoding Encoding => Encoding.UTF8;
}
public string Format(CoverageResult result)
{
XmlDocument xml = new XmlDocument();
XmlElement coverage = xml.CreateElement("CoverageSession");
XmlElement coverageSummary = xml.CreateElement("Summary");
XmlElement modules = xml.CreateElement("Modules");
int numSequencePoints = 0, numClasses = 0, numMethods = 0;
int visitedSequencePoints = 0, visitedClasses = 0, visitedMethods = 0;
int i = 1;
foreach (var mod in result.Modules)
{
XmlElement module = xml.CreateElement("Module");
module.SetAttribute("hash", Guid.NewGuid().ToString().ToUpper());
XmlElement path = xml.CreateElement("ModulePath");
path.AppendChild(xml.CreateTextNode(mod.Key));
XmlElement time = xml.CreateElement("ModuleTime");
time.AppendChild(xml.CreateTextNode(DateTime.UtcNow.ToString("yyyy-MM-ddThh:mm:ss")));
XmlElement name = xml.CreateElement("ModuleName");
name.AppendChild(xml.CreateTextNode(Path.GetFileNameWithoutExtension(mod.Key)));
module.AppendChild(path);
module.AppendChild(time);
module.AppendChild(name);
XmlElement files = xml.CreateElement("Files");
XmlElement classes = xml.CreateElement("Classes");
foreach (var doc in mod.Value)
{
XmlElement file = xml.CreateElement("File");
file.SetAttribute("uid", i.ToString());
file.SetAttribute("fullPath", doc.Key);
files.AppendChild(file);
foreach (var cls in doc.Value)
{
XmlElement @class = xml.CreateElement("Class");
XmlElement classSummary = xml.CreateElement("Summary");
XmlElement className = xml.CreateElement("FullName");
className.AppendChild(xml.CreateTextNode(cls.Key));
XmlElement methods = xml.CreateElement("Methods");
int j = 0;
var classVisited = false;
foreach (var meth in cls.Value)
{
XmlElement method = xml.CreateElement("Method");
method.SetAttribute("cyclomaticComplexity", "0");
method.SetAttribute("nPathComplexity", "0");
method.SetAttribute("sequenceCoverage", "0");
method.SetAttribute("branchCoverage", "0");
method.SetAttribute("isConstructor", meth.Key.Contains("ctor").ToString());
method.SetAttribute("isGetter", meth.Key.Contains("get_").ToString());
method.SetAttribute("isSetter", meth.Key.Contains("set_").ToString());
method.SetAttribute("isStatic", (!meth.Key.Contains("get_") || !meth.Key.Contains("set_")).ToString());
XmlElement methodName = xml.CreateElement("Name");
methodName.AppendChild(xml.CreateTextNode(meth.Key));
XmlElement fileRef = xml.CreateElement("FileRef");
fileRef.SetAttribute("uid", i.ToString());
XmlElement methodPoint = xml.CreateElement("MethodPoint");
methodPoint.SetAttribute("vc", meth.Value.Select(l => l.Value.Hits).Sum().ToString());
methodPoint.SetAttribute("upsid", "0");
methodPoint.SetAttribute("type", "xsi", "SequencePoint");
methodPoint.SetAttribute("ordinal", j.ToString());
methodPoint.SetAttribute("offset", j.ToString());
methodPoint.SetAttribute("sc", "0");
methodPoint.SetAttribute("sl", meth.Value.First().Key.ToString());
methodPoint.SetAttribute("ec", "1");
methodPoint.SetAttribute("el", meth.Value.Last().Key.ToString());
methodPoint.SetAttribute("bec", "0");
methodPoint.SetAttribute("bev", "0");
methodPoint.SetAttribute("fileid", i.ToString());
// They're really just lines
XmlElement sequencePoints = xml.CreateElement("SequencePoints");
XmlElement methodSummary = xml.CreateElement("Summary");
int k = 0;
var methodVisited = false;
foreach (var lines in meth.Value)
{
XmlElement sequencePoint = xml.CreateElement("SequencePoint");
sequencePoint.SetAttribute("vc", lines.Value.ToString());
sequencePoint.SetAttribute("upsid", lines.Key.ToString());
sequencePoint.SetAttribute("ordinal", k.ToString());
sequencePoint.SetAttribute("sl", lines.Key.ToString());
sequencePoint.SetAttribute("sc", "1");
sequencePoint.SetAttribute("el", lines.Key.ToString());
sequencePoint.SetAttribute("ec", "2");
sequencePoint.SetAttribute("bec", "0");
sequencePoint.SetAttribute("bev", "0");
sequencePoint.SetAttribute("fileid", i.ToString());
sequencePoints.AppendChild(sequencePoint);
numSequencePoints++;
if (lines.Value.Hits > 0)
{
visitedSequencePoints++;
classVisited = true;
methodVisited = true;
}
k++;
}
numMethods++;
if (methodVisited)
visitedMethods++;
methodSummary.SetAttribute("numSequencePoints", meth.Value.Count().ToString());
methodSummary.SetAttribute("visitedSequencePoints", meth.Value.Where(l => l.Value.Hits > 0).Count().ToString());
methodSummary.SetAttribute("numBranchPoints", "0");
methodSummary.SetAttribute("visitedBranchPoints", "0");
methodSummary.SetAttribute("sequenceCoverage", "0");
methodSummary.SetAttribute("branchCoverage", "0");
methodSummary.SetAttribute("maxCyclomaticComplexity", "0");
methodSummary.SetAttribute("minCyclomaticComplexity", "0");
methodSummary.SetAttribute("visitedClasses", "0");
methodSummary.SetAttribute("numClasses", "0");
methodSummary.SetAttribute("visitedMethods", methodVisited ? "1" : "0");
methodSummary.SetAttribute("numMethods", "1");
method.AppendChild(methodSummary);
method.AppendChild(xml.CreateElement("MetadataToken"));
method.AppendChild(methodName);
method.AppendChild(fileRef);
method.AppendChild(sequencePoints);
method.AppendChild(xml.CreateElement("BranchPoints"));
method.AppendChild(methodPoint);
methods.AppendChild(method);
j++;
}
numClasses++;
if (classVisited)
visitedClasses++;
classSummary.SetAttribute("numSequencePoints", cls.Value.Select(c => c.Value.Count).Sum().ToString());
classSummary.SetAttribute("visitedSequencePoints", cls.Value.Select(c => c.Value.Where(l => l.Value.Hits > 0).Count()).Sum().ToString());
classSummary.SetAttribute("numBranchPoints", "0");
classSummary.SetAttribute("visitedBranchPoints", "0");
classSummary.SetAttribute("sequenceCoverage", "0");
classSummary.SetAttribute("branchCoverage", "0");
classSummary.SetAttribute("maxCyclomaticComplexity", "0");
classSummary.SetAttribute("minCyclomaticComplexity", "0");
classSummary.SetAttribute("visitedClasses", classVisited ? "1" : "0");
classSummary.SetAttribute("numClasses", "1");
classSummary.SetAttribute("visitedMethods", "0");
classSummary.SetAttribute("numMethods", cls.Value.Count.ToString());
@class.AppendChild(classSummary);
@class.AppendChild(className);
@class.AppendChild(methods);
classes.AppendChild(@class);
}
i++;
}
module.AppendChild(files);
module.AppendChild(classes);
modules.AppendChild(module);
}
coverageSummary.SetAttribute("numSequencePoints", numSequencePoints.ToString());
coverageSummary.SetAttribute("visitedSequencePoints", visitedSequencePoints.ToString());
coverageSummary.SetAttribute("numBranchPoints", "0");
coverageSummary.SetAttribute("visitedBranchPoints", "0");
coverageSummary.SetAttribute("sequenceCoverage", "0");
coverageSummary.SetAttribute("branchCoverage", "0");
coverageSummary.SetAttribute("maxCyclomaticComplexity", "0");
coverageSummary.SetAttribute("minCyclomaticComplexity", "0");
coverageSummary.SetAttribute("visitedClasses", visitedClasses.ToString());
coverageSummary.SetAttribute("numClasses", numClasses.ToString());
coverageSummary.SetAttribute("visitedMethods", visitedMethods.ToString());
coverageSummary.SetAttribute("numMethods", numMethods.ToString());
coverage.AppendChild(coverageSummary);
coverage.AppendChild(modules);
xml.AppendChild(coverage);
Utf8StringWriter writer = new Utf8StringWriter();
xml.Save(writer);
return writer.ToString();
}
}
}