public void Execute_SequencePointsOfAutoPropertiesAdded()
        {
            XDocument report = XDocument.Load(filePath);

            var classSearcherFactory = new ClassSearcherFactory();
            new OpenCoverReportPreprocessor(report, classSearcherFactory, new ClassSearcher(string.Empty)).Execute();

            Assert.AreEqual(9, report.Descendants("File").Count(), "Wrong number of total files.");

            var gettersAndSetters = report.Descendants("Class")
                .Single(c => c.Element("FullName") != null && c.Element("FullName").Value == "Test.TestClass2")
                .Elements("Methods")
                .Elements("Method")
                .Where(m => m.Attribute("isGetter").Value == "true" || m.Attribute("isSetter").Value == "true");

            foreach (var getterOrSetter in gettersAndSetters)
            {
                Assert.IsTrue(getterOrSetter.Element("FileRef") != null);
                Assert.IsTrue(getterOrSetter.Element("SequencePoints") != null);

                var sequencePoints = getterOrSetter.Element("SequencePoints").Elements("SequencePoint");
                Assert.AreEqual(1, sequencePoints.Count(), "Wrong number of sequence points.");
                Assert.AreEqual(getterOrSetter.Element("MethodPoint").Attribute("vc").Value, sequencePoints.First().Attribute("vc").Value, "Getter or setter should have been visited.");
            }
        }
        public void CreateClassSearcher_PassParentDirectory_NewInstanceIsReturned()
        {
            var sut = new ClassSearcherFactory();

            var classSearcher1 = sut.CreateClassSearcher("C:\\temp");
            var classSearcher2 = sut.CreateClassSearcher("C:\\");

            Assert.AreNotSame(classSearcher1, classSearcher2, "ClassSearchers are the same instance.");
        }
        public void CreateClassSearcher_PassSubdirectory_CachedInstanceIsReturned()
        {
            var sut = new ClassSearcherFactory();

            var classSearcher1 = sut.CreateClassSearcher("C:\\temp");
            var classSearcher2 = sut.CreateClassSearcher("C:\\temp\\sub");

            Assert.AreSame(classSearcher1, classSearcher2, "ClassSearchers are not the same instance.");
        }
        public void CreateClassSearcher_PassNull_ClassSearcherWithNullDirectoryIsReturned()
        {
            var sut = new ClassSearcherFactory();

            var classSearcher = sut.CreateClassSearcher((string)null);

            Assert.IsNotNull(classSearcher, "ClassSearcher must not be null");
            Assert.IsNull(classSearcher.Directory, "ClassSearcher directory must be null");
        }
        public static void MyClassInitialize(TestContext testContext)
        {
            FileManager.CopyTestClasses();
            assembliesWithoutPreprocessing = new PartCover23Parser(XDocument.Load(filePath)).Assemblies;

            var report = XDocument.Load(filePath);

            var classSearcherFactory = new ClassSearcherFactory();
            var globalClassSearcher = classSearcherFactory.CreateClassSearcher("C:\\test");
            new PartCover23ReportPreprocessor(report, classSearcherFactory, globalClassSearcher).Execute();
            assembliesWithPreprocessing = new PartCover23Parser(report).Assemblies;
        }
        /// <summary>
        /// Tries to initiate the correct parsers for the given reports.
        /// </summary>
        /// <param name="reportFiles">The report files to parse.</param>
        /// <param name="sourceDirectories">The source directories.</param>
        /// <returns>
        /// The IParser instance.
        /// </returns>
        public static IParser CreateParser(IEnumerable<string> reportFiles, IEnumerable<string> sourceDirectories)
        {
            if (reportFiles == null)
            {
                throw new ArgumentNullException("reportFiles");
            }

            var classSearcherFactory = new ClassSearcherFactory();
            var globalClassSearcher = classSearcherFactory.CreateClassSearcher(sourceDirectories.ToArray());

            var multiReportParser = new MultiReportParser();

            foreach (var report in reportFiles)
            {
                foreach (var parser in GetParsersOfFile(report, classSearcherFactory, globalClassSearcher))
                {
                    multiReportParser.AddParser(parser);
                }
            }

            return multiReportParser;
        }
        public void Execute_MoveStartupCodeElementsToParentType()
        {
            XDocument report = XDocument.Load(FSharpFilePath);

            var startupCodeClasses = report.Root
                .Elements("Assembly")
                .Elements("Namespace")
                .Where(c => c.Attribute("Name").Value.StartsWith("<StartupCode$", StringComparison.OrdinalIgnoreCase))
                .Elements("Type")
                .Where(t => t.Attribute("Name").Value.StartsWith("$Module", StringComparison.OrdinalIgnoreCase))
                .Elements("Type")
                .ToArray();

            Assert.AreEqual(14, startupCodeClasses.Length, "Wrong number of auto generated classes.");

            var classSearcherFactory = new ClassSearcherFactory();
            new DotCoverReportPreprocessor(report).Execute();

            var updatedStartupCodeClasses = report.Root
                .Elements("Assembly")
                .Elements("Namespace")
                .Where(c => c.Attribute("Name").Value.StartsWith("<StartupCode$", StringComparison.OrdinalIgnoreCase))
                .Elements("Type")
                .Where(t => t.Attribute("Name").Value.StartsWith("$Module", StringComparison.OrdinalIgnoreCase))
                .Elements("Type")
                .ToArray();

            Assert.AreEqual(0, updatedStartupCodeClasses.Length, "Wrong number of auto generated classes.");

            for (int i = 3; i < 7; i++)
            {
                Assert.IsTrue(startupCodeClasses[i].Parent.Attribute("Name").Value.StartsWith("MouseBehavior"));
            }

            for (int i = 8; i < 13; i++)
            {
                Assert.IsTrue(startupCodeClasses[i].Parent.Attribute("Name").Value.StartsWith("TestMouseBehavior"));
            }
        }
        public void Execute_ClassNameAddedToStartupCodeElements()
        {
            XDocument report = XDocument.Load(FSharpFilePath);

            var startupCodeClasses = report.Root
                .Elements("Modules")
                .Elements("Module")
                .Elements("Classes")
                .Elements("Class")
                .Where(c => c.Element("FullName").Value.StartsWith("<StartupCode$"))
                .ToArray();

            Assert.AreEqual(17, startupCodeClasses.Length, "Wrong number of auto generated classes.");

            var classSearcherFactory = new ClassSearcherFactory();
            new OpenCoverReportPreprocessor(report, classSearcherFactory, new ClassSearcher(string.Empty)).Execute();

            var updatedStartupCodeClasses = report.Root
                .Elements("Modules")
                .Elements("Module")
                .Elements("Classes")
                .Elements("Class")
                .Where(c => c.Element("FullName").Value.StartsWith("<StartupCode$"))
                .ToArray();

            Assert.AreEqual(3, updatedStartupCodeClasses.Length, "Wrong number of auto generated classes.");

            for (int i = 2; i < 9; i++)
            {
                Assert.IsTrue(startupCodeClasses[i].Element("FullName").Value.StartsWith("ViewModels.MouseBehavior/"));
            }

            for (int i = 9; i < 16; i++)
            {
                Assert.IsTrue(startupCodeClasses[i].Element("FullName").Value.StartsWith("ViewModels.TestMouseBehavior/"));
            }
        }
        public void Execute_SequencePointsOfAutoPropertiesAdded()
        {
            XDocument report = XDocument.Load(FilePath);

            var classSearcherFactory = new ClassSearcherFactory();
            new PartCover22ReportPreprocessor(report, classSearcherFactory, new ClassSearcher(string.Empty)).Execute();

            Assert.AreEqual(7, report.Root.Elements("file").Count(), "Wrong number of total files.");

            var gettersAndSetters = report.Root.Elements("type")
                .Single(c => c.Attribute("name").Value == "Test.TestClass2")
                .Elements("method")
                .Where(m => m.Attribute("name").Value.StartsWith("get_") || m.Attribute("name").Value.StartsWith("set_"))
                .Elements("code")
                .Select(c => c.Element("pt"));

            Assert.IsTrue(gettersAndSetters.Any());

            foreach (var getterOrSetter in gettersAndSetters)
            {
                Assert.IsTrue(getterOrSetter.Attribute("fid") != null);
                Assert.IsTrue(getterOrSetter.Attribute("sl") != null);
            }
        }
 /// <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;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="PartCover23ReportPreprocessor"/> 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 PartCover23ReportPreprocessor(XContainer report, ClassSearcherFactory classSearcherFactory, ClassSearcher globalClassSearcher)
     : base(report, classSearcherFactory, globalClassSearcher)
 {
 }
        /// <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("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));
                }
            }
            else if (report.Descendants("CoverageDSPriv").Any())
            {
                foreach (var item in report.Descendants("CoverageDSPriv"))
                {
                    Logger.DebugFormat(" " + Resources.InitiatingParser, "Visual Studio");
                    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");
                        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)
 {
 }