grid_view_test.dart 23.4 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 DragStartBehavior;
6 7 8
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
9

Adam Barth's avatar
Adam Barth committed
10
import '../rendering/mock_canvas.dart';
11
import '../rendering/rendering_tester.dart';
12 13 14
import 'states.dart';

void main() {
15
  testWidgets('Empty GridView', (WidgetTester tester) async {
16
    await tester.pumpWidget(
17
      Directionality(
18
        textDirection: TextDirection.ltr,
19
        child: GridView.count(
20
          dragStartBehavior: DragStartBehavior.down,
21 22 23 24 25
          crossAxisCount: 4,
          children: const <Widget>[],
        ),
      ),
    );
26 27
  });

28
  testWidgets('GridView.count control test', (WidgetTester tester) async {
29
    final List<String> log = <String>[];
30

31
    await tester.pumpWidget(
32
      Directionality(
33
        textDirection: TextDirection.ltr,
34
        child: GridView.count(
35
          dragStartBehavior: DragStartBehavior.down,
36
          crossAxisCount: 4,
37
          children: kStates.map<Widget>((String state) {
38
            return GestureDetector(
39
              dragStartBehavior: DragStartBehavior.down,
40 41 42
              onTap: () {
                log.add(state);
              },
43
              child: Container(
44
                color: const Color(0xFF0000FF),
45
                child: Text(state),
46 47 48 49 50 51
              ),
            );
          }).toList(),
        ),
      ),
    );
52 53 54 55 56 57 58 59 60 61 62 63

    expect(tester.getSize(find.text('Arkansas')), equals(const Size(200.0, 200.0)));

    for (int i = 0; i < 8; ++i) {
      await tester.tap(find.text(kStates[i]));
      expect(log, equals(<String>[kStates[i]]));
      log.clear();
    }

    expect(find.text(kStates[12]), findsNothing);
    expect(find.text('Nevada'), findsNothing);

64
    await tester.drag(find.text('Arkansas'), const Offset(0.0, -200.0));
65 66 67 68 69 70 71 72 73 74 75
    await tester.pump();

    for (int i = 0; i < 4; ++i)
      expect(find.text(kStates[i]), findsNothing);

    for (int i = 4; i < 12; ++i) {
      await tester.tap(find.text(kStates[i]));
      expect(log, equals(<String>[kStates[i]]));
      log.clear();
    }

76
    await tester.drag(find.text('Delaware'), const Offset(0.0, -4000.0));
77 78 79 80 81
    await tester.pump();

    expect(find.text('Alabama'), findsNothing);
    expect(find.text('Pennsylvania'), findsNothing);

82
    expect(tester.getCenter(find.text('Tennessee')), equals(const Offset(300.0, 100.0)));
83 84 85 86 87

    await tester.tap(find.text('Tennessee'));
    expect(log, equals(<String>['Tennessee']));
    log.clear();

88
    await tester.drag(find.text('Tennessee'), const Offset(0.0, 200.0));
89 90 91 92 93 94 95 96 97 98 99
    await tester.pump();

    await tester.tap(find.text('Tennessee'));
    expect(log, equals(<String>['Tennessee']));
    log.clear();

    await tester.tap(find.text('Pennsylvania'));
    expect(log, equals(<String>['Pennsylvania']));
    log.clear();
  });

100
  testWidgets('GridView.extent control test', (WidgetTester tester) async {
101
    final List<String> log = <String>[];
102

103
    await tester.pumpWidget(
104
      Directionality(
105
        textDirection: TextDirection.ltr,
106
        child: GridView.extent(
107
          dragStartBehavior: DragStartBehavior.down,
108
          maxCrossAxisExtent: 200.0,
109
          children: kStates.map<Widget>((String state) {
110
            return GestureDetector(
111
              dragStartBehavior: DragStartBehavior.down,
112 113 114
              onTap: () {
                log.add(state);
              },
115
              child: Container(
116
                color: const Color(0xFF0000FF),
117
                child: Text(state),
118 119 120 121 122 123
              ),
            );
          }).toList(),
        ),
      ),
    );
124 125 126 127 128 129 130 131 132 133 134

    expect(tester.getSize(find.text('Arkansas')), equals(const Size(200.0, 200.0)));

    for (int i = 0; i < 8; ++i) {
      await tester.tap(find.text(kStates[i]));
      expect(log, equals(<String>[kStates[i]]));
      log.clear();
    }

    expect(find.text('Nevada'), findsNothing);

135
    await tester.drag(find.text('Arkansas'), const Offset(0.0, -4000.0));
136 137 138 139
    await tester.pump();

    expect(find.text('Alabama'), findsNothing);

140
    expect(tester.getCenter(find.text('Tennessee')), equals(const Offset(300.0, 100.0)));
141 142 143 144 145 146

    await tester.tap(find.text('Tennessee'));
    expect(log, equals(<String>['Tennessee']));
    log.clear();
  });

147
  testWidgets('GridView large scroll jump', (WidgetTester tester) async {
148
    final List<int> log = <int>[];
149

150
    await tester.pumpWidget(
151
      Directionality(
152
        textDirection: TextDirection.ltr,
153
        child: GridView.extent(
154 155 156
          scrollDirection: Axis.horizontal,
          maxCrossAxisExtent: 200.0,
          childAspectRatio: 0.75,
157 158
          children: List<Widget>.generate(80, (int i) {
            return Builder(
159 160
              builder: (BuildContext context) {
                log.add(i);
161
                return Text('$i');
162
              },
163 164 165
            );
          }),
        ),
166
      ),
167
    );
168 169 170 171 172 173 174

    expect(tester.getSize(find.text('4')), equals(const Size(200.0 / 0.75, 200.0)));

    expect(log, equals(<int>[
      0, 1, 2, // col 0
      3, 4, 5, // col 1
      6, 7, 8, // col 2
175
      9, 10, 11, // col 3 (in cached area)
176 177 178
    ]));
    log.clear();

179 180 181 182 183 184 185
    for (int i = 0; i < 9; i++) {
      expect(find.text('$i'), findsOneWidget);
    }
    for (int i = 9; i < 80; i++) {
      expect(find.text('$i'), findsNothing);
    }

186 187
    final ScrollableState state = tester.state(find.byType(Scrollable));
    final ScrollPosition position = state.position;
188 189 190 191 192 193
    position.jumpTo(3025.0);

    expect(log, isEmpty);
    await tester.pump();

    expect(log, equals(<int>[
194
      30, 31, 32, // col 10 (in cached area)
195 196 197 198
      33, 34, 35, // col 11
      36, 37, 38, // col 12
      39, 40, 41, // col 13
      42, 43, 44, // col 14
199
      45, 46, 47, // col 15 (in cached area)
200 201 202
    ]));
    log.clear();

203 204 205 206 207 208 209 210 211 212
    for (int i = 0; i < 33; i++) {
      expect(find.text('$i'), findsNothing);
    }
    for (int i = 33; i < 45; i++) {
      expect(find.text('$i'), findsOneWidget);
    }
    for (int i = 45; i < 80; i++) {
      expect(find.text('$i'), findsNothing);
    }

213 214 215 216 217 218
    position.jumpTo(975.0);

    expect(log, isEmpty);
    await tester.pump();

    expect(log, equals(<int>[
219
      6, 7, 8, // col2 (in cached area)
220 221 222 223
      9, 10, 11, // col 3
      12, 13, 14, // col 4
      15, 16, 17, // col 5
      18, 19, 20, // col 6
224
      21, 22, 23, // col 7 (in cached area)
225 226
    ]));
    log.clear();
227 228 229 230 231 232 233 234 235 236

    for (int i = 0; i < 9; i++) {
      expect(find.text('$i'), findsNothing);
    }
    for (int i = 9; i < 21; i++) {
      expect(find.text('$i'), findsOneWidget);
    }
    for (int i = 21; i < 80; i++) {
      expect(find.text('$i'), findsNothing);
    }
237 238
  });

239
  testWidgets('GridView - change crossAxisCount', (WidgetTester tester) async {
240
    final List<int> log = <int>[];
241 242

    await tester.pumpWidget(
243
      Directionality(
244
        textDirection: TextDirection.ltr,
245
        child: GridView(
246 247 248
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 4,
          ),
249 250
          children: List<Widget>.generate(40, (int i) {
            return Builder(
251 252
              builder: (BuildContext context) {
                log.add(i);
253
                return Text('$i');
254
              },
255 256
            );
          }),
257 258 259 260 261 262 263 264 265 266
        ),
      ),
    );

    expect(tester.getSize(find.text('4')), equals(const Size(200.0, 200.0)));

    expect(log, equals(<int>[
      0, 1, 2, 3, // row 0
      4, 5, 6, 7, // row 1
      8, 9, 10, 11, // row 2
267 268
      12, 13, 14, 15, // row 3 (in cached area)
      16, 17, 18, 19, // row 4 (in cached area)
269
    ]));
270 271 272 273 274 275
    for (int i = 0; i < 12; i++) {
      expect(find.text('$i'), findsOneWidget);
    }
    for (int i = 12; i < 40; i++) {
      expect(find.text('$i'), findsNothing);
    }
276 277 278
    log.clear();

    await tester.pumpWidget(
279
      Directionality(
280
        textDirection: TextDirection.ltr,
281
        child: GridView(
282 283 284
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
          ),
285 286
          children: List<Widget>.generate(40, (int i) {
            return Builder(
287 288
              builder: (BuildContext context) {
                log.add(i);
289
                return Text('$i');
290
              },
291 292
            );
          }),
293 294 295 296 297 298 299 300
        ),
      ),
    );

    expect(log, equals(<int>[
      0, 1, 2, 3, // row 0
      4, 5, 6, 7, // row 1
      8, 9, 10, 11, // row 2
301 302
      12, 13, 14, 15, // row 3 (in cached area)
      16, 17, 18, 19, // row 4 (in cached area)
303 304 305 306 307 308 309
    ]));
    log.clear();

    expect(tester.getSize(find.text('3')), equals(const Size(400.0, 400.0)));
    expect(find.text('4'), findsNothing);
  });

