/// <summary> /// Tries to find file ids of class. /// </summary> /// <param name="classSearcher">The class searcher.</param> /// <param name="className">Name of the class.</param> /// <param name="filenameByFileIdDictionary">Dictionary containing all files used in the report by their corresponding id.</param> /// <param name="filesContainer">The files container.</param> /// <returns>The ids of the files the class is defined in.</returns> private IEnumerable <string> TryToFindFileIdsOfClass(ClassSearcher classSearcher, string className, Dictionary <string, string> filenameByFileIdDictionary, XContainer filesContainer) { IEnumerable <string> files = classSearcher.GetFilesOfClass(className.Replace("/", string.Empty)); var fileIds = new List <string>(); foreach (var file in files) { var existingFileId = filenameByFileIdDictionary.Where(kv => kv.Value == file).Select(kv => kv.Key).FirstOrDefault(); if (existingFileId != null) { fileIds.Add(existingFileId); } else { // Update dictionary string newFileId = this.currentFileId.ToString(CultureInfo.InvariantCulture); filenameByFileIdDictionary.Add(newFileId, file); fileIds.Add(newFileId); // Update report this.AddNewFile(filesContainer, newFileId, file); this.currentFileId--; } } return(fileIds); }
/// <summary> /// Creates a collection of relations from a collection of classes. /// <para>A returned collection contains only relations between classes included in argument <paramref name="classes"/></para> /// </summary> /// <param name="classes">Collection of classes</param> /// <returns>Collection of relations</returns> public static IEnumerable <Relation> CreateFromClasses(IEnumerable <ClassInfo> classes) { var relations = new HashSet <Relation>(); var classSearcher = new ClassSearcher(classes.SelectMany(c => c.GetAllClasses())); foreach (var cls in classes) { // Inheritance foreach (var inheritedType in cls.InheritedClasses) { var inheritedClass = classSearcher.Search(inheritedType); if (inheritedClass == null) { continue; } var type = (inheritedClass.Category == ClassCategory.Interface) ? RelationType.Realization : RelationType.Generalization; relations.Add(new Relation(cls, inheritedClass, type)); } // Inner classes GetNestedRelationsRecursively(cls, relations); // Types used in fields -> Association foreach (var type in cls.Fields.SelectMany(f => f.GetRelatedTypes())) { // Uses a corresponding type name in a ClassInfo collection, instead of using a type name described in a field definition. var relatedClass = classSearcher.Search(type); if (relatedClass == null) { continue; } relations.Add(new Relation(cls, relatedClass, RelationType.Association)); } // Types used in methods -> Dependency foreach (var type in cls.Methods.SelectMany(m => m.GetRelatedTypes())) { // Uses a corresponding type name in a ClassInfo collection, instead of using a type name described in a method definition. var relatedClass = classSearcher.Search(type); if (relatedClass == null) { continue; } relations.Add(new Relation(cls, relatedClass, RelationType.Dependency)); } } RemoveRedundantRelations(relations); return(relations); }
/// <summary> /// Searches the given source element (e.g. property) and updates the report if element can be found in source code files. /// </summary> /// <param name="sourceElement">The source element.</param> /// <param name="filenameByFileIdDictionary">Dictionary containing all files used in the report by their corresponding id.</param> /// <param name="fileIdsOfClass">The file ids of class.</param> /// <param name="reportElement">The report element.</param> /// <param name="updateReportElement">Action that updates the report element.</param> /// <param name="filesContainer">The files container.</param> /// <returns><c>true</c> if source element has been found.</returns> protected bool SearchElement( SourceElement sourceElement, Dictionary <string, string> filenameByFileIdDictionary, IEnumerable <string> fileIdsOfClass, XContainer reportElement, Action <XContainer, SourceElementPosition, string> updateReportElement, XContainer filesContainer) { Func <bool> searchSourceElement = () => { foreach (var fileId in fileIdsOfClass) { var elementPosition = SourceCodeAnalyzer.FindSourceElement(filenameByFileIdDictionary[fileId], sourceElement); if (elementPosition != null) { updateReportElement(reportElement, elementPosition, fileId); return(true); } } return(false); }; // Search files from module first if (!searchSourceElement()) { // Property has not been found in classes of module, now search the common directory if (this.ClassSearcher == null) { this.ClassSearcher = this.classSearcherFactory.CreateClassSearcher(CommonDirectorySearcher.GetCommonDirectory(filenameByFileIdDictionary.Values)); } fileIdsOfClass = this.TryToFindFileIdsOfClass( this.ClassSearcher, sourceElement.Classname, filenameByFileIdDictionary, filesContainer); // Property has not been found in common directory, now search the global directory if (!searchSourceElement()) { fileIdsOfClass = this.TryToFindFileIdsOfClass( this.globalClassSearcher, sourceElement.Classname, filenameByFileIdDictionary, filesContainer); return(searchSourceElement()); } } return(true); }
/// <summary> /// Tries to initiate the correct parsers for the given report. An empty list is returned if no parser has been found. /// The report may contain several reports. For every report an extra parser is initiated. /// </summary> /// <param name="reportFile">The report file to parse.</param> /// <param name="classSearcherFactory">The class searcher factory.</param> /// <param name="globalClassSearcher">The global class searcher.</param> /// <returns> /// The IParser instances or an empty list if no matching parser has been found. /// </returns> private static IEnumerable <IParser> GetParsersOfFile(string reportFile, ClassSearcherFactory classSearcherFactory, ClassSearcher globalClassSearcher) { var parsers = new List <IParser>(); XContainer report = null; try { Logger.InfoFormat(Resources.LoadingReport, reportFile); report = XDocument.Load(reportFile); } catch (Exception ex) { Logger.ErrorFormat(" " + Resources.ErrorDuringReadingReport, reportFile, ex.Message); return(parsers); } if (report.Descendants("CoverageSession").Any()) { foreach (var item in report.Descendants("CoverageSession")) { Logger.Debug(" " + Resources.PreprocessingReport); new OpenCoverReportPreprocessor(item).Execute(); Logger.DebugFormat(" " + Resources.InitiatingParser, "OpenCover"); parsers.Add(new OpenCoverParser(item)); } } else if (report.Descendants("Root").Where(e => e.Attribute("ReportType") != null && e.Attribute("ReportType").Value == "DetailedXml").Any()) { foreach (var item in report.Descendants("Root").Where(e => e.Attribute("ReportType") != null && e.Attribute("ReportType").Value == "DetailedXml")) { Logger.Debug(" " + Resources.PreprocessingReport); new DotCoverReportPreprocessor(item).Execute(); Logger.DebugFormat(" " + Resources.InitiatingParser, "dotCover"); parsers.Add(new DotCoverParser(item)); } } else if (report.Descendants("PartCoverReport").Any()) { // PartCover 2.2 and PartCover 2.3 reports differ in version attribute, so use this to determine the correct parser if (report.Descendants("PartCoverReport").First().Attribute("ver") != null) { foreach (var item in report.Descendants("PartCoverReport")) { Logger.Debug(" " + Resources.PreprocessingReport); new PartCover22ReportPreprocessor(item, classSearcherFactory, globalClassSearcher).Execute(); Logger.DebugFormat(" " + Resources.InitiatingParser, "PartCover 2.2"); parsers.Add(new PartCover22Parser(item)); } } else { foreach (var item in report.Descendants("PartCoverReport")) { Logger.Debug(" " + Resources.PreprocessingReport); new PartCover23ReportPreprocessor(item, classSearcherFactory, globalClassSearcher).Execute(); Logger.DebugFormat(" " + Resources.InitiatingParser, "PartCover 2.3"); parsers.Add(new PartCover23Parser(item)); } } } else if (report.Descendants("coverage").Any()) { foreach (var item in report.Descendants("coverage")) { if (item.Attribute("profilerVersion") != null) { Logger.DebugFormat(" " + Resources.InitiatingParser, "NCover"); parsers.Add(new NCoverParser(item)); } else if (item.Attributes().Count() > 1) { Logger.Debug(" " + Resources.PreprocessingReport); new CoberturaReportPreprocessor(item).Execute(); Logger.DebugFormat(" " + Resources.InitiatingParser, "Cobertura"); parsers.Add(new CoberturaParser(item)); } else { Logger.DebugFormat(" " + Resources.InitiatingParser, "mprof"); parsers.Add(new MProfParser(item)); } } } else if (report.Descendants("CoverageDSPriv").Any()) { foreach (var item in report.Descendants("CoverageDSPriv")) { Logger.DebugFormat(" " + Resources.InitiatingParser, "Visual Studio"); new VisualStudioReportPreprocessor(item).Execute(); parsers.Add(new VisualStudioParser(item)); } } else if (report.Descendants("results").Any()) { foreach (var item in report.Descendants("results")) { if (item.Element("modules") != null) { Logger.DebugFormat(" " + Resources.InitiatingParser, "Dynamic Code Coverage"); new DynamicCodeCoverageReportPreprocessor(item).Execute(); parsers.Add(new DynamicCodeCoverageParser(item)); } } } return(parsers); }
/// <summary> /// Initializes a new instance of the <see cref="OpenCoverReportPreprocessor"/> class. /// </summary> /// <param name="report">The report.</param> /// <param name="classSearcherFactory">The class searcher factory.</param> /// <param name="globalClassSearcher">The global class searcher.</param> public OpenCoverReportPreprocessor(XContainer report, ClassSearcherFactory classSearcherFactory, ClassSearcher globalClassSearcher) : base(report, classSearcherFactory, globalClassSearcher) { }
/// <summary> /// Initializes a new instance of the <see cref="PartCover22ReportPreprocessor"/> class. /// </summary> /// <param name="report">The report.</param> /// <param name="classSearcherFactory">The class searcher factory.</param> /// <param name="globalClassSearcher">The global class searcher.</param> internal PartCover22ReportPreprocessor(XContainer report, ClassSearcherFactory classSearcherFactory, ClassSearcher globalClassSearcher) : base(report, classSearcherFactory, globalClassSearcher) { }
/// <summary> /// Initializes a new instance of the <see cref="ReportPreprocessorBase"/> class. /// </summary> /// <param name="report">The report.</param> /// <param name="classSearcherFactory">The class searcher factory.</param> /// <param name="globalClassSearcher">The global class searcher.</param> internal ReportPreprocessorBase(XContainer report, ClassSearcherFactory classSearcherFactory, ClassSearcher globalClassSearcher) { this.Report = report; this.classSearcherFactory = classSearcherFactory; this.globalClassSearcher = globalClassSearcher; }
public static void MyClassInitialize(TestContext testContext) { FileManager.CopyTestClasses(); classSearcher = new ClassSearcher("C:\\temp"); }
public static void MyClassInitialize(TestContext testContext) { classSearcher = new ClassSearcher("C:\\temp"); }
/// <summary> /// Tries to initiate the correct parsers for the given report. An empty list is returned if no parser has been found. /// The report may contain serveral reports. For every report an extra parser is initiated. /// </summary> /// <param name="reportFile">The report file to parse.</param> /// <param name="classSearcherFactory">The class searcher factory.</param> /// <param name="globalClassSearcher">The global class searcher.</param> /// <returns> /// The IParser instances or an empty list if no matching parser has been found. /// </returns> private static IEnumerable <IParser> GetParsersOfFile(string reportFile, ClassSearcherFactory classSearcherFactory, ClassSearcher globalClassSearcher) { var parsers = new List <IParser>(); XContainer report = null; try { logger.InfoFormat(Resources.LoadingReport, reportFile); report = XDocument.Load(reportFile); } catch (Exception ex) { logger.ErrorFormat(" " + Resources.ErrorDuringReadingReport, reportFile, ex.Message); return(parsers); } if (report.Descendants("PartCoverReport").Any()) { // PartCover 2.2 and PartCover 2.3 reports differ in version attribute, so use this to determine the correct parser if (report.Descendants("PartCoverReport").First().Attribute("ver") != null) { foreach (var item in report.Descendants("PartCoverReport")) { logger.Debug(" " + Resources.PreprocessingReport); new PartCover22ReportPreprocessor(item, classSearcherFactory, globalClassSearcher).Execute(); logger.DebugFormat(" " + Resources.InitiatingParser, "PartCover 2.2"); parsers.Add(new PartCover22Parser(item)); } } else { foreach (var item in report.Descendants("PartCoverReport")) { logger.Debug(" " + Resources.PreprocessingReport); new PartCover23ReportPreprocessor(item, classSearcherFactory, globalClassSearcher).Execute(); logger.DebugFormat(" " + Resources.InitiatingParser, "PartCover 2.3"); parsers.Add(new PartCover23Parser(item)); } } } else if (report.Descendants("CoverageSession").Any()) { foreach (var item in report.Descendants("CoverageSession")) { logger.Debug(" " + Resources.PreprocessingReport); new OpenCoverReportPreprocessor(item, classSearcherFactory, globalClassSearcher).Execute(); logger.DebugFormat(" " + Resources.InitiatingParser, "OpenCover"); parsers.Add(new OpenCoverParser(item)); } } else if (report.Descendants("coverage").Any()) { foreach (var item in report.Descendants("coverage")) { logger.DebugFormat(" " + Resources.InitiatingParser, "NCover"); parsers.Add(new NCoverParser(item)); } } return(parsers); }