/// <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);
        }
Example #5
0
 /// <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");
 }
Example #10
0
        /// <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);
        }