Skip to content

Commit

Permalink
Test EnC document diagnostics in non-host workspace
Browse files Browse the repository at this point in the history
  • Loading branch information
tmat committed Sep 16, 2024
1 parent 7b7951a commit 1e2ba80
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -354,11 +354,6 @@ private async Task<TestLspServer> 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);
}

Expand All @@ -375,10 +370,6 @@ private protected async Task<TestLspServer> 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);
}

Expand Down Expand Up @@ -564,6 +555,11 @@ private void InitializeClientRpc()

internal static async Task<TestLspServer> 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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = """
<Workspace>
<Project Language='C#' CommonReferences='true' AssemblyName='Submission' Name='Submission1'>
<Document FilePath='C:\Submission#1.cs'>1+1</Document>
</Project>
</Workspace>
""";

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<EditAndContinueSessionState>();

// 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)
{
Expand All @@ -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<EditAndContinueSessionState>();

var results = await RunGetWorkspacePullDiagnosticsAsync(testLspServer, useVSDiagnostics: false, includeTaskListItems: false, category: PullDiagnosticCategories.EditAndContinue);
Assert.Empty(results);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,6 @@ private async Task<TestLspServer> 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<AsynchronousOperationListenerProvider>();
var workspaceWaiter = operations.GetWaiter(FeatureAttribute.Workspace);
await workspaceWaiter.ExpeditedWaitAsync();

var server = await TestLspServer.CreateAsync(workspace, new InitializationOptions(), _logger);
return server;
}
Expand Down

0 comments on commit 1e2ba80

Please sign in to comment.