// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

import 'clipboard_utils.dart';
import 'keyboard_utils.dart';

Iterable<SingleActivator> allModifierVariants(LogicalKeyboardKey trigger) {
  const Iterable<bool> trueFalse = <bool>[false, true];
  return trueFalse.expand((bool shift) {
    return trueFalse.expand((bool control) {
      return trueFalse.expand((bool alt) {
        return trueFalse.map((bool meta) => SingleActivator(trigger, shift: shift, control: control, alt: alt, meta: meta));
      });
    });
  });
}

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();
  final MockClipboard mockClipboard = MockClipboard();

  setUp(() async {
    TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
    await Clipboard.setData(const ClipboardData(text: 'empty'));
  });

  tearDown(() {
    TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
  });

  const String testText =
      'Now is the time for\n' // 20
      'all good people\n'     // 20 + 16 => 36
      'to come to the aid\n'  // 36 + 19 => 55
      'of their country.';    // 55 + 17 => 72
  const String testCluster = '👨‍👩‍👦👨‍👩‍👦👨‍👩‍👦'; // 8 * 3

  // Exactly 20 characters each line.
  const String testSoftwrapText =
      '0123456789ABCDEFGHIJ'
      '0123456789ABCDEFGHIJ'
      '0123456789ABCDEFGHIJ'
      '0123456789ABCDEFGHIJ';

  const String testVerticalText = '1\n2\n3\n4\n5\n6\n7\n8\n9';
  final TextEditingController controller = TextEditingController(text: testText);

  final FocusNode focusNode = FocusNode();
  Widget buildEditableText({
    TextAlign textAlign = TextAlign.left,
    bool readOnly = false,
    bool obscured = false,
    TextStyle style = const TextStyle(fontSize: 10.0),
  }) {
    return MaterialApp(
      home: Align(
        alignment: Alignment.topLeft,
        child: SizedBox(
          // Softwrap at exactly 20 characters.
          width: 201,
          height: 200,
          child: EditableText(
            controller: controller,
            showSelectionHandles: true,
            autofocus: true,
            focusNode: focusNode,
            style: style,
            textScaleFactor: 1,
            // Avoid the cursor from taking up width.
            cursorWidth: 0,
            cursorColor: Colors.blue,
            backgroundCursorColor: Colors.grey,
            selectionControls: materialTextSelectionControls,
            keyboardType: TextInputType.text,
            maxLines: obscured ? 1 : null,
            readOnly: readOnly,
            textAlign: textAlign,
            obscureText: obscured,
          ),
        ),
      ),
    );
  }

  testWidgets(
    'Movement/Deletion shortcuts do nothing when the selection is invalid',
    (WidgetTester tester) async {
      await tester.pumpWidget(buildEditableText());
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(offset: -1);
      await tester.pump();

      const List<LogicalKeyboardKey> triggers = <LogicalKeyboardKey>[
        LogicalKeyboardKey.backspace,
        LogicalKeyboardKey.delete,
        LogicalKeyboardKey.arrowLeft,
        LogicalKeyboardKey.arrowRight,
        LogicalKeyboardKey.arrowUp,
        LogicalKeyboardKey.arrowDown,
        LogicalKeyboardKey.pageUp,
        LogicalKeyboardKey.pageDown,
        LogicalKeyboardKey.home,
        LogicalKeyboardKey.end,
      ];

      for (final SingleActivator activator in triggers.expand(allModifierVariants)) {
        await sendKeyCombination(tester, activator);
        await tester.pump();
        expect(controller.text, testText, reason: activator.toString());
        expect(controller.selection, const TextSelection.collapsed(offset: -1), reason: activator.toString());
      }
    },
    skip: kIsWeb, // [intended] on web these keys are handled by the browser.
    variant: TargetPlatformVariant.all(),
  );

  group('Common text editing shortcuts: ',
    () {
      final TargetPlatformVariant allExceptApple = TargetPlatformVariant.all(excluding: <TargetPlatform>{TargetPlatform.macOS, TargetPlatform.iOS});

      group('backspace', () {
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.backspace;

        testWidgets('backspace', (WidgetTester tester) async {
          controller.text = testText;
          // Move the selection to the beginning of the 2nd line (after the newline
          // character).
          controller.selection = const TextSelection.collapsed(
            offset: 20,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            'Now is the time forall good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 19),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('backspace readonly', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 20,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText(readOnly: true));
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(controller.text, testText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 20, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('backspace at start', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 0,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('backspace at end', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 72,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 71),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('backspace inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 1,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('backspace at cluster boundary', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 8,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());
      });

      group('delete: ', () {
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.delete;

        testWidgets('delete', (WidgetTester tester) async {
          controller.text = testText;
          // Move the selection to the beginning of the 2nd line (after the newline
          // character).
          controller.selection = const TextSelection.collapsed(
            offset: 20,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            'Now is the time for\n'
            'll good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 20),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('delete readonly', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 20,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText(readOnly: true));
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(controller.text, testText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 20, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('delete at start', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 0,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            'ow is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('delete at end', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 72,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 72, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('delete inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 1,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('delete at cluster boundary', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 8,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 8),
          );
        }, variant: TargetPlatformVariant.all());
      });

      group('Non-collapsed delete', () {
        // This shares the same logic as backspace.
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.delete;

        testWidgets('inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection(
            baseOffset: 9,
            extentOffset: 12,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 8),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at the boundaries of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection(
            baseOffset: 8,
            extentOffset: 16,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 8),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('cross-cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection(
            baseOffset: 1,
            extentOffset: 9,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('cross-cluster obscured text', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection(
            baseOffset: 1,
            extentOffset: 9,
          );

          await tester.pumpWidget(buildEditableText(obscured: true));
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 1),
          );
        }, variant: TargetPlatformVariant.all());
      });

      group('word modifier + backspace', () {
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.backspace;
        SingleActivator wordModifierBackspace() {
          final bool isApple = defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.iOS;
          return SingleActivator(trigger, control: !isApple, alt: isApple);
        }

        testWidgets('WordModifier-backspace', (WidgetTester tester) async {
          controller.text = testText;
          // Place the caret before "people".
          controller.selection = const TextSelection.collapsed(
            offset: 29,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierBackspace());

          expect(
            controller.text,
            'Now is the time for\n'
            'all people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 24),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('readonly', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 29,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText(readOnly: true));
          await sendKeyCombination(tester, wordModifierBackspace());

          expect(controller.text, testText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 29, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at start', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 0,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierBackspace());

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at end', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 72,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierBackspace());

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 71),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 1,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierBackspace());

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at cluster boundary', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 8,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierBackspace());

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());
      });

      group('word modifier + delete', () {
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.delete;
        SingleActivator wordModifierDelete() {
          final bool isApple = defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.iOS;
          return SingleActivator(trigger, control: !isApple, alt: isApple);
        }

        testWidgets('WordModifier-delete', (WidgetTester tester) async {
          controller.text = testText;
          // Place the caret after "all".
          controller.selection = const TextSelection.collapsed(
            offset: 23,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierDelete());

          expect(
            controller.text,
            'Now is the time for\n'
            'all people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 23),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('readonly', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 23,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText(readOnly: true));
          await sendKeyCombination(tester, wordModifierDelete());

          expect(controller.text, testText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 23, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at start', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 0,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierDelete());

          expect(
            controller.text,
            ' is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at end', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 72,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierDelete());

          expect(controller.text, testText);
          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 72, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 1,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierDelete());

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at cluster boundary', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 8,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierDelete());

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 8),
          );
        }, variant: TargetPlatformVariant.all());
      });

      group('line modifier + backspace', () {
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.backspace;
        SingleActivator lineModifierBackspace() {
          final bool isApple = defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.iOS;
          return SingleActivator(trigger, meta: isApple, alt: !isApple);
        }

        testWidgets('alt-backspace', (WidgetTester tester) async {
          controller.text = testText;
          // Place the caret before "people".
          controller.selection = const TextSelection.collapsed(
            offset: 29,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.text,
            'Now is the time for\n'
            'people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 20),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('softwrap line boundary, upstream', (WidgetTester tester) async {
          controller.text = testSoftwrapText;
          // Place the caret at the beginning of the 3rd line.
          controller.selection = const TextSelection.collapsed(
            offset: 40,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.text,
            '0123456789ABCDEFGHIJ'
            '0123456789ABCDEFGHIJ'
            '0123456789ABCDEFGHIJ'
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 20),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('softwrap line boundary, downstream', (WidgetTester tester) async {
          controller.text = testSoftwrapText;
          // Place the caret at the beginning of the 3rd line.
          controller.selection = const TextSelection.collapsed(
            offset: 40,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(controller.text, testSoftwrapText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 40),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('readonly', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 29,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText(readOnly: true));
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(controller.text, testText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 29, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at start', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 0,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at end', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 72,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 55),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 1,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at cluster boundary', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 8,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());
      });

      group('line modifier + delete', () {
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.delete;
        SingleActivator lineModifierDelete() {
          final bool isApple = defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.iOS;
          return SingleActivator(trigger, meta: isApple, alt: !isApple);
        }

        testWidgets('alt-delete', (WidgetTester tester) async {
          controller.text = testText;
          // Place the caret after "all".
          controller.selection = const TextSelection.collapsed(
            offset: 23,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(
            controller.text,
            'Now is the time for\n'
            'all\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 23),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('softwrap line boundary, upstream', (WidgetTester tester) async {
          controller.text = testSoftwrapText;
          // Place the caret at the beginning of the 3rd line.
          controller.selection = const TextSelection.collapsed(
            offset: 40,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(controller.text, testSoftwrapText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 40, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('softwrap line boundary, downstream', (WidgetTester tester) async {
          controller.text = testSoftwrapText;
          // Place the caret at the beginning of the 3rd line.
          controller.selection = const TextSelection.collapsed(
            offset: 40,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(
            controller.text,
            '0123456789ABCDEFGHIJ'
            '0123456789ABCDEFGHIJ'
            '0123456789ABCDEFGHIJ'
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 40),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('readonly', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 23,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText(readOnly: true));
          await sendKeyCombination(tester, lineModifierDelete());

          expect(controller.text, testText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 23, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at start', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 0,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(
            controller.text,
            '\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at end', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 72,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(controller.text, testText);
          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 72, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 1,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(
            controller.text,
            isEmpty,
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at cluster boundary', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 8,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(
            controller.text,
            '👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 8),
          );
        }, variant: TargetPlatformVariant.all());
      });

      group('Arrow Movement', () {
        group('left', () {
          const LogicalKeyboardKey trigger = LogicalKeyboardKey.arrowLeft;

          testWidgets('at start', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 0,
            );

            await tester.pumpWidget(buildEditableText());

            for (final SingleActivator activator in allModifierVariants(trigger)) {
              await sendKeyCombination(tester, activator);
              await tester.pump();

              expect(
                controller.selection,
                const TextSelection.collapsed(offset: 0),
                reason: activator.toString(),
              );
            }
          }, variant: TargetPlatformVariant.all());

          testWidgets('base arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 20,
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(trigger));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 19,
            ));
          }, variant: TargetPlatformVariant.all());

          testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 7,   // Before the first "the"
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(trigger, control: true));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 4,
            ));
          }, variant: allExceptApple);

          testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 24,   // Before the "good".
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(trigger, alt: true));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 20,
            ));
          }, variant: allExceptApple);
        });

        group('right', () {
          const LogicalKeyboardKey trigger = LogicalKeyboardKey.arrowRight;

          testWidgets('at end', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 72,
            );

            await tester.pumpWidget(buildEditableText());

            for (final SingleActivator activator in allModifierVariants(trigger)) {
              await sendKeyCombination(tester, activator);
              await tester.pump();

              expect(controller.selection.isCollapsed, isTrue, reason: activator.toString());
              expect(controller.selection.baseOffset, 72, reason: activator.toString());
            }
          }, variant: TargetPlatformVariant.all());

          testWidgets('base arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 20,
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(trigger));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 21,
              affinity: TextAffinity.upstream,
            ));
          }, variant: TargetPlatformVariant.all());

          testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 7,   // Before the first "the"
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(trigger, control: true));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 10,
              affinity: TextAffinity.upstream,
            ));
          }, variant: allExceptApple);

         testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 24,   // Before the "good".
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(trigger, alt: true));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 35, // Before the newline character.
              affinity: TextAffinity.upstream,
            ));
          }, variant: allExceptApple);
        });

        group('With initial non-collapsed selection', () {
          testWidgets('base arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            // The word "all" is selected.
            controller.selection = const TextSelection(
              baseOffset: 20,
              extentOffset: 23,
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 20,
            ));

            // The word "all" is selected.
            controller.selection = const TextSelection(
              baseOffset: 23,
              extentOffset: 20,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 20,
            ));

            // The word "all" is selected.
            controller.selection = const TextSelection(
              baseOffset: 20,
              extentOffset: 23,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 23,
            ));

            // The word "all" is selected.
            controller.selection = const TextSelection(
              baseOffset: 23,
              extentOffset: 20,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 23,
            ));
          }, variant: TargetPlatformVariant.all());

          testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 24,
              extentOffset: 43,
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, control: true));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 39, // Before "come".
            ));

            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 43,
              extentOffset: 24,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, control: true));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 20, // Before "all".
              //offset: 39, // Before "come".
            ));

            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 24,
              extentOffset: 43,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, control: true));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 46, // After "to".
              affinity: TextAffinity.upstream,
            ));

            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 43,
              extentOffset: 24,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, control: true));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 28, // After "good".
              affinity: TextAffinity.upstream,
            ));
          }, variant: allExceptApple);

         testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 24,
              extentOffset: 43,
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 36, // Before "to".
            ));

            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 43,
              extentOffset: 24,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 20, // Before "all".
            ));

            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 24,
              extentOffset: 43,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 54, // After "aid".
              affinity: TextAffinity.upstream,
            ));

            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 43,
              extentOffset: 24,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 35, // After "people".
              affinity: TextAffinity.upstream,
            ));
          }, variant: allExceptApple);
        });

        group('vertical movement', () {
          testWidgets('at start', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 0,
            );

            await tester.pumpWidget(buildEditableText());

            for (final SingleActivator activator in allModifierVariants(LogicalKeyboardKey.arrowUp)) {
              await sendKeyCombination(tester, activator);
              await tester.pump();

              expect(controller.text, testText);
              expect(
                controller.selection,
                const TextSelection.collapsed(offset: 0),
                reason: activator.toString(),
              );
            }

            for (final SingleActivator activator in allModifierVariants(LogicalKeyboardKey.pageUp)) {
              await sendKeyCombination(tester, activator);
              await tester.pump();

              expect(controller.text, testText);
              expect(
                controller.selection,
                const TextSelection.collapsed(offset: 0),
                reason: activator.toString(),
              );
            }
          }, variant: TargetPlatformVariant.all());

          testWidgets('at end', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 72,
            );

            await tester.pumpWidget(buildEditableText());

            for (final SingleActivator activator in allModifierVariants(LogicalKeyboardKey.arrowDown)) {
              await sendKeyCombination(tester, activator);
              await tester.pump();

              expect(controller.text, testText);
              expect(controller.selection.baseOffset, 72, reason: activator.toString());
              expect(controller.selection.extentOffset, 72, reason: activator.toString());
            }

            for (final SingleActivator activator in allModifierVariants(LogicalKeyboardKey.pageDown)) {
              await sendKeyCombination(tester, activator);
              await tester.pump();

              expect(controller.text, testText);
              expect(controller.selection.baseOffset, 72, reason: activator.toString());
              expect(controller.selection.extentOffset, 72, reason: activator.toString());
            }
          }, variant: TargetPlatformVariant.all());

          testWidgets('run', (WidgetTester tester) async {
            controller.text =
              'aa\n'     // 3
              'a\n'      // 3 + 2 = 5
              'aa\n'     // 5 + 3 = 8
              'aaa\n'    // 8 + 4 = 12
              'aaaa';    // 12 + 4 = 16

            controller.selection = const TextSelection.collapsed(
              offset: 2,
            );
            await tester.pumpWidget(buildEditableText());
            await tester.pump(); // Wait for autofocus to take effect.

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 4,
              affinity: TextAffinity.upstream,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 7,
              affinity: TextAffinity.upstream,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 10,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 14,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 16,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 10,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 7,
              affinity: TextAffinity.upstream,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 4,
              affinity: TextAffinity.upstream,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 2,
              affinity: TextAffinity.upstream,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 0,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 4,
              affinity: TextAffinity.upstream,
            ));
          }, variant: TargetPlatformVariant.all());

          testWidgets('run with page down/up', (WidgetTester tester) async {
            controller.text =
              'aa\n'     // 3
              'a\n'      // 3 + 2 = 5
              'aa\n'     // 5 + 3 = 8
              'aaa\n'    // 8 + 4 = 12
              '${"aaa\n" * 50}'
              'aaaa';

            controller.selection = const TextSelection.collapsed(offset: 2);
            await tester.pumpWidget(buildEditableText());

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 4,
              affinity: TextAffinity.upstream,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.pageDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(offset: 82));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(offset: 78));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.pageUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 2,
              affinity: TextAffinity.upstream,
            ));
          }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{TargetPlatform.iOS, TargetPlatform.macOS})); // intended: on macOS Page Up/Down only scrolls

          testWidgets('run can be interrupted by layout changes', (WidgetTester tester) async {
            controller.text =
              'aa\n'     // 3
              'a\n'      // 3 + 2 = 5
              'aa\n'     // 5 + 3 = 8
              'aaa\n'    // 8 + 4 = 12
              'aaaa';    // 12 + 4 = 16

            controller.selection = const TextSelection.collapsed(
              offset: 2,
            );
            await tester.pumpWidget(buildEditableText());

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 0,
            ));

            // Layout changes.
            await tester.pumpWidget(buildEditableText(textAlign: TextAlign.right));
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 3,
            ));
          }, variant: TargetPlatformVariant.all());

          testWidgets('run can be interrupted by selection changes', (WidgetTester tester) async {
            controller.text =
              'aa\n'     // 3
              'a\n'      // 3 + 2 = 5
              'aa\n'     // 5 + 3 = 8
              'aaa\n'    // 8 + 4 = 12
              'aaaa';    // 12 + 4 = 16

            controller.selection = const TextSelection.collapsed(
              offset: 2,
            );
            await tester.pumpWidget(buildEditableText());

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 0,
            ));

            controller.selection = const TextSelection.collapsed(
              offset: 1,
            );
            await tester.pump();
            controller.selection = const TextSelection.collapsed(
              offset: 0,
            );
            await tester.pump();

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 3,   // Would have been 4 if the run wasn't interrupted.
            ));
          }, variant: TargetPlatformVariant.all());

          testWidgets('long run with fractional text height', (WidgetTester tester) async {
            controller.text = "${'źdźbło\n' * 49}źdźbło";
            controller.selection = const TextSelection.collapsed(offset: 2);
            await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 13.0, height: 1.17)));

            for (int i = 1; i <= 49; i++) {
              await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
              await tester.pump();
              expect(
                controller.selection,
                TextSelection.collapsed(offset: 2 + i * 7),
                reason: 'line $i',
              );
            }

            for (int i = 49; i >= 1; i--) {
              await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
              await tester.pump();
              expect(
                controller.selection,
                TextSelection.collapsed(offset: 2 + (i - 1) * 7),
                reason: 'line $i',
              );
            }
          }, variant: TargetPlatformVariant.all());
        });
      });
    },
    skip: kIsWeb, // [intended] on web these keys are handled by the browser.
  );

  group('macOS shortcuts', () {
    final TargetPlatformVariant macOSOnly = TargetPlatformVariant.only(TargetPlatform.macOS);

    testWidgets('word modifier + arrowLeft', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 7,   // Before the first "the"
      );
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(
        offset: 4,
      ));
    }, variant: macOSOnly);

    testWidgets('word modifier + arrowRight', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 7,   // Before the first "the"
      );
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(
        offset: 10,
        affinity: TextAffinity.upstream,
      ));
    }, variant: macOSOnly);

    testWidgets('line modifier + arrowLeft', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 24,   // Before the "good".
      );
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(
        offset: 20,
      ));
    }, variant: macOSOnly);

    testWidgets('line modifier + arrowRight', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 24,   // Before the "good".
      );
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(
        offset: 35, // Before the newline character.
        affinity: TextAffinity.upstream,
      ));
    }, variant: macOSOnly);

    testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
      controller.text = testText;
      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 24,
        extentOffset: 43,
      );
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(
        offset: 39, // Before "come".
      ));

      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 43,
        extentOffset: 24,
      );
      await tester.pump();
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(
        offset: 20, // Before "all".
        //offset: 39, // Before "come".
      ));

      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 24,
        extentOffset: 43,
      );
      await tester.pump();
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(
        offset: 46, // After "to".
        affinity: TextAffinity.upstream,
      ));

      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 43,
        extentOffset: 24,
      );
      await tester.pump();
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(
        offset: 28, // After "good".
        affinity: TextAffinity.upstream,
      ));
    }, variant: macOSOnly);

    testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
      controller.text = testText;
      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 24,
        extentOffset: 43,
      );
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(
        offset: 36, // Before "to".
      ));

      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 43,
        extentOffset: 24,
      );
      await tester.pump();
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(
        offset: 20, // Before "all".
      ));

      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 24,
        extentOffset: 43,
      );
      await tester.pump();
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(
        offset: 54, // After "aid".
        affinity: TextAffinity.upstream,
      ));

      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 43,
        extentOffset: 24,
      );
      await tester.pump();
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(
        offset: 35, // After "people".
        affinity: TextAffinity.upstream,
      ));
    }, variant: macOSOnly);
  }, skip: kIsWeb); // [intended] on web these keys are handled by the browser.

  group('Web does not accept', () {
    final TargetPlatformVariant allExceptApple = TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS });
    const TargetPlatformVariant appleOnly = TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS, TargetPlatform.iOS });
    group('macOS shortcuts', () {

      testWidgets('word modifier + arrowLeft', (WidgetTester tester) async {
        controller.text = testText;
        controller.selection = const TextSelection.collapsed(
          offset: 7,   // Before the first "the"
        );
        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
        await tester.pump();

        expect(controller.selection, const TextSelection.collapsed(offset: 7));
      }, variant: appleOnly);

      testWidgets('word modifier + arrowRight', (WidgetTester tester) async {
        controller.text = testText;
        controller.selection = const TextSelection.collapsed(
          offset: 7,   // Before the first "the"
        );
        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
        await tester.pump();

        expect(controller.selection, const TextSelection.collapsed(offset: 7));
      }, variant: appleOnly);

      testWidgets('line modifier + arrowLeft', (WidgetTester tester) async {
        controller.text = testText;
        controller.selection = const TextSelection.collapsed(
          offset: 24,   // Before the "good".
        );
        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true));
        await tester.pump();

        expect(controller.selection, const TextSelection.collapsed(offset: 24,));
      }, variant: appleOnly);

      testWidgets('line modifier + arrowRight', (WidgetTester tester) async {
        controller.text = testText;
        controller.selection = const TextSelection.collapsed(
          offset: 24,   // Before the "good".
        );
        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true));
        await tester.pump();

        expect(controller.selection, const TextSelection.collapsed(
          offset: 24, // Before the newline character.
        ));
      }, variant: appleOnly);

      testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
        controller.text = testText;
        controller.selection = const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        );
        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
        await tester.pump();

        expect(controller.selection, const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        ));

        controller.selection = const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        );
        await tester.pump();
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
        await tester.pump();
        expect(controller.selection, const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        ));

        controller.selection = const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        );
        await tester.pump();
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
        await tester.pump();
        expect(controller.selection, const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        ));

        // "good" to "come" is selected.
        controller.selection = const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        );
        await tester.pump();
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
        await tester.pump();
        expect(controller.selection, const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        ));
      }, variant: appleOnly);

      testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
        controller.text = testText;
        // "good" to "come" is selected.
        controller.selection = const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        );
        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true));
        await tester.pump();

        expect(controller.selection, const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        ));

        // "good" to "come" is selected.
        controller.selection = const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        );
        await tester.pump();
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true));
        await tester.pump();
        expect(controller.selection, const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        ));

        // "good" to "come" is selected.
        controller.selection = const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        );
        await tester.pump();
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true));
        await tester.pump();
        expect(controller.selection, const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        ));

        // "good" to "come" is selected.
        controller.selection = const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        );
        await tester.pump();
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true));
        await tester.pump();
        expect(controller.selection, const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        ));
      }, variant: appleOnly);
    });

    testWidgets('vertical movement outside of selection',
        (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 0,
      );

      await tester.pumpWidget(buildEditableText());

      for (final SingleActivator activator in allModifierVariants(LogicalKeyboardKey.arrowDown)) {
        // Skip for the shift shortcut since web accepts it.
        if (activator.shift) {
          continue;
        }
        await sendKeyCombination(tester, activator);
        await tester.pump();

        expect(controller.text, testText);
        expect(
          controller.selection,
          const TextSelection.collapsed(offset: 0),
          reason: activator.toString(),
        );
      }
    }, variant: TargetPlatformVariant.all());

    testWidgets('horizontal movement', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 0,
      );

      await tester.pumpWidget(buildEditableText());

      for (final SingleActivator activator in allModifierVariants(LogicalKeyboardKey.arrowRight)) {
        await sendKeyCombination(tester, activator);
        await tester.pump();

        expect(controller.selection, const TextSelection.collapsed(offset: 0));
      }
    }, variant: TargetPlatformVariant.all());

    testWidgets('select all non apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 0,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyA, control: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(offset: 0));
    }, variant: allExceptApple);

    testWidgets('select all apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 0,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyA, meta: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(offset: 0));
    }, variant: appleOnly);

    testWidgets('copy non apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection(
        baseOffset: 0,
        extentOffset: 4,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyC, control: true));
      await tester.pump();

      final Map<String, dynamic> clipboardData = mockClipboard.clipboardData as Map<String, dynamic>;
      expect(clipboardData['text'], 'empty');
    }, variant: allExceptApple);

    testWidgets('copy apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection(
        baseOffset: 0,
        extentOffset: 4,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyC, meta: true));
      await tester.pump();

      final Map<String, dynamic> clipboardData = mockClipboard.clipboardData as Map<String, dynamic>;
      expect(clipboardData['text'], 'empty');
    }, variant: appleOnly);

    testWidgets('cut non apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection(
        baseOffset: 0,
        extentOffset: 4,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyX, control: true));
      await tester.pump();

      final Map<String, dynamic> clipboardData = mockClipboard.clipboardData as Map<String, dynamic>;
      expect(clipboardData['text'], 'empty');
      expect(controller.selection, const TextSelection(
        baseOffset: 0,
        extentOffset: 4,
      ));
    }, variant: allExceptApple);

    testWidgets('cut apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection(
        baseOffset: 0,
        extentOffset: 4,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyX, meta: true));
      await tester.pump();

      final Map<String, dynamic> clipboardData = mockClipboard.clipboardData as Map<String, dynamic>;
      expect(clipboardData['text'], 'empty');
      expect(controller.selection, const TextSelection(
        baseOffset: 0,
        extentOffset: 4,
      ));
    }, variant: appleOnly);

    testWidgets('paste non apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(offset: 0);
      mockClipboard.clipboardData = <String, dynamic>{
        'text': 'some text',
      };
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyV, control: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(offset: 0));
      expect(controller.text, testText);
    }, variant: allExceptApple);

    testWidgets('paste apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(offset: 0);
      mockClipboard.clipboardData = <String, dynamic>{
        'text': 'some text',
      };
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyV, meta: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(offset: 0));
      expect(controller.text, testText);
    }, variant: appleOnly);

  }, skip: !kIsWeb);// [intended] specific tests target web.

  group('Web does accept', () {
      testWidgets('select up', (WidgetTester tester) async {
        const SingleActivator selectUp =
            SingleActivator(LogicalKeyboardKey.arrowUp, shift: true);
        controller.text = testVerticalText;
        controller.selection = const TextSelection.collapsed(
          offset: 5,
        );

        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, selectUp);
        await tester.pump();

        expect(controller.text, testVerticalText);
        expect(
          controller.selection,
          const TextSelection(
              baseOffset: 5,
              extentOffset: 3), // selection extends upwards from 5
          reason: selectUp.toString(),
        );
      }, variant: TargetPlatformVariant.desktop());

      testWidgets('select down', (WidgetTester tester) async {
        const SingleActivator selectDown =
            SingleActivator(LogicalKeyboardKey.arrowDown, shift: true);
        controller.text = testVerticalText;
        controller.selection = const TextSelection.collapsed(
          offset: 5,
        );

        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, selectDown);
        await tester.pump();

        expect(controller.text, testVerticalText);
        expect(
          controller.selection,
          const TextSelection(
              baseOffset: 5,
              extentOffset: 7), // selection extends downwards from 5
          reason: selectDown.toString(),
        );
      }, variant: TargetPlatformVariant.desktop());

      testWidgets('select all up', (WidgetTester tester) async {
        final bool isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
        final SingleActivator selectAllUp = isMacOS
            ? const SingleActivator(LogicalKeyboardKey.arrowUp,
                shift: true, meta: true)
            : const SingleActivator(LogicalKeyboardKey.arrowUp,
                shift: true, alt: true);
        controller.text = testVerticalText;
        controller.selection = const TextSelection.collapsed(
          offset: 5,
        );

        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, selectAllUp);
        await tester.pump();

        expect(controller.text, testVerticalText);
        expect(
          controller.selection,
          const TextSelection(
              baseOffset: 5,
              extentOffset: 0), // selection extends all the way up
          reason: selectAllUp.toString(),
        );
      }, variant: TargetPlatformVariant.desktop());

      testWidgets('select all down', (WidgetTester tester) async {
        final bool isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
        final SingleActivator selectAllDown = isMacOS
            ? const SingleActivator(LogicalKeyboardKey.arrowDown,
                shift: true, meta: true)
            : const SingleActivator(LogicalKeyboardKey.arrowDown,
                shift: true, alt: true);
        controller.text = testVerticalText;
        controller.selection = const TextSelection.collapsed(
          offset: 5,
        );

        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, selectAllDown);
        await tester.pump();

        expect(controller.text, testVerticalText);
        expect(
          controller.selection,
          const TextSelection(
              baseOffset: 5,
              extentOffset: 17), // selection extends all the way down
          reason: selectAllDown.toString(),
        );
    }, variant: TargetPlatformVariant.desktop());
  }, skip: !kIsWeb); // [intended] specific tests target web.
}
