public async Task DidChange_MultipleChanges() { var source = @"class A { void M() { {|type:|} } }"; var expected = @"class A { void M() { // hi there // this builds on that } }"; var(testLspServer, locationTyped, documentText) = await GetTestLspServerAndLocationAsync(source); using (testLspServer) { await DidOpen(testLspServer, CreateDidOpenTextDocumentParams(locationTyped, documentText)); await DidChange(testLspServer, CreateDidChangeTextDocumentParams(locationTyped.Uri, (4, 8, "// hi there"), (5, 0, " // this builds on that\r\n"))); var document = testLspServer.GetQueueAccessor().GetTrackedTexts().FirstOrDefault(); Assert.NotNull(document); Assert.Equal(expected, document.ToString()); } }
public async Task DidChange_AppliesChanges() { var source = @"class A { void M() { {|type:|} } }"; var expected = @"class A { void M() { // hi there } }"; var(workspace, locationTyped, documentText) = await GetWorkspaceAndLocationAsync(source); using (workspace) { var queue = CreateRequestQueue(workspace.CurrentSolution); await DidOpen(queue, workspace.CurrentSolution, CreateDidOpenTextDocumentParams(locationTyped, documentText)); await DidChange(queue, workspace.CurrentSolution, CreateDidChangeTextDocumentParams(locationTyped.Uri, (4, 8, "// hi there"))); var document = queue.GetTestAccessor().GetTrackedTexts().FirstOrDefault(); Assert.NotNull(document); Assert.Equal(expected, document.ToString()); } }
public async Task DidChangeWithoutDidOpen_Errors() { var source = @"class A { void M() { {|type:|} } }"; var(testLspServer, locationTyped, documentText) = await GetTestLspServerAndLocationAsync(source); using (testLspServer) { await Assert.ThrowsAsync <InvalidOperationException>( () => DidChange( testLspServer, CreateDidChangeTextDocumentParams(locationTyped.Uri, (0, 0, "goo")) ) ); } }
public async Task LinkedDocuments_AllTextChanged() { var workspaceXml = @"<Workspace> <Project Language=""C#"" CommonReferences=""true"" AssemblyName=""CSProj1""> <Document FilePath=""C:\C.cs"">{|caret:|}</Document> </Project> <Project Language=""C#"" CommonReferences=""true"" AssemblyName=""CSProj2""> <Document IsLinkFile=""true"" LinkFilePath=""C:\C.cs"" LinkAssemblyName=""CSProj1""></Document> </Project> </Workspace>"; using var testLspServer = CreateXmlTestLspServer(workspaceXml, out var locations); var caretLocation = locations["caret"].Single(); var initialText = @"class A { void M() { } }"; var updatedText = @"class A { void M() { // hi there } }"; await DidOpen( testLspServer, CreateDidOpenTextDocumentParams(caretLocation, initialText) ); Assert.Equal(1, testLspServer.GetQueueAccessor().GetTrackedTexts().Count); await DidChange( testLspServer, CreateDidChangeTextDocumentParams(caretLocation.Uri, (4, 8, "// hi there")) ); var solution = await GetLSPSolution(testLspServer, caretLocation.Uri); foreach (var document in solution.Projects.First().Documents) { Assert.Equal( updatedText, document.GetTextSynchronously(CancellationToken.None).ToString() ); } await DidClose(testLspServer, CreateDidCloseTextDocumentParams(caretLocation)); Assert.Empty(testLspServer.GetQueueAccessor().GetTrackedTexts()); }
public async Task DidChange_DoesntUpdateWorkspace() { var source = @"class A { void M() { {|type:|} } }"; var expected = @"class A { void M() { // hi there } }"; var(testLspServer, locationTyped, documentText) = await GetTestLspServerAndLocationAsync(source); using (testLspServer) { await DidOpen( testLspServer, CreateDidOpenTextDocumentParams(locationTyped, documentText) ); await DidChange( testLspServer, CreateDidChangeTextDocumentParams(locationTyped.Uri, (4, 8, "// hi there")) ); var documentTextFromWorkspace = ( await testLspServer .GetCurrentSolution() .GetDocuments(locationTyped.Uri) .Single() .GetTextAsync() ).ToString(); Assert.NotNull(documentTextFromWorkspace); Assert.Equal(documentText, documentTextFromWorkspace); // Just to ensure this test breaks if didChange stops working for some reason Assert.NotEqual(expected, documentTextFromWorkspace); } }
public async Task DocumentChanges_EndToEnd() { var source = @"class A { void M() { {|type:|} } }"; var expected = @"class A { void M() { // hi there } }"; var(testLspServer, locationTyped, documentText) = await GetTestLspServerAndLocationAsync(source); using (testLspServer) { Assert.Empty(testLspServer.GetQueueAccessor().GetTrackedTexts()); await DidOpen( testLspServer, CreateDidOpenTextDocumentParams(locationTyped, documentText) ); Assert.Single(testLspServer.GetQueueAccessor().GetTrackedTexts()); var document = testLspServer.GetQueueAccessor().GetTrackedTexts().Single(); Assert.Equal(documentText, document.ToString()); await DidChange( testLspServer, CreateDidChangeTextDocumentParams(locationTyped.Uri, (4, 8, "// hi there")) ); document = testLspServer.GetQueueAccessor().GetTrackedTexts().Single(); Assert.Equal(expected, document.ToString()); await DidClose(testLspServer, CreateDidCloseTextDocumentParams(locationTyped)); Assert.Empty(testLspServer.GetQueueAccessor().GetTrackedTexts()); } }
public async Task FindReferencesInChangingDocument() { var source = @"class A { public int {|type:|}someInt = 1; void M() { } } class B { void M2() { } }"; var(testLspServer, locationTyped, documentText) = await GetTestLspServerAndLocationAsync(source); using (testLspServer) { Assert.Empty(testLspServer.GetQueueAccessor().GetTrackedTexts()); await DidOpen(testLspServer, CreateDidOpenTextDocumentParams(locationTyped, documentText)); var findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync(testLspServer, locationTyped); Assert.Single(findResults); Assert.Equal("A", findResults[0].ContainingType); // Declare a local inside A.M() await DidChange(testLspServer, CreateDidChangeTextDocumentParams(locationTyped.Uri, (5, 0, "var i = someInt + 1;\r\n"))); findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync(testLspServer, locationTyped); Assert.Equal(2, findResults.Length); Assert.Equal("A", findResults[0].ContainingType); Assert.Equal("M", findResults[1].ContainingMember); // Declare a field in B await DidChange(testLspServer, CreateDidChangeTextDocumentParams(locationTyped.Uri, (10, 0, "int someInt = A.someInt + 1;\r\n"))); findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync(testLspServer, locationTyped); Assert.Equal(3, findResults.Length); Assert.Equal("A", findResults[0].ContainingType); Assert.Equal("B", findResults[2].ContainingType); Assert.Equal("M", findResults[1].ContainingMember); // Declare a local inside B.M2() await DidChange(testLspServer, CreateDidChangeTextDocumentParams(locationTyped.Uri, (13, 0, "var j = someInt + A.someInt;\r\n"))); findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync(testLspServer, locationTyped); Assert.Equal(4, findResults.Length); Assert.Equal("A", findResults[0].ContainingType); Assert.Equal("B", findResults[2].ContainingType); Assert.Equal("M", findResults[1].ContainingMember); Assert.Equal("M2", findResults[3].ContainingMember); // NOTE: This is not a real world scenario // By closing the document we revert back to the original state, but in the real world // the original state will have been updated by back channels (text buffer sync, file changed on disk, etc.) // This is validating that the above didn't succeed by any means except the FAR handler being passed // the updated document, so if we regress and get lucky, we still know about it. await DidClose(testLspServer, CreateDidCloseTextDocumentParams(locationTyped)); findResults = await FindAllReferencesHandlerTests.RunFindAllReferencesAsync(testLspServer, locationTyped); Assert.Single(findResults); Assert.Equal("A", findResults[0].ContainingType); } }
public async Task DidChangeWithoutDidOpen_Errors() { var source = @"class A { void M() { {|type:|} } }"; var(workspace, locationTyped, documentText) = await GetWorkspaceAndLocationAsync(source); using (workspace) { var queue = CreateRequestQueue(workspace.CurrentSolution); await Assert.ThrowsAsync <InvalidOperationException>(() => DidChange(queue, workspace.CurrentSolution, CreateDidChangeTextDocumentParams(locationTyped.Uri, (0, 0, "goo")))); } }