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); }
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.IsNull(sut.CoveredBranches, "Not null"); Assert.IsNull(sut.TotalBranches, "Not null"); Assert.IsTrue(sut.TestMethods.Contains(testMethod)); }
/// <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; }
/// <summary> /// Adds the coverage by test method. /// </summary> /// <param name="testMethod">The test method.</param> /// <param name="coverage">The coverage.</param> internal void AddCoverageByTestMethod(TestMethod testMethod, int[] coverage) { if (testMethod == null) { throw new ArgumentNullException(nameof(testMethod)); } if (coverage == null) { throw new ArgumentNullException(nameof(coverage)); } this.lineCoveragesByTestMethod.Add(testMethod, coverage); }
/// <summary> /// Adds the coverage by test method. /// </summary> /// <param name="testMethod">The test method.</param> /// <param name="coverage">The coverage.</param> public void AddCoverageByTestMethod(TestMethod testMethod, int[] coverage) { if (testMethod == null) { throw new ArgumentNullException("testMethod"); } if (coverage == null) { throw new ArgumentNullException("coverage"); } this.lineCoveragesByTestMethod.Add(testMethod, coverage); }
private void ProcessTestMethods(CodeFile codeFile, IEnumerable<CoverageLine> lines) { var methods = lines.GroupBy (x => x.MethodName); foreach (var method in methods) { string shortName = method.Key.Substring(method.Key.Substring(0, method.Key.IndexOf('/') + 1).LastIndexOf('.') + 1); TestMethod testMethod = new TestMethod (method.Key, shortName); var maxLine = method.Max (x => x.LineNumStart); if (maxLine == -1) continue; int [] coverage = new int [maxLine+1]; for (int i = 0; i < coverage.Length; i++) coverage [i] = -1; foreach (var sourceLine in method) { if (sourceLine.LineNumStart != -1) for (int i = sourceLine.LineNumStart; i <= sourceLine.LineNumEnd; i++) coverage [i] = sourceLine.Missed ? 0 : 1; } codeFile.AddCoverageByTestMethod (testMethod, coverage); } }