/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/EditorFeatures/TestUtilities2/Intellisense/TestState.vb
731 строка
38 KB
Cyrus Najmabadi
Organize VB imports
27 июн 2025, 21:53
27 июн 2025, 21:53
e9c47fd
Код
Авторство
О чём код?
' 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. Imports System.Collections.Immutable Imports System.Threading Imports Microsoft.CodeAnalysis.Collections Imports Microsoft.CodeAnalysis.Completion Imports Microsoft.CodeAnalysis.Editor.CommandHandlers Imports Microsoft.CodeAnalysis.Editor.CSharp.CompleteStatement Imports Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.AsyncCompletion Imports Microsoft.CodeAnalysis.Editor.[Shared].Utilities Imports Microsoft.CodeAnalysis.Editor.UnitTests.Extensions Imports Microsoft.CodeAnalysis.Editor.UnitTests.Utilities Imports Microsoft.CodeAnalysis.ErrorReporting Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.LanguageService Imports Microsoft.CodeAnalysis.Shared.TestHooks Imports Microsoft.CodeAnalysis.SignatureHelp Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.Commanding Imports Microsoft.VisualStudio.Language.Intellisense Imports Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion Imports Microsoft.VisualStudio.Text Imports Microsoft.VisualStudio.Text.Editor Imports Microsoft.VisualStudio.Text.Editor.Commanding.Commands Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense Friend Class TestState Inherits AbstractCommandHandlerTestState Private Const timeoutMs = 60000 Friend ReadOnly EditorCompletionCommandHandler As ICommandHandler Friend ReadOnly CompletionPresenterProvider As ICompletionPresenterProvider Protected ReadOnly SessionTestState As IIntelliSenseTestState Private ReadOnly SignatureHelpBeforeCompletionCommandHandler As SignatureHelpBeforeCompletionCommandHandler Protected ReadOnly CompleteStatementCommandHandler As CompleteStatementCommandHandler Private ReadOnly FormatCommandHandler As FormatCommandHandler Public Shared ReadOnly CompositionWithoutCompletionTestParts As TestComposition = EditorTestCompositions.EditorFeatures. AddExcludedPartTypes( GetType(IIntelliSensePresenter(Of ISignatureHelpPresenterSession, ISignatureHelpSession)), GetType(FormatCommandHandler)). AddParts( GetType(TestSignatureHelpPresenter), GetType(IntelliSenseTestState), GetType(MockCompletionPresenterProvider)) Friend ReadOnly Property CurrentSignatureHelpPresenterSession As TestSignatureHelpPresenterSession Get Return SessionTestState.CurrentSignatureHelpPresenterSession End Get End Property ' Do not call directly. Use TestStateFactory Friend Sub New(workspaceElement As XElement, excludedTypes As IEnumerable(Of Type), extraExportedTypes As IEnumerable(Of Type), includeFormatCommandHandler As Boolean, workspaceKind As String, Optional makeSeparateBufferForCursor As Boolean = False, Optional roles As ImmutableArray(Of String) = Nothing) MyBase.New(workspaceElement, GetComposition(excludedTypes, extraExportedTypes, includeFormatCommandHandler), workspaceKind:=workspaceKind, makeSeparateBufferForCursor, roles) ' Disable editor's responsive completion option to ensure a deterministic test behavior MyBase.TextView.Options.GlobalOptions.SetOptionValue(DefaultOptions.ResponsiveCompletionOptionId, False) MyBase.TextView.Options.GlobalOptions.SetOptionValue(DefaultOptions.IndentStyleId, IndentingStyle.Smart) Dim language = Me.Workspace.CurrentSolution.Projects.First().Language Me.SessionTestState = GetExportedValue(Of IIntelliSenseTestState)() Me.SignatureHelpBeforeCompletionCommandHandler = GetExportedValue(Of SignatureHelpBeforeCompletionCommandHandler)() Me.CompleteStatementCommandHandler = GetExportedValue(Of CompleteStatementCommandHandler)() Me.FormatCommandHandler = If(includeFormatCommandHandler, GetExportedValue(Of FormatCommandHandler)(), Nothing) Me.CompleteStatementCommandHandler = Workspace.ExportProvider.GetCommandHandler(Of CompleteStatementCommandHandler)(NameOf(CompleteStatementCommandHandler)) CompletionPresenterProvider = GetExportedValues(Of ICompletionPresenterProvider)(). Single(Function(e As ICompletionPresenterProvider) e.GetType().FullName = "Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense.MockCompletionPresenterProvider") EditorCompletionCommandHandler = GetExportedValues(Of ICommandHandler)(). Single(Function(e As ICommandHandler) e.GetType().Name = PredefinedCompletionNames.CompletionCommandHandler) End Sub Private Overloads Shared Function GetComposition( excludedTypes As IEnumerable(Of Type), extraExportedTypes As IEnumerable(Of Type), includeFormatCommandHandler As Boolean) As TestComposition Dim composition = CompositionWithoutCompletionTestParts. AddExcludedPartTypes(excludedTypes). AddParts(extraExportedTypes) If includeFormatCommandHandler Then ' FormatCommandHandler would generally be included in the catalog, but is excluded from tests by adding ' it to the list of excluded part types. Here we validate the input state and restore the default ' behavior of the catalog by removing FormatCommandHandler from the excluded parts list. Assert.Contains(GetType(FormatCommandHandler).Assembly, composition.Assemblies) Assert.Contains(GetType(FormatCommandHandler), composition.ExcludedPartTypes) composition = composition.RemoveExcludedPartTypes(GetType(FormatCommandHandler)) End If Return composition End Function #Region "Editor Related Operations" Protected Overloads Sub ExecuteTypeCharCommand(args As TypeCharCommandArgs, finalHandler As Action, context As CommandExecutionContext, completionCommandHandler As IChainedCommandHandler(Of TypeCharCommandArgs)) Dim sigHelpHandler = DirectCast(SignatureHelpBeforeCompletionCommandHandler, IChainedCommandHandler(Of TypeCharCommandArgs)) Dim formatHandler = DirectCast(FormatCommandHandler, IChainedCommandHandler(Of TypeCharCommandArgs)) If formatHandler Is Nothing Then sigHelpHandler.ExecuteCommand( args, Sub() completionCommandHandler.ExecuteCommand( args, Sub() CompleteStatementCommandHandler.ExecuteCommand(args, finalHandler, context), context), context) Else formatHandler.ExecuteCommand( args, Sub() sigHelpHandler.ExecuteCommand( args, Sub() completionCommandHandler.ExecuteCommand( args, Sub() CompleteStatementCommandHandler.ExecuteCommand(args, finalHandler, context), context), context), context) End If End Sub Public Overloads Sub SendTab() Dim handler = GetHandler(Of IChainedCommandHandler(Of TabKeyCommandArgs))() MyBase.SendTab(Sub(a, n, c) handler.ExecuteCommand(a, n, c), Sub() EditorOperations.InsertText(vbTab)) End Sub Public Overloads Sub SendReturn() Dim handler = GetHandler(Of IChainedCommandHandler(Of ReturnKeyCommandArgs))() MyBase.SendReturn(Sub(a, n, c) handler.ExecuteCommand(a, n, c), Sub() EditorOperations.InsertNewLine()) End Sub Public Sub SendBackspaces(count As Integer) For i = 0 To count - 1 Me.SendBackspace() Next End Sub Public Overrides Sub SendBackspace() Dim compHandler = GetHandler(Of IChainedCommandHandler(Of BackspaceKeyCommandArgs))() MyBase.SendBackspace(Sub(a, n, c) compHandler.ExecuteCommand(a, n, c), AddressOf MyBase.SendBackspace) End Sub Public Overrides Sub SendDelete() Dim compHandler = GetHandler(Of IChainedCommandHandler(Of DeleteKeyCommandArgs))() MyBase.SendDelete(Sub(a, n, c) compHandler.ExecuteCommand(a, n, c), AddressOf MyBase.SendDelete) End Sub Public Sub SendDeleteToSpecificViewAndBuffer(view As IWpfTextView, buffer As ITextBuffer) Dim compHandler = GetHandler(Of IChainedCommandHandler(Of DeleteKeyCommandArgs))() compHandler.ExecuteCommand(New DeleteKeyCommandArgs(view, buffer), AddressOf MyBase.SendDelete, TestCommandExecutionContext.Create()) End Sub Private Overloads Sub ExecuteTypeCharCommand(args As TypeCharCommandArgs, finalHandler As Action, context As CommandExecutionContext) Dim compHandler = GetHandler(Of IChainedCommandHandler(Of TypeCharCommandArgs))() ExecuteTypeCharCommand(args, finalHandler, context, compHandler) End Sub Public Overloads Sub SendTypeChars(typeChars As String) MyBase.SendTypeChars(typeChars, Sub(a, n, c) ExecuteTypeCharCommand(a, n, c)) End Sub Public Async Function SendTypeCharsAndWaitForUiRenderAsync(typeChars As String) As Task Dim uiRender = WaitForUIRenderedAsync() SendTypeChars(typeChars) Await uiRender End Function Public Overloads Sub SendEscape() MyBase.SendEscape(Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, Sub() Me.CurrentSignatureHelpPresenterSession?.Dismiss(), c), Sub() Return) End Sub Public Overloads Sub SendDownKey() MyBase.SendDownKey( Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, Sub() EditorOperations.MoveLineDown(extendSelection:=False), c), Sub() EditorOperations.MoveLineDown(extendSelection:=False)) End Sub Public Overloads Sub SendUpKey() MyBase.SendUpKey( Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, Sub() EditorOperations.MoveLineUp(extendSelection:=False), c), Sub() EditorOperations.MoveLineUp(extendSelection:=False)) End Sub Public Overloads Sub SendPageUp() Dim handler = DirectCast(EditorCompletionCommandHandler, ICommandHandler(Of PageUpKeyCommandArgs)) MyBase.SendPageUp(Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, n, c), Sub() Return) End Sub Public Overloads Sub SendCut() MyBase.SendCut(Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, n, c), Sub() Return) End Sub Public Overloads Sub SendPaste() MyBase.SendPaste(Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, n, c), Sub() Return) End Sub Public Overloads Sub SendInvokeCompletionList() MyBase.SendInvokeCompletionList(Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, n, c), Sub() Return) End Sub Public Async Function SendInvokeCompletionListAndWaitForUiRenderAsync() As Task Dim uiRender = WaitForUIRenderedAsync() MyBase.SendInvokeCompletionList(Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, n, c), Sub() Return) Await uiRender End Function Public Overloads Sub SendInsertSnippetCommand() MyBase.SendInsertSnippetCommand(Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, n, c), Sub() Return) End Sub Public Overloads Sub SendSurroundWithCommand() MyBase.SendSurroundWithCommand(Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, n, c), Sub() Return) End Sub Public Overloads Sub SendSave() MyBase.SendSave(Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, n, c), Sub() Return) End Sub Public Overloads Sub SendSelectAll() MyBase.SendSelectAll(Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, n, c), Sub() Return) End Sub Public Overrides Sub SendDeleteWordToLeft() Dim compHandler = DirectCast(EditorCompletionCommandHandler, ICommandHandler(Of WordDeleteToStartCommandArgs)) MyBase.SendWordDeleteToStart(Sub(a, n, c) compHandler.ExecuteCommand(a, n, c), AddressOf MyBase.SendDeleteWordToLeft) End Sub Public Overloads Sub SendToggleCompletionMode() Dim handler = DirectCast(EditorCompletionCommandHandler, ICommandHandler(Of ToggleCompletionModeCommandArgs)) MyBase.SendToggleCompletionMode(Sub(a, n, c) handler.ExecuteCommand(a, n, c), Sub() Return) End Sub Protected Function GetHandler(Of T As ICommandHandler)() As T Return DirectCast(EditorCompletionCommandHandler, T) End Function #End Region #Region "Completion Operations" Public Async Function SendCommitUniqueCompletionListItemAsync() As Task Await WaitForAsynchronousOperationsAsync() ' When we send the commit completion list item, it processes asynchronously; we can find out when it's complete ' by seeing that either the items are updated or the list is dismissed. We'll use a TaskCompletionSource to track ' when it's done which will release an async token. Dim sessionComplete = New TaskCompletionSource(Of Object)() Dim asynchronousOperationListenerProvider = Workspace.ExportProvider.GetExportedValue(Of AsynchronousOperationListenerProvider)() Dim asyncToken = asynchronousOperationListenerProvider.GetListener(FeatureAttribute.CompletionSet) _ .BeginAsyncOperation(NameOf(SendCommitUniqueCompletionListItemAsync)) #Disable Warning BC42358 ' Because this call is not awaited, execution of the current method continues before the call is completed sessionComplete.Task.CompletesAsyncOperation(asyncToken) Dim waitingForUI = WaitForUIRenderedAsync() #Enable Warning BC42358 ' Because this call is not awaited, execution of the current method continues before the call is completed Dim itemsUpdatedHandler = Sub(sender As Object, e As Data.ComputedCompletionItemsEventArgs) ' If there is 0 or more than one item left, then it means this was the filter operation that resulted and we're done. ' Otherwise we know a Dismiss operation is coming so we should wait for it. If e.Items.Items.Count() <> 1 Then Dim threadingContext = Workspace.ExportProvider.GetExportedValue(Of IThreadingContext)() ' Set up a timeout path to make sure tests don't deadlock Dim asyncToken2 = asynchronousOperationListenerProvider.GetListener(FeatureAttribute.CompletionSet) _ .BeginAsyncOperation(NameOf(SendCommitUniqueCompletionListItemAsync)) Task.Run( Async Function() As Task Using cancellationSource = CancellationTokenSource.CreateLinkedTokenSource(threadingContext.DisposalToken) Await Task.WhenAny(sessionComplete.Task, Task.Delay(TimeSpan.FromSeconds(2), cancellationSource.Token)) If sessionComplete.TrySetException(New TimeoutException()) Then Throw New TimeoutException() End If End Using End Function).CompletesAsyncOperation(asyncToken2).ReportNonFatalErrorUnlessCancelledAsync(threadingContext.DisposalToken) ' Now set up the expected path of just waiting for the UI to complete rendering threadingContext.JoinableTaskFactory.RunAsync( Async Function() As Task Await waitingForUI sessionComplete.SetResult(Nothing) End Function) End If End Sub Dim sessionDismissedHandler = Sub(sender As Object, e As EventArgs) sessionComplete.TrySetResult(Nothing) Dim session As IAsyncCompletionSession Dim addHandlers = Sub(sender As Object, e As Data.CompletionTriggeredEventArgs) AddHandler e.CompletionSession.ItemsUpdated, itemsUpdatedHandler AddHandler e.CompletionSession.Dismissed, sessionDismissedHandler session = e.CompletionSession End Sub Dim asyncCompletionBroker As IAsyncCompletionBroker = GetExportedValue(Of IAsyncCompletionBroker)() session = asyncCompletionBroker.GetSession(TextView) If session Is Nothing Then AddHandler asyncCompletionBroker.CompletionTriggered, addHandlers Else ' A session was already active so we'll fake the event addHandlers(asyncCompletionBroker, New Data.CompletionTriggeredEventArgs(session, TextView)) End If MyBase.SendCommitUniqueCompletionListItem(Sub(a, n, c) EditorCompletionCommandHandler.ExecuteCommand(a, n, c), Sub() Return) Await WaitForAsynchronousOperationsAsync() RemoveHandler session.ItemsUpdated, itemsUpdatedHandler RemoveHandler session.Dismissed, sessionDismissedHandler RemoveHandler asyncCompletionBroker.CompletionTriggered, addHandlers ' It's possible for the wait to bail and give up if it was clear nothing was completing; ensure we clean up our ' async token so as not to interfere with later tests. sessionComplete.TrySetResult(Nothing) End Function Public Async Function AssertNoCompletionSession() As Task Await WaitForAsynchronousOperationsAsync() Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(TextView) If session Is Nothing Then Return End If If session.IsDismissed Then Return End If Dim completionItems = session.GetComputedItems(CancellationToken.None) ' During the computation we can explicitly dismiss the session or we can return no items. ' Each of these conditions mean that there is no active completion. Assert.True(session.IsDismissed OrElse completionItems.Items.Count() = 0, "AssertNoCompletionSession") End Function Public Sub AssertNoCompletionSessionWithNoBlock() Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(TextView) If session Is Nothing Then Return End If If session.IsDismissed Then Return End If ' If completionItems cannot be calculated in 5 seconds, no session exists. Dim task1 = Task.Delay(5000) Dim task2 = Task.Run( Sub() Dim completionItems = session.GetComputedItems(CancellationToken.None) ' In the non blocking mode, we are not interested for a session appeared later than in 5 seconds. If task1.Status = TaskStatus.Running Then ' During the computation we can explicitly dismiss the session or we can return no items. ' Each of these conditions mean that there is no active completion. Assert.True(session.IsDismissed OrElse completionItems.Items.Count() = 0) End If End Sub) Task.WaitAny(task1, task2) End Sub Public Async Function GetCompletionSession(Optional projectionsView As ITextView = Nothing) As Task(Of IAsyncCompletionSession) Await WaitForAsynchronousOperationsAsync() Dim view = If(projectionsView, TextView) Return GetExportedValue(Of IAsyncCompletionBroker)().GetSession(view) End Function Public Async Function AssertCompletionSession(Optional projectionsView As ITextView = Nothing) As Task Await WaitForAsynchronousOperationsAsync() Dim view = If(projectionsView, TextView) Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(view) Assert.NotNull(session) End Function Public Async Function AssertCompletionItemsDoNotContainAny(ParamArray displayText As String()) As Task Await WaitForAsynchronousOperationsAsync() Dim items = GetCompletionItems() Assert.False(displayText.Any(Function(v) items.Any(Function(i) i.DisplayText = v))) End Function Public Async Function AssertCompletionItemsContainAll(ParamArray displayText As String()) As Task Await WaitForAsynchronousOperationsAsync() Dim items = GetCompletionItems() Assert.All(displayText, Sub(v) Assert.Contains(v, items.Select(Function(i) i.DisplayText))) End Function Public Async Function AssertCompletionItemsContain(displayText As String, displayTextSuffix As String) As Task Await AssertCompletionItemsContain(Function(i) i.DisplayText = displayText AndAlso i.DisplayTextSuffix = displayTextSuffix) End Function Public Async Function AssertCompletionItemsContain(predicate As Func(Of CompletionItem, Boolean)) As Task Await WaitForAsynchronousOperationsAsync() Dim items = GetCompletionItems() Assert.True(items.Any(predicate)) End Function Public Sub AssertItemsInOrder(expectedOrder As String()) Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(TextView) Assert.NotNull(session) Dim items = session.GetComputedItems(CancellationToken.None).Items Assert.Equal(expectedOrder.Count, items.Count) For i = 0 To expectedOrder.Count - 1 Assert.Equal(expectedOrder(i), items(i).DisplayText) Next End Sub Public Sub AssertItemsInOrder(expectedOrder As (String, String)()) Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(TextView) Assert.NotNull(session) Dim items = session.GetComputedItems(CancellationToken.None).Items Assert.Equal(expectedOrder.Count, items.Count) For i = 0 To expectedOrder.Count - 1 Assert.Equal(expectedOrder(i).Item1, items(i).DisplayText) Assert.Equal(expectedOrder(i).Item2, items(i).Suffix) Next End Sub Public Async Function AssertSelectedCompletionItem( Optional displayText As String = Nothing, Optional displayTextSuffix As String = Nothing, Optional description As String = Nothing, Optional isSoftSelected As Boolean? = Nothing, Optional isHardSelected As Boolean? = Nothing, Optional shouldFormatOnCommit As Boolean? = Nothing, Optional inlineDescription As String = Nothing, Optional automationText As String = Nothing, Optional projectionsView As ITextView = Nothing) As Task Await WaitForAsynchronousOperationsAsync() Dim view = If(projectionsView, TextView) Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(view) Assert.NotNull(session) Dim items = session.GetComputedItems(CancellationToken.None) If isSoftSelected.HasValue Then If isSoftSelected.Value Then Assert.True(items.UsesSoftSelection, "Current completion is not soft-selected. Expected: soft-selected") Else Assert.False(items.UsesSoftSelection, "Current completion is soft-selected. Expected: not soft-selected") End If End If If isHardSelected.HasValue Then If isHardSelected.Value Then Assert.True(Not items.UsesSoftSelection, "Current completion is not hard-selected. Expected: hard-selected") Else Assert.True(items.UsesSoftSelection, "Current completion is hard-selected. Expected: not hard-selected") End If End If If displayText IsNot Nothing Then Assert.NotNull(items.SelectedItem) If displayTextSuffix IsNot Nothing Then Assert.NotNull(items.SelectedItem) Assert.Equal(displayText + displayTextSuffix, items.SelectedItem.DisplayText) Else Assert.Equal(displayText, items.SelectedItem.DisplayText) End If End If If shouldFormatOnCommit.HasValue Then Assert.Equal(shouldFormatOnCommit.Value, GetRoslynCompletionItem(items.SelectedItem).Rules.FormatOnCommit) End If If description IsNot Nothing Then Dim itemDescription = Await GetSelectedItemDescriptionAsync() Assert.Equal(description, itemDescription.Text) End If If inlineDescription IsNot Nothing Then Assert.Equal(inlineDescription, items.SelectedItem.Suffix) End If If automationText IsNot Nothing Then Assert.Equal(automationText, items.SelectedItem.AutomationText) End If End Function Public Async Function GetSelectedItemDescriptionAsync() As Task(Of CompletionDescription) Dim document = Me.Workspace.CurrentSolution.Projects.First().Documents.First() Dim service = CompletionService.GetService(document) Dim roslynItem = GetSelectedItem() Dim options = CompletionOptions.Default Return Await service.GetDescriptionAsync(document, roslynItem, options, SymbolDescriptionOptions.Default) End Function Public Sub AssertCompletionItemExpander(isAvailable As Boolean, isSelected As Boolean) Dim presenter = DirectCast(CompletionPresenterProvider.GetOrCreate(Me.TextView), MockCompletionPresenter) Dim expander = presenter.GetExpander() If Not isAvailable Then Assert.False(isSelected) Assert.Null(expander) Else Assert.NotNull(expander) Assert.Equal(expander.IsSelected, isSelected) End If End Sub Public Async Function SetCompletionItemExpanderStateAndWaitForUiRenderAsync(isSelected As Boolean) As Task Dim uiRender = WaitForUIRenderedAsync() Dim presenter = DirectCast(CompletionPresenterProvider.GetOrCreate(Me.TextView), MockCompletionPresenter) Dim expander = presenter.GetExpander() Assert.NotNull(expander) presenter.SetExpander(isSelected) Await uiRender End Function Public Async Function AssertSessionIsNothingOrNoCompletionItemLike(text As String) As Task Await WaitForAsynchronousOperationsAsync() Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(TextView) If session IsNot Nothing Then Await AssertCompletionItemsDoNotContainAny(text) End If End Function Public Function GetSelectedItem() As CompletionItem Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(TextView) Assert.NotNull(session) Dim items = session.GetComputedItems(CancellationToken.None) Return GetRoslynCompletionItem(items.SelectedItem) End Function Public Sub CalculateItemsIfSessionExists() Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(TextView) If session IsNot Nothing Then Dim item = session.GetComputedItems(CancellationToken.None).SelectedItem End If End Sub Public Function GetCompletionItems() As IList(Of CompletionItem) Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(TextView) Assert.NotNull(session) Return session.GetComputedItems(CancellationToken.None).Items.Select(Function(item) GetRoslynCompletionItem(item)).ToList() End Function Private Shared Function GetRoslynCompletionItem(item As Data.CompletionItem) As CompletionItem If (item Is Nothing) Then Return Nothing End If Dim roslynItemData As CompletionItemData = Nothing If (CompletionItemData.TryGetData(item, roslynItemData) = False) Then Return Nothing End If Return roslynItemData.RoslynItem End Function Public Async Function RaiseFiltersChangedAndWaitForUiRenderAsync(args As ImmutableArray(Of Data.CompletionFilterWithState)) As Task Dim uiRender = WaitForUIRenderedAsync() Dim presenter = DirectCast(CompletionPresenterProvider.GetOrCreate(Me.TextView), MockCompletionPresenter) Dim newArgs = New Data.CompletionFilterChangedEventArgs(args) presenter.TriggerFiltersChanged(Me, newArgs) Await uiRender End Function Public Function GetCompletionItemFilters() As ImmutableArray(Of Data.CompletionFilterWithState) Dim presenter = DirectCast(CompletionPresenterProvider.GetOrCreate(Me.TextView), MockCompletionPresenter) Return presenter.GetFilters() End Function Public Function HasSuggestedItem() As Boolean Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(TextView) Assert.NotNull(session) Dim computedItems = session.GetComputedItems(CancellationToken.None) Return computedItems.SuggestionItem IsNot Nothing End Function Public Sub AssertSuggestedItemSelected(displayText As String) Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(TextView) Assert.NotNull(session) Dim computedItems = session.GetComputedItems(CancellationToken.None) Assert.True(computedItems.SuggestionItemSelected) Assert.Equal(computedItems.SuggestionItem.DisplayText, displayText) End Sub Public Function IsSoftSelected() As Boolean Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(TextView) Assert.NotNull(session) Dim computedItems = session.GetComputedItems(CancellationToken.None) Return computedItems.UsesSoftSelection End Function Public Sub SendSelectCompletionItem(displayText As String) Dim session = GetExportedValue(Of IAsyncCompletionBroker)().GetSession(TextView) Dim operations = DirectCast(session, IAsyncCompletionSessionOperations) operations.SelectCompletionItem(session.GetComputedItems(CancellationToken.None).Items.Single(Function(i) i.DisplayText = displayText)) End Sub Public Async Function WaitForUIRenderedAsync() As Task Dim tcs = New TaskCompletionSource(Of Boolean) Dim presenter = DirectCast(CompletionPresenterProvider.GetOrCreate(TextView), MockCompletionPresenter) Dim uiUpdated As EventHandler(Of Data.CompletionItemSelectedEventArgs) uiUpdated = Sub() RemoveHandler presenter.UiUpdated, uiUpdated tcs.TrySetResult(True) End Sub AddHandler presenter.UiUpdated, uiUpdated Dim ct = New CancellationTokenSource(timeoutMs) Using registration = ct.Token.Register(Sub() tcs.TrySetCanceled(), useSynchronizationContext:=False) Await tcs.Task.ConfigureAwait(True) End Using End Function Public Overloads Sub SendTypeCharsToSpecificViewAndBuffer(typeChars As String, view As IWpfTextView, buffer As ITextBuffer) For Each ch In typeChars Dim localCh = ch ExecuteTypeCharCommand(New TypeCharCommandArgs(view, buffer, localCh), Sub() EditorOperations.InsertText(localCh.ToString()), TestCommandExecutionContext.Create()) Next End Sub Public Async Function AssertLineTextAroundCaret(expectedTextBeforeCaret As String, expectedTextAfterCaret As String) As Task Await WaitForAsynchronousOperationsAsync() Dim actual = GetLineTextAroundCaretPosition() Assert.Equal(expectedTextBeforeCaret, actual.TextBeforeCaret) Assert.Equal(expectedTextAfterCaret, actual.TextAfterCaret) End Function Public Sub NavigateToDisplayText(targetText As String) Dim currentText = GetSelectedItem().DisplayText ' GetComputedItems provided by the Editor for tests does not guarantee that ' the order of items match the order of items actually displayed in the completion popup. ' For example, they put starred items (intellicode) below non-starred ones. ' And the order they display those items in the UI is opposite. ' Therefore, we do the full traverse: down to the bottom and if not found up to the top. Do While currentText <> targetText SendDownKey() Dim newText = GetSelectedItem().DisplayText If currentText = newText Then ' Nothing found on going down. Try going up Do While currentText <> targetText SendUpKey() newText = GetSelectedItem().DisplayText Assert.True(newText <> currentText, "Reached the bottom, then the top and didn't find the match") currentText = newText Loop End If currentText = newText Loop End Sub #End Region #Region "Signature Help Operations" Public Overloads Sub SendInvokeSignatureHelp() Dim handler = DirectCast(SignatureHelpBeforeCompletionCommandHandler, IChainedCommandHandler(Of InvokeSignatureHelpCommandArgs)) MyBase.SendInvokeSignatureHelp(Sub(a, n, c) handler.ExecuteCommand(a, n, c), Sub() Return) End Sub Public Overloads Async Function AssertNoSignatureHelpSession(Optional block As Boolean = True) As Task If block Then Await WaitForAsynchronousOperationsAsync() End If Assert.Null(Me.CurrentSignatureHelpPresenterSession) End Function Public Overloads Async Function AssertSignatureHelpSession() As Task Await WaitForAsynchronousOperationsAsync() Assert.NotNull(Me.CurrentSignatureHelpPresenterSession) End Function Public Overloads Function GetSignatureHelpItems() As IList(Of SignatureHelpItem) Return CurrentSignatureHelpPresenterSession.SignatureHelpItems End Function Public Async Function AssertSignatureHelpItemsContainAll(displayText As String()) As Task Await WaitForAsynchronousOperationsAsync() Assert.True(displayText.All(Function(v) CurrentSignatureHelpPresenterSession.SignatureHelpItems.Any( Function(i) GetDisplayText(i, CurrentSignatureHelpPresenterSession.SelectedParameter.Value) = v))) End Function Public Async Function AssertSelectedSignatureHelpItem(Optional displayText As String = Nothing, Optional documentation As String = Nothing, Optional selectedParameter As String = Nothing) As Task Await WaitForAsynchronousOperationsAsync() If displayText IsNot Nothing Then Assert.Equal(displayText, GetDisplayText(Me.CurrentSignatureHelpPresenterSession.SelectedItem, Me.CurrentSignatureHelpPresenterSession.SelectedParameter.Value)) End If If documentation IsNot Nothing Then Assert.Equal(documentation, Me.CurrentSignatureHelpPresenterSession.SelectedItem.DocumentationFactory(CancellationToken.None).GetFullText()) End If If selectedParameter IsNot Nothing Then Assert.Equal(selectedParameter, GetDisplayText( Me.CurrentSignatureHelpPresenterSession.SelectedItem.Parameters( Me.CurrentSignatureHelpPresenterSession.SelectedParameter.Value).DisplayParts)) End If End Function #End Region #Region "Helpers" Private Shared Function GetDisplayText(item As SignatureHelpItem, selectedParameter As Integer) As String Dim suffix = If(selectedParameter < item.Parameters.Count, GetDisplayText(item.Parameters(selectedParameter).SuffixDisplayParts), String.Empty) Return String.Join( String.Empty, GetDisplayText(item.PrefixDisplayParts), String.Join( GetDisplayText(item.SeparatorDisplayParts), item.Parameters.Select(Function(p) GetDisplayText(p.DisplayParts))), GetDisplayText(item.SuffixDisplayParts), suffix) End Function Private Shared Function GetDisplayText(parts As IEnumerable(Of TaggedText)) As String Return String.Join(String.Empty, parts.Select(Function(p) p.ToString())) End Function #End Region End Class End Namespace