Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
<_MicrosoftExtensionsPackageVersion>9.0.0</_MicrosoftExtensionsPackageVersion>
<_BasicReferenceAssembliesVersion>1.7.2</_BasicReferenceAssembliesVersion>
<_BenchmarkDotNetPackageVersion>0.13.5.2136</_BenchmarkDotNetPackageVersion>
<_MicrosoftVisualStudioExtensibilityTestingVersion>0.1.800-beta</_MicrosoftVisualStudioExtensibilityTestingVersion>
<_MicrosoftVisualStudioLanguageServicesPackageVersion>$(MicrosoftVisualStudioLanguageServicesPackageVersion)</_MicrosoftVisualStudioLanguageServicesPackageVersion>
<_XunitPackageVersion>2.9.2</_XunitPackageVersion>
<_MicrosoftBuildPackageVersion>17.15.0-preview-25357-08</_MicrosoftBuildPackageVersion>
Expand Down Expand Up @@ -65,8 +64,8 @@
<PackageVersion Include="Microsoft.NET.Sdk.Razor" Version="$(MicrosoftNETSdkRazorPackageVersion)" />
<PackageVersion Include="Microsoft.VisualStudio.Copilot" Version="0.2.28-beta" />
<PackageVersion Include="Microsoft.VisualStudio.Editor" Version="$(_MicrosoftVisualStudioPackagesVersion)" />
<PackageVersion Include="Microsoft.VisualStudio.Extensibility.Testing.Xunit" Version="$(_MicrosoftVisualStudioExtensibilityTestingVersion)" />
<PackageVersion Include="Microsoft.VisualStudio.Extensibility.Testing.SourceGenerator" Version="$(_MicrosoftVisualStudioExtensibilityTestingVersion)" />
<PackageVersion Include="Microsoft.VisualStudio.Extensibility.Testing.Xunit" Version="$(MicrosoftVisualStudioExtensibilityTestingXunitPackageVersion)" />
<PackageVersion Include="Microsoft.VisualStudio.Extensibility.Testing.SourceGenerator" Version="$(MicrosoftVisualStudioExtensibilityTestingSourceGeneratorPackageVersion)" />
<PackageVersion Include="Microsoft.VisualStudio.Interop" Version="$(_MicrosoftVisualStudioShellPackagesVersion)" />
<PackageVersion Include="Microsoft.VisualStudio.Language" Version="$(_MicrosoftVisualStudioPackagesVersion)" />
<PackageVersion Include="Microsoft.VisualStudio.Language.Intellisense" Version="$(_MicrosoftVisualStudioPackagesVersion)" />
Expand Down
4 changes: 4 additions & 0 deletions eng/Version.Details.props
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ This file should be imported by eng/Versions.props
<MicrosoftCodeAnalysisWorkspacesMSBuildPackageVersion>5.3.0-2.25630.5</MicrosoftCodeAnalysisWorkspacesMSBuildPackageVersion>
<MicrosoftCommonLanguageServerProtocolFrameworkPackageVersion>5.3.0-2.25630.5</MicrosoftCommonLanguageServerProtocolFrameworkPackageVersion>
<MicrosoftNetCompilersToolsetPackageVersion>5.3.0-2.25630.5</MicrosoftNetCompilersToolsetPackageVersion>
<MicrosoftVisualStudioExtensibilityTestingXunitPackageVersion>5.3.0-2.25630.5</MicrosoftVisualStudioExtensibilityTestingXunitPackageVersion>
<MicrosoftVisualStudioExtensibilityTestingSourceGeneratorPackageVersion>5.3.0-2.25630.5</MicrosoftVisualStudioExtensibilityTestingSourceGeneratorPackageVersion>
<MicrosoftVisualStudioLanguageServicesPackageVersion>5.3.0-2.25630.5</MicrosoftVisualStudioLanguageServicesPackageVersion>
<RoslynDiagnosticsAnalyzersPackageVersion>5.3.0-2.25630.5</RoslynDiagnosticsAnalyzersPackageVersion>
<!-- dotnet/arcade dependencies -->
Expand Down Expand Up @@ -59,6 +61,8 @@ This file should be imported by eng/Versions.props
<MicrosoftCodeAnalysisWorkspacesMSBuildVersion>$(MicrosoftCodeAnalysisWorkspacesMSBuildPackageVersion)</MicrosoftCodeAnalysisWorkspacesMSBuildVersion>
<MicrosoftCommonLanguageServerProtocolFrameworkVersion>$(MicrosoftCommonLanguageServerProtocolFrameworkPackageVersion)</MicrosoftCommonLanguageServerProtocolFrameworkVersion>
<MicrosoftNetCompilersToolsetVersion>$(MicrosoftNetCompilersToolsetPackageVersion)</MicrosoftNetCompilersToolsetVersion>
<MicrosoftVisualStudioExtensibilityTestingXunitVersion>$(MicrosoftVisualStudioExtensibilityTestingXunitPackageVersion)</MicrosoftVisualStudioExtensibilityTestingXunitVersion>
<MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion>$(MicrosoftVisualStudioExtensibilityTestingSourceGeneratorPackageVersion)</MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion>
<MicrosoftVisualStudioLanguageServicesVersion>$(MicrosoftVisualStudioLanguageServicesPackageVersion)</MicrosoftVisualStudioLanguageServicesVersion>
<RoslynDiagnosticsAnalyzersVersion>$(RoslynDiagnosticsAnalyzersPackageVersion)</RoslynDiagnosticsAnalyzersVersion>
<!-- dotnet/arcade dependencies -->
Expand Down
8 changes: 8 additions & 0 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@
<Uri>https://github.com/dotnet/roslyn</Uri>
<Sha>635d2b812121ef9fafe0de223b09be64e5a4a291</Sha>
</Dependency>
<Dependency Name="Microsoft.VisualStudio.Extensibility.Testing.Xunit" Version="5.3.0-2.25630.5">
<Uri>https://github.com/dotnet/roslyn</Uri>
<Sha>635d2b812121ef9fafe0de223b09be64e5a4a291</Sha>
</Dependency>
<Dependency Name="Microsoft.VisualStudio.Extensibility.Testing.SourceGenerator" Version="5.3.0-2.25630.5">
<Uri>https://github.com/dotnet/roslyn</Uri>
<Sha>635d2b812121ef9fafe0de223b09be64e5a4a291</Sha>
</Dependency>
<Dependency Name="Microsoft.VisualStudio.LanguageServices" Version="5.3.0-2.25630.5">
<Uri>https://github.com/dotnet/roslyn</Uri>
<Sha>635d2b812121ef9fafe0de223b09be64e5a4a291</Sha>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,14 @@ namespace Microsoft.VisualStudio.Extensibility.Testing;

