提交 ab446dd8 编写于 作者: G Gen Lu

Merge pull request #5602 from genlu/AddMockClipboard

Add a mock clipboard to interactive window tests
// 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.Windows;
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal partial class InteractiveWindow
{
private sealed class SystemClipboard : InteractiveWindowClipboard
{
internal override bool ContainsData(string format) => Clipboard.ContainsData(format);
internal override object GetData(string format) => Clipboard.GetData(format);
internal override bool ContainsText() => Clipboard.ContainsText();
internal override string GetText() => Clipboard.GetText();
internal override void SetDataObject(object data, bool copy) => Clipboard.SetDataObject(data, copy);
}
}
}
......@@ -602,9 +602,9 @@ public bool Paste()
{
InsertCode(format);
}
else if (Clipboard.ContainsData(ClipboardFormat))
else if (_window.InteractiveWindowClipboard.ContainsData(ClipboardFormat))
{
var blocks = BufferBlock.Deserialize((string)Clipboard.GetData(ClipboardFormat));
var blocks = BufferBlock.Deserialize((string)_window.InteractiveWindowClipboard.GetData(ClipboardFormat));
// Paste each block separately.
foreach (var block in blocks)
{
......@@ -618,9 +618,9 @@ public bool Paste()
}
}
}
else if (Clipboard.ContainsText())
else if (_window.InteractiveWindowClipboard.ContainsText())
{
InsertCode(Clipboard.GetText());
InsertCode(_window.InteractiveWindowClipboard.GetText());
}
else
{
......@@ -2419,7 +2419,7 @@ private void CutOrDelete(IEnumerable<SnapshotSpan> projectionSpans, bool isCut)
}
data.SetText(deletedText.ToString());
Clipboard.SetDataObject(data, true);
_window.InteractiveWindowClipboard.SetDataObject(data, true);
}
}
......@@ -2439,7 +2439,7 @@ private void CopySelection()
{
var spans = GetSelectionSpans(TextView);
var data = Copy(spans);
Clipboard.SetDataObject(data, true);
_window.InteractiveWindowClipboard.SetDataObject(data, true);
}
private static NormalizedSnapshotSpanCollection GetSelectionSpans(ITextView textView)
......
......@@ -46,6 +46,8 @@ internal partial class InteractiveWindow : IInteractiveWindow, IInteractiveWindo
/// </remarks>
private readonly UIThreadOnly _uiOnly;
internal InteractiveWindowClipboard InteractiveWindowClipboard { get; set; } = new SystemClipboard();
#region Initialization
public InteractiveWindow(
......
......@@ -90,7 +90,9 @@
<Compile Include="Commands\InteractiveCommandsFactory.cs" />
<Compile Include="IInteractiveWindowOperations.cs" />
<Compile Include="IInteractiveWindowOperations2.cs" />
<Compile Include="InteractiveWindowClipboard.cs" />
<Compile Include="InteractiveWindow.SpanRangeEdit.cs" />
<Compile Include="InteractiveWindow.SystemClipboard.cs" />
<Compile Include="ProjectionBufferExtensions.cs" />
<Compile Include="InteractiveWindow.PendingSubmission.cs" />
<Compile Include="InteractiveWindow.ReplSpanKind.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.
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal abstract class InteractiveWindowClipboard
{
internal abstract bool ContainsData(string format);
internal abstract object GetData(string format);
internal abstract bool ContainsText();
internal abstract string GetText();
internal abstract void SetDataObject(object data, bool copy);
}
}
......@@ -80,6 +80,7 @@
<Compile Include="HistoryTests.cs" />
<Compile Include="InteractiveWindowHistoryTests.cs" />
<Compile Include="InteractiveWindowTests.cs" />
<Compile Include="TestClipboard.cs" />
<Compile Include="TestContentTypeDefinition.cs" />
<Compile Include="TestInteractiveEngine.cs" />
<Compile Include="TestSmartIndent.cs" />
......@@ -95,4 +96,4 @@
<Import Project="..\..\..\build\Targets\VSL.Imports.targets" />
<Import Project="..\..\..\build\Targets\Roslyn.Toolsets.Xunit.targets" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
......@@ -20,11 +20,14 @@ public class InteractiveWindowTests : IDisposable
private InteractiveWindowTestHost _testHost;
private List<InteractiveWindow.State> _states;
private readonly TestClipboard _testClipboard;
public InteractiveWindowTests()
{
_states = new List<InteractiveWindow.State>();
_testHost = new InteractiveWindowTestHost(_states.Add);
_testClipboard = new TestClipboard();
((InteractiveWindow)Window).InteractiveWindowClipboard = _testClipboard;
}
void IDisposable.Dispose()
......@@ -32,7 +35,7 @@ void IDisposable.Dispose()
_testHost.Dispose();
}
private IInteractiveWindow Window => _testHost.Window;
private IInteractiveWindow Window => _testHost.Window;
private static IEnumerable<IInteractiveWindowCommand> MockCommands(params string[] commandNames)
{
......@@ -372,13 +375,13 @@ public void CallSelectAllOnNonUIThread()
Task.Run(() => Window.Operations.SelectAll()).PumpingWait();
}
[Fact(Skip = "5544"), WorkItem(5544, "https://github.com/dotnet/roslyn/issues/5544")]
[Fact]
public void CallPasteOnNonUIThread()
{
Task.Run(() => Window.Operations.Paste()).PumpingWait();
}
[Fact(Skip = "5544"), WorkItem(5544, "https://github.com/dotnet/roslyn/issues/5544")]
[Fact]
public void CallCutOnNonUIThread()
{
Task.Run(() => Window.Operations.Cut()).PumpingWait();
......@@ -579,10 +582,10 @@ public void ReformatBraces()
new Span(23, 2));
}
[Fact(Skip = "5544"), WorkItem(5544, "https://github.com/dotnet/roslyn/issues/5544")]
[Fact]
public void CopyWithinInput()
{
Clipboard.Clear();
_testClipboard.Clear();
Window.InsertCode("1 + 2");
Window.Operations.SelectAll();
......@@ -598,10 +601,10 @@ public void CopyWithinInput()
VerifyClipboardData(" + ", " + ", @"[{""content"":"" + "",""kind"":2}]");
}
[Fact(Skip = "5544"), WorkItem(5544, "https://github.com/dotnet/roslyn/issues/5544")]
[Fact]
public void CopyInputAndOutput()
{
Clipboard.Clear();
_testClipboard.Clear();
Submit(
@"foreach (var o in new[] { 1, 2, 3 })
......@@ -641,10 +644,10 @@ public void CopyInputAndOutput()
@"[{""content"":""oreach (var o in new[] { 1, 2, 3 })\u000d\u000a"",""kind"":2},{""content"":""> "",""kind"":0},{""content"":""System.Console.WriteLine();\u000d\u000a"",""kind"":2},{""content"":""1\u000d\u000a2\u000d\u000a3"",""kind"":1}]");
}
[Fact(Skip = "5544"), WorkItem(5544, "https://github.com/dotnet/roslyn/issues/5544")]
[Fact]
public void CutWithinInput()
{
Clipboard.Clear();
_testClipboard.Clear();
Window.InsertCode("foreach (var o in new[] { 1, 2, 3 })");
Window.Operations.BreakLine();
......@@ -669,10 +672,10 @@ public void CutWithinInput()
expectedRepl: null);
}
[Fact(Skip = "5544"), WorkItem(5544, "https://github.com/dotnet/roslyn/issues/5544")]
[Fact]
public void CutInputAndOutput()
{
Clipboard.Clear();
_testClipboard.Clear();
Submit(
@"foreach (var o in new[] { 1, 2, 3 })
......@@ -695,7 +698,7 @@ public void CutInputAndOutput()
/// When there is no selection, copy
/// should copy the current line.
/// </summary>
[Fact(Skip = "5544"), WorkItem(5544, "https://github.com/dotnet/roslyn/issues/5544")]
[Fact]
public void CopyNoSelection()
{
Submit(
......@@ -719,14 +722,14 @@ private void CopyNoSelectionAndVerify(int start, int end, string expectedText, s
var snapshot = Window.TextView.TextBuffer.CurrentSnapshot;
for (int i = start; i < end; i++)
{
Clipboard.Clear();
_testClipboard.Clear();
caret.MoveTo(new SnapshotPoint(snapshot, i));
Window.Operations.Copy();
VerifyClipboardData(expectedText, expectedRtf, expectedRepl);
}
}
[Fact(Skip = "5544"), WorkItem(5544, "https://github.com/dotnet/roslyn/issues/5544")]
[Fact]
public void Paste()
{
var blocks = new[]
......@@ -756,9 +759,9 @@ public void Paste()
Assert.Equal("> a\r\n> bc123", text);
}
private static void CopyToClipboard(BufferBlock[] blocks, bool includeRepl)
private void CopyToClipboard(BufferBlock[] blocks, bool includeRepl)
{
Clipboard.Clear();
_testClipboard.Clear();
var data = new DataObject();
var builder = new StringBuilder();
foreach (var block in blocks)
......@@ -772,7 +775,7 @@ private static void CopyToClipboard(BufferBlock[] blocks, bool includeRepl)
{
data.SetData(InteractiveWindow.ClipboardFormat, BufferBlock.Serialize(blocks));
}
Clipboard.SetDataObject(data, false);
_testClipboard.SetDataObject(data, false);
}
[Fact]
......@@ -1106,7 +1109,7 @@ public void ReturnWithSelectionInReadonlyArea()
AssertCaretVirtualPosition(3, 2);
}
[Fact(Skip = "5544"), WorkItem(5544, "https://github.com/dotnet/roslyn/issues/5544")]
[Fact]
public void CutWithOutSelectionInReadOnlyArea()
{
Submit(
......@@ -1115,8 +1118,8 @@ public void CutWithOutSelectionInReadOnlyArea()
");
Window.InsertCode("2");
var caret = Window.TextView.Caret;
Clipboard.Clear();
var caret = Window.TextView.Caret;
_testClipboard.Clear();
// Cut() with caret in readonly area, no-op
caret.MoveToPreviousCaretPosition();
......@@ -1141,7 +1144,7 @@ public void CutWithOutSelectionInReadOnlyArea()
VerifyClipboardData("2", expectedRtf: null, expectedRepl: null);
}
[Fact(Skip = "5544"), WorkItem(5544, "https://github.com/dotnet/roslyn/issues/5544")]
[Fact]
public void CutWithSelectionInReadonlyArea()
{
Submit(
......@@ -1152,7 +1155,7 @@ public void CutWithSelectionInReadonlyArea()
var caret = Window.TextView.Caret;
var selection = Window.TextView.Selection;
Clipboard.Clear();
_testClipboard.Clear();
// Cut() with selection in readonly area, no-op
......@@ -1200,7 +1203,7 @@ public void CutWithSelectionInReadonlyArea()
VerifyClipboardData("2", expectedRtf: null, expectedRepl: null);
}
[Fact(Skip = "5544"), WorkItem(5544, "https://github.com/dotnet/roslyn/issues/5544")]
[Fact]
public void PasteWithOutSelectionInReadOnlyArea()
{
Submit(
......@@ -1211,7 +1214,7 @@ public void PasteWithOutSelectionInReadOnlyArea()
var caret = Window.TextView.Caret;
Clipboard.Clear();
_testClipboard.Clear();
Window.Operations.Home(true);
Window.Operations.Copy();
VerifyClipboardData("2", @"\ansi{\fonttbl{\f0 Consolas;}}{\colortbl;\red0\green0\blue0;\red255\green255\blue255;}\f0 \fs24 \cf1 \cb2 \highlight2 2", @"[{""content"":""2"",""kind"":2}]");
......@@ -1236,7 +1239,7 @@ public void PasteWithOutSelectionInReadOnlyArea()
AssertCaretVirtualPosition(2, 3);
}
[Fact(Skip = "5544"), WorkItem(5544, "https://github.com/dotnet/roslyn/issues/5544")]
[Fact]
public void PasteWithSelectionInReadonlyArea()
{
Submit(
......@@ -1248,7 +1251,7 @@ public void PasteWithSelectionInReadonlyArea()
var caret = Window.TextView.Caret;
var selection = Window.TextView.Selection;
Clipboard.Clear();
_testClipboard.Clear();
Window.Operations.Home(true);
Window.Operations.Copy();
VerifyClipboardData("23", @"\ansi{\fonttbl{\f0 Consolas;}}{\colortbl;\red0\green0\blue0;\red255\green255\blue255;}\f0 \fs24 \cf1 \cb2 \highlight2 23", @"[{""content"":""23"",""kind"":2}]");
......@@ -1293,8 +1296,8 @@ public void PasteWithSelectionInReadonlyArea()
Task.Run(() => Window.Operations.Paste()).PumpingWait();
Assert.Equal("> 1\r\n1\r\n> 233", Window.TextView.TextBuffer.CurrentSnapshot.GetText());
AssertCaretVirtualPosition(2, 4);
}
}
private void Submit(string submission, string output)
{
Task.Run(() => Window.SubmitAsync(new[] { submission })).PumpingWait();
......@@ -1309,14 +1312,14 @@ private void Submit(string submission, string output)
}
}
private static void VerifyClipboardData(string expectedText, string expectedRtf, string expectedRepl)
private void VerifyClipboardData(string expectedText, string expectedRtf, string expectedRepl)
{
var data = Clipboard.GetDataObject();
Assert.Equal(expectedText, data.GetData(DataFormats.StringFormat));
Assert.Equal(expectedText, data.GetData(DataFormats.Text));
Assert.Equal(expectedText, data.GetData(DataFormats.UnicodeText));
Assert.Equal(expectedRepl, (string)data.GetData(InteractiveWindow.ClipboardFormat));
var actualRtf = (string)data.GetData(DataFormats.Rtf);
var data = _testClipboard.GetDataObject();
Assert.Equal(expectedText, data?.GetData(DataFormats.StringFormat));
Assert.Equal(expectedText, data?.GetData(DataFormats.Text));
Assert.Equal(expectedText, data?.GetData(DataFormats.UnicodeText));
Assert.Equal(expectedRepl, (string)data?.GetData(InteractiveWindow.ClipboardFormat));
var actualRtf = (string)data?.GetData(DataFormats.Rtf);
if (expectedRtf == null)
{
Assert.Null(actualRtf);
......
// 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.Windows;
namespace Microsoft.VisualStudio.InteractiveWindow.UnitTests
{
internal sealed class TestClipboard : InteractiveWindowClipboard
{
DataObject _data = null;
internal void Clear() => _data = null;
internal IDataObject GetDataObject() => _data;
internal override bool ContainsData(string format) => _data?.GetData(format) != null;
internal override object GetData(string format) => _data?.GetData(format);
internal override bool ContainsText() => _data != null ? _data.ContainsText() : false;
internal override string GetText() => _data?.GetText();
internal override void SetDataObject(object data, bool copy) => _data = (DataObject)data;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册