public void AddCoverageByTestMethod_AddCoverageByTestMethodForExistingMethod_CoverageInformationIsMerged()
        {
            var sut        = new CodeFile("C:\\temp\\Program.cs", new int[0], new LineVisitStatus[0]);
            var testMethod = new TestMethod("TestFull", "Test");

            var coverageByTrackedMethod = new CoverageByTrackedMethod()
            {
                Coverage = new int[] { -1, -1, -1, -1, 0, 0, 0, 1, 1, 1 }, LineVisitStatus = new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.NotCovered, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.Covered, LineVisitStatus.Covered }
            };
            var repeatedCoverageByTrackedMethod = new CoverageByTrackedMethod()
            {
                Coverage = new int[] { -1, 0, 1, -1, 1, 0, 1, -1, 1, 0 }, LineVisitStatus = new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.Covered, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.Covered, LineVisitStatus.NotCovered }
            };

            sut.AddCoverageByTestMethod(testMethod, coverageByTrackedMethod);
            sut.AddCoverageByTestMethod(testMethod, repeatedCoverageByTrackedMethod);

            Assert.Contains(testMethod, sut.TestMethods);

            // using AnalyseFile() to retrieve merged coverage by test method
            var lineAnalyses       = sut.AnalyzeFile(new CachingFileReader(0)).Lines;
            var testMethodCoverage = lineAnalyses.Take(9).Select(l => l.LineCoverageByTestMethod).ToArray();

            Assert.True(testMethodCoverage.All(coverage => coverage.ContainsKey(testMethod)), "All lines should be covered by given test method");

            var actualLineVisits        = testMethodCoverage.Select(c => c[testMethod].LineVisits).ToArray();
            var actualLineVisitStatuses = testMethodCoverage.Select(c => c[testMethod].LineVisitStatus).ToArray();

            Assert.Equal(new int[] { 0, 1, -1, 1, 0, 1, 1, 2, 1 }, actualLineVisits);
            Assert.Equal(new LineVisitStatus[] { LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.Covered, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.Covered, LineVisitStatus.Covered, LineVisitStatus.Covered }, actualLineVisitStatuses);
        }
예제 #2
0
        public void AnalyzeFile_ExistingFileWithTrackedMethods_AnalysisIsReturned()
        {
            var sut        = new CodeFile("C:\\temp\\Program.cs", new int[] { -2, -1, 0, 1 });
            var testMethod = new TestMethod("TestFull", "Test");

            sut.AddCoverageByTestMethod(testMethod, new int[] { -2, 1, -1, 0 });

            var fileAnalysis = sut.AnalyzeFile();

            Assert.AreEqual(1, fileAnalysis.Lines.First().LineCoverageByTestMethod[testMethod].LineVisits);
            Assert.AreEqual(LineVisitStatus.Covered, fileAnalysis.Lines.First().LineCoverageByTestMethod[testMethod].LineVisitStatus);
        }
