slivers_block_test.dart 10.9 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 5 6
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

9
Future<void> test(WidgetTester tester, double offset) {
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
  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) {
32
  return tester.pumpWidget(
33
    Directionality(
34
      textDirection: TextDirection.ltr,
35 36
      child: Viewport(
        offset: ViewportOffset.fixed(offset),
37
        slivers: const <Widget>[
38
          SliverList(
39
            delegate: SliverChildListDelegate.fixed(<Widget>[
40 41 42 43 44
              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')),
45 46 47
            ]),
          ),
        ],
Ian Hickson's avatar
Ian Hickson committed
48
      ),
49 50
    ),
  );
Ian Hickson's avatar
Ian Hickson committed
51 52
}

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

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

    await test(tester, 200.0);
75 76 77
    verify(tester, <Offset>[
      const Offset(0.0, -200.0),
      const Offset(0.0, 200.0),
Ian Hickson's avatar
Ian Hickson committed
78 79 80
    ], 'ab');

    await test(tester, 600.0);
81 82 83
    verify(tester, <Offset>[
      const Offset(0.0, -200.0),
      const Offset(0.0, 200.0),
Ian Hickson's avatar
Ian Hickson committed
84 85 86
    ], 'bc');

    await test(tester, 900.0);
87 88 89
    verify(tester, <Offset>[
      const Offset(0.0, -100.0),
      const Offset(0.0, 300.0),
Ian Hickson's avatar
Ian Hickson committed
90 91 92
    ], 'cd');

    await test(tester, 200.0);
93 94 95
    verify(tester, <Offset>[
      const Offset(0.0, -200.0),
      const Offset(0.0, 200.0),
Ian Hickson's avatar
Ian Hickson committed
96 97 98
    ], 'ab');
  });

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

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

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

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

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

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

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

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

Adam Barth's avatar
Adam Barth committed
308
    expect(find.byType(Viewport), paints..clipRect());
309 310
  });

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

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

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

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

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

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

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

Adam Barth's avatar
Adam Barth committed
382
    expect(find.byType(Viewport), paints..clipRect());
383
  });
Ian Hickson's avatar
Ian Hickson committed
384
}