text_field_splash_test.dart 5.53 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 9
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/rendering.dart';

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

class TestInkSplash extends InkSplash {
  TestInkSplash({
15 16 17 18
    required MaterialInkController controller,
    required RenderBox referenceBox,
    Offset? position,
    required Color color,
19
    bool containedInkWell = false,
20 21 22 23 24 25
    RectCallback? rectCallback,
    BorderRadius? borderRadius,
    ShapeBorder? customBorder,
    double? radius,
    VoidCallback? onRemoved,
    required TextDirection textDirection,
26 27 28 29 30 31 32 33
  }) : super(
    controller: controller,
    referenceBox: referenceBox,
    position: position,
    color: color,
    containedInkWell: containedInkWell,
    rectCallback: rectCallback,
    borderRadius: borderRadius,
34
    customBorder: customBorder,
35 36
    radius: radius,
    onRemoved: onRemoved,
37
    textDirection: textDirection,
38 39 40 41
  );

  @override
  void confirm() {
42
    confirmCalled = true;
43 44 45 46 47
    super.confirm();
  }

  @override
  void cancel() {
48
    cancelCalled = true;
49 50 51 52 53 54 55 56 57
    super.cancel();
  }
}

class TestInkSplashFactory extends InteractiveInkFeatureFactory {
  const TestInkSplashFactory();

  @override
  InteractiveInkFeature create({
58 59 60 61
    required MaterialInkController controller,
    required RenderBox referenceBox,
    Offset? position,
    required Color color,
62
    bool containedInkWell = false,
63 64 65 66 67 68
    RectCallback? rectCallback,
    BorderRadius? borderRadius,
    ShapeBorder? customBorder,
    double? radius,
    VoidCallback? onRemoved,
    required TextDirection textDirection,
69
  }) {
70
    return TestInkSplash(
71 72 73 74 75 76 77
      controller: controller,
      referenceBox: referenceBox,
      position: position,
      color: color,
      containedInkWell: containedInkWell,
      rectCallback: rectCallback,
      borderRadius: borderRadius,
78
      customBorder: customBorder,
79 80
      radius: radius,
      onRemoved: onRemoved,
81
      textDirection: textDirection,
82 83 84 85 86
    );
  }
}

void main() {
87 88 89 90 91 92
  setUp(() {
    confirmCalled = false;
    cancelCalled = false;
  });

  testWidgets('Tapping should never cause a splash', (WidgetTester tester) async {
93 94
    final Key textField1 = UniqueKey();
    final Key textField2 = UniqueKey();
95 96

    await tester.pumpWidget(
97 98 99 100 101
      MaterialApp(
        home: Theme(
          data: ThemeData.light().copyWith(splashFactory: const TestInkSplashFactory()),
          child: Material(
            child: Container(
102
              alignment: Alignment.topLeft,
103
              child: Column(
104
                children: <Widget>[
105
                  TextField(
106 107 108 109 110
                    key: textField1,
                    decoration: const InputDecoration(
                      labelText: 'label',
                    ),
                  ),
111
                  TextField(
112 113 114 115 116 117 118 119 120 121
                    key: textField2,
                    decoration: const InputDecoration(
                      labelText: 'label',
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
122
      ),
123 124 125
    );

    await tester.tap(find.byKey(textField1));
126
    await tester.pumpAndSettle();
127 128
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
129 130

    await tester.tap(find.byKey(textField1));
131
    await tester.pumpAndSettle();
132 133
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
134 135

    await tester.tap(find.byKey(textField2));
136
    await tester.pumpAndSettle();
137 138
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
139 140

    await tester.tapAt(tester.getTopLeft(find.byKey(textField1)));
141
    await tester.pumpAndSettle();
142 143
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
144 145

    await tester.tap(find.byKey(textField2));
146
    await tester.pumpAndSettle();
147 148
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
149 150
  });

151
  testWidgets('Splash should never be created or canceled', (WidgetTester tester) async {
152
    await tester.pumpWidget(
153 154 155 156 157
      MaterialApp(
        home: Theme(
          data: ThemeData.light().copyWith(splashFactory: const TestInkSplashFactory()),
          child: Material(
            child: ListView(
158 159
              children: <Widget>[
                const TextField(
160
                  decoration: InputDecoration(
161 162 163 164
                    labelText: 'label1',
                  ),
                ),
                const TextField(
165
                  decoration: InputDecoration(
166 167 168
                    labelText: 'label2',
                  ),
                ),
169
                Container(
170 171 172 173 174 175 176
                  height: 1000.0,
                  color: const Color(0xFF00FF00),
                ),
              ],
            ),
          ),
        ),
177
      ),
178 179
    );

180
    // If there were a splash, this would cancel the splash.
181
    final TestGesture gesture1 = await tester.startGesture(tester.getCenter(find.text('label1')));
182 183 184

    await tester.pump(kPressTimeout);

185 186
    await gesture1.moveTo(const Offset(400.0, 300.0));
    await gesture1.up();
187 188
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
189

190
    // Pointer is dragged upwards causing a scroll, splash would be canceled.
191
    final TestGesture gesture2 = await tester.startGesture(tester.getCenter(find.text('label2')));
192 193
    await tester.pump(kPressTimeout);
    await gesture2.moveBy(const Offset(0.0, -200.0));
194
    await gesture2.up();
195 196
    expect(confirmCalled, isFalse);
    expect(cancelCalled, isFalse);
197 198
  });
}