slivers_block_test.dart 11 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 7 8
// 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/rendering.dart';
import 'package:flutter/widgets.dart';

9 10
import '../rendering/mock_canvas.dart';

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

55 56 57
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
58 59 60
  ).toList();
  expect(testAnswers, equals(answerKey));
  final String foundText =
Ian Hickson's avatar
Ian Hickson committed
61 62
    tester.widgetList<Text>(find.byType(Text))
    .map<String>((Text widget) => widget.data)
Ian Hickson's avatar
Ian Hickson committed
63 64 65 66 67
    .reduce((String value, String element) => value + element);
  expect(foundText, equals(text));
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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