public Report Parse(string file)
        {
            var coverageReport = new Report
            {
                ModuleElements = new List <ModuleElement>()
            };

            var report  = XDocument.Load(file);
            var modules = report.Root.Elements("Modules").SelectMany(x => x.Elements("Module"));

            foreach (var module in modules)
            {
                var moduleInfo = new ModuleElement
                {
                    FilesList      = GetProjectFilesList(module.Element("Files")?.Elements("File")),
                    ClassCoverages = new List <ClassCoverage>()
                };

                var classes = module.Element("Classes").Elements("Class");

                foreach (var projectClass in classes)
                {
                    var summaryElem = projectClass.Element("Summary");
                    if (summaryElem == null)
                    {
                        continue;
                    }

                    var coverageInfo = new ClassCoverage
                    {
                        SequenceCoverage = Convert.ToDouble(summaryElem.Attribute("sequenceCoverage").Value, CultureInfo.InvariantCulture)
                    };

                    int?fileId         = null;
                    var methodCoverage = new List <LineCoverage>();

                    var methods = projectClass.Element("Methods");
                    if (methods != null && methods.Elements("Method").Any())
                    {
                        foreach (var method in methods.Elements("Method"))
                        {
                            if (method.Element("FileRef") == null)
                            {
                                continue;
                            }

                            fileId = Convert.ToInt32(method.Element("FileRef").Attribute("uid").Value);
                            var lines = method.Element("SequencePoints");
                            if (lines != null && lines.Elements("SequencePoint").Any())
                            {
                                foreach (var line in lines.Elements("SequencePoint"))
                                {
                                    methodCoverage.Add(new LineCoverage
                                    {
                                        LineNumber = Convert.ToInt32(line.Attribute("sl").Value),
                                        VisitCount = Convert.ToInt32(line.Attribute("vc").Value)
                                    });
                                }
                            }
                        }
                    }

                    if (fileId != null && moduleInfo.FilesList.ContainsKey(fileId.Value))
                    {
                        coverageInfo.FileId       = fileId.Value;
                        coverageInfo.CoveredLines = methodCoverage.ToList();
                        moduleInfo.ClassCoverages.Add(coverageInfo);
                    }
                }

                coverageReport.ModuleElements.Add(moduleInfo);
            }

            return(coverageReport);
        }
