private static void TransformSequences_AddSources(IEnumerable <File> files, IEnumerable <Method> methods, IDictionary <uint, CodeCoverageStringTextSource> sourceRepository) { if (files == null || !files.Any()) { return; } // Dictionary with stored source file names per module var filesDictionary = new Dictionary <string, uint>(); foreach (var file in files. Where(file => !String.IsNullOrWhiteSpace(file.FullPath) && !filesDictionary.ContainsKey(file.FullPath))) { var source = CodeCoverageStringTextSource.GetSource(file.FullPath); // never reurns null if (source.FileType == FileType.CSharp) { sourceRepository.Add(file.UniqueId, source); } filesDictionary.Add(file.FullPath, file.UniqueId); } foreach (var method in methods) { if (method.SequencePoints.Length != 0) { MapFileReferences(method.SequencePoints, filesDictionary); } if (method.BranchPoints.Length != 0) { MapFileReferences(method.BranchPoints, filesDictionary); } } }
public void WhenLoggerNotProvided_ExceptionThrown() { // arrange ILog logger = null; // act/assert Assert.Throws <ArgumentNullException>(() => CodeCoverageStringTextSource.GetSource("", logger)); }
public void CreateGetKeysValuesCopyEnumerate() { var sRepo = new SourceRepository(); Assert.True(sRepo.IsReadOnly == false); Assert.True(sRepo.Count == 0); var mockLog = new Mock <ILog>(); var source1 = new CodeCoverageStringTextSource("abc", "", mockLog.Object); const uint fileId1 = 1; sRepo.Add(fileId1, source1); Assert.True(sRepo.Count == 1); Assert.True(sRepo.Keys.Count == 1); Assert.True(sRepo.Values.Count == 1); var source2 = new CodeCoverageStringTextSource("def", "", mockLog.Object); const uint fileId2 = 2; sRepo.Add(fileId2, source2); Assert.True(sRepo.Count == 2); var array = new KeyValuePair <uint, CodeCoverageStringTextSource> [2]; Assert.That(delegate { sRepo.CopyTo(array, 0); }, Throws.Nothing); // IDictionary is not ordered Assert.True(array[0].Key == fileId1 || array[1].Key == fileId2); Assert.True(array[0].Value == source1 || array[1].Value == source2); Assert.True(array[1].Key != default(uint)); Assert.True(array[1].Value != default(CodeCoverageStringTextSource)); // covers generic enumerator int count = 0; foreach (var item in sRepo) { Assert.True(item.Key != default(uint)); Assert.True(item.Value != default(CodeCoverageStringTextSource)); count += 1; } Assert.True(count == 2); // covers GetEnumerator count = 0; var e = ((IEnumerable)sRepo).GetEnumerator(); while (e.MoveNext()) { count += 1; } Assert.True(count == 2); }
public void CreateGetSourceAndSequencePoints() { const uint fileId1 = 1; const string sourceString = "abc { def }"; var mockLog = new Mock <ILog>(); var source = new CodeCoverageStringTextSource(sourceString, "", mockLog.Object); var sRepo = new SourceRepository(); sRepo[fileId1] = source; var spLeft = new SequencePoint() { FileId = 1, StartLine = 1, EndLine = 1, StartColumn = 5, EndColumn = 6 }; var spRight = new SequencePoint() { FileId = 1, StartLine = 1, EndLine = 1, StartColumn = 11, EndColumn = 12 }; var spInvalid = new SequencePoint() { FileId = 2, StartLine = 1, EndLine = 1, StartColumn = 11, EndColumn = 12 }; Assert.True(sRepo.GetCodeCoverageStringTextSource(0) == null); Assert.True(sRepo.GetCodeCoverageStringTextSource(1) == source); Assert.True(sRepo.GetCodeCoverageStringTextSource(2) == null); Assert.True(sRepo.GetCodeCoverageStringTextSource(1).GetLine(1) == sourceString); Assert.True(sRepo.GetCodeCoverageStringTextSource(1).GetText(spLeft) == "{"); Assert.True(sRepo.GetCodeCoverageStringTextSource(1).GetText(spRight) == "}"); Assert.True(sRepo.GetSequencePointText(null) == ""); Assert.True(sRepo.GetSequencePointText(spInvalid) == ""); Assert.True(sRepo.GetSequencePointText(spLeft) == "{"); Assert.True(sRepo.GetSequencePointText(spRight) == "}"); }
public void CreateAddClear() { var sRepo = new SourceRepository(); Assert.True(sRepo.Count == 0); var source = new CodeCoverageStringTextSource("", ""); const uint fileId = 1; sRepo.Add(fileId, source); Assert.True(sRepo.Count == 1); sRepo.Clear(); Assert.True(sRepo.Count == 0); }
public void CountLinesWithCrLf() { // arrange const string input = "\r\n\r\n\r\n\r\n"; var source = new CodeCoverageStringTextSource(input, ""); // assert Assert.True(source.LinesCount == 4); // act var result = source.GetLine(1); // existing line index // assert Assert.True(result == "\r\n"); }
public void CreateAddRemoveKeyAndValue() { var sRepo = new SourceRepository(); var source = new CodeCoverageStringTextSource("", ""); const uint fileId = 1; sRepo.Add(fileId, source); Assert.True(sRepo.Count == 1); Assert.True(sRepo.ContainsKey(fileId)); Assert.True(sRepo.Remove(fileId)); Assert.True(sRepo.Count == 0); Assert.False(sRepo.Remove(fileId)); Assert.True(sRepo.Count == 0); }
public void CountLinesWithMixedLineEnd() { // arrange const string input = "\r\r\r\n \r\n \r\n \r \n \n\n\n\r\n\n"; // 1 2 3 4 5 6 7 8 910 1112 var source = new CodeCoverageStringTextSource(input, ""); // assert Assert.True(source.LinesCount == 12); // act var result = source.GetLine(1); // existing line index // assert Assert.True(result == "\r"); }
public void CountLinesWithLineFeed() { // arrange const string input = "\n\n\n\n\n\n\n"; var mockLog = new Mock <ILog>(); var source = new CodeCoverageStringTextSource(input, "", mockLog.Object); // assert Assert.True(source.LinesCount == 7); // act var result = source.GetLine(1); // existing line index // assert Assert.True(result == "\n"); }
public void ConstructWithTwoLinesNoCrLfAtEof() { // arrange const string input = "\tfirst line\r\tsecond line"; var mockLog = new Mock <ILog>(); var source = new CodeCoverageStringTextSource(input, "", mockLog.Object); // assert Assert.True(source.LinesCount == 2); // act var result = source.GetLine(1); // existing line index // assert Assert.True(result == "\tfirst line\r"); // act result = source.GetLine(2); // existing line index // assert Assert.True(result == "\tsecond line"); // act result = source.GetLine(0); // invalid line index // assert Assert.True(result == string.Empty); // act on first line var sp = new SequencePoint { StartLine = 1, StartColumn = 8, EndLine = 1, EndColumn = 12 }; result = source.GetText(sp); // assert Assert.True(result == "line"); // act on second line sp = new SequencePoint { StartLine = 2, StartColumn = 9, EndLine = 2, EndColumn = 13 }; result = source.GetText(sp); // assert Assert.True(result == "line"); }
public void CreateAddRemoveKeyValuePair() { var sRepo = new SourceRepository(); Assert.True(sRepo.Count == 0); var source = new CodeCoverageStringTextSource("", ""); const uint fileId = 1; sRepo.Add(new KeyValuePair <uint, CodeCoverageStringTextSource>(fileId, source)); Assert.True(sRepo.Contains(new KeyValuePair <uint, CodeCoverageStringTextSource>(fileId, source))); Assert.True(sRepo.Remove(new KeyValuePair <uint, CodeCoverageStringTextSource>(fileId, source))); Assert.False(sRepo.Remove(new KeyValuePair <uint, CodeCoverageStringTextSource>(fileId, source))); sRepo.Clear(); Assert.True(sRepo.Count == 0); }
public void CreateAddIndexerTryGetValue() { var sRepo = new SourceRepository(); Assert.True(sRepo.Count == 0); var source = new CodeCoverageStringTextSource("", ""); const uint fileId = 1; Assert.That(delegate { sRepo[fileId] = source; }, Throws.Nothing); Assert.True(sRepo.Count == 1); Assert.True(ReferenceEquals(sRepo[fileId], source)); CodeCoverageStringTextSource getSource = null; sRepo.TryGetValue(fileId, out getSource); Assert.True(ReferenceEquals(getSource, source)); }
public void ConstructWithNullString() { // arrange var source = new CodeCoverageStringTextSource(null, ""); // assert Assert.True(source.LinesCount == 0); // act var result = source.GetLine(1); // not existing line index // assert Assert.True(result == string.Empty); // act result = source.GetLine(0); // invalid line index // assert Assert.True(result == string.Empty); }
public void ConstructWithEmptyString() { // arrangevar mockLog = new Mock<ILog>(); var mockLog = new Mock <ILog>(); var source = new CodeCoverageStringTextSource(string.Empty, "", mockLog.Object); // assert Assert.True(source.LinesCount == 0); // act var result = source.GetLine(1); // not existing line index // assert Assert.True(result == string.Empty); // act result = source.GetLine(0); // invalid line index // assert Assert.True(result == string.Empty); // act var sp = new SequencePoint { StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 6 }; result = source.GetText(sp); // assert Assert.True(result == string.Empty); // act sp = new SequencePoint { StartLine = -1, StartColumn = -1, EndLine = -2, EndColumn = 6 }; result = source.GetText(sp); // assert Assert.True(result == string.Empty); }
private static void TransformSequences_RemoveCompilerGeneratedBranches(Method method, CodeCoverageStringTextSource source, ref long startOffset, ref long finalOffset) { // order SequencePoints by source order (Line/Column) var sourceLineOrderedSps = method.SequencePoints.OrderBy(sp => sp.StartLine).ThenBy(sp => sp.StartColumn).Where(sp => sp.FileId == method.FileRefUniqueId).ToArray(); // get "{" if on first two positions for (int index = 0; index < Math.Min(2, sourceLineOrderedSps.Length); index++) { if (source.GetText(sourceLineOrderedSps[0]) == "{") { startOffset = sourceLineOrderedSps[0].Offset; break; } } // get "}" if on last position if (source.GetText(sourceLineOrderedSps.Last()) == "}") { finalOffset = sourceLineOrderedSps.Last().Offset; } }
private static bool TransformSequences_RemoveCompilerGeneratedBranches(Method method, CodeCoverageStringTextSource source) { // Do we have C# source? if (source.FileType == FileType.CSharp) { if (source.FileFound) { // initialize offset with unreachable values long startOffset = long.MinValue; long finalOffset = long.MaxValue; if (!method.IsGenerated) { // fill offsets with values TransformSequences_RemoveCompilerGeneratedBranches(method, source, ref startOffset, ref finalOffset); } if (!TransformSequences_RemoveCompilerGeneratedBranches(method, source, startOffset, finalOffset)) { return(false); // return error/failure to caller } } else { // Do as much possible without source // This will remove generated branches within "{", "}" and "in" (single-line SequencePoints) // but cannot remove Code Contract ccrewite generated branches foreach (var sp in method.SequencePoints) { if (sp.BranchPoints.Count != 0 && sp.StartLine == sp.EndLine && sp.EndColumn - sp.StartColumn <= 2) { // Zero, one or two character sequence point should not contain branches // Never found 0 character sequencePoint // Never found 1 character sequencePoint except "{" and "}" // Never found 2 character sequencePoint except "in" keyword // Afaik, c# cannot express branch condition in one or two characters of source code // Keyword "do" does not generate SequencePoint sp.BranchPoints = new List <BranchPoint>(); } } } } return(true); }
public void ConstructWithSingleLine() { // arrange const string input = "single line"; var source = new CodeCoverageStringTextSource(input, ""); // assert Assert.True(source.LinesCount == 1); // act var result = source.GetLine(1); // existing line index // assert Assert.True(result == input); // act result = source.GetLine(0); // invalid line index // assert Assert.True(result == string.Empty); // act var sp = new SequencePoint { StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 7 }; result = source.GetText(sp); // assert Assert.True(result == "single"); // act with too small StartColumn sp = new SequencePoint { StartLine = 1, StartColumn = -1, EndLine = 1, EndColumn = 7 }; result = source.GetText(sp); // assert Assert.True(result == "single"); // act with too large StartColumn sp = new SequencePoint { StartLine = 1, StartColumn = 19, EndLine = 1, EndColumn = 20 }; result = source.GetText(sp); // assert Assert.True(result == ""); // act with too small EndColumn sp = new SequencePoint { StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 0 }; result = source.GetText(sp); // assert Assert.True(result == ""); // act with too large EndColumn sp = new SequencePoint { StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 20 }; result = source.GetText(sp); // assert Assert.True(result == "single line"); }
public void GetSource() { var timeReference = DateTime.UtcNow; System.Threading.Thread.Sleep(100); string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid(); string cSharpFileName = fileName + ".cs"; string vBasicFileName = fileName + ".vb"; string[] lines = { "First line", "Second line", "Third line" }; // act on not existing file var source = CodeCoverageStringTextSource.GetSource(cSharpFileName); // assert Assert.True(!ReferenceEquals(source, null)); Assert.True(source.FileType == FileType.CSharp); Assert.True(source.FilePath == cSharpFileName); Assert.False(source.FileFound); Assert.True(source.FileTime == DateTime.MinValue); Assert.False(source.IsChanged(source.FileTime)); Assert.False(source.IsChanged(DateTime.MinValue)); Assert.False(source.IsChanged(DateTime.Now)); Assert.False(source.IsChanged(timeReference)); // arrange System.IO.File.WriteAllLines(cSharpFileName, lines); // act on existing file source = CodeCoverageStringTextSource.GetSource(cSharpFileName); // assert Assert.True(!ReferenceEquals(source, null)); Assert.True(source.FileType == FileType.CSharp); Assert.True(source.FilePath == cSharpFileName); Assert.True(source.FileFound); Assert.True(source.FileTime == System.IO.File.GetLastWriteTimeUtc(cSharpFileName)); Assert.False(source.IsChanged(source.FileTime)); Assert.False(source.IsChanged(DateTime.MinValue)); Assert.False(source.IsChanged(DateTime.Now)); Assert.True(source.IsChanged(timeReference)); // destroy temp file System.IO.File.Delete(cSharpFileName); // arrange System.IO.File.WriteAllLines(vBasicFileName, lines); // act on existing file source = CodeCoverageStringTextSource.GetSource(vBasicFileName); // assert Assert.True(!ReferenceEquals(source, null)); Assert.True(source.FileType == FileType.Unsupported); Assert.True(source.FilePath == vBasicFileName); Assert.True(source.FileFound); Assert.True(source.FileTime == System.IO.File.GetLastWriteTimeUtc(vBasicFileName)); Assert.False(source.IsChanged(source.FileTime)); Assert.False(source.IsChanged(DateTime.MinValue)); Assert.False(source.IsChanged(DateTime.Now)); Assert.True(source.IsChanged(timeReference)); // destroy temp file System.IO.File.Delete(vBasicFileName); }
public void ConstructWithFiveLines() { // arrange const string input = "\tfirst line\n \n\tthird line\r\n \r fifth line\r"; var source = new CodeCoverageStringTextSource(input, ""); // assert Assert.True(source.LinesCount == 5); // act var result = source.GetLine(1); // existing line index // assert Assert.True(result == "\tfirst line\n"); // act result = source.GetLine(2); // existing line index // assert Assert.True(result == " \n"); // act result = source.GetLine(3); // existing line index // assert Assert.True(result == "\tthird line\r\n"); // act result = source.GetLine(4); // existing line index // assert Assert.True(result == " \r"); // act result = source.GetLine(5); // existing line index // assert Assert.True(result == " fifth line\r"); // act result = source.GetLine(9); // invalid line index // assert Assert.True(result == string.Empty); // act third line request var sp = new SequencePoint { StartLine = 3, StartColumn = 8, EndLine = 3, EndColumn = 12 }; result = source.GetText(sp); // assert Assert.True(result == "line"); // act invalid two lines request sp = new SequencePoint { StartLine = 1, StartColumn = 8, EndLine = 2, EndColumn = 13 }; result = source.GetText(sp); // assert Assert.True(result == "line\n \n"); // act valid two lines request sp = new SequencePoint { StartLine = 1, StartColumn = 8, EndLine = 2, EndColumn = 2 }; result = source.GetText(sp); // assert Assert.True(result == "line\n "); // act three lines request sp = new SequencePoint { StartLine = 1, StartColumn = 8, EndLine = 3, EndColumn = 12 }; result = source.GetText(sp); // assert Assert.True(result == "line\n \n\tthird line"); }
private static bool TransformSequences_RemoveCompilerGeneratedBranches(Method method, CodeCoverageStringTextSource source, long startOffset, long finalOffset) { // foreach sequence point foreach (var sp in method.SequencePoints .Where(sp => sp.FileId == method.FileRefUniqueId && sp.BranchPoints.Count != 0)) { if (sp.Offset <= startOffset || sp.Offset >= finalOffset) { // doRemoveBranches where .Offset <= startOffset"{" or finalOffset"}" <= .Offset // this will exclude "{" and "}" compiler generated branches and majority of ccrewrite Code-Contract's sp.BranchPoints = new List <BranchPoint>(); } else // branches not removed // check for other options by reading SequencePoint source { var text = source.GetText(sp); // text is never null if (text.Length == 0) { ("Empty sequence-point at line: " + sp.StartLine + " column: " + sp.StartColumn).InformUser(); ("Source file: " + source.FilePath).InformUser(); return(false); // signal error to caller's caller loop (break) } // Contract.Requires/Ensures is occasionally left inside method offset // Quick check for "C" before using Regex // Use Regex here! "Contract" and "." and "Requires/Ensures" // can be separated by spaces and newlines if (text[0] == 'C' && contractRegex.IsMatch(text)) { sp.BranchPoints = new List <BranchPoint>(); } // "in" keyword? if (text == "in") { // Remove generated ::MoveNext branches within "in" keyword // Not always removed in CecilSymbolManager (enumerated KeyValuePair) sp.BranchPoints = new List <BranchPoint>(); } } } return(true); }
public void GetSource() { var timeReference = DateTime.UtcNow; System.Threading.Thread.Sleep(100); string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid(); string cSharpFileName = fileName + ".cs"; string vBasicFileName = fileName + ".vb"; string[] lines = { "First line", "Second line", "Third line" }; var mockLog = new Mock <ILog>(); mockLog.Setup(x => x.InfoFormat(It.IsAny <string>())); // act on not existing file var source = CodeCoverageStringTextSource.GetSource(cSharpFileName, mockLog.Object); mockLog.Verify(x => x.InfoFormat($"Source file does not exist: {cSharpFileName}"), Times.Once()); // assert Assert.True(!ReferenceEquals(source, null)); Assert.True(source.FileType == FileType.CSharp); Assert.True(source.FilePath == cSharpFileName); Assert.False(source.FileFound); Assert.True(source.FileTime == DateTime.MinValue); Assert.False(source.IsChanged(source.FileTime)); Assert.False(source.IsChanged(DateTime.MinValue)); Assert.False(source.IsChanged(DateTime.UtcNow)); Assert.False(source.IsChanged(timeReference)); // arrange System.IO.File.WriteAllLines(cSharpFileName, lines); // act on existing file source = CodeCoverageStringTextSource.GetSource(cSharpFileName, mockLog.Object); // assert Assert.True(!ReferenceEquals(source, null)); Assert.True(source.FileType == FileType.CSharp); Assert.True(source.FilePath == cSharpFileName); Assert.True(source.FileFound); Assert.True(source.FileTime == System.IO.File.GetLastWriteTimeUtc(cSharpFileName)); Assert.False(source.IsChanged(source.FileTime)); Assert.False(source.IsChanged(DateTime.MinValue)); Assert.False(source.IsChanged(DateTime.UtcNow)); Assert.True(source.IsChanged(timeReference)); // destroy temp file System.IO.File.Delete(cSharpFileName); // arrange System.IO.File.WriteAllLines(vBasicFileName, lines); // act on existing file source = CodeCoverageStringTextSource.GetSource(vBasicFileName, mockLog.Object); // assert Assert.True(!ReferenceEquals(source, null)); Assert.True(source.FileType == FileType.Unsupported); Assert.True(source.FilePath == vBasicFileName); Assert.True(source.FileFound); Assert.True(source.FileTime == System.IO.File.GetLastWriteTimeUtc(vBasicFileName)); Assert.False(source.IsChanged(source.FileTime)); Assert.False(source.IsChanged(DateTime.MinValue)); Assert.False(source.IsChanged(DateTime.UtcNow)); Assert.True(source.IsChanged(timeReference)); // destroy temp file System.IO.File.Delete(vBasicFileName); }
private static void TransformSequences_RemoveFalsePositiveUnvisited(Method method, CodeCoverageStringTextSource source, ICollection <Tuple <Method, SequencePoint> > toRemoveMethodSequencePoint) { // Select false unvisited right-curly-braces at generated "MoveNext" method // (Curly braces moved to generated "MoveNext" method and left unvisited) // Source is required here to identify curly braces if (method.CallName == "MoveNext" && source.FileFound && source.FileType == FileType.CSharp) { int countDown = 2; // remove up to two last right-curly-braces foreach (var sp in method.SequencePoints.Reverse()) { if (sp.FileId == method.FileRefUniqueId && sp.IsSingleCharSequencePoint && sp.VisitCount == 0) // unvisited only { if (countDown > 0) { if (source.GetText(sp) == "}") { toRemoveMethodSequencePoint.Add(new Tuple <Method, SequencePoint>(method, sp)); countDown -= 1; } } else { break; } } } } }
public void ConstructWithTwoLines() { // arrange const string input = "\tfirst line\n\tsecond line\r"; var source = new CodeCoverageStringTextSource(input, ""); // assert Assert.True(source.LinesCount == 2); // act with existing line index var result = source.GetLine(1); // assert Assert.True(result == "\tfirst line\n"); // act with existing line index result = source.GetLine(2); // assert Assert.True(result == "\tsecond line\r"); // act with invalid line index result = source.GetLine(0); // assert Assert.True(result == string.Empty); // act var sp = new SequencePoint { StartLine = 2, StartColumn = 9, EndLine = 2, EndColumn = 13 }; result = source.GetText(sp); // assert Assert.True(result == "line"); // act with two lines request sp = new SequencePoint { StartLine = 1, StartColumn = 8, EndLine = 2, EndColumn = 13 }; result = source.GetText(sp); // assert Assert.True(result == "line\n\tsecond line"); // act with extended two lines request sp = new SequencePoint { StartLine = 1, StartColumn = -8, EndLine = 2, EndColumn = 30 }; result = source.GetText(sp); // assert Assert.True(result == "\tfirst line\n\tsecond line\r"); // act with invalid first line request sp = new SequencePoint { StartLine = 1, StartColumn = 28, EndLine = 2, EndColumn = 30 }; result = source.GetText(sp); // assert Assert.True(result == "\tsecond line\r"); // act with invalid first line and invalid second line request sp = new SequencePoint { StartLine = 1, StartColumn = 28, EndLine = 2, EndColumn = 0 }; result = source.GetText(sp); // assert Assert.True(result == ""); }