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

import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle, Paragraph, TextBox;

import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

import 'rendering_tester.dart';

const String _kText =
    "I polished up that handle so carefullee\nThat now I am the Ruler of the Queen's Navee!";

void _applyParentData(List<RenderBox> inlineRenderBoxes, InlineSpan span) {
  var index = 0;
  RenderBox? previousBox;
  span.visitChildren((InlineSpan span) {
    if (span is! WidgetSpan) {
      return true;
    }

    final RenderBox box = inlineRenderBoxes[index];
    box.parentData = TextParentData()
      ..span = span
      ..previousSibling = previousBox;
    (previousBox?.parentData as TextParentData?)?.nextSibling = box;
    index += 1;
    previousBox = box;
    return true;
  });
}

// A subclass of RenderParagraph that returns an empty list in getBoxesForSelection
// for a given TextSelection.
// This is intended to simulate SkParagraph's implementation of Paragraph.getBoxesForRange,
// which may return an empty list in some situations where Libtxt would return a list
// containing an empty box.
class RenderParagraphWithEmptySelectionBoxList extends RenderParagraph {
  RenderParagraphWithEmptySelectionBoxList(
    super.text, {
    required super.textDirection,
    required this.emptyListSelection,
  });

  TextSelection emptyListSelection;

  @override
  List<ui.TextBox> getBoxesForSelection(
    TextSelection selection, {
    ui.BoxHeightStyle boxHeightStyle = ui.BoxHeightStyle.tight,
    ui.BoxWidthStyle boxWidthStyle = ui.BoxWidthStyle.tight,
  }) {
    if (selection == emptyListSelection) {
      return <ui.TextBox>[];
    }
    return super.getBoxesForSelection(
      selection,
      boxHeightStyle: boxHeightStyle,
      boxWidthStyle: boxWidthStyle,
    );
  }
}

// A subclass of RenderParagraph that returns an empty list in getBoxesForSelection
// for a selection representing a WidgetSpan.
// This is intended to simulate how SkParagraph's implementation of Paragraph.getBoxesForRange
// can return an empty list for a WidgetSpan with empty dimensions.
class RenderParagraphWithEmptyBoxListForWidgetSpan extends RenderParagraph {
  RenderParagraphWithEmptyBoxListForWidgetSpan(
    super.text, {
    required List<RenderBox> super.children,
    required super.textDirection,
  });

  @override
  List<ui.TextBox> getBoxesForSelection(
    TextSelection selection, {
    ui.BoxHeightStyle boxHeightStyle = ui.BoxHeightStyle.tight,
    ui.BoxWidthStyle boxWidthStyle = ui.BoxWidthStyle.tight,
  }) {
    if (text.getSpanForPosition(selection.base) is WidgetSpan) {
      return <ui.TextBox>[];
    }
    return super.getBoxesForSelection(
      selection,
      boxHeightStyle: boxHeightStyle,
      boxWidthStyle: boxWidthStyle,
    );
  }
}