예제 #2
0
        private static IList <ClassCoverage> FindExternalCoveredClasses(SourceClassDetail source, CoverageDSPriv codeCoverage)
        {
            var data           = new List <ClassCoverage>();
            var thirdPartyLibs = source.TestClaz.ClassProject
                                 .GetProjectThirdPartyLibraries()
                                 .Select(x => x
                                         .Split('\\')
                                         .Last()).ToList();

            thirdPartyLibs.Add("nunit");
            thirdPartyLibs.Add("microsoft.");
            if (codeCoverage != null)
            {
                var parentClassNameList = $"{source.Claz.Syntax.NameSpace()}.{string.Join(".", source.Claz.Syntax.Ancestors<ClassDeclarationSyntax>().Select(x => x.ClassNameWithoutGeneric()))}".TrimEnd('.');
                var nestedClassNameList = $"{parentClassNameList}.{source.Claz.Syntax.ClassNameWithoutGeneric()}.{string.Join(".", source.Claz.Syntax.DescendantNodes<ClassDeclarationSyntax>().Select(x => x.ClassNameWithoutGeneric()))}".TrimEnd('.');
                if (parentClassNameList == source.Claz.Syntax.NameSpace())
                {
                    parentClassNameList = $"{parentClassNameList}.{source.Claz.Syntax.ClassNameWithoutGeneric()}";
                }

                foreach (CoverageDSPriv.ClassRow claz in codeCoverage.Class)
                {
                    if (claz.LinesCovered > 0 && thirdPartyLibs.All(x => !claz.NamespaceTableRow.ModuleRow.ModuleName.StartsWith(x, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        var className            = claz.ClassName;
                        var genericIndexLocation = claz.ClassName.IndexOf(GenericMethodStart, StringComparison.Ordinal);
                        if (genericIndexLocation != -1)
                        {
                            className = className.Substring(0, genericIndexLocation).TrimEnd('.');
                        }

                        var fullName = $"{claz.NamespaceTableRow.NamespaceName}.{className}";
                        if (data.All(x => x.ClassName != fullName) &&
                            !fullName.Contains(parentClassNameList) &&
                            !fullName.Contains(nestedClassNameList))
                        {
                            var coverages = codeCoverage
                                            .Class
                                            .Where(x => x.ClassName == className ||
                                                   x.ClassName.StartsWith($"{className}.{GenericMethodStart}") ||
                                                   x.ClassName.StartsWith($"{className}{GenericMethodStart}")).ToList();

                            coverages = coverages.Where(x => x.NamespaceTableRow.NamespaceKeyName == claz.NamespaceKeyName).ToList();

                            if (coverages.Any())
                            {
                                var methods         = codeCoverage.Method.Where(x => x.ClassKeyName == claz.ClassKeyName).ToList();
                                var method          = methods.FirstOrDefault();
                                var numberOfMutants = 0;
                                var excluded        = false;
                                var mutantsLines    = new List <int>();

                                uint autogeneratedLineCovered     = 0;
                                uint autogeneratedLineNonCovered  = 0;
                                uint autogeneratedBlockCovered    = 0;
                                uint autogeneratedBlockNonCovered = 0;

                                var file = string.Empty;
                                if (method != null)
                                {
                                    file = codeCoverage.SourceFileNames.FirstOrDefault(x => x.SourceFileID == method.GetLinesRows().FirstOrDefault()?.SourceFileID)?.SourceFileName;
                                    if (!string.IsNullOrWhiteSpace(file) && File.Exists(file))
                                    {
                                        var root             = file.GetCodeFileContent().RootNode().ClassNode(className.Split('.').Last());
                                        var classDeclaration = new ClassDeclaration(root);
                                        var classDetail      = new SourceClassDetail
                                        {
                                            Claz     = classDeclaration,
                                            TestClaz = new TestClassDetail()
                                        };

                                        if (root != null)
                                        {
                                            new MethodsInitializer().FindMethods(classDetail).Wait();
                                            var mutants = classDetail.MethodDetails
                                                          .Where(x => !x.IsProperty && !x.IsConstructor && !x.IsOverrideMethod)
                                                          .SelectMany(x => MutantOrchestrator.GetDefaultMutants(x.Method, classDetail.Claz));
                                            var coveredLines = claz.GetMethodRows().SelectMany(x => x.GetLinesRows()).Where(x => x.Coverage == 0).ToList();
                                            mutants         = mutants.Where(x => coveredLines.Any(y => y.LnStart == x.Mutation.Location)).ToList();
                                            mutantsLines    = mutants.Select(x => x.Mutation.Location ?? 0).ToList();
                                            numberOfMutants = mutants.Count();

                                            excluded = root.ExcludeFromExternalCoverage();

                                            var autogeneratedMethods = root.GetGeneratedCodeMethods();
                                            foreach (var methodSyntax in autogeneratedMethods)
                                            {
                                                var autoGeneratedCoverage = methods.FirstOrDefault(x => x.MethodFullName.Equals($"{methodSyntax.MethodName()}()") ||
                                                                                                   x.MethodName.Equals($"{methodSyntax.MethodName()}()"));
                                                if (autoGeneratedCoverage != null)
                                                {
                                                    autogeneratedLineCovered     += autoGeneratedCoverage.LinesCovered;
                                                    autogeneratedLineNonCovered  += autoGeneratedCoverage.LinesNotCovered;
                                                    autogeneratedBlockCovered    += autoGeneratedCoverage.BlocksCovered;
                                                    autogeneratedBlockNonCovered += autoGeneratedCoverage.BlocksNotCovered;
                                                }
                                            }

                                            if (methods.Any(x => x.MethodFullName.Equals($"{InitializecomponentMethod}()")) &&
                                                !autogeneratedMethods.Any() &&
                                                !classDetail.MethodDetails.Any(x => x.Method.MethodName().Equals(InitializecomponentMethod)))
                                            {
                                                var autoGeneratedCoverage = methods.First(x => x.MethodFullName.Equals($"{InitializecomponentMethod}()"));

                                                autogeneratedLineCovered     += autoGeneratedCoverage.LinesCovered;
                                                autogeneratedLineNonCovered  += autoGeneratedCoverage.LinesNotCovered;
                                                autogeneratedBlockCovered    += autoGeneratedCoverage.BlocksCovered;
                                                autogeneratedBlockNonCovered += autoGeneratedCoverage.BlocksNotCovered;
                                            }
                                        }
                                        else
                                        {
                                            excluded = true;
                                        }
                                    }
                                }

                                var classCoverage = new ClassCoverage
                                {
                                    ClassName = fullName,
                                    ClassPath = file,
                                    Coverage  = new Coverage {
                                        LinesCovered     = (uint)coverages.Sum(x => x.LinesCovered) - autogeneratedLineCovered,
                                        LinesNotCovered  = (uint)coverages.Sum(x => x.LinesNotCovered) - autogeneratedLineNonCovered,
                                        BlocksCovered    = (uint)coverages.Sum(x => x.BlocksCovered) - autogeneratedBlockCovered,
                                        BlocksNotCovered = (uint)coverages.Sum(x => x.BlocksNotCovered) - autogeneratedBlockNonCovered
                                    },
                                    NumberOfMutants = numberOfMutants,
                                    Excluded        = excluded
                                };

                                classCoverage.MutantsLines.AddRange(mutantsLines);
                                data.Add(classCoverage);
                            }
                        }
                    }
                }
            }

            return(data);
        }
        public Report Parse(string file)
        {
            var reportXml  = XDocument.Load(file);
            var modules    = reportXml.Root;
            var namespaces = modules.Elements("Assembly").SelectMany(x => x.Elements("Namespace"));

            var report = new Report
            {
                ClassCoverages = new List <ClassCoverage>(),
                FilesList      = GetProjectFilesList(modules.Element("FileIndices")?.Elements("File") ??
                                                     modules.Elements("File"))
            };

            if (report.FilesList.Count == 0)
            {
                Console.WriteLine("Warning: Got a report without File elements. Consider report dotCover with --ReportType=DetailedXML");
            }

            foreach (var module in namespaces)
            {
                var classes = module.Elements("Type");

                foreach (var projectClass in classes)
                {
                    var coverageInfo = new ClassCoverage
                    {
                        CoveragePercent = Convert.ToDouble(projectClass.Attribute("CoveragePercent").Value)
                    };

                    int?fileId         = null;
                    var methodCoverage = new List <LineCoverage>();
                    var methods        = projectClass.Elements("Member");
                    if (!methods.Any())
                    {
                        methods = projectClass.Elements("Method");
                    }

                    foreach (var method in methods)
                    {
                        var lines = method.Elements("Statement");
                        if (lines.Any())
                        {
                            fileId = Convert.ToInt32(lines.First().Attribute("FileIndex").Value);
                            foreach (var line in lines)
                            {
                                methodCoverage.Add(new LineCoverage
                                {
                                    Line    = int.Parse(line.Attribute("Line").Value),
                                    EndLine = int.Parse(line.Attribute("EndLine").Value),
                                    Covered = line.Attribute("Covered").Value == "True"
                                });
                            }
                        }

                        if (fileId != null && report.FilesList.ContainsKey(fileId.Value))
                        {
                            coverageInfo.FileId       = fileId.Value;
                            coverageInfo.CoveredLines = methodCoverage.ToList();
                            report.ClassCoverages.Add(coverageInfo);
                        }
                    }
                }
            }

            return(report);
        }