// 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.

@TestOn('!chrome')
import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle;

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

import '../widgets/editable_text_utils.dart' show textOffsetToPosition;
import '../widgets/semantics_tester.dart';

class MockClipboard {
  dynamic _clipboardData = <String, dynamic>{
    'text': null,
  };

  Future<dynamic> handleMethodCall(MethodCall methodCall) async {
    switch (methodCall.method) {
      case 'Clipboard.getData':
        return _clipboardData;
      case 'Clipboard.setData':
        _clipboardData = methodCall.arguments;
        break;
    }
  }
}

class MaterialLocalizationsDelegate extends LocalizationsDelegate<MaterialLocalizations> {
  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<MaterialLocalizations> load(Locale locale) => DefaultMaterialLocalizations.load(locale);

  @override
  bool shouldReload(MaterialLocalizationsDelegate old) => false;
}

class WidgetsLocalizationsDelegate extends LocalizationsDelegate<WidgetsLocalizations> {
  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<WidgetsLocalizations> load(Locale locale) => DefaultWidgetsLocalizations.load(locale);

  @override
  bool shouldReload(WidgetsLocalizationsDelegate old) => false;
}

Widget overlay({ Widget? child }) {
  final OverlayEntry entry = OverlayEntry(
    builder: (BuildContext context) {
      return Center(
        child: Material(
          child: child,
        ),
      );
    },
  );
  return overlayWithEntry(entry);
}

Widget overlayWithEntry(OverlayEntry entry) {
  return Localizations(
    locale: const Locale('en', 'US'),
    delegates: <LocalizationsDelegate<dynamic>>[
      WidgetsLocalizationsDelegate(),
      MaterialLocalizationsDelegate(),
    ],
    child: Directionality(
      textDirection: TextDirection.ltr,
      child: MediaQuery(
        data: const MediaQueryData(size: Size(800.0, 600.0)),
        child: Overlay(
          initialEntries: <OverlayEntry>[
            entry,
          ],
        ),
      ),
    ),
  );
}

Widget boilerplate({ Widget? child }) {
  return Localizations(
    locale: const Locale('en', 'US'),
    delegates: <LocalizationsDelegate<dynamic>>[
      WidgetsLocalizationsDelegate(),
      MaterialLocalizationsDelegate(),
    ],
    child: Directionality(
      textDirection: TextDirection.ltr,
      child: MediaQuery(
        data: const MediaQueryData(size: Size(800.0, 600.0)),
        child: Center(
          child: Material(
            child: child,
          ),
        ),
      ),
    ),
  );
}

Future<void> skipPastScrollingAnimation(WidgetTester tester) async {
  await tester.pump();
  await tester.pump(const Duration(milliseconds: 200));
}

