コード例 #1
0
        private CoverageData GetCoverageData(string lcovData)
        {
            var    coverageData   = new CoverageData();
            string currentPackage = null;
            string currentFile    = null;

            long fileLinesTotal      = 0;
            long fileLinesCovered    = 0;
            long fileBranchesTotal   = 0;
            long fileBranchesCovered = 0;

            var fileLines   = new Dictionary <long, FileLine>();
            var fileMethods = new Dictionary <string, FileMethod>();

            foreach (var line in lcovData.Split('\n'))
            {
                if (line.Trim() == "end_of_record" && currentFile != null)
                {
                    // new { currentPackage, currentFile }.Dump();
                    var package = coverageData.Packages[currentPackage];
                    package.LinesTotal      += fileLinesTotal;
                    package.LinesCovered    += fileLinesCovered;
                    package.BranchesTotal   += fileBranchesTotal;
                    package.BranchesCovered += fileBranchesCovered;

                    var file = package.Classes[currentFile];
                    file.LinesTotal      = fileLinesTotal;
                    file.LinesCovered    = fileLinesCovered;
                    file.BranchesTotal   = fileBranchesTotal;
                    file.BranchesCovered = fileBranchesCovered;
                    foreach (var item in fileLines)
                    {
                        file.Lines.Add(item);
                    }
                    foreach (var item in fileMethods)
                    {
                        file.Methods.Add(item);
                    }

                    coverageData.LinesTotal      += fileLinesTotal;
                    coverageData.LinesCovered    += fileLinesCovered;
                    coverageData.BranchesTotal   += fileBranchesTotal;
                    coverageData.BranchesCovered += fileBranchesCovered;
                    continue;
                }

                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                // line.Dump();
                var inputType   = line.Substring(0, line.IndexOf(":"));
                var lineContent = line.Substring(line.IndexOf(":") + 1);
                var parts       = lineContent.Trim().Split(',');

                switch (inputType)
                {
                case "SF":
                    var fileName = lineContent.Trim();
                    // TODO: USE cake method here...
                    var relativeFileName = _baseDirectory.GetRelativePath(new FilePath(fileName));
                    var packageName      = string.Join(".", relativeFileName.Segments.Take(relativeFileName.Segments.Length - 1));
                    var className        = relativeFileName.Segments.Last();

                    if (!coverageData.Packages.TryGetValue(packageName, out var package))
                    {
                        package = new Package();
                        coverageData.Packages.Add(packageName, package);
                    }

                    package.Classes[relativeFileName.FullPath] = new Class(className);

                    currentPackage      = packageName;
                    currentFile         = relativeFileName.FullPath;
                    fileLinesTotal      = 0;
                    fileLinesCovered    = 0;
                    fileBranchesTotal   = 0;
                    fileBranchesCovered = 0;
                    fileLines           = new Dictionary <long, FileLine>();
                    fileMethods         = new Dictionary <string, FileMethod>();
                    break;

                case "DA":
                    // DA:2,0
                {
                    var lineNumber = long.Parse(parts[0]);
                    var lineHits   = parts[1];

                    if (!fileLines.TryGetValue(lineNumber, out var fileLine))
                    {
                        fileLine = new FileLine();
                        fileLines.Add(lineNumber, fileLine);
                    }

                    if (long.TryParse(lineHits, out var hits))
                    {
                        fileLine.Hits += hits;
                        if (hits > 0)
                        {
                            fileLinesCovered++;
                        }
                    }
                    fileLinesTotal++;
                }
                break;

                case "BRDA":
                    // BRDA:1,1,2,0
                {
                    var lineNumber   = long.Parse(parts[0]);
                    var blockNumber  = long.Parse(parts[1]);
                    var branchNumber = long.Parse(parts[2]);
                    var branchHits   = parts[3];

                    if (!fileLines.TryGetValue(lineNumber, out var fileLine))
                    {
                        fileLine = new FileLine();
                        fileLines.Add(lineNumber, fileLine);
                    }

                    fileLine.Branch = true;
                    fileLine.BranchesTotal++;
                    fileBranchesTotal++;

                    var covered = false;

                    if (branchHits != "-" && long.Parse(branchHits) > 0)
                    {
                        covered = true;
                        fileLine.BranchesCovered++;
                        fileBranchesCovered++;
                    }
                    fileLine.Conditions.Add(new BranchCondition()
                        {
                            Number  = branchNumber,
                            Covered = covered
                        });
                }
                break;

                case "BRF":
                {
                    fileBranchesTotal = long.Parse(lineContent);
                }
                break;

                case "BRH":
                {
                    fileBranchesCovered = long.Parse(lineContent);
                }
                break;

                case "FN":
                {
                    // FN:5,(anonymous_1)

                    var functionLine = long.Parse(parts[0]);
                    var functionName = parts[1];

                    fileMethods[functionName] = new FileMethod()
                    {
                        Line = functionLine,
                        Hits = 0
                    };
                }
                break;

                case "FNDA":
                {
                    // FNDA:0,(anonymous_1)
                    var functionHits = long.Parse(parts[0]);
                    var functionName = parts[1];

                    if (!fileMethods.TryGetValue(functionName, out var fileMethod))
                    {
                        fileMethod = new FileMethod()
                        {
                            Line = 0, Hits = 0
                        };
                        fileMethods.Add(functionName, fileMethod);
                    }

                    fileMethod.Hits = functionHits;
                }
                break;
                }
            }

            return(coverageData);
        }