310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
  testWidgets('SliverGridRegularTileLayout - can handle close to zero mainAxisStride', (WidgetTester tester) async {
    const SliverGridDelegateWithMaxCrossAxisExtent delegate = SliverGridDelegateWithMaxCrossAxisExtent(
      childAspectRatio: 1e300,
      maxCrossAxisExtent: 500.0,
    );
    final SliverGridLayout layout = delegate.getLayout(
      const SliverConstraints(
        axisDirection: AxisDirection.down,
        growthDirection: GrowthDirection.forward,
        userScrollDirection: ScrollDirection.forward,
        scrollOffset: 100.0,
        precedingScrollExtent: 0.0,
        overlap: 0.0,
        remainingPaintExtent: 0.0,
        crossAxisExtent: 500,
        crossAxisDirection: AxisDirection.right,
        viewportMainAxisExtent: 100.0,
        remainingCacheExtent: 0.0,
        cacheOrigin: 0.0,
329
      ),
330 331 332 333
    );
    expect(layout.getMinChildIndexForScrollOffset(1000.0), 0.0);
  });

334
  testWidgets('GridView - change maxChildCrossAxisExtent', (WidgetTester tester) async {
335
    final List<int> log = <int>[];
336 337

    await tester.pumpWidget(
338
      Directionality(
339
        textDirection: TextDirection.ltr,
340
        child: GridView(
341 342 343
          gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
            maxCrossAxisExtent: 200.0,
          ),
344 345
          children: List<Widget>.generate(40, (int i) {
            return Builder(
346 347
              builder: (BuildContext context) {
                log.add(i);
348
                return Text('$i');
349
              },
350 351
            );
          }),
352 353 354 355 356 357 358 359 360 361
        ),
      ),
    );

    expect(tester.getSize(find.text('4')), equals(const Size(200.0, 200.0)));

    expect(log, equals(<int>[
      0, 1, 2, 3, // row 0
      4, 5, 6, 7, // row 1
      8, 9, 10, 11, // row 2
362 363
      12, 13, 14, 15, // row 3 (in cached area)
      16, 17, 18, 19, // row 4 (in cached area)
364
    ]));
365 366 367 368 369 370
    for (int i = 0; i < 12; i++) {
      expect(find.text('$i'), findsOneWidget);
    }
    for (int i = 12; i < 40; i++) {
      expect(find.text('$i'), findsNothing);
    }
371 372 373
    log.clear();

    await tester.pumpWidget(
374
      Directionality(
375
        textDirection: TextDirection.ltr,
376
        child: GridView(
377 378 379
          gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
            maxCrossAxisExtent: 400.0,
          ),
380 381
          children: List<Widget>.generate(40, (int i) {
            return Builder(
382 383
              builder: (BuildContext context) {
                log.add(i);
384
                return Text('$i');
385
              },
386 387
            );
          }),
388 389 390 391 392 393 394 395
        ),
      ),
    );

    expect(log, equals(<int>[
      0, 1, 2, 3, // row 0
      4, 5, 6, 7, // row 1
      8, 9, 10, 11, // row 2
396 397
      12, 13, 14, 15, // row 3 (in cached area)
      16, 17, 18, 19, // row 4 (in cached area)
398 399 400 401 402 403
    ]));
    log.clear();

    expect(tester.getSize(find.text('3')), equals(const Size(400.0, 400.0)));
    expect(find.text('4'), findsNothing);
  });
