list_view_test.dart 8.55 KB
Newer Older
Adam Barth's avatar
Adam Barth committed
1 2 3 4 5 6 7
// 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.

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';

8 9 10 11 12 13 14 15 16 17 18
class TestSliverChildListDelegate extends SliverChildListDelegate {
  TestSliverChildListDelegate(List<Widget> children) : super(children);

  final List<String> log = <String>[];

  @override
  void didFinishLayout(int firstIndex, int lastIndex) {
    log.add('didFinishLayout firstIndex=$firstIndex lastIndex=$lastIndex');
  }
}

Adam Barth's avatar
Adam Barth committed
19
void main() {
20
  testWidgets('ListView default control', (WidgetTester tester) async {
21 22 23 24 25 26 27 28
    await tester.pumpWidget(
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new Center(
          child: new ListView(itemExtent: 100.0),
        ),
      ),
    );
29 30
  });

31
  testWidgets('ListView itemExtent control test', (WidgetTester tester) async {
Adam Barth's avatar
Adam Barth committed
32
    await tester.pumpWidget(
33 34 35 36 37 38 39 40 41 42
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new ListView(
          itemExtent: 200.0,
          children: new List<Widget>.generate(20, (int i) {
            return new Container(
              child: new Text('$i'),
            );
          }),
        ),
Adam Barth's avatar
Adam Barth committed
43 44 45
      ),
    );

46
    final RenderBox box = tester.renderObject<RenderBox>(find.byType(Container).first);
Adam Barth's avatar
Adam Barth committed
47 48 49 50 51
    expect(box.size.height, equals(200.0));

    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsOneWidget);
    expect(find.text('2'), findsOneWidget);
Adam Barth's avatar
Adam Barth committed
52
    expect(find.text('3'), findsNothing);
Adam Barth's avatar
Adam Barth committed
53 54
    expect(find.text('4'), findsNothing);

55
    await tester.drag(find.byType(ListView), const Offset(0.0, -250.0));
Adam Barth's avatar
Adam Barth committed
56 57 58 59 60 61 62
    await tester.pump();

    expect(find.text('0'), findsNothing);
    expect(find.text('1'), findsOneWidget);
    expect(find.text('2'), findsOneWidget);
    expect(find.text('3'), findsOneWidget);
    expect(find.text('4'), findsOneWidget);
Adam Barth's avatar
Adam Barth committed
63
    expect(find.text('5'), findsNothing);
Adam Barth's avatar
Adam Barth committed
64 65
    expect(find.text('6'), findsNothing);

66
    await tester.drag(find.byType(ListView), const Offset(0.0, 200.0));
Adam Barth's avatar
Adam Barth committed
67 68 69 70 71 72
    await tester.pump();

    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsOneWidget);
    expect(find.text('2'), findsOneWidget);
    expect(find.text('3'), findsOneWidget);
Adam Barth's avatar
Adam Barth committed
73
    expect(find.text('4'), findsNothing);
Adam Barth's avatar
Adam Barth committed
74 75 76
    expect(find.text('5'), findsNothing);
  });

77
  testWidgets('ListView large scroll jump', (WidgetTester tester) async {
78
    final List<int> log = <int>[];
Adam Barth's avatar
Adam Barth committed
79 80

    await tester.pumpWidget(
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new ListView(
          itemExtent: 200.0,
          children: new List<Widget>.generate(20, (int i) {
            return new Builder(
              builder: (BuildContext context) {
                log.add(i);
                return new Container(
                  child: new Text('$i'),
                );
              }
            );
          }),
        ),
Adam Barth's avatar
Adam Barth committed
96 97 98
      ),
    );

Adam Barth's avatar
Adam Barth committed
99
    expect(log, equals(<int>[0, 1, 2]));
Adam Barth's avatar
Adam Barth committed
100 101
    log.clear();

102 103
    final ScrollableState state = tester.state(find.byType(Scrollable));
    final ScrollPosition position = state.position;
Adam Barth's avatar
Adam Barth committed
104 105 106 107 108
    position.jumpTo(2025.0);

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

Adam Barth's avatar
Adam Barth committed
109
    expect(log, equals(<int>[10, 11, 12, 13]));
Adam Barth's avatar
Adam Barth committed
110 111 112 113 114 115 116
    log.clear();

    position.jumpTo(975.0);

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

Adam Barth's avatar
Adam Barth committed
117
    expect(log, equals(<int>[4, 5, 6, 7]));
Adam Barth's avatar
Adam Barth committed
118 119
    log.clear();
  });
