public void GetTags_DifferentSnapshots_SnapshotsAreTranslated()
        {
            const int length = 100;
            var       buffer = CreateBufferMock(length, ValidBufferDocName).Object;

            var versionMock2 = CreateTextVersion(buffer, 2);
            var versionMock1 = CreateTextVersion(buffer, 1, nextVersion: versionMock2);

            var snapshotMock1 = CreateSnapshot(buffer, length, versionMock1);
            var snapshotMock2 = CreateSnapshot(buffer, length, versionMock2);

            var locSpan1  = new Span(1, 10);
            var locSpan2  = new Span(11, 5);
            var storeMock = CreateStoreWithLocationsWithSpans(snapshotMock1, out _, locSpan1, locSpan2);

            var inputSpans = new NormalizedSnapshotSpanCollection(snapshotMock2, new Span(18, 22));

            var testSubject = new LocationTagger(buffer, storeMock, ValidSpanCalculator, ValidLogger);

            // Sanity checks
            testSubject.TagSpans.Count().Should().Be(2);
            testSubject.TagSpans[0].Span.Snapshot.Should().Be(snapshotMock1);
            testSubject.TagSpans[1].Span.Snapshot.Should().Be(snapshotMock1);
            testSubject.TagSpans[0].Tag.Location.Span.Value.Snapshot.Should().Be(snapshotMock1);
            testSubject.TagSpans[1].Tag.Location.Span.Value.Snapshot.Should().Be(snapshotMock1);

            testSubject.GetTags(inputSpans).ToArray(); // GetTags is lazy so we need to reify the result to force evaluation

            testSubject.TagSpans.Count().Should().Be(2);
            testSubject.TagSpans[0].Span.Snapshot.Should().Be(snapshotMock2);
            testSubject.TagSpans[1].Span.Snapshot.Should().Be(snapshotMock2);

            testSubject.TagSpans[0].Tag.Location.Span.Value.Snapshot.Should().Be(snapshotMock2);
            testSubject.TagSpans[1].Tag.Location.Span.Value.Snapshot.Should().Be(snapshotMock2);
        }
        public void GetTags_EmptyInputSpan_ReturnsEmpty()
        {
            var testSubject = new LocationTagger(ValidBuffer, ValidStore, ValidSpanCalculator, ValidLogger);

            var inputSpans = new NormalizedSnapshotSpanCollection();

            testSubject.GetTags(inputSpans)
            .Should().BeEmpty();
        }
        public void GetTags_NoTags_ReturnsEmpty()
        {
            var testSubject = new LocationTagger(ValidBuffer, ValidStore, ValidSpanCalculator, ValidLogger);

            var validSpan  = new Span(0, ValidBuffer.CurrentSnapshot.Length);
            var inputSpans = new NormalizedSnapshotSpanCollection(ValidBuffer.CurrentSnapshot, validSpan);

            testSubject.GetTags(inputSpans)
            .Should().BeEmpty();
        }
        public void GetTags_NoIntersectingSpans_ReturnsEmpty()
        {
            // Make sure the tagger and NormalizedSpanCollection use the same snapshot
            // so we don't attempt to translate the spans
            var buffer    = CreateBufferMock();
            var locSpan1  = new Span(1, 10);
            var locSpan2  = new Span(11, 10);
            var storeMock = CreateStoreWithLocationsWithSpans(buffer.Object.CurrentSnapshot, out _, locSpan1, locSpan2);

            var inputSpans = new NormalizedSnapshotSpanCollection(buffer.Object.CurrentSnapshot, new Span(32, 5));

            var testSubject = new LocationTagger(buffer.Object, storeMock, ValidSpanCalculator, ValidLogger);

            testSubject.TagSpans.Count.Should().Be(2); // sanity check

            var matchingTags = testSubject.GetTags(inputSpans);

            matchingTags.Should().BeEmpty();
        }
        public void GetTags_ExceptionInTranslatingSpan_ExceptionSuppressedAndLogged()
        {
            const int length    = 100;
            var       buffer    = CreateBufferMock(length, ValidBufferDocName).Object;
            var       snapshot  = CreateSnapshot(buffer, length);
            var       storeMock = CreateStoreWithLocationsWithSpans(snapshot, out _, new Span(1, 10));

            var logger      = new TestLogger();
            var testSubject = new LocationTagger(buffer, storeMock, ValidSpanCalculator, logger);

            testSubject.TagSpans.Count.Should().Be(1);

            var snapshotForAnotherBuffer = CreateSnapshot(CreateBuffer(), length);
            var inputSpans = new NormalizedSnapshotSpanCollection(snapshotForAnotherBuffer, new Span(18, 22));

            Action act = () => testSubject.GetTags(inputSpans).ToArray();

            act.Should().NotThrow();

            testSubject.TagSpans.Count.Should().Be(0);
            logger.AssertPartialOutputStringExists(ValidBufferDocName, "The specified ITextSnapshot doesn't belong to the correct TextBuffer.");
        }
        [DataRow(11, false)] // after -> no match
        public void GetTags_RequestedSpansAreZeroLength_ReturnsExpectedTags(int inputSpanStart, bool shouldMatch)
        {
            // Regression test for #1720: Tooltips do not appear for primary locations
            // https://github.com/SonarSource/sonarlint-visualstudio/issues/1720

            var tagSpan   = Span.FromBounds(5, 10);
            var inputSpan = Span.FromBounds(inputSpanStart, inputSpanStart);

            // Make sure the tagger and NormalizedSpanCollection use the same snapshot
            // so we don't attempt to translate the spans
            var buffer    = CreateBufferMock();
            var storeMock = CreateStoreWithLocationsWithSpans(buffer.Object.CurrentSnapshot, out _, tagSpan);

            var inputSpans  = new NormalizedSnapshotSpanCollection(buffer.Object.CurrentSnapshot, inputSpan);
            var testSubject = new LocationTagger(buffer.Object, storeMock, ValidSpanCalculator, ValidLogger);

            var matchingTags = testSubject.GetTags(inputSpans);

            var expectedCount = shouldMatch ? 1 : 0;

            matchingTags.Count().Should().Be(expectedCount);
        }