double getOpacity(WidgetTester tester, Finder finder) {
  return tester.widget<FadeTransition>(
      find.ancestor(
        of: finder,
        matching: find.byType(FadeTransition),
      ),
  ).opacity.value;
}

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();
  final MockClipboard mockClipboard = MockClipboard();
  TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);

  const String kThreeLines =
      'First line of text is\n'
      'Second line goes until\n'
      'Third line of stuff';
  const String kMoreThanFourLines =
      '$kThreeLines\n'
      "Fourth line won't display and ends at";

  // Returns the first RenderEditable.
  RenderEditable findRenderEditable(WidgetTester tester) {
    final RenderObject root = tester.renderObject(find.byType(EditableText));
    expect(root, isNotNull);

    late RenderEditable renderEditable;
    void recursiveFinder(RenderObject child) {
      if (child is RenderEditable) {
        renderEditable = child;
        return;
      }
      child.visitChildren(recursiveFinder);
    }
    root.visitChildren(recursiveFinder);
    expect(renderEditable, isNotNull);
    return renderEditable;
  }

  List<TextSelectionPoint> globalize(Iterable<TextSelectionPoint> points, RenderBox box) {
    return points.map<TextSelectionPoint>((TextSelectionPoint point) {
      return TextSelectionPoint(
        box.localToGlobal(point.point),
        point.direction,
      );
    }).toList();
  }

  setUp(() async {
    debugResetSemanticsIdCounter();
    // Fill the clipboard so that the Paste option is available in the text
    // selection menu.
    await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
  });

  Widget selectableTextBuilder({
    String text = '',
    int? maxLines = 1,
    int? minLines,
  }) {
    return boilerplate(
      child: SelectableText(
        text,
        style: const TextStyle(color: Colors.black, fontSize: 34.0),
        maxLines: maxLines,
        minLines: minLines,
      ),
    );
  }

  testWidgets('can use the desktop cut/copy/paste buttons on Mac', (WidgetTester tester) async {
    final TextEditingController controller = TextEditingController(
      text: 'blah1 blah2',
    );
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: TextFormField(
              controller: controller,
            ),
          ),
        ),
      ),
    );

    // Initially, the menu is not shown and there is no selection.
    expect(find.byType(CupertinoButton), findsNothing);
    expect(controller.selection, const TextSelection(baseOffset: -1, extentOffset: -1));

    final Offset midBlah1 = textOffsetToPosition(tester, 2);

    // Right clicking shows the menu.
    final TestGesture gesture = await tester.startGesture(
      midBlah1,
      kind: PointerDeviceKind.mouse,
      buttons: kSecondaryMouseButton,
    );
    addTearDown(gesture.removePointer);
    await tester.pump();
    await gesture.up();
    await tester.pumpAndSettle();
    expect(controller.selection, const TextSelection(baseOffset: 0, extentOffset: 5));
    expect(find.text('Copy'), findsOneWidget);
    expect(find.text('Cut'), findsOneWidget);
    expect(find.text('Paste'), findsOneWidget);

    // Copy the first word.
    await tester.tap(find.text('Copy'));
    await tester.pumpAndSettle();
    expect(controller.text, 'blah1 blah2');
    expect(controller.selection, const TextSelection(baseOffset: 5, extentOffset: 5));
    expect(find.byType(CupertinoButton), findsNothing);

    // Paste it at the end.
    await gesture.down(textOffsetToPosition(tester, controller.text.length));
    await tester.pump();
    await gesture.up();
    await tester.pumpAndSettle();
    expect(controller.selection, const TextSelection(baseOffset: 11, extentOffset: 11, affinity: TextAffinity.upstream));
    expect(find.text('Cut'), findsNothing);
    expect(find.text('Copy'), findsNothing);
    expect(find.text('Paste'), findsOneWidget);
    await tester.tap(find.text('Paste'));
    await tester.pumpAndSettle();
    expect(controller.text, 'blah1 blah2blah1');
    expect(controller.selection, const TextSelection(baseOffset: 16, extentOffset: 16));

    // Cut the first word.
    await gesture.down(midBlah1);
    await tester.pump();
    await gesture.up();
    await tester.pumpAndSettle();
    expect(find.text('Cut'), findsOneWidget);
    expect(find.text('Copy'), findsOneWidget);
    expect(find.text('Paste'), findsOneWidget);
    expect(controller.selection, const TextSelection(baseOffset: 0, extentOffset: 5));
    await tester.tap(find.text('Cut'));
    await tester.pumpAndSettle();
    expect(controller.text, ' blah2blah1');
    expect(controller.selection, const TextSelection(baseOffset: 0, extentOffset: 0));
    expect(find.byType(CupertinoButton), findsNothing);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS, TargetPlatform.windows, TargetPlatform.linux }), skip: kIsWeb);

  testWidgets('has expected defaults', (WidgetTester tester) async {
    await tester.pumpWidget(
      boilerplate(
          child: const SelectableText('selectable text'),
      ),
    );

    final SelectableText selectableText = tester.firstWidget(find.byType(SelectableText));
    expect(selectableText.showCursor, false);
    expect(selectableText.autofocus, false);
    expect(selectableText.dragStartBehavior, DragStartBehavior.start);
    expect(selectableText.cursorWidth, 2.0);
    expect(selectableText.cursorHeight, isNull);
    expect(selectableText.enableInteractiveSelection, true);
  });

  testWidgets('Rich selectable text has expected defaults', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MediaQuery(
        data: MediaQueryData(devicePixelRatio: 1.0),
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: SelectableText.rich(
              TextSpan(
                text: 'First line!',
                style: TextStyle(
                    fontSize: 14,
                    fontFamily: 'Roboto',
                ),
                children: <TextSpan>[
                  TextSpan(
                    text: 'Second line!\n',
                    style: TextStyle(
                      fontSize: 30,
                      fontFamily: 'Roboto',
                    ),
                  ),
                  TextSpan(
                    text: 'Third line!\n',
                    style: TextStyle(
                      fontSize: 14,
                      fontFamily: 'Roboto',
                    ),
                  ),
                ],
              ),
          ),
        ),
      ),
    );

    final SelectableText selectableText =
    tester.firstWidget(find.byType(SelectableText));
    expect(selectableText.showCursor, false);
    expect(selectableText.autofocus, false);
    expect(selectableText.dragStartBehavior, DragStartBehavior.start);
    expect(selectableText.cursorWidth, 2.0);
    expect(selectableText.cursorHeight, isNull);
    expect(selectableText.enableInteractiveSelection, true);
  });

  testWidgets('Rich selectable text only support TextSpan', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MediaQuery(
        data: MediaQueryData(devicePixelRatio: 1.0),
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: SelectableText.rich(
              TextSpan(
                text: 'First line!',
                style: TextStyle(
                    fontSize: 14,
                    fontFamily: 'Roboto',
                ),
                children: <InlineSpan>[
                  WidgetSpan(
                      child: SizedBox(
                        width: 120,
                        height: 50,
                        child: Card(
                            child: Center(
                                child: Text('Hello World!'),
                            ),
                        ),
                      ),
                  ),
                  TextSpan(
                    text: 'Third line!\n',
                    style: TextStyle(
                      fontSize: 14,
                      fontFamily: 'Roboto',
                    ),
                  ),
                ],
              ),
          ),
        ),
      ),
    );
    expect(tester.takeException(), isAssertionError);
  });

  testWidgets('no text keyboard when widget is focused', (WidgetTester tester) async {
    await tester.pumpWidget(
        overlay(
          child: const SelectableText('selectable text'),
        ),
    );
    await tester.tap(find.byType(SelectableText));
    await tester.idle();
    expect(tester.testTextInput.hasAnyClients, false);
  });

  testWidgets('Selectable Text has adaptive size', (WidgetTester tester) async {
    await tester.pumpWidget(
        boilerplate(
          child: const SelectableText('s'),
        ),
    );

    RenderBox findSelectableTextBox() => tester.renderObject(find.byType(SelectableText));

    final RenderBox textBox = findSelectableTextBox();
    expect(textBox.size, const Size(17.0, 14.0));

    await tester.pumpWidget(
        boilerplate(
          child: const SelectableText('very very long'),
        ),
    );

    final RenderBox longtextBox = findSelectableTextBox();
    expect(longtextBox.size, const Size(199.0, 14.0));
  });

  testWidgets('can scale with textScaleFactor', (WidgetTester tester) async {
    await tester.pumpWidget(
      boilerplate(
        child: const SelectableText('selectable text'),
      ),
    );

    final RenderBox renderBox = tester.renderObject(find.byType(SelectableText));
    expect(renderBox.size.height, 14.0);

    await tester.pumpWidget(
      boilerplate(
        child: const SelectableText(
          'selectable text',
          textScaleFactor: 1.9,
        ),
      ),
    );

    final RenderBox scaledBox = tester.renderObject(find.byType(SelectableText));
    expect(scaledBox.size.height, 27.0);
  });

  testWidgets('can switch between textWidthBasis', (WidgetTester tester) async {
    RenderBox findTextBox() => tester.renderObject(find.byType(SelectableText));
    const String text = 'I can face roll keyboardkeyboardaszzaaaaszzaaaaszzaaaaszzaaaa';
    await tester.pumpWidget(
      boilerplate(
        child: const SelectableText(
          text,
          textWidthBasis: TextWidthBasis.parent,
        ),
      ),
    );
    RenderBox textBox = findTextBox();
    expect(textBox.size, const Size(800.0, 28.0));

    await tester.pumpWidget(
      boilerplate(
        child: const SelectableText(
          text,
          textWidthBasis: TextWidthBasis.longestLine,
        ),
      ),
    );
    textBox = findTextBox();
    expect(textBox.size, const Size(633.0, 28.0));
  });

  testWidgets('can switch between textHeightBehavior', (WidgetTester tester) async {
    const String text = 'selectable text';
    const TextHeightBehavior textHeightBehavior = TextHeightBehavior(
      applyHeightToFirstAscent: false,
      applyHeightToLastDescent: false,
    );
    await tester.pumpWidget(
      boilerplate(
        child: const SelectableText(text),
      ),
    );
    expect(findRenderEditable(tester).textHeightBehavior, isNull);

    await tester.pumpWidget(
      boilerplate(
        child: const SelectableText(
          text,
          textHeightBehavior: textHeightBehavior,
        ),
      ),
    );
    expect(findRenderEditable(tester).textHeightBehavior, textHeightBehavior);
  });

  testWidgets('Cursor blinks when showCursor is true', (WidgetTester tester) async {
    await tester.pumpWidget(
      overlay(
        child: const SelectableText(
          'some text',
          showCursor: true,
        ),
      ),
    );
    await tester.tap(find.byType(SelectableText));
    await tester.idle();

    final EditableTextState editableText = tester.state(find.byType(EditableText));

    // Check that the cursor visibility toggles after each blink interval.
    final bool initialShowCursor = editableText.cursorCurrentlyVisible;
    await tester.pump(editableText.cursorBlinkInterval);
    expect(editableText.cursorCurrentlyVisible, equals(!initialShowCursor));
    await tester.pump(editableText.cursorBlinkInterval);
    expect(editableText.cursorCurrentlyVisible, equals(initialShowCursor));
    await tester.pump(editableText.cursorBlinkInterval ~/ 10);
    expect(editableText.cursorCurrentlyVisible, equals(initialShowCursor));
    await tester.pump(editableText.cursorBlinkInterval);
    expect(editableText.cursorCurrentlyVisible, equals(!initialShowCursor));
    await tester.pump(editableText.cursorBlinkInterval);
    expect(editableText.cursorCurrentlyVisible, equals(initialShowCursor));
  });

  testWidgets('selectable text selection toolbar renders correctly inside opacity', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: Center(
            child: SizedBox(
              width: 100,
              height: 100,
              child: Opacity(
                opacity: 0.5,
                child: SelectableText('selectable text'),
              ),
            ),
          ),
        ),
      ),
    );

    // The selectWordsInRange with SelectionChangedCause.tap seems to be needed to show the toolbar.
    final EditableTextState state = tester.state<EditableTextState>(find.byType(EditableText));
    state.renderEditable.selectWordsInRange(from: Offset.zero, cause: SelectionChangedCause.tap);

    expect(state.showToolbar(), true);

    // This is needed for the AnimatedOpacity to turn from 0 to 1 so the toolbar is visible.
    await tester.pumpAndSettle();
    await tester.pump(const Duration(seconds: 1));

    expect(find.text('Select all'), findsOneWidget);
  });

  testWidgets('Caret position is updated on tap', (WidgetTester tester) async {
    await tester.pumpWidget(
        overlay(
          child: const SelectableText('abc def ghi'),
        ),
    );
    final EditableText editableText = tester.widget(find.byType(EditableText));
    expect(editableText.controller.selection.baseOffset, -1);
    expect(editableText.controller.selection.extentOffset, -1);

    // Tap to reposition the caret.
    const int tapIndex = 4;
    final Offset ePos = textOffsetToPosition(tester, tapIndex);
    await tester.tapAt(ePos);
    await tester.pump();

    expect(editableText.controller.selection.baseOffset, tapIndex);
    expect(editableText.controller.selection.extentOffset, tapIndex);
  });

  testWidgets('enableInteractiveSelection = false, tap', (WidgetTester tester) async {
    await tester.pumpWidget(
        overlay(
          child: const SelectableText(
            'abc def ghi',
            enableInteractiveSelection: false,
          ),
        ),
    );
    final EditableText editableText = tester.widget(find.byType(EditableText));
    expect(editableText.controller.selection.baseOffset, -1);
    expect(editableText.controller.selection.extentOffset, -1);

    // Tap would ordinarily reposition the caret.
    const int tapIndex = 4;
    final Offset ePos = textOffsetToPosition(tester, tapIndex);
    await tester.tapAt(ePos);
    await tester.pump();

    expect(editableText.controller.selection.baseOffset, -1);
    expect(editableText.controller.selection.extentOffset, -1);
  });

  testWidgets('enableInteractiveSelection = false, long-press', (WidgetTester tester) async {
    await tester.pumpWidget(
        overlay(
          child: const SelectableText(
            'abc def ghi',
            enableInteractiveSelection: false,
          ),
        ),
    );
    final EditableText editableText = tester.widget(find.byType(EditableText));
    expect(editableText.controller.selection.baseOffset, -1);
    expect(editableText.controller.selection.extentOffset, -1);

    // Long press the 'e' to select 'def'.
    final Offset ePos = textOffsetToPosition(tester, 5);
    final TestGesture gesture = await tester.startGesture(ePos, pointer: 7);
    await tester.pump(const Duration(seconds: 2));
    await gesture.up();
    await tester.pump();

    expect(editableText.controller.selection.isCollapsed, true);
    expect(editableText.controller.selection.baseOffset, -1);
    expect(editableText.controller.selection.extentOffset, -1);
  });

  testWidgets('Can long press to select', (WidgetTester tester) async {
    await tester.pumpWidget(
        overlay(
          child: const SelectableText('abc def ghi'),
        ),
    );

    final EditableText editableText = tester.widget(find.byType(EditableText));

    expect(editableText.controller.selection.isCollapsed, true);

    // Long press the 'e' to select 'def'.
    const int tapIndex = 5;
    final Offset ePos = textOffsetToPosition(tester, tapIndex);
    await tester.longPressAt(ePos);
    await tester.pump();

    // 'def' is selected.
    expect(editableText.controller.selection.baseOffset, 4);
    expect(editableText.controller.selection.extentOffset, 7);

    // Tapping elsewhere immediately collapses and moves the cursor.
    await tester.tapAt(textOffsetToPosition(tester, 9));
    await tester.pump();

    expect(editableText.controller.selection.isCollapsed, true);
    expect(editableText.controller.selection.baseOffset, 9);
  });

  testWidgets("Slight movements in longpress don't hide/show handles", (WidgetTester tester) async {
    await tester.pumpWidget(
        overlay(
          child: const SelectableText('abc def ghi'),
        ),
    );
    // Long press the 'e' to select 'def', but don't release the gesture.
    final Offset ePos = textOffsetToPosition(tester, 5);
    final TestGesture gesture = await tester.startGesture(ePos, pointer: 7);
    await tester.pump(const Duration(seconds: 2));
    await tester.pumpAndSettle();

    // Handles are shown
    final Finder fadeFinder = find.byType(FadeTransition);
    expect(fadeFinder, findsNWidgets(2)); // 2 handles, 1 toolbar
    FadeTransition handle = tester.widget(fadeFinder.at(0));
    expect(handle.opacity.value, equals(1.0));

    // Move the gesture very slightly
    await gesture.moveBy(const Offset(1.0, 1.0));
    await tester.pump(TextSelectionOverlay.fadeDuration * 0.5);
    handle = tester.widget(fadeFinder.at(0));

    // The handle should still be fully opaque.
    expect(handle.opacity.value, equals(1.0));
  });

  testWidgets('Mouse long press is just like a tap', (WidgetTester tester) async {
    await tester.pumpWidget(
        overlay(
          child: const SelectableText('abc def ghi'),
        ),
    );

    final EditableText editableText = tester.widget(find.byType(EditableText));

    // Long press the 'e' using a mouse device.
    const int eIndex = 5;
    final Offset ePos = textOffsetToPosition(tester, eIndex);
    final TestGesture gesture = await tester.startGesture(ePos, kind: PointerDeviceKind.mouse);
    addTearDown(gesture.removePointer);
    await tester.pump(const Duration(seconds: 2));
    await gesture.up();
    await tester.pump();

    // The cursor is placed just like a regular tap.
    expect(editableText.controller.selection.baseOffset, eIndex);
    expect(editableText.controller.selection.extentOffset, eIndex);
  });

  testWidgets('selectable text basic', (WidgetTester tester) async {
    await tester.pumpWidget(
        overlay(
          child: const SelectableText('selectable'),
        ),
    );
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText));
    // selectable text cannot open keyboard.
    await tester.showKeyboard(find.byType(SelectableText));
    expect(tester.testTextInput.hasAnyClients, false);
    await skipPastScrollingAnimation(tester);

    expect(editableTextWidget.controller.selection.isCollapsed, true);

    await tester.tap(find.byType(SelectableText));
    await tester.pump();

    final EditableTextState editableText = tester.state(find.byType(EditableText));
    // Collapse selection should not paint.
    expect(editableText.selectionOverlay!.handlesAreVisible, isFalse);
    // Long press on the 't' character of text 'selectable' to show context menu.
    const int dIndex = 5;
    final Offset dPos = textOffsetToPosition(tester, dIndex);
    await tester.longPressAt(dPos);
    await tester.pump();

    // Context menu should not have paste and cut.
    expect(find.text('Copy'), findsOneWidget);
    expect(find.text('Paste'), findsNothing);
    expect(find.text('Cut'), findsNothing);
  });

  testWidgets('selectable text can disable toolbar options', (WidgetTester tester) async {
    await tester.pumpWidget(
      overlay(
        child: const SelectableText(
          'a selectable text',
          toolbarOptions: ToolbarOptions(
            copy: false,
            selectAll: true,
          ),
        ),
      ),
    );
    const int dIndex = 5;
    final Offset dPos = textOffsetToPosition(tester, dIndex);
    await tester.longPressAt(dPos);
    await tester.pump();
    // Context menu should not have copy.
    expect(find.text('Copy'), findsNothing);
    expect(find.text('Select all'), findsOneWidget);
  });

  testWidgets('Can select text by dragging with a mouse', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText(
            'abc def ghi',
            dragStartBehavior: DragStartBehavior.down,
          ),
        ),
      ),
    );
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText));
    final TextEditingController controller = editableTextWidget.controller;

    final Offset ePos = textOffsetToPosition(tester, 5);
    final Offset gPos = textOffsetToPosition(tester, 8);

    final TestGesture gesture = await tester.startGesture(ePos, kind: PointerDeviceKind.mouse);
    addTearDown(gesture.removePointer);
    await tester.pump();
    await gesture.moveTo(gPos);
    await tester.pump();
    await gesture.up();
    await tester.pumpAndSettle();

    expect(controller.selection.baseOffset, 5);
    expect(controller.selection.extentOffset, 8);
  });

  testWidgets('Continuous dragging does not cause flickering', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText(
            'abc def ghi',
            dragStartBehavior: DragStartBehavior.down,
            style: TextStyle(fontFamily: 'Ahem', fontSize: 10.0),
          ),
        ),
      ),
    );
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText));
    final TextEditingController controller = editableTextWidget.controller;

    int selectionChangedCount = 0;

    controller.addListener(() {
      selectionChangedCount++;
    });

    final Offset cPos = textOffsetToPosition(tester, 2); // Index of 'c'.
    final Offset gPos = textOffsetToPosition(tester, 8); // Index of 'g'.
    final Offset hPos = textOffsetToPosition(tester, 9); // Index of 'h'.

    // Drag from 'c' to 'g'.
    final TestGesture gesture = await tester.startGesture(cPos, kind: PointerDeviceKind.mouse);
    addTearDown(gesture.removePointer);
    await tester.pump();
    await gesture.moveTo(gPos);
    await tester.pumpAndSettle();

    expect(selectionChangedCount, isNonZero);
    selectionChangedCount = 0;
    expect(controller.selection.baseOffset, 2);
    expect(controller.selection.extentOffset, 8);

    // Tiny movement shouldn't cause text selection to change.
    await gesture.moveTo(gPos + const Offset(4.0, 0.0));
    await tester.pumpAndSettle();
    expect(selectionChangedCount, 0);

    // Now a text selection change will occur after a significant movement.
    await gesture.moveTo(hPos);
    await tester.pump();
    await gesture.up();
    await tester.pumpAndSettle();

    expect(selectionChangedCount, 1);
    expect(controller.selection.baseOffset, 2);
    expect(controller.selection.extentOffset, 9);
  });

  testWidgets('Dragging in opposite direction also works', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText(
            'abc def ghi',
            dragStartBehavior: DragStartBehavior.down,
          ),
        ),
      ),
    );
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText));
    final TextEditingController controller = editableTextWidget.controller;

    final Offset ePos = textOffsetToPosition(tester, 5);
    final Offset gPos = textOffsetToPosition(tester, 8);

    final TestGesture gesture = await tester.startGesture(gPos, kind: PointerDeviceKind.mouse);
    addTearDown(gesture.removePointer);
    await tester.pump();
    await gesture.moveTo(ePos);
    await tester.pump();
    await gesture.up();
    await tester.pumpAndSettle();

    expect(controller.selection.baseOffset, 8);
    expect(controller.selection.extentOffset, 5);
  });

  testWidgets('Slow mouse dragging also selects text', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText(
            'abc def ghi',
            dragStartBehavior: DragStartBehavior.down,
          ),
        ),
      ),
    );
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText));
    final TextEditingController controller = editableTextWidget.controller;

    final Offset ePos = textOffsetToPosition(tester, 5);
    final Offset gPos = textOffsetToPosition(tester,8);

    final TestGesture gesture = await tester.startGesture(ePos, kind: PointerDeviceKind.mouse);
    addTearDown(gesture.removePointer);
    await tester.pump(const Duration(seconds: 2));
    await gesture.moveTo(gPos);
    await tester.pump();
    await gesture.up();

    expect(controller.selection.baseOffset, 5);
    expect(controller.selection.extentOffset,8);
  });

  testWidgets('Can drag handles to change selection', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText(
            'abc def ghi',
            dragStartBehavior: DragStartBehavior.down,
          ),
        ),
      ),
    );
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText));
    final TextEditingController controller = editableTextWidget.controller;

    // Long press the 'e' to select 'def'.
    final Offset ePos = textOffsetToPosition(tester, 5);
    TestGesture gesture = await tester.startGesture(ePos, pointer: 7);
    await tester.pump(const Duration(seconds: 2));
    await gesture.up();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200)); // skip past the frame where the opacity is zero

    final TextSelection selection = controller.selection;
    expect(selection.baseOffset, 4);
    expect(selection.extentOffset, 7);

    final RenderEditable renderEditable = findRenderEditable(tester);
    final List<TextSelectionPoint> endpoints = globalize(
      renderEditable.getEndpointsForSelection(selection),
      renderEditable,
    );
    expect(endpoints.length, 2);

    // Drag the right handle 2 letters to the right.
    // We use a small offset because the endpoint is on the very corner
    // of the handle.
    Offset handlePos = endpoints[1].point + const Offset(1.0, 1.0);
    Offset newHandlePos = textOffsetToPosition(tester, 11);
    gesture = await tester.startGesture(handlePos, pointer: 7);
    await tester.pump();
    await gesture.moveTo(newHandlePos);
    await tester.pump();
    await gesture.up();
    await tester.pump();

    expect(controller.selection.baseOffset, 4);
    expect(controller.selection.extentOffset, 11);

    // Drag the left handle 2 letters to the left.
    handlePos = endpoints[0].point + const Offset(-1.0, 1.0);
    newHandlePos = textOffsetToPosition(tester, 0);
    gesture = await tester.startGesture(handlePos, pointer: 7);
    await tester.pump();
    await gesture.moveTo(newHandlePos);
    await tester.pump();
    await gesture.up();
    await tester.pump();

    expect(controller.selection.baseOffset, 0);
    expect(controller.selection.extentOffset, 11);
  });

  testWidgets('Dragging handles calls onSelectionChanged', (WidgetTester tester) async {
    TextSelection? newSelection;
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: SelectableText(
            'abc def ghi',
            dragStartBehavior: DragStartBehavior.down,
            onSelectionChanged: (TextSelection selection, SelectionChangedCause? cause) {
              expect(newSelection, isNull);
              newSelection = selection;
            },
          ),
        ),
      ),
    );

    // Long press the 'e' to select 'def'.
    final Offset ePos = textOffsetToPosition(tester, 5);
    TestGesture gesture = await tester.startGesture(ePos, pointer: 7);
    await tester.pump(const Duration(seconds: 2));
    await gesture.up();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200)); // skip past the frame where the opacity is zero

    expect(newSelection!.baseOffset, 4);
    expect(newSelection!.extentOffset, 7);

    final RenderEditable renderEditable = findRenderEditable(tester);
    final List<TextSelectionPoint> endpoints = globalize(
      renderEditable.getEndpointsForSelection(newSelection!),
      renderEditable,
    );
    expect(endpoints.length, 2);
    newSelection = null;

    // Drag the right handle 2 letters to the right.
    // We use a small offset because the endpoint is on the very corner
    // of the handle.
    final Offset handlePos = endpoints[1].point + const Offset(1.0, 1.0);
    final Offset newHandlePos = textOffsetToPosition(tester, 9);
    gesture = await tester.startGesture(handlePos, pointer: 7);
    await tester.pump();
    await gesture.moveTo(newHandlePos);
    await tester.pump();
    await gesture.up();
    await tester.pump();

    expect(newSelection!.baseOffset, 4);
    expect(newSelection!.extentOffset, 9);
  });

  testWidgets('Cannot drag one handle past the other', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText(
            'abc def ghi',
            dragStartBehavior: DragStartBehavior.down,
          ),
        ),
      ),
    );
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText));
    final TextEditingController controller = editableTextWidget.controller;

    // Long press the 'e' to select 'def'.
    final Offset ePos = textOffsetToPosition(tester, 5); // Position before 'e'.
    TestGesture gesture = await tester.startGesture(ePos, pointer: 7);
    await tester.pump(const Duration(seconds: 2));
    await gesture.up();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200)); // skip past the frame where the opacity is zero

    final TextSelection selection = controller.selection;
    expect(selection.baseOffset, 4);
    expect(selection.extentOffset, 7);

    final RenderEditable renderEditable = findRenderEditable(tester);
    final List<TextSelectionPoint> endpoints = globalize(
      renderEditable.getEndpointsForSelection(selection),
      renderEditable,
    );
    expect(endpoints.length, 2);

    // Drag the right handle until there's only 1 char selected.
    // We use a small offset because the endpoint is on the very corner
    // of the handle.
    final Offset handlePos = endpoints[1].point + const Offset(4.0, 0.0);
    Offset newHandlePos = textOffsetToPosition(tester, 5); // Position before 'e'.
    gesture = await tester.startGesture(handlePos, pointer: 7);
    await tester.pump();
    await gesture.moveTo(newHandlePos);
    await tester.pump();

    expect(controller.selection.baseOffset, 4);
    expect(controller.selection.extentOffset, 5);

    newHandlePos = textOffsetToPosition(tester, 2); // Position before 'c'.
    await gesture.moveTo(newHandlePos);
    await tester.pump();
    await gesture.up();
    await tester.pump();

    expect(controller.selection.baseOffset, 4);
    // The selection doesn't move beyond the left handle. There's always at
    // least 1 char selected.
    expect(controller.selection.extentOffset, 5);
  });

  testWidgets('Can use selection toolbar', (WidgetTester tester) async {
    const String testValue = 'abc def ghi';
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText(
            testValue,
          ),
        ),
      ),
    );
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText));
    final TextEditingController controller = editableTextWidget.controller;

    // Tap the selection handle to bring up the "paste / select all" menu.
    await tester.tapAt(textOffsetToPosition(tester, testValue.indexOf('e')));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200)); // skip past the frame where the opacity is zero
    final RenderEditable renderEditable = findRenderEditable(tester);
    final List<TextSelectionPoint> endpoints = globalize(
      renderEditable.getEndpointsForSelection(controller.selection),
      renderEditable,
    );
    // Tapping on the part of the handle's GestureDetector where it overlaps
    // with the text itself does not show the menu, so add a small vertical
    // offset to tap below the text.
    await tester.tapAt(endpoints[0].point + const Offset(1.0, 13.0));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200)); // skip past the frame where the opacity is zero

    // Select all should select all the text.
    await tester.tap(find.text('Select all'));
    await tester.pump();
    expect(controller.selection.baseOffset, 0);
    expect(controller.selection.extentOffset, testValue.length);

    // Copy should reset the selection.
    await tester.tap(find.text('Copy'));
    await skipPastScrollingAnimation(tester);
    expect(controller.selection.isCollapsed, true);
  });

  testWidgets('Selectable height with maxLine', (WidgetTester tester) async {
    await tester.pumpWidget(selectableTextBuilder());

    RenderBox findTextBox() => tester.renderObject(find.byType(SelectableText));

    final RenderBox textBox = findTextBox();
    final Size emptyInputSize = textBox.size;

    await tester.pumpWidget(selectableTextBuilder(text: 'No wrapping here.'));
    expect(findTextBox(), equals(textBox));
    expect(textBox.size.height, emptyInputSize.height);

    // Even when entering multiline text, SelectableText doesn't grow. It's a single
    // line input.
    await tester.pumpWidget(selectableTextBuilder(text: kThreeLines));
    expect(findTextBox(), equals(textBox));
    expect(textBox.size.height, emptyInputSize.height);

    // maxLines: 3 makes the SelectableText 3 lines tall
    await tester.pumpWidget(selectableTextBuilder(maxLines: 3));
    expect(findTextBox(), equals(textBox));
    expect(textBox.size.height, greaterThan(emptyInputSize.height));

    final Size threeLineInputSize = textBox.size;

    // Filling with 3 lines of text stays the same size
    await tester.pumpWidget(selectableTextBuilder(text: kThreeLines, maxLines: 3));
    expect(findTextBox(), equals(textBox));
    expect(textBox.size.height, threeLineInputSize.height);

    // An extra line won't increase the size because we max at 3.
    await tester.pumpWidget(selectableTextBuilder(text: kMoreThanFourLines, maxLines: 3));
    expect(findTextBox(), equals(textBox));
    expect(textBox.size.height, threeLineInputSize.height);

    // But now it will... but it will max at four
    await tester.pumpWidget(selectableTextBuilder(text: kMoreThanFourLines, maxLines: 4));
    expect(findTextBox(), equals(textBox));
    expect(textBox.size.height, greaterThan(threeLineInputSize.height));

    final Size fourLineInputSize = textBox.size;

    // Now it won't max out until the end
    await tester.pumpWidget(selectableTextBuilder(maxLines: null));
    expect(findTextBox(), equals(textBox));
    expect(textBox.size, equals(emptyInputSize));
    await tester.pumpWidget(selectableTextBuilder(text: kThreeLines, maxLines: null));
    expect(textBox.size.height, equals(threeLineInputSize.height));
    await tester.pumpWidget(selectableTextBuilder(text: kMoreThanFourLines, maxLines: null));
    expect(textBox.size.height, greaterThan(fourLineInputSize.height));
  });

  testWidgets('Can drag handles to change selection in multiline', (WidgetTester tester) async {
    const String testValue = kThreeLines;
    await tester.pumpWidget(
      overlay(
        child: const SelectableText(
          testValue,
          dragStartBehavior: DragStartBehavior.down,
          style: TextStyle(color: Colors.black, fontSize: 34.0),
          maxLines: 3,
        ),
      ),
    );

    final EditableText editableTextWidget = tester.widget(find.byType(EditableText));
    final TextEditingController controller = editableTextWidget.controller;

    // Check that the text spans multiple lines.
    final Offset firstPos = textOffsetToPosition(tester, testValue.indexOf('First'));
    final Offset secondPos = textOffsetToPosition(tester, testValue.indexOf('Second'));
    final Offset thirdPos = textOffsetToPosition(tester, testValue.indexOf('Third'));
    final Offset middleStringPos = textOffsetToPosition(tester, testValue.indexOf('irst'));

    expect(firstPos.dx, 24.5);
    expect(secondPos.dx, 24.5);
    expect(thirdPos.dx, 24.5);
    expect(middleStringPos.dx, 58.5);
    expect(firstPos.dx, secondPos.dx);
    expect(firstPos.dx, thirdPos.dx);
    expect(firstPos.dy, lessThan(secondPos.dy));
    expect(secondPos.dy, lessThan(thirdPos.dy));

    // Long press the 'n' in 'until' to select the word.
    final Offset untilPos = textOffsetToPosition(tester, testValue.indexOf('until')+1);
    TestGesture gesture = await tester.startGesture(untilPos, pointer: 7);
    await tester.pump(const Duration(seconds: 2));
    await gesture.up();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200)); // skip past the frame where the opacity is zero

    expect(controller.selection.baseOffset, 39);
    expect(controller.selection.extentOffset, 44);

    final RenderEditable renderEditable = findRenderEditable(tester);
    final List<TextSelectionPoint> endpoints = globalize(
      renderEditable.getEndpointsForSelection(controller.selection),
      renderEditable,
    );
    expect(endpoints.length, 2);

    // Drag the right handle to the third line, just after 'Third'.
    Offset handlePos = endpoints[1].point + const Offset(1.0, 1.0);
    Offset newHandlePos = textOffsetToPosition(tester, testValue.indexOf('Third') + 5);
    gesture = await tester.startGesture(handlePos, pointer: 7);
    await tester.pump();
    await gesture.moveTo(newHandlePos);
    await tester.pump();
    await gesture.up();
    await tester.pump();

    expect(controller.selection.baseOffset, 39);
    expect(controller.selection.extentOffset, 50);

    // Drag the left handle to the first line, just after 'First'.
    handlePos = endpoints[0].point + const Offset(-1.0, 1.0);
    newHandlePos = textOffsetToPosition(tester, testValue.indexOf('First') + 5);
    gesture = await tester.startGesture(handlePos, pointer: 7);
    await tester.pump();
    await gesture.moveTo(newHandlePos);
    await tester.pump();
    await gesture.up();
    await tester.pump();

    expect(controller.selection.baseOffset, 5);
    expect(controller.selection.extentOffset, 50);
    await tester.tap(find.text('Copy'));
    await tester.pump();
    expect(controller.selection.isCollapsed, true);
  });

  testWidgets('Can scroll multiline input', (WidgetTester tester) async {
    await tester.pumpWidget(
      overlay(
        child: const SelectableText(
          kMoreThanFourLines,
          dragStartBehavior: DragStartBehavior.down,
          style: TextStyle(color: Colors.black, fontSize: 34.0),
          maxLines: 2,
        ),
      ),
    );

    final EditableText editableTextWidget = tester.widget(find.byType(EditableText));
    final TextEditingController controller = editableTextWidget.controller;
    RenderBox findInputBox() => tester.renderObject(find.byType(SelectableText));
    final RenderBox inputBox = findInputBox();

    // Check that the last line of text is not displayed.
    final Offset firstPos = textOffsetToPosition(tester, kMoreThanFourLines.indexOf('First'));
    final Offset fourthPos = textOffsetToPosition(tester, kMoreThanFourLines.indexOf('Fourth'));
    expect(firstPos.dx, 0.0);
    expect(fourthPos.dx, 0.0);
    expect(firstPos.dx, fourthPos.dx);
    expect(firstPos.dy, lessThan(fourthPos.dy));
    expect(inputBox.hitTest(BoxHitTestResult(), position: inputBox.globalToLocal(firstPos)), isTrue);
    expect(inputBox.hitTest(BoxHitTestResult(), position: inputBox.globalToLocal(fourthPos)), isFalse);

    TestGesture gesture = await tester.startGesture(firstPos, pointer: 7);
    await tester.pump();
    await gesture.moveBy(const Offset(0.0, -1000.0));
    await tester.pump(const Duration(seconds: 1));
    // Wait and drag again to trigger https://github.com/flutter/flutter/issues/6329
    // (No idea why this is necessary, but the bug wouldn't repro without it.)
    await gesture.moveBy(const Offset(0.0, -1000.0));
    await tester.pump(const Duration(seconds: 1));
    await gesture.up();
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));

    // Now the first line is scrolled up, and the fourth line is visible.
    Offset newFirstPos = textOffsetToPosition(tester, kMoreThanFourLines.indexOf('First'));
    Offset newFourthPos = textOffsetToPosition(tester, kMoreThanFourLines.indexOf('Fourth'));

    expect(newFirstPos.dy, lessThan(firstPos.dy));
    expect(inputBox.hitTest(BoxHitTestResult(), position: inputBox.globalToLocal(newFirstPos)), isFalse);
    expect(inputBox.hitTest(BoxHitTestResult(), position: inputBox.globalToLocal(newFourthPos)), isTrue);

    // Now try scrolling by dragging the selection handle.
    // Long press the middle of the word "won't" in the fourth line.
    final Offset selectedWordPos = textOffsetToPosition(
      tester,
      kMoreThanFourLines.indexOf('Fourth line') + 14,
    );

    gesture = await tester.startGesture(selectedWordPos, pointer: 7);
    await tester.pump(const Duration(seconds: 1));
    await gesture.up();
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));

    expect(controller.selection.base.offset, 77);
    expect(controller.selection.extent.offset, 82);
    // Sanity check for the word selected is the intended one.
    expect(
      controller.text.substring(controller.selection.baseOffset, controller.selection.extentOffset),
      "won't",
    );

    final RenderEditable renderEditable = findRenderEditable(tester);
    final List<TextSelectionPoint> endpoints = globalize(
      renderEditable.getEndpointsForSelection(controller.selection),
      renderEditable,
    );
    expect(endpoints.length, 2);

    // Drag the left handle to the first line, just after 'First'.
    final Offset handlePos = endpoints[0].point + const Offset(-1, 1);
    final Offset newHandlePos = textOffsetToPosition(tester, kMoreThanFourLines.indexOf('First') + 5);
    gesture = await tester.startGesture(handlePos, pointer: 7);
    await tester.pump(const Duration(seconds: 1));
    await gesture.moveTo(newHandlePos + const Offset(0.0, -10.0));
    await tester.pump(const Duration(seconds: 1));
    await gesture.up();
    await tester.pump(const Duration(seconds: 1));

    // The text should have scrolled up with the handle to keep the active
    // cursor visible, back to its original position.
    newFirstPos = textOffsetToPosition(tester, kMoreThanFourLines.indexOf('First'));
    newFourthPos = textOffsetToPosition(tester, kMoreThanFourLines.indexOf('Fourth'));
    expect(newFirstPos.dy, firstPos.dy);
    expect(inputBox.hitTest(BoxHitTestResult(), position: inputBox.globalToLocal(newFirstPos)), isTrue);
    expect(inputBox.hitTest(BoxHitTestResult(), position: inputBox.globalToLocal(newFourthPos)), isFalse);
  });

  testWidgets('minLines cannot be greater than maxLines', (WidgetTester tester) async {
    expect(
      () async {
        await tester.pumpWidget(
          overlay(
            child: SizedBox(
              width: 300.0,
              child: SelectableText(
                'abcd',
                minLines: 4,
                maxLines: 3,
              ),
            ),
          ),
        );
      },
      throwsA(isA<AssertionError>().having(
        (AssertionError error) => error.toString(),
        '.toString()',
        contains("minLines can't be greater than maxLines"),
      )),
    );
  });

  testWidgets('Selectable height with minLine', (WidgetTester tester) async {
    await tester.pumpWidget(selectableTextBuilder());

    RenderBox findTextBox() => tester.renderObject(find.byType(SelectableText));

    final RenderBox textBox = findTextBox();
    final Size emptyInputSize = textBox.size;

    // Even if the text is a one liner, minimum height of SelectableText will determined by minLines
    await tester.pumpWidget(selectableTextBuilder(text: 'No wrapping here.', minLines: 2, maxLines: 3));
    expect(findTextBox(), equals(textBox));
    expect(textBox.size.height, emptyInputSize.height * 2);
  });

  testWidgets('Can align to center', (WidgetTester tester) async {
    await tester.pumpWidget(
      overlay(
        child: const SizedBox(
          width: 300.0,
          child: SelectableText(
            'abcd',
            textAlign: TextAlign.center,
          ),
        ),
      ),
    );

    final RenderEditable editable = findRenderEditable(tester);

    final Offset topLeft = editable.localToGlobal(
      editable.getLocalRectForCaret(const TextPosition(offset: 2)).topLeft,
    );

    expect(topLeft.dx, equals(399.0));
  });

  testWidgets('Can align to center within center', (WidgetTester tester) async {
    await tester.pumpWidget(
      overlay(
        child: const SizedBox(
          width: 300.0,
          child: Center(
            child: SelectableText(
              'abcd',
              textAlign: TextAlign.center,
            ),
          ),
        ),
      ),
    );

    final RenderEditable editable = findRenderEditable(tester);

    final Offset topLeft = editable.localToGlobal(
      editable.getLocalRectForCaret(const TextPosition(offset: 2)).topLeft,
    );

    expect(topLeft.dx, equals(399.0));
  });

  testWidgets('Selectable text drops selection when losing focus', (WidgetTester tester) async {
    final Key key1 = UniqueKey();
    final Key key2 = UniqueKey();

    await tester.pumpWidget(
      overlay(
        child: Column(
          children: <Widget>[
            SelectableText(
              'text 1',
              key: key1,
            ),
            SelectableText(
                'text 2',
                key: key2,
            ),
          ],
        ),
      ),
    );

    await tester.tap(find.byKey(key1));
    await tester.pump();
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;
    controller.selection = const TextSelection(baseOffset: 0, extentOffset: 3);
    await tester.pump();
    expect(controller.selection, isNot(equals(TextRange.empty)));

    await tester.tap(find.byKey(key2));
    await tester.pump();
    expect(controller.selection, equals(TextRange.empty));
  });

    testWidgets('Selectable text is skipped during focus traversal',
      (WidgetTester tester) async {
    final FocusNode firstFieldFocus = FocusNode();
    final FocusNode lastFieldFocus = FocusNode();

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: Column(
              children: <Widget>[
                TextField(
                  focusNode: firstFieldFocus,
                  autofocus: true,
                ),
                const SelectableText('some text'),
                TextField(
                  focusNode: lastFieldFocus,
                ),
              ],
            ),
          ),
        ),
      ),
    );

    await tester.pump();

    expect(firstFieldFocus.hasFocus, isTrue);
    expect(lastFieldFocus.hasFocus, isFalse);

    firstFieldFocus.nextFocus();
    await tester.pump();

    // expecting focus to skip straight to the second field
    expect(firstFieldFocus.hasFocus, isFalse);
    expect(lastFieldFocus.hasFocus, isTrue);
  });

  testWidgets('Selectable text identifies as text field in semantics', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: Center(
            child: SelectableText('some text'),
          ),
        ),
      ),
    );

    expect(
      semantics,
      includesNodeWith(
        flags: <SemanticsFlag>[
          SemanticsFlag.isTextField,
          SemanticsFlag.isReadOnly,
          SemanticsFlag.isMultiline,
        ],
      ),
    );

    semantics.dispose();
  });

  testWidgets('Selectable rich text with gesture recognizer has correct semantics', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    await tester.pumpWidget(
      overlay(
        child: SelectableText.rich(
          TextSpan(
            children: <TextSpan>[
              const TextSpan(text: 'text'),
              TextSpan(
                text: 'link',
                recognizer: TapGestureRecognizer()
                  ..onTap = () { },
              ),
            ],
          ),
        ),
      ),
    );

    expect(semantics, hasSemantics(TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: 1,
          actions: <SemanticsAction>[SemanticsAction.longPress],
          textDirection: TextDirection.ltr,
          children: <TestSemantics>[
            TestSemantics(
              id: 2,
              children: <TestSemantics>[
                TestSemantics(
                  id: 3,
                  label: 'text',
                  textDirection: TextDirection.ltr,
                ),
                TestSemantics(
                  id: 4,
                  flags: <SemanticsFlag>[SemanticsFlag.isLink],
                  actions: <SemanticsAction>[SemanticsAction.tap],
                  label: 'link',
                  textDirection: TextDirection.ltr,
                ),
              ],
            ),
          ],
        ),
      ],
    ), ignoreTransform: true, ignoreRect: true));

    semantics.dispose();
  });

  group('Keyboard Tests', () {
    late TextEditingController controller;

    Future<void> setupWidget(WidgetTester tester, String text) async {
      final FocusNode focusNode = FocusNode();
      await tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: RawKeyboardListener(
              focusNode: focusNode,
              onKey: null,
              child: SelectableText(
                text,
                maxLines: 3,
              ),
            ),
          ),
        ),
      );
      await tester.tap(find.byType(SelectableText));
      await tester.pumpAndSettle();
      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      controller = editableTextWidget.controller;
    }

    testWidgets('Shift test 1', (WidgetTester tester) async {
      await setupWidget(tester, 'a big house');

      await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
      await tester.sendKeyDownEvent(LogicalKeyboardKey.arrowLeft);
      expect(controller.selection.extentOffset - controller.selection.baseOffset, -1);
    });

    testWidgets('Shift test 2', (WidgetTester tester) async {
      await setupWidget(tester, 'abcdefghi');

      controller.selection = const TextSelection.collapsed(offset: 3);
      await tester.pump();

      await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
      await tester.sendKeyDownEvent(LogicalKeyboardKey.arrowRight);
      await tester.pumpAndSettle();
      expect(controller.selection.extentOffset - controller.selection.baseOffset, 1);
    });

    testWidgets('Control Shift test', (WidgetTester tester) async {
      await setupWidget(tester, 'their big house');

      await tester.sendKeyDownEvent(LogicalKeyboardKey.control);
      await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
      await tester.sendKeyDownEvent(LogicalKeyboardKey.arrowLeft);

      await tester.pumpAndSettle();

      expect(controller.selection.extentOffset - controller.selection.baseOffset, -5);
    });

    testWidgets('Down and up test', (WidgetTester tester) async {
      await setupWidget(tester, 'a big house');

      await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
      await tester.sendKeyDownEvent(LogicalKeyboardKey.arrowUp);
      await tester.pumpAndSettle();

      expect(controller.selection.extentOffset - controller.selection.baseOffset, -11);

      await tester.sendKeyUpEvent(LogicalKeyboardKey.arrowUp);
      await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
      await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
      await tester.sendKeyDownEvent(LogicalKeyboardKey.arrowDown);
      await tester.pumpAndSettle();

      expect(controller.selection.extentOffset - controller.selection.baseOffset, 0);
    });

    testWidgets('Down and up test 2', (WidgetTester tester) async {
      await setupWidget(tester, 'a big house\njumped over a mouse\nOne more line yay');

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

      for (int i = 0; i < 5; i += 1) {
        await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
        await tester.pumpAndSettle();
      }
      await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
      await tester.pumpAndSettle();
      await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
      await tester.pumpAndSettle();

      expect(controller.selection.extentOffset - controller.selection.baseOffset, 12);

      await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
      await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
      await tester.pumpAndSettle();
      await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
      await tester.pumpAndSettle();

      expect(controller.selection.extentOffset - controller.selection.baseOffset, 32);

      await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
      await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
      await tester.pumpAndSettle();
      await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
      await tester.pumpAndSettle();

      expect(controller.selection.extentOffset - controller.selection.baseOffset, 12);

      await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
      await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
      await tester.pumpAndSettle();
      await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
      await tester.pumpAndSettle();

      expect(controller.selection.extentOffset - controller.selection.baseOffset, 0);

      await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
      await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
      await tester.pumpAndSettle();
      await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
      await tester.pumpAndSettle();

      expect(controller.selection.extentOffset - controller.selection.baseOffset, -5);
    });
  });

  testWidgets('Copy test', (WidgetTester tester) async {
    final FocusNode focusNode = FocusNode();

    String clipboardContent = '';
    tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
      if (methodCall.method == 'Clipboard.setData')
        clipboardContent = (methodCall.arguments as Map<String, dynamic>)['text'] as String;
      else if (methodCall.method == 'Clipboard.getData')
        return <String, dynamic>{'text': clipboardContent};
      return null;
    });
    const String testValue = 'a big house\njumped over a mouse';
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: RawKeyboardListener(
            focusNode: focusNode,
            onKey: null,
            child: const SelectableText(
              testValue,
              maxLines: 3,
            ),
          ),
        ),
      ),
    );
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;
    focusNode.requestFocus();
    await tester.pump();

    await tester.tap(find.byType(SelectableText));
    await tester.pumpAndSettle();

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

    // Select the first 5 characters
    await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
    for (int i = 0; i < 5; i += 1) {
      await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
      await tester.pumpAndSettle();
    }
    await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);

    // Copy them
    await tester.sendKeyDownEvent(LogicalKeyboardKey.controlRight);
    await tester.sendKeyDownEvent(LogicalKeyboardKey.keyC);
    await tester.sendKeyUpEvent(LogicalKeyboardKey.keyC);
    await tester.sendKeyUpEvent(LogicalKeyboardKey.controlRight);
    await tester.pumpAndSettle();

    expect(clipboardContent, 'a big');

    await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
    await tester.pumpAndSettle();
  });

  testWidgets('Select all test', (WidgetTester tester) async {
    final FocusNode focusNode = FocusNode();
    const String testValue = 'a big house\njumped over a mouse';
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: RawKeyboardListener(
            focusNode: focusNode,
            onKey: null,
            child: const SelectableText(
              testValue,
              maxLines: 3,
            ),
          ),
        ),
      ),
    );
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;
    focusNode.requestFocus();
    await tester.pump();

    await tester.tap(find.byType(SelectableText));
    await tester.pumpAndSettle();

    // Select All
    await tester.sendKeyDownEvent(LogicalKeyboardKey.control);
    await tester.sendKeyEvent(LogicalKeyboardKey.keyA);
    await tester.sendKeyUpEvent(LogicalKeyboardKey.control);
    await tester.pumpAndSettle();

    expect(controller.selection.baseOffset, 0);
    expect(controller.selection.extentOffset, 31);
  });

  testWidgets('keyboard selection should call onSelectionChanged', (WidgetTester tester) async {
    final FocusNode focusNode = FocusNode();
    TextSelection? newSelection;
    const String testValue = 'a big house\njumped over a mouse';
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: RawKeyboardListener(
            focusNode: focusNode,
            onKey: null,
            child: SelectableText(
              testValue,
              maxLines: 3,
              onSelectionChanged: (TextSelection selection, SelectionChangedCause? cause) {
                expect(newSelection, isNull);
                newSelection = selection;
              },
            ),
          ),
        ),
      ),
    );
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;
    focusNode.requestFocus();
    await tester.pump();

    await tester.tap(find.byType(SelectableText));
    await tester.pumpAndSettle();
    expect(newSelection!.baseOffset, 31);
    expect(newSelection!.extentOffset, 31);
    newSelection = null;

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

    // Select the first 5 characters
    await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
    for (int i = 0; i < 5; i += 1) {
      await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
      await tester.pumpAndSettle();
      expect(newSelection!.baseOffset, 0);
      expect(newSelection!.extentOffset, i + 1);
      newSelection = null;
    }
  });

  testWidgets('Changing positions of selectable text', (WidgetTester tester) async {
    final FocusNode focusNode = FocusNode();
    final List<RawKeyEvent> events = <RawKeyEvent>[];

    final Key key1 = UniqueKey();
    final Key key2 = UniqueKey();

    await tester.pumpWidget(
      MaterialApp(
        home:
        Material(
          child: RawKeyboardListener(
            focusNode: focusNode,
            onKey: events.add,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                SelectableText(
                  'a big house',
                  key: key1,
                  maxLines: 3,
                ),
                SelectableText(
                  'another big house',
                  key: key2,
                  maxLines: 3,
                ),
              ],
            ),
          ),
        ),
      ),
    );

    EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    TextEditingController c1 = editableTextWidget.controller;

    await tester.tap(find.byType(EditableText).first);
    await tester.pumpAndSettle();

    await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
    for (int i = 0; i < 5; i += 1) {
      await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
      await tester.pumpAndSettle();
    }
    await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
    await tester.pumpAndSettle();

    expect(c1.selection.extentOffset - c1.selection.baseOffset, -5);

    await tester.pumpWidget(
      MaterialApp(
        home:
        Material(
          child: RawKeyboardListener(
            focusNode: focusNode,
            onKey: events.add,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                SelectableText(
                  'another big house',
                  key: key2,
                  maxLines: 3,
                ),
                SelectableText(
                  'a big house',
                  key: key1,
                  maxLines: 3,
                ),
              ],
            ),
          ),
        ),
      ),
    );

    await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
    for (int i = 0; i < 5; i += 1) {
      await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
    }
    await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
    await tester.pumpAndSettle();

    editableTextWidget = tester.widget(find.byType(EditableText).last);
    c1 = editableTextWidget.controller;

    expect(c1.selection.extentOffset - c1.selection.baseOffset, -6);
  });


  testWidgets('Changing focus test', (WidgetTester tester) async {
    final FocusNode focusNode = FocusNode();
    final List<RawKeyEvent> events = <RawKeyEvent>[];

    final Key key1 = UniqueKey();
    final Key key2 = UniqueKey();

    await tester.pumpWidget(
      MaterialApp(
        home:
        Material(
          child: RawKeyboardListener(
            focusNode: focusNode,
            onKey: events.add,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                SelectableText(
                  'a big house',
                  key: key1,
                  maxLines: 3,
                ),
                SelectableText(
                  'another big house',
                  key: key2,
                  maxLines: 3,
                ),
              ],
            ),
          ),
        ),
      ),
    );

    final EditableText editableTextWidget1 = tester.widget(find.byType(EditableText).first);
    final TextEditingController c1 = editableTextWidget1.controller;

    final EditableText editableTextWidget2 = tester.widget(find.byType(EditableText).last);
    final TextEditingController c2 = editableTextWidget2.controller;

    await tester.tap(find.byType(SelectableText).first);
    await tester.pumpAndSettle();

    await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
    for (int i = 0; i < 5; i += 1) {
      await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
      await tester.pumpAndSettle();
    }
    await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
    await tester.pumpAndSettle();

    expect(c1.selection.extentOffset - c1.selection.baseOffset, -5);
    expect(c2.selection.extentOffset - c2.selection.baseOffset, 0);

    await tester.tap(find.byType(SelectableText).last);
    await tester.pumpAndSettle();

    await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
    for (int i = 0; i < 5; i += 1) {
      await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
      await tester.pumpAndSettle();
    }
    await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
    await tester.pumpAndSettle();

    expect(c1.selection.extentOffset - c1.selection.baseOffset, 0);
    expect(c2.selection.extentOffset - c2.selection.baseOffset, -5);
  });

  testWidgets('Caret works when maxLines is null', (WidgetTester tester) async {
    await tester.pumpWidget(
        overlay(
          child: const SelectableText(
            'x',
            maxLines: null,
          ),
        ),
    );

    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;

    expect(controller.selection.baseOffset, -1);

    // Tap the selection handle to bring up the "paste / select all" menu.
    await tester.tapAt(textOffsetToPosition(tester, 0));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200)); // skip past the frame where the opacity is

    // Confirm that the selection was updated.
    expect(controller.selection.baseOffset, 0);
  });

  testWidgets('SelectableText baseline alignment no-strut', (WidgetTester tester) async {
    final Key keyA = UniqueKey();
    final Key keyB = UniqueKey();

    await tester.pumpWidget(
      overlay(
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.baseline,
          textBaseline: TextBaseline.alphabetic,
          children: <Widget>[
            Expanded(
              child: SelectableText(
                'A',
                key: keyA,
                style: const TextStyle(fontSize: 10.0),
                strutStyle: StrutStyle.disabled,
              ),
            ),
            const Text(
              'abc',
              style: TextStyle(fontSize: 20.0),
            ),
            Expanded(
              child: SelectableText(
                'B',
                key: keyB,
                style: const TextStyle(fontSize: 30.0),
                strutStyle: StrutStyle.disabled,
              ),
            ),
          ],
        ),
      ),
    );

    // The Ahem font extends 0.2 * fontSize below the baseline.
    // So the three row elements line up like this:
    //
    //  A  abc  B
    //  ---------   baseline
    //  2  4    6   space below the baseline = 0.2 * fontSize
    //  ---------   rowBottomY

    final double rowBottomY = tester.getBottomLeft(find.byType(Row)).dy;
    expect(tester.getBottomLeft(find.byKey(keyA)).dy, moreOrLessEquals(rowBottomY - 4.0, epsilon: 1e-3));
    expect(tester.getBottomLeft(find.text('abc')).dy, moreOrLessEquals(rowBottomY - 2.0, epsilon: 1e-3));
    expect(tester.getBottomLeft(find.byKey(keyB)).dy, rowBottomY);
  });

  testWidgets('SelectableText baseline alignment', (WidgetTester tester) async {
    final Key keyA = UniqueKey();
    final Key keyB = UniqueKey();

    await tester.pumpWidget(
      overlay(
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.baseline,
          textBaseline: TextBaseline.alphabetic,
          children: <Widget>[
            Expanded(
              child: SelectableText(
                'A',
                key: keyA,
                style: const TextStyle(fontSize: 10.0),
              ),
            ),
            const Text(
              'abc',
              style: TextStyle(fontSize: 20.0),
            ),
            Expanded(
              child: SelectableText(
                'B',
                key: keyB,
                style: const TextStyle(fontSize: 30.0),
              ),
            ),
          ],
        ),
      ),
    );

    // The Ahem font extends 0.2 * fontSize below the baseline.
    // So the three row elements line up like this:
    //
    //  A  abc  B
    //  ---------   baseline
    //  2  4    6   space below the baseline = 0.2 * fontSize
    //  ---------   rowBottomY

    final double rowBottomY = tester.getBottomLeft(find.byType(Row)).dy;
    expect(tester.getBottomLeft(find.byKey(keyA)).dy, moreOrLessEquals(rowBottomY - 4.0, epsilon: 1e-3));
    expect(tester.getBottomLeft(find.text('abc')).dy, moreOrLessEquals(rowBottomY - 2.0, epsilon: 1e-3));
    expect(tester.getBottomLeft(find.byKey(keyB)).dy, rowBottomY);
  });

  testWidgets('SelectableText semantics', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    final Key key = UniqueKey();

    await tester.pumpWidget(
      overlay(
        child: SelectableText(
          'Guten Tag',
          key: key,
        ),
      ),
    );

    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;

    expect(semantics, hasSemantics(TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: 1,
          textDirection: TextDirection.ltr,
          value: 'Guten Tag',
          actions: <SemanticsAction>[
            SemanticsAction.longPress,
          ],
          flags: <SemanticsFlag>[
            SemanticsFlag.isTextField,
            SemanticsFlag.isReadOnly,
            SemanticsFlag.isMultiline,
          ],
        ),
      ],
    ), ignoreTransform: true, ignoreRect: true));

    await tester.tap(find.byKey(key));
    await tester.pump();

    controller.selection = const TextSelection.collapsed(offset: 9);
    await tester.pump();

    expect(semantics, hasSemantics(TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: 1,
          textDirection: TextDirection.ltr,
          value: 'Guten Tag',
          textSelection: const TextSelection.collapsed(offset: 9),
          actions: <SemanticsAction>[
            SemanticsAction.longPress,
            SemanticsAction.moveCursorBackwardByCharacter,
            SemanticsAction.moveCursorBackwardByWord,
            SemanticsAction.setSelection,
          ],
          flags: <SemanticsFlag>[
            SemanticsFlag.isReadOnly,
            SemanticsFlag.isTextField,
            SemanticsFlag.isMultiline,
            SemanticsFlag.isFocused,
          ],
        ),
      ],
    ), ignoreTransform: true, ignoreRect: true));

    controller.selection = const TextSelection.collapsed(offset: 4);
    await tester.pump();

    expect(semantics, hasSemantics(TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: 1,
          textDirection: TextDirection.ltr,
          textSelection: const TextSelection.collapsed(offset: 4),
          value: 'Guten Tag',
          actions: <SemanticsAction>[
            SemanticsAction.longPress,
            SemanticsAction.moveCursorBackwardByCharacter,
            SemanticsAction.moveCursorForwardByCharacter,
            SemanticsAction.moveCursorBackwardByWord,
            SemanticsAction.moveCursorForwardByWord,
            SemanticsAction.setSelection,
          ],
          flags: <SemanticsFlag>[
            SemanticsFlag.isReadOnly,
            SemanticsFlag.isTextField,
            SemanticsFlag.isMultiline,
            SemanticsFlag.isFocused,
          ],
        ),
      ],
    ), ignoreTransform: true, ignoreRect: true));

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

    expect(semantics, hasSemantics(TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: 1,
          textDirection: TextDirection.ltr,
          textSelection: const TextSelection.collapsed(offset: 0),
          value: 'Guten Tag',
          actions: <SemanticsAction>[
            SemanticsAction.longPress,
            SemanticsAction.moveCursorForwardByCharacter,
            SemanticsAction.moveCursorForwardByWord,
            SemanticsAction.setSelection,
          ],
          flags: <SemanticsFlag>[
            SemanticsFlag.isReadOnly,
            SemanticsFlag.isTextField,
            SemanticsFlag.isMultiline,
            SemanticsFlag.isFocused,
          ],
        ),
      ],
    ), ignoreTransform: true, ignoreRect: true));

    semantics.dispose();
  });

  testWidgets('SelectableText semantics, enableInteractiveSelection = false', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    final Key key = UniqueKey();

    await tester.pumpWidget(
      overlay(
        child: SelectableText(
          'Guten Tag',
          key: key,
          enableInteractiveSelection: false,
        ),
      ),
    );

    await tester.tap(find.byKey(key));
    await tester.pump();

    expect(semantics, hasSemantics(TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: 1,
          value: 'Guten Tag',
          textDirection: TextDirection.ltr,
          actions: <SemanticsAction>[
            SemanticsAction.longPress,
            // Absent the following because enableInteractiveSelection: false
            // SemanticsAction.moveCursorBackwardByCharacter,
            // SemanticsAction.moveCursorBackwardByWord,
            // SemanticsAction.setSelection,
            // SemanticsAction.paste,
          ],
          flags: <SemanticsFlag>[
            SemanticsFlag.isReadOnly,
            SemanticsFlag.isTextField,
            SemanticsFlag.isMultiline,
            // SelectableText act like a text widget when enableInteractiveSelection
            // is false. It will not respond to any pointer event.
            // SemanticsFlag.isFocused,
          ],
        ),
      ],
    ), ignoreTransform: true, ignoreRect: true));

    semantics.dispose();
  });

  testWidgets('SelectableText semantics for selections', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    final Key key = UniqueKey();

    await tester.pumpWidget(
      overlay(
        child: SelectableText(
          'Hello',
          key: key,
        ),
      ),
    );

    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;

    expect(semantics, hasSemantics(TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: 1,
          value: 'Hello',
          textDirection: TextDirection.ltr,
          actions: <SemanticsAction>[
            SemanticsAction.longPress,
          ],
          flags: <SemanticsFlag>[
            SemanticsFlag.isReadOnly,
            SemanticsFlag.isTextField,
            SemanticsFlag.isMultiline,
          ],
        ),
      ],
    ), ignoreTransform: true, ignoreRect: true));

    // Focus the selectable text
    await tester.tap(find.byKey(key));
    await tester.pump();

    controller.selection = const TextSelection.collapsed(offset: 5);
    await tester.pump();

    expect(semantics, hasSemantics(TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: 1,
          value: 'Hello',
          textSelection: const TextSelection.collapsed(offset: 5),
          textDirection: TextDirection.ltr,
          actions: <SemanticsAction>[
            SemanticsAction.longPress,
            SemanticsAction.moveCursorBackwardByCharacter,
            SemanticsAction.moveCursorBackwardByWord,
            SemanticsAction.setSelection,
          ],
          flags: <SemanticsFlag>[
            SemanticsFlag.isReadOnly,
            SemanticsFlag.isTextField,
            SemanticsFlag.isMultiline,
            SemanticsFlag.isFocused,
          ],
        ),
      ],
    ), ignoreTransform: true, ignoreRect: true));

    controller.selection = const TextSelection(baseOffset: 5, extentOffset: 3);
    await tester.pump();

    expect(semantics, hasSemantics(TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: 1,
          value: 'Hello',
          textSelection: const TextSelection(baseOffset: 5, extentOffset: 3),
          textDirection: TextDirection.ltr,
          actions: <SemanticsAction>[
            SemanticsAction.longPress,
            SemanticsAction.moveCursorBackwardByCharacter,
            SemanticsAction.moveCursorForwardByCharacter,
            SemanticsAction.moveCursorBackwardByWord,
            SemanticsAction.moveCursorForwardByWord,
            SemanticsAction.setSelection,
            SemanticsAction.copy,
          ],
          flags: <SemanticsFlag>[
            SemanticsFlag.isReadOnly,
            SemanticsFlag.isTextField,
            SemanticsFlag.isMultiline,
            SemanticsFlag.isFocused,
          ],
        ),
      ],
    ), ignoreTransform: true, ignoreRect: true));

    semantics.dispose();
  });

  testWidgets('SelectableText change selection with semantics', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!;
    final Key key = UniqueKey();

    await tester.pumpWidget(
      overlay(
        child: SelectableText(
          'Hello',
          key: key,
        ),
      ),
    );

    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;

    // Focus the selectable text
    await tester.tap(find.byKey(key));
    await tester.pump();

    controller.selection = const TextSelection(baseOffset: 5, extentOffset: 5);
    await tester.pump();

    const int inputFieldId = 1;

    expect(semantics, hasSemantics(TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: inputFieldId,
          value: 'Hello',
          textSelection: const TextSelection.collapsed(offset: 5),
          textDirection: TextDirection.ltr,
          actions: <SemanticsAction>[
            SemanticsAction.longPress,
            SemanticsAction.moveCursorBackwardByCharacter,
            SemanticsAction.moveCursorBackwardByWord,
            SemanticsAction.setSelection,
          ],
          flags: <SemanticsFlag>[
            SemanticsFlag.isReadOnly,
            SemanticsFlag.isTextField,
            SemanticsFlag.isMultiline,
            SemanticsFlag.isFocused,
          ],
        ),
      ],
    ), ignoreTransform: true, ignoreRect: true));

    // move cursor back once
    semanticsOwner.performAction(inputFieldId, SemanticsAction.setSelection, <dynamic, dynamic>{
      'base': 4,
      'extent': 4,
    });
    await tester.pump();
    expect(controller.selection, const TextSelection.collapsed(offset: 4));

    // move cursor to front
    semanticsOwner.performAction(inputFieldId, SemanticsAction.setSelection, <dynamic, dynamic>{
      'base': 0,
      'extent': 0,
    });
    await tester.pump();
    expect(controller.selection, const TextSelection.collapsed(offset: 0));

    // select all
    semanticsOwner.performAction(inputFieldId, SemanticsAction.setSelection, <dynamic, dynamic>{
      'base': 0,
      'extent': 5,
    });
    await tester.pump();
    expect(controller.selection, const TextSelection(baseOffset: 0, extentOffset: 5));
    expect(semantics, hasSemantics(TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: inputFieldId,
          value: 'Hello',
          textSelection: const TextSelection(baseOffset: 0, extentOffset: 5),
          textDirection: TextDirection.ltr,
          actions: <SemanticsAction>[
            SemanticsAction.longPress,
            SemanticsAction.moveCursorBackwardByCharacter,
            SemanticsAction.moveCursorBackwardByWord,
            SemanticsAction.setSelection,
            SemanticsAction.copy,
          ],
          flags: <SemanticsFlag>[
            SemanticsFlag.isReadOnly,
            SemanticsFlag.isTextField,
            SemanticsFlag.isMultiline,
            SemanticsFlag.isFocused,
          ],
        ),
      ],
    ), ignoreTransform: true, ignoreRect: true));

    semantics.dispose();
  });

  testWidgets('Can activate SelectableText with explicit controller via semantics', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/17801

    const String testValue = 'Hello';

    final SemanticsTester semantics = SemanticsTester(tester);
    final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!;
    final Key key = UniqueKey();

    await tester.pumpWidget(
      overlay(
        child: SelectableText(
          testValue,
          key: key,
        ),
      ),
    );

    const int inputFieldId = 1;

    expect(semantics, hasSemantics(
      TestSemantics.root(
        children: <TestSemantics>[
          TestSemantics(
            id: inputFieldId,
            flags: <SemanticsFlag>[
              SemanticsFlag.isReadOnly,
              SemanticsFlag.isTextField,
              SemanticsFlag.isMultiline,
            ],
            actions: <SemanticsAction>[SemanticsAction.longPress],
            value: testValue,
            textDirection: TextDirection.ltr,
          ),
        ],
      ),
      ignoreRect: true, ignoreTransform: true,
    ));

    semanticsOwner.performAction(inputFieldId, SemanticsAction.longPress);
    await tester.pumpAndSettle();

    expect(semantics, hasSemantics(
      TestSemantics.root(
        children: <TestSemantics>[
          TestSemantics(
            id: inputFieldId,
            flags: <SemanticsFlag>[
              SemanticsFlag.isReadOnly,
              SemanticsFlag.isTextField,
              SemanticsFlag.isMultiline,
              SemanticsFlag.isFocused,
            ],
            actions: <SemanticsAction>[
              SemanticsAction.longPress,
              SemanticsAction.moveCursorBackwardByCharacter,
              SemanticsAction.moveCursorBackwardByWord,
              SemanticsAction.setSelection,
            ],
            value: testValue,
            textDirection: TextDirection.ltr,
            textSelection: const TextSelection(
              baseOffset: testValue.length,
              extentOffset: testValue.length,
            ),
          ),
        ],
      ),
      ignoreRect: true, ignoreTransform: true,
    ));

    semantics.dispose();
  });

  testWidgets('SelectableText throws when not descended from a MediaQuery widget', (WidgetTester tester) async {
    const Widget selectableText = SelectableText('something');
    await tester.pumpWidget(selectableText);
    final dynamic exception = tester.takeException();
    expect(exception, isFlutterError);
    expect(exception.toString(), startsWith('No MediaQuery widget ancestor found.\nSelectableText widgets require a MediaQuery widget ancestor.'));
  });

  testWidgets('onTap is called upon tap', (WidgetTester tester) async {
    int tapCount = 0;
    await tester.pumpWidget(
      overlay(
        child: SelectableText(
          'something',
          onTap: () {
            tapCount += 1;
          },
        ),
      ),
    );

    expect(tapCount, 0);
    await tester.tap(find.byType(SelectableText));
    // Wait a bit so they're all single taps and not double taps.
    await tester.pump(const Duration(milliseconds: 300));
    await tester.tap(find.byType(SelectableText));
    await tester.pump(const Duration(milliseconds: 300));
    await tester.tap(find.byType(SelectableText));
    await tester.pump(const Duration(milliseconds: 300));
    expect(tapCount, 3);
  });

  testWidgets('SelectableText style is merged with default text style', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/23994
    final TextStyle defaultStyle = TextStyle(
      color: Colors.blue[500],
    );
    Widget buildFrame(TextStyle style) {
      return MaterialApp(
        home: Material(
          child: DefaultTextStyle (
            style: defaultStyle,
            child: Center(
              child: SelectableText(
                'something',
                style: style,
              ),
            ),
          ),
        ),
      );
    }

    // Empty TextStyle is overridden by theme
    await tester.pumpWidget(buildFrame(const TextStyle()));
    EditableText editableText = tester.widget(find.byType(EditableText));
    expect(editableText.style.color, defaultStyle.color);
    expect(editableText.style.background, defaultStyle.background);
    expect(editableText.style.shadows, defaultStyle.shadows);
    expect(editableText.style.decoration, defaultStyle.decoration);
    expect(editableText.style.locale, defaultStyle.locale);
    expect(editableText.style.wordSpacing, defaultStyle.wordSpacing);

    // Properties set on TextStyle override theme
    const Color setColor = Colors.red;
    await tester.pumpWidget(buildFrame(const TextStyle(color: setColor)));
    editableText = tester.widget(find.byType(EditableText));
    expect(editableText.style.color, setColor);

    // inherit: false causes nothing to be merged in from theme
    await tester.pumpWidget(buildFrame(const TextStyle(
      fontSize: 24.0,
      textBaseline: TextBaseline.alphabetic,
      inherit: false,
    )));
    editableText = tester.widget(find.byType(EditableText));
    expect(editableText.style.color, isNull);
  });

  testWidgets('style enforces required fields', (WidgetTester tester) async {
    Widget buildFrame(TextStyle style) {
      return MaterialApp(
        home: Material(
          child: SelectableText(
            'something',
            style: style,
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame(const TextStyle(
      inherit: false,
      fontSize: 12.0,
      textBaseline: TextBaseline.alphabetic,
    )));
    expect(tester.takeException(), isNull);

    // With inherit not set to false, will pickup required fields from theme
    await tester.pumpWidget(buildFrame(const TextStyle(
      fontSize: 12.0,
    )));
    expect(tester.takeException(), isNull);

    await tester.pumpWidget(buildFrame(const TextStyle(
      inherit: false,
      fontSize: 12.0,
    )));
    expect(tester.takeException(), isNotNull);
  });

  testWidgets(
    'tap moves cursor to the edge of the word it tapped',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.tapAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump();

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;
      // We moved the cursor.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 7, affinity: TextAffinity.upstream),
      );

      // But don't trigger the toolbar.
      expect(find.byType(CupertinoButton), findsNothing);
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }),
  );

  testWidgets(
    'tap moves cursor to the position tapped (Android)',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.tapAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump();

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // We moved the cursor.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 4, affinity: TextAffinity.upstream),
      );

      // But don't trigger the toolbar.
      expect(find.byType(TextButton), findsNothing);
    },
  );

  testWidgets(
    'two slow taps do not trigger a word selection',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.tapAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump(const Duration(milliseconds: 500));
      await tester.tapAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump();

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // Plain collapsed selection.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 7, affinity: TextAffinity.upstream),
      );

      // No toolbar.
      expect(find.byType(CupertinoButton), findsNothing);
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }),
  );

  testWidgets(
    'double tap selects word and first tap of double tap moves cursor',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      // This tap just puts the cursor somewhere different than where the double
      // tap will occur to test that the double tap moves the existing cursor first.
      await tester.tapAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump(const Duration(milliseconds: 500));

      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // First tap moved the cursor.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 12, affinity: TextAffinity.upstream),
      );
      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump();

      // Second tap selects the word around the cursor.
      expect(
        controller.selection,
        const TextSelection(baseOffset: 8, extentOffset: 12),
      );

      // Selected text shows 1 toolbar buttons.
      expect(find.byType(CupertinoButton), findsNWidgets(1));
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }),
  );

  testWidgets(
    'double tap selects word and first tap of double tap moves cursor and shows toolbar (Android)',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      // This tap just puts the cursor somewhere different than where the double
      // tap will occur to test that the double tap moves the existing cursor first.
      await tester.tapAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump(const Duration(milliseconds: 500));

      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // First tap moved the cursor.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 11, affinity: TextAffinity.upstream),
      );
      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump();

      // Second tap selects the word around the cursor.
      expect(
        controller.selection,
        const TextSelection(baseOffset: 8, extentOffset: 12),
      );

      // Selected text shows 2 toolbar buttons: copy, select all
      expect(find.byType(TextButton), findsNWidgets(2));
    },
  );

  testWidgets(
    'double tap on top of cursor also selects word (Android)',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      // Tap to put the cursor after the "w".
      const int index = 3;
      await tester.tapAt(textOffsetToPosition(tester, index));
      await tester.pump(const Duration(milliseconds: 500));

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

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

      // Double tap on the same location.
      await tester.tapAt(textOffsetToPosition(tester, index));
      await tester.pump(const Duration(milliseconds: 50));

      // First tap doesn't change the selection
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: index),
      );

      // Second tap selects the word around the cursor.
      await tester.tapAt(textOffsetToPosition(tester, index));
      await tester.pump();
      expect(
        controller.selection,
        const TextSelection(baseOffset: 0, extentOffset: 7),
      );

      // Selected text shows 2 toolbar buttons: copy, select all
      expect(find.byType(TextButton), findsNWidgets(2));
    },
  );

  testWidgets(
    'double tap hold selects word',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));
      final TestGesture gesture =
      await tester.startGesture(selectableTextStart + const Offset(150.0, 5.0));
      // Hold the press.
      await tester.pump(const Duration(milliseconds: 500));

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      expect(
        controller.selection,
        const TextSelection(baseOffset: 8, extentOffset: 12),
      );

      // Selected text shows 1 toolbar buttons.
      expect(find.byType(CupertinoButton), findsNWidgets(1));

      await gesture.up();
      await tester.pump();

      // Still selected.
      expect(
        controller.selection,
        const TextSelection(baseOffset: 8, extentOffset: 12),
      );
      // The toolbar is still showing.
      expect(find.byType(CupertinoButton), findsNWidgets(1));
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }),
  );

  testWidgets(
    'double tap selects word with semantics label',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText.rich(
                TextSpan(text: 'Atwater Peel Sherbrooke Bonaventure', semanticsLabel: ''),
              ),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.tapAt(selectableTextStart + const Offset(220.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));
      await tester.tapAt(selectableTextStart + const Offset(220.0, 5.0));
      await tester.pump();

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      expect(
        controller.selection,
        const TextSelection(baseOffset: 13, extentOffset: 23),
      );
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }),
  );

  testWidgets(
    'tap after a double tap select is not affected (iOS)',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // First tap moved the cursor.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 12, affinity: TextAffinity.upstream),
      );
      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump(const Duration(milliseconds: 500));

      await tester.tapAt(selectableTextStart + const Offset(100.0, 5.0));
      await tester.pump();

      // Plain collapsed selection at the edge of first word. In iOS 12, the
      // first tap after a double tap ends up putting the cursor at where
      // you tapped instead of the edge like every other single tap. This is
      // likely a bug in iOS 12 and not present in other versions.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 7),
      );

      // No toolbar.
      expect(find.byType(CupertinoButton), findsNothing);
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }),
  );

  testWidgets(
    'long press selects word and shows toolbar (iOS)',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.longPressAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump();

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // The longpressed word is selected.
      expect(
        controller.selection,
        const TextSelection(
          baseOffset: 0,
          extentOffset: 7,
        ),
      );

      // Toolbar shows one button.
      expect(find.byType(CupertinoButton), findsNWidgets(1));
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }),
  );

  testWidgets(
    'long press selects word and shows toolbar (Android)',
    (WidgetTester tester) async {

      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.longPressAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump();

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      expect(
        controller.selection,
        const TextSelection(baseOffset: 0, extentOffset: 7),
      );

      // Collapsed toolbar shows 2 buttons: copy, select all
      expect(find.byType(TextButton), findsNWidgets(2));
    },
  );

  testWidgets(
    'long press selects word and shows custom toolbar (Android)',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure',
              selectionControls: cupertinoTextSelectionControls,
              ),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.longPressAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump();

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // The longpressed word is selected.
      expect(
        controller.selection,
        const TextSelection(
          baseOffset: 0,
          extentOffset: 7,
        ),
      );

      // Toolbar shows one button.
      expect(find.byType(CupertinoButton), findsNWidgets(1));
    },
    variant: TargetPlatformVariant.all(),
  );

  testWidgets(
    'long press selects word and shows custom toolbar (iOS)',
    (WidgetTester tester) async {

      await tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure',
              selectionControls: materialTextSelectionControls,
              ),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.longPressAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump();

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      expect(
        controller.selection,
        const TextSelection(baseOffset: 0, extentOffset: 7),
      );

      // Collapsed toolbar shows 2 buttons: copy, select all
      expect(find.byType(TextButton), findsNWidgets(2));
    },
    variant: TargetPlatformVariant.all(),
  );

  testWidgets(
    'textSelectionControls is passed to EditableText',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: Scaffold(
              body: SelectableText('Atwater Peel Sherbrooke Bonaventure',
                selectionControls: materialTextSelectionControls,
              ),
            ),
          ),
        ),
      );

      final EditableText widget = tester.widget(find.byType(EditableText));
      expect(widget.selectionControls, equals(materialTextSelectionControls));
    },
  );

  testWidgets(
    'long press tap cannot initiate a double tap',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.longPressAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));

      await tester.tapAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump();

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // We ended up moving the cursor to the edge of the same word and dismissed
      // the toolbar.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 7, affinity: TextAffinity.upstream),
      );

      expect(find.byType(CupertinoButton), findsNothing);
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }),
  );

  testWidgets(
    'long press drag moves the cursor under the drag and shows toolbar on lift (iOS)',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      final TestGesture gesture =
      await tester.startGesture(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump(const Duration(milliseconds: 500));

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // The longpressed word is selected.
      expect(
        controller.selection,
        const TextSelection(
          baseOffset: 0,
          extentOffset: 7,
          affinity: TextAffinity.downstream,
        ),
      );
      // Cursor move doesn't trigger a toolbar initially.
      expect(find.byType(CupertinoButton), findsNothing);

      await gesture.moveBy(const Offset(100, 0));
      await tester.pump();

      // The selection position is now moved with the drag.
      expect(
        controller.selection,
        const TextSelection(
          baseOffset: 0,
          extentOffset: 12,
          affinity: TextAffinity.downstream,
        ),
      );
      // Still no toolbar.
      expect(find.byType(CupertinoButton), findsNothing);

      await gesture.moveBy(const Offset(100, 0));
      await tester.pump();

      // The selection position is now moved with the drag.
      expect(
        controller.selection,
        const TextSelection(
          baseOffset: 0,
          extentOffset: 23,
          affinity: TextAffinity.downstream,
        ),
      );
      // Still no toolbar.
      expect(find.byType(CupertinoButton), findsNothing);

      await gesture.up();
      await tester.pump();

      // The selection isn't affected by the gesture lift.
      expect(
        controller.selection,
        const TextSelection(
          baseOffset: 0,
          extentOffset: 23,
          affinity: TextAffinity.downstream,
        ),
      );
      // The toolbar now shows up.
      expect(find.byType(CupertinoButton), findsNWidgets(1));
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
  );

  testWidgets(
    'long press drag moves the cursor under the drag and shows toolbar on lift (macOS)',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      final TestGesture gesture =
      await tester.startGesture(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump(const Duration(milliseconds: 500));

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // The longpressed word is selected.
      expect(
        controller.selection,
        const TextSelection(
          baseOffset: 0,
          extentOffset: 7,
          affinity: TextAffinity.downstream,
        ),
      );
      // Cursor move doesn't trigger a toolbar initially.
      expect(find.byType(CupertinoButton), findsNothing);

      await gesture.moveBy(const Offset(50, 0));
      await tester.pump();

      // The selection position is now moved with the drag.
      expect(
        controller.selection,
        const TextSelection(
          baseOffset: 0,
          extentOffset: 8,
          affinity: TextAffinity.downstream,
        ),
      );
      // Still no toolbar.
      expect(find.byType(CupertinoButton), findsNothing);

      await gesture.moveBy(const Offset(50, 0));
      await tester.pump();

      // The selection position is now moved with the drag.
      expect(
        controller.selection,
        const TextSelection(
          baseOffset: 0,
          extentOffset: 12,
          affinity: TextAffinity.downstream,
        ),
      );
      // Still no toolbar.
      expect(find.byType(CupertinoButton), findsNothing);

      await gesture.up();
      await tester.pump();

      // The selection isn't affected by the gesture lift.
      expect(
        controller.selection,
        const TextSelection(
          baseOffset: 0,
          extentOffset: 12,
          affinity: TextAffinity.downstream,
        ),
      );
      // The toolbar now shows up.
      expect(find.byType(CupertinoButton), findsNWidgets(1));
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS }),
  );

  testWidgets('long press drag can edge scroll', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: Center(
            child: SelectableText(
              'Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges',
              maxLines: 1,
            ),
          ),
        ),
      ),
    );

    final RenderEditable renderEditable = findRenderEditable(tester);

    List<TextSelectionPoint> lastCharEndpoint = renderEditable.getEndpointsForSelection(
      const TextSelection.collapsed(offset: 66), // Last character's position.
    );

    expect(lastCharEndpoint.length, 1);
    // Just testing the test and making sure that the last character is off
    // the right side of the screen.
    expect(lastCharEndpoint[0].point.dx, 924.0);

    final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

    final TestGesture gesture =
    await tester.startGesture(selectableTextStart + const Offset(300, 5));
    await tester.pump(const Duration(milliseconds: 500));

    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;

    expect(
      controller.selection,
      const TextSelection(baseOffset: 13, extentOffset: 23),
    );
    expect(find.byType(CupertinoButton), findsNothing);

    await gesture.moveBy(const Offset(600, 0));
    // To the edge of the screen basically.
    await tester.pump();
    expect(
      controller.selection,
      const TextSelection(
        baseOffset: 13,
        extentOffset: 66,
        affinity: TextAffinity.downstream,
      ),
    );
    // Keep moving out.
    await gesture.moveBy(const Offset(1, 0));
    await tester.pump();
    expect(
      controller.selection,
      const TextSelection(
        baseOffset: 13,
        extentOffset: 66,
        affinity: TextAffinity.downstream,
      ),
    );
    await gesture.moveBy(const Offset(1, 0));
    await tester.pump();
    expect(
      controller.selection,
      const TextSelection(
        baseOffset: 13,
        extentOffset: 66,
        affinity: TextAffinity.downstream,
      ),
    );
    expect(find.byType(CupertinoButton), findsNothing);

    await gesture.up();
    await tester.pump();

    // The selection isn't affected by the gesture lift.
    expect(
      controller.selection,
      const TextSelection(
        baseOffset: 13,
        extentOffset: 66,
        affinity: TextAffinity.downstream,
      ),
    );
    // The toolbar now shows up.
    expect(find.byType(CupertinoButton), findsNWidgets(1));

    lastCharEndpoint = renderEditable.getEndpointsForSelection(
      const TextSelection.collapsed(offset: 66), // Last character's position.
    );

    expect(lastCharEndpoint.length, 1);
    // The last character is now on screen near the right edge.
    expect(lastCharEndpoint[0].point.dx, moreOrLessEquals(798, epsilon: 1));

    final List<TextSelectionPoint> firstCharEndpoint = renderEditable.getEndpointsForSelection(
      const TextSelection.collapsed(offset: 0), // First character's position.
    );
    expect(firstCharEndpoint.length, 1);
    // The first character is now offscreen to the left.
    expect(firstCharEndpoint[0].point.dx, moreOrLessEquals(-125, epsilon: 1));
  },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }),
    skip: true, // https://github.com/flutter/flutter/issues/64059
  );

  testWidgets(
    'long tap still selects after a double tap select (iOS)',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // First tap moved the cursor to the beginning of the second word.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 12, affinity: TextAffinity.upstream),
      );
      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump(const Duration(milliseconds: 500));

      await tester.longPressAt(selectableTextStart + const Offset(100.0, 5.0));
      await tester.pump();

      // Selected the "word" where the tap happened, which is the first space.
      // Because the "word" is a whitespace, the selection will shift to the
      // previous "word" that is not a whitespace.
      expect(
        controller.selection,
        const TextSelection(baseOffset: 0, extentOffset: 7),
      );

      // Long press toolbar.
      expect(find.byType(CupertinoButton), findsNWidgets(1));
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
  );

  testWidgets(
    'long tap still selects after a double tap select (macOS)',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // First tap moved the cursor to the beginning of the second word.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 12, affinity: TextAffinity.upstream),
      );
      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump(const Duration(milliseconds: 500));

      await tester.longPressAt(selectableTextStart + const Offset(100.0, 5.0));
      await tester.pump();

      // Selected the "word" where the tap happened, which is the first space.
      expect(
        controller.selection,
        const TextSelection(baseOffset: 7, extentOffset: 8),
      );

      // Long press toolbar.
      expect(find.byType(CupertinoButton), findsNWidgets(1));
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS }),
  );
