dismissible_test.dart 26 KB
Newer Older
Hixie's avatar
Hixie committed
1 2 3 4
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
Ian Hickson's avatar
Ian Hickson committed
7
import 'package:flutter_test/flutter_test.dart';
8

9
const double itemExtent = 100.0;
10
Axis scrollDirection = Axis.vertical;
11
DismissDirection dismissDirection = DismissDirection.horizontal;
12
DismissDirection reportedDismissDirection;
13
List<int> dismissedItems = <int>[];
14
Widget background;
15
const double crossAxisEndOffset = 0.5;
16

17
Widget buildTest({ double startToEndThreshold, TextDirection textDirection = TextDirection.ltr }) {
Ian Hickson's avatar
Ian Hickson committed
18
  return new Directionality(
Ian Hickson's avatar
Ian Hickson committed
19
    textDirection: textDirection,
Ian Hickson's avatar
Ian Hickson committed
20 21 22 23 24 25 26 27 28 29 30 31 32 33
    child: new StatefulBuilder(
      builder: (BuildContext context, StateSetter setState) {
        Widget buildDismissibleItem(int item) {
          return new Dismissible(
            key: new ValueKey<int>(item),
            direction: dismissDirection,
            onDismissed: (DismissDirection direction) {
              setState(() {
                reportedDismissDirection = direction;
                expect(dismissedItems.contains(item), isFalse);
                dismissedItems.add(item);
              });
            },
            onResize: () {
34
              expect(dismissedItems.contains(item), isFalse);
Ian Hickson's avatar
Ian Hickson committed
35 36 37 38 39
            },
            background: background,
            dismissThresholds: startToEndThreshold == null
                ? <DismissDirection, double>{}
                : <DismissDirection, double>{DismissDirection.startToEnd: startToEndThreshold},
40
            crossAxisEndOffset: crossAxisEndOffset,
Ian Hickson's avatar
Ian Hickson committed
41 42 43 44 45 46 47 48
            child: new Container(
              width: itemExtent,
              height: itemExtent,
              child: new Text(item.toString()),
            ),
          );
        }

Ian Hickson's avatar
Ian Hickson committed
49 50 51 52 53 54 55 56
        return new Container(
          padding: const EdgeInsets.all(10.0),
          child: new ListView(
            scrollDirection: scrollDirection,
            itemExtent: itemExtent,
            children: <int>[0, 1, 2, 3, 4]
              .where((int i) => !dismissedItems.contains(i))
              .map(buildDismissibleItem).toList(),
57 58
          ),
        );
Ian Hickson's avatar
Ian Hickson committed
59 60
      },
    ),
61 62 63
  );
}

64
typedef Future<Null> DismissMethod(WidgetTester tester, Finder finder, { @required AxisDirection gestureDirection });
65

Ian Hickson's avatar
Ian Hickson committed
66
Future<Null> dismissElement(WidgetTester tester, Finder finder, { @required AxisDirection gestureDirection }) async {
67 68
  Offset downLocation;
  Offset upLocation;
69
  switch (gestureDirection) {
Ian Hickson's avatar
Ian Hickson committed
70
    case AxisDirection.left:
71
      // getTopRight() returns a point that's just beyond itemWidget's right
72
      // edge and outside the Dismissible event listener's bounds.
73 74
      downLocation = tester.getTopRight(finder) + const Offset(-0.1, 0.0);
      upLocation = tester.getTopLeft(finder);
75
      break;
Ian Hickson's avatar
Ian Hickson committed
76
    case AxisDirection.right:
77
      // we do the same thing here to keep the test symmetric
78 79
      downLocation = tester.getTopLeft(finder) + const Offset(0.1, 0.0);
      upLocation = tester.getTopRight(finder);
80
      break;
Ian Hickson's avatar
Ian Hickson committed
81
    case AxisDirection.up:
82
      // getBottomLeft() returns a point that's just below itemWidget's bottom
83
      // edge and outside the Dismissible event listener's bounds.
84 85
      downLocation = tester.getBottomLeft(finder) + const Offset(0.0, -0.1);
      upLocation = tester.getTopLeft(finder);
86
      break;
Ian Hickson's avatar
Ian Hickson committed
87
    case AxisDirection.down:
88
      // again with doing the same here for symmetry
89 90
      downLocation = tester.getTopLeft(finder) + const Offset(0.1, 0.0);
      upLocation = tester.getBottomLeft(finder);
91
      break;
92
    default:
Ian Hickson's avatar
Ian Hickson committed
93
      fail('unsupported gestureDirection');
94 95
  }

Ian Hickson's avatar
Ian Hickson committed
96
  final TestGesture gesture = await tester.startGesture(downLocation);
97 98
  await gesture.moveTo(upLocation);
  await gesture.up();
Hixie's avatar
Hixie committed
99 100
}

