You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As per #407 but not limited to the visual studio xml report. Similarly for cobertura.
Given an auto implemented property, if only one of the accessors is used they will both be shown as Covered and the corresponding CodeElement.CoverageQuota will be 100 for both.
This will also manifest itself when you pass in a cobertura file and get out a cobertura file.
Here is a portion of the in file
private static CodeFile ProcessFile(XElement module, string fileId, ClassWithNamespace classWithNamespace, string filePath)
{
var methods = module
.Elements("functions")
.Elements("function")
.Where(c => c.Attribute("namespace")?.Value == classWithNamespace.Namespace)
.Where(c => c.Attribute("type_name").Value.Equals(classWithNamespace.ClassName, StringComparison.Ordinal)
|| c.Attribute("type_name").Value.StartsWith(classWithNamespace.ClassName + ".", StringComparison.Ordinal))
.Where(m => m.Elements("ranges").Elements("range").Any(r => r.Attribute("source_id").Value == fileId))
.ToArray();
var linesOfFile = methods
.Elements("ranges")
.Elements("range")
.Where(l => l.Attribute("start_line").Value != "15732480")
.Select(l => new
{
LineNumberStart = int.Parse(l.Attribute("start_line").Value, CultureInfo.InvariantCulture),
LineNumberEnd = int.Parse(l.Attribute("end_line").Value, CultureInfo.InvariantCulture),
// correctly reading the attribute
Coverage = l.Attribute("covered").Value.Equals("no") ? 0 : 1,
Partial = l.Attribute("covered").Value.Equals("partial")
})
.OrderBy(seqpnt => seqpnt.LineNumberEnd)
.ToArray();
int[] coverage = new int[] { };
LineVisitStatus[] lineVisitStatus = new LineVisitStatus[] { };
if (linesOfFile.Length > 0)
{
coverage = new int[linesOfFile[linesOfFile.LongLength - 1].LineNumberEnd + 1];
lineVisitStatus = new LineVisitStatus[linesOfFile[linesOfFile.LongLength - 1].LineNumberEnd + 1];
for (int i = 0; i < coverage.Length; i++)
{
coverage[i] = -1;
}
foreach (var seqpnt in linesOfFile)
{
for (int lineNumber = seqpnt.LineNumberStart; lineNumber <= seqpnt.LineNumberEnd; lineNumber++)
{
// Both the get and set can set
coverage[lineNumber] = coverage[lineNumber] == -1 ? seqpnt.Coverage : Math.Min(coverage[lineNumber] + seqpnt.Coverage, 1);
// Both the get and set get to mark the LineVisitStatus as Covered
if (lineVisitStatus[lineNumber] != LineVisitStatus.Covered)
{
LineVisitStatus statusOfLine = seqpnt.Partial ? LineVisitStatus.PartiallyCovered : (seqpnt.Coverage == 1 ? LineVisitStatus.Covered : LineVisitStatus.NotCovered);
lineVisitStatus[lineNumber] = (LineVisitStatus)Math.Max((int)lineVisitStatus[lineNumber], (int)statusOfLine);
}
}
}
}
var codeFile = new CodeFile(filePath, coverage, lineVisitStatus);
SetMethodMetrics(codeFile, methods);
SetCodeElements(codeFile, methods);
return codeFile;
}
Given that the information from the xml files are lost in the ParserResult and the FileAnalysis is solely line based then every builder will be rendering incorrectly.
public void CreateClassReport(Class @class, IEnumerable<FileAnalysis> fileAnalyses)
{
.....
var classesElement = packageElement.Element("classes");
foreach (var fileAnalysis in fileAnalyses)
{
decimal? fileComplexity = null;
var classElement = new XElement(
"class",
new XAttribute("name", @class.Name),
new XAttribute("filename", fileAnalysis.Path));
var methodsElement = new XElement("methods");
foreach (var file in @class.Files)
{
if (file.Path == fileAnalysis.Path)
{
foreach (var codeElement in file.CodeElements)
{
int index = codeElement.Name.LastIndexOf('(');
var methodLinesElement = new XElement("lines");
var methodElement = new XElement(
"method",
new XAttribute("name", index == -1 ? codeElement.Name : codeElement.Name.Substring(0, index)),
new XAttribute("signature", index == -1 ? string.Empty : codeElement.Name.Substring(index)),
methodLinesElement);
// uses the LineAnalysis for the range of the CodeElement
this.AddLineElements(
methodLinesElement,
fileAnalysis.Lines.Skip(codeElement.FirstLine - 1).Take(codeElement.LastLine - codeElement.FirstLine + 1),
out double methodLineRate,
out double methodBranchRate);
methodElement.Add(new XAttribute("line-rate", methodLineRate.ToString(CultureInfo.InvariantCulture)));
methodElement.Add(new XAttribute("branch-rate", methodBranchRate.ToString(CultureInfo.InvariantCulture)));
.......
methodsElement.Add(methodElement);
}
break;
}
}
private void AddLineElements(XElement parent, IEnumerable<LineAnalysis> lines, out double lineRate, out double branchRate)
{
int coveredLines = 0;
int totalLines = 0;
int coveredBranches = 0;
int totalBranches = 0;
foreach (var line in lines)
{
if (line.LineVisitStatus == LineVisitStatus.NotCoverable)
{
continue;
}
totalLines++;
if (line.LineVisits > 0)
{
coveredLines++;
}
bool hasBranch = line.TotalBranches.GetValueOrDefault() > 0;
var lineElement = new XElement(
"line",
new XAttribute("number", line.LineNumber),
// will be 1 for both get/set when only one is hit
new XAttribute("hits", line.LineVisits.ToString(CultureInfo.InvariantCulture)),
new XAttribute("branch", hasBranch ? "true" : "false"));
if (hasBranch)
{
int visitedBranchesLine = line.CoveredBranches.GetValueOrDefault();
int totalBranchesLine = line.TotalBranches.GetValueOrDefault();
coveredBranches += visitedBranchesLine;
totalBranches += totalBranchesLine;
double coverage = visitedBranchesLine / (double)totalBranchesLine;
lineElement.Add(new XAttribute(
"condition-coverage",
string.Format("{0}% ({1}/{2})", Math.Round(coverage * 100, MidpointRounding.AwayFromZero), visitedBranchesLine, totalBranchesLine)));
}
parent.Add(lineElement);
}
// will be the same for get and set
lineRate = totalLines == 0 ? 1 : coveredLines / (double)totalLines;
branchRate = totalBranches == 0 ? 1 : coveredBranches / (double)totalBranches;
}
}
The text was updated successfully, but these errors were encountered:
As per #407 but not limited to the visual studio xml report. Similarly for cobertura.
Given an auto implemented property, if only one of the accessors is used they will both be shown as Covered and the corresponding CodeElement.CoverageQuota will be 100 for both.
This will also manifest itself when you pass in a cobertura file and get out a cobertura file.
Here is a portion of the in file
and the out file
If the in file is an xml file then you can see that the data is available with the lines_covered attribute.
For the CoberturaParser https://github.com/danielpalme/ReportGenerator/blob/537c17c126cefe4da5de2bb885cee520cdf43b70/src/ReportGenerator.Core/Parser/CoberturaParser.cs#L195C1-L262C10 the method line is ignored. The line will have hits 1. ( The CoverageElement.CoverageQuota is incorrect as is using the lineVisitStatus )
For the DynamicCodeCoverageParser
https://github.com/danielpalme/ReportGenerator/blob/537c17c126cefe4da5de2bb885cee520cdf43b70/src/ReportGenerator.Core/Parser/DynamicCodeCoverageParser.cs#L186C1-L245C10
Both the get and the set get to set the lineVisiitStatus so the line is covered and again the lineVisitStatus is used for the CoverageElement.CoverageQuota.
Given that the information from the xml files are lost in the ParserResult and the FileAnalysis is solely line based then every builder will be rendering incorrectly.
For instance the CoberturaReportBuilder https://github.com/danielpalme/ReportGenerator/blob/537c17c126cefe4da5de2bb885cee520cdf43b70/src/ReportGenerator.Core/Reporting/Builders/CoberturaReportBuilder.cs#L52C21-L52C38 use the analysis lines for the range of a CodeElement and so get/set will have the same line-rate="1" and line hits="1"
The text was updated successfully, but these errors were encountered: