From 1b795b8e6ee98eea1088bbc9cd143020354534e8 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Fri, 1 Apr 2022 16:53:51 -0700 Subject: [PATCH] Update to Microsoft.VisualStudio.Extensibility.Testing 0.1.135-beta --- eng/Versions.props | 4 +- .../AbstractIdeIntegrationTest.cs | 116 -------- ...andNames.cs => AbstractIntegrationTest.cs} | 10 +- .../CreateProjectTests.cs | 106 ++++--- .../InProcess/EditorInProcess.cs | 51 +--- .../InProcess/ErrorListInProcess.cs | 44 +-- .../InProcess/InProcComponent.cs | 76 ----- .../InProcess/SolutionExplorerInProcess.cs | 267 ++++-------------- .../SynchronizationContextTaskScheduler.cs | 49 ---- .../InProcess/TestServices.cs | 41 --- .../Roslyn.SDK.IntegrationTests.csproj | 1 + 11 files changed, 144 insertions(+), 621 deletions(-) delete mode 100644 tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/AbstractIdeIntegrationTest.cs rename tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/{WellKnownCommandNames.cs => AbstractIntegrationTest.cs} (56%) delete mode 100644 tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/InProcComponent.cs delete mode 100644 tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/SynchronizationContextTaskScheduler.cs delete mode 100644 tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/TestServices.cs diff --git a/eng/Versions.props b/eng/Versions.props index f238a111..61e990f0 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -21,6 +21,7 @@ 4.0.0-1.21267.34 17.0.0-previews-4-31709-430 17.0.391-preview-g5e248c9073 + 0.1.135-beta 3.3.2 $(MicrosoftCodeAnalysisPackagesVersion) @@ -74,7 +75,8 @@ 1.0.1-beta1.20374.2 $(xunitVersion) 1.2.7 - 0.1.100-beta + $(MicrosoftVisualStudioExtensibilityTestingVersion) + $(MicrosoftVisualStudioExtensibilityTestingVersion) 2.9.8 1.2.0-beta.164 diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/AbstractIdeIntegrationTest.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/AbstractIdeIntegrationTest.cs deleted file mode 100644 index 60194c34..00000000 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/AbstractIdeIntegrationTest.cs +++ /dev/null @@ -1,116 +0,0 @@ -// 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 System; -using System.Diagnostics.CodeAnalysis; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Threading; -using Microsoft.CodeAnalysis.Testing.InProcess; -using Microsoft.VisualStudio.Shell; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Task = System.Threading.Tasks.Task; - -namespace Microsoft.CodeAnalysis.Testing -{ - [IdeSettings(MinVersion = VisualStudioVersion.VS2022)] - public abstract class AbstractIdeIntegrationTest : IAsyncLifetime, IDisposable - { - /// - /// A long timeout used to avoid hangs in tests, where a test failure manifests as an operation never occurring. - /// - public static readonly TimeSpan HangMitigatingTimeout = TimeSpan.FromMinutes(4); - - private JoinableTaskContext? _joinableTaskContext; - private JoinableTaskCollection? _joinableTaskCollection; - private JoinableTaskFactory? _joinableTaskFactory; - - private TestServices? _testServices; - - private CancellationTokenSource _hangMitigatingCancellationTokenSource; - - protected AbstractIdeIntegrationTest() - { - Assert.True(Application.Current.Dispatcher.CheckAccess()); - - JoinableTaskContext = ThreadHelper.JoinableTaskContext; - - _hangMitigatingCancellationTokenSource = new CancellationTokenSource(HangMitigatingTimeout); - } - - [NotNull] - protected JoinableTaskContext? JoinableTaskContext - { - get - { - return _joinableTaskContext ?? throw new InvalidOperationException(); - } - - private set - { - if (value == _joinableTaskContext) - { - return; - } - - if (value is null) - { - _joinableTaskContext = null; - _joinableTaskCollection = null; - _joinableTaskFactory = null; - } - else - { - _joinableTaskContext = value; - _joinableTaskCollection = value.CreateCollection(); - _joinableTaskFactory = value.CreateFactory(_joinableTaskCollection).WithPriority(Application.Current.Dispatcher, DispatcherPriority.Background); - } - } - } - - [NotNull] - protected TestServices? TestServices - { - get - { - return _testServices ?? throw new InvalidOperationException(); - } - - private set - { - _testServices = value; - } - } - - protected JoinableTaskFactory JoinableTaskFactory - => _joinableTaskFactory ?? throw new InvalidOperationException(); - - protected CancellationToken HangMitigatingCancellationToken - => _hangMitigatingCancellationTokenSource.Token; - - public virtual async Task InitializeAsync() - { - TestServices = await CreateTestServicesAsync(); - } - - public virtual async Task DisposeAsync() - { - if (_joinableTaskCollection is object) - { - await _joinableTaskCollection.JoinTillEmptyAsync(); - } - - JoinableTaskContext = null; - } - - public virtual void Dispose() - { - } - - protected virtual async Task CreateTestServicesAsync() - => await TestServices.CreateAsync(JoinableTaskFactory); - } -} diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/WellKnownCommandNames.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/AbstractIntegrationTest.cs similarity index 56% rename from tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/WellKnownCommandNames.cs rename to tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/AbstractIntegrationTest.cs index 3c162a8d..29109cbb 100644 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/WellKnownCommandNames.cs +++ b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/AbstractIntegrationTest.cs @@ -2,13 +2,13 @@ // 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.VisualStudio.Extensibility.Testing; +using Xunit; + namespace Microsoft.CodeAnalysis.Testing { - internal static class WellKnownCommandNames + [IdeSettings(MinVersion = VisualStudioVersion.VS2022)] + public abstract class AbstractIntegrationTest : AbstractIdeIntegrationTest { - public static class Build - { - public const string BuildSolution = "Build.BuildSolution"; - } } } diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/CreateProjectTests.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/CreateProjectTests.cs index 99a44b93..5bc93d2f 100644 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/CreateProjectTests.cs +++ b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/CreateProjectTests.cs @@ -5,150 +5,140 @@ using System; using Microsoft.CodeAnalysis.Testing.Verifiers; using Microsoft.VisualStudio.Shell.Interop; -using Microsoft.VisualStudio.Threading; using Xunit; using Task = System.Threading.Tasks.Task; namespace Microsoft.CodeAnalysis.Testing { - public class CreateProjectTests : AbstractIdeIntegrationTest + public class CreateProjectTests : AbstractIntegrationTest { - public override async Task DisposeAsync() - { - await JoinableTaskFactory.SwitchToMainThreadAsync(); - - await TestServices.SolutionExplorer.CloseSolutionAsync(); - - await base.DisposeAsync(); - } - [IdeFact] public async Task CreateFromTemplateAsync() { - await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests)); - await TestServices.SolutionExplorer.AddProjectAsync("TestProj", WellKnownProjectTemplates.CSharpNetCoreClassLibrary, languageName: LanguageNames.CSharp); + await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken); + await TestServices.SolutionExplorer.AddProjectAsync("TestProj", WellKnownProjectTemplates.CSharpNetCoreClassLibrary, languageName: LanguageNames.CSharp, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken); - await TestServices.Editor.SetTextAsync(@"using System"); + await TestServices.Editor.SetTextAsync(@"using System", HangMitigatingCancellationToken); - var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true); + var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken); Assert.Equal("========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========", buildSummary); - await TestServices.ErrorList.ShowBuildErrorsAsync(); + await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken); // Verify that intentional errors get validated by the test - var errors = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_ERROR); + var errors = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken); var expected = "(Compiler) Class1.cs(1, 13): error CS1002: ; expected"; new XUnitVerifier().EqualOrDiff(expected, string.Join(Environment.NewLine, errors)); - Assert.Equal(1, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR)); + Assert.Equal(1, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken)); } [IdeFact] public async Task CreateAnalyzerFromCSharpTemplateAsync() { - await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests)); - await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.CSharp.Analyzer", languageName: LanguageNames.CSharp); + await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken); + await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.CSharp.Analyzer", languageName: LanguageNames.CSharp, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken); - var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true); + var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken); Assert.Equal("========== Build: 5 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========", buildSummary); - await TestServices.ErrorList.ShowBuildErrorsAsync(); + await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken); - var errors = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_ERROR); + var errors = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken); new XUnitVerifier().EqualOrDiff(string.Empty, string.Join(Environment.NewLine, errors)); - Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR)); + Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken)); // Currently have two analyzer warnings in the template. - var warnings = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_WARNING); + var warnings = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken); new XUnitVerifier().EqualOrDiff(string.Empty, string.Join(Environment.NewLine, warnings)); - Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING)); + Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken)); } [IdeFact] public async Task CreateRefactoringFromCSharpTemplateAsync() { - await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests)); - await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.CSharp.CodeRefactoring", languageName: LanguageNames.CSharp); + await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken); + await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.CSharp.CodeRefactoring", languageName: LanguageNames.CSharp, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken); - var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true); + var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken); Assert.Equal("========== Build: 2 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========", buildSummary); - await TestServices.ErrorList.ShowBuildErrorsAsync(); + await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken); - Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR)); - Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING)); + Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken)); + Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken)); } [IdeFact] public async Task CreateStandaloneToolFromCSharpTemplateAsync() { - await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests)); - await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.CSharp.StandaloneCodeAnalysis", languageName: LanguageNames.CSharp); + await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken); + await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.CSharp.StandaloneCodeAnalysis", languageName: LanguageNames.CSharp, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken); - var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true); + var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken); Assert.Equal("========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========", buildSummary); - await TestServices.ErrorList.ShowBuildErrorsAsync(); + await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken); - Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR)); - Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING)); + Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken)); + Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken)); } [IdeFact] public async Task CreateAnalyzerFromVisualBasicTemplateAsync() { - await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests)); - await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.VisualBasic.Analyzer", languageName: LanguageNames.VisualBasic); + await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken); + await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.VisualBasic.Analyzer", languageName: LanguageNames.VisualBasic, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken); - var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true); + var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken); Assert.Equal("========== Build: 5 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========", buildSummary); - await TestServices.ErrorList.ShowBuildErrorsAsync(); + await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken); - var errors = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_ERROR); + var errors = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken); new XUnitVerifier().EqualOrDiff(string.Empty, string.Join(Environment.NewLine, errors)); - Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR)); + Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken)); // Currently have two analyzer warnings in the template. - var warnings = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_WARNING); + var warnings = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken); new XUnitVerifier().EqualOrDiff(string.Empty, string.Join(Environment.NewLine, warnings)); - Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING)); + Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken)); } [IdeFact] public async Task CreateRefactoringFromVisualBasicTemplateAsync() { - await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests)); - await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.VisualBasic.CodeRefactoring", languageName: LanguageNames.VisualBasic); + await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken); + await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.VisualBasic.CodeRefactoring", languageName: LanguageNames.VisualBasic, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken); - var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true); + var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken); Assert.Equal("========== Build: 2 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========", buildSummary); - await TestServices.ErrorList.ShowBuildErrorsAsync(); + await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken); - Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR)); - Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING)); + Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken)); + Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken)); } [IdeFact] public async Task CreateStandaloneToolFromVisualBasicTemplateAsync() { - await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests)); - await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.VisualBasic.StandaloneCodeAnalysis", languageName: LanguageNames.VisualBasic); + await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken); + await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.VisualBasic.StandaloneCodeAnalysis", languageName: LanguageNames.VisualBasic, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken); - var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true); + var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken); Assert.Equal("========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========", buildSummary); - await TestServices.ErrorList.ShowBuildErrorsAsync(); + await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken); - Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR)); - Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING)); + Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken)); + Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken)); } } } diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/EditorInProcess.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/EditorInProcess.cs index 03936d8d..48544c99 100644 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/EditorInProcess.cs +++ b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/EditorInProcess.cs @@ -2,60 +2,19 @@ // 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 Microsoft.VisualStudio; using Microsoft.VisualStudio.Text; -using Microsoft.VisualStudio.Text.Editor; -using Microsoft.VisualStudio.TextManager.Interop; -namespace Microsoft.CodeAnalysis.Testing.InProcess +namespace Microsoft.VisualStudio.Extensibility.Testing { - public class EditorInProcess : InProcComponent + internal partial class EditorInProcess { - internal static readonly Guid IWpfTextViewId = new Guid("8C40265E-9FDB-4F54-A0FD-EBB72B7D0476"); - - public EditorInProcess(TestServices testServices) - : base(testServices) + public async Task SetTextAsync(string text, CancellationToken cancellationToken) { - } + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - public async Task GetActiveTextViewAsync() - => (await GetActiveTextViewHostAsync()).TextView; - - private async Task GetActiveVsTextViewAsync() - { - await JoinableTaskFactory.SwitchToMainThreadAsync(); - - var vsTextManager = await GetRequiredGlobalServiceAsync(); - - ErrorHandler.ThrowOnFailure(vsTextManager.GetActiveView(fMustHaveFocus: 1, pBuffer: null, ppView: out var vsTextView)); - - return vsTextView; - } - - private async Task GetActiveTextViewHostAsync() - { - // The active text view might not have finished composing yet, waiting for the application to 'idle' - // means that it is done pumping messages (including WM_PAINT) and the window should return the correct text - // view. - await WaitForApplicationIdleAsync(CancellationToken.None); - - await JoinableTaskFactory.SwitchToMainThreadAsync(); - - var activeVsTextView = (IVsUserData)await GetActiveVsTextViewAsync(); - - ErrorHandler.ThrowOnFailure(activeVsTextView.GetData(IWpfTextViewId, out var wpfTextViewHost)); - - return (IWpfTextViewHost)wpfTextViewHost; - } - - public async Task SetTextAsync(string text) - { - await JoinableTaskFactory.SwitchToMainThreadAsync(); - - var view = await GetActiveTextViewAsync(); + var view = await GetActiveTextViewAsync(cancellationToken); var textSnapshot = view.TextSnapshot; var replacementSpan = new SnapshotSpan(textSnapshot, 0, textSnapshot.Length); view.TextBuffer.Replace(replacementSpan, text); diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/ErrorListInProcess.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/ErrorListInProcess.cs index 63e8cbfb..ca81bfbd 100644 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/ErrorListInProcess.cs +++ b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/ErrorListInProcess.cs @@ -7,7 +7,9 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.IO; using System.Linq; +using System.Threading; using System.Threading.Tasks; +using Microsoft.VisualStudio.Extensibility.Testing; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Shell.TableControl; @@ -16,18 +18,14 @@ using Task = System.Threading.Tasks.Task; namespace Microsoft.CodeAnalysis.Testing.InProcess { - public class ErrorListInProcess : InProcComponent + [TestService] + internal partial class ErrorListInProcess { - public ErrorListInProcess(TestServices testServices) - : base(testServices) + public async Task ShowBuildErrorsAsync(CancellationToken cancellationToken) { - } + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - public async Task ShowBuildErrorsAsync() - { - await JoinableTaskFactory.SwitchToMainThreadAsync(); - - var errorList = await GetRequiredGlobalServiceAsync(); + var errorList = await GetRequiredGlobalServiceAsync(cancellationToken); errorList.AreBuildErrorSourceEntriesShown = true; errorList.AreOtherErrorSourceEntriesShown = false; errorList.AreErrorsShown = true; @@ -35,11 +33,16 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess errorList.AreWarningsShown = false; } - public async Task> GetBuildErrorsAsync(__VSERRORCATEGORY minimumSeverity = __VSERRORCATEGORY.EC_WARNING) + public Task> GetBuildErrorsAsync(CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + return GetBuildErrorsAsync(__VSERRORCATEGORY.EC_WARNING, cancellationToken); + } - var errorItems = await GetErrorItemsAsync(); + public async Task> GetBuildErrorsAsync(__VSERRORCATEGORY minimumSeverity, CancellationToken cancellationToken) + { + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + + var errorItems = await GetErrorItemsAsync(cancellationToken); var list = new List(); foreach (var item in errorItems) @@ -79,19 +82,24 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess .ToImmutableArray(); } - public async Task GetErrorCountAsync(__VSERRORCATEGORY minimumSeverity = __VSERRORCATEGORY.EC_WARNING) + public Task GetErrorCountAsync(CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + return GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, cancellationToken); + } - var errorItems = await GetErrorItemsAsync(); + public async Task GetErrorCountAsync(__VSERRORCATEGORY minimumSeverity, CancellationToken cancellationToken) + { + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + + var errorItems = await GetErrorItemsAsync(cancellationToken); return errorItems.Count(e => e.GetCategory() <= minimumSeverity); } - private async Task> GetErrorItemsAsync() + private async Task> GetErrorItemsAsync(CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - var errorList = await GetRequiredGlobalServiceAsync(); + var errorList = await GetRequiredGlobalServiceAsync(cancellationToken); var args = await errorList.TableControl.ForceUpdateAsync(); return args.AllEntries.ToImmutableArray(); } diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/InProcComponent.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/InProcComponent.cs deleted file mode 100644 index 24f1d743..00000000 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/InProcComponent.cs +++ /dev/null @@ -1,76 +0,0 @@ -// 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 System; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Threading; - -using Microsoft.VisualStudio.ComponentModelHost; -using Microsoft.VisualStudio.Shell; -using Microsoft.VisualStudio.Shell.Interop; -using Microsoft.VisualStudio.Threading; - -using Task = System.Threading.Tasks.Task; - -namespace Microsoft.CodeAnalysis.Testing.InProcess -{ - public abstract class InProcComponent - { - protected InProcComponent(TestServices testServices) - { - TestServices = testServices ?? throw new ArgumentNullException(nameof(testServices)); - } - - public TestServices TestServices { get; } - - protected JoinableTaskFactory JoinableTaskFactory => TestServices.JoinableTaskFactory; - - protected async Task ExecuteCommandAsync(string commandName, string args = "") - { - await JoinableTaskFactory.SwitchToMainThreadAsync(); - - var dte = await GetRequiredGlobalServiceAsync(); - dte.ExecuteCommand(commandName, args); - } - - protected async Task GetRequiredGlobalServiceAsync() - where TService : class - where TInterface : class - { - await JoinableTaskFactory.SwitchToMainThreadAsync(); - - var serviceProvider = (IAsyncServiceProvider2?)await AsyncServiceProvider.GlobalProvider.GetServiceAsync(typeof(SAsyncServiceProvider)); - Assumes.Present(serviceProvider); - - var @interface = (TInterface?)await serviceProvider.GetServiceAsync(typeof(TService)); - Assumes.Present(@interface); - return @interface; - } - - protected async Task GetComponentModelServiceAsync() - where TService : class - { - var componentModel = await GetRequiredGlobalServiceAsync(); - return componentModel.GetService(); - } - - /// - /// Waiting for the application to 'idle' means that it is done pumping messages (including WM_PAINT). - /// - /// The cancellation token that the operation will observe. - /// A representing the asynchronous operation. - protected static async Task WaitForApplicationIdleAsync(CancellationToken cancellationToken) - { - var synchronizationContext = new DispatcherSynchronizationContext(Application.Current.Dispatcher, DispatcherPriority.ApplicationIdle); - var taskScheduler = new SynchronizationContextTaskScheduler(synchronizationContext); - await Task.Factory.StartNew( - () => { }, - cancellationToken, - TaskCreationOptions.None, - taskScheduler); - } - } -} diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/SolutionExplorerInProcess.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/SolutionExplorerInProcess.cs index 1047a788..74c8cf41 100644 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/SolutionExplorerInProcess.cs +++ b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/SolutionExplorerInProcess.cs @@ -8,119 +8,42 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using Microsoft.VisualStudio.OperationProgress; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; -using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.TextManager.Interop; using Microsoft.VisualStudio.Threading; using NuGet.SolutionRestoreManager; using Task = System.Threading.Tasks.Task; -namespace Microsoft.CodeAnalysis.Testing.InProcess +namespace Microsoft.VisualStudio.Extensibility.Testing { - public class SolutionExplorerInProcess : InProcComponent + internal partial class SolutionExplorerInProcess { - public SolutionExplorerInProcess(TestServices testServices) - : base(testServices) + public async Task CreateSolutionAsync(string solutionName, CancellationToken cancellationToken) { - } - - private async Task IsSolutionOpenAsync() - { - await JoinableTaskFactory.SwitchToMainThreadAsync(); - - var solution = await GetRequiredGlobalServiceAsync(); - ErrorHandler.ThrowOnFailure(solution.GetProperty((int)__VSPROPID.VSPROPID_IsSolutionOpen, out var isOpen)); - return (bool)isOpen; - } - - public async Task CloseSolutionAsync(bool saveFirst = false) - { - await JoinableTaskFactory.SwitchToMainThreadAsync(); - if (!await IsSolutionOpenAsync()) - { - return; - } - - if (saveFirst) - { - await SaveSolutionAsync(); - } - - await CloseSolutionAsync(); - } - - private async Task CloseSolutionAsync() - { - await JoinableTaskFactory.SwitchToMainThreadAsync(); - - var solution = await GetRequiredGlobalServiceAsync(); - if (!await IsSolutionOpenAsync()) - { - return; - } - - using var semaphore = new SemaphoreSlim(1); - using var solutionEvents = new SolutionEvents(JoinableTaskFactory, solution); - - await semaphore.WaitAsync(); - - void HandleAfterCloseSolution(object sender, EventArgs e) => semaphore.Release(); - - solutionEvents.AfterCloseSolution += HandleAfterCloseSolution; - try - { - ErrorHandler.ThrowOnFailure(solution.CloseSolutionElement((uint)__VSSLNCLOSEOPTIONS.SLNCLOSEOPT_DeleteProject | (uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_NoSave, null, 0)); - await semaphore.WaitAsync(); - } - finally - { - solutionEvents.AfterCloseSolution -= HandleAfterCloseSolution; - } - } - - public async Task CreateSolutionAsync(string solutionName) - { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); var solutionPath = CreateTemporaryPath(); - await CreateSolutionAsync(solutionPath, solutionName); + await CreateSolutionAsync(solutionPath, solutionName, cancellationToken); } - private async Task CreateSolutionAsync(string solutionPath, string solutionName) + private async Task CreateSolutionAsync(string solutionPath, string solutionName, CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - await CloseSolutionAsync(); + await CloseSolutionAsync(cancellationToken); var solutionFileName = Path.ChangeExtension(solutionName, ".sln"); Directory.CreateDirectory(solutionPath); - var solution = await GetRequiredGlobalServiceAsync(); + var solution = await GetRequiredGlobalServiceAsync(cancellationToken); ErrorHandler.ThrowOnFailure(solution.CreateSolution(solutionPath, solutionFileName, (uint)__VSCREATESOLUTIONFLAGS.CSF_SILENT)); ErrorHandler.ThrowOnFailure(solution.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, null, 0)); } - public async Task SaveSolutionAsync() - { - await JoinableTaskFactory.SwitchToMainThreadAsync(); - - if (!await IsSolutionOpenAsync()) - { - throw new InvalidOperationException("Cannot save solution when no solution is open."); - } - - var solution = await GetRequiredGlobalServiceAsync(); - - // Make sure the directory exists so the Save dialog doesn't appear - ErrorHandler.ThrowOnFailure(solution.GetSolutionInfo(out var solutionDirectory, out _, out _)); - Directory.CreateDirectory(solutionDirectory); - - ErrorHandler.ThrowOnFailure(solution.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, null, 0)); - } - private static string ConvertLanguageName(string languageName) { return languageName switch @@ -131,11 +54,11 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess }; } - private async Task GetDirectoryNameAsync() + private async Task GetDirectoryNameAsync(CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - var solution = await GetRequiredGlobalServiceAsync(); + var solution = await GetRequiredGlobalServiceAsync(cancellationToken); ErrorHandler.ThrowOnFailure(solution.GetSolutionInfo(out _, out var solutionFileFullPath, out _)); if (string.IsNullOrEmpty(solutionFileFullPath)) { @@ -145,11 +68,11 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess return Path.GetDirectoryName(solutionFileFullPath); } - private async Task> GetCSharpProjectTemplatesAsync() + private async Task> GetCSharpProjectTemplatesAsync(CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - var hostLocale = await GetRequiredGlobalServiceAsync(); + var hostLocale = await GetRequiredGlobalServiceAsync(cancellationToken); ErrorHandler.ThrowOnFailure(hostLocale.GetUILocale(out var localeID)); var builder = ImmutableDictionary.CreateBuilder(); @@ -162,11 +85,11 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess return builder.ToImmutable(); } - private async Task> GetVisualBasicProjectTemplatesAsync() + private async Task> GetVisualBasicProjectTemplatesAsync(CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - var hostLocale = await GetRequiredGlobalServiceAsync(); + var hostLocale = await GetRequiredGlobalServiceAsync(cancellationToken); ErrorHandler.ThrowOnFailure(hostLocale.GetUILocale(out var localeID)); var builder = ImmutableDictionary.CreateBuilder(); @@ -179,31 +102,31 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess return builder.ToImmutable(); } - public async Task AddProjectAsync(string projectName, string projectTemplate, string languageName) + public async Task AddProjectAsync(string projectName, string projectTemplate, string languageName, CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - var projectPath = Path.Combine(await GetDirectoryNameAsync(), projectName); - var projectTemplatePath = await GetProjectTemplatePathAsync(projectTemplate, ConvertLanguageName(languageName)); - var solution = await GetRequiredGlobalServiceAsync(); + var projectPath = Path.Combine(await GetDirectoryNameAsync(cancellationToken), projectName); + var projectTemplatePath = await GetProjectTemplatePathAsync(projectTemplate, ConvertLanguageName(languageName), cancellationToken); + var solution = await GetRequiredGlobalServiceAsync(cancellationToken); ErrorHandler.ThrowOnFailure(solution.AddNewProjectFromTemplate(projectTemplatePath, null, null, projectPath, projectName, null, out _)); } - private async Task GetProjectTemplatePathAsync(string projectTemplate, string languageName) + private async Task GetProjectTemplatePathAsync(string projectTemplate, string languageName, CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - var dte = await GetRequiredGlobalServiceAsync(); + var dte = await GetRequiredGlobalServiceAsync(cancellationToken); var solution = (EnvDTE80.Solution2)dte.Solution; if (string.Equals(languageName, "csharp", StringComparison.OrdinalIgnoreCase) - && (await GetCSharpProjectTemplatesAsync()).TryGetValue(projectTemplate, out var csharpProjectTemplate)) + && (await GetCSharpProjectTemplatesAsync(cancellationToken)).TryGetValue(projectTemplate, out var csharpProjectTemplate)) { return solution.GetProjectTemplate(csharpProjectTemplate, languageName); } if (string.Equals(languageName, "visualbasic", StringComparison.OrdinalIgnoreCase) - && (await GetVisualBasicProjectTemplatesAsync()).TryGetValue(projectTemplate, out var visualBasicProjectTemplate)) + && (await GetVisualBasicProjectTemplatesAsync(cancellationToken)).TryGetValue(projectTemplate, out var visualBasicProjectTemplate)) { return solution.GetProjectTemplate(visualBasicProjectTemplate, languageName); } @@ -213,9 +136,9 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess public async Task RestoreNuGetPackagesAsync(CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - var dte = await GetRequiredGlobalServiceAsync(); + var dte = await GetRequiredGlobalServiceAsync(cancellationToken); var solution = (EnvDTE80.Solution2)dte.Solution; foreach (var project in solution.Projects.OfType()) { @@ -225,17 +148,17 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess public async Task RestoreNuGetPackagesAsync(string projectName, CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - var operationProgressStatus = await GetRequiredGlobalServiceAsync(); + var operationProgressStatus = await GetRequiredGlobalServiceAsync(cancellationToken); var stageStatus = operationProgressStatus.GetStageStatus(CommonOperationProgressStageIds.Intellisense); await stageStatus.WaitForCompletionAsync(); - var solutionRestoreService = await GetComponentModelServiceAsync(); + var solutionRestoreService = await GetComponentModelServiceAsync(cancellationToken); await solutionRestoreService.CurrentRestoreOperation; - var projectFullPath = (await GetProjectAsync(projectName)).FullName; - var solutionRestoreStatusProvider = await GetComponentModelServiceAsync(); + var projectFullPath = (await GetProjectAsync(projectName, cancellationToken)).FullName; + var solutionRestoreStatusProvider = await GetComponentModelServiceAsync(cancellationToken); if (await solutionRestoreStatusProvider.IsRestoreCompleteAsync(cancellationToken)) { return; @@ -255,42 +178,42 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess } } - public async Task BuildSolutionAsync(bool waitForBuildToFinish) + public async Task BuildSolutionAsync(bool waitForBuildToFinish, CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - var buildOutputWindowPane = await GetBuildOutputWindowPaneAsync(); + var buildOutputWindowPane = await GetBuildOutputWindowPaneAsync(cancellationToken); buildOutputWindowPane.Clear(); - await ExecuteCommandAsync(WellKnownCommandNames.Build.BuildSolution); + await TestServices.Shell.ExecuteCommandAsync(VSConstants.VSStd97CmdID.BuildSln, cancellationToken); if (waitForBuildToFinish) { - return await WaitForBuildToFinishAsync(buildOutputWindowPane); + return await WaitForBuildToFinishAsync(buildOutputWindowPane, cancellationToken); } return null; } - public async Task WaitForBuildToFinishAsync() + public async Task WaitForBuildToFinishAsync(CancellationToken cancellationToken) { - var buildOutputWindowPane = await GetBuildOutputWindowPaneAsync(); - return await WaitForBuildToFinishAsync(buildOutputWindowPane); + var buildOutputWindowPane = await GetBuildOutputWindowPaneAsync(cancellationToken); + return await WaitForBuildToFinishAsync(buildOutputWindowPane, cancellationToken); } - public async Task GetBuildOutputWindowPaneAsync() + public async Task GetBuildOutputWindowPaneAsync(CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - var outputWindow = await GetRequiredGlobalServiceAsync(); + var outputWindow = await GetRequiredGlobalServiceAsync(cancellationToken); ErrorHandler.ThrowOnFailure(outputWindow.GetPane(VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid, out var pane)); return pane; } - private async Task WaitForBuildToFinishAsync(IVsOutputWindowPane buildOutputWindowPane) + private async Task WaitForBuildToFinishAsync(IVsOutputWindowPane buildOutputWindowPane, CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - var buildManager = await GetRequiredGlobalServiceAsync(); + var buildManager = await GetRequiredGlobalServiceAsync(cancellationToken); using var semaphore = new SemaphoreSlim(1); using var solutionEvents = new UpdateSolutionEvents(buildManager); @@ -311,8 +234,8 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess ErrorHandler.ThrowOnFailure(buildOutputWindowPane.FlushToTaskList()); var textView = (IVsTextView)buildOutputWindowPane; - ErrorHandler.ThrowOnFailure(((IVsUserData)textView).GetData(EditorInProcess.IWpfTextViewId, out var wpfTextViewHost)); - var lines = ((IWpfTextViewHost)wpfTextViewHost).TextView.TextViewLines; + var wpfTextViewHost = await textView.GetTextViewHostAsync(JoinableTaskFactory, cancellationToken); + var lines = wpfTextViewHost.TextView.TextViewLines; if (lines.Count < 1) { return string.Empty; @@ -326,11 +249,11 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess return Path.Combine(Path.GetTempPath(), "roslyn-sdk-test", Path.GetRandomFileName()); } - private async Task GetProjectAsync(string nameOrFileName) + private async Task GetProjectAsync(string nameOrFileName, CancellationToken cancellationToken) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - var dte = await GetRequiredGlobalServiceAsync(); + var dte = await GetRequiredGlobalServiceAsync(cancellationToken); var solution = (EnvDTE80.Solution2)dte.Solution; return solution.Projects.OfType().First( project => @@ -341,84 +264,6 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess }); } - private sealed class SolutionEvents : IVsSolutionEvents, IDisposable - { - private readonly JoinableTaskFactory _joinableTaskFactory; - private readonly IVsSolution _solution; - private readonly uint _cookie; - - public SolutionEvents(JoinableTaskFactory joinableTaskFactory, IVsSolution solution) - { - ThreadHelper.ThrowIfNotOnUIThread(); - - _joinableTaskFactory = joinableTaskFactory; - _solution = solution; - ErrorHandler.ThrowOnFailure(solution.AdviseSolutionEvents(this, out _cookie)); - } - - public event EventHandler? AfterCloseSolution; - - public void Dispose() - { - _joinableTaskFactory.Run(async () => - { - await _joinableTaskFactory.SwitchToMainThreadAsync(); - ErrorHandler.ThrowOnFailure(_solution.UnadviseSolutionEvents(_cookie)); - }); - } - - public int OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded) - { - return VSConstants.S_OK; - } - - public int OnQueryCloseProject(IVsHierarchy pHierarchy, int fRemoving, ref int pfCancel) - { - return VSConstants.S_OK; - } - - public int OnBeforeCloseProject(IVsHierarchy pHierarchy, int fRemoved) - { - return VSConstants.S_OK; - } - - public int OnAfterLoadProject(IVsHierarchy pStubHierarchy, IVsHierarchy pRealHierarchy) - { - return VSConstants.S_OK; - } - - public int OnQueryUnloadProject(IVsHierarchy pRealHierarchy, ref int pfCancel) - { - return VSConstants.S_OK; - } - - public int OnBeforeUnloadProject(IVsHierarchy pRealHierarchy, IVsHierarchy pStubHierarchy) - { - return VSConstants.S_OK; - } - - public int OnAfterOpenSolution(object pUnkReserved, int fNewSolution) - { - return VSConstants.S_OK; - } - - public int OnQueryCloseSolution(object pUnkReserved, ref int pfCancel) - { - return VSConstants.S_OK; - } - - public int OnBeforeCloseSolution(object pUnkReserved) - { - return VSConstants.S_OK; - } - - public int OnAfterCloseSolution(object pUnkReserved) - { - AfterCloseSolution?.Invoke(this, EventArgs.Empty); - return VSConstants.S_OK; - } - } - internal sealed class UpdateSolutionEvents : IVsUpdateSolutionEvents, IVsUpdateSolutionEvents2, IDisposable { private uint _cookie; diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/SynchronizationContextTaskScheduler.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/SynchronizationContextTaskScheduler.cs deleted file mode 100644 index 95f99b12..00000000 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/SynchronizationContextTaskScheduler.cs +++ /dev/null @@ -1,49 +0,0 @@ -// 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 System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.CodeAnalysis.Testing.InProcess -{ - // Based on CoreCLR's implementation of the TaskScheduler they return from TaskScheduler.FromCurrentSynchronizationContext - internal class SynchronizationContextTaskScheduler : TaskScheduler - { - private readonly SendOrPostCallback _postCallback; - private readonly SynchronizationContext _synchronizationContext; - - internal SynchronizationContextTaskScheduler(SynchronizationContext synchronizationContext) - { - _postCallback = new SendOrPostCallback(PostCallback); - _synchronizationContext = synchronizationContext ?? throw new ArgumentNullException(nameof(synchronizationContext)); - } - - public override int MaximumConcurrencyLevel => 1; - - protected override void QueueTask(Task task) - { -#pragma warning disable VSTHRD001 // Avoid legacy thread switching APIs - _synchronizationContext.Post(_postCallback, task); -#pragma warning restore VSTHRD001 // Avoid legacy thread switching APIs - } - - protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) - { - if (SynchronizationContext.Current == _synchronizationContext) - { - return TryExecuteTask(task); - } - - return false; - } - - protected override IEnumerable? GetScheduledTasks() - => null; - - private void PostCallback(object obj) - => TryExecuteTask((Task)obj); - } -} diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/TestServices.cs b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/TestServices.cs deleted file mode 100644 index 160a3e77..00000000 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/InProcess/TestServices.cs +++ /dev/null @@ -1,41 +0,0 @@ -// 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 System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; - -namespace Microsoft.CodeAnalysis.Testing.InProcess -{ - public class TestServices - { - protected TestServices(JoinableTaskFactory joinableTaskFactory) - { - JoinableTaskFactory = joinableTaskFactory; - - Editor = new EditorInProcess(this); - ErrorList = new ErrorListInProcess(this); - SolutionExplorer = new SolutionExplorerInProcess(this); - } - - public JoinableTaskFactory JoinableTaskFactory { get; } - - public EditorInProcess Editor { get; } - - public ErrorListInProcess ErrorList { get; } - - public SolutionExplorerInProcess SolutionExplorer { get; } - - internal static async Task CreateAsync(JoinableTaskFactory joinableTaskFactory) - { - var services = new TestServices(joinableTaskFactory); - await services.InitializeAsync(); - return services; - } - - protected virtual Task InitializeAsync() - { - return Task.CompletedTask; - } - } -} diff --git a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/Roslyn.SDK.IntegrationTests.csproj b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/Roslyn.SDK.IntegrationTests.csproj index f98055e6..5558606c 100644 --- a/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/Roslyn.SDK.IntegrationTests.csproj +++ b/tests/VisualStudio.Roslyn.SDK/Roslyn.SDK.IntegrationTests/Roslyn.SDK.IntegrationTests.csproj @@ -22,6 +22,7 @@ +