コード例 #2
0
        private XDocument GenerateCoberturaXml(CoverageData data)
        {
            var doc = new XDocument();

            doc.Add(new XDocumentType("coverage", "SYSTEM", "http://cobertura.sourceforge.net/xml/coverage-04.dtd", ""));
            doc.Declaration = new XDeclaration("1.0", null, null);
            var root = new XElement("coverage");

            doc.Add(root);

            root.SetAttributeValue("branch-rate", data.BranchRate);
            root.SetAttributeValue("branches-covered", data.BranchesCovered);
            root.SetAttributeValue("branches-valid", data.BranchesTotal);
            root.SetAttributeValue("complexity", "0");
            root.SetAttributeValue("line-rate", data.LineRate);
            root.SetAttributeValue("lines-covered", data.LinesCovered);
            root.SetAttributeValue("lines-valid", data.LinesTotal);
            root.SetAttributeValue("timestamp", data.Timestamp);
            root.SetAttributeValue("version", "2.0.3");

            var sources = new XElement("sources");

            root.Add(sources);
            var source = new XElement("source");

            sources.Add(source);

            source.Add(new XText(_baseDirectory.FullPath));

            var packagesElement = new XElement("packages");

            root.Add(packagesElement);

            foreach (var package in data.Packages)
            {
                var packageElement = new XElement("package");
                packagesElement.Add(packageElement);

                packageElement.SetAttributeValue("line-rate", package.Value.LineRate);
                packageElement.SetAttributeValue("branch-rate", package.Value.BranchRate);
                packageElement.SetAttributeValue("name", package.Key);
                packageElement.SetAttributeValue("complexity", "0");

                var classesElement = new XElement("classes");
                packageElement.Add(classesElement);

                foreach (var @class in package.Value.Classes)
                {
                    var classElement = new XElement("class");
                    classesElement.Add(classElement);

                    classElement.SetAttributeValue("complexity", "0");
                    classElement.SetAttributeValue("line-rate", @class.Value.LineRate);
                    classElement.SetAttributeValue("branch-rate", @class.Value.BranchRate);
                    classElement.SetAttributeValue("filename", @class.Key);
                    classElement.SetAttributeValue("name", @class.Value.Name);

                    var methodsElement = new XElement("methods");
                    classElement.Add(methodsElement);

                    foreach (var method in @class.Value.Methods)
                    {
                        var methodElement = new XElement("method");
                        methodsElement.Add(methodElement);

                        methodElement.SetAttributeValue("name", method.Key);
                        methodElement.SetAttributeValue("signature", "");
                        methodElement.SetAttributeValue("line-rate", method.Value.Hits > 0 ? "1.0" : "0.0");
                        methodElement.SetAttributeValue("branch-rate", method.Value.Hits > 0 ? "1.0" : "0.0");

                        var linesElement = new XElement("lines");
                        methodElement.Add(linesElement);

                        var lineElement = new XElement("line");
                        linesElement.Add(lineElement);

                        lineElement.SetAttributeValue("hits", method.Value.Hits);
                        lineElement.SetAttributeValue("number", method.Value.Line);
                        lineElement.SetAttributeValue("branch", "false");
                    }

                    {
                        var linesElement = new XElement("lines");
                        classElement.Add(linesElement);

                        foreach (var line in @class.Value.Lines.OrderBy(x => x.Key))
                        {
                            var lineElement = new XElement("line");
                            linesElement.Add(lineElement);
                            lineElement.SetAttributeValue("hits", line.Value.Hits);
                            lineElement.SetAttributeValue("number", line.Key);
                            lineElement.SetAttributeValue("branch", line.Value.Branch);
                            if (line.Value.Branch)
                            {
                                lineElement.SetAttributeValue("condition-coverage",
                                                              $"{line.Value.BranchRate * 100}% ({line.Value.BranchesCovered}/{line.Value.BranchesTotal})");

                                var conditionsElement = new XElement("conditions");
                                lineElement.Add(conditionsElement);

                                foreach (var condition in line.Value.Conditions)
                                {
                                    var conditionElement = new XElement("condition");
                                    conditionsElement.Add(conditionElement);

                                    conditionElement.SetAttributeValue("type", condition.Type);
                                    conditionElement.SetAttributeValue("number", condition.Number);
                                    if (condition.Covered)
                                    {
                                        var coverage = Math.Floor(1d / line.Value.Conditions.Count * 100);
                                        conditionElement.SetAttributeValue("coverage", $"{coverage}%");
                                    }
                                    else
                                    {
                                        conditionElement.SetAttributeValue("coverage", "0%");
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(doc);
        }