提交 2ba0d8f2 编写于 作者: I Ivan Basov 提交者: GitHub

Ivanbasov/integration tests (#17885)

Integration tests for CSharpInteractiveCommands
上级 8e5a0b08
......@@ -9,7 +9,6 @@
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.IntegrationTest.Utilities;
using Microsoft.VisualStudio.IntegrationTest.Utilities.Common;
using Microsoft.VisualStudio.IntegrationTest.Utilities.InProcess;
using Microsoft.VisualStudio.IntegrationTest.Utilities.Input;
using Microsoft.VisualStudio.IntegrationTest.Utilities.OutOfProcess;
using Roslyn.Test.Utilities;
......@@ -138,15 +137,6 @@ protected int GetErrorListErrorCount()
protected void SendKeys(params object[] keys)
=> Editor.SendKeys(keys);
protected KeyPress KeyPress(VirtualKey virtualKey, ShiftState shiftState)
=> new KeyPress(virtualKey, shiftState);
protected KeyPress Ctrl(VirtualKey virtualKey)
=> new KeyPress(virtualKey, ShiftState.Ctrl);
protected KeyPress Shift(VirtualKey virtualKey)
=> new KeyPress(virtualKey, ShiftState.Shift);
protected void DisableSuggestionMode()
=> VisualStudioWorkspaceOutOfProc.SetUseSuggestionMode(false);
......@@ -175,9 +165,6 @@ protected void InvokeCodeActionList()
WaitForAsyncOperations(FeatureAttribute.LightBulb);
}
protected void ExecuteCommand(string commandName, string argument = "")
=> VisualStudio.Instance.ExecuteCommand(commandName, argument);
private void VerifyCurrentLineTextAndAssertCaretPosition(string expectedText, bool trimWhitespace)
{
var caretStartIndex = expectedText.IndexOf("$$");
......
......@@ -3,6 +3,7 @@
using System;
using System.Threading;
using Microsoft.VisualStudio.IntegrationTest.Utilities;
using Microsoft.VisualStudio.IntegrationTest.Utilities.Input;
namespace Roslyn.VisualStudio.IntegrationTests
{
......@@ -24,5 +25,20 @@ protected void Wait(double seconds)
var timeout = TimeSpan.FromMilliseconds(seconds * 1000);
Thread.Sleep(timeout);
}
protected KeyPress KeyPress(VirtualKey virtualKey, ShiftState shiftState)
=> new KeyPress(virtualKey, shiftState);
protected KeyPress Ctrl(VirtualKey virtualKey)
=> new KeyPress(virtualKey, ShiftState.Ctrl);
protected KeyPress Shift(VirtualKey virtualKey)
=> new KeyPress(virtualKey, ShiftState.Shift);
protected KeyPress Alt(VirtualKey virtualKey)
=> new KeyPress(virtualKey, ShiftState.Alt);
protected void ExecuteCommand(string commandName, string argument = "")
=> VisualStudio.Instance.ExecuteCommand(commandName, argument);
}
}
......@@ -25,6 +25,7 @@ protected AbstractInteractiveWindowTest(VisualStudioInstanceFactory instanceFact
protected void ClearInteractiveWindow()
{
InteractiveWindow.Initialize();
InteractiveWindow.ClearScreen();
InteractiveWindow.ShowWindow();
InteractiveWindow.Reset();
}
......@@ -44,12 +45,32 @@ protected void Reset(bool waitForPrompt = true)
protected void SubmitText(string text, bool waitForPrompt = true)
=> InteractiveWindow.SubmitText(text, waitForPrompt);
protected void SendKeys(params object[] input)
{
VisualStudio.Instance.SendKeys.Send(input);
}
protected void InsertCode(string text)
=> InteractiveWindow.InsertCode(text);
protected void VerifyLastReplOutput(string expectedReplOutput)
{
var lastReplOutput = InteractiveWindow.GetLastReplOutput();
Assert.Equal(expectedReplOutput, lastReplOutput);
}
protected void VerifyLastReplInput(string expectedReplInput)
{
var lastReplInput = InteractiveWindow.GetLastReplInput();
Assert.Equal(expectedReplInput, lastReplInput);
}
protected void VerifyCaretPosition(int expectedCaretPosition)
{
var position = InteractiveWindow.GetCaretPosition();
Assert.Equal(expectedCaretPosition, position);
}
protected void VerifyLastReplOutputContains(string expectedReplOutput)
{
var lastReplOutput = InteractiveWindow.GetLastReplOutput();
......
// 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 Microsoft.VisualStudio.IntegrationTest.Utilities;
using Microsoft.VisualStudio.IntegrationTest.Utilities.Input;
using Xunit;
namespace Roslyn.VisualStudio.IntegrationTests.CSharp
{
[Collection(nameof(SharedIntegrationHostFixture))]
public class CSharpInteractiveCommands : AbstractInteractiveWindowTest
{
public CSharpInteractiveCommands(VisualStudioInstanceFactory instanceFactory)
: base(instanceFactory)
{
}
[Fact]
public void VerifyPreviousAndNextHistory()
{
SubmitText("1 + 2");
SubmitText("1.ToString()");
SendKeys(Alt(VirtualKey.Up));
VerifyLastReplInput("1.ToString()");
SendKeys(VirtualKey.Enter);
WaitForReplOutput("\"1\"");
SendKeys(Alt(VirtualKey.Up));
VerifyLastReplInput("1.ToString()");
SendKeys(Alt(VirtualKey.Up));
VerifyLastReplInput("1 + 2");
SendKeys(VirtualKey.Enter);
WaitForReplOutput("3");
SendKeys(Alt(VirtualKey.Down));
VerifyLastReplInput("1.ToString()");
SendKeys(VirtualKey.Enter);
WaitForReplOutput("\"1\"");
}
[Fact]
public void VerifyMaybeExecuteInput()
{
InsertCode("2 + 3");
SendKeys(VirtualKey.Enter);
WaitForReplOutput("5");
}
[Fact]
public void VerifyNewLineAndIndent()
{
InsertCode("3 + ");
SendKeys(VirtualKey.Enter);
InsertCode("4");
SendKeys(VirtualKey.Enter);
WaitForReplOutput("7");
}
[Fact]
public void VerifyExecuteInput()
{
SubmitText("1 + ");
VerifyLastReplOutputContains("CS1733");
}
[Fact]
public void VerifyForceNewLineAndIndent()
{
InsertCode("1 + 2");
SendKeys(VirtualKey.Enter);
SubmitText("+ 3");
VerifyReplPromptConsistency("<![CDATA[1 + 2 + 3]]>", "6");
}
[Fact]
public void VerifyCancelInput()
{
InsertCode("1 + 4");
SendKeys(Shift(VirtualKey.Enter));
SendKeys(VirtualKey.Escape);
VerifyLastReplInput(string.Empty);
}
[Fact]
public void VerifyUndoAndRedo()
{
ClearReplText();
InsertCode(" 2 + 4 ");
SendKeys(Ctrl(VirtualKey.Z));
VerifyReplPromptConsistency("< ![CDATA[]] >", string.Empty);
SendKeys(Ctrl(VirtualKey.Y));
VerifyLastReplInput(" 2 + 4 ");
SendKeys(VirtualKey.Enter);
WaitForReplOutput("6");
}
[Fact]
public void CutDeletePasteSelectAll()
{
SendKeys("Text");
ExecuteCommand("Edit.LineStart");
ExecuteCommand("Edit.LineEnd");
ExecuteCommand("Edit.LineStartExtend");
ExecuteCommand("Edit.SelectionCancel");
ExecuteCommand("Edit.LineEndExtend");
ExecuteCommand("Edit.SelectAll");
ExecuteCommand("Edit.SelectAll");
ExecuteCommand("Edit.Copy");
ExecuteCommand("Edit.Cut");
ExecuteCommand("Edit.Paste");
ExecuteCommand("Edit.Delete");
ExecuteCommand("Edit.LineUp");
ExecuteCommand("Edit.LineDown");
ExecuteCommand("Edit.Paste");
ExecuteCommand("Edit.Paste");
SendKeys(VirtualKey.Escape);
}
//<!-- Regression test for bug 13731.
// Unfortunately we don't have good unit-test infrastructure to test InteractiveWindow.cs.
// For now, since we don't have coverage of InteractiveWindow.IndentCurrentLine at all,
// I'd rather have a quick integration test scenario rather than no coverage at all.
// At some point when we start investing in Interactive work again, we'll go through some
// of these tests and convert them to unit-tests.
// -->
//<!-- TODO(https://github.com/dotnet/roslyn/issues/4235)
[Fact]
public void VerifyReturnIndentCurrentLine()
{
InteractiveWindow.ClearScreen();
SendKeys(" (");
SendKeys(")");
SendKeys(VirtualKey.Left);
SendKeys(VirtualKey.Enter);
VerifyCaretPosition(12);
}
}
}
\ 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.VisualStudio.IntegrationTest.Utilities;
using Xunit;
namespace Roslyn.VisualStudio.IntegrationTests.CSharp
{
[Collection(nameof(SharedIntegrationHostFixture))]
public class CSharpInteractiveDemo : AbstractInteractiveWindowTest
{
public CSharpInteractiveDemo(VisualStudioInstanceFactory instanceFactory)
: base(instanceFactory)
{
}
[Fact]
public void BclMathCall()
{
SubmitText("Math.Sin(1)");
VerifyLastReplOutput("0.8414709848078965");
}
[Fact]
public void BclConsoleCall()
{
SubmitText(@"Console.WriteLine(""Hello, World!"");");
VerifyLastReplOutput("Hello, World!");
}
[Fact]
public void ForStatement()
{
SubmitText("for (int i = 0; i < 10; i++) Console.WriteLine(i * i);");
VerifyLastReplOutputEndsWith($"{81}");
}
[Fact]
public void ForEachStatement()
{
SubmitText(@"foreach (var f in System.IO.Directory.GetFiles(@""c:\windows"")) Console.WriteLine($""{f}"".ToLower());");
VerifyLastReplOutputContains(@"c:\windows\win.ini");
}
[Fact]
public void TopLevelMethod()
{
SubmitText(@"int Fac(int x)
{
return x < 1 ? 1 : x * Fac(x - 1);
}
Fac(4)");
VerifyLastReplOutput($"{24}");
}
[Fact]
public async Task WpfInteraction()
{
SubmitText(@"#r ""WindowsBase""
#r ""PresentationCore""
#r ""PresentationFramework""
#r ""System.Xaml""");
SubmitText(@"using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;");
SubmitText(@"var w = new Window();
w.Title = ""Hello World"";
w.FontFamily = new FontFamily(""Calibri"");
w.FontSize = 24;
w.Height = 300;
w.Width = 300;
w.Topmost = true;
w.Visibility = Visibility.Visible;");
var testValue = Guid.NewGuid();
SubmitText($@"var b = new Button();
b.Content = ""{testValue}"";
b.Margin = new Thickness(40);
b.Click += (sender, e) => Console.WriteLine(""Hello, World!"");
var g = new Grid();
g.Children.Add(b);
w.Content = g;");
await VisualStudio.Instance.ClickAutomationElementAsync(testValue.ToString(), recursive: true);
WaitForReplOutput("Hello, World!");
VerifyLastReplOutput("Hello, World!");
SubmitText("b = null; w.Close(); w = null;");
}
}
}
......@@ -32,6 +32,7 @@
<Compile Include="CSharp\CSharpIntelliSense.cs" />
<Compile Include="CSharp\CSharpInteractive.cs" />
<Compile Include="AbstractEditorTest.cs" />
<Compile Include="CSharp\CSharpInteractiveCommands.cs" />
<Compile Include="CSharp\CSharpSignatureHelp.cs" />
<Compile Include="CSharp\CSharpWinForms.cs" />
<Compile Include="CSharp\CSharpAddMissingReference.cs" />
......
......@@ -15,6 +15,7 @@ namespace Microsoft.VisualStudio.IntegrationTest.Utilities.InProcess
internal abstract class InteractiveWindow_InProc : InProcComponent
{
private const string ResetCommand = "InteractiveConsole.Reset";
private const string CleanScreenCommand = "InteractiveConsole.ClearScreen";
private const string ReplSubmissionText = ". ";
private const string ReplPromptText = "> ";
......@@ -45,6 +46,9 @@ public bool IsInitializing
public string GetReplText()
=> _interactiveWindow.TextView.TextBuffer.CurrentSnapshot.GetText();
public int GetCaretPosition()
=> _interactiveWindow.TextView.Caret.Position.BufferPosition.Position;
/// <summary>
/// Gets the contents of the REPL window without the prompt text.
/// </summary>
......@@ -99,6 +103,30 @@ public string GetLastReplOutput()
return replText.Substring(firstNewLineIndex, replText.Length - firstNewLineIndex);
}
/// <summary>
/// Gets the last input from the REPL.
/// </summary>
public string GetLastReplInput()
{
// TODO: This may be flaky if the last submission contains ReplPromptText
// TODO: ReplSubmissionText is not yet supported
var replText = GetReplText();
var lastPromptIndex = replText.LastIndexOf(ReplPromptText);
replText = replText.Substring(lastPromptIndex, replText.Length - lastPromptIndex);
replText = replText.Substring(ReplPromptText.Length);
var firstNewLineIndex = replText.IndexOf(Environment.NewLine);
if (firstNewLineIndex <= 0)
{
return replText;
}
return replText.Substring(0, firstNewLineIndex);
}
public void Reset(bool waitForPrompt = true)
{
ExecuteCommand(ResetCommand);
......@@ -157,6 +185,16 @@ private async Task WaitForReplPromptAsync()
public void WaitForReplOutput(string outputText)
=> WaitForReplOutputAsync(outputText).Wait();
public void ClearScreen()
{
ExecuteCommand(CleanScreenCommand);
}
public void InsertCode(string text)
{
_interactiveWindow.InsertCode(text);
}
private async Task WaitForReplOutputAsync(string outputText)
{
while (!GetReplText().EndsWith(outputText + Environment.NewLine + ReplPromptText))
......
......@@ -28,6 +28,15 @@ public void Initialize()
public string GetLastReplOutput()
=> _inProc.GetLastReplOutput();
/// <summary>
/// Gets the last input from the REPL.
/// </summary>
public string GetLastReplInput()
=> _inProc.GetLastReplInput();
public int GetCaretPosition()
=> _inProc.GetCaretPosition();
public string GetReplText()
=> _inProc.GetReplText();
......@@ -52,7 +61,13 @@ public void WaitForReplOutput(string outputText)
public void WaitForReplOutputContains(string outputText)
=> _inProc.WaitForReplOutputContains(outputText);
public void CleanUpInteractiveWindow()
public void CloseInteractiveWindow()
=> _inProc.CloseWindow();
public void ClearScreen()
=> _inProc.ClearScreen();
public void InsertCode(string text)
=> _inProc.InsertCode(text);
}
}
......@@ -150,7 +150,7 @@ public void CleanUp()
VisualStudioWorkspace.CleanUpWaitingService();
VisualStudioWorkspace.CleanUpWorkspace();
SolutionExplorer.CleanUpOpenSolution();
CSharpInteractiveWindow.CleanUpInteractiveWindow();
CSharpInteractiveWindow.CloseInteractiveWindow();
}
public void Close(bool exitHostProcess = true)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册