101
Future<Null> flingElement(WidgetTester tester, Finder finder, { @required AxisDirection gestureDirection, double initialOffsetFactor = 0.0 }) async {
Ian Hickson's avatar
Ian Hickson committed
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
  Offset delta;
  switch (gestureDirection) {
    case AxisDirection.left:
      delta = const Offset(-300.0, 0.0);
      break;
    case AxisDirection.right:
      delta = const Offset(300.0, 0.0);
      break;
    case AxisDirection.up:
      delta = const Offset(0.0, -300.0);
      break;
    case AxisDirection.down:
      delta = const Offset(0.0, 300.0);
      break;
    default:
      fail('unsupported gestureDirection');
  }
  await tester.fling(finder, delta, 1000.0, initialOffset: delta * initialOffsetFactor);
}
Hixie's avatar
Hixie committed
121

Ian Hickson's avatar
Ian Hickson committed
122 123 124
Future<Null> flingElementFromZero(WidgetTester tester, Finder finder, { @required AxisDirection gestureDirection }) async {
  // This is a special case where we drag in one direction, then fling back so
  // that at the point of release, we're at exactly the point at which we
Josh Soref's avatar
Josh Soref committed
125
  // started, but with velocity. This is needed to check a boundary condition
Ian Hickson's avatar
Ian Hickson committed
126 127 128 129 130 131
  // in the flinging behavior.
  await flingElement(tester, finder, gestureDirection: gestureDirection, initialOffsetFactor: -1.0);
}

Future<Null> dismissItem(WidgetTester tester, int item, {
  @required AxisDirection gestureDirection,
132
  DismissMethod mechanism = dismissElement,
Ian Hickson's avatar
Ian Hickson committed
133 134
}) async {
  assert(gestureDirection != null);
135
  final Finder itemFinder = find.text(item.toString());
136
  expect(itemFinder, findsOneWidget);
Hixie's avatar
Hixie committed
137

Ian Hickson's avatar
Ian Hickson committed
138
  await mechanism(tester, itemFinder, gestureDirection: gestureDirection);
139

140 141 142 143 144
  await tester.pump(); // start the slide
  await tester.pump(const Duration(seconds: 1)); // finish the slide and start shrinking...
  await tester.pump(); // first frame of shrinking animation
  await tester.pump(const Duration(seconds: 1)); // finish the shrinking and call the callback...
  await tester.pump(); // rebuild after the callback removes the entry
145 146
}

147 148
Future<Null> checkFlingItemBeforeMovementEnd(WidgetTester tester, int item, {
  @required AxisDirection gestureDirection,
149
  DismissMethod mechanism = rollbackElement
150 151 152 153 154 155 156 157 158 159 160 161 162
}) async {
  assert(gestureDirection != null);
  final Finder itemFinder = find.text(item.toString());
  expect(itemFinder, findsOneWidget);

  await mechanism(tester, itemFinder, gestureDirection: gestureDirection);

  await tester.pump(); // start the slide
  await tester.pump(const Duration(milliseconds: 100));
}