404

Adam Barth's avatar
Adam Barth committed
405
  testWidgets('One-line GridView paints', (WidgetTester tester) async {
406
    const Color green = Color(0xFF00FF00);
Adam Barth's avatar
Adam Barth committed
407

408
    final Container container = Container(
Adam Barth's avatar
Adam Barth committed
409
      decoration: const BoxDecoration(
410
        color: green,
Adam Barth's avatar
Adam Barth committed
411 412 413
      ),
    );

414
    await tester.pumpWidget(
415
      Directionality(
416
        textDirection: TextDirection.ltr,
417 418
        child: Center(
          child: SizedBox(
419
            height: 200.0,
420
            child: GridView.count(
421
              cacheExtent: 0.0,
422 423 424 425
              crossAxisCount: 2,
              children: <Widget>[ container, container, container, container ],
            ),
          ),
Adam Barth's avatar
Adam Barth committed
426 427
        ),
      ),
428
    );
Adam Barth's avatar
Adam Barth committed
429 430 431 432 433

    expect(find.byType(GridView), paints..rect(color: green)..rect(color: green));
    expect(find.byType(GridView), isNot(paints..rect(color: green)..rect(color: green)..rect(color: green)));
  });

434 435
  testWidgets('GridView in zero context', (WidgetTester tester) async {
    await tester.pumpWidget(
436
      Directionality(
437
        textDirection: TextDirection.ltr,
438 439
        child: Center(
          child: SizedBox(
440 441
            width: 0.0,
            height: 0.0,
442
            child: GridView.count(
443
              crossAxisCount: 4,
444
              children: List<Widget>.generate(20, (int i) {
445
                return Text('$i');
446 447 448 449 450 451 452
              }),
            ),
          ),
        ),
      ),
    );

453
    expect(find.text('0'), findsNothing);
454 455 456 457 458
    expect(find.text('1'), findsNothing);
  });

  testWidgets('GridView in unbounded context', (WidgetTester tester) async {
    await tester.pumpWidget(
459
      Directionality(
460
        textDirection: TextDirection.ltr,
461 462
        child: SingleChildScrollView(
          child: GridView.count(
463
            crossAxisCount: 4,
464
            shrinkWrap: true,
465
            children: List<Widget>.generate(20, (int i) {
466
              return Text('$i');
467 468 469 470 471 472 473
            }),
          ),
        ),
      ),
    );

    expect(find.text('0'), findsOneWidget);
474
    expect(find.text('19'), findsOneWidget);
475 476
  });

