// 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';

Future<void> sendKeyCombination(
  WidgetTester tester,
  SingleActivator activator,
) async {
  final List<LogicalKeyboardKey> modifiers = <LogicalKeyboardKey>[
    if (activator.control) LogicalKeyboardKey.control,
    if (activator.shift) LogicalKeyboardKey.shift,
    if (activator.alt) LogicalKeyboardKey.alt,
    if (activator.meta) LogicalKeyboardKey.meta,
  ];
  for (final LogicalKeyboardKey modifier in modifiers) {
    await tester.sendKeyDownEvent(modifier);
  }
  await tester.sendKeyDownEvent(activator.trigger);
  await tester.sendKeyUpEvent(activator.trigger);
  await tester.pump();
  for (final LogicalKeyboardKey modifier in modifiers.reversed) {
    await tester.sendKeyUpEvent(modifier);
  }
}

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() {
  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';
  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.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 allExceptMacOS = TargetPlatformVariant(TargetPlatform.values.toSet()..remove(TargetPlatform.macOS));

      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 isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
          return SingleActivator(trigger, control: !isMacOS, alt: isMacOS);
        }

        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 isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
          return SingleActivator(trigger, control: !isMacOS, alt: isMacOS);
        }

        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 isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
          return SingleActivator(trigger, meta: isMacOS, alt: !isMacOS);
        }

        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 isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
          return SingleActivator(trigger, meta: isMacOS, alt: !isMacOS);
        }

        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: allExceptMacOS);

          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: allExceptMacOS);
        });

        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,
            ));
          }, 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,
            ));
          }, variant: allExceptMacOS);

         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: allExceptMacOS);
        });

        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".
            ));

            // "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".
            ));
          }, variant: allExceptMacOS);

         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: allExceptMacOS);
        });

        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(),
              );
            }
          }, 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());
            }
          }, 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 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 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,
      ));
    }, 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".
      ));

      // "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".
      ));
    }, 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.
}
