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

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

import 'semantics_tester.dart';

void main() {
  testWidgets('Text respects media query', (WidgetTester tester) async {
    await tester.pumpWidget(MediaQuery.withClampedTextScaling(
      minScaleFactor: 1.3,
      maxScaleFactor: 1.3,
      child: const Center(
        child: Text('Hello', textDirection: TextDirection.ltr),
      ),
    ));

    RichText text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.textScaler, const TextScaler.linear(1.3));

    await tester.pumpWidget(const Center(
      child: Text('Hello', textDirection: TextDirection.ltr),
    ));

    text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.textScaler, TextScaler.noScaling);
  });

  testWidgets('Text respects textScaleFactor with default font size', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Center(child: Text('Hello', textDirection: TextDirection.ltr)),
    );

    RichText text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.textScaler, TextScaler.noScaling);
    final Size baseSize = tester.getSize(find.byType(RichText));
    expect(baseSize.width, equals(70.0));
    expect(baseSize.height, equals(14.0));

    await tester.pumpWidget(const Center(
      child: Text(
        'Hello',
        textScaleFactor: 1.5,
        textDirection: TextDirection.ltr,
      ),
    ));

    text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.textScaler, const TextScaler.linear(1.5));
    final Size largeSize = tester.getSize(find.byType(RichText));
    expect(largeSize.width, 105.0);
    expect(largeSize.height, equals(21.0));
  });

  testWidgets('Text respects textScaleFactor with explicit font size', (WidgetTester tester) async {
    await tester.pumpWidget(const Center(
      child: Text(
        'Hello',
        style: TextStyle(fontSize: 20.0),
        textDirection: TextDirection.ltr,
      ),
    ));

    RichText text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.textScaler, TextScaler.noScaling);
    final Size baseSize = tester.getSize(find.byType(RichText));
    expect(baseSize.width, equals(100.0));
    expect(baseSize.height, equals(20.0));

    await tester.pumpWidget(const Center(
      child: Text(
        'Hello',
        style: TextStyle(fontSize: 20.0),
        textScaleFactor: 1.3,
        textDirection: TextDirection.ltr,
      ),
    ));

    text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.textScaler, const TextScaler.linear(1.3));
    final Size largeSize = tester.getSize(find.byType(RichText));
    expect(largeSize.width, 130.0);
    expect(largeSize.height, equals(26.0));
  });

  testWidgets("Text throws a nice error message if there's no Directionality",
  experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), // leaking by design because of exception
  (WidgetTester tester) async {
    await tester.pumpWidget(const Text('Hello'));
    final String message = tester.takeException().toString();
    expect(message, contains('Directionality'));
    expect(message, contains(' Text '));
  });

  testWidgets('Text can be created from TextSpans and uses defaultTextStyle', (WidgetTester tester) async {
    await tester.pumpWidget(
      const DefaultTextStyle(
        style: TextStyle(
          fontSize: 20.0,
        ),
        child: Text.rich(
          TextSpan(
            text: 'Hello',
            children: <TextSpan>[
              TextSpan(
                text: ' beautiful ',
                style: TextStyle(fontStyle: FontStyle.italic),
              ),
              TextSpan(
                text: 'world',
                style: TextStyle(fontWeight: FontWeight.bold),
              ),
            ],
          ),
          textDirection: TextDirection.ltr,
        ),
      ),
    );

    final RichText text = tester.firstWidget(find.byType(RichText));
    expect(text, isNotNull);
    expect(text.text.style!.fontSize, 20.0);
  });

  testWidgets('inline widgets works with ellipsis', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/35869
    const TextStyle textStyle = TextStyle();
    await tester.pumpWidget(
      Text.rich(
        TextSpan(
          children: <InlineSpan>[
            const TextSpan(
              text: 'a very very very very very very very very very very long line',
            ),
            WidgetSpan(
              child: SizedBox(
                width: 20,
                height: 40,
                child: Card(
                  child: RichText(
                    text: const TextSpan(text: 'widget should be truncated'),
                    textDirection: TextDirection.rtl,
                  ),
                ),
              ),
            ),
          ],
          style: textStyle,
        ),
        textDirection: TextDirection.ltr,
        maxLines: 1,
        overflow: TextOverflow.ellipsis,
      ),
    );
    expect(tester.takeException(), null);
  });

  testWidgets('inline widgets hitTest works with ellipsis', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/68559
    const TextStyle textStyle = TextStyle();
    await tester.pumpWidget(
      Text.rich(
        TextSpan(
          children: <InlineSpan>[
            const TextSpan(
              text: 'a very very very very very very very very very very long line',
            ),
            WidgetSpan(
              child: SizedBox(
                width: 20,
                height: 40,
                child: Card(
                  child: RichText(
                    text: const TextSpan(text: 'widget should be truncated'),
                    textDirection: TextDirection.rtl,
                  ),
                ),
              ),
            ),
          ],
          style: textStyle,
        ),
        textDirection: TextDirection.ltr,
        maxLines: 1,
        overflow: TextOverflow.ellipsis,
      ),
    );

    await tester.tap(find.byType(Text));

    expect(tester.takeException(), null);
  });

  testWidgets('inline widgets works with textScaleFactor', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/59316
    final UniqueKey key = UniqueKey();
    double textScaleFactor = 1.0;
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(useMaterial3: false),
        home: Scaffold(
          appBar: AppBar(title: const Text('title')),
          body: Center(
            child: Text.rich(
              TextSpan(
                children: <InlineSpan>[
                  WidgetSpan(
                    child: RichText(
                      text: const TextSpan(text: 'widget should be truncated'),
                      textDirection: TextDirection.ltr,
                    ),
                  ),
                ],
              ),
              key: key,
              textDirection: TextDirection.ltr,
              textScaleFactor: textScaleFactor,
            ),
          ),
        ),
      ),
    );
    RenderBox renderText = tester.renderObject(find.byKey(key));
    final double singleLineHeight = renderText.size.height;
    // Now, increases the text scale factor by 5 times.
    textScaleFactor = textScaleFactor * 5;
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(useMaterial3: false),
        home: Scaffold(
          appBar: AppBar(title: const Text('title')),
          body: Center(
            child: Text.rich(
              TextSpan(
                children: <InlineSpan>[
                  WidgetSpan(
                    child: RichText(
                      text: const TextSpan(text: 'widget should be truncated'),
                      textDirection: TextDirection.ltr,
                    ),
                  ),
                ],
              ),
              key: key,
              textDirection: TextDirection.ltr,
              textScaleFactor: textScaleFactor,
            ),
          ),
        ),
      ),
    );

    renderText = tester.renderObject(find.byKey(key));
    // The RichText in the widget span should wrap into three lines.
    expect(renderText.size.height, singleLineHeight * textScaleFactor * 3);
  });

  testWidgets("Inline widgets' scaled sizes are constrained", (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/130588
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: SizedBox(
            width: 502.5454545454545,
            child: Text.rich(WidgetSpan(child: Row()), textScaleFactor: 0.95),
          ),
        ),
      ),
    );

    expect(tester.takeException(), isNull);
  });

  testWidgets('semanticsLabel can override text label', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    await tester.pumpWidget(
      const Text(
        r'$$',
        semanticsLabel: 'Double dollars',
        textDirection: TextDirection.ltr,
      ),
    );
    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          label: 'Double dollars',
          textDirection: TextDirection.ltr,
        ),
      ],
    );
    expect(
      semantics,
      hasSemantics(
        expectedSemantics,
        ignoreTransform: true,
        ignoreId: true,
        ignoreRect: true,
      ),
    );

    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: Text(r'$$', semanticsLabel: 'Double dollars'),
      ),
    );

    expect(
      semantics,
      hasSemantics(
        expectedSemantics,
        ignoreTransform: true,
        ignoreId: true,
        ignoreRect: true,
      ),
    );
    semantics.dispose();
  });

  testWidgets('semantics label is in order when uses widget span', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Text.rich(
          TextSpan(
            children: <InlineSpan>[
              const TextSpan(text: 'before '),
              WidgetSpan(
                alignment: PlaceholderAlignment.baseline,
                baseline: TextBaseline.alphabetic,
                child: Semantics(label: 'foo'),
              ),
              const TextSpan(text: ' after'),
            ],
          ),
        ),
      ),
    );
    expect(
      tester.getSemantics(find.byType(Text)),
      matchesSemantics(label: 'before \nfoo\n after'),
    );

    // If the Paragraph is not dirty it should use the cache correctly.
    final RenderObject parent = tester.renderObject<RenderObject>(find.byType(Directionality));
    parent.markNeedsSemanticsUpdate();
    await tester.pumpAndSettle();

    expect(
      tester.getSemantics(find.byType(Text)),
      matchesSemantics(label: 'before \nfoo\n after'),
    );
  });

  testWidgets('semantics can handle some widget spans without semantics', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Text.rich(
          TextSpan(
            children: <InlineSpan>[
              const TextSpan(text: 'before '),
              const WidgetSpan(
                alignment: PlaceholderAlignment.baseline,
                baseline: TextBaseline.alphabetic,
                child: SizedBox(width: 10.0),
              ),
              const TextSpan(text: ' mid'),
              WidgetSpan(
                alignment: PlaceholderAlignment.baseline,
                baseline: TextBaseline.alphabetic,
                child: Semantics(label: 'foo'),
              ),
              const TextSpan(text: ' after'),
              const WidgetSpan(
                alignment: PlaceholderAlignment.baseline,
                baseline: TextBaseline.alphabetic,
                child: SizedBox(width: 10.0),
              ),
            ],
          ),
        ),
      ),
    );
    expect(tester.getSemantics(find.byType(Text)),
        matchesSemantics(label: 'before \n mid\nfoo\n after'));

    // If the Paragraph is not dirty it should use the cache correctly.
    final RenderObject parent = tester.renderObject<RenderObject>(find.byType(Directionality));
    parent.markNeedsSemanticsUpdate();
    await tester.pumpAndSettle();

    expect(tester.getSemantics(find.byType(Text)),
        matchesSemantics(label: 'before \n mid\nfoo\n after'));
  });

  testWidgets('semantics can handle all widget spans without semantics', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: Text.rich(
          TextSpan(
            children: <InlineSpan>[
              TextSpan(text: 'before '),
              WidgetSpan(
                alignment: PlaceholderAlignment.baseline,
                baseline: TextBaseline.alphabetic,
                child: SizedBox(width: 10.0),
              ),
              TextSpan(text: ' mid'),
              WidgetSpan(
                alignment: PlaceholderAlignment.baseline,
                baseline: TextBaseline.alphabetic,
                child: SizedBox(width: 10.0),
              ),
              TextSpan(text: ' after'),
              WidgetSpan(
                alignment: PlaceholderAlignment.baseline,
                baseline: TextBaseline.alphabetic,
                child: SizedBox(width: 10.0),
              ),
            ],
          ),
        ),
      ),
    );
    expect(tester.getSemantics(find.byType(Text)),
        matchesSemantics(label: 'before \n mid\n after'));

    // If the Paragraph is not dirty it should use the cache correctly.
    final RenderObject parent = tester.renderObject<RenderObject>(find.byType(Directionality));
    parent.markNeedsSemanticsUpdate();
    await tester.pumpAndSettle();

    expect(tester.getSemantics(find.byType(Text)),
        matchesSemantics(label: 'before \n mid\n after'));
  });

  testWidgets('semantics can handle widget spans with explicit semantics node', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Text.rich(
          TextSpan(
            children: <InlineSpan>[
              const TextSpan(text: 'before '),
              WidgetSpan(
                alignment: PlaceholderAlignment.baseline,
                baseline: TextBaseline.alphabetic,
                child: Semantics(label: 'inner', container: true),
              ),
              const TextSpan(text: ' after'),
            ],
          ),
        ),
      ),
    );
    expect(
      tester.getSemantics(find.byType(Text)),
      matchesSemantics(label: 'before \n after', children: <Matcher>[matchesSemantics(label: 'inner')]),
    );

    // If the Paragraph is not dirty it should use the cache correctly.
    final RenderObject parent = tester.renderObject<RenderObject>(find.byType(Directionality));
    parent.markNeedsSemanticsUpdate();
    await tester.pumpAndSettle();

    expect(
      tester.getSemantics(find.byType(Text)),
      matchesSemantics(label: 'before \n after', children: <Matcher>[matchesSemantics(label: 'inner')]),
    );
  });

  testWidgets('semanticsLabel can be shorter than text', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    final TapGestureRecognizer recognizer = TapGestureRecognizer();
    addTearDown(recognizer.dispose);

    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: RichText(
        text: TextSpan(
          children: <InlineSpan>[
            const TextSpan(
              text: 'Some Text',
              semanticsLabel: '',
            ),
            TextSpan(
              text: 'Clickable',
              recognizer: recognizer..onTap = () { },
            ),
          ],
        ),
      ),
    ));
    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics(
          children: <TestSemantics>[
            TestSemantics(
              textDirection: TextDirection.ltr,
            ),
            TestSemantics(
              label: 'Clickable',
              actions: <SemanticsAction>[SemanticsAction.tap],
              flags: <SemanticsFlag>[SemanticsFlag.isLink],
              textDirection: TextDirection.ltr,
            ),
          ],
        ),
      ],
    );
    expect(
      semantics,
      hasSemantics(
        expectedSemantics,
        ignoreTransform: true,
        ignoreId: true,
        ignoreRect: true,
      ),
    );
    semantics.dispose();
  });

  testWidgets('recognizers split semantic node', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    const TextStyle textStyle = TextStyle();
    final TapGestureRecognizer recognizer = TapGestureRecognizer();
    addTearDown(recognizer.dispose);

    await tester.pumpWidget(
      Text.rich(
        TextSpan(
          children: <TextSpan>[
            const TextSpan(text: 'hello '),
            TextSpan(
              text: 'world',
              recognizer: recognizer..onTap = () { },
            ),
            const TextSpan(text: ' this is a '),
            const TextSpan(text: 'cat-astrophe'),
          ],
          style: textStyle,
        ),
        textDirection: TextDirection.ltr,
      ),
    );
    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          children: <TestSemantics>[
            TestSemantics(
              label: 'hello ',
              textDirection: TextDirection.ltr,
            ),
            TestSemantics(
              label: 'world',
              textDirection: TextDirection.ltr,
              actions: <SemanticsAction>[SemanticsAction.tap],
              flags: <SemanticsFlag>[SemanticsFlag.isLink],
            ),
            TestSemantics(
              label: ' this is a cat-astrophe',
              textDirection: TextDirection.ltr,
            ),
          ],
        ),
      ],
    );
    expect(
      semantics,
      hasSemantics(
        expectedSemantics,
        ignoreTransform: true,
        ignoreId: true,
        ignoreRect: true,
      ),
    );
    semantics.dispose();
  });

  testWidgets('semantic nodes of offscreen recognizers are marked hidden', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/100395.
    final SemanticsTester semantics = SemanticsTester(tester);
    const TextStyle textStyle = TextStyle(fontSize: 200);
    const String onScreenText = 'onscreen\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n';
    const String offScreenText = 'off screen';
    final ScrollController controller = ScrollController();
    addTearDown(controller.dispose);
    final TapGestureRecognizer recognizer = TapGestureRecognizer();
    addTearDown(recognizer.dispose);

    await tester.pumpWidget(
      SingleChildScrollView(
        controller: controller,
        child: Text.rich(
          TextSpan(
            children: <TextSpan>[
              const TextSpan(text: onScreenText),
              TextSpan(
                text: offScreenText,
                recognizer: recognizer..onTap = () { },
              ),
            ],
            style: textStyle,
          ),
          textDirection: TextDirection.ltr,
        ),
      ),
    );

    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics(
          flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling],
          actions: <SemanticsAction>[SemanticsAction.scrollUp],
          children: <TestSemantics>[
            TestSemantics(
              children: <TestSemantics>[
                TestSemantics(
                  label: onScreenText,
                  textDirection: TextDirection.ltr,
                ),
                TestSemantics(
                  label: offScreenText,
                  textDirection: TextDirection.ltr,
                  actions: <SemanticsAction>[SemanticsAction.tap],
                  flags: <SemanticsFlag>[SemanticsFlag.isLink, SemanticsFlag.isHidden],
                ),
              ],
            ),
          ],
        ),
      ],
    );
    expect(
      semantics,
      hasSemantics(
        expectedSemantics,
        ignoreTransform: true,
        ignoreId: true,
        ignoreRect: true,
      ),
    );

    // Test show on screen.
    expect(controller.offset, 0.0);
    tester.binding.pipelineOwner.semanticsOwner!.performAction(4, SemanticsAction.showOnScreen);
    await tester.pumpAndSettle();
    expect(controller.offset != 0.0, isTrue);

    semantics.dispose();
  });

  testWidgets('recognizers split semantic node when TextSpan overflows', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    const TextStyle textStyle = TextStyle();
    final TapGestureRecognizer recognizer = TapGestureRecognizer();
    addTearDown(recognizer.dispose);

    await tester.pumpWidget(
      SizedBox(
        height: 10,
        child: Text.rich(
          TextSpan(
            children: <TextSpan>[
              const TextSpan(text: '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'),
              TextSpan(
                text: 'world',
                recognizer: recognizer..onTap = () { },
              ),
            ],
            style: textStyle,
          ),
          textDirection: TextDirection.ltr,
        ),
      ),
    );
    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          children: <TestSemantics>[
            TestSemantics(
              label: '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n',
              textDirection: TextDirection.ltr,
            ),
            TestSemantics(
              label: 'world',
              textDirection: TextDirection.ltr,
              actions: <SemanticsAction>[SemanticsAction.tap],
              flags: <SemanticsFlag>[SemanticsFlag.isLink],
            ),
          ],
        ),
      ],
    );
    expect(
      semantics,
      hasSemantics(
        expectedSemantics,
        ignoreTransform: true,
        ignoreId: true,
        ignoreRect: true,
      ),
    );
    semantics.dispose();
  });

  testWidgets('recognizers split semantic nodes with text span labels', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    const TextStyle textStyle = TextStyle();
    final TapGestureRecognizer recognizer = TapGestureRecognizer();
    addTearDown(recognizer.dispose);

    await tester.pumpWidget(
      Text.rich(
        TextSpan(
          children: <TextSpan>[
            const TextSpan(text: 'hello '),
            TextSpan(
              text: 'world',
              recognizer: recognizer..onTap = () { },
            ),
            const TextSpan(text: ' this is a '),
            const TextSpan(
              text: 'cat-astrophe',
              semanticsLabel: 'regrettable event',
            ),
          ],
          style: textStyle,
        ),
        textDirection: TextDirection.ltr,
      ),
    );
    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          children: <TestSemantics>[
            TestSemantics(
              label: 'hello ',
              textDirection: TextDirection.ltr,
            ),
            TestSemantics(
              label: 'world',
              textDirection: TextDirection.ltr,
              actions: <SemanticsAction>[SemanticsAction.tap],
              flags: <SemanticsFlag>[SemanticsFlag.isLink],
            ),
            TestSemantics(
              label: ' this is a regrettable event',
              textDirection: TextDirection.ltr,
            ),
          ],
        ),
      ],
    );
    expect(
      semantics,
      hasSemantics(
        expectedSemantics,
        ignoreTransform: true,
        ignoreId: true,
        ignoreRect: true,
      ),
    );
    semantics.dispose();
  });


  testWidgets('recognizers split semantic node - bidi', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    const TextStyle textStyle = TextStyle();
    final LongPressGestureRecognizer recognizer1 = LongPressGestureRecognizer();
    addTearDown(recognizer1.dispose);
    final TapGestureRecognizer recognizer2 = TapGestureRecognizer();
    addTearDown(recognizer2.dispose);

    await tester.pumpWidget(
      RichText(
        text: TextSpan(
          style: textStyle,
          children: <TextSpan>[
            const TextSpan(text: 'hello world${Unicode.RLE}${Unicode.RLO} '),
            TextSpan(
              text: 'BOY',
              recognizer: recognizer1..onLongPress = () { },
            ),
            const TextSpan(text: ' HOW DO${Unicode.PDF} you ${Unicode.RLO} DO '),
            TextSpan(
              text: 'SIR',
              recognizer: recognizer2..onTap = () { },
            ),
            const TextSpan(text: '${Unicode.PDF}${Unicode.PDF} good bye'),
          ],
        ),
        textDirection: TextDirection.ltr,
      ),
    );
    // The expected visual order of the text is:
    //   hello world RIS OD you OD WOH YOB good bye
    // There are five unique text areas, they are, in visual order but
    // showing the logical text:
    //   [hello world][SIR][HOW DO you DO][BOY][good bye]
    // The direction of each varies based on the first bit of that area.
    // The presence of the bidi formatting characters in the text is a
    // bit dubious, but that's what we do currently, and it's not really
    // clear what the perfect behavior would be...
    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 600.0),
          children: <TestSemantics>[
            TestSemantics(
              rect: const Rect.fromLTRB(-4.0, -4.0, 480.0, 18.0),
              label: 'hello world${Unicode.RLE}${Unicode.RLO} ',
              textDirection: TextDirection.ltr,
            ),
            TestSemantics(
              rect: const Rect.fromLTRB(416.0, -4.0, 466.0, 18.0),
              label: 'BOY',
              textDirection: TextDirection.rtl,
              actions: <SemanticsAction>[SemanticsAction.longPress],
            ),
            TestSemantics(
              rect: const Rect.fromLTRB(192.0, -4.0, 424.0, 18.0),
              label: ' HOW DO${Unicode.PDF} you ${Unicode.RLO} DO ',
              textDirection: TextDirection.rtl,
            ),
            TestSemantics(
              rect: const Rect.fromLTRB(150.0, -4.0, 200.0, 18.0),
              label: 'SIR',
              textDirection: TextDirection.rtl,
              actions: <SemanticsAction>[SemanticsAction.tap],
              flags: <SemanticsFlag>[SemanticsFlag.isLink],
            ),
            TestSemantics(
              rect: const Rect.fromLTRB(472.0, -4.0, 606.0, 18.0),
              label: '${Unicode.PDF}${Unicode.PDF} good bye',
              textDirection: TextDirection.rtl,
            ),
          ],
        ),
      ],
    );
    expect(
      semantics,
      hasSemantics(
        expectedSemantics,
        ignoreTransform: true,
        ignoreId: true,
      ),
    );
    semantics.dispose();
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/62945

  testWidgets('TapGesture recognizers contribute link semantics', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    const TextStyle textStyle = TextStyle();
    final TapGestureRecognizer recognizer = TapGestureRecognizer();
    addTearDown(recognizer.dispose);

    await tester.pumpWidget(
      Text.rich(
        TextSpan(
          children: <TextSpan>[
            TextSpan(
              text: 'click me',
              recognizer: recognizer..onTap = () { },
            ),
          ],
          style: textStyle,
        ),
        textDirection: TextDirection.ltr,
      ),
    );
    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          children: <TestSemantics>[
            TestSemantics(
              label: 'click me',
              textDirection: TextDirection.ltr,
              actions: <SemanticsAction>[SemanticsAction.tap],
              flags: <SemanticsFlag>[SemanticsFlag.isLink],
            ),
          ],
        ),
      ],
    );
    expect(semantics, hasSemantics(
      expectedSemantics,
      ignoreTransform: true,
      ignoreId: true,
      ignoreRect: true,
    ));
    semantics.dispose();
  });

  testWidgets('inline widgets generate semantic nodes', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    const TextStyle textStyle = TextStyle();
    final TapGestureRecognizer recognizer = TapGestureRecognizer();
    addTearDown(recognizer.dispose);

    await tester.pumpWidget(
      Text.rich(
        TextSpan(
          children: <InlineSpan>[
            const TextSpan(text: 'a '),
            TextSpan(
              text: 'pebble',
              recognizer: recognizer..onTap = () { },
            ),
            const TextSpan(text: ' in the '),
            WidgetSpan(
              child: SizedBox(
                width: 20,
                height: 40,
                child: Card(
                  child: RichText(
                    text: const TextSpan(text: 'INTERRUPTION'),
                    textDirection: TextDirection.rtl,
                  ),
                ),
              ),
            ),
            const TextSpan(text: 'sky'),
          ],
          style: textStyle,
        ),
        textDirection: TextDirection.ltr,
      ),
    );
    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          children: <TestSemantics>[
            TestSemantics(
              label: 'a ',
              textDirection: TextDirection.ltr,
            ),
            TestSemantics(
              label: 'pebble',
              textDirection: TextDirection.ltr,
              actions: <SemanticsAction>[SemanticsAction.tap],
              flags: <SemanticsFlag>[SemanticsFlag.isLink],
            ),
            TestSemantics(
              label: ' in the ',
              textDirection: TextDirection.ltr,
            ),
            TestSemantics(
              label: 'INTERRUPTION',
              textDirection: TextDirection.rtl,
            ),
            TestSemantics(
              label: 'sky',
              textDirection: TextDirection.ltr,
            ),
          ],
        ),
      ],
    );
    expect(
      semantics,
      hasSemantics(
        expectedSemantics,
        ignoreTransform: true,
        ignoreId: true,
        ignoreRect: true,
      ),
    );
    semantics.dispose();
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/62945

  testWidgets('inline widgets semantic nodes scale', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    const TextStyle textStyle = TextStyle();
    final TapGestureRecognizer recognizer = TapGestureRecognizer();
    addTearDown(recognizer.dispose);

    await tester.pumpWidget(
      Text.rich(
        TextSpan(
          children: <InlineSpan>[
            const TextSpan(text: 'a '),
            TextSpan(
              text: 'pebble',
              recognizer: recognizer..onTap = () { },
            ),
            const TextSpan(text: ' in the '),
            WidgetSpan(
              child: SizedBox(
                width: 20,
                height: 40,
                child: Card(
                  child: RichText(
                    text: const TextSpan(text: 'INTERRUPTION'),
                    textDirection: TextDirection.rtl,
                  ),
                ),
              ),
            ),
            const TextSpan(text: 'sky'),
          ],
          style: textStyle,
        ),
        textDirection: TextDirection.ltr,
        textScaleFactor: 2,
      ),
    );
    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 600.0),
          children: <TestSemantics>[
            TestSemantics(
              label: 'a ',
              textDirection: TextDirection.ltr,
              rect: const Rect.fromLTRB(-4.0, 48.0, 60.0, 84.0),
            ),
            TestSemantics(
              label: 'pebble',
              textDirection: TextDirection.ltr,
              actions: <SemanticsAction>[SemanticsAction.tap],
              flags: <SemanticsFlag>[SemanticsFlag.isLink],
              rect: const Rect.fromLTRB(52.0, 48.0, 228.0, 84.0),
            ),
            TestSemantics(
              label: ' in the ',
              textDirection: TextDirection.ltr,
              rect: const Rect.fromLTRB(220.0, 48.0, 452.0, 84.0),
            ),
            TestSemantics(
              label: 'INTERRUPTION',
              textDirection: TextDirection.rtl,
              rect: const Rect.fromLTRB(0.0, 0.0, 20.0, 40.0),
            ),
            TestSemantics(
              label: 'sky',
              textDirection: TextDirection.ltr,
              rect: const Rect.fromLTRB(484.0, 48.0, 576.0, 84.0),
            ),
          ],
        ),
      ],
    );
    expect(
      semantics,
      hasSemantics(
        expectedSemantics,
        ignoreTransform: true,
        ignoreId: true,
      ),
    );
    semantics.dispose();
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/62945

  testWidgets('receives fontFamilyFallback and package from root ThemeData', (WidgetTester tester) async {
    const String fontFamily = 'fontFamily';
    const String package = 'package_name';
    final List<String> fontFamilyFallback = <String>['font', 'family', 'fallback'];
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          fontFamily: fontFamily,
          fontFamilyFallback: fontFamilyFallback,
          package: package,
          primarySwatch: Colors.blue,
        ),
        home: const Scaffold(
          body: Center(
            child: Text(
              'foo',
            ),
          ),
        ),
      ),
    );

    expect(find.byType(RichText), findsOneWidget);
    final RichText richText = tester.widget(find.byType(RichText));
    final InlineSpan text = richText.text;
    final TextStyle? style = text.style;
    expect(style?.fontFamily, equals('packages/$package/$fontFamily'));
    for (int i = 0; i < fontFamilyFallback.length; i++) {
      final String fallback = fontFamilyFallback[i];
      expect(style?.fontFamilyFallback?[i], equals('packages/$package/$fallback'));
    }
  });

  testWidgets('Overflow is clipping correctly - short text with overflow: clip', (WidgetTester tester) async {
    await _pumpTextWidget(
      tester: tester,
      overflow: TextOverflow.clip,
      text: 'Hi',
    );

    expect(find.byType(Text), isNot(paints..clipRect()));
  });

  testWidgets('Overflow is clipping correctly - long text with overflow: ellipsis', (WidgetTester tester) async {
    await _pumpTextWidget(
      tester: tester,
      overflow: TextOverflow.ellipsis,
      text: 'a long long long long text, should be clip',
    );

    expect(
      find.byType(Text),
      paints..clipRect(rect: const Rect.fromLTWH(0, 0, 50, 50)),
    );
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/87878

  testWidgets('Overflow is clipping correctly - short text with overflow: ellipsis', (WidgetTester tester) async {
    await _pumpTextWidget(
      tester: tester,
      overflow: TextOverflow.ellipsis,
      text: 'Hi',
    );

    expect(find.byType(Text), isNot(paints..clipRect()));
  });

  testWidgets('Overflow is clipping correctly - long text with overflow: fade', (WidgetTester tester) async {
    await _pumpTextWidget(
      tester: tester,
      overflow: TextOverflow.fade,
      text: 'a long long long long text, should be clip',
    );

    expect(
      find.byType(Text),
      paints..clipRect(rect: const Rect.fromLTWH(0, 0, 50, 50)),
    );
  });

  testWidgets('Overflow is clipping correctly - short text with overflow: fade', (WidgetTester tester) async {
    await _pumpTextWidget(
      tester: tester,
      overflow: TextOverflow.fade,
      text: 'Hi',
    );

    expect(find.byType(Text), isNot(paints..clipRect()));
  });

  testWidgets('Overflow is clipping correctly - long text with overflow: visible', (WidgetTester tester) async {
    await _pumpTextWidget(
      tester: tester,
      overflow: TextOverflow.visible,
      text: 'a long long long long text, should be clip',
    );

    expect(find.byType(Text), isNot(paints..clipRect()));
  });

  testWidgets('Overflow is clipping correctly - short text with overflow: visible', (WidgetTester tester) async {
    await _pumpTextWidget(
      tester: tester,
      overflow: TextOverflow.visible,
      text: 'Hi',
    );

    expect(find.byType(Text), isNot(paints..clipRect()));
  });

  testWidgets('textWidthBasis affects the width of a Text widget', (WidgetTester tester) async {
    Future<void> createText(TextWidthBasis textWidthBasis) {
      return tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(useMaterial3: false),
          home: Scaffold(
            body: Center(
              // Each word takes up more than a half of a line. Together they
              // wrap onto two lines, but leave a lot of extra space.
              child: Text(
                'twowordsthateachtakeupmorethanhalfof alineoftextsothattheywrapwithlotsofextraspace',
                textDirection: TextDirection.ltr,
                textWidthBasis: textWidthBasis,
              ),
            ),
          ),
        ),
      );
    }

    const double fontHeight = 14.0;
    const double screenWidth = 800.0;

    // When textWidthBasis is parent, takes up full screen width.
    await createText(TextWidthBasis.parent);
    final Size textSizeParent = tester.getSize(find.byType(Text));
    expect(textSizeParent.width, equals(screenWidth));
    expect(textSizeParent.height, equals(fontHeight * 2));

    // When textWidthBasis is longestLine, sets the width to as small as
    // possible for the two lines.
    await createText(TextWidthBasis.longestLine);
    final Size textSizeLongestLine = tester.getSize(find.byType(Text));
    expect(textSizeLongestLine.width, equals(630.0));
    expect(textSizeLongestLine.height, equals(fontHeight * 2));
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/44020

  testWidgets('textWidthBasis with textAlign still obeys parent alignment', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text(
                  'LEFT ALIGNED, PARENT',
                  textAlign: TextAlign.left,
                  textWidthBasis: TextWidthBasis.parent,
                ),
                Text(
                  'RIGHT ALIGNED, PARENT',
                  textAlign: TextAlign.right,
                  textWidthBasis: TextWidthBasis.parent,
                ),
                Text(
                  'LEFT ALIGNED, LONGEST LINE',
                  textAlign: TextAlign.left,
                  textWidthBasis: TextWidthBasis.longestLine,
                ),
                Text(
                  'RIGHT ALIGNED, LONGEST LINE',
                  textAlign: TextAlign.right,
                  textWidthBasis: TextWidthBasis.longestLine,
                ),
              ],
            ),
          ),
        ),
      ),
    );

    // All Texts have the same horizontal alignment.
    final double offsetX = tester.getTopLeft(find.text('LEFT ALIGNED, PARENT')).dx;
    expect(tester.getTopLeft(find.text('RIGHT ALIGNED, PARENT')).dx, equals(offsetX));
    expect(tester.getTopLeft(find.text('LEFT ALIGNED, LONGEST LINE')).dx, equals(offsetX));
    expect(tester.getTopLeft(find.text('RIGHT ALIGNED, LONGEST LINE')).dx, equals(offsetX));

    // All Texts are less than or equal to the width of the Column.
    final double width = tester.getSize(find.byType(Column)).width;
    expect(tester.getSize(find.text('LEFT ALIGNED, PARENT')).width, lessThan(width));
    expect(tester.getSize(find.text('RIGHT ALIGNED, PARENT')).width, lessThan(width));
    expect(tester.getSize(find.text('LEFT ALIGNED, LONGEST LINE')).width, lessThan(width));
    expect(tester.getSize(find.text('RIGHT ALIGNED, LONGEST LINE')).width, equals(width));
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/44020

  testWidgets(
    'textWidthBasis.longestLine confines the width of the paragraph '
    'when given loose constraints',
    (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/62550.
      await tester.pumpWidget(
          Center(
            child: SizedBox(
              width: 400,
              child: Center(
                child: RichText(
                  // 400 is not wide enough for this string. The part after the
                  // whitespace is going to be broken into a 2nd line.
                  text: const TextSpan(text: 'fwefwefwewfefewfwe fwfwfwefweabcdefghijklmnopqrstuvwxyz'),
                  textWidthBasis: TextWidthBasis.longestLine,
                  textDirection: TextDirection.rtl,
                ),
              ),
            ),
          ),
        );

      expect(find.byType(RichText), paints..something((Symbol method, List<dynamic> arguments) {
        if (method != #drawParagraph) {
          return false;
        }
        final ui.Paragraph paragraph = arguments[0] as ui.Paragraph;
        final Offset offset = arguments[1] as Offset;
        final List<ui.LineMetrics> lines = paragraph.computeLineMetrics();
        for (final ui.LineMetrics line in lines) {
          if (line.left + offset.dx + line.width >= 400) {
            throw 'line $line is greater than the max width constraints';
          }
        }
        return true;
      }));
    },
    skip: isBrowser, // https://github.com/flutter/flutter/issues/44020
  );

  testWidgets('Paragraph.getBoxesForRange returns nothing when selection range is zero length', (WidgetTester tester) async {
    final ui.ParagraphBuilder builder = ui.ParagraphBuilder(ui.ParagraphStyle());
    builder.addText('hello');
    final ui.Paragraph paragraph = builder.build();
    paragraph.layout(const ui.ParagraphConstraints(width: 1000));
    expect(paragraph.getBoxesForRange(2, 2), isEmpty);
    paragraph.dispose();
  });

  // Regression test for https://github.com/flutter/flutter/issues/65818
  testWidgets('WidgetSpans with no semantic information are elided from semantics', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    final TapGestureRecognizer recognizer = TapGestureRecognizer();
    addTearDown(recognizer.dispose);
    // Without the fix for this bug the pump widget will throw a RangeError.
    await tester.pumpWidget(
      RichText(
        textDirection: TextDirection.ltr,
        text: TextSpan(children: <InlineSpan>[
          const WidgetSpan(child: SizedBox.shrink()),
          TextSpan(
            text: 'HELLO',
            style: const TextStyle(color: Colors.black),
            recognizer: recognizer..onTap = () {},
          ),
        ]),
      ),
    );

    expect(semantics, hasSemantics(TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics(
          id: 1,
          rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 600.0),
          transform: Matrix4(
            3.0,0.0,0.0,0.0,
            0.0,3.0,0.0,0.0,
            0.0,0.0,1.0,0.0,
            0.0,0.0,0.0,1.0,
          ),
          children: <TestSemantics>[
            TestSemantics(
              rect: const Rect.fromLTRB(-4.0, -4.0, 74.0, 18.0),
              id: 2,
              label: 'HELLO',
              actions: <SemanticsAction>[
                SemanticsAction.tap,
              ],
              flags: <SemanticsFlag>[
                SemanticsFlag.isLink,
              ],
            ),
          ],
        ),
      ],
    )));
    semantics.dispose();
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/87877

  // Regression test for https://github.com/flutter/flutter/issues/69787
  testWidgets('WidgetSpans with no semantic information are elided from semantics - case 2', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    final TapGestureRecognizer recognizer = TapGestureRecognizer();
    addTearDown(recognizer.dispose);

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: RichText(
          text: TextSpan(children: <InlineSpan>[
            const WidgetSpan(child: SizedBox.shrink()),
            const WidgetSpan(child: Text('included')),
            TextSpan(
              text: 'HELLO',
              style: const TextStyle(color: Colors.black),
              recognizer: recognizer..onTap = () {},
            ),
            const WidgetSpan(child: Text('included2')),
          ]),
        ),
      ),
    );

    expect(
      semantics,
      hasSemantics(
        TestSemantics.root(
          children: <TestSemantics>[
            TestSemantics(
              children: <TestSemantics>[
                TestSemantics(label: 'included'),
                TestSemantics(
                  label: 'HELLO',
                  actions: <SemanticsAction>[
                    SemanticsAction.tap,
                  ],
                  flags: <SemanticsFlag>[
                    SemanticsFlag.isLink,
                  ],
                ),
                TestSemantics(label: 'included2'),
              ],
            ),
          ],
        ),
        ignoreId: true,
        ignoreRect: true,
        ignoreTransform: true,
      ),
    );
    semantics.dispose();
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/87877

  // Regression test for https://github.com/flutter/flutter/issues/69787
  testWidgets('WidgetSpans with no semantic information are elided from semantics - case 3', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    final TapGestureRecognizer recognizer = TapGestureRecognizer();
    addTearDown(recognizer.dispose);

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: RichText(
          text: TextSpan(children: <InlineSpan>[
            const WidgetSpan(child: SizedBox.shrink()),
            WidgetSpan(
              child: Row(
                children: <Widget>[
                  Semantics(
                    container: true,
                    child: const Text('foo'),
                  ),
                  Semantics(
                    container: true,
                    child: const Text('bar'),
                  ),
                ],
              ),
            ),
            TextSpan(
              text: 'HELLO',
              style: const TextStyle(color: Colors.black),
              recognizer: recognizer..onTap = () {},
            ),
          ]),
        ),
      ),
    );

    expect(
      semantics,
      hasSemantics(
        TestSemantics.root(
          children: <TestSemantics>[
            TestSemantics(
              children: <TestSemantics>[
                TestSemantics(label: 'foo'),
                TestSemantics(label: 'bar'),
                TestSemantics(
                  label: 'HELLO',
                  actions: <SemanticsAction>[
                    SemanticsAction.tap,
                  ],
                  flags: <SemanticsFlag>[
                    SemanticsFlag.isLink,
                  ],
                ),
              ],
            ),
          ],
        ),
        ignoreId: true,
        ignoreRect: true,
        ignoreTransform: true,
      ),
    );
    semantics.dispose();
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/87877

  // Regression test for https://github.com/flutter/flutter/issues/69787
  testWidgets('WidgetSpans with no semantic information are elided from semantics - case 4', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    final TapGestureRecognizer recognizer = TapGestureRecognizer();
    addTearDown(recognizer.dispose);

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: ClipRect(
            child: Container(
              color: Colors.green,
              height: 100,
              width: 100,
              child: OverflowBox(
                alignment: Alignment.topLeft,
                maxWidth: double.infinity,
                child: RichText(
                  text: TextSpan(
                    children: <InlineSpan>[
                      const WidgetSpan(
                        child: Icon(
                          Icons.edit,
                          size: 16,
                          semanticLabel: 'not clipped',
                        ),
                      ),
                      TextSpan(
                        text: 'next WS is clipped',
                        recognizer: recognizer..onTap = () { },
                      ),
                      const WidgetSpan(
                        child: Icon(
                          Icons.edit,
                          size: 16,
                          semanticLabel: 'clipped',
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );

    expect(
      semantics,
      hasSemantics(
        TestSemantics.root(
          children: <TestSemantics>[
            TestSemantics(
              children: <TestSemantics>[
                TestSemantics(label: 'not clipped'),
                TestSemantics(
                  label: 'next WS is clipped',
                  flags: <SemanticsFlag>[SemanticsFlag.isLink],
                  actions: <SemanticsAction>[SemanticsAction.tap],
                ),
              ],
            ),
          ],
        ),
        ignoreId: true,
        ignoreRect: true,
        ignoreTransform: true,
      ),
    );
    semantics.dispose();
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/87877

  testWidgets('RenderParagraph intrinsic width', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: SizedBox(
            height: 100,
            child: IntrinsicWidth(
              child: RichText(
                text: const TextSpan(
                  style: TextStyle(fontSize: 16, height: 1),
                  children: <InlineSpan>[
                    TextSpan(text: 'S '),
                    WidgetSpan(
                      alignment: PlaceholderAlignment.top,
                      child: Wrap(
                        direction: Axis.vertical,
                        children: <Widget>[
                          SizedBox(width: 200, height: 100),
                          SizedBox(width: 200, height: 30),
                        ],
                      ),
                    ),
                    TextSpan(text: ' E'),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );

    expect(tester.getSize(find.byType(RichText)).width, 200 + 4 * 16.0);
    final RenderParagraph paragraph = tester.renderObject<RenderParagraph>(find.byType(RichText));
    // The inline spans are rendered on one (horizontal) line, the sum of the widths is the max intrinsic width.
    expect(paragraph.getMaxIntrinsicWidth(0.0), 200 + 4 * 16.0);
    // The inline spans are rendered in one vertical run, the widest one determines the min intrinsic width.
    expect(paragraph.getMinIntrinsicWidth(0.0), 200);
  });

  testWidgets('can compute intrinsic width and height for widget span with text scaling', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/59316
    const Key textKey = Key('RichText');
    Widget textWithNestedInlineSpans({ required double textScaleFactor, required double screenWidth }) {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: OverflowBox(
            alignment: Alignment.topLeft,
            maxWidth: screenWidth,
            child: RichText(
              key: textKey,
              textScaleFactor: textScaleFactor,
              text: const TextSpan(children: <InlineSpan>[
                WidgetSpan(child: Text('one two')),
              ]),
            ),
          ),
        ),
      );
    }
    // The render object is going to be reused across widget tree rebuilds.
    late final RenderParagraph outerParagraph = tester.renderObject(find.byKey(textKey));

    await tester.pumpWidget(textWithNestedInlineSpans(textScaleFactor: 1.0, screenWidth: 100.0));
    expect(
      outerParagraph.getMaxIntrinsicHeight(100.0),
      14.0,
      reason: 'singleLineHeight = 14.0',
    );

    await tester.pumpWidget(textWithNestedInlineSpans(textScaleFactor: 2.0, screenWidth: 100.0));
    expect(
      outerParagraph.getMinIntrinsicHeight(100.0),
      14.0 * 2.0 * 2,
      reason: 'intrinsicHeight = singleLineHeight * textScaleFactor * two lines.',
    );

    await tester.pumpWidget(textWithNestedInlineSpans(textScaleFactor: 1.0, screenWidth: 1000.0));
    expect(
      outerParagraph.getMaxIntrinsicWidth(1000.0),
      14.0 * 7,
      reason: 'intrinsic width = 14.0 * 7',
    );

    await tester.pumpWidget(textWithNestedInlineSpans(textScaleFactor: 2.0, screenWidth: 1000.0));
    expect(
      outerParagraph.getMaxIntrinsicWidth(1000.0),
      14.0 * 2.0 * 7,
      reason: 'intrinsic width = glyph advance * textScaleFactor * num of glyphs',
    );
  });

  testWidgets('Text uses TextStyle.overflow', (WidgetTester tester) async {
    const TextOverflow overflow = TextOverflow.fade;

    await tester.pumpWidget(const Text(
      'Hello World',
      textDirection: TextDirection.ltr,
      style: TextStyle(overflow: overflow),
    ));

    final RichText richText = tester.firstWidget(find.byType(RichText));

    expect(richText.overflow, overflow);
    expect(richText.text.style!.overflow, overflow);
  });

  testWidgets(
    'Text can be hit-tested without layout or paint being called in a frame',
    (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/85108.
      await tester.pumpWidget(
        const Opacity(
          opacity: 1.0,
          child: Text(
            'Hello World',
            textDirection: TextDirection.ltr,
            style: TextStyle(color: Color(0xFF123456)),
          ),
        ),
      );

      // The color changed and the opacity is set to 0:
      //  * 0 opacity will prevent RenderParagraph.paint from being called.
      //  * Only changing the color will prevent RenderParagraph.performLayout
      //    from being called.
      //  The underlying TextPainter should not evict its layout cache in this
      //  case, for hit-testing.
      await tester.pumpWidget(
        const Opacity(
          opacity: 0.0,
          child: Text(
            'Hello World',
            textDirection: TextDirection.ltr,
            style: TextStyle(color: Color(0x87654321)),
          ),
        ),
      );

      await tester.tap(find.text('Hello World'));
      expect(tester.takeException(), isNull);
  });

  testWidgets('Mouse hovering over selectable Text uses SystemMouseCursor.text', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(
      home: SelectionArea(
        child: Text('Flutter'),
      ),
    ));

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
    await gesture.addPointer(location: tester.getCenter(find.byType(Text)));

    await tester.pump();

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

  testWidgets('Mouse hovering over selectable Text uses default selection style mouse cursor', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      home: SelectionArea(
        child: DefaultSelectionStyle.merge(
          mouseCursor: SystemMouseCursors.click,
          child: const Text('Flutter'),
        ),
      ),
    ));

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
    await gesture.addPointer(location: tester.getCenter(find.byType(Text)));

    await tester.pump();

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

Future<void> _pumpTextWidget({
  required WidgetTester tester,
  required String text,
  required TextOverflow overflow,
}) {
  return tester.pumpWidget(
    Directionality(
      textDirection: TextDirection.ltr,
      child: Center(
        child: SizedBox(
          width: 50.0,
          height: 50.0,
          child: Text(
            text,
            overflow: overflow,
          ),
        ),
      ),
    ),
  );
}