477
  testWidgets('GridView.builder control test', (WidgetTester tester) async {
478
    await tester.pumpWidget(
479
      Directionality(
480
        textDirection: TextDirection.ltr,
481
        child: GridView.builder(
482 483 484
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 4,
          ),
485
          shrinkWrap: true,
486 487
          itemCount: 20,
          itemBuilder: (BuildContext context, int index) {
488
            return Text('$index');
489
          },
490 491 492
        ),
      ),
    );
493 494 495 496 497
    expect(find.text('0'), findsOneWidget);
    expect(find.text('11'), findsOneWidget);
    expect(find.text('12'), findsNothing);
  });

498 499
  testWidgets('GridView.builder with undefined itemCount', (WidgetTester tester) async {
    await tester.pumpWidget(
500
      Directionality(
501
        textDirection: TextDirection.ltr,
502
        child: GridView.builder(
503 504 505 506 507
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 4,
          ),
          shrinkWrap: true,
          itemBuilder: (BuildContext context, int index) {
508
            return Text('$index');
509 510 511 512 513 514 515 516 517 518 519
          },
        ),
      ),
    );
    expect(find.text('0'), findsOneWidget);
    expect(find.text('11'), findsOneWidget);
    await tester.drag(find.byType(GridView), const Offset(0.0, -300.0));
    await tester.pump(const Duration(milliseconds: 200));
    expect(find.text('13'), findsOneWidget);
  });

