public Validator( string[] markedSource, ImmutableArray <ActiveStatementDebugInfo> activeStatements, ImmutableDictionary <ActiveMethodId, ImmutableArray <NonRemappableRegion> > nonRemappableRegions = null, Func <Solution, Solution> adjustSolution = null, CommittedSolution.DocumentState initialState = CommittedSolution.DocumentState.MatchesBuildOutput, bool openDocuments = false) { Workspace = TestWorkspace.CreateCSharp(ActiveStatementsDescription.ClearTags(markedSource), composition: s_composition, openDocuments: openDocuments); if (adjustSolution != null) { Workspace.ChangeSolution(adjustSolution(Workspace.CurrentSolution)); } var solution = Workspace.CurrentSolution; var mockDebuggeModuleProvider = new Mock <IDebuggeeModuleMetadataProvider>(MockBehavior.Strict); var mockCompilationOutputsProvider = new Func <Project, CompilationOutputs>(_ => new MockCompilationOutputs(Guid.NewGuid())); var debuggingSession = new DebuggingSession(solution, mockCompilationOutputsProvider); if (initialState != CommittedSolution.DocumentState.None) { EditAndContinueWorkspaceServiceTests.SetDocumentsState(debuggingSession, solution, initialState); } debuggingSession.Test_SetNonRemappableRegions(nonRemappableRegions ?? ImmutableDictionary <ActiveMethodId, ImmutableArray <NonRemappableRegion> > .Empty); var telemetry = new EditSessionTelemetry(); EditSession = new EditSession(debuggingSession, telemetry, cancellationToken => Task.FromResult(activeStatements), mockDebuggeModuleProvider.Object); }
private static Solution AddDefaultTestSolution( TestWorkspace workspace, string[] markedSources ) { var solution = workspace.CurrentSolution; var project = solution .AddProject("proj", "proj", LanguageNames.CSharp) .WithMetadataReferences( TargetFrameworkUtil.GetReferences(TargetFramework.Standard) ); solution = project.Solution; for (var i = 0; i < markedSources.Length; i++) { var name = $"test{i + 1}.cs"; var text = SourceText.From( ActiveStatementsDescription.ClearTags(markedSources[i]), Encoding.UTF8 ); var id = DocumentId.CreateNewId(project.Id, name); solution = solution.AddDocument( id, name, text, filePath: Path.Combine(TempRoot.Root, name) ); } workspace.ChangeSolution(solution); return solution; }
public Validator( string[] markedSource, ImmutableArray <ActiveStatementDebugInfo> activeStatements, ImmutableDictionary <ActiveMethodId, ImmutableArray <NonRemappableRegion> > nonRemappableRegions = null, Func <Solution, Solution> adjustSolution = null, CommittedSolution.DocumentState initialState = CommittedSolution.DocumentState.MatchesBuildOutput) { var exportProviderFactory = ExportProviderCache.GetOrCreateExportProviderFactory( TestExportProvider.MinimumCatalogWithCSharpAndVisualBasic.WithPart(typeof(CSharpEditAndContinueAnalyzer)).WithPart(typeof(DummyLanguageService))); var exportProvider = exportProviderFactory.CreateExportProvider(); Workspace = TestWorkspace.CreateCSharp(ActiveStatementsDescription.ClearTags(markedSource), exportProvider: exportProvider, openDocuments: true); if (adjustSolution != null) { Workspace.ChangeSolution(adjustSolution(Workspace.CurrentSolution)); } var mockDebuggeModuleProvider = new Mock <IDebuggeeModuleMetadataProvider>(); var mockCompilationOutputsProvider = new Func <Project, CompilationOutputs>(_ => new MockCompilationOutputs(Guid.NewGuid())); var debuggingSession = new DebuggingSession(Workspace, mockDebuggeModuleProvider.Object, mockCompilationOutputsProvider); if (initialState != CommittedSolution.DocumentState.None) { EditAndContinueWorkspaceServiceTests.SetDocumentsState(debuggingSession, Workspace.CurrentSolution, initialState); } debuggingSession.Test_SetNonRemappableRegions(nonRemappableRegions ?? ImmutableDictionary <ActiveMethodId, ImmutableArray <NonRemappableRegion> > .Empty); var telemetry = new EditSessionTelemetry(); EditSession = new EditSession(debuggingSession, telemetry, cancellationToken => Task.FromResult(activeStatements)); }
private static async Task <TestLspServer> CreateTestLspServerAsync(TestWorkspace workspace, LSP.ClientCapabilities?clientCapabilities, WellKnownLspServerKinds serverKind) { var solution = workspace.CurrentSolution; foreach (var document in workspace.Documents) { if (document.IsSourceGenerated) { continue; } solution = solution.WithDocumentFilePath(document.Id, GetDocumentFilePathFromName(document.Name)); var documentText = await solution.GetRequiredDocument(document.Id).GetTextAsync(CancellationToken.None); solution = solution.WithDocumentText(document.Id, SourceText.From(documentText.ToString(), System.Text.Encoding.UTF8)); } foreach (var project in workspace.Projects) { // Ensure all the projects have a valid file path. solution = solution.WithProjectFilePath(project.Id, GetDocumentFilePathFromName(project.FilePath)); } workspace.ChangeSolution(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, clientCapabilities ?? new LSP.ClientCapabilities(), serverKind)); }
private static async Task <TestLspServer> CreateTestLspServerAsync(TestWorkspace workspace) { var solution = workspace.CurrentSolution; foreach (var document in workspace.Documents) { solution = solution.WithDocumentFilePath(document.Id, GetDocumentFilePathFromName(document.Name)); } workspace.ChangeSolution(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(new TestLspServer(workspace)); }
private static async Task <TestLspServer> CreateTestLspServerAsync(TestWorkspace workspace, LSP.ClientCapabilities?clientCapabilities, WellKnownLspServerKinds serverKind) { var solution = workspace.CurrentSolution; foreach (var document in workspace.Documents) { if (document.IsSourceGenerated) { continue; } solution = solution.WithDocumentFilePath(document.Id, GetDocumentFilePathFromName(document.Name)); } workspace.ChangeSolution(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, clientCapabilities ?? new LSP.ClientCapabilities(), serverKind)); }
public Validator( string[] markedSource, ImmutableArray <ManagedActiveStatementDebugInfo> activeStatements, ImmutableDictionary <ManagedMethodId, ImmutableArray <NonRemappableRegion> > nonRemappableRegions = null, Func <Solution, Solution> adjustSolution = null, CommittedSolution.DocumentState initialState = CommittedSolution.DocumentState.MatchesBuildOutput, bool openDocuments = false) { Workspace = TestWorkspace.CreateCSharp(ActiveStatementsDescription.ClearTags(markedSource), composition: s_composition, openDocuments: openDocuments); if (adjustSolution != null) { Workspace.ChangeSolution(adjustSolution(Workspace.CurrentSolution)); } var solution = Workspace.CurrentSolution; var mockDebuggerService = new MockManagedEditAndContinueDebuggerService() { GetActiveStatementsImpl = () => activeStatements }; var mockCompilationOutputsProvider = new Func <Project, CompilationOutputs>(_ => new MockCompilationOutputs(Guid.NewGuid())); var debuggingSession = new DebuggingSession(solution, mockCompilationOutputsProvider, SpecializedCollections.EmptyEnumerable <KeyValuePair <DocumentId, CommittedSolution.DocumentState> >()); if (initialState != CommittedSolution.DocumentState.None) { EditAndContinueWorkspaceServiceTests.SetDocumentsState(debuggingSession, solution, initialState); } debuggingSession.Test_SetNonRemappableRegions(nonRemappableRegions ?? ImmutableDictionary <ManagedMethodId, ImmutableArray <NonRemappableRegion> > .Empty); var telemetry = new EditSessionTelemetry(); EditSession = new EditSession(debuggingSession, telemetry, mockDebuggerService); }
private static async Task <TestLspServer> CreateTestLspServerAsync(TestWorkspace workspace, InitializationOptions initializationOptions) { var solution = workspace.CurrentSolution; foreach (var document in workspace.Documents) { if (document.IsSourceGenerated) { continue; } solution = solution.WithDocumentFilePath(document.Id, "C:\\" + document.Name); var documentText = await solution.GetRequiredDocument(document.Id).GetTextAsync(CancellationToken.None); solution = solution.WithDocumentText(document.Id, SourceText.From(documentText.ToString(), System.Text.Encoding.UTF8)); } foreach (var project in workspace.Projects) { // Ensure all the projects have a valid file path. solution = solution.WithProjectFilePath(project.Id, "C:\\" + project.Name); } solution = solution.WithAnalyzerReferences(new[] { new TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap()) }); workspace.ChangeSolution(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(); return(await TestLspServer.CreateAsync(workspace, initializationOptions)); }
public async Task Proxy(TestHost testHost) { var localComposition = EditorTestCompositions.EditorFeatures.WithTestHostParts(testHost); if (testHost == TestHost.InProcess) { localComposition = localComposition.AddParts(typeof(MockEncServiceFactory)); } using var localWorkspace = new TestWorkspace(composition: localComposition); MockEditAndContinueWorkspaceService mockEncService; var clientProvider = (InProcRemoteHostClientProvider?)localWorkspace.Services.GetService <IRemoteHostClientProvider>(); if (testHost == TestHost.InProcess) { Assert.Null(clientProvider); mockEncService = (MockEditAndContinueWorkspaceService)localWorkspace.Services.GetRequiredService <IEditAndContinueWorkspaceService>(); } else { Assert.NotNull(clientProvider); clientProvider !.AdditionalRemoteParts = new[] { typeof(MockEncServiceFactory) }; var client = await InProcRemoteHostClient.GetTestClientAsync(localWorkspace).ConfigureAwait(false); var remoteWorkspace = client.TestData.WorkspaceManager.GetWorkspace(); mockEncService = (MockEditAndContinueWorkspaceService)remoteWorkspace.Services.GetRequiredService <IEditAndContinueWorkspaceService>(); } localWorkspace.ChangeSolution(localWorkspace.CurrentSolution. AddProject("proj", "proj", LanguageNames.CSharp). AddMetadataReferences(TargetFrameworkUtil.GetReferences(TargetFramework.Mscorlib40)). AddDocument("test.cs", SourceText.From("class C { }", Encoding.UTF8), filePath: "test.cs").Project.Solution); var solution = localWorkspace.CurrentSolution; var project = solution.Projects.Single(); var document = project.Documents.Single(); var mockDiagnosticService = new MockDiagnosticAnalyzerService(); void VerifyReanalyzeInvocation(ImmutableArray <DocumentId> documentIds) { AssertEx.Equal(documentIds, mockDiagnosticService.DocumentsToReanalyze); mockDiagnosticService.DocumentsToReanalyze.Clear(); } var diagnosticUpdateSource = new EditAndContinueDiagnosticUpdateSource(); var emitDiagnosticsUpdated = new List <DiagnosticsUpdatedArgs>(); var emitDiagnosticsClearedCount = 0; diagnosticUpdateSource.DiagnosticsUpdated += (object sender, DiagnosticsUpdatedArgs args) => emitDiagnosticsUpdated.Add(args); diagnosticUpdateSource.DiagnosticsCleared += (object sender, EventArgs args) => emitDiagnosticsClearedCount++; var span1 = new LinePositionSpan(new LinePosition(1, 2), new LinePosition(1, 5)); var moduleId1 = new Guid("{44444444-1111-1111-1111-111111111111}"); var methodId1 = new ManagedMethodId(moduleId1, token: 0x06000003, version: 2); var instructionId1 = new ManagedInstructionId(methodId1, ilOffset: 10); var as1 = new ManagedActiveStatementDebugInfo( instructionId1, documentName: "test.cs", span1.ToSourceSpan(), flags: ActiveStatementFlags.IsLeafFrame | ActiveStatementFlags.PartiallyExecuted); var methodId2 = new ManagedModuleMethodId(token: 0x06000002, version: 1); var exceptionRegionUpdate1 = new ManagedExceptionRegionUpdate( methodId2, delta: 1, newSpan: new SourceSpan(1, 2, 1, 5)); var document1 = localWorkspace.CurrentSolution.Projects.Single().Documents.Single(); var activeSpans1 = ImmutableArray.Create( new ActiveStatementSpan(0, new LinePositionSpan(new LinePosition(1, 2), new LinePosition(3, 4)), ActiveStatementFlags.IsNonLeafFrame, document.Id)); var activeStatementSpanProvider = new ActiveStatementSpanProvider((documentId, path, cancellationToken) => { Assert.Equal(document1.Id, documentId); Assert.Equal("test.cs", path); return(new(activeSpans1)); }); var proxy = new RemoteEditAndContinueServiceProxy(localWorkspace); // StartDebuggingSession IManagedEditAndContinueDebuggerService?remoteDebuggeeModuleMetadataProvider = null; var debuggingSession = mockEncService.StartDebuggingSessionImpl = (solution, debuggerService, captureMatchingDocuments, captureAllMatchingDocuments, reportDiagnostics) => { Assert.Equal("proj", solution.Projects.Single().Name); AssertEx.Equal(new[] { document1.Id }, captureMatchingDocuments); Assert.False(captureAllMatchingDocuments); Assert.True(reportDiagnostics); remoteDebuggeeModuleMetadataProvider = debuggerService; return(new DebuggingSessionId(1)); }; var sessionProxy = await proxy.StartDebuggingSessionAsync( localWorkspace.CurrentSolution, debuggerService : new MockManagedEditAndContinueDebuggerService() { IsEditAndContinueAvailable = _ => new ManagedEditAndContinueAvailability(ManagedEditAndContinueAvailabilityStatus.NotAllowedForModule, "can't do enc"), GetActiveStatementsImpl = () => ImmutableArray.Create(as1) }, captureMatchingDocuments : ImmutableArray.Create(document1.Id), captureAllMatchingDocuments : false, reportDiagnostics : true, CancellationToken.None).ConfigureAwait(false); Contract.ThrowIfNull(sessionProxy); // BreakStateEntered mockEncService.BreakStateEnteredImpl = (out ImmutableArray <DocumentId> documentsToReanalyze) => { documentsToReanalyze = ImmutableArray.Create(document.Id); }; await sessionProxy.BreakStateEnteredAsync(mockDiagnosticService, CancellationToken.None).ConfigureAwait(false); VerifyReanalyzeInvocation(ImmutableArray.Create(document.Id)); var activeStatement = (await remoteDebuggeeModuleMetadataProvider !.GetActiveStatementsAsync(CancellationToken.None).ConfigureAwait(false)).Single(); Assert.Equal(as1.ActiveInstruction, activeStatement.ActiveInstruction); Assert.Equal(as1.SourceSpan, activeStatement.SourceSpan); Assert.Equal(as1.Flags, activeStatement.Flags); var availability = await remoteDebuggeeModuleMetadataProvider !.GetAvailabilityAsync(moduleId1, CancellationToken.None).ConfigureAwait(false); Assert.Equal(new ManagedEditAndContinueAvailability(ManagedEditAndContinueAvailabilityStatus.NotAllowedForModule, "can't do enc"), availability); // HasChanges mockEncService.HasChangesImpl = (solution, activeStatementSpanProvider, sourceFilePath) => { Assert.Equal("proj", solution.Projects.Single().Name); Assert.Equal("test.cs", sourceFilePath); AssertEx.Equal(activeSpans1, activeStatementSpanProvider(document1.Id, "test.cs", CancellationToken.None).AsTask().Result); return(true); }; Assert.True(await sessionProxy.HasChangesAsync(localWorkspace.CurrentSolution, activeStatementSpanProvider, "test.cs", CancellationToken.None).ConfigureAwait(false)); // EmitSolutionUpdate var diagnosticDescriptor1 = EditAndContinueDiagnosticDescriptors.GetDescriptor(EditAndContinueErrorCode.ErrorReadingFile); mockEncService.EmitSolutionUpdateImpl = (solution, activeStatementSpanProvider) => { var project = solution.Projects.Single(); Assert.Equal("proj", project.Name); AssertEx.Equal(activeSpans1, activeStatementSpanProvider(document1.Id, "test.cs", CancellationToken.None).AsTask().Result); var deltas = ImmutableArray.Create(new ManagedModuleUpdate( module: moduleId1, ilDelta: ImmutableArray.Create <byte>(1, 2), metadataDelta: ImmutableArray.Create <byte>(3, 4), pdbDelta: ImmutableArray.Create <byte>(5, 6), updatedMethods: ImmutableArray.Create(0x06000001), updatedTypes: ImmutableArray.Create(0x02000001), sequencePoints: ImmutableArray.Create(new SequencePointUpdates("file.cs", ImmutableArray.Create(new SourceLineUpdate(1, 2)))), activeStatements: ImmutableArray.Create(new ManagedActiveStatementUpdate(instructionId1.Method.Method, instructionId1.ILOffset, span1.ToSourceSpan())), exceptionRegions: ImmutableArray.Create(exceptionRegionUpdate1))); var syntaxTree = project.Documents.Single().GetSyntaxTreeSynchronously(CancellationToken.None) !; var documentDiagnostic = Diagnostic.Create(diagnosticDescriptor1, Location.Create(syntaxTree, TextSpan.FromBounds(1, 2)), new[] { "doc", "some error" }); var projectDiagnostic = Diagnostic.Create(diagnosticDescriptor1, Location.None, new[] { "proj", "some error" }); var updates = new ManagedModuleUpdates(ManagedModuleUpdateStatus.Ready, deltas); var diagnostics = ImmutableArray.Create((project.Id, ImmutableArray.Create(documentDiagnostic, projectDiagnostic))); var documentsWithRudeEdits = ImmutableArray.Create((document1.Id, ImmutableArray <RudeEditDiagnostic> .Empty)); return(new(updates, diagnostics, documentsWithRudeEdits)); }; var(updates, _, _) = await sessionProxy.EmitSolutionUpdateAsync(localWorkspace.CurrentSolution, activeStatementSpanProvider, mockDiagnosticService, diagnosticUpdateSource, CancellationToken.None).ConfigureAwait(false); VerifyReanalyzeInvocation(ImmutableArray.Create(document1.Id)); Assert.Equal(ManagedModuleUpdateStatus.Ready, updates.Status); Assert.Equal(1, emitDiagnosticsClearedCount); emitDiagnosticsClearedCount = 0; AssertEx.Equal(new[] { $"[{project.Id}] Error ENC1001: test.cs(0, 1, 0, 2): {string.Format(FeaturesResources.ErrorReadingFile, "doc", "some error")}", $"[{project.Id}] Error ENC1001: {string.Format(FeaturesResources.ErrorReadingFile, "proj", "some error")}" }, emitDiagnosticsUpdated.Select(update => { var d = update.GetPushDiagnostics(localWorkspace, InternalDiagnosticsOptions.NormalDiagnosticMode).Single(); return($"[{d.ProjectId}] {d.Severity} {d.Id}:" + (d.DataLocation != null ? $" {d.DataLocation.OriginalFilePath}({d.DataLocation.OriginalStartLine}, {d.DataLocation.OriginalStartColumn}, {d.DataLocation.OriginalEndLine}, {d.DataLocation.OriginalEndColumn}):" : "") + $" {d.Message}"); })); emitDiagnosticsUpdated.Clear(); var delta = updates.Updates.Single(); Assert.Equal(moduleId1, delta.Module); AssertEx.Equal(new byte[] { 1, 2 }, delta.ILDelta); AssertEx.Equal(new byte[] { 3, 4 }, delta.MetadataDelta); AssertEx.Equal(new byte[] { 5, 6 }, delta.PdbDelta); AssertEx.Equal(new[] { 0x06000001 }, delta.UpdatedMethods); AssertEx.Equal(new[] { 0x02000001 }, delta.UpdatedTypes); var lineEdit = delta.SequencePoints.Single(); Assert.Equal("file.cs", lineEdit.FileName); AssertEx.Equal(new[] { new SourceLineUpdate(1, 2) }, lineEdit.LineUpdates); Assert.Equal(exceptionRegionUpdate1, delta.ExceptionRegions.Single()); var activeStatements = delta.ActiveStatements.Single(); Assert.Equal(instructionId1.Method.Method, activeStatements.Method); Assert.Equal(instructionId1.ILOffset, activeStatements.ILOffset); Assert.Equal(span1, activeStatements.NewSpan.ToLinePositionSpan()); // CommitSolutionUpdate mockEncService.CommitSolutionUpdateImpl = (out ImmutableArray <DocumentId> documentsToReanalyze) => { documentsToReanalyze = ImmutableArray.Create(document.Id); }; await sessionProxy.CommitSolutionUpdateAsync(mockDiagnosticService, CancellationToken.None).ConfigureAwait(false); VerifyReanalyzeInvocation(ImmutableArray.Create(document.Id)); // DiscardSolutionUpdate var called = false; mockEncService.DiscardSolutionUpdateImpl = () => called = true; await sessionProxy.DiscardSolutionUpdateAsync(CancellationToken.None).ConfigureAwait(false); Assert.True(called); // GetCurrentActiveStatementPosition mockEncService.GetCurrentActiveStatementPositionImpl = (solution, activeStatementSpanProvider, instructionId) => { Assert.Equal("proj", solution.Projects.Single().Name); Assert.Equal(instructionId1, instructionId); AssertEx.Equal(activeSpans1, activeStatementSpanProvider(document1.Id, "test.cs", CancellationToken.None).AsTask().Result); return(new LinePositionSpan(new LinePosition(1, 2), new LinePosition(1, 5))); }; Assert.Equal(span1, await sessionProxy.GetCurrentActiveStatementPositionAsync( localWorkspace.CurrentSolution, activeStatementSpanProvider, instructionId1, CancellationToken.None).ConfigureAwait(false)); // IsActiveStatementInExceptionRegion mockEncService.IsActiveStatementInExceptionRegionImpl = (solution, instructionId) => { Assert.Equal(instructionId1, instructionId); return(true); }; Assert.True(await sessionProxy.IsActiveStatementInExceptionRegionAsync(localWorkspace.CurrentSolution, instructionId1, CancellationToken.None).ConfigureAwait(false)); // GetBaseActiveStatementSpans var activeStatementSpan1 = new ActiveStatementSpan(0, span1, ActiveStatementFlags.IsNonLeafFrame | ActiveStatementFlags.PartiallyExecuted, unmappedDocumentId: document1.Id); mockEncService.GetBaseActiveStatementSpansImpl = (solution, documentIds) => { AssertEx.Equal(new[] { document1.Id }, documentIds); return(ImmutableArray.Create(ImmutableArray.Create(activeStatementSpan1))); }; var baseActiveSpans = await sessionProxy.GetBaseActiveStatementSpansAsync(localWorkspace.CurrentSolution, ImmutableArray.Create(document1.Id), CancellationToken.None).ConfigureAwait(false); Assert.Equal(activeStatementSpan1, baseActiveSpans.Single().Single()); // GetDocumentActiveStatementSpans mockEncService.GetAdjustedActiveStatementSpansImpl = (document, activeStatementSpanProvider) => { Assert.Equal("test.cs", document.Name); AssertEx.Equal(activeSpans1, activeStatementSpanProvider(document.Id, "test.cs", CancellationToken.None).AsTask().Result); return(ImmutableArray.Create(activeStatementSpan1)); }; var documentActiveSpans = await sessionProxy.GetAdjustedActiveStatementSpansAsync(document1, activeStatementSpanProvider, CancellationToken.None).ConfigureAwait(false); Assert.Equal(activeStatementSpan1, documentActiveSpans.Single()); // GetDocumentActiveStatementSpans (default array) mockEncService.GetAdjustedActiveStatementSpansImpl = (document, _) => default; documentActiveSpans = await sessionProxy.GetAdjustedActiveStatementSpansAsync(document1, activeStatementSpanProvider, CancellationToken.None).ConfigureAwait(false); Assert.True(documentActiveSpans.IsDefault); // OnSourceFileUpdatedAsync called = false; mockEncService.OnSourceFileUpdatedImpl = updatedDocument => { Assert.Equal(document.Id, updatedDocument.Id); called = true; }; await proxy.OnSourceFileUpdatedAsync(document, CancellationToken.None).ConfigureAwait(false); Assert.True(called); // EndDebuggingSession mockEncService.EndDebuggingSessionImpl = (out ImmutableArray <DocumentId> documentsToReanalyze) => { documentsToReanalyze = ImmutableArray.Create(document.Id); }; await sessionProxy.EndDebuggingSessionAsync(solution, diagnosticUpdateSource, mockDiagnosticService, CancellationToken.None).ConfigureAwait(false); VerifyReanalyzeInvocation(ImmutableArray.Create(document.Id)); Assert.Equal(1, emitDiagnosticsClearedCount); emitDiagnosticsClearedCount = 0; Assert.Empty(emitDiagnosticsUpdated); }