text_field_splash_test.dart 5.1 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
import 'package:flutter/gestures.dart' show kPressTimeout;
6 7 8
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

9 10
bool confirmCalled = false;
bool cancelCalled = false;
11 12 13

class TestInkSplash extends InkSplash {
  TestInkSplash({
14 15 16 17 18 19 20 21 22 23 24 25
    required super.controller,
    required super.referenceBox,
    super.position,
    required super.color,
    super.containedInkWell,
    super.rectCallback,
    super.borderRadius,
    super.customBorder,
    super.radius,
    super.onRemoved,
    required super.textDirection,
  });
26 27 28

  @override
  void confirm() {
29
    confirmCalled = true;
30 31 32 33 34
    super.confirm();
  }

  @override
  void cancel() {
35
    cancelCalled = true;
36 37 38 39 40 41 42 43 44
    super.cancel();
  }
}

class TestInkSplashFactory extends InteractiveInkFeatureFactory {
  const TestInkSplashFactory();

  @override
  InteractiveInkFeature create({
45 46 47 48
    required MaterialInkController controller,
    required RenderBox referenceBox,
    Offset? position,
    required Color color,
49
    bool containedInkWell = false,
50 51 52 53 54 55
    RectCallback? rectCallback,
    BorderRadius? borderRadius,
    ShapeBorder? customBorder,
    double? radius,
    VoidCallback? onRemoved,
    required TextDirection textDirection,
56
  }) {
57
    return TestInkSplash(
58 59 60 61 62 63 64
      controller: controller,
      referenceBox: referenceBox,
      position: position,
      color: color,
      containedInkWell: containedInkWell,
      rectCallback: rectCallback,
      borderRadius: borderRadius,
65
      customBorder: customBorder,
66 67
      radius: radius,
      onRemoved: onRemoved,
68
      textDirection: textDirection,
69 70 71 72 73
    );
  }
}

void main() {
74 75 76 77 78 79
  setUp(() {
    confirmCalled = false;
    cancelCalled = false;
  });

  testWidgets('Tapping should never cause a splash', (WidgetTester tester) async {
80 81
    final Key textField1 = UniqueKey();
    final Key textField2 = UniqueKey();
82 83

    await tester.pumpWidget(
84 85 86 87 88
      MaterialApp(
        home: Theme(
          data: ThemeData.light().copyWith(splashFactory: const TestInkSplashFactory()),
          child: Material(
            child: Container(
89
              alignment: Alignment.topLeft,
90
              child: Column(
91
                children: <Widget>[
92
                  TextField(
93 94 95 96 97
                    key: textField1,
                    decoration: const InputDecoration(
                      labelText: 'label',
                    ),
                  ),
98
                  TextField(
99 100 101 102 103 104 105 106 107 108
                    key: textField2,
                    decoration: const InputDecoration(
                      labelText: 'label',
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
109
      ),
110 111 112
    );

    await tester.tap(find.byKey(textField1));
113
    await tester.pumpAndSettle();
114 115
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
116 117

    await tester.tap(find.byKey(textField1));
118
    await tester.pumpAndSettle();
119 120
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
121 122

    await tester.tap(find.byKey(textField2));
123
    await tester.pumpAndSettle();
124 125
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
126 127

    await tester.tapAt(tester.getTopLeft(find.byKey(textField1)));
128
    await tester.pumpAndSettle();
129 130
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
131 132

    await tester.tap(find.byKey(textField2));
133
    await tester.pumpAndSettle();
134 135
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
136 137
  });

138
  testWidgets('Splash should never be created or canceled', (WidgetTester tester) async {
139
    await tester.pumpWidget(
140 141 142 143 144
      MaterialApp(
        home: Theme(
          data: ThemeData.light().copyWith(splashFactory: const TestInkSplashFactory()),
          child: Material(
            child: ListView(
145 146
              children: <Widget>[
                const TextField(
147
                  decoration: InputDecoration(
148 149 150 151
                    labelText: 'label1',
                  ),
                ),
                const TextField(
152
                  decoration: InputDecoration(
153 154 155
                    labelText: 'label2',
                  ),
                ),
156
                Container(
157 158 159 160 161 162 163
                  height: 1000.0,
                  color: const Color(0xFF00FF00),
                ),
              ],
            ),
          ),
        ),
164
      ),
165 166
    );

167
    // If there were a splash, this would cancel the splash.
168
    final TestGesture gesture1 = await tester.startGesture(tester.getCenter(find.text('label1')));
169 170 171

    await tester.pump(kPressTimeout);

172 173
    await gesture1.moveTo(const Offset(400.0, 300.0));
    await gesture1.up();
174 175
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
176

177
    // Pointer is dragged upwards causing a scroll, splash would be canceled.
178
    final TestGesture gesture2 = await tester.startGesture(tester.getCenter(find.text('label2')));
179 180
    await tester.pump(kPressTimeout);
    await gesture2.moveBy(const Offset(0.0, -200.0));
181
    await gesture2.up();
182 183
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
184 185
  });
}