520
  testWidgets('GridView cross axis layout', (WidgetTester tester) async {
521
    final Key target = UniqueKey();
522 523

    Widget build(TextDirection textDirection) {
524
      return Directionality(
525
        textDirection: textDirection,
526
        child: GridView.count(
527 528
          crossAxisCount: 4,
          children: <Widget>[
529
            Container(key: target),
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
          ],
        ),
      );
    }

    await tester.pumpWidget(build(TextDirection.ltr));

    expect(tester.getTopLeft(find.byKey(target)), Offset.zero);
    expect(tester.getBottomRight(find.byKey(target)), const Offset(200.0, 200.0));

    await tester.pumpWidget(build(TextDirection.rtl));

    expect(tester.getTopLeft(find.byKey(target)), const Offset(600.0, 0.0));
    expect(tester.getBottomRight(find.byKey(target)), const Offset(800.0, 200.0));
  });
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572

  testWidgets('GridView crossAxisSpacing', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/27151.
    final Key target = UniqueKey();

    Widget build(TextDirection textDirection) {
      return Directionality(
        textDirection: textDirection,
        child: GridView.count(
          crossAxisCount: 4,
          crossAxisSpacing: 8.0,
          children: <Widget>[
            Container(key: target),
          ],
        ),
      );
    }

    await tester.pumpWidget(build(TextDirection.ltr));

    expect(tester.getTopLeft(find.byKey(target)), Offset.zero);
    expect(tester.getBottomRight(find.byKey(target)), const Offset(194.0, 194.0));

    await tester.pumpWidget(build(TextDirection.rtl));

    expect(tester.getTopLeft(find.byKey(target)), const Offset(606.0, 0.0));
    expect(tester.getBottomRight(find.byKey(target)), const Offset(800.0, 194.0));
  });