internal partial class EditorInProcess
{
public async Task MoveCaretAsync(int position, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

var view = await GetActiveTextViewAsync(cancellationToken);

var subjectBuffer = view.GetBufferContainingCaret();
Assumes.Present(subjectBuffer);

var point = new SnapshotPoint(subjectBuffer.CurrentSnapshot, position);

view.Caret.MoveTo(point);
}

public async Task PlaceCaretAsync(int position, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

var view = await GetActiveTextViewAsync(cancellationToken);
view.Caret.MoveTo(new SnapshotPoint(view.GetBufferContainingCaret()!.CurrentSnapshot, position));

await ActivateAsync(cancellationToken);
}

public Task PlaceCaretAsync(string marker, int charsOffset, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Threading;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Razor.IntegrationTests.InProcess;
using Microsoft.VisualStudio.Shell;
Expand Down Expand Up @@ -56,13 +57,7 @@ public async Task InvokeRenameAsync(CancellationToken cancellationToken)
{
var commandGuid = typeof(VSStd2KCmdID).GUID;
var commandId = VSStd2KCmdID.RENAME;

// Rename seems to be extra-succeptable to COM exceptions
await Helper.RetryAsync<bool?>(async (cancellationToken) =>
{
await ExecuteCommandAsync(commandGuid, (uint)commandId, cancellationToken);
return true;
}, TimeSpan.FromSeconds(1), cancellationToken);
await ExecuteCommandAsync(commandGuid, (uint)commandId, cancellationToken);
}

public async Task CloseCodeFileAsync(string projectName, string relativeFilePath, bool saveFile, CancellationToken cancellationToken)
Expand All @@ -88,7 +83,34 @@ private async Task ExecuteCommandAsync(Guid commandGuid, uint commandId, Cancell
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

var dispatcher = await GetRequiredGlobalServiceAsync<SUIHostCommandDispatcher, IOleCommandTarget>(cancellationToken);
var dispatcher = await TestServices.Shell.GetRequiredGlobalServiceAsync<SUIHostCommandDispatcher, IOleCommandTarget>(cancellationToken);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: It would be nice to add some comments explaining what this is doing. My understanding is that we're basically checking (with a retry) that the command is actually enabled before trying to execute it?


// Before we execute the command, lets wait until it's enabled and available. Unfortunately this is an annoying COM pattern.

// Set up the data for the API to fill in. We set command id, it sets the status in "cmdf"
var cmds = new OLECMD[1];
cmds[0].cmdID = commandId;
cmds[0].cmdf = 0;

await Helper.RetryAsync(ct =>
{
// The return value here is just whether the QueryStatus call worked, not whether the command is enabled.
ErrorHandler.ThrowOnFailure(dispatcher.QueryStatus(ref commandGuid, 1, cmds, IntPtr.Zero));

// Now check the status flags that were filled in for the command we asked about.
var status = (OLECMDF)cmds[0].cmdf;
if (status.HasFlag(OLECMDF.OLECMDF_ENABLED) &&
status.HasFlag(OLECMDF.OLECMDF_SUPPORTED))
{
// Returning non-default from RetryAsync stops the retry loop.
return SpecializedTasks.True;
}

// Returning default means it will try again.
return SpecializedTasks.False;
}, TimeSpan.FromMilliseconds(100), cancellationToken);

// Now we can be reasonably sure the command is available, so execute it.
ErrorHandler.ThrowOnFailure(dispatcher.Exec(commandGuid, commandId, (uint)OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, IntPtr.Zero, IntPtr.Zero));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.OperationProgress;
using Microsoft.VisualStudio.Razor;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TextManager.Interop;
using Microsoft.VisualStudio.Threading;
using Xunit;

namespace Microsoft.VisualStudio.Extensibility.Testing;
Expand Down Expand Up @@ -110,4 +112,11 @@ internal async Task CloseActiveDocumentWindowsAsync(CancellationToken cancellati
window.CloseFrame((uint)__FRAMECLOSE.FRAMECLOSE_NoSave);
}
}

public async Task WaitForOperationProgressAsync(CancellationToken cancellationToken)
{
var operationProgressStatus = await GetRequiredGlobalServiceAsync<SVsOperationProgress, IVsOperationProgressStatusService>(cancellationToken);
var stageStatus = operationProgressStatus.GetStageStatus(CommonOperationProgressStageIds.Intellisense);
await stageStatus.WaitForCompletionAsync().WithCancellation(cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public async Task RazorCodeActions_AddUsing()
// Open the file
await TestServices.SolutionExplorer.OpenFileAsync(RazorProjectConstants.BlazorProjectName, RazorProjectConstants.CounterRazorFile, ControlledHangMitigatingCancellationToken);

await TestServices.Editor.SetTextAsync("<SurveyPrompt></SurveyPrompt>", ControlledHangMitigatingCancellationToken);
await TestServices.Editor.MoveCaretAsync(3, ControlledHangMitigatingCancellationToken);
var position = await TestServices.Editor.SetTextAsync("<Su$$rveyPrompt></SurveyPrompt>", ControlledHangMitigatingCancellationToken);
await TestServices.Editor.PlaceCaretAsync(position, ControlledHangMitigatingCancellationToken);

// Act
var codeActions = await TestServices.Editor.InvokeCodeActionListAsync(ControlledHangMitigatingCancellationToken);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Razor.IntegrationTests.Extensions;
using Microsoft.VisualStudio.Razor.IntegrationTests.InProcess;
using Microsoft.VisualStudio.Text.Editor.Commanding.Commands;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -212,21 +217,23 @@ await TestServices.SolutionExplorer.AddFileAsync(RazorProjectConstants.BlazorPro

await TestServices.Editor.PlaceCaretAsync(position, ControlledHangMitigatingCancellationToken);

await Task.Delay(500);
// For some reason, this particular rename exercise is particularly flaky so we have a few hail marys to recite
await TestServices.Shell.WaitForOperationProgressAsync(ControlledHangMitigatingCancellationToken);
await WaitForRoslynRenameReadyAsync(ControlledHangMitigatingCancellationToken);

// Act
await TestServices.Editor.InvokeRenameAsync(ControlledHangMitigatingCancellationToken);

// Even though we waited for the command to be ready and available, it can still be a bit slow to come up
await Task.Delay(500);

TestServices.Input.Send("ZooperDooper{ENTER}");

await TestServices.Editor.WaitForCurrentLineTextAsync("public class ZooperDooper : ComponentBase", ControlledHangMitigatingCancellationToken);

// The rename operation updates the editor as the new name is being typed, so waiting for the line in the editor can trigger before the rename
// actually occurs, and then moving tabs cancels it. So we have to wait a beat.
await Task.Delay(500);

// Assert
await TestServices.SolutionExplorer.OpenFileAsync(RazorProjectConstants.BlazorProjectName, "MyPage.razor", ControlledHangMitigatingCancellationToken);
await TestServices.Editor.VerifyTextContainsAsync("<ZooperDooper></ZooperDooper>", ControlledHangMitigatingCancellationToken);
await TestServices.Editor.WaitForTextContainsAsync("<ZooperDooper></ZooperDooper>", ControlledHangMitigatingCancellationToken);
}

[IdeFact]
Expand Down Expand Up @@ -351,4 +358,23 @@ public class MyComponent : ComponentBase
await TestServices.SolutionExplorer.OpenFileAsync(RazorProjectConstants.BlazorProjectName, "MyComponent.cs", ControlledHangMitigatingCancellationToken);
await TestServices.Editor.VerifyTextContainsAsync("public class ZooperDooper : ComponentBase", ControlledHangMitigatingCancellationToken);
}

private async Task WaitForRoslynRenameReadyAsync(CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

var view = await TestServices.Editor.GetActiveTextViewAsync(cancellationToken);
var buffer = view.GetBufferContainingCaret();

var commandArgs = new RenameCommandArgs(view, buffer);

// We don't have EA from this project, so we have to resort to reflection. Fortunately it's pretty simple
var roslynHandler = Type.GetType("Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.AbstractRenameCommandHandler, Microsoft.CodeAnalysis.EditorFeatures");
var canRename = roslynHandler.GetMethod("CanRename", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);

await Helper.RetryAsync(ct =>
{
return Task.FromResult((bool)canRename.Invoke(null, [commandArgs]));
}, TimeSpan.FromMilliseconds(100), cancellationToken);
}
}
Loading