Future<Null> checkFlingItemAfterMovement(WidgetTester tester, int item, {
  @required AxisDirection gestureDirection,
163
  DismissMethod mechanism = rollbackElement
164 165 166 167 168 169 170 171 172 173 174
}) async {
  assert(gestureDirection != null);
  final Finder itemFinder = find.text(item.toString());
  expect(itemFinder, findsOneWidget);

  await mechanism(tester, itemFinder, gestureDirection: gestureDirection);

  await tester.pump(); // start the slide
  await tester.pump(const Duration(milliseconds: 300));
}

175
Future<Null> rollbackElement(WidgetTester tester, Finder finder, { @required AxisDirection gestureDirection, double initialOffsetFactor = 0.0 }) async {
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
  Offset delta;
  switch (gestureDirection) {
    case AxisDirection.left:
      delta = const Offset(-30.0, 0.0);
      break;
    case AxisDirection.right:
      delta = const Offset(30.0, 0.0);
      break;
    case AxisDirection.up:
      delta = const Offset(0.0, -30.0);
      break;
    case AxisDirection.down:
      delta = const Offset(0.0, 30.0);
      break;
  }
  await tester.fling(finder, delta, 1000.0, initialOffset: delta * initialOffsetFactor);
}

194
class Test1215DismissibleWidget extends StatelessWidget {
195
  const Test1215DismissibleWidget(this.text);
196

Hixie's avatar
Hixie committed
197
  final String text;
198 199

  @override
Hixie's avatar
Hixie committed
200
  Widget build(BuildContext context) {
201
    return new Dismissible(
202
      key: new ObjectKey(text),
Hixie's avatar
Hixie committed
203 204
      child: new AspectRatio(
        aspectRatio: 1.0,
205
        child: new Text(text),
206
      ),
Hixie's avatar
Hixie committed
207 208 209 210
    );
  }
}

211
void main() {
212 213 214 215 216
  setUp(() {
    dismissedItems = <int>[];
    background = null;
  });

217
  testWidgets('Horizontal drag triggers dismiss scrollDirection=vertical', (WidgetTester tester) async {
218 219
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.horizontal;
220

221
    await tester.pumpWidget(buildTest());
222
    expect(dismissedItems, isEmpty);
223

Ian Hickson's avatar
Ian Hickson committed
224
    await dismissItem(tester, 0, gestureDirection: AxisDirection.right);
225
    expect(find.text('0'), findsNothing);
226
    expect(dismissedItems, equals(<int>[0]));
227
    expect(reportedDismissDirection, DismissDirection.startToEnd);
228

Ian Hickson's avatar
Ian Hickson committed
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
    await dismissItem(tester, 1, gestureDirection: AxisDirection.left);
    expect(find.text('1'), findsNothing);
    expect(dismissedItems, equals(<int>[0, 1]));
    expect(reportedDismissDirection, DismissDirection.endToStart);
  });

  testWidgets('Horizontal fling triggers dismiss scrollDirection=vertical', (WidgetTester tester) async {
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.horizontal;

    await tester.pumpWidget(buildTest());
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, gestureDirection: AxisDirection.right, mechanism: flingElement);
    expect(find.text('0'), findsNothing);
    expect(dismissedItems, equals(<int>[0]));
    expect(reportedDismissDirection, DismissDirection.startToEnd);

    await dismissItem(tester, 1, gestureDirection: AxisDirection.left, mechanism: flingElement);
    expect(find.text('1'), findsNothing);
    expect(dismissedItems, equals(<int>[0, 1]));
    expect(reportedDismissDirection, DismissDirection.endToStart);
  });

  testWidgets('Horizontal fling does not trigger at zero offset, but does otherwise', (WidgetTester tester) async {
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.horizontal;

    await tester.pumpWidget(buildTest(startToEndThreshold: 0.95));
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, gestureDirection: AxisDirection.right, mechanism: flingElementFromZero);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, equals(<int>[]));

    await dismissItem(tester, 0, gestureDirection: AxisDirection.left, mechanism: flingElementFromZero);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, equals(<int>[]));

    await dismissItem(tester, 0, gestureDirection: AxisDirection.right, mechanism: flingElement);
    expect(find.text('0'), findsNothing);
    expect(dismissedItems, equals(<int>[0]));
    expect(reportedDismissDirection, DismissDirection.startToEnd);

    await dismissItem(tester, 1, gestureDirection: AxisDirection.left, mechanism: flingElement);