573 574 575 576 577 578 579 580 581 582

  testWidgets('GridView does not cache itemBuilder calls', (WidgetTester tester) async {
    final Map<int, int> counters = <int, int>{};

    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: GridView.builder(
        itemCount: 1000,
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
        itemBuilder: (BuildContext context, int index) {
583
          counters[index] = (counters[index] ?? 0) + 1;
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607
          return SizedBox(
            key: ValueKey<int>(index),
            width: 200,
            height: 200,
          );
        },
      ),
    ));

    expect(find.byKey(const ValueKey<int>(4)), findsOneWidget);
    expect(counters[4], 1);

    await tester.fling(find.byType(GridView), const Offset(0, -300), 5000);
    await tester.pumpAndSettle();

    expect(find.byKey(const ValueKey<int>(4)), findsNothing);
    expect(counters[4], 1);

    await tester.fling(find.byType(GridView), const Offset(0, 300), 5000);
    await tester.pumpAndSettle();

    expect(find.byKey(const ValueKey<int>(4)), findsOneWidget);
    expect(counters[4], 2);
  });
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635

  testWidgets('GridView respects clipBehavior', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: GridView(
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
          children: <Widget>[Container(height: 2000.0)],
        ),
      ),
    );

    // 1st, check that the render object has received the default clip behavior.
    final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
    expect(renderObject.clipBehavior, equals(Clip.hardEdge));

    // 2nd, check that the painting context has received the default clip behavior.
    final TestClipPaintingContext context = TestClipPaintingContext();
    renderObject.paint(context, Offset.zero);
    expect(context.clipBehavior, equals(Clip.hardEdge));

    // 3rd, pump a new widget to check that the render object can update its clip behavior.
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: GridView(
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
          clipBehavior: Clip.antiAlias,
636
          children: <Widget>[Container(height: 2000.0)],
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687
        ),
      ),
    );
    expect(renderObject.clipBehavior, equals(Clip.antiAlias));

    // 4th, check that a non-default clip behavior can be sent to the painting context.
    renderObject.paint(context, Offset.zero);
    expect(context.clipBehavior, equals(Clip.antiAlias));
  });

  testWidgets('GridView.builder respects clipBehavior', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: GridView.builder(
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
          itemCount: 10,
          itemBuilder: (BuildContext _, int __) => Container(height: 2000.0),
          clipBehavior: Clip.antiAlias,
        ),
      ),
    );
    final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
    expect(renderObject.clipBehavior, equals(Clip.antiAlias));
  });

  testWidgets('GridView.custom respects clipBehavior', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: GridView.custom(
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
          childrenDelegate: SliverChildBuilderDelegate(
                (BuildContext context, int index) => Container(height: 2000.0),
            childCount: 1,
          ),
          clipBehavior: Clip.antiAlias,
        ),
      ),
    );
    final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
    expect(renderObject.clipBehavior, equals(Clip.antiAlias));
  });

  testWidgets('GridView.count respects clipBehavior', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: GridView.count(
          crossAxisCount: 3,
          clipBehavior: Clip.antiAlias,
688
          children: <Widget>[Container(height: 2000.0)],
689 690 691 692 693 694 695 696 697 698 699 700 701 702
        ),
      ),
    );
    final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
    expect(renderObject.clipBehavior, equals(Clip.antiAlias));
  });

  testWidgets('GridView.extent respects clipBehavior', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: GridView.extent(
          maxCrossAxisExtent: 1000,
          clipBehavior: Clip.antiAlias,
703
          children: <Widget>[Container(height: 2000.0)],
704 705 706 707 708 709
        ),
      ),
    );
    final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
    expect(renderObject.clipBehavior, equals(Clip.antiAlias));
  });
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725

  testWidgets('SliverGridDelegateWithFixedCrossAxisCount mainAxisExtent works as expected', (WidgetTester tester) async {
    const int crossAxisCount = 4;
    const double mainAxisExtent = 100.0;

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: GridView(
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: crossAxisCount,
            mainAxisExtent: mainAxisExtent,
          ),
          children: List<Widget>.generate(20, (int i) {
            return Builder(
              builder: (BuildContext context) {
726
                return Text('$i');
727
              },
728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751
            );
          }),
        ),
      ),
    );

    expect(tester.getSize(find.text('4')), equals(const Size(200.0, mainAxisExtent)));
  });

  testWidgets('SliverGridDelegateWithMaxCrossAxisExtent mainAxisExtent works as expected', (WidgetTester tester) async {
    const double maxCrossAxisExtent = 200.0;
    const double mainAxisExtent = 100.0;

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: GridView(
          gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
            maxCrossAxisExtent: maxCrossAxisExtent,
            mainAxisExtent: mainAxisExtent,
          ),
          children: List<Widget>.generate(20, (int i) {
            return Builder(
              builder: (BuildContext context) {
752
                return Text('$i');
753
              },
754 755 756 757 758 759 760 761
            );
          }),
        ),
      ),
    );

    expect(tester.getSize(find.text('4')), equals(const Size(200.0, mainAxisExtent)));
  });
762 763 764 765 766 767 768 769 770

  testWidgets('SliverGridDelegateWithMaxCrossAxisExtent throws assertion error when maxCrossAxisExtent is 0', (WidgetTester tester) async {
    const double maxCrossAxisExtent = 0;

    expect(() => Directionality(
      textDirection: TextDirection.ltr,
      child: GridView.extent(
        maxCrossAxisExtent: maxCrossAxisExtent,
      ),
771
    ), throwsAssertionError);
772 773

  });
774
}