120 121 122

  testWidgets('ListView can build out of underflow', (WidgetTester tester) async {
    await tester.pumpWidget(
123 124 125 126 127
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new ListView(
          itemExtent: 100.0,
        ),
128 129 130 131 132 133 134 135 136 137 138
      ),
    );

    expect(find.text('0'), findsNothing);
    expect(find.text('1'), findsNothing);
    expect(find.text('2'), findsNothing);
    expect(find.text('3'), findsNothing);
    expect(find.text('4'), findsNothing);
    expect(find.text('5'), findsNothing);

    await tester.pumpWidget(
139 140 141 142 143 144 145 146 147 148
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new ListView(
          itemExtent: 100.0,
          children: new List<Widget>.generate(2, (int i) {
            return new Container(
              child: new Text('$i'),
            );
          }),
        ),
149 150 151 152 153 154 155 156 157 158 159
      ),
    );

    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsOneWidget);
    expect(find.text('2'), findsNothing);
    expect(find.text('3'), findsNothing);
    expect(find.text('4'), findsNothing);
    expect(find.text('5'), findsNothing);

    await tester.pumpWidget(
160 161 162 163 164 165 166 167 168 169
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new ListView(
          itemExtent: 100.0,
          children: new List<Widget>.generate(5, (int i) {
            return new Container(
              child: new Text('$i'),
            );
          }),
        ),
170 171 172 173 174 175 176 177 178 179
      ),
    );

    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsOneWidget);
    expect(find.text('2'), findsOneWidget);
    expect(find.text('3'), findsOneWidget);
    expect(find.text('4'), findsOneWidget);
    expect(find.text('5'), findsNothing);
  });
180

181 182
  testWidgets('ListView can build out of overflow padding', (WidgetTester tester) async {
    await tester.pumpWidget(
183 184 185 186 187 188 189 190 191
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new Center(
          child: new SizedBox(
            width: 0.0,
            height: 0.0,
            child: new ListView(
              padding: const EdgeInsets.all(8.0),
              children: <Widget>[
Ian Hickson's avatar
Ian Hickson committed
192
                const Text('padded', textDirection: TextDirection.ltr),
193 194
              ],
            ),
195 196 197 198 199 200 201
          ),
        ),
      ),
    );
    expect(find.text('padded'), findsOneWidget);
  });

202 203
  testWidgets('ListView with itemExtent in unbounded context', (WidgetTester tester) async {
    await tester.pumpWidget(
204 205 206 207 208 209 210 211 212 213 214 215
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new SingleChildScrollView(
          child: new ListView(
            itemExtent: 100.0,
            shrinkWrap: true,
            children: new List<Widget>.generate(20, (int i) {
              return new Container(
                child: new Text('$i'),
              );
            }),
          ),
216 217 218 219 220 221 222
        ),
      ),
    );

    expect(find.text('0'), findsOneWidget);
    expect(find.text('19'), findsOneWidget);
  });
223 224 225 226 227

  testWidgets('didFinishLayout has correct indicies', (WidgetTester tester) async {
    final TestSliverChildListDelegate delegate = new TestSliverChildListDelegate(
      new List<Widget>.generate(20, (int i) {
        return new Container(
Ian Hickson's avatar
Ian Hickson committed
228
          child: new Text('$i', textDirection: TextDirection.ltr),
229 230 231 232 233
        );
      })
    );

    await tester.pumpWidget(
234 235 236 237 238 239
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new ListView.custom(
          itemExtent: 110.0,
          childrenDelegate: delegate,
        ),
240 241 242 243 244 245 246
      ),
    );

    expect(delegate.log, equals(<String>['didFinishLayout firstIndex=0 lastIndex=5']));
    delegate.log.clear();

    await tester.pumpWidget(
247 248 249 250 251 252
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new ListView.custom(
          itemExtent: 210.0,
          childrenDelegate: delegate,
        ),
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
      ),
    );

    expect(delegate.log, equals(<String>['didFinishLayout firstIndex=0 lastIndex=2']));
    delegate.log.clear();

    await tester.drag(find.byType(ListView), const Offset(0.0, -600.0));

    expect(delegate.log, isEmpty);

    await tester.pump();

    expect(delegate.log, equals(<String>['didFinishLayout firstIndex=2 lastIndex=5']));
    delegate.log.clear();
  });
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295

  testWidgets('ListView automatically pad MediaQuery on axis', (WidgetTester tester) async {
    EdgeInsets innerMediaQueryPadding;

    await tester.pumpWidget(
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new MediaQuery(
          data: const MediaQueryData(
            padding: const EdgeInsets.all(30.0),
          ),
          child: new ListView(
            children: <Widget>[
              const Text('top', textDirection: TextDirection.ltr),
              new Builder(builder: (BuildContext context) {
                innerMediaQueryPadding = MediaQuery.of(context).padding;
                return new Container();
              }),
            ],
          ),
        ),
      ),
    );
    // Automatically apply the top/bottom padding into sliver.
    expect(tester.getTopLeft(find.text('top')).dy, 30.0);
    // Leave left/right padding as is for children.
    expect(innerMediaQueryPadding, const EdgeInsets.symmetric(horizontal: 30.0));
  });
Adam Barth's avatar
Adam Barth committed
296
}