274
    expect(find.text('1'), findsNothing);
275
    expect(dismissedItems, equals(<int>[0, 1]));
276
    expect(reportedDismissDirection, DismissDirection.endToStart);
277 278
  });

279
  testWidgets('Vertical drag triggers dismiss scrollDirection=horizontal', (WidgetTester tester) async {
280 281
    scrollDirection = Axis.horizontal;
    dismissDirection = DismissDirection.vertical;
282

283
    await tester.pumpWidget(buildTest());
284
    expect(dismissedItems, isEmpty);
285

Ian Hickson's avatar
Ian Hickson committed
286
    await dismissItem(tester, 0, gestureDirection: AxisDirection.up);
287
    expect(find.text('0'), findsNothing);
288
    expect(dismissedItems, equals(<int>[0]));
289
    expect(reportedDismissDirection, DismissDirection.up);
290

Ian Hickson's avatar
Ian Hickson committed
291
    await dismissItem(tester, 1, gestureDirection: AxisDirection.down);
292
    expect(find.text('1'), findsNothing);
293
    expect(dismissedItems, equals(<int>[0, 1]));
294
    expect(reportedDismissDirection, DismissDirection.down);
295 296
  });

Ian Hickson's avatar
Ian Hickson committed
297
  testWidgets('drag-left with DismissDirection.endToStart triggers dismiss (LTR)', (WidgetTester tester) async {
298 299
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.endToStart;
300

301
    await tester.pumpWidget(buildTest());
302
    expect(dismissedItems, isEmpty);
303

Ian Hickson's avatar
Ian Hickson committed
304
    await dismissItem(tester, 0, gestureDirection: AxisDirection.right);
305 306
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);
Ian Hickson's avatar
Ian Hickson committed
307
    await dismissItem(tester, 1, gestureDirection: AxisDirection.right);
308

Ian Hickson's avatar
Ian Hickson committed
309
    await dismissItem(tester, 0, gestureDirection: AxisDirection.left);
310
    expect(find.text('0'), findsNothing);
311
    expect(dismissedItems, equals(<int>[0]));
Ian Hickson's avatar
Ian Hickson committed
312
    await dismissItem(tester, 1, gestureDirection: AxisDirection.left);
313 314
  });

Ian Hickson's avatar
Ian Hickson committed
315
  testWidgets('drag-right with DismissDirection.startToEnd triggers dismiss (LTR)', (WidgetTester tester) async {
316 317
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.startToEnd;
318

319
    await tester.pumpWidget(buildTest());
320
    expect(dismissedItems, isEmpty);
321

Ian Hickson's avatar
Ian Hickson committed
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
    await dismissItem(tester, 0, gestureDirection: AxisDirection.left);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, gestureDirection: AxisDirection.right);
    expect(find.text('0'), findsNothing);
    expect(dismissedItems, equals(<int>[0]));
  });

  testWidgets('drag-right with DismissDirection.endToStart triggers dismiss (RTL)', (WidgetTester tester) async {
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.endToStart;

    await tester.pumpWidget(buildTest(textDirection: TextDirection.rtl));
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, gestureDirection: AxisDirection.left);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, gestureDirection: AxisDirection.right);
    expect(find.text('0'), findsNothing);
    expect(dismissedItems, equals(<int>[0]));
  });

  testWidgets('drag-left with DismissDirection.startToEnd triggers dismiss (RTL)', (WidgetTester tester) async {
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.startToEnd;

    await tester.pumpWidget(buildTest(textDirection: TextDirection.rtl));
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, gestureDirection: AxisDirection.right);
355 356
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);
Ian Hickson's avatar
Ian Hickson committed
357
    await dismissItem(tester, 1, gestureDirection: AxisDirection.right);
358

Ian Hickson's avatar
Ian Hickson committed
359
    await dismissItem(tester, 0, gestureDirection: AxisDirection.left);
