lazy_block_viewport_test.dart 8.87 KB
Newer Older
Hixie's avatar
Hixie committed
1 2 3 4
// 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.

Adam Barth's avatar
Adam Barth committed
5
import 'package:flutter_test/flutter_test.dart';
6
import 'package:flutter/material.dart';
7
import 'package:flutter/rendering.dart';
Hixie's avatar
Hixie committed
8 9 10 11

import 'test_widgets.dart';

void main() {
12
  testWidgets('LazyBlockViewport mount/dismount smoke test', (WidgetTester tester) async {
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
    List<int> callbackTracker = <int>[];

    // the root view is 800x600 in the test environment
    // so if our widget is 100 pixels tall, it should fit exactly 6 times.

    Widget builder() {
      return new FlipWidget(
        left: new LazyBlockViewport(
          delegate: new LazyBlockBuilder(builder: (BuildContext context, int i) {
            callbackTracker.add(i);
            return new Container(
              key: new ValueKey<int>(i),
              height: 100.0,
              child: new Text("$i")
            );
          }),
          startOffset: 0.0
        ),
        right: new Text('Not Today')
      );
    }
Hixie's avatar
Hixie committed
34

35
    await tester.pumpWidget(builder());
Hixie's avatar
Hixie committed
36

37
    FlipWidgetState testWidget = tester.state(find.byType(FlipWidget));
Hixie's avatar
Hixie committed
38

39
    expect(callbackTracker, equals(<int>[0, 1, 2, 3, 4, 5]));
Hixie's avatar
Hixie committed
40

41 42
    callbackTracker.clear();
    testWidget.flip();
43
    await tester.pump();
Hixie's avatar
Hixie committed
44

45
    expect(callbackTracker, equals(<int>[]));
Hixie's avatar
Hixie committed
46

47 48
    callbackTracker.clear();
    testWidget.flip();
49
    await tester.pump();
Hixie's avatar
Hixie committed
50

51
    expect(callbackTracker, equals(<int>[0, 1, 2, 3, 4, 5]));
52
  });
Hixie's avatar
Hixie committed
53

54
  testWidgets('LazyBlockViewport vertical', (WidgetTester tester) async {
55
    List<int> callbackTracker = <int>[];
Hixie's avatar
Hixie committed
56

57 58 59
    // the root view is 800x600 in the test environment
    // so if our widget is 200 pixels tall, it should fit exactly 3 times.
    // but if we are offset by 300 pixels, there will be 4, numbered 1-4.
Hixie's avatar
Hixie committed
60

61
    double offset = 300.0;
Adam Barth's avatar
Adam Barth committed
62

63
    IndexedWidgetBuilder itemBuilder = (BuildContext context, int i) {
64 65 66 67 68 69 70 71
      callbackTracker.add(i);
      return new Container(
        key: new ValueKey<int>(i),
        width: 500.0, // this should be ignored
        height: 200.0,
        child: new Text("$i")
      );
    };
Hixie's avatar
Hixie committed
72

73 74 75 76 77 78 79 80 81
    Widget builder() {
      return new FlipWidget(
        left: new LazyBlockViewport(
          delegate: new LazyBlockBuilder(builder: itemBuilder),
          startOffset: offset
        ),
        right: new Text('Not Today')
      );
    }
Hixie's avatar
Hixie committed
82

83
    await tester.pumpWidget(builder());
Hixie's avatar
Hixie committed
84

85
    // 0 is built to find its height
86
    expect(callbackTracker, equals(<int>[0, 1, 2, 3, 4]));
87
    callbackTracker.clear();
Hixie's avatar
Hixie committed
88

89
    offset = 400.0; // now only 3 should fit, numbered 2-4.
Hixie's avatar
Hixie committed
90

91
    await tester.pumpWidget(builder());
Hixie's avatar
Hixie committed
92

93
    // We build all the children to find their new size.
94
    expect(callbackTracker, equals(<int>[0, 1, 2, 3, 4]));
95
    callbackTracker.clear();
Hixie's avatar
Hixie committed
96

97
    await tester.pumpWidget(builder());
Hixie's avatar
Hixie committed
98

99
    // 0 isn't built because they're not visible.
100
    expect(callbackTracker, equals(<int>[1, 2, 3, 4]));
101 102
    callbackTracker.clear();
  });
Hixie's avatar
Hixie committed
103

104
  testWidgets('LazyBlockViewport horizontal', (WidgetTester tester) async {
105
    List<int> callbackTracker = <int>[];
Hixie's avatar
Hixie committed
106

107 108 109
    // the root view is 800x600 in the test environment
    // so if our widget is 200 pixels wide, it should fit exactly 4 times.
    // but if we are offset by 300 pixels, there will be 5, numbered 1-5.
Hixie's avatar
Hixie committed
110

111
    double offset = 300.0;
Hixie's avatar
Hixie committed
112

113
    IndexedWidgetBuilder itemBuilder = (BuildContext context, int i) {
114 115 116 117 118 119 120 121
      callbackTracker.add(i);
      return new Container(
        key: new ValueKey<int>(i),
        height: 500.0, // this should be ignored
        width: 200.0,
        child: new Text("$i")
      );
    };
Hixie's avatar
Hixie committed
122

123 124 125 126 127 128 129 130 131 132
    Widget builder() {
      return new FlipWidget(
        left: new LazyBlockViewport(
          delegate: new LazyBlockBuilder(builder: itemBuilder),
          startOffset: offset,
          mainAxis: Axis.horizontal
        ),
        right: new Text('Not Today')
      );
    }
Adam Barth's avatar
Adam Barth committed
133

134
    await tester.pumpWidget(builder());
Adam Barth's avatar
Adam Barth committed
135

136
    // 0 is built to find its width
137
    expect(callbackTracker, equals(<int>[0, 1, 2, 3, 4, 5]));
Adam Barth's avatar
Adam Barth committed
138

139
    callbackTracker.clear();
Adam Barth's avatar
Adam Barth committed
140

141
    offset = 400.0; // now only 4 should fit, numbered 2-5.
Adam Barth's avatar
Adam Barth committed
142

143
    await tester.pumpWidget(builder());
Adam Barth's avatar
Adam Barth committed
144

145
    // We build all the children to find their new size.
146
    expect(callbackTracker, equals(<int>[0, 1, 2, 3, 4, 5]));
147 148
    callbackTracker.clear();

149
    await tester.pumpWidget(builder());
150 151

    // 0 isn't built because they're not visible.
152
    expect(callbackTracker, equals(<int>[1, 2, 3, 4, 5]));
153
    callbackTracker.clear();
Adam Barth's avatar
Adam Barth committed
154
  });
155

156
  testWidgets('LazyBlockViewport reinvoke builders', (WidgetTester tester) async {
157 158 159
    List<int> callbackTracker = <int>[];
    List<String> text = <String>[];

160
    IndexedWidgetBuilder itemBuilder = (BuildContext context, int i) {
161 162 163 164 165 166
      callbackTracker.add(i);
      return new Container(
        key: new ValueKey<int>(i),
        width: 500.0, // this should be ignored
        height: 220.0,
        child: new Text("$i")
Adam Barth's avatar
Adam Barth committed
167
      );
168
    };
169

170 171 172
    void collectText(Widget widget) {
      if (widget is Text)
        text.add(widget.data);
pq's avatar
pq committed
173
    }
174 175 176 177 178

    Widget builder() {
      return new LazyBlockViewport(
        delegate: new LazyBlockBuilder(builder: itemBuilder),
        startOffset: 0.0
179
      );
180 181
    }

182
    await tester.pumpWidget(builder());
183

184
    expect(callbackTracker, equals(<int>[0, 1, 2]));
185
    callbackTracker.clear();
186
    tester.allWidgets.forEach(collectText);
187
    expect(text, equals(<String>['0', '1', '2']));
188
    text.clear();
189

190
    await tester.pumpWidget(builder());
191

192
    expect(callbackTracker, equals(<int>[0, 1, 2]));
193
    callbackTracker.clear();
194
    tester.allWidgets.forEach(collectText);
195
    expect(text, equals(<String>['0', '1', '2']));
196 197
    text.clear();
  });
198

199
  testWidgets('LazyBlockViewport reinvoke builders', (WidgetTester tester) async {
200 201 202
    StateSetter setState;
    ThemeData themeData = new ThemeData.light();

203
    IndexedWidgetBuilder itemBuilder = (BuildContext context, int i) {
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
      return new Container(
        key: new ValueKey<int>(i),
        width: 500.0, // this should be ignored
        height: 220.0,
        decoration: new BoxDecoration(
          backgroundColor: Theme.of(context).primaryColor
        ),
        child: new Text("$i")
      );
    };

    Widget viewport = new LazyBlockViewport(
      delegate: new LazyBlockBuilder(builder: itemBuilder)
    );

219
    await tester.pumpWidget(
220 221 222 223 224 225 226 227 228 229 230 231 232 233
      new StatefulBuilder(
        builder: (BuildContext context, StateSetter setter) {
          setState = setter;
          return new Theme(data: themeData, child: viewport);
        }
      )
    );

    DecoratedBox widget = tester.firstWidget(find.byType(DecoratedBox));
    BoxDecoration decoraton = widget.decoration;
    expect(decoraton.backgroundColor, equals(Colors.blue[500]));

    setState(() {
      themeData = new ThemeData(primarySwatch: Colors.green);
234
    });
235

236
    await tester.pump();
237 238 239 240

    widget = tester.firstWidget(find.byType(DecoratedBox));
    decoraton = widget.decoration;
    expect(decoraton.backgroundColor, equals(Colors.green[500]));
241
  });
242

243
  testWidgets('LazyBlockViewport padding', (WidgetTester tester) async {
244
    IndexedWidgetBuilder itemBuilder = (BuildContext context, int i) {
245 246 247 248 249 250 251 252
      return new Container(
        key: new ValueKey<int>(i),
        width: 500.0, // this should be ignored
        height: 220.0,
        decoration: new BoxDecoration(
          backgroundColor: Colors.green[500]
        ),
        child: new Text("$i")
253
      );
254
    };
255

256
    await tester.pumpWidget(
257 258 259 260 261 262 263 264 265 266
      new LazyBlockViewport(
        padding: new EdgeInsets.fromLTRB(7.0, 3.0, 5.0, 11.0),
        delegate: new LazyBlockBuilder(builder: itemBuilder)
      )
    );

    RenderBox firstBox = tester.renderObject(find.text('0'));
    Point upperLeft = firstBox.localToGlobal(Point.origin);
    expect(upperLeft, equals(new Point(7.0, 3.0)));
    expect(firstBox.size.width, equals(800.0 - 12.0));
267 268
  });

269
  testWidgets('Underflow extents', (WidgetTester tester) async {
270 271 272 273
    int lastFirstIndex;
    int lastLastIndex;
    double lastFirstStartOffset;
    double lastLastEndOffset;
274
    double lastMinScrollOffset;
275 276 277 278 279 280
    double lastContainerExtent;
    void handleExtendsChanged(int firstIndex, int lastIndex, double firstStartOffset, double lastEndOffset, double minScrollOffset, double containerExtent) {
      lastFirstIndex = firstIndex;
      lastLastIndex = lastIndex;
      lastFirstStartOffset = firstStartOffset;
      lastLastEndOffset = lastEndOffset;
281
      lastMinScrollOffset = minScrollOffset;
282
      lastContainerExtent = containerExtent;
283 284
    }

285
    await tester.pumpWidget(new LazyBlockViewport(
286 287 288 289 290 291 292 293 294 295
      onExtentsChanged: handleExtendsChanged,
      delegate: new LazyBlockChildren(
        children: <Widget>[
          new Container(height: 100.0),
          new Container(height: 100.0),
          new Container(height: 100.0),
        ]
      )
    ));

296 297 298 299 300 301
    expect(lastFirstIndex, 0);
    expect(lastLastIndex, 2);
    expect(lastFirstStartOffset, 0.0);
    expect(lastLastEndOffset, 300.0);
    expect(lastContainerExtent, 600.0);
    expect(lastMinScrollOffset, 0.0);
302
  });
Hixie's avatar
Hixie committed
303
}