예제 #3
0
        public void Merge_MergeCodeFileWithEqualLengthCoverageArray_CoverageInformationIsUpdated()
        {
            var sut             = new CodeFile("C:\\temp\\Program.cs", new int[] { -1, -1, -1, 0, 0, 0, 1, 1, 1 });
            var codeFileToMerge = new CodeFile("C:\\temp\\Program.cs", new int[] { -1, 0, 1, -1, 0, 1, -1, 0, 1 });
            var testMethod      = new TestMethod("TestFull", "Test");

            codeFileToMerge.AddCoverageByTestMethod(testMethod, new int[] { -1, -1, -1, 0, 0, 0, 1, 1, 1 });

            sut.Merge(codeFileToMerge);

            Assert.AreEqual(8, sut.CoverableLines, "Not equal");
            Assert.AreEqual(5, sut.CoveredLines, "Not equal");
            Assert.IsTrue(sut.TestMethods.Contains(testMethod));
        }
        public void AnalyzeFile_ExistingFileWithTrackedMethods_AnalysisIsReturned()
        {
            var sut        = new CodeFile("C:\\temp\\Program.cs", new int[] { -2, -1, 0, 1 }, new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered });
            var testMethod = new TestMethod("TestFull", "Test");

            sut.AddCoverageByTestMethod(testMethod, new CoverageByTrackedMethod()
            {
                Coverage = new int[] { -2, 2, -1, 0 }, LineVisitStatus = new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered }
            });

            var fileAnalysis = sut.AnalyzeFile(new CachingFileReader(0));

            Assert.Equal(2, fileAnalysis.Lines.First().LineCoverageByTestMethod[testMethod].LineVisits);
            Assert.Equal(LineVisitStatus.Covered, fileAnalysis.Lines.First().LineCoverageByTestMethod[testMethod].LineVisitStatus);
        }
        public void Merge_MergeCodeFileWithLongerCoverageArray_CoverageInformationIsUpdated()
        {
            var branches = new Dictionary <int, ICollection <Branch> >()
            {
                { 1, new List <Branch>()
                  {
                      new Branch(1, "1"), new Branch(0, "2")
                  } },
                { 2, new List <Branch>()
                  {
                      new Branch(0, "3"), new Branch(2, "4")
                  } }
            };
            var sut        = new CodeFile("C:\\temp\\Program.cs", new int[] { -1, -1, -1, 0, 0, 0, 1, 1, 1 }, new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.NotCovered, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.Covered, LineVisitStatus.Covered }, branches);
            var testMethod = new TestMethod("TestFull", "Test");

            sut.AddCoverageByTestMethod(testMethod, new CoverageByTrackedMethod()
            {
                Coverage = new int[] { -1, -1, -1, 0, 0, 0, 1, 1, 1 }, LineVisitStatus = new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.NotCovered, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.Covered, LineVisitStatus.Covered }
            });

            var branches2 = new Dictionary <int, ICollection <Branch> >()
            {
                { 1, new List <Branch>()
                  {
                      new Branch(4, "1"), new Branch(3, "5")
                  } },
                { 3, new List <Branch>()
                  {
                      new Branch(0, "3"), new Branch(2, "4")
                  } }
            };
            var codeFileToMerge = new CodeFile("C:\\temp\\Program.cs", new int[] { -1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1 }, new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered }, branches2);

            testMethod = new TestMethod("TestFull", "Test");
            codeFileToMerge.AddCoverageByTestMethod(testMethod, new CoverageByTrackedMethod()
            {
                Coverage = new int[] { -1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1 }, LineVisitStatus = new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered }
            });

            sut.Merge(codeFileToMerge);

            Assert.Equal(10, sut.CoverableLines);
            Assert.Equal(6, sut.CoveredLines);

            Assert.Equal(4, sut.CoveredBranches);
            Assert.Equal(7, sut.TotalBranches);
        }
        public void Merge_MergeCodeFileWithEqualLengthCoverageArray_CoverageInformationIsUpdated()
        {
            var sut             = new CodeFile("C:\\temp\\Program.cs", new int[] { -1, -1, -1, 0, 0, 0, 1, 1, 1 }, new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.NotCovered, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.Covered, LineVisitStatus.Covered });
            var codeFileToMerge = new CodeFile("C:\\temp\\Program.cs", new int[] { -1, 0, 1, -1, 0, 1, -1, 0, 1 }, new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered });
            var testMethod      = new TestMethod("TestFull", "Test");

            codeFileToMerge.AddCoverageByTestMethod(testMethod, new CoverageByTrackedMethod()
            {
                Coverage = new int[] { -1, -1, -1, 0, 0, 0, 1, 1, 1 }, LineVisitStatus = new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.NotCovered, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.Covered, LineVisitStatus.Covered }
            });

            sut.Merge(codeFileToMerge);

            Assert.Equal(8, sut.CoverableLines);
            Assert.Equal(5, sut.CoveredLines);

            Assert.Null(sut.CoveredBranches);
            Assert.Null(sut.TotalBranches);

            Assert.Contains(testMethod, sut.TestMethods);
        }