void main() {
  TestRenderingFlutterBinding.ensureInitialized();

  test('getOffsetForCaret control test', () {
    final paragraph = RenderParagraph(
      const TextSpan(text: _kText),
      textDirection: TextDirection.ltr,
    );
    layout(paragraph);

    const caret = Rect.fromLTWH(0.0, 0.0, 2.0, 20.0);

    final Offset offset5 = paragraph.getOffsetForCaret(const TextPosition(offset: 5), caret);
    expect(offset5.dx, greaterThan(0.0));

    final Offset offset25 = paragraph.getOffsetForCaret(const TextPosition(offset: 25), caret);
    expect(offset25.dx, greaterThan(offset5.dx));

    final Offset offset50 = paragraph.getOffsetForCaret(const TextPosition(offset: 50), caret);
    expect(offset50.dy, greaterThan(offset5.dy));
  });

  test('getFullHeightForCaret control test', () {
    final paragraph = RenderParagraph(
      const TextSpan(text: _kText, style: TextStyle(fontSize: 10.0)),
      textDirection: TextDirection.ltr,
    );
    layout(paragraph);

    final double height5 = paragraph.getFullHeightForCaret(const TextPosition(offset: 5));
    expect(height5, equals(10.0));
  });

  test('getPositionForOffset control test', () {
    final paragraph = RenderParagraph(
      const TextSpan(text: _kText),
      textDirection: TextDirection.ltr,
    );
    layout(paragraph);

    final TextPosition position20 = paragraph.getPositionForOffset(const Offset(20.0, 5.0));
    expect(position20.offset, greaterThan(0.0));

    final TextPosition position40 = paragraph.getPositionForOffset(const Offset(40.0, 5.0));
    expect(position40.offset, greaterThan(position20.offset));

    final TextPosition positionBelow = paragraph.getPositionForOffset(const Offset(5.0, 20.0));
    expect(positionBelow.offset, greaterThan(position40.offset));
  });

  test('getBoxesForSelection control test', () {
    final paragraph = RenderParagraph(
      const TextSpan(text: _kText, style: TextStyle(fontSize: 10.0)),
      textDirection: TextDirection.ltr,
    );
    layout(paragraph);

    List<ui.TextBox> boxes = paragraph.getBoxesForSelection(
      const TextSelection(baseOffset: 5, extentOffset: 25),
    );

    expect(boxes.length, equals(1));

    boxes = paragraph.getBoxesForSelection(const TextSelection(baseOffset: 25, extentOffset: 50));

    expect(boxes.any((ui.TextBox box) => box.left == 250 && box.top == 0), isTrue);
    expect(boxes.any((ui.TextBox box) => box.right == 100 && box.top == 10), isTrue);
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/61016

  test('getBoxesForSelection test with multiple TextSpans and lines', () {
    final paragraph = RenderParagraph(
      const TextSpan(
        text: 'First ',
        style: TextStyle(fontSize: 10.0),
        children: <InlineSpan>[
          TextSpan(text: 'smallsecond ', style: TextStyle(fontSize: 5.0)),
          TextSpan(text: 'third fourth fifth'),
        ],
      ),
      textDirection: TextDirection.ltr,
    );
    // Do layout with width chosen so that this splits as
    // First smallsecond |
    // third fourth |
    // fifth|
    // The corresponding line widths come out to be:
    // 1st line: 120px wide: 6 chars * 10px plus 12 chars * 5px.
    // 2nd line: 130px wide: 13 chars * 10px.
    // 3rd line: 50px wide.
    layout(paragraph, constraints: const BoxConstraints(maxWidth: 140.0));

    final List<ui.TextBox> boxes = paragraph.getBoxesForSelection(
      const TextSelection(baseOffset: 0, extentOffset: 36),
    );

    expect(boxes.length, equals(4));

    // The widths of the boxes should match the calculations above.
    // The heights should all be 10, except for the box for 'smallsecond ',
    // which should have height 5, and be alphabetic baseline-aligned with
    // 'First '. The test font specifies alphabetic baselines at 0.25em above
    // the bottom extent, and 0.75em below the top, so the difference in top
    // alignment becomes (10px * 0.75 - 5px * 0.75) = 3.75px.

    // 'First ':
    expect(boxes[0], const TextBox.fromLTRBD(0.0, 0.0, 60.0, 10.0, TextDirection.ltr));
    // 'smallsecond ' in size 5:
    expect(boxes[1], const TextBox.fromLTRBD(60.0, 3.75, 120.0, 8.75, TextDirection.ltr));
    // 'third fourth ':
    expect(boxes[2], const TextBox.fromLTRBD(0.0, 10.0, 130.0, 20.0, TextDirection.ltr));
    // 'fifth':
    expect(boxes[3], const TextBox.fromLTRBD(0.0, 20.0, 50.0, 30.0, TextDirection.ltr));
  });

  test('getBoxesForSelection test with boxHeightStyle and boxWidthStyle set to max', () {
    final paragraph = RenderParagraph(
      const TextSpan(
        text: 'First ',
        style: TextStyle(fontFamily: 'FlutterTest', fontSize: 10.0),
        children: <InlineSpan>[
          TextSpan(text: 'smallsecond ', style: TextStyle(fontSize: 8.0)),
          TextSpan(text: 'third fourth fifth'),
        ],
      ),
      textDirection: TextDirection.ltr,
    );
    // Do layout with width chosen so that this splits as
    // First smallsecond |
    // third fourth |
    // fifth|
    // The corresponding line widths come out to be:
    // 1st line: 156px wide: 6 chars * 10px plus 12 chars * 8px.
    // 2nd line: 130px wide: 13 chars * 10px.
    // 3rd line: 50px wide.
    layout(paragraph, constraints: const BoxConstraints(maxWidth: 160.0));

    final List<ui.TextBox> boxes = paragraph.getBoxesForSelection(
      const TextSelection(baseOffset: 0, extentOffset: 36),
      boxHeightStyle: ui.BoxHeightStyle.max,
      boxWidthStyle: ui.BoxWidthStyle.max,
    );

    expect(boxes.length, equals(5));

    // 'First ':
    expect(boxes[0], const TextBox.fromLTRBD(0.0, 0.0, 60.0, 10.0, TextDirection.ltr));
    // 'smallsecond ' in size 8, but on same line as previous box, so height remains 10:
    expect(boxes[1], const TextBox.fromLTRBD(60.0, 0.0, 156.0, 10.0, TextDirection.ltr));
    // 'third fourth ':
    expect(boxes[2], const TextBox.fromLTRBD(0.0, 10.0, 130.0, 20.0, TextDirection.ltr));
    // extra box added to extend width, as per definition of ui.BoxWidthStyle.max:
    expect(boxes[3], const TextBox.fromLTRBD(130.0, 10.0, 156.0, 20.0, TextDirection.ltr));
    // 'fifth':
    expect(boxes[4], const TextBox.fromLTRBD(0.0, 20.0, 50.0, 30.0, TextDirection.ltr));
  });

  test('getWordBoundary control test', () {
    final paragraph = RenderParagraph(
      const TextSpan(text: _kText),
      textDirection: TextDirection.ltr,
    );
    layout(paragraph);

    final TextRange range5 = paragraph.getWordBoundary(const TextPosition(offset: 5));
    expect(range5.textInside(_kText), equals('polished'));

    final TextRange range50 = paragraph.getWordBoundary(const TextPosition(offset: 50));
    expect(range50.textInside(_kText), equals(' '));

    final TextRange range85 = paragraph.getWordBoundary(const TextPosition(offset: 75));
    expect(range85.textInside(_kText), equals("Queen's"));
  });

  test('overflow test', () {
    final paragraph = RenderParagraph(
      const TextSpan(
        text:
            'This\n' // 4 characters * 10px font size = 40px width on the first line
            'is a wrapping test. It should wrap at manual newlines, and if softWrap is true, also at spaces.',
        style: TextStyle(fontSize: 10.0),
      ),
      textDirection: TextDirection.ltr,
      maxLines: 1,
    );

    void relayoutWith({int? maxLines, required bool softWrap, required TextOverflow overflow}) {
      paragraph
        ..maxLines = maxLines
        ..softWrap = softWrap
        ..overflow = overflow;
      pumpFrame();
    }

    // Lay out in a narrow box to force wrapping.
    layout(
      paragraph,
      constraints: const BoxConstraints(maxWidth: 50.0),
    ); // enough to fit "This" but not "This is"
    final double lineHeight = paragraph.size.height;

    relayoutWith(maxLines: 3, softWrap: true, overflow: TextOverflow.clip);
    expect(paragraph.size.height, equals(3 * lineHeight));

    relayoutWith(softWrap: true, overflow: TextOverflow.clip);
    expect(paragraph.size.height, greaterThan(5 * lineHeight));

    // Try again with ellipsis overflow. We can't test that the ellipsis are
    // drawn, but we can test the sizing.
    relayoutWith(maxLines: 1, softWrap: true, overflow: TextOverflow.ellipsis);
    expect(paragraph.size.height, equals(lineHeight));

    relayoutWith(maxLines: 3, softWrap: true, overflow: TextOverflow.ellipsis);
    expect(paragraph.size.height, equals(3 * lineHeight));

    // This is the one weird case. If maxLines is null, we would expect to allow
    // infinite wrapping. However, if we did, we'd never know when to append an
    // ellipsis, so this really means "append ellipsis as soon as we exceed the
    // width".
    relayoutWith(softWrap: true, overflow: TextOverflow.ellipsis);
    expect(paragraph.size.height, equals(2 * lineHeight));

    // Now with no soft wrapping.
    relayoutWith(maxLines: 1, softWrap: false, overflow: TextOverflow.clip);
    expect(paragraph.size.height, equals(lineHeight));

    relayoutWith(maxLines: 3, softWrap: false, overflow: TextOverflow.clip);
    expect(paragraph.size.height, equals(2 * lineHeight));

    relayoutWith(softWrap: false, overflow: TextOverflow.clip);
    expect(paragraph.size.height, equals(2 * lineHeight));

    relayoutWith(maxLines: 1, softWrap: false, overflow: TextOverflow.ellipsis);
    expect(paragraph.size.height, equals(lineHeight));

    relayoutWith(maxLines: 3, softWrap: false, overflow: TextOverflow.ellipsis);
    expect(paragraph.size.height, equals(3 * lineHeight));

    relayoutWith(softWrap: false, overflow: TextOverflow.ellipsis);
    expect(paragraph.size.height, equals(2 * lineHeight));

    // Test presence of the fade effect.
    relayoutWith(maxLines: 3, softWrap: true, overflow: TextOverflow.fade);
    expect(paragraph.debugHasOverflowShader, isTrue);

    // Change back to ellipsis and check that the fade shader is cleared.
    relayoutWith(maxLines: 3, softWrap: true, overflow: TextOverflow.ellipsis);
    expect(paragraph.debugHasOverflowShader, isFalse);

    relayoutWith(maxLines: 100, softWrap: true, overflow: TextOverflow.fade);
    expect(paragraph.debugHasOverflowShader, isFalse);
  });

  test('maxLines', () {
    final paragraph = RenderParagraph(
      const TextSpan(
        text:
            "How do you write like you're running out of time? Write day and night like you're running out of time?",
        // 0123456789 0123456789 012 345 0123456 012345 01234 012345678 012345678 0123 012 345 0123456 012345 01234
        // 0          1          2       3       4      5     6         7         8    9       10      11     12
        style: TextStyle(fontSize: 10.0),
      ),
      textDirection: TextDirection.ltr,
    );
    layout(paragraph, constraints: const BoxConstraints(maxWidth: 100.0));
    void layoutAt(int? maxLines) {
      paragraph.maxLines = maxLines;
      pumpFrame();
    }

    layoutAt(null);
    expect(paragraph.size.height, 130.0);

    layoutAt(1);
    expect(paragraph.size.height, 10.0);

    layoutAt(2);
    expect(paragraph.size.height, 20.0);

    layoutAt(3);
    expect(paragraph.size.height, 30.0);
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/61018

  test('textAlign triggers TextPainter relayout in the paint method', () {
    final paragraph = RenderParagraph(
      const TextSpan(text: 'A', style: TextStyle(fontSize: 10.0)),
      textDirection: TextDirection.ltr,
      textAlign: TextAlign.left,
    );

    Rect getRectForA() => paragraph
        .getBoxesForSelection(const TextSelection(baseOffset: 0, extentOffset: 1))
        .single
        .toRect();

    layout(paragraph, constraints: const BoxConstraints.tightFor(width: 100.0));

    expect(getRectForA(), const Rect.fromLTWH(0, 0, 10, 10));

    paragraph.textAlign = TextAlign.right;
    expect(paragraph.debugNeedsLayout, isFalse);
    expect(paragraph.debugNeedsPaint, isTrue);

    paragraph.paint(MockPaintingContext(), Offset.zero);
    expect(getRectForA(), const Rect.fromLTWH(90, 0, 10, 10));
  });

  group('didExceedMaxLines', () {
    RenderParagraph createRenderParagraph({
      int? maxLines,
      TextOverflow overflow = TextOverflow.clip,
    }) {
      return RenderParagraph(
        const TextSpan(
          text: 'Here is a long text, maybe exceed maxlines',
          style: TextStyle(fontSize: 10.0),
        ),
        textDirection: TextDirection.ltr,
        overflow: overflow,
        maxLines: maxLines,
      );
    }

    test('none limited', () {
      final RenderParagraph paragraph = createRenderParagraph();
      layout(paragraph, constraints: const BoxConstraints(maxWidth: 100.0));
      expect(paragraph.didExceedMaxLines, false);
    });

    test('limited by maxLines', () {
      final RenderParagraph paragraph = createRenderParagraph(maxLines: 1);
      layout(paragraph, constraints: const BoxConstraints(maxWidth: 100.0));
      expect(paragraph.didExceedMaxLines, true);
    });

    test('limited by ellipsis', () {
      final RenderParagraph paragraph = createRenderParagraph(overflow: TextOverflow.ellipsis);
      layout(paragraph, constraints: const BoxConstraints(maxWidth: 100.0));
      expect(paragraph.didExceedMaxLines, true);
    });
  });

  test('changing color does not do layout', () {
    final paragraph = RenderParagraph(
      const TextSpan(
        text: 'Hello',
        style: TextStyle(color: Color(0xFF000000)),
      ),
      textDirection: TextDirection.ltr,
    );
    layout(paragraph, constraints: const BoxConstraints(maxWidth: 100.0), phase: EnginePhase.paint);
    expect(paragraph.debugNeedsLayout, isFalse);
    expect(paragraph.debugNeedsPaint, isFalse);
    paragraph.text = const TextSpan(
      text: 'Hello World',
      style: TextStyle(color: Color(0xFF000000)),
    );
    expect(paragraph.debugNeedsLayout, isTrue);
    expect(paragraph.debugNeedsPaint, isFalse);
    pumpFrame(phase: EnginePhase.paint);
    expect(paragraph.debugNeedsLayout, isFalse);
    expect(paragraph.debugNeedsPaint, isFalse);
    paragraph.text = const TextSpan(
      text: 'Hello World',
      style: TextStyle(color: Color(0xFFFFFFFF)),
    );
    expect(paragraph.debugNeedsLayout, isFalse);
    expect(paragraph.debugNeedsPaint, isTrue);
    pumpFrame(phase: EnginePhase.paint);
    expect(paragraph.debugNeedsLayout, isFalse);
    expect(paragraph.debugNeedsPaint, isFalse);
  });

  test('nested TextSpans in paragraph handle linear textScaler correctly.', () {
    const testSpan = TextSpan(
      text: 'a',
      style: TextStyle(fontSize: 10.0),
      children: <TextSpan>[
        TextSpan(
          text: 'b',
          children: <TextSpan>[TextSpan(text: 'c')],
          style: TextStyle(fontSize: 20.0),
        ),
        TextSpan(text: 'd'),
      ],
    );
    final paragraph = RenderParagraph(
      testSpan,
      textDirection: TextDirection.ltr,
      textScaler: const TextScaler.linear(1.3),
    );
    paragraph.layout(const BoxConstraints());
    expect(paragraph.size.width, 78.0);
    expect(paragraph.size.height, 26.0);

    final int length = testSpan.toPlainText().length;
    // Test the sizes of nested spans.
    final boxes = <ui.TextBox>[
      for (int i = 0; i < length; ++i)
        ...paragraph.getBoxesForSelection(TextSelection(baseOffset: i, extentOffset: i + 1)),
    ];
    expect(boxes, hasLength(4));

    expect(boxes[0].toRect().width, 13.0);
    expect(boxes[0].toRect().height, 13.0);
    expect(boxes[1].toRect().width, 26.0);
    expect(boxes[1].toRect().height, 26.0);
    expect(boxes[2].toRect().width, 26.0);
    expect(boxes[2].toRect().height, 26.0);
    expect(boxes[3].toRect().width, 13.0);
    expect(boxes[3].toRect().height, 13.0);
  });

  test('toStringDeep', () {
    final paragraph = RenderParagraph(
      const TextSpan(text: _kText),
      textDirection: TextDirection.ltr,
      locale: const Locale('ja', 'JP'),
    );
    expect(paragraph, hasAGoodToStringDeep);
    expect(
      paragraph.toStringDeep(minLevel: DiagnosticLevel.info),
      equalsIgnoringHashCodes(
        'RenderParagraph#00000 NEEDS-LAYOUT NEEDS-PAINT DETACHED\n'
        ' │ parentData: MISSING\n'
        ' │ constraints: MISSING\n'
        ' │ size: MISSING\n'
        ' │ textAlign: start\n'
        ' │ textDirection: ltr\n'
        ' │ softWrap: wrapping at box width\n'
        ' │ overflow: clip\n'
        ' │ locale: ja_JP\n'
        ' │ maxLines: unlimited\n'
        ' ╘═╦══ text ═══\n'
        '   ║ TextSpan:\n'
        '   ║   "I polished up that handle so carefullee\n'
        '   ║   That now I am the Ruler of the Queen\'s Navee!"\n'
        '   ╚═══════════\n',
      ),
    );
  });

  test('locale setter', () {
    // Regression test for https://github.com/flutter/flutter/issues/18175

    final paragraph = RenderParagraph(
      const TextSpan(text: _kText),
      locale: const Locale('zh', 'HK'),
      textDirection: TextDirection.ltr,
    );
    expect(paragraph.locale, const Locale('zh', 'HK'));

    paragraph.locale = const Locale('ja', 'JP');
    expect(paragraph.locale, const Locale('ja', 'JP'));
  });

  test('inline widgets test', () {
    const text = TextSpan(
      text: 'a',
      style: TextStyle(fontSize: 10.0),
      children: <InlineSpan>[
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
        TextSpan(text: 'a'),
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
      ],
    );
    // Fake the render boxes that correspond to the WidgetSpans. We use
    // RenderParagraph to reduce dependencies this test has.
    final renderBoxes = <RenderBox>[
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
    ];

    final paragraph = RenderParagraph(
      text,
      textDirection: TextDirection.ltr,
      children: renderBoxes,
    );
    _applyParentData(renderBoxes, text);
    layout(paragraph, constraints: const BoxConstraints(maxWidth: 100.0));

    final List<ui.TextBox> boxes = paragraph.getBoxesForSelection(
      const TextSelection(baseOffset: 0, extentOffset: 8),
    );

    expect(boxes.length, equals(5));
    expect(boxes[0], const TextBox.fromLTRBD(0.0, 4.0, 10.0, 14.0, TextDirection.ltr));
    expect(boxes[1], const TextBox.fromLTRBD(10.0, 0.0, 24.0, 14.0, TextDirection.ltr));
    expect(boxes[2], const TextBox.fromLTRBD(24.0, 0.0, 38.0, 14.0, TextDirection.ltr));
    expect(boxes[3], const TextBox.fromLTRBD(38.0, 4.0, 48.0, 14.0, TextDirection.ltr));
    expect(boxes[4], const TextBox.fromLTRBD(48.0, 0.0, 62.0, 14.0, TextDirection.ltr));
  });

  test('getBoxesForSelection with boxHeightStyle for inline widgets', () {
    const text = TextSpan(
      text: 'a',
      style: TextStyle(fontSize: 10.0),
      children: <InlineSpan>[
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
        TextSpan(text: 'a'),
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
      ],
    );
    // Fake the render boxes that correspond to the WidgetSpans. We use
    // RenderParagraph to reduce the dependencies this test has. The dimensions
    // of these get used in place of the widths and heights specified in the
    // SizedBoxes above: each comes out as (w,h) = (14,14).
    final renderBoxes = <RenderBox>[
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
    ];

    final paragraph = RenderParagraph(
      text,
      textDirection: TextDirection.ltr,
      children: renderBoxes,
    );
    _applyParentData(renderBoxes, text);
    layout(paragraph, constraints: const BoxConstraints(maxWidth: 100.0));

    final List<ui.TextBox> boxes = paragraph.getBoxesForSelection(
      const TextSelection(baseOffset: 0, extentOffset: 8),
      boxHeightStyle: ui.BoxHeightStyle.max,
    );

    expect(boxes.length, equals(5));
    expect(boxes[0], const TextBox.fromLTRBD(0.0, 0.0, 10.0, 14.0, TextDirection.ltr));
    expect(boxes[1], const TextBox.fromLTRBD(10.0, 0.0, 24.0, 14.0, TextDirection.ltr));
    expect(boxes[2], const TextBox.fromLTRBD(24.0, 0.0, 38.0, 14.0, TextDirection.ltr));
    expect(boxes[3], const TextBox.fromLTRBD(38.0, 0.0, 48.0, 14.0, TextDirection.ltr));
    expect(boxes[4], const TextBox.fromLTRBD(48.0, 0.0, 62.0, 14.0, TextDirection.ltr));
  });

  test('inline widgets multiline test', () {
    const text = TextSpan(
      text: 'a',
      style: TextStyle(fontSize: 10.0),
      children: <InlineSpan>[
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
        TextSpan(text: 'a'),
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
        WidgetSpan(child: SizedBox(width: 21, height: 21)),
      ],
    );
    // Fake the render boxes that correspond to the WidgetSpans. We use
    // RenderParagraph to reduce dependencies this test has.
    final renderBoxes = <RenderBox>[
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
    ];

    final paragraph = RenderParagraph(
      text,
      textDirection: TextDirection.ltr,
      children: renderBoxes,
    );
    _applyParentData(renderBoxes, text);
    layout(paragraph, constraints: const BoxConstraints(maxWidth: 50.0));

    final List<ui.TextBox> boxes = paragraph.getBoxesForSelection(
      const TextSelection(baseOffset: 0, extentOffset: 12),
    );

    expect(boxes.length, equals(9));
    expect(boxes[0], const TextBox.fromLTRBD(0.0, 4.0, 10.0, 14.0, TextDirection.ltr));
    expect(boxes[1], const TextBox.fromLTRBD(10.0, 0.0, 24.0, 14.0, TextDirection.ltr));
    expect(boxes[2], const TextBox.fromLTRBD(24.0, 0.0, 38.0, 14.0, TextDirection.ltr));
    expect(boxes[3], const TextBox.fromLTRBD(38.0, 4.0, 48.0, 14.0, TextDirection.ltr));
    // Wraps
    expect(boxes[4], const TextBox.fromLTRBD(0.0, 14.0, 14.0, 28.0, TextDirection.ltr));
    expect(boxes[5], const TextBox.fromLTRBD(14.0, 14.0, 28.0, 28.0, TextDirection.ltr));
    expect(boxes[6], const TextBox.fromLTRBD(28.0, 14.0, 42.0, 28.0, TextDirection.ltr));
    // Wraps
    expect(boxes[7], const TextBox.fromLTRBD(0.0, 28.0, 14.0, 42.0, TextDirection.ltr));
    expect(boxes[8], const TextBox.fromLTRBD(14.0, 28.0, 28.0, 42.0, TextDirection.ltr));
  });

  test('Does not include the semantics node of truncated rendering children', () {
    // Regression test for https://github.com/flutter/flutter/issues/88180
    const double screenWidth = 100;
    const sentence = 'truncated';
    final renderBoxes = <RenderBox>[
      RenderParagraph(const TextSpan(text: sentence), textDirection: TextDirection.ltr),
    ];
    final paragraph = RenderParagraph(
      const TextSpan(
        text: 'a long line to be truncated.',
        children: <InlineSpan>[WidgetSpan(child: Text(sentence))],
      ),
      overflow: TextOverflow.ellipsis,
      children: renderBoxes,
      textDirection: TextDirection.ltr,
    );
    _applyParentData(renderBoxes, paragraph.text);
    layout(paragraph, constraints: const BoxConstraints(maxWidth: screenWidth));
    final result = SemanticsNode();
    final truncatedChild = SemanticsNode();
    truncatedChild.tags = <SemanticsTag>{const PlaceholderSpanIndexSemanticsTag(0)};
    paragraph.assembleSemanticsNode(result, SemanticsConfiguration(), <SemanticsNode>[
      truncatedChild,
    ]);
    // It should only contain the semantics node of the TextSpan.
    expect(result.childrenCount, 1);
    result.visitChildren((SemanticsNode node) {
      expect(node != truncatedChild, isTrue);
      return true;
    });
  });

  test('Supports gesture recognizer semantics', () {
    final paragraph = RenderParagraph(
      TextSpan(
        text: _kText,
        children: <InlineSpan>[
          TextSpan(text: 'one', recognizer: TapGestureRecognizer()..onTap = () {}),
          TextSpan(text: 'two', recognizer: LongPressGestureRecognizer()..onLongPress = () {}),
          TextSpan(text: 'three', recognizer: DoubleTapGestureRecognizer()..onDoubleTap = () {}),
        ],
      ),
      textDirection: TextDirection.rtl,
    );
    layout(paragraph);

    final node = SemanticsNode();
    paragraph.assembleSemanticsNode(node, SemanticsConfiguration(), <SemanticsNode>[]);
    final children = <SemanticsNode>[];
    node.visitChildren((SemanticsNode child) {
      children.add(child);
      return true;
    });
    expect(children.length, 4);
    expect(children[0].getSemanticsData().actions, 0);
    expect(children[1].getSemanticsData().hasAction(SemanticsAction.tap), true);
    expect(children[2].getSemanticsData().hasAction(SemanticsAction.longPress), true);
    expect(children[3].getSemanticsData().hasAction(SemanticsAction.tap), true);
  });

  test('Supports empty text span with spell out', () {
    final paragraph = RenderParagraph(
      const TextSpan(text: '', spellOut: true),
      textDirection: TextDirection.rtl,
    );
    layout(paragraph);
    final node = SemanticsNode();
    paragraph.assembleSemanticsNode(node, SemanticsConfiguration(), <SemanticsNode>[]);
    expect(node.attributedLabel.string, '');
    expect(node.attributedLabel.attributes.length, 0);
  });

  test('Asserts on unsupported gesture recognizer', () {
    final paragraph = RenderParagraph(
      TextSpan(
        text: _kText,
        children: <InlineSpan>[
          TextSpan(text: 'three', recognizer: MultiTapGestureRecognizer()..onTap = (int id) {}),
        ],
      ),
      textDirection: TextDirection.rtl,
    );
    layout(paragraph);

    var failed = false;
    try {
      paragraph.assembleSemanticsNode(SemanticsNode(), SemanticsConfiguration(), <SemanticsNode>[]);
    } on AssertionError catch (e) {
      failed = true;
      expect(e.message, 'MultiTapGestureRecognizer is not supported.');
    }
    expect(failed, true);
  });

  test('assembleSemanticsNode handles text spans that do not yield selection boxes', () {
    final RenderParagraph paragraph = RenderParagraphWithEmptySelectionBoxList(
      TextSpan(
        text: '',
        children: <InlineSpan>[
          TextSpan(text: 'A', recognizer: TapGestureRecognizer()..onTap = () {}),
          TextSpan(text: 'B', recognizer: TapGestureRecognizer()..onTap = () {}),
          TextSpan(text: 'C', recognizer: TapGestureRecognizer()..onTap = () {}),
        ],
      ),
      textDirection: TextDirection.rtl,
      emptyListSelection: const TextSelection(baseOffset: 0, extentOffset: 1),
    );
    layout(paragraph);

    final node = SemanticsNode();
    paragraph.assembleSemanticsNode(node, SemanticsConfiguration(), <SemanticsNode>[]);
    expect(node.childrenCount, 2);
  });

  test('assembleSemanticsNode handles empty WidgetSpans that do not yield selection boxes', () {
    final text = TextSpan(
      text: '',
      children: <InlineSpan>[
        TextSpan(text: 'A', recognizer: TapGestureRecognizer()..onTap = () {}),
        const WidgetSpan(child: SizedBox.shrink()),
        TextSpan(text: 'C', recognizer: TapGestureRecognizer()..onTap = () {}),
      ],
    );
    final renderBoxes = <RenderBox>[
      RenderParagraph(const TextSpan(text: 'b'), textDirection: TextDirection.ltr),
    ];
    final RenderParagraph paragraph = RenderParagraphWithEmptyBoxListForWidgetSpan(
      text,
      children: renderBoxes,
      textDirection: TextDirection.ltr,
    );
    _applyParentData(renderBoxes, paragraph.text);
    layout(paragraph);

    final node = SemanticsNode();
    paragraph.assembleSemanticsNode(node, SemanticsConfiguration(), <SemanticsNode>[]);
    expect(node.childrenCount, 2);
  });

  test('Basic TextSpan Hit testing', () {
    final textSpanA = TextSpan(text: 'A' * 10);
    const textSpanBC = TextSpan(text: 'BC', style: TextStyle(letterSpacing: 26.0));

    final text = TextSpan(
      style: const TextStyle(fontSize: 10.0),
      children: <InlineSpan>[textSpanA, textSpanBC],
    );

    final paragraph = RenderParagraph(text, textDirection: TextDirection.ltr);
    layout(paragraph, constraints: const BoxConstraints.tightFor(width: 100.0));

    BoxHitTestResult result;

    // Hit-testing the first line
    // First A
    expect(
      paragraph.hitTest(result = BoxHitTestResult(), position: const Offset(5.0, 5.0)),
      isTrue,
    );
    expect(
      result.path.map((HitTestEntry<HitTestTarget> entry) => entry.target).whereType<TextSpan>(),
      <TextSpan>[textSpanA],
    );
    // The last A.
    expect(
      paragraph.hitTest(result = BoxHitTestResult(), position: const Offset(95.0, 5.0)),
      isTrue,
    );
    expect(
      result.path.map((HitTestEntry<HitTestTarget> entry) => entry.target).whereType<TextSpan>(),
      <TextSpan>[textSpanA],
    );
    // Far away from the line.
    expect(
      paragraph.hitTest(result = BoxHitTestResult(), position: const Offset(200.0, 5.0)),
      isFalse,
    );
    expect(
      result.path.map((HitTestEntry<HitTestTarget> entry) => entry.target).whereType<TextSpan>(),
      <TextSpan>[],
    );

    // Hit-testing the second line
    // Tapping on B (startX = letter-spacing / 2 = 13.0).
    expect(
      paragraph.hitTest(result = BoxHitTestResult(), position: const Offset(18.0, 15.0)),
      isTrue,
    );
    expect(
      result.path.map((HitTestEntry<HitTestTarget> entry) => entry.target).whereType<TextSpan>(),
      <TextSpan>[textSpanBC],
    );

    // Between B and C, with large letter-spacing.
    expect(
      paragraph.hitTest(result = BoxHitTestResult(), position: const Offset(31.0, 15.0)),
      isTrue,
    );
    expect(
      result.path.map((HitTestEntry<HitTestTarget> entry) => entry.target).whereType<TextSpan>(),
      <TextSpan>[textSpanBC],
    );

    // On C.
    expect(
      paragraph.hitTest(result = BoxHitTestResult(), position: const Offset(54.0, 15.0)),
      isTrue,
    );
    expect(
      result.path.map((HitTestEntry<HitTestTarget> entry) => entry.target).whereType<TextSpan>(),
      <TextSpan>[textSpanBC],
    );

    // After C.
    expect(
      paragraph.hitTest(result = BoxHitTestResult(), position: const Offset(100.0, 15.0)),
      isFalse,
    );
    expect(
      result.path.map((HitTestEntry<HitTestTarget> entry) => entry.target).whereType<TextSpan>(),
      <TextSpan>[],
    );

    // Not even remotely close.
    expect(
      paragraph.hitTest(result = BoxHitTestResult(), position: const Offset(9999.0, 9999.0)),
      isFalse,
    );
    expect(
      result.path.map((HitTestEntry<HitTestTarget> entry) => entry.target).whereType<TextSpan>(),
      <TextSpan>[],
    );
  });

  test('TextSpan Hit testing with text justification', () {
    const textSpanA = TextSpan(text: 'A '); // The space is a word break.
    const textSpanB = TextSpan(text: 'B\u200B'); // The zero-width space is used as a line break.
    final textSpanC = TextSpan(
      text: 'C' * 10,
    ); // The third span starts a new line since it's too long for the first line.

    // The text should look like:
    // A        B
    // CCCCCCCCCC
    final text = TextSpan(
      text: '',
      style: const TextStyle(fontSize: 10.0),
      children: <InlineSpan>[textSpanA, textSpanB, textSpanC],
    );

    final paragraph = RenderParagraph(
      text,
      textDirection: TextDirection.ltr,
      textAlign: TextAlign.justify,
    );
    layout(paragraph, constraints: const BoxConstraints.tightFor(width: 100.0));
    BoxHitTestResult result;

    // Tapping on A.
    expect(
      paragraph.hitTest(result = BoxHitTestResult(), position: const Offset(5.0, 5.0)),
      isTrue,
    );
    expect(
      result.path.map((HitTestEntry<HitTestTarget> entry) => entry.target).whereType<TextSpan>(),
      <TextSpan>[textSpanA],
    );

    // Between A and B.
    expect(
      paragraph.hitTest(result = BoxHitTestResult(), position: const Offset(50.0, 5.0)),
      isTrue,
    );
    expect(
      result.path.map((HitTestEntry<HitTestTarget> entry) => entry.target).whereType<TextSpan>(),
      <TextSpan>[textSpanA],
    );

    // On B.
    expect(
      paragraph.hitTest(result = BoxHitTestResult(), position: const Offset(95.0, 5.0)),
      isTrue,
    );
    expect(
      result.path.map((HitTestEntry<HitTestTarget> entry) => entry.target).whereType<TextSpan>(),
      <TextSpan>[textSpanB],
    );
  });

  group('Selection', () {
    void selectionParagraph(RenderParagraph paragraph, TextPosition start, TextPosition end) {
      for (final Selectable selectable
          in (paragraph.registrar! as TestSelectionRegistrar).selectables) {
        selectable.dispatchSelectionEvent(
          SelectionEdgeUpdateEvent.forStart(
            globalPosition: paragraph.getOffsetForCaret(start, Rect.zero) + const Offset(0, 5),
          ),
        );
        selectable.dispatchSelectionEvent(
          SelectionEdgeUpdateEvent.forEnd(
            globalPosition: paragraph.getOffsetForCaret(end, Rect.zero) + const Offset(0, 5),
          ),
        );
      }
    }

    test('subscribe to SelectionRegistrar', () {
      final registrar = TestSelectionRegistrar();
      final paragraph = RenderParagraph(
        const TextSpan(text: '1234567'),
        textDirection: TextDirection.ltr,
        registrar: registrar,
      );
      expect(registrar.selectables.length, 1);

      paragraph.text = const TextSpan(text: '');
      expect(registrar.selectables.length, 0);
    });

    test('paints selection highlight', () async {
      final registrar = TestSelectionRegistrar();
      const selectionColor = Color(0xAF6694e8);
      final paragraph = RenderParagraph(
        const TextSpan(text: '1234567'),
        textDirection: TextDirection.ltr,
        registrar: registrar,
        selectionColor: selectionColor,
      );
      layout(paragraph);
      final paintingContext = MockPaintingContext();
      paragraph.paint(paintingContext, Offset.zero);
      expect(paintingContext.canvas.drawnRect, isNull);
      expect(paintingContext.canvas.drawnRectPaint, isNull);
      selectionParagraph(paragraph, const TextPosition(offset: 1), const TextPosition(offset: 5));

      paintingContext.canvas.clear();
      paragraph.paint(paintingContext, Offset.zero);
      expect(paintingContext.canvas.drawnRect, const Rect.fromLTWH(14.0, 0.0, 56.0, 14.0));
      expect(paintingContext.canvas.drawnRectPaint!.style, PaintingStyle.fill);
      expect(paintingContext.canvas.drawnRectPaint!.color, isSameColorAs(selectionColor));
      // Selection highlight is painted before text.
      expect(paintingContext.canvas.drawnItemTypes, <Type>[Rect, ui.Paragraph]);

      selectionParagraph(paragraph, const TextPosition(offset: 2), const TextPosition(offset: 4));
      paragraph.paint(paintingContext, Offset.zero);
      expect(paintingContext.canvas.drawnRect, const Rect.fromLTWH(28.0, 0.0, 28.0, 14.0));
      expect(paintingContext.canvas.drawnRectPaint!.style, PaintingStyle.fill);
      expect(paintingContext.canvas.drawnRectPaint!.color, isSameColorAs(selectionColor));
    });

    // Regression test for https://github.com/flutter/flutter/issues/126652.
    test('paints selection when tap at chinese character', () async {
      final registrar = TestSelectionRegistrar();
      const selectionColor = Color(0xAF6694e8);
      final paragraph = RenderParagraph(
        const TextSpan(text: '你好'),
        textDirection: TextDirection.ltr,
        registrar: registrar,
        selectionColor: selectionColor,
      );
      layout(paragraph);
      final paintingContext = MockPaintingContext();
      paragraph.paint(paintingContext, Offset.zero);
      expect(paintingContext.canvas.drawnRect, isNull);
      expect(paintingContext.canvas.drawnRectPaint, isNull);

      for (final Selectable selectable
          in (paragraph.registrar! as TestSelectionRegistrar).selectables) {
        selectable.dispatchSelectionEvent(
          const SelectWordSelectionEvent(globalPosition: Offset(7, 0)),
        );
      }

      paintingContext.canvas.clear();
      paragraph.paint(paintingContext, Offset.zero);
      expect(paintingContext.canvas.drawnRect!.isEmpty, false);
      expect(paintingContext.canvas.drawnRectPaint!.style, PaintingStyle.fill);
      expect(paintingContext.canvas.drawnRectPaint!.color, isSameColorAs(selectionColor));
    });

    test('getPositionForOffset works', () async {
      final paragraph = RenderParagraph(
        const TextSpan(text: '1234567'),
        textDirection: TextDirection.ltr,
      );
      layout(paragraph);
      expect(
        paragraph.getPositionForOffset(const Offset(42.0, 14.0)),
        const TextPosition(offset: 3),
      );
    });

    test('can handle select all when contains widget span', () async {
      final registrar = TestSelectionRegistrar();
      final renderBoxes = <RenderBox>[
        RenderParagraph(const TextSpan(text: 'widget'), textDirection: TextDirection.ltr),
      ];
      final paragraph = RenderParagraph(
        const TextSpan(
          children: <InlineSpan>[
            TextSpan(text: 'before the span'),
            WidgetSpan(child: Text('widget')),
            TextSpan(text: 'after the span'),
          ],
        ),
        textDirection: TextDirection.ltr,
        registrar: registrar,
        children: renderBoxes,
      );
      _applyParentData(renderBoxes, paragraph.text);
      layout(paragraph);
      // The widget span will register to the selection container without going
      // through the render paragraph.
      expect(registrar.selectables.length, 2);
      final Selectable segment1 = registrar.selectables[0];
      segment1.dispatchSelectionEvent(const SelectAllSelectionEvent());
      final SelectionGeometry geometry1 = segment1.value;
      expect(geometry1.hasContent, true);
      expect(geometry1.status, SelectionStatus.uncollapsed);

      final Selectable segment2 = registrar.selectables[1];
      segment2.dispatchSelectionEvent(const SelectAllSelectionEvent());
      final SelectionGeometry geometry2 = segment2.value;
      expect(geometry2.hasContent, true);
      expect(geometry2.status, SelectionStatus.uncollapsed);
    });

    test('can granularly extend selection - character', () async {
      final registrar = TestSelectionRegistrar();
      final renderBoxes = <RenderBox>[];
      final paragraph = RenderParagraph(
        const TextSpan(children: <InlineSpan>[TextSpan(text: 'how are you\nI am fine\nThank you')]),
        textDirection: TextDirection.ltr,
        registrar: registrar,
        children: renderBoxes,
      );
      layout(paragraph);

      expect(registrar.selectables.length, 1);
      selectionParagraph(paragraph, const TextPosition(offset: 4), const TextPosition(offset: 5));
      expect(paragraph.selections.length, 1);
      TextSelection selection = paragraph.selections[0];
      expect(selection.start, 4); // how [a]re you
      expect(selection.end, 5);

      // Equivalent to sending shift + arrow-right
      registrar.selectables[0].dispatchSelectionEvent(
        const GranularlyExtendSelectionEvent(
          forward: true,
          isEnd: true,
          granularity: TextGranularity.character,
        ),
      );
      selection = paragraph.selections[0];
      expect(selection.start, 4); // how [ar]e you
      expect(selection.end, 6);

      // Equivalent to sending shift + arrow-left
      registrar.selectables[0].dispatchSelectionEvent(
        const GranularlyExtendSelectionEvent(
          forward: false,
          isEnd: true,
          granularity: TextGranularity.character,
        ),
      );
      selection = paragraph.selections[0];
      expect(selection.start, 4); // how [a]re you
      expect(selection.end, 5);
    });

    test('can granularly extend selection - word', () async {
      final registrar = TestSelectionRegistrar();
      final renderBoxes = <RenderBox>[];
      final paragraph = RenderParagraph(
        const TextSpan(children: <InlineSpan>[TextSpan(text: 'how are you\nI am fine\nThank you')]),
        textDirection: TextDirection.ltr,
        registrar: registrar,
        children: renderBoxes,
      );
      layout(paragraph);

      expect(registrar.selectables.length, 1);
      selectionParagraph(paragraph, const TextPosition(offset: 4), const TextPosition(offset: 5));
      expect(paragraph.selections.length, 1);
      TextSelection selection = paragraph.selections[0];
      expect(selection.start, 4); // how [a]re you
      expect(selection.end, 5);

      // Equivalent to sending shift + alt + arrow-right.
      registrar.selectables[0].dispatchSelectionEvent(
        const GranularlyExtendSelectionEvent(
          forward: true,
          isEnd: true,
          granularity: TextGranularity.word,
        ),
      );
      selection = paragraph.selections[0];
      expect(selection.start, 4); // how [are] you
      expect(selection.end, 7);

      // Equivalent to sending shift + alt + arrow-left.
      registrar.selectables[0].dispatchSelectionEvent(
        const GranularlyExtendSelectionEvent(
          forward: false,
          isEnd: true,
          granularity: TextGranularity.word,
        ),
      );
      expect(paragraph.selections.length, 1); // how []are you
      expect(paragraph.selections[0], const TextSelection.collapsed(offset: 4));

      // Equivalent to sending shift + alt + arrow-left.
      registrar.selectables[0].dispatchSelectionEvent(
        const GranularlyExtendSelectionEvent(
          forward: false,
          isEnd: true,
          granularity: TextGranularity.word,
        ),
      );
      selection = paragraph.selections[0];
      expect(selection.start, 0); // [how ]are you
      expect(selection.end, 4);
    });

    test('can granularly extend selection - line', () async {
      final registrar = TestSelectionRegistrar();
      final renderBoxes = <RenderBox>[];
      final paragraph = RenderParagraph(
        const TextSpan(children: <InlineSpan>[TextSpan(text: 'how are you\nI am fine\nThank you')]),
        textDirection: TextDirection.ltr,
        registrar: registrar,
        children: renderBoxes,
      );
      layout(paragraph);

      expect(registrar.selectables.length, 1);
      selectionParagraph(paragraph, const TextPosition(offset: 4), const TextPosition(offset: 5));
      expect(paragraph.selections.length, 1);
      TextSelection selection = paragraph.selections[0];
      expect(selection.start, 4); // how [a]re you
      expect(selection.end, 5);

      // Equivalent to sending shift + meta + arrow-right.
      registrar.selectables[0].dispatchSelectionEvent(
        const GranularlyExtendSelectionEvent(
          forward: true,
          isEnd: true,
          granularity: TextGranularity.line,
        ),
      );
      selection = paragraph.selections[0];
      // how [are you]
      expect(selection, const TextRange(start: 4, end: 11));

      // Equivalent to sending shift + meta + arrow-left.
      registrar.selectables[0].dispatchSelectionEvent(
        const GranularlyExtendSelectionEvent(
          forward: false,
          isEnd: true,
          granularity: TextGranularity.line,
        ),
      );
      selection = paragraph.selections[0];
      // [how ]are you
      expect(selection, const TextRange(start: 0, end: 4));
    });

    test('can granularly extend selection - document', () async {
      final registrar = TestSelectionRegistrar();
      final renderBoxes = <RenderBox>[];
      final paragraph = RenderParagraph(
        const TextSpan(children: <InlineSpan>[TextSpan(text: 'how are you\nI am fine\nThank you')]),
        textDirection: TextDirection.ltr,
        registrar: registrar,
        children: renderBoxes,
      );
      layout(paragraph);

      expect(registrar.selectables.length, 1);
      selectionParagraph(paragraph, const TextPosition(offset: 14), const TextPosition(offset: 15));
      expect(paragraph.selections.length, 1);
      TextSelection selection = paragraph.selections[0];
      // how are you
      // I [a]m fine
      expect(selection.start, 14);
      expect(selection.end, 15);

      // Equivalent to sending shift + meta + arrow-down.
      registrar.selectables[0].dispatchSelectionEvent(
        const GranularlyExtendSelectionEvent(
          forward: true,
          isEnd: true,
          granularity: TextGranularity.document,
        ),
      );
      selection = paragraph.selections[0];
      // how are you
      // I [am fine
      // Thank you]
      expect(selection.start, 14);
      expect(selection.end, 31);

      // Equivalent to sending shift + meta + arrow-up.
      registrar.selectables[0].dispatchSelectionEvent(
        const GranularlyExtendSelectionEvent(
          forward: false,
          isEnd: true,
          granularity: TextGranularity.document,
        ),
      );
      selection = paragraph.selections[0];
      // [how are you
      // I ]am fine
      // Thank you
      expect(selection.start, 0);
      expect(selection.end, 14);
    });

    test('can granularly extend selection when no active selection', () async {
      final registrar = TestSelectionRegistrar();
      final renderBoxes = <RenderBox>[];
      final paragraph = RenderParagraph(
        const TextSpan(children: <InlineSpan>[TextSpan(text: 'how are you\nI am fine\nThank you')]),
        textDirection: TextDirection.ltr,
        registrar: registrar,
        children: renderBoxes,
      );
      layout(paragraph);

      expect(registrar.selectables.length, 1);
      expect(paragraph.selections.length, 0);

      // Equivalent to sending shift + alt + right.
      registrar.selectables[0].dispatchSelectionEvent(
        const GranularlyExtendSelectionEvent(
          forward: true,
          isEnd: true,
          granularity: TextGranularity.word,
        ),
      );
      TextSelection selection = paragraph.selections[0];
      // [how] are you
      // I am fine
      // Thank you
      expect(selection.start, 0);
      expect(selection.end, 3);

      // Remove selection
      registrar.selectables[0].dispatchSelectionEvent(const ClearSelectionEvent());
      expect(paragraph.selections.length, 0);

      // Equivalent to sending shift + alt + left.
      registrar.selectables[0].dispatchSelectionEvent(
        const GranularlyExtendSelectionEvent(
          forward: false,
          isEnd: true,
          granularity: TextGranularity.word,
        ),
      );
      selection = paragraph.selections[0];
      // how are you
      // I am fine
      // Thank [you]
      expect(selection.start, 28);
      expect(selection.end, 31);
    });

    test('can directionally extend selection', () async {
      final registrar = TestSelectionRegistrar();
      final renderBoxes = <RenderBox>[];
      final paragraph = RenderParagraph(
        const TextSpan(children: <InlineSpan>[TextSpan(text: 'how are you\nI am fine\nThank you')]),
        textDirection: TextDirection.ltr,
        registrar: registrar,
        children: renderBoxes,
      );
      layout(paragraph);

      expect(registrar.selectables.length, 1);
      selectionParagraph(paragraph, const TextPosition(offset: 14), const TextPosition(offset: 15));
      expect(paragraph.selections.length, 1);
      TextSelection selection = paragraph.selections[0];
      // how are you
      // I [a]m fine
      expect(selection.start, 14);
      expect(selection.end, 15);

      final Matrix4 transform = registrar.selectables[0].getTransformTo(null);
      final double baseline = MatrixUtils.transformPoint(
        transform,
        registrar.selectables[0].value.endSelectionPoint!.localPosition,
      ).dx;

      // Equivalent to sending shift + arrow-down.
      registrar.selectables[0].dispatchSelectionEvent(
        DirectionallyExtendSelectionEvent(
          isEnd: true,
          dx: baseline,
          direction: SelectionExtendDirection.nextLine,
        ),
      );
      selection = paragraph.selections[0];
      // how are you
      // I [am fine
      // Tha]nk you
      expect(selection.start, 14);
      expect(selection.end, 25);

      // Equivalent to sending shift + arrow-up.
      registrar.selectables[0].dispatchSelectionEvent(
        DirectionallyExtendSelectionEvent(
          isEnd: true,
          dx: baseline,
          direction: SelectionExtendDirection.previousLine,
        ),
      );
      selection = paragraph.selections[0];
      // how are you
      // I [a]m fine
      // Thank you
      expect(selection.start, 14);
      expect(selection.end, 15);
    });

    test('can directionally extend selection when no selection', () async {
      final registrar = TestSelectionRegistrar();
      final renderBoxes = <RenderBox>[];
      final paragraph = RenderParagraph(
        const TextSpan(children: <InlineSpan>[TextSpan(text: 'how are you\nI am fine\nThank you')]),
        textDirection: TextDirection.ltr,
        registrar: registrar,
        children: renderBoxes,
      );
      layout(paragraph);

      expect(registrar.selectables.length, 1);
      expect(paragraph.selections.length, 0);

      final Matrix4 transform = registrar.selectables[0].getTransformTo(null);
      final double baseline = MatrixUtils.transformPoint(
        transform,
        Offset(registrar.selectables[0].size.width / 2, 0),
      ).dx;

      // Equivalent to sending shift + arrow-down.
      registrar.selectables[0].dispatchSelectionEvent(
        DirectionallyExtendSelectionEvent(
          isEnd: true,
          dx: baseline,
          direction: SelectionExtendDirection.forward,
        ),
      );
      TextSelection selection = paragraph.selections[0];
      // [how ar]e you
      // I am fine
      // Thank you
      expect(selection.start, 0);
      expect(selection.end, 6);

      registrar.selectables[0].dispatchSelectionEvent(const ClearSelectionEvent());
      expect(paragraph.selections.length, 0);

      // Equivalent to sending shift + arrow-up.
      registrar.selectables[0].dispatchSelectionEvent(
        DirectionallyExtendSelectionEvent(
          isEnd: true,
          dx: baseline,
          direction: SelectionExtendDirection.backward,
        ),
      );
      selection = paragraph.selections[0];
      // how are you
      // I am fine
      // Thank [you]
      expect(selection.start, 28);
      expect(selection.end, 31);
    });
  });

  test('can just update the gesture recognizer', () async {
    final recognizerBefore = TapGestureRecognizer()..onTap = () {};
    final paragraph = RenderParagraph(
      TextSpan(text: 'How are you \n', recognizer: recognizerBefore),
      textDirection: TextDirection.ltr,
    );

    var semanticsUpdateCount = 0;
    final SemanticsHandle semanticsHandle = TestRenderingFlutterBinding.instance.ensureSemantics();
    TestRenderingFlutterBinding.instance.pipelineOwner.semanticsOwner!.addListener(() {
      ++semanticsUpdateCount;
    });

    layout(paragraph);

    expect((paragraph.text as TextSpan).recognizer, same(recognizerBefore));
    final nodeBefore = SemanticsNode();
    paragraph.assembleSemanticsNode(nodeBefore, SemanticsConfiguration(), <SemanticsNode>[]);
    expect(semanticsUpdateCount, 0);
    var children = <SemanticsNode>[];
    nodeBefore.visitChildren((SemanticsNode child) {
      children.add(child);
      return true;
    });
    SemanticsData data = children.single.getSemanticsData();
    expect(data.hasAction(SemanticsAction.longPress), false);
    expect(data.hasAction(SemanticsAction.tap), true);

    final recognizerAfter = LongPressGestureRecognizer()..onLongPress = () {};
    paragraph.text = TextSpan(text: 'How are you \n', recognizer: recognizerAfter);

    pumpFrame(phase: EnginePhase.flushSemantics);

    expect((paragraph.text as TextSpan).recognizer, same(recognizerAfter));
    final nodeAfter = SemanticsNode();
    paragraph.assembleSemanticsNode(nodeAfter, SemanticsConfiguration(), <SemanticsNode>[]);
    expect(semanticsUpdateCount, 1);
    children = <SemanticsNode>[];
    nodeAfter.visitChildren((SemanticsNode child) {
      children.add(child);
      return true;
    });
    data = children.single.getSemanticsData();
    expect(data.hasAction(SemanticsAction.longPress), true);
    expect(data.hasAction(SemanticsAction.tap), false);

    semanticsHandle.dispose();
  });
}

class MockCanvas extends Fake implements Canvas {
  Rect? drawnRect;
  Paint? drawnRectPaint;
  List<Type> drawnItemTypes = <Type>[];

  @override
  void drawRect(Rect rect, Paint paint) {
    drawnRect = rect;
    drawnRectPaint = paint;
    drawnItemTypes.add(Rect);
  }

  @override
  void drawParagraph(ui.Paragraph paragraph, Offset offset) {
    drawnItemTypes.add(ui.Paragraph);
  }

  void clear() {
    drawnRect = null;
    drawnRectPaint = null;
    drawnItemTypes.clear();
  }
}

class MockPaintingContext extends Fake implements PaintingContext {
  @override
  final MockCanvas canvas = MockCanvas();
}

class TestSelectionRegistrar extends SelectionRegistrar {
  final List<Selectable> selectables = <Selectable>[];
  @override
  void add(Selectable selectable) {
    selectables.add(selectable);
  }

  @override
  void remove(Selectable selectable) {
    expect(selectables.remove(selectable), isTrue);
  }
}
