Skip to content

Commit

Permalink
Go To Definition int tests (dotnet#14855)
Browse files Browse the repository at this point in the history
  • Loading branch information
psfinaki authored and kant2002 committed Apr 1, 2023
1 parent b36c6e6 commit ffc6dd5
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.

using System;
using System.Linq;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Projection;

namespace FSharp.Editor.IntegrationTests.Extensions;

internal static class IBufferGraphExtensions
{
public static SnapshotSpan? MapUpOrDownToFirstMatch(this IBufferGraph bufferGraph, SnapshotSpan span, Predicate<ITextSnapshot> match)
{
var spans = bufferGraph.MapDownToFirstMatch(span, SpanTrackingMode.EdgeExclusive, match);
if (!spans.Any())
{
spans = bufferGraph.MapUpToFirstMatch(span, SpanTrackingMode.EdgeExclusive, match);
}

return spans.Select(s => (SnapshotSpan?)s).FirstOrDefault();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.

using System;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Utilities;

namespace FSharp.Editor.IntegrationTests.Extensions;

internal static class ITextViewExtensions
{
public static SnapshotPoint? GetCaretPoint(this ITextView textView, Predicate<ITextSnapshot> match)
{
var caret = textView.Caret.Position;
var span = textView.BufferGraph.MapUpOrDownToFirstMatch(new SnapshotSpan(caret.BufferPosition, 0), match);
if (span.HasValue)
{
return span.Value.Start;
}
else
{
return null;
}
}

public static ITextBuffer? GetBufferContainingCaret(this ITextView textView, string contentType = StandardContentTypeNames.Text)
{
var point = textView.GetCaretPoint(s => s.ContentType.IsOfType(contentType));
return point.HasValue ? point.Value.Snapshot.TextBuffer : null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.CodeAnalysis.Testing;
using Microsoft.VisualStudio.Extensibility.Testing;
using System.Threading.Tasks;
using Xunit;
using static Microsoft.VisualStudio.VSConstants;

namespace FSharp.Editor.IntegrationTests;

public class GoToDefinitionTests : AbstractIntegrationTest
{
[IdeFact]
public async Task GoesToDefinition_Async()
{
var token = HangMitigatingCancellationToken;
var template = WellKnownProjectTemplates.FSharpNetCoreClassLibrary;

var solutionExplorer = TestServices.SolutionExplorer;
var editor = TestServices.Editor;
var shell = TestServices.Shell;
var workspace = TestServices.Workspace;

var code = """
module Test
let add x y = x + y
let increment = add 1
""";
var expectedText = "let add x y = x + y";

await solutionExplorer.CreateSolutionAsync(nameof(GoToDefinitionTests), token);
await solutionExplorer.AddProjectAsync("Library", template, token);
await solutionExplorer.RestoreNuGetPackagesAsync(token);
await editor.SetTextAsync(code, token);

await editor.PlaceCaretAsync("add 1", token);
await shell.ExecuteCommandAsync(VSStd97CmdID.GotoDefn, token);
var actualText = await editor.GetCurrentLineTextAsync(token);

Assert.Contains(expectedText, actualText);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Threading;
using System.Threading.Tasks;
using FSharp.Editor.IntegrationTests.Extensions;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Text;

namespace Microsoft.VisualStudio.Extensibility.Testing;
Expand All @@ -19,6 +22,16 @@ public async Task<string> GetTextAsync(CancellationToken cancellationToken)
return textSnapshot.GetText();
}

public async Task<string> GetCurrentLineTextAsync(CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

var view = await TestServices.Editor.GetActiveTextViewAsync(cancellationToken);
var bufferPosition = view.Caret.Position.BufferPosition;
var line = bufferPosition.GetContainingLine();
return line.GetText();
}

public async Task SetTextAsync(string text, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
Expand All @@ -28,4 +41,31 @@ public async Task SetTextAsync(string text, CancellationToken cancellationToken)
var replacementSpan = new SnapshotSpan(textSnapshot, 0, textSnapshot.Length);
view.TextBuffer.Replace(replacementSpan, text);
}

public async Task PlaceCaretAsync(string marker, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

var view = await GetActiveTextViewAsync(cancellationToken);

var dte = await GetRequiredGlobalServiceAsync<SDTE, EnvDTE.DTE>(cancellationToken);
dte.Find.FindWhat = marker;
dte.Find.MatchCase = true;
dte.Find.MatchInHiddenText = true;
dte.Find.Target = EnvDTE.vsFindTarget.vsFindTargetCurrentDocument;
dte.Find.Action = EnvDTE.vsFindAction.vsFindActionFind;

view.Caret.MoveTo(new SnapshotPoint(view.GetBufferContainingCaret()!.CurrentSnapshot, 0));

var result = dte.Find.Execute();
if (result != EnvDTE.vsFindResult.vsFindResultFound)
{
throw new Exception("Marker '" + marker + "' not found in text: " + view.TextSnapshot.GetText());
}

// On the first negative charsOffset, move to anchor-point position, as if the user hit the LEFT key
view.Caret.MoveTo(new SnapshotPoint(view.TextSnapshot, view.Selection.AnchorPoint.Position.Position));

view.Selection.Clear();
}
}

0 comments on commit ffc6dd5

Please sign in to comment.