예제 #7
0
        /// <summary>
        /// Processes the file.
        /// </summary>
        /// <param name="fileIds">The file ids of the class.</param>
        /// <param name="class">The class.</param>
        /// <param name="filePath">The file path.</param>
        /// <returns>The <see cref="CodeFile"/>.</returns>
        private CodeFile ProcessFile(HashSet <string> fileIds, Class @class, string filePath)
        {
            var methods = this.modules
                          .Where(m => m.Element("ModuleName").Value.Equals(@class.Assembly.Name))
                          .Elements("Classes")
                          .Elements("Class")
                          .Where(c => c.Element("FullName").Value.Equals(@class.Name) ||
                                 c.Element("FullName").Value.StartsWith(@class.Name + "/", StringComparison.Ordinal))
                          .Elements("Methods")
                          .Elements("Method")
                          .ToArray();

            var methodsOfFile = methods
                                .Where(m => m.Element("FileRef") != null && fileIds.Contains(m.Element("FileRef").Attribute("uid").Value))
                                .ToArray();

            SetMethodMetrics(methodsOfFile, @class);

            var seqpntsOfFile = methods
                                .Elements("SequencePoints")
                                .Elements("SequencePoint")
                                .Where(seqpnt => (seqpnt.Attribute("fileid") != null &&
                                                  fileIds.Contains(seqpnt.Attribute("fileid").Value)) ||
                                       (seqpnt.Attribute("fileid") == null && seqpnt.Parent.Parent.Element("FileRef") != null &&
                                        fileIds.Contains(seqpnt.Parent.Parent.Element("FileRef").Attribute("uid").Value)))
                                .Select(seqpnt => new
            {
                LineNumberStart   = int.Parse(seqpnt.Attribute("sl").Value, CultureInfo.InvariantCulture),
                LineNumberEnd     = seqpnt.Attribute("el") != null ? int.Parse(seqpnt.Attribute("el").Value, CultureInfo.InvariantCulture) : int.Parse(seqpnt.Attribute("sl").Value, CultureInfo.InvariantCulture),
                Visits            = int.Parse(seqpnt.Attribute("vc").Value, CultureInfo.InvariantCulture),
                TrackedMethodRefs = seqpnt.Elements("TrackedMethodRefs")
                                    .Elements("TrackedMethodRef")
                                    .Select(t => new
                {
                    Visits          = int.Parse(t.Attribute("vc").Value, CultureInfo.InvariantCulture),
                    TrackedMethodId = t.Attribute("uid").Value
                })
            })
                                .OrderBy(seqpnt => seqpnt.LineNumberEnd)
                                .ToArray();

            int[] coverage = new int[] { };
            var   branches = GetBranches(methods, fileIds);

            var trackedMethodsCoverage = seqpntsOfFile
                                         .SelectMany(s => s.TrackedMethodRefs)
                                         .Select(t => t.TrackedMethodId)
                                         .Distinct()
                                         .ToDictionary(id => id, id => new int[] { });

            if (seqpntsOfFile.Length > 0)
            {
                coverage = new int[seqpntsOfFile[seqpntsOfFile.LongLength - 1].LineNumberEnd + 1];

                for (int i = 0; i < coverage.Length; i++)
                {
                    coverage[i] = -1;
                }

                foreach (var name in trackedMethodsCoverage.Keys.ToArray())
                {
                    trackedMethodsCoverage[name] = (int[])coverage.Clone();
                }

                foreach (var seqpnt in seqpntsOfFile)
                {
                    for (int lineNumber = seqpnt.LineNumberStart; lineNumber <= seqpnt.LineNumberEnd; lineNumber++)
                    {
                        int visits = coverage[lineNumber] == -1 ? seqpnt.Visits : coverage[lineNumber] + seqpnt.Visits;
                        coverage[lineNumber] = visits;

                        if (visits > -1)
                        {
                            foreach (var trackedMethodCoverage in trackedMethodsCoverage)
                            {
                                if (trackedMethodCoverage.Value[lineNumber] == -1)
                                {
                                    trackedMethodCoverage.Value[lineNumber] = 0;
                                }
                            }
                        }

                        foreach (var trackedMethod in seqpnt.TrackedMethodRefs)
                        {
                            var trackedMethodCoverage = trackedMethodsCoverage[trackedMethod.TrackedMethodId];
                            trackedMethodCoverage[lineNumber] = trackedMethodCoverage[lineNumber] == -1 ? trackedMethod.Visits : trackedMethodCoverage[lineNumber] + trackedMethod.Visits;
                        }
                    }
                }
            }

            var codeFile = new CodeFile(filePath, coverage, branches);

            foreach (var trackedMethodCoverage in trackedMethodsCoverage)
            {
                string name = null;

                // Sometimes no corresponding MethodRef element exists
                if (this.trackedMethods.TryGetValue(trackedMethodCoverage.Key, out name))
                {
                    string     shortName  = name.Substring(name.Substring(0, name.IndexOf(':') + 1).LastIndexOf('.') + 1);
                    TestMethod testMethod = new TestMethod(name, shortName);
                    codeFile.AddCoverageByTestMethod(testMethod, trackedMethodCoverage.Value);
                }
            }

            return(codeFile);
        }
