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

5 6
// @dart = 2.8

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

11 12
import '../rendering/mock_canvas.dart';

13
Future<void> test(WidgetTester tester, double offset) {
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
  return tester.pumpWidget(
    Directionality(
      textDirection: TextDirection.ltr,
      child: Viewport(
        offset: ViewportOffset.fixed(offset),
        slivers: <Widget>[
          SliverList(
            delegate: SliverChildListDelegate(const <Widget>[
              SizedBox(height: 400.0, child: Text('a')),
              SizedBox(height: 400.0, child: Text('b')),
              SizedBox(height: 400.0, child: Text('c')),
              SizedBox(height: 400.0, child: Text('d')),
              SizedBox(height: 400.0, child: Text('e')),
            ]),
          ),
        ],
      ),
    ),
  );
}

Future<void> testWithConstChildDelegate(WidgetTester tester, double offset) {
36
  return tester.pumpWidget(
37
    Directionality(
38
      textDirection: TextDirection.ltr,
39 40
      child: Viewport(
        offset: ViewportOffset.fixed(offset),
41
        slivers: const <Widget>[
42
          SliverList(
43
            delegate: SliverChildListDelegate.fixed(<Widget>[
44 45 46 47 48
              SizedBox(height: 400.0, child: Text('a')),
              SizedBox(height: 400.0, child: Text('b')),
              SizedBox(height: 400.0, child: Text('c')),
              SizedBox(height: 400.0, child: Text('d')),
              SizedBox(height: 400.0, child: Text('e')),
49 50 51
            ]),
          ),
        ],
Ian Hickson's avatar
Ian Hickson committed
52
      ),
53 54
    ),
  );
Ian Hickson's avatar
Ian Hickson committed
55 56
}

57 58 59
void verify(WidgetTester tester, List<Offset> answerKey, String text) {
  final List<Offset> testAnswers = tester.renderObjectList<RenderBox>(find.byType(SizedBox)).map<Offset>(
    (RenderBox target) => target.localToGlobal(const Offset(0.0, 0.0))
Ian Hickson's avatar
Ian Hickson committed
60 61 62
  ).toList();
  expect(testAnswers, equals(answerKey));
  final String foundText =
Ian Hickson's avatar
Ian Hickson committed
63 64
    tester.widgetList<Text>(find.byType(Text))
    .map<String>((Text widget) => widget.data)
Ian Hickson's avatar
Ian Hickson committed
65 66 67 68 69
    .reduce((String value, String element) => value + element);
  expect(foundText, equals(text));
}

