From 1e2ba80de376e26005fe88c0a9e9f4c2e5b55df7 Mon Sep 17 00:00:00 2001 From: tmat Date: Mon, 16 Sep 2024 16:15:02 -0700 Subject: [PATCH] Test EnC document diagnostics in non-host workspace --- .../AbstractLanguageServerProtocolTests.cs | 14 ++++------ .../Diagnostics/PullDiagnosticTests.cs | 28 +++++++++++++++++-- .../Workspaces/LspWorkspaceManagerTests.cs | 6 +--- .../DocumentOutlineTestsBase.cs | 7 ----- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/EditorFeatures/TestUtilities/LanguageServer/AbstractLanguageServerProtocolTests.cs b/src/EditorFeatures/TestUtilities/LanguageServer/AbstractLanguageServerProtocolTests.cs index ab040589da27e..ab9c0c9652a1a 100644 --- a/src/EditorFeatures/TestUtilities/LanguageServer/AbstractLanguageServerProtocolTests.cs +++ b/src/EditorFeatures/TestUtilities/LanguageServer/AbstractLanguageServerProtocolTests.cs @@ -354,11 +354,6 @@ private async Task CreateTestLspServerAsync(EditorTestWorkspace w solution = solution.WithAnalyzerReferences([analyzerReferencesByLanguage]); await workspace.ChangeSolutionAsync(solution); - // Important: We must wait for workspace creation operations to finish. - // Otherwise we could have a race where workspace change events triggered by creation are changing the state - // created by the initial test steps. This can interfere with the expected test state. - await WaitForWorkspaceOperationsAsync(workspace); - return await TestLspServer.CreateAsync(workspace, initializationOptions, TestOutputLspLogger); } @@ -375,10 +370,6 @@ private protected async Task CreateXmlTestLspServerAsync( workspace.InitializeDocuments(XElement.Parse(xmlContent), openDocuments: false); workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences([CreateTestAnalyzersReference()])); - // Important: We must wait for workspace creation operations to finish. - // Otherwise we could have a race where workspace change events triggered by creation are changing the state - // created by the initial test steps. This can interfere with the expected test state. - await WaitForWorkspaceOperationsAsync(workspace); return await TestLspServer.CreateAsync(workspace, lspOptions, TestOutputLspLogger); } @@ -564,6 +555,11 @@ private void InitializeClientRpc() internal static async Task CreateAsync(EditorTestWorkspace testWorkspace, InitializationOptions initializationOptions, AbstractLspLogger logger) { + // Important: We must wait for workspace creation operations to finish. + // Otherwise we could have a race where workspace change events triggered by creation are changing the state + // created by the initial test steps. This can interfere with the expected test state. + await WaitForWorkspaceOperationsAsync(testWorkspace); + var locations = await GetAnnotatedLocationsAsync(testWorkspace, testWorkspace.CurrentSolution); var (clientStream, serverStream) = FullDuplexStream.CreatePair(); diff --git a/src/LanguageServer/ProtocolUnitTests/Diagnostics/PullDiagnosticTests.cs b/src/LanguageServer/ProtocolUnitTests/Diagnostics/PullDiagnosticTests.cs index d0be59f92a78b..0509b13a9f171 100644 --- a/src/LanguageServer/ProtocolUnitTests/Diagnostics/PullDiagnosticTests.cs +++ b/src/LanguageServer/ProtocolUnitTests/Diagnostics/PullDiagnosticTests.cs @@ -1165,6 +1165,32 @@ class A { Assert.Equal("TODO", results[0].Diagnostics![0].Code); } + [Theory, CombinatorialData] + public async Task EditAndContinue_NonHostWorkspace(bool mutatingLspWorkspace) + { + var xmlWorkspace = """ + + + 1+1 + + + """; + + var options = GetInitializationOptions(BackgroundAnalysisScope.OpenFiles, compilerDiagnosticsScope: null, useVSDiagnostics: false); + await using var testLspServer = await CreateXmlTestLspServerAsync(xmlWorkspace, mutatingLspWorkspace, WorkspaceKind.Interactive, options); + + var document = testLspServer.TestWorkspace.CurrentSolution.Projects.Single().Documents.Single(); + await OpenDocumentAsync(testLspServer, document); + + var encSessionState = testLspServer.TestWorkspace.GetService(); + + // active session, but should get no EnC diagnostics for Interactive workspace + encSessionState.IsSessionActive = true; + + var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document.GetURI(), useVSDiagnostics: false, category: PullDiagnosticCategories.EditAndContinue); + Assert.Empty(results); + } + [Theory, CombinatorialData] public async Task EditAndContinue_NoActiveSession(bool mutatingLspWorkspace) { @@ -1174,8 +1200,6 @@ public async Task EditAndContinue_NoActiveSession(bool mutatingLspWorkspace) await using var testLspServer = await CreateTestLspServerAsync([markup1], LanguageNames.CSharp, mutatingLspWorkspace, options); - var encSessionState = testLspServer.TestWorkspace.GetService(); - var results = await RunGetWorkspacePullDiagnosticsAsync(testLspServer, useVSDiagnostics: false, includeTaskListItems: false, category: PullDiagnosticCategories.EditAndContinue); Assert.Empty(results); } diff --git a/src/LanguageServer/ProtocolUnitTests/Workspaces/LspWorkspaceManagerTests.cs b/src/LanguageServer/ProtocolUnitTests/Workspaces/LspWorkspaceManagerTests.cs index 3998238e041dd..da491d13201d4 100644 --- a/src/LanguageServer/ProtocolUnitTests/Workspaces/LspWorkspaceManagerTests.cs +++ b/src/LanguageServer/ProtocolUnitTests/Workspaces/LspWorkspaceManagerTests.cs @@ -468,11 +468,6 @@ public async Task TestSeparateWorkspaceManagerPerServerAsync(bool mutatingLspWor using var testWorkspace = CreateWorkspace(options: null, workspaceKind: null, mutatingLspWorkspace); testWorkspace.InitializeDocuments(XElement.Parse(workspaceXml)); - // Wait for workspace creation operations to complete. - await WaitForWorkspaceOperationsAsync(testWorkspace); - - var documentUri = testWorkspace.CurrentSolution.Projects.First().Documents.First().GetURI(); - await using var testLspServerOne = await TestLspServer.CreateAsync(testWorkspace, new InitializationOptions(), TestOutputLspLogger); await using var testLspServerTwo = await TestLspServer.CreateAsync(testWorkspace, new InitializationOptions(), TestOutputLspLogger); @@ -483,6 +478,7 @@ public async Task TestSeparateWorkspaceManagerPerServerAsync(bool mutatingLspWor Assert.True(IsWorkspaceRegistered(testWorkspace, testLspServerTwo)); // Verify that the LSP solution uses the correct text for each server. + var documentUri = testWorkspace.CurrentSolution.Projects.First().Documents.First().GetURI(); var documentServerOne = await OpenDocumentAndVerifyLspTextAsync(documentUri, testLspServerOne, "Server one text"); var (_, documentServerTwo) = await GetLspWorkspaceAndDocumentAsync(documentUri, testLspServerTwo).ConfigureAwait(false); diff --git a/src/VisualStudio/CSharp/Test/DocumentOutline/DocumentOutlineTestsBase.cs b/src/VisualStudio/CSharp/Test/DocumentOutline/DocumentOutlineTestsBase.cs index bfd1d41affb48..5b549fcc253d8 100644 --- a/src/VisualStudio/CSharp/Test/DocumentOutline/DocumentOutlineTestsBase.cs +++ b/src/VisualStudio/CSharp/Test/DocumentOutline/DocumentOutlineTestsBase.cs @@ -118,13 +118,6 @@ private async Task CreateTestLspServerAsync(EditorTestWorkspace w solution = solution.WithAnalyzerReferences([new TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap())]); await workspace.ChangeSolutionAsync(solution); - // Important: We must wait for workspace creation operations to finish. - // Otherwise we could have a race where workspace change events triggered by creation are changing the state - // created by the initial test steps. This can interfere with the expected test state. - var operations = workspace.ExportProvider.GetExportedValue(); - var workspaceWaiter = operations.GetWaiter(FeatureAttribute.Workspace); - await workspaceWaiter.ExpeditedWaitAsync(); - var server = await TestLspServer.CreateAsync(workspace, new InitializationOptions(), _logger); return server; }