예제 #8
0
        /// <summary>
        /// Processes the file.
        /// </summary>
        /// <param name="fileIds">The file ids of the class.</param>
        /// <param name="class">The class.</param>
        /// <param name="filePath">The file path.</param>
        /// <returns>The <see cref="CodeFile"/>.</returns>
        private CodeFile ProcessFile(HashSet <string> fileIds, Class @class, string filePath)
        {
            var methods = this.modules
                          .Where(m => m.Element("ModuleName").Value.Equals(@class.Assembly.Name))
                          .Elements("Classes")
                          .Elements("Class")
                          .Where(c => c.Element("FullName").Value.Equals(@class.Name) ||
                                 c.Element("FullName").Value.StartsWith(@class.Name + "/", StringComparison.Ordinal))
                          .Elements("Methods")
                          .Elements("Method")
                          .ToArray();

            var methodsOfFile = methods
                                .Where(m => m.Element("FileRef") != null && fileIds.Contains(m.Element("FileRef").Attribute("uid").Value))
                                .ToArray();

            SetMethodMetrics(methodsOfFile, @class);

            var seqpntsOfFile = methods
                                .Elements("SequencePoints")
                                .Elements("SequencePoint")
                                .Where(seqpnt => (seqpnt.Attribute("fileid") != null &&
                                                  fileIds.Contains(seqpnt.Attribute("fileid").Value)) ||
                                       (seqpnt.Attribute("fileid") == null && seqpnt.Parent.Parent.Element("FileRef") != null &&
                                        fileIds.Contains(seqpnt.Parent.Parent.Element("FileRef").Attribute("uid").Value)))
                                .Select(seqpnt => new
            {
                LineNumberStart   = int.Parse(seqpnt.Attribute("sl").Value, CultureInfo.InvariantCulture),
                LineNumberEnd     = seqpnt.Attribute("el") != null ? int.Parse(seqpnt.Attribute("el").Value, CultureInfo.InvariantCulture) : int.Parse(seqpnt.Attribute("sl").Value, CultureInfo.InvariantCulture),
                Visits            = int.Parse(seqpnt.Attribute("vc").Value, CultureInfo.InvariantCulture),
                TrackedMethodRefs = seqpnt.Elements("TrackedMethodRefs")
                                    .Elements("TrackedMethodRef")
                                    .Select(t => new
                {
                    Visits          = int.Parse(t.Attribute("vc").Value, CultureInfo.InvariantCulture),
                    TrackedMethodId = t.Attribute("uid").Value
                })
            })
                                .OrderBy(seqpnt => seqpnt.LineNumberEnd)
                                .ToArray();

            var branches = GetBranches(methods, fileIds);

            var coverageByTrackedMethod = seqpntsOfFile
                                          .SelectMany(s => s.TrackedMethodRefs)
                                          .Select(t => t.TrackedMethodId)
                                          .Distinct()
                                          .ToDictionary(id => id, id => new CoverageByTrackedMethod {
                Coverage = new int[] { }, LineVisitStatus = new LineVisitStatus[] { }
            });

            int[]             coverage        = new int[] { };
            LineVisitStatus[] lineVisitStatus = new LineVisitStatus[] { };

            if (seqpntsOfFile.Length > 0)
            {
                coverage        = new int[seqpntsOfFile[seqpntsOfFile.LongLength - 1].LineNumberEnd + 1];
                lineVisitStatus = new LineVisitStatus[seqpntsOfFile[seqpntsOfFile.LongLength - 1].LineNumberEnd + 1];

                for (int i = 0; i < coverage.Length; i++)
                {
                    coverage[i] = -1;
                }

                foreach (var trackedMethodCoverage in coverageByTrackedMethod)
                {
                    trackedMethodCoverage.Value.Coverage        = (int[])coverage.Clone();
                    trackedMethodCoverage.Value.LineVisitStatus = new LineVisitStatus[seqpntsOfFile[seqpntsOfFile.LongLength - 1].LineNumberEnd + 1];
                }

                foreach (var seqpnt in seqpntsOfFile)
                {
                    for (int lineNumber = seqpnt.LineNumberStart; lineNumber <= seqpnt.LineNumberEnd; lineNumber++)
                    {
                        int visits = coverage[lineNumber] == -1 ? seqpnt.Visits : coverage[lineNumber] + seqpnt.Visits;
                        coverage[lineNumber] = visits;

                        if (lineVisitStatus[lineNumber] != LineVisitStatus.Covered)
                        {
                            bool partiallyCovered = false;

                            ICollection <Branch> branchesOfLine = null;

                            // Use 'LineNumberStart' instead of 'lineNumber' here. Branches have line number of first line of seqpnt
                            if (branches.TryGetValue(seqpnt.LineNumberStart, out branchesOfLine))
                            {
                                partiallyCovered = branchesOfLine.Any(b => b.BranchVisits == 0);
                            }

                            LineVisitStatus statusOfLine = visits > 0 ? (partiallyCovered ? LineVisitStatus.PartiallyCovered : LineVisitStatus.Covered) : LineVisitStatus.NotCovered;
                            lineVisitStatus[lineNumber] = (LineVisitStatus)Math.Max((int)lineVisitStatus[lineNumber], (int)statusOfLine);
                        }

                        if (visits > -1)
                        {
                            foreach (var trackedMethodCoverage in coverageByTrackedMethod)
                            {
                                if (trackedMethodCoverage.Value.Coverage[lineNumber] == -1)
                                {
                                    trackedMethodCoverage.Value.Coverage[lineNumber]        = 0;
                                    trackedMethodCoverage.Value.LineVisitStatus[lineNumber] = LineVisitStatus.NotCovered;
                                }
                            }
                        }

                        foreach (var trackedMethod in seqpnt.TrackedMethodRefs)
                        {
                            var trackedMethodCoverage = coverageByTrackedMethod[trackedMethod.TrackedMethodId];

                            int             trackeMethodVisits = trackedMethodCoverage.Coverage[lineNumber] == -1 ? trackedMethod.Visits : trackedMethodCoverage.Coverage[lineNumber] + trackedMethod.Visits;
                            LineVisitStatus statusOfLine       = trackeMethodVisits > 0 ? (LineVisitStatus)Math.Min((int)LineVisitStatus.Covered, (int)lineVisitStatus[lineNumber]) : LineVisitStatus.NotCovered;

                            trackedMethodCoverage.Coverage[lineNumber]        = trackeMethodVisits;
                            trackedMethodCoverage.LineVisitStatus[lineNumber] = statusOfLine;
                        }
                    }
                }
            }

            var codeFile = new CodeFile(filePath, coverage, lineVisitStatus, branches);

            foreach (var trackedMethodCoverage in coverageByTrackedMethod)
            {
                string name = null;

                // Sometimes no corresponding MethodRef element exists
                if (this.trackedMethods.TryGetValue(trackedMethodCoverage.Key, out name))
                {
                    string     shortName  = name.Substring(name.Substring(0, name.IndexOf(':') + 1).LastIndexOf('.') + 1);
                    TestMethod testMethod = new TestMethod(name, shortName);
                    codeFile.AddCoverageByTestMethod(testMethod, trackedMethodCoverage.Value);
                }
            }

            SetCodeElements(codeFile, methodsOfFile);

            return(codeFile);
        }