//convert
  testWidgets(
    'double tap after a long tap is not affected',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.longPressAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));

      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      // First tap moved the cursor.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 12, affinity: TextAffinity.upstream),
      );
      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump();

      // Double tap selection.
      expect(
        controller.selection,
        const TextSelection(baseOffset: 8, extentOffset: 12),
      );
      expect(find.byType(CupertinoButton), findsNWidgets(1));
    }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }),
  );

  testWidgets(
    'double tap chains work',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: Center(
              child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
            ),
          ),
        ),
      );

      final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

      await tester.tapAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));

      final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
      final TextEditingController controller = editableTextWidget.controller;

      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 7, affinity: TextAffinity.upstream),
      );
      await tester.tapAt(selectableTextStart + const Offset(50.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));
      expect(
        controller.selection,
        const TextSelection(baseOffset: 0, extentOffset: 7),
      );
      expect(find.byType(CupertinoButton), findsNWidgets(1));

      // Double tap selecting the same word somewhere else is fine.
      await tester.tapAt(selectableTextStart + const Offset(10.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));
      // First tap moved the cursor.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 0, affinity: TextAffinity.downstream),
      );
      await tester.tapAt(selectableTextStart + const Offset(10.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));
      expect(
        controller.selection,
        const TextSelection(baseOffset: 0, extentOffset: 7),
      );
      expect(find.byType(CupertinoButton), findsNWidgets(1));

      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));
      // First tap moved the cursor.
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 12, affinity: TextAffinity.upstream),
      );
      await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
      await tester.pump(const Duration(milliseconds: 50));
      expect(
        controller.selection,
        const TextSelection(baseOffset: 8, extentOffset: 12),
      );
      expect(find.byType(CupertinoButton), findsNWidgets(1));
    },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }),
  );

  testWidgets('force press does not select a word on (android)', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
        ),
      ),
    );

    final Offset offset = tester.getTopLeft(find.byType(SelectableText)) + const Offset(150.0, 5.0);

    final int pointerValue = tester.nextPointer;
    final TestGesture gesture = await tester.createGesture();
    await gesture.downWithCustomEvent(
      offset,
      PointerDownEvent(
        pointer: pointerValue,
        position: offset,
        pressure: 0.0,
        pressureMax: 6.0,
        pressureMin: 0.0,
      ),
    );
    await gesture.updateWithCustomEvent(PointerMoveEvent(pointer: pointerValue, position: offset + const Offset(150.0, 5.0), pressure: 0.5, pressureMin: 0, pressureMax: 1));

    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;

    // We don't want this gesture to select any word on Android.
    expect(controller.selection, const TextSelection.collapsed(offset: -1));

    await gesture.up();
    await tester.pump();
    expect(find.byType(TextButton), findsNothing);
  });

  testWidgets('force press selects word', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
        ),
      ),
    );

    final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

    final int pointerValue = tester.nextPointer;
    final Offset offset = selectableTextStart + const Offset(150.0, 5.0);
    final TestGesture gesture = await tester.createGesture();
    await gesture.downWithCustomEvent(
      offset,
      PointerDownEvent(
        pointer: pointerValue,
        position: offset,
        pressure: 0.0,
        pressureMax: 6.0,
        pressureMin: 0.0,
      ),
    );

    await gesture.updateWithCustomEvent(PointerMoveEvent(pointer: pointerValue, position: selectableTextStart + const Offset(150.0, 5.0), pressure: 0.5, pressureMin: 0, pressureMax: 1));

    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;

    // We expect the force press to select a word at the given location.
    expect(
      controller.selection,
      const TextSelection(baseOffset: 8, extentOffset: 12),
    );

    await gesture.up();
    await tester.pump();
    expect(find.byType(CupertinoButton), findsNWidgets(1));
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }));

  testWidgets('tap on non-force-press-supported devices work', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText('Atwater Peel Sherbrooke Bonaventure'),
        ),
      ),
    );

    final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

    final int pointerValue = tester.nextPointer;
    final Offset offset = selectableTextStart + const Offset(150.0, 5.0);
    final TestGesture gesture = await tester.createGesture();
    await gesture.downWithCustomEvent(
      offset,
      PointerDownEvent(
        pointer: pointerValue,
        position: offset,
        // iPhone 6 and below report 0 across the board.
        pressure: 0,
        pressureMax: 0,
        pressureMin: 0,
      ),
    );

    await gesture.updateWithCustomEvent(PointerMoveEvent(pointer: pointerValue, position: selectableTextStart + const Offset(150.0, 5.0), pressure: 0.5, pressureMin: 0, pressureMax: 1));
    await gesture.up();

    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;

    // The event should fallback to a normal tap and move the cursor.
    // Single taps selects the edge of the word.
    expect(
      controller.selection,
      const TextSelection.collapsed(offset: 12, affinity: TextAffinity.upstream),
    );

    await tester.pump();
    // Single taps shouldn't trigger the toolbar.
    expect(find.byType(CupertinoButton), findsNothing);

    // TODO(gspencergoog): Add in TargetPlatform.macOS in the line below when we
    // figure out what global state is leaking.
    // https://github.com/flutter/flutter/issues/43445
  }, variant: TargetPlatformVariant.only(TargetPlatform.iOS));

  testWidgets('default SelectableText debugFillProperties', (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();

    const SelectableText('something').debugFillProperties(builder);

    final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString()).toList();

    expect(description, <String>['data: something']);
  });

  testWidgets('SelectableText implements debugFillProperties', (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();

    // Not checking controller, inputFormatters, focusNode
    const SelectableText(
      'something',
      style: TextStyle(color: Color(0xff00ff00)),
      textAlign: TextAlign.end,
      textDirection: TextDirection.ltr,
      textScaleFactor: 1.0,
      autofocus: true,
      showCursor: true,
      minLines: 2,
      maxLines: 10,
      cursorWidth: 1.0,
      cursorHeight: 1.0,
      cursorRadius: Radius.zero,
      cursorColor: Color(0xff00ff00),
      scrollPhysics: ClampingScrollPhysics(),
      enableInteractiveSelection: false,
    ).debugFillProperties(builder);

    final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString()).toList();

    expect(description, <String>[
      'data: something',
      'style: TextStyle(inherit: true, color: Color(0xff00ff00))',
      'autofocus: true',
      'showCursor: true',
      'minLines: 2',
      'maxLines: 10',
      'textAlign: end',
      'textDirection: ltr',
      'textScaleFactor: 1.0',
      'cursorWidth: 1.0',
      'cursorHeight: 1.0',
      'cursorRadius: Radius.circular(0.0)',
      'cursorColor: Color(0xff00ff00)',
      'selection disabled',
      'scrollPhysics: ClampingScrollPhysics',
    ]);
  });

  testWidgets(
    'strut basic single line',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(platform: TargetPlatform.android),
          home: const Material(
            child: Center(
              child: SelectableText('something'),
            ),
          ),
        ),
      );

      expect(
        tester.getSize(find.byType(SelectableText)),
        // This is the height of the decoration (24) plus the metrics from the default
        // TextStyle of the theme (16).
        const Size(129.0, 14.0),
      );
    },
  );

  testWidgets(
    'strut TextStyle increases height',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(platform: TargetPlatform.android),
          home: const Material(
            child: Center(
              child: SelectableText(
                'something',
                style: TextStyle(fontSize: 20),
              ),
            ),
          ),
        ),
      );

      expect(
        tester.getSize(find.byType(SelectableText)),
        // Strut should inherit the TextStyle.fontSize by default and produce the
        // same height as if it were disabled.
        const Size(183.0, 20.0),
      );

      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(platform: TargetPlatform.android),
          home: const Material(
            child: Center(
              child: SelectableText(
                'something',
                style: TextStyle(fontSize: 20),
                strutStyle: StrutStyle.disabled,
              ),
            ),
          ),
        ),
      );

      expect(
        tester.getSize(find.byType(SelectableText)),
        // The height here should match the previous version with strut enabled.
        const Size(183.0, 20.0),
      );
    },
  );

  testWidgets(
    'strut basic multi line',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(platform: TargetPlatform.android),
          home: const Material(
            child: Center(
              child: SelectableText(
                'something',
                maxLines: 6,
              ),
            ),
          ),
        ),
      );

      expect(
        tester.getSize(find.byType(SelectableText)),
        const Size(129.0, 84.0),
      );
    },
  );

  testWidgets(
    'strut no force small strut',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(platform: TargetPlatform.android),
          home: const Material(
            child: Center(
              child: SelectableText(
                'something',
                maxLines: 6,
                strutStyle: StrutStyle(
                  // The small strut is overtaken by the larger
                  // TextStyle fontSize.
                  fontSize: 5,
                ),
              ),
            ),
          ),
        ),
      );

      expect(
        tester.getSize(find.byType(SelectableText)),
        // When the strut's height is smaller than TextStyle's and forceStrutHeight
        // is disabled, then the TextStyle takes precedence. Should be the same height
        // as 'strut basic multi line'.
        const Size(129.0, 84.0),
      );
    },
  );

  testWidgets(
    'strut no force large strut',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(platform: TargetPlatform.android),
          home: const Material(
            child: Center(
              child: SelectableText(
                'something',
                maxLines: 6,
                strutStyle: StrutStyle(
                  fontSize: 25,
                ),
              ),
            ),
          ),
        ),
      );

      expect(
        tester.getSize(find.byType(SelectableText)),
        // When the strut's height is larger than TextStyle's and forceStrutHeight
        // is disabled, then the StrutStyle takes precedence.
        const Size(129.0, 150.0),
      );
    },
  );

  testWidgets(
    'strut height override',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(platform: TargetPlatform.android),
          home: const Material(
            child: Center(
              child: SelectableText(
                'something',
                maxLines: 3,
                strutStyle: StrutStyle(
                  fontSize: 8,
                  forceStrutHeight: true,
                ),
              ),
            ),
          ),
        ),
      );

      expect(
        tester.getSize(find.byType(SelectableText)),
        // The smaller font size of strut make the field shorter than normal.
        const Size(129.0, 24.0),
      );
    },
  );

  testWidgets(
    'strut forces field taller',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(platform: TargetPlatform.android),
          home: const Material(
            child: Center(
              child: SelectableText(
                'something',
                maxLines: 3,
                style: TextStyle(fontSize: 10),
                strutStyle: StrutStyle(
                  fontSize: 18,
                  forceStrutHeight: true,
                ),
              ),
            ),
          ),
        ),
      );

      expect(
        tester.getSize(find.byType(SelectableText)),
        // When the strut fontSize is larger than a provided TextStyle, the
        // strut's height takes precedence.
        const Size(93.0, 54.0),
      );
    },
  );

  testWidgets('Caret center position', (WidgetTester tester) async {
    await tester.pumpWidget(
      overlay(
        child: const SizedBox(
          width: 300.0,
          child: SelectableText(
            'abcd',
            textAlign: TextAlign.center,
          ),
        ),
      ),
    );

    final RenderEditable editable = findRenderEditable(tester);

    Offset topLeft = editable.localToGlobal(
      editable.getLocalRectForCaret(const TextPosition(offset: 4)).topLeft,
    );
    expect(topLeft.dx, equals(427));

    topLeft = editable.localToGlobal(
      editable.getLocalRectForCaret(const TextPosition(offset: 3)).topLeft,
    );
    expect(topLeft.dx, equals(413));

    topLeft = editable.localToGlobal(
      editable.getLocalRectForCaret(const TextPosition(offset: 2)).topLeft,
    );
    expect(topLeft.dx, equals(399));

    topLeft = editable.localToGlobal(
      editable.getLocalRectForCaret(const TextPosition(offset: 1)).topLeft,
    );
    expect(topLeft.dx, equals(385));
  });

  testWidgets('Caret indexes into trailing whitespace center align', (WidgetTester tester) async {
    await tester.pumpWidget(
      overlay(
        child: const SizedBox(
          width: 300.0,
          child: SelectableText(
            'abcd    ',
            textAlign: TextAlign.center,
          ),
        ),
      ),
    );

    final RenderEditable editable = findRenderEditable(tester);

    Offset topLeft = editable.localToGlobal(
      editable.getLocalRectForCaret(const TextPosition(offset: 7)).topLeft,
    );
    expect(topLeft.dx, equals(469));

    topLeft = editable.localToGlobal(
      editable.getLocalRectForCaret(const TextPosition(offset: 8)).topLeft,
    );
    expect(topLeft.dx, equals(483));

    topLeft = editable.localToGlobal(
      editable.getLocalRectForCaret(const TextPosition(offset: 4)).topLeft,
    );
    expect(topLeft.dx, equals(427));

    topLeft = editable.localToGlobal(
      editable.getLocalRectForCaret(const TextPosition(offset: 3)).topLeft,
    );
    expect(topLeft.dx, equals(413));

    topLeft = editable.localToGlobal(
      editable.getLocalRectForCaret(const TextPosition(offset: 2)).topLeft,
    );
    expect(topLeft.dx, equals(399));

    topLeft = editable.localToGlobal(
      editable.getLocalRectForCaret(const TextPosition(offset: 1)).topLeft,
    );
    expect(topLeft.dx, equals(385));
  });

  testWidgets('selection handles are rendered and not faded away', (WidgetTester tester) async {
    const String testText = 'lorem ipsum';
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText(testText),
        ),
      ),
    );

    final EditableTextState state =
    tester.state<EditableTextState>(find.byType(EditableText));
    final RenderEditable renderEditable = state.renderEditable;

    await tester.tapAt(const Offset(20, 10));
    renderEditable.selectWord(cause: SelectionChangedCause.longPress);
    await tester.pumpAndSettle();

    final List<FadeTransition> transitions = find.descendant(
      of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_TextSelectionHandleOverlay'),
      matching: find.byType(FadeTransition),
    ).evaluate().map((Element e) => e.widget).cast<FadeTransition>().toList();
    expect(transitions.length, 2);
    final FadeTransition left = transitions[0];
    final FadeTransition right = transitions[1];

    expect(left.opacity.value, equals(1.0));
    expect(right.opacity.value, equals(1.0));
  });

  testWidgets('selection handles are rendered and not faded away', (WidgetTester tester) async {
    const String testText = 'lorem ipsum';

    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText(testText),
        ),
      ),
    );

    final RenderEditable renderEditable =
        tester.state<EditableTextState>(find.byType(EditableText)).renderEditable;

    await tester.tapAt(const Offset(20, 10));
    renderEditable.selectWord(cause: SelectionChangedCause.longPress);
    await tester.pumpAndSettle();

    final List<Widget> transitions =
    find.byType(FadeTransition).evaluate().map((Element e) => e.widget).toList();
    expect(transitions.length, 2);
    final FadeTransition left = transitions[0] as FadeTransition;
    final FadeTransition right = transitions[1] as FadeTransition;

    expect(left.opacity.value, equals(1.0));
    expect(right.opacity.value, equals(1.0));
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('Long press shows handles and toolbar', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText('abc def ghi'),
        ),
      ),
    );

    // Long press at 'e' in 'def'.
    final Offset ePos = textOffsetToPosition(tester, 5);
    await tester.longPressAt(ePos);
    await tester.pumpAndSettle();

    final EditableTextState editableText = tester.state(find.byType(EditableText));
    expect(editableText.selectionOverlay!.handlesAreVisible, isTrue);
    expect(editableText.selectionOverlay!.toolbarIsVisible, isTrue);
  });

  testWidgets('Double tap shows handles and toolbar', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText('abc def ghi'),
        ),
      ),
    );

    // Double tap at 'e' in 'def'.
    final Offset ePos = textOffsetToPosition(tester, 5);
    await tester.tapAt(ePos);
    await tester.pump(const Duration(milliseconds: 50));
    await tester.tapAt(ePos);
    await tester.pump();

    final EditableTextState editableText = tester.state(find.byType(EditableText));
    expect(editableText.selectionOverlay!.handlesAreVisible, isTrue);
    expect(editableText.selectionOverlay!.toolbarIsVisible, isTrue);
  });

  testWidgets(
    'Mouse tap does not show handles nor toolbar',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: SelectableText('abc def ghi'),
          ),
        ),
      );

      // Long press to trigger the selectable text.
      final Offset ePos = textOffsetToPosition(tester, 5);
      final TestGesture gesture = await tester.startGesture(
        ePos,
        pointer: 7,
        kind: PointerDeviceKind.mouse,
      );
      addTearDown(gesture.removePointer);
      await tester.pump();
      await gesture.up();
      await tester.pump();

      final EditableTextState editableText = tester.state(find.byType(EditableText));
      expect(editableText.selectionOverlay!.toolbarIsVisible, isFalse);
      expect(editableText.selectionOverlay!.handlesAreVisible, isFalse);
    },
  );

  testWidgets(
    'Mouse long press does not show handles nor toolbar',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: SelectableText('abc def ghi'),
          ),
        ),
      );

      // Long press to trigger the selectable text.
      final Offset ePos = textOffsetToPosition(tester, 5);
      final TestGesture gesture = await tester.startGesture(
        ePos,
        pointer: 7,
        kind: PointerDeviceKind.mouse,
      );
      addTearDown(gesture.removePointer);
      await tester.pump(const Duration(seconds: 2));
      await gesture.up();
      await tester.pump();

      final EditableTextState editableText = tester.state(find.byType(EditableText));
      expect(editableText.selectionOverlay!.toolbarIsVisible, isFalse);
      expect(editableText.selectionOverlay!.handlesAreVisible, isFalse);
    },
  );

  testWidgets(
    'Mouse double tap does not show handles nor toolbar',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: SelectableText('abc def ghi'),
          ),
        ),
      );

      // Double tap to trigger the selectable text.
      final Offset selectableTextPos = tester.getCenter(find.byType(SelectableText));
      final TestGesture gesture = await tester.startGesture(
        selectableTextPos,
        pointer: 7,
        kind: PointerDeviceKind.mouse,
      );
      addTearDown(gesture.removePointer);
      await tester.pump(const Duration(milliseconds: 50));
      await gesture.up();
      await tester.pump();
      await gesture.down(selectableTextPos);
      await tester.pump();
      await gesture.up();
      await tester.pump();

      final EditableTextState editableText = tester.state(find.byType(EditableText));
      expect(editableText.selectionOverlay!.toolbarIsVisible, isFalse);
      expect(editableText.selectionOverlay!.handlesAreVisible, isFalse);
    },
  );

  testWidgets('text span with tap gesture recognizer works in selectable rich text', (WidgetTester tester) async {
    int spyTaps = 0;
    final TapGestureRecognizer spyRecognizer = TapGestureRecognizer()
      ..onTap = () {
        spyTaps += 1;
      };
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: SelectableText.rich(
              TextSpan(
                children: <TextSpan>[
                  const TextSpan(text: 'Atwater '),
                  TextSpan(text: 'Peel', recognizer: spyRecognizer),
                  const TextSpan(text: ' Sherbrooke Bonaventure'),
                ],
              ),
            ),
          ),
        ),
      ),
    );
    expect(spyTaps, 0);
    final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

    await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
    expect(spyTaps, 1);

    // Waits for a while to avoid double taps.
    await tester.pump(const Duration(seconds: 1));

    // Starts a long press.
    final TestGesture gesture =
      await tester.startGesture(selectableTextStart + const Offset(150.0, 5.0));
    await tester.pump(const Duration(milliseconds: 500));
    await gesture.up();
    await tester.pump();
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);

    final TextEditingController controller = editableTextWidget.controller;
    // Long press still triggers selection.
    expect(
      controller.selection,
      const TextSelection(baseOffset: 8, extentOffset: 12),
    );
    // Long press does not trigger gesture recognizer.
    expect(spyTaps, 1);
  });

  testWidgets('text span with long press gesture recognizer works in selectable rich text', (WidgetTester tester) async {
    int spyLongPress = 0;
    final LongPressGestureRecognizer spyRecognizer = LongPressGestureRecognizer()
      ..onLongPress = () {
        spyLongPress += 1;
      };
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: SelectableText.rich(
              TextSpan(
                children: <TextSpan>[
                  const TextSpan(text: 'Atwater '),
                  TextSpan(text: 'Peel', recognizer: spyRecognizer),
                  const TextSpan(text: ' Sherbrooke Bonaventure'),
                ],
              ),
            ),
          ),
        ),
      ),
    );
    expect(spyLongPress, 0);
    final Offset selectableTextStart = tester.getTopLeft(find.byType(SelectableText));

    await tester.tapAt(selectableTextStart + const Offset(150.0, 5.0));
    expect(spyLongPress, 0);

    // Waits for a while to avoid double taps.
    await tester.pump(const Duration(seconds: 1));

    // Starts a long press.
    final TestGesture gesture =
    await tester.startGesture(selectableTextStart + const Offset(150.0, 5.0));
    await tester.pump(const Duration(milliseconds: 500));
    await gesture.up();
    await tester.pump();
    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);

    final TextEditingController controller = editableTextWidget.controller;
    // Long press does not trigger selection if there is text span with long
    // press recognizer.
    expect(
      controller.selection,
      const TextSelection(baseOffset: 11, extentOffset: 11, affinity: TextAffinity.upstream),
    );
    // Long press triggers gesture recognizer.
    expect(spyLongPress, 1);
  });

  testWidgets('SelectableText changes mouse cursor when hovered', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: Center(
            child: SelectableText('test'),
          ),
        ),
      ),
    );

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
    await gesture.addPointer(location: tester.getCenter(find.text('test')));
    addTearDown(gesture.removePointer);

    await tester.pump();

    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
  });

  testWidgets('The handles show after pressing Select All', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText('abc def ghi'),
        ),
      ),
    );

    // Long press at 'e' in 'def'.
    final Offset ePos = textOffsetToPosition(tester, 5);
    await tester.longPressAt(ePos);
    await tester.pumpAndSettle();

    expect(find.text('Select all'), findsOneWidget);
    expect(find.text('Copy'), findsOneWidget);
    expect(find.text('Paste'), findsNothing);
    expect(find.text('Cut'), findsNothing);
    EditableTextState editableText = tester.state(find.byType(EditableText));
    expect(editableText.selectionOverlay!.handlesAreVisible, isTrue);
    expect(editableText.selectionOverlay!.toolbarIsVisible, isTrue);

    await tester.tap(find.text('Select all'));
    await tester.pump();
    expect(find.text('Copy'), findsOneWidget);
    expect(find.text('Select all'), findsNothing);
    expect(find.text('Paste'), findsNothing);
    expect(find.text('Cut'), findsNothing);
    editableText = tester.state(find.byType(EditableText));
    expect(editableText.selectionOverlay!.handlesAreVisible, isTrue);
  },
    variant: const TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.android,
      TargetPlatform.fuchsia,
    }),
  );

  testWidgets('The Select All calls on selection changed', (WidgetTester tester) async {
    TextSelection? newSelection;
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: SelectableText(
            'abc def ghi',
            onSelectionChanged: (TextSelection selection, SelectionChangedCause? cause) {
              expect(newSelection, isNull);
              newSelection = selection;
            },
          ),
        ),
      ),
    );

    // Long press at 'e' in 'def'.
    final Offset ePos = textOffsetToPosition(tester, 5);
    await tester.longPressAt(ePos);
    await tester.pumpAndSettle();

    expect(newSelection!.baseOffset, 4);
    expect(newSelection!.extentOffset, 7);
    newSelection = null;

    await tester.tap(find.text('Select all'));
    await tester.pump();
    expect(newSelection!.baseOffset, 0);
    expect(newSelection!.extentOffset, 11);
  },
    variant: const TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.android,
      TargetPlatform.fuchsia,
    }),
  );

  testWidgets('The Select All calls on selection changed with a mouse on windows and linux', (WidgetTester tester) async {
    const String string = 'abc def ghi';
    TextSelection? newSelection;
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: SelectableText(
            string,
            onSelectionChanged: (TextSelection selection, SelectionChangedCause? cause) {
              expect(newSelection, isNull);
              newSelection = selection;
            },
          ),
        ),
      ),
    );

    // Right-click on the 'e' in 'def'.
    final Offset ePos = textOffsetToPosition(tester, 5);
    final TestGesture gesture = await tester.startGesture(
      ePos,
      kind: PointerDeviceKind.mouse,
      buttons: kSecondaryMouseButton,
    );
    addTearDown(gesture.removePointer);
    await tester.pump();
    await gesture.up();
    await tester.pumpAndSettle();
    expect(newSelection!.baseOffset, 4);
    expect(newSelection!.extentOffset, 7);
    newSelection = null;

    await tester.tap(find.text('Select all'));
    await tester.pump();
    expect(newSelection!.baseOffset, 0);
    expect(newSelection!.extentOffset, 11);
  },
    variant: const TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.windows,
      TargetPlatform.linux,
    }),
  );

  testWidgets('Does not show handles when updated from the web engine', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: SelectableText('abc def ghi'),
        ),
      ),
    );

    // Interact with the selectable text to establish the input connection.
    final Offset topLeft = tester.getTopLeft(find.byType(EditableText));
    final TestGesture gesture = await tester.startGesture(
      topLeft + const Offset(0.0, 5.0),
      kind: PointerDeviceKind.mouse,
    );
    addTearDown(gesture.removePointer);
    await tester.pump(const Duration(milliseconds: 50));
    await gesture.up();
    await tester.pumpAndSettle();

    final EditableTextState state = tester.state(find.byType(EditableText));
    expect(state.selectionOverlay!.handlesAreVisible, isFalse);
    expect(
      state.currentTextEditingValue.selection,
      const TextSelection.collapsed(offset: 0),
    );

    if (kIsWeb) {
      tester.testTextInput.updateEditingValue(const TextEditingValue(
        selection: TextSelection(baseOffset: 2, extentOffset: 7),
      ));
      // Wait for all the `setState` calls to be flushed.
      await tester.pumpAndSettle();
      expect(
        state.currentTextEditingValue.selection,
        const TextSelection(baseOffset: 2, extentOffset: 7),
      );
      expect(state.selectionOverlay!.handlesAreVisible, isFalse);
    }
  });

  testWidgets('onSelectionChanged is called when selection changes', (WidgetTester tester) async {
    int onSelectionChangedCallCount = 0;

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: SelectableText(
            'abc def ghi',
            onSelectionChanged: (TextSelection selection, SelectionChangedCause? cause) {
              onSelectionChangedCallCount += 1;
            },
          ),
        ),
      ),
    );

    // Long press to select 'abc'.
    final Offset aLocation = textOffsetToPosition(tester, 1);
    await tester.longPressAt(aLocation);
    await tester.pump();
    expect(onSelectionChangedCallCount, equals(1));
    // Long press to select 'def'.
    await tester.longPressAt(textOffsetToPosition(tester, 5));
    await tester.pump();
    expect(onSelectionChangedCallCount, equals(2));
    // Tap on 'Select all' option to select the whole text.
    await tester.tap(find.text('Select all'));
    expect(onSelectionChangedCallCount, equals(3));
  });

  testWidgets('selecting a space selects the previous word on mobile', (WidgetTester tester) async {
    TextSelection? selection;

    await tester.pumpWidget(
      MaterialApp(
        home: SelectableText(
          ' blah blah',
          onSelectionChanged: (TextSelection newSelection, SelectionChangedCause? cause) {
            selection = newSelection;
          },
        ),
      ),
    );

    expect(selection, isNull);

    // Put the cursor at the end of the field.
    await tester.tapAt(textOffsetToPosition(tester, 10));
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 10);
    expect(selection!.extentOffset, 10);

    // Long press on the second space and the previous word is selected.
    await tester.longPressAt(textOffsetToPosition(tester, 5));
    await tester.pumpAndSettle();
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 1);
    expect(selection!.extentOffset, 5);

    // Put the cursor at the end of the field.
    await tester.tapAt(textOffsetToPosition(tester, 10));
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 10);
    expect(selection!.extentOffset, 10);

    // Long press on the first space and the space is selected because there is
    // no previous word.
    await tester.longPressAt(textOffsetToPosition(tester, 0));
    await tester.pumpAndSettle();
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 0);
    expect(selection!.extentOffset, 1);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.android }));

  testWidgets('selecting a space selects the space on non-mobile platforms', (WidgetTester tester) async {
    TextSelection? selection;

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: SelectableText(
              ' blah blah',
              onSelectionChanged: (TextSelection newSelection, SelectionChangedCause? cause) {
                selection = newSelection;
              },
            ),
          ),
        ),
      ),
    );

    expect(selection, isNull);

    // Put the cursor at the end of the field.
    await tester.tapAt(textOffsetToPosition(tester, 10));
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 10);
    expect(selection!.extentOffset, 10);

    // Double tapping the second space selects it.
    await tester.pump(const Duration(milliseconds: 500));
    await tester.tapAt(textOffsetToPosition(tester, 5));
    await tester.pump(const Duration(milliseconds: 50));
    await tester.tapAt(textOffsetToPosition(tester, 5));
    await tester.pumpAndSettle();
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 5);
    expect(selection!.extentOffset, 6);

    // Put the cursor at the end of the field.
    await tester.tapAt(textOffsetToPosition(tester, 10));
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 10);
    expect(selection!.extentOffset, 10);

    // Double tapping the first space selects it.
    await tester.pump(const Duration(milliseconds: 500));
    await tester.tapAt(textOffsetToPosition(tester, 0));
    await tester.pump(const Duration(milliseconds: 50));
    await tester.tapAt(textOffsetToPosition(tester, 0));
    await tester.pumpAndSettle();
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 0);
    expect(selection!.extentOffset, 1);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS,  TargetPlatform.windows, TargetPlatform.linux, TargetPlatform.fuchsia }));

  testWidgets('double tapping a space selects the previous word on mobile', (WidgetTester tester) async {
    TextSelection? selection;

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: SelectableText(
              ' blah blah  \n  blah',
              onSelectionChanged: (TextSelection newSelection, SelectionChangedCause? cause) {
                selection = newSelection;
              },
            ),
          ),
        ),
      ),
    );

    expect(selection, isNull);

    // Put the cursor at the end of the field.
    await tester.tapAt(textOffsetToPosition(tester, 19));
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 19);
    expect(selection!.extentOffset, 19);

    // Double tapping the second space selects the previous word.
    await tester.pump(const Duration(milliseconds: 500));
    await tester.tapAt(textOffsetToPosition(tester, 5));
    await tester.pump(const Duration(milliseconds: 50));
    await tester.tapAt(textOffsetToPosition(tester, 5));
    await tester.pumpAndSettle();
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 1);
    expect(selection!.extentOffset, 5);

    // Double tapping does the same thing for the first space.
    await tester.pump(const Duration(milliseconds: 500));
    await tester.tapAt(textOffsetToPosition(tester, 0));
    await tester.pump(const Duration(milliseconds: 50));
    await tester.tapAt(textOffsetToPosition(tester, 0));
    await tester.pumpAndSettle();
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 0);
    expect(selection!.extentOffset, 1);

    // Put the cursor at the end of the field.
    await tester.tapAt(textOffsetToPosition(tester, 19));
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 19);
    expect(selection!.extentOffset, 19);

    // Double tapping the last space selects all previous contiguous spaces on
    // both lines and the previous word.
    await tester.pump(const Duration(milliseconds: 500));
    await tester.tapAt(textOffsetToPosition(tester, 14));
    await tester.pump(const Duration(milliseconds: 50));
    await tester.tapAt(textOffsetToPosition(tester, 14));
    await tester.pumpAndSettle();
    expect(selection, isNotNull);
    expect(selection!.baseOffset, 6);
    expect(selection!.extentOffset, 14);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.android }));

  testWidgets('text selection style 1', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: Column(
              children: const <Widget>[
                SelectableText.rich(
                  TextSpan(
                    children: <TextSpan>[
                      TextSpan(
                        text: 'Atwater Peel ',
                        style: TextStyle(
                          fontSize: 30.0,
                        ),
                      ),
                      TextSpan(
                        text: 'Sherbrooke Bonaventure ',
                        style: TextStyle(
                          fontSize: 15.0,
                        ),
                      ),
                      TextSpan(
                        text: 'hi wassup!',
                        style: TextStyle(
                          fontSize: 10.0,
                        ),
                      ),
                    ],
                  ),
                  key: Key('field0'),
                  selectionHeightStyle: ui.BoxHeightStyle.includeLineSpacingTop,
                  selectionWidthStyle: ui.BoxWidthStyle.max,
                ),
              ],
            ),
          ),
        ),
      ),
    );

    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;
    controller.selection = const TextSelection(baseOffset: 0, extentOffset: 46);
    await tester.pump();

    await expectLater(
      find.byType(MaterialApp),
      matchesGoldenFile('selectable_text_golden.TextSelectionStyle.1.png'),
    );
  });

  testWidgets('text selection style 2', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: Column(
              children: const <Widget>[
                SelectableText.rich(
                  TextSpan(
                    children: <TextSpan>[
                      TextSpan(
                        text: 'Atwater Peel ',
                        style: TextStyle(
                          fontSize: 30.0,
                        ),
                      ),
                      TextSpan(
                        text: 'Sherbrooke Bonaventure ',
                        style: TextStyle(
                          fontSize: 15.0,
                        ),
                      ),
                      TextSpan(
                        text: 'hi wassup!',
                        style: TextStyle(
                          fontSize: 10.0,
                        ),
                      ),
                    ],
                  ),
                  key: Key('field0'),
                  selectionHeightStyle: ui.BoxHeightStyle.includeLineSpacingBottom,
                  selectionWidthStyle: ui.BoxWidthStyle.tight,
                ),
              ],
            ),
          ),
        ),
      ),
    );

    final EditableText editableTextWidget = tester.widget(find.byType(EditableText).first);
    final TextEditingController controller = editableTextWidget.controller;
    controller.selection = const TextSelection(baseOffset: 0, extentOffset: 46);
    await tester.pump();

    await expectLater(
      find.byType(MaterialApp),
      matchesGoldenFile('selectable_text_golden.TextSelectionStyle.2.png'),
    );
  });
}
