private static void TestHandled(
     string inputMarkup, string expectedOutputMarkup,
     bool verifyUndo = true, IndentStyle indentStyle = IndentStyle.Smart,
     bool useTabs    = false)
 {
     TestWorker(
         inputMarkup, expectedOutputMarkup,
         callback: () =>
     {
         Assert.True(false, "Should not reach here.");
     },
         verifyUndo, indentStyle, useTabs);
 }
        private static void TestWorker(
            string inputMarkup,
            string expectedOutputMarkup,
            Action callback,
            bool verifyUndo         = true,
            IndentStyle indentStyle = IndentStyle.Smart,
            bool useTabs            = false)
        {
            using var workspace = TestWorkspace.CreateCSharp(inputMarkup);

            // TODO: set SmartIndent to textView.Options (https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1412138)
            workspace.TryApplyChanges(workspace.CurrentSolution.WithOptions(workspace.Options
                                                                            .WithChangedOption(FormattingOptions2.SmartIndent, LanguageNames.CSharp, indentStyle)));

            if (useTabs && expectedOutputMarkup != null)
            {
                Assert.Contains("\t", expectedOutputMarkup);
            }

            var document = workspace.Documents.Single();
            var view     = document.GetTextView();

            view.Options.SetOptionValue(DefaultOptions.ConvertTabsToSpacesOptionId, !useTabs);
            view.Options.SetOptionValue(DefaultOptions.TabSizeOptionId, 4);

            var originalSnapshot   = view.TextBuffer.CurrentSnapshot;
            var originalSelections = document.SelectedSpans;

            var snapshotSpans = new List <SnapshotSpan>();

            foreach (var selection in originalSelections)
            {
                snapshotSpans.Add(selection.ToSnapshotSpan(originalSnapshot));
            }

            view.SetMultiSelection(snapshotSpans);

            var undoHistoryRegistry = workspace.GetService <ITextUndoHistoryRegistry>();
            var commandHandler      = workspace.ExportProvider.GetCommandHandler <SplitStringLiteralCommandHandler>(nameof(SplitStringLiteralCommandHandler));

            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());
                Assert.Equal(expectedSpans.First().Start, view.Caret.Position.BufferPosition.Position);

                if (verifyUndo)
                {
                    // 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());
                    Assert.Equal(originalSelections.First().Start, view.Caret.Position.BufferPosition.Position);
                }
            }
        }
        private static void TestWorker(
            string inputMarkup,
            string expectedOutputMarkup,
            Action callback,
            bool verifyUndo         = true,
            IndentStyle indentStyle = IndentStyle.Smart,
            bool useTabs            = false)
        {
            using var workspace = TestWorkspace.CreateCSharp(inputMarkup);

            if (useTabs && expectedOutputMarkup != null)
            {
                Assert.Contains("\t", expectedOutputMarkup);
            }

            var editorOptionsFactory = workspace.GetService <IEditorOptionsFactoryService>();

            var document   = workspace.Documents.Single();
            var view       = document.GetTextView();
            var textBuffer = view.TextBuffer;
            var options    = editorOptionsFactory.GetOptions(textBuffer);

            options.SetOptionValue(DefaultOptions.ConvertTabsToSpacesOptionId, !useTabs);
            options.SetOptionValue(DefaultOptions.TabSizeOptionId, 4);
            options.SetOptionValue(DefaultOptions.IndentStyleId, indentStyle.ToEditorIndentStyle());

            // Remove once https://github.com/dotnet/roslyn/issues/62204 is fixed:
            workspace.GlobalOptions.SetGlobalOption(new OptionKey(IndentationOptionsStorage.SmartIndent, document.Project.Language), indentStyle);

            var originalSnapshot   = textBuffer.CurrentSnapshot;
            var originalSelections = document.SelectedSpans;

            var snapshotSpans = new List <SnapshotSpan>();

            foreach (var selection in originalSelections)
            {
                snapshotSpans.Add(selection.ToSnapshotSpan(originalSnapshot));
            }

            view.SetMultiSelection(snapshotSpans);

            var undoHistoryRegistry = workspace.GetService <ITextUndoHistoryRegistry>();
            var commandHandler      = workspace.ExportProvider.GetCommandHandler <SplitStringLiteralCommandHandler>(nameof(SplitStringLiteralCommandHandler));

            if (!commandHandler.ExecuteCommand(new ReturnKeyCommandArgs(view, textBuffer), TestCommandExecutionContext.Create()))
            {
                callback();
            }

            if (expectedOutputMarkup != null)
            {
                MarkupTestFile.GetSpans(expectedOutputMarkup,
                                        out var expectedOutput, out ImmutableArray <TextSpan> expectedSpans);

                Assert.Equal(expectedOutput, textBuffer.CurrentSnapshot.AsText().ToString());
                Assert.Equal(expectedSpans.First().Start, view.Caret.Position.BufferPosition.Position);

                if (verifyUndo)
                {
                    // 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());
                    Assert.Equal(originalSelections.First().Start, view.Caret.Position.BufferPosition.Position);
                }
            }
        }