360
    expect(find.text('0'), findsNothing);
361
    expect(dismissedItems, equals(<int>[0]));
Ian Hickson's avatar
Ian Hickson committed
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
    await dismissItem(tester, 1, gestureDirection: AxisDirection.left);
  });

  testWidgets('fling-left with DismissDirection.endToStart triggers dismiss (LTR)', (WidgetTester tester) async {
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.endToStart;

    await tester.pumpWidget(buildTest());
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, gestureDirection: AxisDirection.right);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);
    await dismissItem(tester, 1, gestureDirection: AxisDirection.right);

    await dismissItem(tester, 0, gestureDirection: AxisDirection.left);
    expect(find.text('0'), findsNothing);
    expect(dismissedItems, equals(<int>[0]));
    await dismissItem(tester, 1, gestureDirection: AxisDirection.left);
  });

  testWidgets('fling-right with DismissDirection.startToEnd triggers dismiss (LTR)', (WidgetTester tester) async {
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.startToEnd;

    await tester.pumpWidget(buildTest());
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.left);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.right);
    expect(find.text('0'), findsNothing);
    expect(dismissedItems, equals(<int>[0]));
  });

  testWidgets('fling-right with DismissDirection.endToStart triggers dismiss (RTL)', (WidgetTester tester) async {
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.endToStart;

    await tester.pumpWidget(buildTest(textDirection: TextDirection.rtl));
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.left);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.right);
    expect(find.text('0'), findsNothing);
    expect(dismissedItems, equals(<int>[0]));
  });

  testWidgets('fling-left with DismissDirection.startToEnd triggers dismiss (RTL)', (WidgetTester tester) async {
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.startToEnd;

    await tester.pumpWidget(buildTest(textDirection: TextDirection.rtl));
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.right);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);
    await dismissItem(tester, 1, mechanism: flingElement, gestureDirection: AxisDirection.right);

    await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.left);
    expect(find.text('0'), findsNothing);
    expect(dismissedItems, equals(<int>[0]));
    await dismissItem(tester, 1, mechanism: flingElement, gestureDirection: AxisDirection.left);
431 432
  });

433
  testWidgets('drag-up with DismissDirection.up triggers dismiss', (WidgetTester tester) async {
434 435
    scrollDirection = Axis.horizontal;
    dismissDirection = DismissDirection.up;
436

437
    await tester.pumpWidget(buildTest());
438
    expect(dismissedItems, isEmpty);
439

Ian Hickson's avatar
Ian Hickson committed
440
    await dismissItem(tester, 0, gestureDirection: AxisDirection.down);
441 442
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);
443

Ian Hickson's avatar
Ian Hickson committed
444
    await dismissItem(tester, 0, gestureDirection: AxisDirection.up);
445
    expect(find.text('0'), findsNothing);
446
    expect(dismissedItems, equals(<int>[0]));
447 448
  });

449
  testWidgets('drag-down with DismissDirection.down triggers dismiss', (WidgetTester tester) async {
450 451
    scrollDirection = Axis.horizontal;
    dismissDirection = DismissDirection.down;
452

453
    await tester.pumpWidget(buildTest());
454
    expect(dismissedItems, isEmpty);
455

Ian Hickson's avatar
Ian Hickson committed
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
    await dismissItem(tester, 0, gestureDirection: AxisDirection.up);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, gestureDirection: AxisDirection.down);
    expect(find.text('0'), findsNothing);
    expect(dismissedItems, equals(<int>[0]));
  });

  testWidgets('fling-up with DismissDirection.up triggers dismiss', (WidgetTester tester) async {
    scrollDirection = Axis.horizontal;
    dismissDirection = DismissDirection.up;

    await tester.pumpWidget(buildTest());
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.down);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.up);
    expect(find.text('0'), findsNothing);
    expect(dismissedItems, equals(<int>[0]));
  });

  testWidgets('fling-down with DismissDirection.down triggers dismiss', (WidgetTester tester) async {
    scrollDirection = Axis.horizontal;
    dismissDirection = DismissDirection.down;

    await tester.pumpWidget(buildTest());
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.up);
489 490
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);
491

