|
// 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.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.Editor.CSharp.SplitStringLiteral;
using Microsoft.CodeAnalysis.Editor.Implementation.SplitComment;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.UnitTests.Extensions;
using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor.Commanding.Commands;
using Microsoft.VisualStudio.Text.Operations;
using Roslyn.Test.Utilities;
using Xunit;
using static Microsoft.CodeAnalysis.Formatting.FormattingOptions;
namespace Microsoft.CodeAnalysis.Editor.UnitTests.SplitComment
{
public abstract class AbstractSplitCommentCommandHandlerTests
{
protected abstract TestWorkspace CreateWorkspace(string markup);
/// <summary>
/// verifyUndo is needed because of https://github.com/dotnet/roslyn/issues/28033
/// Most tests will continue to verifyUndo, but select tests will skip it due to
/// this known test infrastructure issue. This bug does not represent a product
/// failure.
/// </summary>
private void TestWorker(
string inputMarkup,
string? expectedOutputMarkup,
Action callback,
bool enabled,
bool useTabs)
{
if (useTabs)
{
// Make sure the tests seem well formed (i.e. no one accidentally replaced the tabs in them with spaces.
Assert.True(inputMarkup.Contains("\t"));
if (expectedOutputMarkup != null)
Assert.True(expectedOutputMarkup.Contains("\t"));
}
using var workspace = CreateWorkspace(inputMarkup);
var globalOptions = workspace.GlobalOptions;
var language = workspace.Projects.Single().Language;
globalOptions.SetGlobalOption(SplitCommentOptionsStorage.Enabled, language, enabled);
globalOptions.SetGlobalOption(FormattingOptions2.UseTabs, language, useTabs);
var document = workspace.Documents.Single();
var view = document.GetTextView();
var originalSnapshot = view.TextBuffer.CurrentSnapshot;
var originalSelections = document.SelectedSpans;
var snapshotSpans = new List<SnapshotSpan>();
foreach (var selection in originalSelections)
snapshotSpans.Add(new SnapshotSpan(originalSnapshot, new Span(selection.Start, selection.Length)));
view.SetMultiSelection(snapshotSpans);
var undoHistoryRegistry = workspace.GetService<ITextUndoHistoryRegistry>();
var commandHandler = workspace.ExportProvider.GetCommandHandler<SplitCommentCommandHandler>(nameof(SplitCommentCommandHandler));
if (!commandHandler.ExecuteCommand(new ReturnKeyCommandArgs(view, view.TextBuffer), TestCommandExecutionContext.Create()))
{
callback();
}
if (expectedOutputMarkup != null)
{
MarkupTestFile.GetSpans(expectedOutputMarkup,
out var expectedOutput, out ImmutableArray<TextSpan> expectedSpans);
Assert.Equal(expectedOutput, view.TextBuffer.CurrentSnapshot.AsText().ToString());
// Ensure that after undo we go back to where we were to begin with.
var history = undoHistoryRegistry.GetHistory(document.GetTextBuffer());
history.Undo(count: originalSelections.Count);
var currentSnapshot = document.GetTextBuffer().CurrentSnapshot;
Assert.Equal(originalSnapshot.GetText(), currentSnapshot.GetText());
}
}
/// <summary>
/// verifyUndo is needed because of https://github.com/dotnet/roslyn/issues/28033
/// Most tests will continue to verifyUndo, but select tests will skip it due to
/// this known test infrastructure issue. This bug does not represent a product
/// failure.
/// </summary>
protected void TestHandled(string inputMarkup, string expectedOutputMarkup, bool enabled = true, bool useTabs = false)
{
TestWorker(
inputMarkup, expectedOutputMarkup,
callback: () =>
{
Assert.True(false, "Should not reach here.");
}, enabled, useTabs);
}
protected void TestNotHandled(string inputMarkup, bool enabled = true, bool useTabs = false)
{
var notHandled = false;
TestWorker(
inputMarkup, null,
callback: () =>
{
notHandled = true;
}, enabled, useTabs);
Assert.True(notHandled);
}
}
}
|