提交 5a9edbec 编写于 作者: D Dustin Campbell

Port bulk of C# IntelliSense tests

上级 97a024dd
......@@ -65,6 +65,7 @@
<InternalsVisibleToTest Include="Roslyn.Services.Editor.UnitTests2" />
<InternalsVisibleToTest Include="Roslyn.Services.Editor.VisualBasic.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.Services.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.VisualStudio.IntegrationTests" />
<InternalsVisibleToTest Include="Roslyn.VisualStudio.Services.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.VisualStudio.Test.Utilities" />
<InternalsVisibleToTest Include="RoslynETAHost" />
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Roslyn.Test.Utilities;
using Roslyn.VisualStudio.Test.Utilities;
using Roslyn.VisualStudio.Test.Utilities.Input;
using Xunit;
namespace Roslyn.VisualStudio.IntegrationTests.CSharp
{
[Collection(nameof(SharedIntegrationHostFixture))]
public class CSharpIntelliSense : EditorTestFixture
{
public CSharpIntelliSense(VisualStudioInstanceFactory instanceFactory)
: base(instanceFactory, nameof(CSharpIntelliSense))
{
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public void AtNamespaceLevel()
{
SetUpEditor(@"$$");
SendKeys("usi");
VerifyCompletionItemExists("using");
SendKeys(VirtualKey.Tab);
VerifyCurrentLineText("using$$");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public void SpeculativeTInList()
{
SetUpEditor(@"
class C
{
$$
}");
SendKeys("pub");
VerifyCompletionItemExists("public");
SendKeys(' ');
VerifyCurrentLineText("public $$");
SendKeys('t');
VerifyCompletionItemExists("T");
SendKeys(' ');
SendKeys("Foo<T>() { }");
VerifyTextContains(@"
class C
{
public T Foo<T>() { }$$
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public void VerifyCompletionListMembersOnStaticTypesAndCompleteThem()
{
SetUpEditor(@"
public class Program
{
static void Main(string[] args)
{
NavigateTo$$
}
}
public static class NavigateTo
{
public static void Search(string s){ }
public static void Navigate(int i){ }
}");
SendKeys('.');
VerifyCompletionItemExists("Search", "Navigate");
SendKeys('S', VirtualKey.Tab);
VerifyCurrentLineText("NavigateTo.Search$$");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public void CtrlAltSpace()
{
SetUpEditor("$$");
DisableSuggestionMode();
SendKeys("nam Foo", VirtualKey.Enter);
SendKeys('{', VirtualKey.Enter, '}', VirtualKey.Up, VirtualKey.Enter);
SendKeys("pu cla Program", VirtualKey.Enter);
SendKeys('{', VirtualKey.Enter, '}', VirtualKey.Up, VirtualKey.Enter);
SendKeys("pub stati voi Main(string[] args)", VirtualKey.Enter);
SendKeys('{', VirtualKey.Enter, '}', VirtualKey.Up, VirtualKey.Enter);
SendKeys("System.Console.writeline();");
VerifyCurrentLineText("System.Console.WriteLine();$$");
SendKeys(VirtualKey.Home, KeyPress(VirtualKey.End, ShiftState.Shift), VirtualKey.Delete);
InvokeVisualStudioCommand("Edit.ToggleCompletionMode");
SendKeys("System.Console.writeline();");
VerifyCurrentLineText("System.Console.writeline();$$");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public void CtrlAltSpaceOption()
{
SetUpEditor("$$");
DisableSuggestionMode();
SendKeys("nam Foo");
VerifyCurrentLineText("namespace Foo$$");
SetUpEditor("$$");
EnableSuggestionMode();
SendKeys("nam Foo");
VerifyCurrentLineText("nam Foo$$");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public void CtrlSpace()
{
SetUpEditor("class c { void M() {$$ } }");
SendKeys(KeyPress(VirtualKey.Space, ShiftState.Ctrl));
VerifyCompletionItemExists("System");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public void NavigatingWithDownKey()
{
SetUpEditor("class c { void M() {$$ } }");
SendKeys('c');
VerifyCurrentCompletionItem("c");
VerifyCompletionItemExists("c");
SendKeys(VirtualKey.Down);
VerifyCurrentCompletionItem("char");
VerifyCompletionItemExists("char");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public void XmlDocCommentIntelliSense()
{
SetUpEditor(@"
class Class1
{
///$$
void Main(string[] args)
{
}
}");
SendKeys("<s");
VerifyCompletionItemExists("see", "seealso", "summary");
SendKeys(VirtualKey.Enter);
VerifyCurrentLineText("///<see cref=\"$$\"/>");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public void XmlTagCompletion()
{
SetUpEditor(@"/// $$
class C { }
");
SendKeys("<summary>");
VerifyCurrentLineText("/// <summary>$$</summary>");
SetUpEditor(@"/// <summary>$$
class C { }
");
SendKeys("</");
VerifyCurrentLineText("/// <summary></summary>$$");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public void SignatureHelpShowsUp()
{
SetUpEditor(@"class Class1
{
void Main(string[] args)
{
$$
}
}");
DisableSuggestionMode();
SendKeys("Mai(");
// TODO: Finish
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Roslyn.Test.Utilities;
using Roslyn.VisualStudio.Test.Utilities;
using Roslyn.VisualStudio.Test.Utilities.Input;
using Xunit;
namespace Roslyn.VisualStudio.IntegrationTests
......@@ -38,6 +41,11 @@ protected void WaitForWorkspace()
_workspace.WaitForAsyncOperations("Workspace");
}
public void WaitForAsyncOperations(string featuresToWaitFor)
{
_workspace.WaitForAsyncOperations(featuresToWaitFor);
}
protected void WaitForAllAsyncOperations()
{
_workspace.WaitForAllAsyncOperations();
......@@ -53,9 +61,29 @@ protected void SetUpEditor(string markupCode)
_editorWindow.MoveCaret(caretPosition);
}
protected void SendKeys(params object[] textOrVirtualKeys)
protected void SendKeys(params object[] keys)
{
_editorWindow.SendKeys(textOrVirtualKeys);
_editorWindow.SendKeys(keys);
}
protected KeyPress KeyPress(VirtualKey virtualKey, ShiftState shiftState)
{
return new KeyPress(virtualKey, shiftState);
}
protected void DisableSuggestionMode()
{
_workspace.UseSuggestionMode = false;
}
protected void EnableSuggestionMode()
{
_workspace.UseSuggestionMode = true;
}
protected void InvokeVisualStudioCommand(string commandName)
{
_visualStudio.Instance.ExecuteCommandAsync("Edit.ToggleCompletionMode").Wait();
}
protected void VerifyCurrentLineText(string expectedText, bool trimWhitespace = true)
......@@ -78,7 +106,18 @@ protected void VerifyCurrentLineText(string expectedText, bool trimWhitespace =
if (trimWhitespace)
{
lineText = lineText.Trim();
if (caretStartIndex == 0)
{
lineText = lineText.TrimEnd();
}
else if (caretEndIndex == expectedText.Length)
{
lineText = lineText.TrimStart();
}
else
{
lineText = lineText.Trim();
}
}
var lineTextBeforeCaret = caretStartIndex < lineText.Length
......@@ -96,6 +135,12 @@ protected void VerifyCurrentLineText(string expectedText, bool trimWhitespace =
else
{
var lineText = _editorWindow.GetCurrentLineText();
if (trimWhitespace)
{
lineText = lineText.Trim();
}
Assert.Equal(expectedText, lineText);
}
}
......@@ -132,5 +177,24 @@ protected void VerifyTextContains(string expectedText)
Assert.Contains(expectedText, editorText);
}
}
protected void VerifyCompletionItemExists(params string[] expectedItems)
{
WaitForAsyncOperations(FeatureAttribute.CompletionSet);
var completionItems = _editorWindow.GetCompletionItems();
foreach (var expectedItem in expectedItems)
{
Assert.Contains(expectedItem, completionItems);
}
}
protected void VerifyCurrentCompletionItem(string expectedItem)
{
WaitForAsyncOperations(FeatureAttribute.CompletionSet);
var currentItem = _editorWindow.GetCurrentCompletionItem();
Assert.Equal(expectedItem, currentItem);
}
}
}
......@@ -17,6 +17,7 @@
<ItemGroup>
<Compile Include="CSharp\CSharpAutomaticBraceCompletion.cs" />
<Compile Include="CSharp\CSharpBuild.cs" />
<Compile Include="CSharp\CSharpIntelliSense.cs" />
<Compile Include="CSharp\CSharpInteractiveDemo.cs" />
<Compile Include="EditorTestFixture.cs" />
<Compile Include="SharedIntegrationHostFixture.cs" />
......@@ -37,6 +38,10 @@
<Project>{76c6f005-c89d-4348-bb4a-39189ddbeb52}</Project>
<Name>ServicesTestUtilities</Name>
</ProjectReference>
<ProjectReference Include="..\..\Features\Core\Portable\Features.csproj">
<Project>{EDC68A0E-C68D-4A74-91B7-BF38EC909888}</Project>
<Name>Features</Name>
</ProjectReference>
<ProjectReference Include="..\..\Test\Utilities\Desktop\TestUtilities.Desktop.csproj">
<Project>{76c6f005-c89d-4348-bb4a-391898dbeb52}</Project>
<Name>TestUtilities.Desktop</Name>
......
......@@ -2,6 +2,7 @@
using System.Windows;
using System.Windows.Threading;
using EnvDTE;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
......@@ -27,6 +28,8 @@ protected static T InvokeOnUIThread<T>(Func<T> action)
}
protected static TInterface GetGlobalService<TService, TInterface>()
where TService : class
where TInterface : class
{
return InvokeOnUIThread(() =>
{
......@@ -34,11 +37,25 @@ protected static T InvokeOnUIThread<T>(Func<T> action)
});
}
protected static TService GetComponentModelService<TService>()
where TService : class
{
return InvokeOnUIThread(() =>
{
return GetComponentModel().GetService<TService>();
});
}
protected static DTE GetDTE()
{
return GetGlobalService<SDTE, DTE>();
}
protected static IComponentModel GetComponentModel()
{
return GetGlobalService<SComponentModel, IComponentModel>();
}
/// <summary>
/// Waiting for the application to 'idle' means that it is done pumping messages (including WM_PAINT).
/// </summary>
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.TextManager.Interop;
......@@ -152,5 +154,41 @@ public void MoveCaret(int position)
view.Caret.MoveTo(point);
});
}
public string[] GetCompletionItems()
{
return ExecuteOnActiveView(view =>
{
var broker = GetComponentModelService<ICompletionBroker>();
var sessions = broker.GetSessions(view);
if (sessions.Count != 1)
{
throw new InvalidOperationException($"Expected exactly one session in the completion list, but found {sessions.Count}");
}
var selectedCompletionSet = sessions[0].SelectedCompletionSet;
return selectedCompletionSet.Completions.Select(c => c.DisplayText).ToArray();
});
}
public string GetCurrentCompletionItem()
{
return ExecuteOnActiveView(view =>
{
var broker = GetComponentModelService<ICompletionBroker>();
var sessions = broker.GetSessions(view);
if (sessions.Count != 1)
{
throw new InvalidOperationException($"Expected exactly one session in the completion list, but found {sessions.Count}");
}
var selectedCompletionSet = sessions[0].SelectedCompletionSet;
return selectedCompletionSet.SelectionStatus.Completion.DisplayText;
});
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Roslyn.VisualStudio.Test.Utilities.Input
{
public struct KeyPress
{
public readonly VirtualKey VirtualKey;
public readonly ShiftState ShiftState;
public KeyPress(VirtualKey virtualKey, ShiftState shiftState)
{
this.VirtualKey = virtualKey;
this.ShiftState = shiftState;
}
}
}
......@@ -15,6 +15,11 @@ public SendKeys(VisualStudioInstance visualStudioInstance)
_visualStudioInstance = visualStudioInstance;
}
public void Send(KeyPress keyPress)
{
Send(keyPress.VirtualKey, keyPress.ShiftState);
}
public void Send(VirtualKey virtualKey, ShiftState shiftState = 0)
{
var foregroundWindow = IntPtr.Zero;
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Roslyn.VisualStudio.Test.Utilities.Input
{
public enum VirtualKey : byte
......@@ -39,6 +33,8 @@ public enum VirtualKey : byte
Insert = 0x2D,
Delete = 0x2E,
Space = 0x20,
F1 = 0x70,
F2 = 0x71,
F3 = 0x72,
......@@ -54,6 +50,33 @@ public enum VirtualKey : byte
F13 = 0x7C,
F14 = 0x7D,
F15 = 0x7E,
F16 = 0x7F
F16 = 0x7F,
A = 0x41,
B = 0x42,
C = 0x43,
D = 0x44,
E = 0x45,
F = 0x46,
G = 0x47,
H = 0x48,
I = 0x49,
J = 0x4A,
K = 0x4B,
L = 0x4C,
M = 0x4D,
N = 0x4E,
O = 0x4F,
P = 0x50,
Q = 0x51,
R = 0x52,
S = 0x53,
T = 0x54,
U = 0x55,
V = 0x56,
W = 0x57,
X = 0x58,
Y = 0x59,
Z = 0x5A
}
}
......@@ -89,6 +89,11 @@ public void WaitForApplicationIdle()
methodName: nameof(RemotingHelper.WaitForApplicationIdle));
}
public async Task ExecuteCommandAsync(string commandName)
{
await this.DTE.ExecuteCommandAsync(commandName);
}
public bool IsRunning => !_hostProcess.HasExited;
public CSharpInteractiveWindow CSharpInteractiveWindow => _csharpInteractiveWindow.Value;
......
......@@ -20,6 +20,7 @@
<ItemGroup>
<Compile Include="Extensions\DteExtensions.cs" />
<Compile Include="InProcess\BaseInProcessComponent.cs" />
<Compile Include="Input\KeyPress.cs" />
<Compile Include="Input\SendKeys.cs" />
<Compile Include="Input\ShiftState.cs" />
<Compile Include="Input\VirtualKey.cs" />
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Immutable;
using Roslyn.VisualStudio.Test.Utilities.InProcess;
using Roslyn.VisualStudio.Test.Utilities.Input;
......@@ -36,15 +37,18 @@ internal EditorWindow(VisualStudioInstance visualStudioInstance)
public void MoveCaret(int position) => _inProcessEditor.MoveCaret(position);
public void SendKeys(params object[] textOrVirtualKeys)
public string[] GetCompletionItems() => _inProcessEditor.GetCompletionItems();
public string GetCurrentCompletionItem() => _inProcessEditor.GetCurrentCompletionItem();
public void SendKeys(params object[] keys)
{
Activate();
foreach (var textOrVirtualKey in textOrVirtualKeys)
foreach (var key in keys)
{
if (textOrVirtualKey is string)
if (key is string)
{
var text = ((string)textOrVirtualKey)
var text = ((string)key)
.Replace("\r\n", "\r")
.Replace("\n", "\r");
......@@ -53,21 +57,25 @@ public void SendKeys(params object[] textOrVirtualKeys)
_visualStudioInstance.SendKeys.Send(ch);
}
}
else if (textOrVirtualKey is char)
else if (key is char)
{
_visualStudioInstance.SendKeys.Send((char)key);
}
else if (key is VirtualKey)
{
_visualStudioInstance.SendKeys.Send((char)textOrVirtualKey);
_visualStudioInstance.SendKeys.Send((VirtualKey)key);
}
else if (textOrVirtualKey is VirtualKey)
else if (key is KeyPress)
{
_visualStudioInstance.SendKeys.Send((VirtualKey)textOrVirtualKey);
_visualStudioInstance.SendKeys.Send((KeyPress)key);
}
else if (textOrVirtualKey == null)
else if (key == null)
{
throw new ArgumentNullException(nameof(textOrVirtualKeys));
throw new ArgumentNullException(nameof(keys));
}
else
{
throw new ArgumentException($"Unexpected type encountered: {textOrVirtualKey.GetType()}", nameof(textOrVirtualKeys));
throw new ArgumentException($"Unexpected type encountered: {key.GetType()}", nameof(keys));
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册