Ian Hickson's avatar
Ian Hickson committed
492
    await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.down);
493
    expect(find.text('0'), findsNothing);
494
    expect(dismissedItems, equals(<int>[0]));
495
  });
496

497
  testWidgets('drag-left has no effect on dismissible with a high dismiss threshold', (WidgetTester tester) async {
498 499 500 501 502 503
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.horizontal;

    await tester.pumpWidget(buildTest(startToEndThreshold: 1.0));
    expect(dismissedItems, isEmpty);

Ian Hickson's avatar
Ian Hickson committed
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
    await dismissItem(tester, 0, gestureDirection: AxisDirection.right);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, gestureDirection: AxisDirection.left);
    expect(find.text('0'), findsNothing);
    expect(dismissedItems, equals(<int>[0]));
  });

  testWidgets('fling-left has no effect on dismissible with a high dismiss threshold', (WidgetTester tester) async {
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.horizontal;

    await tester.pumpWidget(buildTest(startToEndThreshold: 1.0));
    expect(dismissedItems, isEmpty);

    await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.right);
521 522 523
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);

Ian Hickson's avatar
Ian Hickson committed
524
    await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.left);
525 526 527 528
    expect(find.text('0'), findsNothing);
    expect(dismissedItems, equals(<int>[0]));
  });

529 530 531 532 533 534
  // This is a regression test for an fn2 bug where dragging a card caused an
  // assert "'!_disqualifiedFromEverAppearingAgain' is not true". The old URL
  // was https://github.com/domokit/sky_engine/issues/1068 but that issue is 404
  // now since we migrated to the new repo. The bug was fixed by
  // https://github.com/flutter/engine/pull/1134 at the time, and later made
  // irrelevant by fn3, but just in case...
535
  testWidgets('Verify that drag-move events do not assert', (WidgetTester tester) async {
536 537 538
    scrollDirection = Axis.horizontal;
    dismissDirection = DismissDirection.down;

539
    await tester.pumpWidget(buildTest());
540
    final Offset location = tester.getTopLeft(find.text('0'));
541
    const Offset offset = const Offset(0.0, 5.0);
542
    final TestGesture gesture = await tester.startGesture(location, pointer: 5);
543
    await gesture.moveBy(offset);
544
    await tester.pumpWidget(buildTest());
545
    await gesture.moveBy(offset);
546
    await tester.pumpWidget(buildTest());
547
    await gesture.moveBy(offset);
548
    await tester.pumpWidget(buildTest());
549
    await gesture.moveBy(offset);
550
    await tester.pumpWidget(buildTest());
551
    await gesture.up();
552
  });
Hixie's avatar
Hixie committed
553

554
  // This one is for a case where dismissing a widget above a previously
555
  // dismissed widget threw an exception, which was documented at the
556 557 558
  // now-obsolete URL https://github.com/flutter/engine/issues/1215 (the URL
  // died in the migration to the new repo). Don't copy this test; it doesn't
  // actually remove the dismissed widget, which is a violation of the
559
  // Dismissible contract. This is not an example of good practice.
560
  testWidgets('dismissing bottom then top (smoketest)', (WidgetTester tester) async {
Ian Hickson's avatar
Ian Hickson committed
561 562 563 564 565 566 567 568
    await tester.pumpWidget(
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new Center(
          child: new Container(
            width: 100.0,
            height: 1000.0,
            child: new Column(
569
              children: const <Widget>[
570 571
                const Test1215DismissibleWidget('1'),
                const Test1215DismissibleWidget('2'),
Ian Hickson's avatar
Ian Hickson committed
572 573 574
              ],
            ),
          ),
575 576
        ),
      ),
Ian Hickson's avatar
Ian Hickson committed
577
    );
578 579
    expect(find.text('1'), findsOneWidget);
    expect(find.text('2'), findsOneWidget);
Ian Hickson's avatar
Ian Hickson committed
580
    await dismissElement(tester, find.text('2'), gestureDirection: AxisDirection.right);
581
    await tester.pump(); // start the slide away
582
    await tester.pump(const Duration(seconds: 1)); // finish the slide away
583 584
    expect(find.text('1'), findsOneWidget);
    expect(find.text('2'), findsNothing);
Ian Hickson's avatar
Ian Hickson committed
585
    await dismissElement(tester, find.text('1'), gestureDirection: AxisDirection.right);
586
    await tester.pump(); // start the slide away
587
    await tester.pump(const Duration(seconds: 1)); // finish the slide away (at which point the child is no longer included in the tree)
588 589
    expect(find.text('1'), findsNothing);
    expect(find.text('2'), findsNothing);
Hixie's avatar
Hixie committed
590
  });