void main() {
Adam Barth's avatar
Adam Barth committed
70
  testWidgets('Viewport+SliverBlock basic test', (WidgetTester tester) async {
Ian Hickson's avatar
Ian Hickson committed
71
    await test(tester, 0.0);
Adam Barth's avatar
Adam Barth committed
72
    expect(tester.renderObject<RenderBox>(find.byType(Viewport)).size, equals(const Size(800.0, 600.0)));
73 74 75
    verify(tester, <Offset>[
      const Offset(0.0, 0.0),
      const Offset(0.0, 400.0),
Ian Hickson's avatar
Ian Hickson committed
76 77 78
    ], 'ab');

    await test(tester, 200.0);
79 80 81
    verify(tester, <Offset>[
      const Offset(0.0, -200.0),
      const Offset(0.0, 200.0),
Ian Hickson's avatar
Ian Hickson committed
82 83 84
    ], 'ab');

    await test(tester, 600.0);
85 86 87
    verify(tester, <Offset>[
      const Offset(0.0, -200.0),
      const Offset(0.0, 200.0),
Ian Hickson's avatar
Ian Hickson committed
88 89 90
    ], 'bc');

    await test(tester, 900.0);
91 92 93
    verify(tester, <Offset>[
      const Offset(0.0, -100.0),
      const Offset(0.0, 300.0),
Ian Hickson's avatar
Ian Hickson committed
94 95 96
    ], 'cd');

    await test(tester, 200.0);
97 98 99
    verify(tester, <Offset>[
      const Offset(0.0, -200.0),
      const Offset(0.0, 200.0),
Ian Hickson's avatar
Ian Hickson committed
100 101 102
    ], 'ab');
  });

103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
  testWidgets('Viewport+SliverBlock basic test with constant SliverChildListDelegate', (WidgetTester tester) async {
    await testWithConstChildDelegate(tester, 0.0);
    expect(tester.renderObject<RenderBox>(find.byType(Viewport)).size, equals(const Size(800.0, 600.0)));
    verify(tester, <Offset>[
      const Offset(0.0, 0.0),
      const Offset(0.0, 400.0),
    ], 'ab');

    await testWithConstChildDelegate(tester, 200.0);
    verify(tester, <Offset>[
      const Offset(0.0, -200.0),
      const Offset(0.0, 200.0),
    ], 'ab');

    await testWithConstChildDelegate(tester, 600.0);
    verify(tester, <Offset>[
      const Offset(0.0, -200.0),
      const Offset(0.0, 200.0),
    ], 'bc');

    await testWithConstChildDelegate(tester, 900.0);
    verify(tester, <Offset>[
      const Offset(0.0, -100.0),
      const Offset(0.0, 300.0),
    ], 'cd');

    await testWithConstChildDelegate(tester, 200.0);
    verify(tester, <Offset>[
      const Offset(0.0, -200.0),
      const Offset(0.0, 200.0),
    ], 'ab');
  });

Adam Barth's avatar
Adam Barth committed
136
  testWidgets('Viewport with GlobalKey reparenting', (WidgetTester tester) async {
137 138
    final Key key1 = GlobalKey();
    final ViewportOffset offset = ViewportOffset.zero();
139
    await tester.pumpWidget(
140
      Directionality(
141
        textDirection: TextDirection.ltr,
142
        child: Viewport(
143 144
          offset: offset,
          slivers: <Widget>[
145 146
            SliverList(
              delegate: SliverChildListDelegate(<Widget>[
147 148
                const SizedBox(height: 251.0, child: Text('a')),
                const SizedBox(height: 252.0, child: Text('b')),
149
                SizedBox(key: key1, height: 253.0, child: const Text('c')),
150 151 152
              ]),
            ),
          ],
Ian Hickson's avatar
Ian Hickson committed
153
        ),
154 155
      ),
    );
156 157 158 159
    verify(tester, <Offset>[
      const Offset(0.0, 0.0),
      const Offset(0.0, 251.0),
      const Offset(0.0, 503.0),
Ian Hickson's avatar
Ian Hickson committed
160
    ], 'abc');
161
    await tester.pumpWidget(
162
      Directionality(
163
        textDirection: TextDirection.ltr,
164
        child: Viewport(
165 166
          offset: offset,
          slivers: <Widget>[
167 168 169
            SliverList(
              delegate: SliverChildListDelegate(<Widget>[
                SizedBox(key: key1, height: 253.0, child: const Text('c')),
170 171
                const SizedBox(height: 251.0, child: Text('a')),
                const SizedBox(height: 252.0, child: Text('b')),
172 173 174
              ]),
            ),
          ],
Ian Hickson's avatar
Ian Hickson committed
175
        ),
176 177
      ),
    );
178 179 180 181
    verify(tester, <Offset>[
      const Offset(0.0, 0.0),
      const Offset(0.0, 253.0),
      const Offset(0.0, 504.0),
Ian Hickson's avatar
Ian Hickson committed
182
    ], 'cab');
183
    await tester.pumpWidget(
184
      Directionality(
185
        textDirection: TextDirection.ltr,
186
        child: Viewport(
187 188
          offset: offset,
          slivers: <Widget>[
189 190
            SliverList(
              delegate: SliverChildListDelegate(<Widget>[
191
                const SizedBox(height: 251.0, child: Text('a')),
192
                SizedBox(key: key1, height: 253.0, child: const Text('c')),
193
                const SizedBox(height: 252.0, child: Text('b')),
194 195 196
              ]),
            ),
          ],
Ian Hickson's avatar
Ian Hickson committed
197
        ),
198 199
      ),
    );
200 201 202 203
    verify(tester, <Offset>[
      const Offset(0.0, 0.0),
      const Offset(0.0, 251.0),
      const Offset(0.0, 504.0),
Ian Hickson's avatar
Ian Hickson committed
204
    ], 'acb');
205
    await tester.pumpWidget(
206
      Directionality(
207
        textDirection: TextDirection.ltr,
208
        child: Viewport(
209
          offset: offset,
210
          slivers: <Widget>[
211
            SliverList(
212
              delegate: SliverChildListDelegate(const <Widget>[
213 214
                SizedBox(height: 251.0, child: Text('a')),
                SizedBox(height: 252.0, child: Text('b')),
215 216 217
              ]),
            ),
          ],
Ian Hickson's avatar
Ian Hickson committed
218
        ),
219 220
      ),
    );
221 222 223
    verify(tester, <Offset>[
      const Offset(0.0, 0.0),
      const Offset(0.0, 251.0),
Ian Hickson's avatar
Ian Hickson committed
224
    ], 'ab');
225
    await tester.pumpWidget(
226
      Directionality(
227
        textDirection: TextDirection.ltr,
228
        child: Viewport(
229 230
          offset: offset,
          slivers: <Widget>[
231 232
            SliverList(
              delegate: SliverChildListDelegate(<Widget>[
233
                const SizedBox(height: 251.0, child: Text('a')),
234
                SizedBox(key: key1, height: 253.0, child: const Text('c')),
235
                const SizedBox(height: 252.0, child: Text('b')),
236 237 238
              ]),
            ),
          ],
Ian Hickson's avatar
Ian Hickson committed
239
        ),
240 241
      ),
    );
242 243 244 245
    verify(tester, <Offset>[
      const Offset(0.0, 0.0),
      const Offset(0.0, 251.0),
      const Offset(0.0, 504.0),
Ian Hickson's avatar
Ian Hickson committed
246 247
    ], 'acb');
  });
248

Adam Barth's avatar
Adam Barth committed
249
  testWidgets('Viewport overflow clipping of SliverToBoxAdapter', (WidgetTester tester) async {
250
    await tester.pumpWidget(
251
      Directionality(
252
        textDirection: TextDirection.ltr,
253 254
        child: Viewport(
          offset: ViewportOffset.zero(),
255
          slivers: const <Widget>[
256 257
            SliverToBoxAdapter(
              child: SizedBox(height: 400.0, child: Text('a')),
258 259
            ),
          ],
260
        ),
261 262
      ),
    );
263

Adam Barth's avatar
Adam Barth committed
264
    expect(find.byType(Viewport), isNot(paints..clipRect()));
265

266
    await tester.pumpWidget(
267
      Directionality(
268
        textDirection: TextDirection.ltr,
269 270
        child: Viewport(
          offset: ViewportOffset.fixed(100.0),
271
          slivers: const <Widget>[
272 273
            SliverToBoxAdapter(
              child: SizedBox(height: 400.0, child: Text('a')),
274 275
            ),
          ],
276
        ),
277 278
      ),
    );
279

Adam Barth's avatar
Adam Barth committed
280
    expect(find.byType(Viewport), paints..clipRect());
281

282
    await tester.pumpWidget(
283
      Directionality(
284
        textDirection: TextDirection.ltr,
285 286
        child: Viewport(
          offset: ViewportOffset.fixed(100.0),
287
          slivers: const <Widget>[
288 289
            SliverToBoxAdapter(
              child: SizedBox(height: 4000.0, child: Text('a')),
290 291
            ),
          ],
292
        ),
293 294
      ),
    );
295

Adam Barth's avatar
Adam Barth committed
296
    expect(find.byType(Viewport), paints..clipRect());
297

298
    await tester.pumpWidget(
299
      Directionality(
300
        textDirection: TextDirection.ltr,
301 302
        child: Viewport(
          offset: ViewportOffset.zero(),
303
          slivers: const <Widget>[
304 305
            SliverToBoxAdapter(
              child: SizedBox(height: 4000.0, child: Text('a')),
306 307
            ),
          ],
308
        ),
309 310
      ),
    );
311

Adam Barth's avatar
Adam Barth committed
312
    expect(find.byType(Viewport), paints..clipRect());
313 314
  });

Adam Barth's avatar
Adam Barth committed
315
  testWidgets('Viewport overflow clipping of SliverBlock', (WidgetTester tester) async {
316
    await tester.pumpWidget(
317
      Directionality(
318
        textDirection: TextDirection.ltr,
319 320
        child: Viewport(
          offset: ViewportOffset.zero(),
321
          slivers: <Widget>[
322
            SliverList(
323
              delegate: SliverChildListDelegate(const <Widget>[
324
                SizedBox(height: 400.0, child: Text('a')),
325 326 327
              ]),
            ),
          ],
328
        ),
329 330
      ),
    );
331

Adam Barth's avatar
Adam Barth committed
332
    expect(find.byType(Viewport), isNot(paints..clipRect()));
333

334
    await tester.pumpWidget(
335
      Directionality(
336
        textDirection: TextDirection.ltr,
337 338
        child: Viewport(
          offset: ViewportOffset.fixed(100.0),
339
          slivers: <Widget>[
340
            SliverList(
341
              delegate: SliverChildListDelegate(const <Widget>[
342
                SizedBox(height: 400.0, child: Text('a')),
343 344 345
              ]),
            ),
          ],
346
        ),
347 348
      ),
    );
349

Adam Barth's avatar
Adam Barth committed
350
    expect(find.byType(Viewport), paints..clipRect());
351

352
    await tester.pumpWidget(
353
      Directionality(
354
        textDirection: TextDirection.ltr,
355 356
        child: Viewport(
          offset: ViewportOffset.fixed(100.0),
357
          slivers: <Widget>[
358
            SliverList(
359
              delegate: SliverChildListDelegate(const <Widget>[
360
                SizedBox(height: 4000.0, child: Text('a')),
361 362 363
              ]),
            ),
          ],
364
        ),
365 366
      ),
    );
367

Adam Barth's avatar
Adam Barth committed
368
    expect(find.byType(Viewport), paints..clipRect());
369

370
    await tester.pumpWidget(
371
      Directionality(
372
        textDirection: TextDirection.ltr,
373 374
        child: Viewport(
          offset: ViewportOffset.zero(),
375
          slivers: <Widget>[
376
            SliverList(
377
              delegate: SliverChildListDelegate(const <Widget>[
378
                SizedBox(height: 4000.0, child: Text('a')),
379 380 381
              ]),
            ),
          ],
382
        ),
383 384
      ),
    );
385

Adam Barth's avatar
Adam Barth committed
386
    expect(find.byType(Viewport), paints..clipRect());
387
  });
Ian Hickson's avatar
Ian Hickson committed
388
}