text_magnifier.0_test.dart 3.87 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_api_samples/widgets/text_magnifier/text_magnifier.0.dart'
    as example;
import 'package:flutter_test/flutter_test.dart';

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

RenderEditable _findRenderEditable<T extends State<StatefulWidget>>(WidgetTester tester) {
  return (tester.state(find.byType(TextField))
          as TextSelectionGestureDetectorBuilderDelegate)
      .editableTextKey
      .currentState!
      .renderEditable;
}

Offset _textOffsetToPosition<T extends State<StatefulWidget>>(WidgetTester tester, int offset) {
  final RenderEditable renderEditable = _findRenderEditable(tester);

  final List<TextSelectionPoint> endpoints = renderEditable
      .getEndpointsForSelection(
        TextSelection.collapsed(offset: offset),
      )
      .map<TextSelectionPoint>((TextSelectionPoint point) => TextSelectionPoint(
            renderEditable.localToGlobal(point.point),
            point.direction,
          ))
      .toList();

  return endpoints[0].point + const Offset(0.0, -2.0);
}

void main() {
Lioness100's avatar
Lioness100 committed
46
  const Duration durationBetweenActions = Duration(milliseconds: 20);
47 48 49 50 51 52 53
  const String defaultText = 'I am a magnifier, fear me!';

  Future<void> showMagnifier(WidgetTester tester, String characterToTapOn) async {
    final Offset tapOffset = _textOffsetToPosition(tester, defaultText.indexOf(characterToTapOn));

    // Double tap 'Magnifier' word to show the selection handles.
    final TestGesture testGesture = await tester.startGesture(tapOffset);
Lioness100's avatar
Lioness100 committed
54
    await tester.pump(durationBetweenActions);
55
    await testGesture.up();
Lioness100's avatar
Lioness100 committed
56
    await tester.pump(durationBetweenActions);
57
    await testGesture.down(tapOffset);
Lioness100's avatar
Lioness100 committed
58
    await tester.pump(durationBetweenActions);
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
    await testGesture.up();
    await tester.pumpAndSettle();

    final TextSelection selection = tester
        .firstWidget<TextField>(find.byType(TextField))
        .controller!
        .selection;

    final RenderEditable renderEditable = _findRenderEditable(tester);
    final List<TextSelectionPoint> endpoints = _globalize(
      renderEditable.getEndpointsForSelection(selection),
      renderEditable,
    );

    final Offset handlePos = endpoints.last.point + const Offset(10.0, 10.0);

    final TestGesture gesture = await tester.startGesture(handlePos);

    await gesture.moveTo(
      _textOffsetToPosition(
        tester,
        defaultText.length - 2,
      ),
    );
    await tester.pump();
  }

  testWidgets('should show custom magnifier on drag', (WidgetTester tester) async {
    await tester.pumpWidget(const example.MyApp(text: defaultText));

    await showMagnifier(tester, 'e');
    expect(find.byType(example.CustomMagnifier), findsOneWidget);

    await expectLater(
      find.byType(example.MyApp),
      matchesGoldenFile('text_magnifier.0_test.png'),
    );
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.android }));


  for (final TextDirection textDirection in TextDirection.values) {
    testWidgets('should show custom magnifier in $textDirection', (WidgetTester tester) async {
      final String text = textDirection == TextDirection.rtl ? 'أثارت زر' : defaultText;
      final String textToTapOn = textDirection == TextDirection.rtl ? 'ت' : 'e';

      await tester.pumpWidget(example.MyApp(textDirection: textDirection, text: text));

      await showMagnifier(tester, textToTapOn);

      expect(find.byType(example.CustomMagnifier), findsOneWidget);
    });
  }
}