591

592
  testWidgets('Dismissible starts from the full size when collapsing', (WidgetTester tester) async {
593 594
    scrollDirection = Axis.vertical;
    dismissDirection = DismissDirection.horizontal;
595
    background = const Text('background');
596

597
    await tester.pumpWidget(buildTest());
598
    expect(dismissedItems, isEmpty);
599

600
    final Finder itemFinder = find.text('0');
601
    expect(itemFinder, findsOneWidget);
Ian Hickson's avatar
Ian Hickson committed
602
    await dismissElement(tester, itemFinder, gestureDirection: AxisDirection.right);
603
    await tester.pump();
604

605
    expect(find.text('background'), findsOneWidget); // The other four have been culled.
606
    final RenderBox backgroundBox = tester.firstRenderObject(find.text('background'));
607
    expect(backgroundBox.size.height, equals(100.0));
608
  });
609 610 611 612 613 614 615 616 617 618 619 620

  testWidgets('Checking fling item before movementDuration completes', (WidgetTester tester) async {
    await tester.pumpWidget(buildTest());
    expect(dismissedItems, isEmpty);

    await checkFlingItemBeforeMovementEnd(tester, 0, gestureDirection: AxisDirection.left, mechanism: flingElement);
    expect(find.text('0'), findsOneWidget);

    await checkFlingItemBeforeMovementEnd(tester, 1, gestureDirection: AxisDirection.right, mechanism: flingElement);
    expect(find.text('1'), findsOneWidget);
  });

621
  testWidgets('Checking fling item after movementDuration', (WidgetTester tester) async {
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
    await tester.pumpWidget(buildTest());
    expect(dismissedItems, isEmpty);

    await checkFlingItemAfterMovement(tester, 1, gestureDirection: AxisDirection.left, mechanism: flingElement);
    expect(find.text('1'), findsNothing);

    await checkFlingItemAfterMovement(tester, 0, gestureDirection: AxisDirection.right, mechanism: flingElement);
    expect(find.text('0'), findsNothing);
  });

  testWidgets('Horizontal fling less than threshold', (WidgetTester tester) async {
    scrollDirection = Axis.horizontal;
    await tester.pumpWidget(buildTest());
    expect(dismissedItems, isEmpty);

    await checkFlingItemAfterMovement(tester, 0, gestureDirection: AxisDirection.left, mechanism: rollbackElement);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);

    await checkFlingItemAfterMovement(tester, 1, gestureDirection: AxisDirection.right, mechanism: rollbackElement);
    expect(find.text('1'), findsOneWidget);
    expect(dismissedItems, isEmpty);
  });

  testWidgets('Vertical fling less than threshold', (WidgetTester tester) async {
    scrollDirection = Axis.vertical;
    await tester.pumpWidget(buildTest());
    expect(dismissedItems, isEmpty);

    await checkFlingItemAfterMovement(tester, 0, gestureDirection: AxisDirection.left, mechanism: rollbackElement);
    expect(find.text('0'), findsOneWidget);
    expect(dismissedItems, isEmpty);

    await checkFlingItemAfterMovement(tester, 1, gestureDirection: AxisDirection.right, mechanism: rollbackElement);
    expect(find.text('1'), findsOneWidget);
    expect(dismissedItems, isEmpty);
  });
659
}