public void LineCoverageImplementsCorrectEqualsMethod() { var lineCoverage1 = new LineCoverage(1, 1, true, "1/1"); var lineCoverage1Again = lineCoverage1; var lineCoverage2 = new LineCoverage(1, 1, true, "1/1"); var lineCoverage3 = new LineCoverage(1, 2, true, "1/1"); var lineCoverage4 = new LineCoverage(2, 1, false, string.Empty); lineCoverage1.Should() .BeEquivalentTo(lineCoverage2); lineCoverage1.Equals(null) .Should() .BeFalse(); lineCoverage1.Equals(lineCoverage1Again) .Should() .BeTrue(); lineCoverage1.Should() .NotBe("bla"); lineCoverage1.GetHashCode() .Should() .Be(lineCoverage2.GetHashCode()); lineCoverage3.Should() .NotBeEquivalentTo(lineCoverage1); lineCoverage4.Should() .NotBeEquivalentTo(lineCoverage2); }
//--------------------------------------------------------------------- LineCoverage MergeLineCoverage( LineCoverage lineCoverage, LineCoverage lineCoverage2) { if (lineCoverage.LineNumber != lineCoverage2.LineNumber) { throw new InvalidOperationException("Line numbers are not the same."); } return(new LineCoverage( lineCoverage.LineNumber, lineCoverage.HasBeenExecuted || lineCoverage2.HasBeenExecuted)); }
//--------------------------------------------------------------------- static void WriteModule(CodedOutputStream outputStream) { var line = LineCoverage.CreateBuilder(); line.SetHasBeenExecuted(hasBeenExecuted); line.SetLineNumber(lineNumber); var file = FileCoverage.CreateBuilder(); file.SetPath(filePath); file.AddLines(line); var module = ModuleCoverage.CreateBuilder(); module.SetPath(modulePath); module.AddFiles(file); WriteMessage(outputStream, module.Build()); }
private static FileCoverage GetFileCoverage(CoverageSession report, Dictionary <int, TestMethod[]> trackedMethods, string filePath) { if (report != null) { foreach (var module in report.Modules) { var file = module.Files .FirstOrDefault(p => StringComparer.OrdinalIgnoreCase.Equals(p.FullPath, filePath)); if (file == null) { continue; } var methods = module.Classes .SelectMany(p => p.Methods) .Where(p => p.FileRef != null && p.FileRef.Id == file.Id) .ToArray(); var sequenceGroups = methods .SelectMany(p => p.SequencePoints) .SelectMany(p => Enumerable .Range(p.StartLine, p.EndLine - p.StartLine + 1) .Select(q => new { LineNumber = q - 1, VisitCount = p.VisitCount, Start = q == p.StartLine ? p.StartColumn - 1 : 0, End = q == p.EndLine ? p.EndColumn - 1 : int.MaxValue, Visitors = p.TrackedMethodRefs })) .GroupBy(p => p.LineNumber) .ToDictionary(p => p.Key); var branchGroups = methods .SelectMany(p => p.BranchPoints) .GroupBy(p => p.StartLine) .ToDictionary(p => p.Key - 1); var affectedLines = sequenceGroups .Select(p => p.Key) .Concat(branchGroups.Select(p => p.Key)) .Distinct(); var lineCoverages = new Dictionary <int, LineCoverage>(); foreach (var affectedLine in affectedLines) { var sequenceGroup = sequenceGroups.TryGetValue(affectedLine); var branchGroup = branchGroups.TryGetValue(affectedLine); var visitCount = sequenceGroup.Max(p => p.VisitCount); var sequenceState = sequenceGroup.All(p => p.VisitCount > 0) ? CoverageState.Covered : (sequenceGroup.All(p => p.VisitCount == 0) ? CoverageState.Uncovered : CoverageState.Mixed); var unvisitedSections = sequenceGroup .Where(p => p.VisitCount == 0) .Select(p => new LineSection(p.Start, p.End)) .ToArray(); var branchesVisited = branchGroup? .GroupBy(p => p.Offset) .Select(p => p .OrderBy(q => q.Path) .Select(q => q.VisitCount > 0) .ToArray()) .ToArray() ?? new bool[0][]; var branchPoints = branchesVisited.SelectMany(p => p).ToArray(); var branchState = branchPoints.All(p => p) ? CoverageState.Covered : (branchPoints.All(p => !p) ? CoverageState.Uncovered : CoverageState.Mixed); var lineVisitors = new HashSet <TestMethod>(sequenceGroup .SelectMany(p => p.Visitors) .Select(p => p.Id) .Distinct() .Where(p => trackedMethods.ContainsKey(p)) .SelectMany(p => trackedMethods[p])); var branchVisitors = branchGroup? .GroupBy(p => p.Offset) .Select(p => p .OrderBy(q => q.Path) .Select(q => new HashSet <TestMethod>(q.TrackedMethodRefs .Where(r => trackedMethods.ContainsKey(r.Id)) .SelectMany(r => trackedMethods[r.Id]))) .ToArray()) .ToArray() ?? new HashSet <TestMethod> [0][]; var lineCoverage = new LineCoverage(visitCount, sequenceState, branchState, branchesVisited, unvisitedSections, lineVisitors, branchVisitors); lineCoverages.Add(affectedLine, lineCoverage); } return(new FileCoverage(lineCoverages)); } } return(FileCoverage.Empty); }
private void AddBranchAdornment(ITextViewLine line, SnapshotSpan span, LineCoverage coverage) { var diameter = _textView.LineHeight / _branchCoverageSpotHeightDivider; var spacing = _branchCoverageSpotGap + diameter; var top = (line.Height - diameter) / 2d; var brush = _brushesAndPens[coverage.BranchCoverageState].Brush; var pen = _brushesAndPens[coverage.BranchCoverageState].Pen; var groupIndex = 0; var index = 0; var left = _sequenceCoverageLineWidth * 1.5d; foreach (var branchPoint in coverage.BranchesVisited) { foreach (var branch in branchPoint) { var rect = new Rect(left, line.Top + top, diameter, diameter); var geometry = new EllipseGeometry(rect); geometry.Freeze(); var brushOverride = brush; var penOverride = pen; if (branch && coverage.BranchVisitors[groupIndex][index].Any(p => SelectedTests.Contains(p))) { brushOverride = _selectedBrushAndPen.Brush; penOverride = _selectedBrushAndPen.Pen; } var drawing = new GeometryDrawing(branch ? brushOverride : null, penOverride, geometry); drawing.Freeze(); var drawingImage = new DrawingImage(drawing); drawingImage.Freeze(); var image = new Image() { Source = drawingImage }; var testMethod = coverage.BranchVisitors[groupIndex][index].FirstOrDefault(); if (testMethod != null) { image.MouseLeftButtonDown += (o, e) => e.Handled = true; image.MouseLeftButtonUp += (o, e) => _selectTestCommand.Execute(testMethod); image.Cursor = Cursors.Hand; image.Tag = coverage.BranchVisitors[groupIndex][index].ToArray(); image.MouseRightButtonDown += (o, e) => e.Handled = true; image.MouseRightButtonUp += OnTestCoverageRightButtonUp; SharedDictionaryManager.InitializeDictionaries(image.Resources.MergedDictionaries); } Canvas.SetLeft(image, geometry.Bounds.Left); Canvas.SetTop(image, geometry.Bounds.Top); _adornmentLayer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, image, null); left += spacing; index++; } groupIndex++; index = 0; left += spacing; } }
private void AddUncoveredAdornment(ITextSnapshotLine line, SnapshotSpan span, LineCoverage coverage) { if (coverage.SequenceCoverageState == CoverageState.Mixed) { foreach (var uncoveredSection in coverage.UncoveredSections) { var highlightStart = line.Start; if (uncoveredSection.Start == 0) { highlightStart += line.GetText().TakeWhile(p => char.IsWhiteSpace(p)).Count(); } else { highlightStart += Math.Min(uncoveredSection.Start, line.Length); } var highlightEnd = line.Start + Math.Min(uncoveredSection.End, line.Length); if (highlightEnd <= highlightStart) { continue; } var highlightSpan = new SnapshotSpan( _textView.TextSnapshot, Span.FromBounds( highlightStart, highlightEnd )); var geometry = _textView.TextViewLines.GetMarkerGeometry(highlightSpan); if (geometry == null) { continue; } geometry.Freeze(); var drawing = new GeometryDrawing(null, _brushesAndPens[CoverageState.Mixed].Pen, geometry); drawing.Freeze(); var drawingImage = new DrawingImage(drawing); drawingImage.Freeze(); var image = new Image() { Source = drawingImage }; Canvas.SetLeft(image, geometry.Bounds.Left); Canvas.SetTop(image, geometry.Bounds.Top); _adornmentLayer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, image, null); } } }
private void AddSequenceAdornment(ITextViewLine line, SnapshotSpan span, LineCoverage coverage) { var rect = new Rect(0d, line.Top, _sequenceCoverageLineWidth, line.Height); var geometry = new RectangleGeometry(rect); geometry.Freeze(); var brush = _brushesAndPens[coverage.SequenceCoverageState].Brush; if (coverage.SequenceCoverageState == CoverageState.Covered && coverage.LineVisitors.Any(p => SelectedTests.Contains(p))) { brush = _selectedBrushAndPen.Brush; } var drawing = new GeometryDrawing(brush, null, geometry); drawing.Freeze(); var drawingImage = new DrawingImage(drawing); drawingImage.Freeze(); var toolTip = new StackPanel(); var header = new TextBlock() { Text = string.Format(Resources.VisitorCount, coverage.VisitCount), TextWrapping = TextWrapping.Wrap }; toolTip.Children.Add(header); var image = new Image() { Source = drawingImage, ToolTip = toolTip }; Canvas.SetLeft(image, geometry.Bounds.Left); Canvas.SetTop(image, geometry.Bounds.Top); SharedDictionaryManager.InitializeDictionaries(image.Resources.MergedDictionaries); if (coverage.LineVisitors.Count > 0) { var description = new TextBlock() { Text = string.Join("\r\n", coverage.LineVisitors.Select(p => p.ShortName)), TextWrapping = TextWrapping.Wrap, Opacity = 0.7d }; toolTip.Children.Add(description); image.Tag = coverage.LineVisitors.ToArray(); image.MouseRightButtonDown += (o, e) => e.Handled = true; image.MouseRightButtonUp += OnTestCoverageRightButtonUp; image.MouseLeftButtonDown += (o, e) => e.Handled = true; image.MouseLeftButtonUp += (o, e) => _selectTestCommand.Execute(coverage.LineVisitors.First()); image.Cursor = Cursors.Hand; } _adornmentLayer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, image, null); }