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);
        }
Exemple #2
0
 //---------------------------------------------------------------------
 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));
 }
Exemple #3
0
        //---------------------------------------------------------------------
        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);
        }