page_view_test.dart 12.8 KB
Newer Older
Adam Barth's avatar
Adam Barth committed
1 2 3 4 5
// Copyright 2017 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';
6
import 'package:flutter/material.dart';
Adam Barth's avatar
Adam Barth committed
7 8 9 10 11 12 13 14
import 'package:flutter/widgets.dart';

import 'states.dart';

const Duration _frameDuration = const Duration(milliseconds: 100);

void main() {
  testWidgets('PageView control test', (WidgetTester tester) async {
15
    final List<String> log = <String>[];
Adam Barth's avatar
Adam Barth committed
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

    await tester.pumpWidget(new PageView(
      children: kStates.map<Widget>((String state) {
        return new GestureDetector(
          onTap: () {
            log.add(state);
          },
          child: new Container(
            height: 200.0,
            decoration: const BoxDecoration(
              backgroundColor: const Color(0xFF0000FF),
            ),
            child: new Text(state),
          ),
        );
31
      }).toList(),
Adam Barth's avatar
Adam Barth committed
32 33 34 35 36 37 38 39
    ));

    await tester.tap(find.text('Alabama'));
    expect(log, equals(<String>['Alabama']));
    log.clear();

    expect(find.text('Alaska'), findsNothing);

40
    await tester.drag(find.byType(PageView), const Offset(-10.0, 0.0));
Adam Barth's avatar
Adam Barth committed
41 42 43 44 45 46
    await tester.pump();

    expect(find.text('Alabama'), findsOneWidget);
    expect(find.text('Alaska'), findsOneWidget);
    expect(find.text('Arizona'), findsNothing);

47
    await tester.pumpAndSettle(_frameDuration);
Adam Barth's avatar
Adam Barth committed
48 49 50 51

    expect(find.text('Alabama'), findsOneWidget);
    expect(find.text('Alaska'), findsNothing);

52 53
    await tester.drag(find.byType(PageView), const Offset(-401.0, 0.0));
    await tester.pumpAndSettle(_frameDuration);
Adam Barth's avatar
Adam Barth committed
54 55 56 57 58 59 60 61 62

    expect(find.text('Alabama'), findsNothing);
    expect(find.text('Alaska'), findsOneWidget);
    expect(find.text('Arizona'), findsNothing);

    await tester.tap(find.text('Alaska'));
    expect(log, equals(<String>['Alaska']));
    log.clear();

63
    await tester.fling(find.byType(PageView), const Offset(-200.0, 0.0), 1000.0);
64
    await tester.pumpAndSettle(_frameDuration);
Adam Barth's avatar
Adam Barth committed
65 66 67 68 69 70

    expect(find.text('Alabama'), findsNothing);
    expect(find.text('Alaska'), findsNothing);
    expect(find.text('Arizona'), findsOneWidget);

    await tester.fling(find.byType(PageView), const Offset(200.0, 0.0), 1000.0);
71
    await tester.pumpAndSettle(_frameDuration);
Adam Barth's avatar
Adam Barth committed
72 73 74 75 76

    expect(find.text('Alabama'), findsNothing);
    expect(find.text('Alaska'), findsOneWidget);
    expect(find.text('Arizona'), findsNothing);
  });
77

78 79
  testWidgets('PageView does not squish when overscrolled',
      (WidgetTester tester) async {
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
    await tester.pumpWidget(new MaterialApp(
      theme: new ThemeData(platform: TargetPlatform.iOS),
      home: new PageView(
        children: new List<Widget>.generate(10, (int i) {
          return new Container(
            key: new ValueKey<int>(i),
            decoration: const BoxDecoration(
              backgroundColor: const Color(0xFF0000FF),
            ),
          );
        }),
      ),
    ));

    Size sizeOf(int i) => tester.getSize(find.byKey(new ValueKey<int>(i)));
95
    double leftOf(int i) => tester.getTopLeft(find.byKey(new ValueKey<int>(i))).x;
96 97 98 99

    expect(leftOf(0), equals(0.0));
    expect(sizeOf(0), equals(const Size(800.0, 600.0)));

100
    await tester.drag(find.byType(PageView), const Offset(100.0, 0.0));
101 102 103 104 105
    await tester.pump();

    expect(leftOf(0), equals(100.0));
    expect(sizeOf(0), equals(const Size(800.0, 600.0)));

106
    await tester.drag(find.byType(PageView), const Offset(-200.0, 0.0));
107 108 109 110 111
    await tester.pump();

    expect(leftOf(0), equals(-100.0));
    expect(sizeOf(0), equals(const Size(800.0, 600.0)));
  });
112 113

  testWidgets('PageController control test', (WidgetTester tester) async {
114
    final PageController controller = new PageController(initialPage: 4);
115 116 117 118 119 120 121

    await tester.pumpWidget(new Center(
      child: new SizedBox(
        width: 600.0,
        height: 400.0,
        child: new PageView(
          controller: controller,
122
          children: kStates.map<Widget>((String state) => new Text(state)).toList(),
123 124 125 126 127 128
        ),
      ),
    ));

    expect(find.text('California'), findsOneWidget);

129 130
    controller.nextPage(duration: const Duration(milliseconds: 150), curve: Curves.ease);
    await tester.pumpAndSettle(const Duration(milliseconds: 100));
131 132 133 134 135 136 137 138 139

    expect(find.text('Colorado'), findsOneWidget);

    await tester.pumpWidget(new Center(
      child: new SizedBox(
        width: 300.0,
        height: 400.0,
        child: new PageView(
          controller: controller,
140
          children: kStates.map<Widget>((String state) => new Text(state)).toList(),
141 142 143 144 145 146
        ),
      ),
    ));

    expect(find.text('Colorado'), findsOneWidget);

147 148
    controller.previousPage(duration: const Duration(milliseconds: 150), curve: Curves.ease);
    await tester.pumpAndSettle(const Duration(milliseconds: 100));
149 150 151 152 153 154 155 156 157 158

    expect(find.text('California'), findsOneWidget);
  });

  testWidgets('PageController page stability', (WidgetTester tester) async {
    await tester.pumpWidget(new Center(
      child: new SizedBox(
        width: 600.0,
        height: 400.0,
        child: new PageView(
159
          children: kStates.map<Widget>((String state) => new Text(state)).toList(),
160 161 162 163 164 165
        ),
      ),
    ));

    expect(find.text('Alabama'), findsOneWidget);

166 167
    await tester.drag(find.byType(PageView), const Offset(-1250.0, 0.0));
    await tester.pumpAndSettle(const Duration(milliseconds: 100));
168 169 170 171 172 173 174 175

    expect(find.text('Arizona'), findsOneWidget);

    await tester.pumpWidget(new Center(
      child: new SizedBox(
        width: 250.0,
        height: 100.0,
        child: new PageView(
176
          children: kStates.map<Widget>((String state) => new Text(state)).toList(),
177 178 179 180 181 182 183 184 185 186 187
        ),
      ),
    ));

    expect(find.text('Arizona'), findsOneWidget);

    await tester.pumpWidget(new Center(
      child: new SizedBox(
        width: 450.0,
        height: 400.0,
        child: new PageView(
188
          children: kStates.map<Widget>((String state) => new Text(state)).toList(),
189 190 191 192 193 194
        ),
      ),
    ));

    expect(find.text('Arizona'), findsOneWidget);
  });
195 196 197 198 199 200 201

  testWidgets('PageView in zero-size container', (WidgetTester tester) async {
    await tester.pumpWidget(new Center(
      child: new SizedBox(
        width: 0.0,
        height: 0.0,
        child: new PageView(
202
          children: kStates.map<Widget>((String state) => new Text(state)).toList(),
203 204 205 206 207
        ),
      ),
    ));

    expect(find.text('Alabama'), findsOneWidget);
208 209 210 211 212 213

    await tester.pumpWidget(new Center(
      child: new SizedBox(
        width: 200.0,
        height: 200.0,
        child: new PageView(
214
          children: kStates.map<Widget>((String state) => new Text(state)).toList(),
215 216 217 218 219
        ),
      ),
    ));

    expect(find.text('Alabama'), findsOneWidget);
220
  });
221 222 223 224

  testWidgets('Page changes at halfway point', (WidgetTester tester) async {
    final List<int> log = <int>[];
    await tester.pumpWidget(new PageView(
225
      onPageChanged: log.add,
226 227 228 229 230
      children: kStates.map<Widget>((String state) => new Text(state)).toList(),
    ));

    expect(log, isEmpty);

231 232
    final TestGesture gesture =
        await tester.startGesture(const Point(100.0, 100.0));
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
    // The page view is 800.0 wide, so this move is just short of halfway.
    await gesture.moveBy(const Offset(-380.0, 0.0));

    expect(log, isEmpty);

    // We've crossed the halfway mark.
    await gesture.moveBy(const Offset(-40.0, 0.0));

    expect(log, equals(const <int>[1]));
    log.clear();

    // Moving a bit more should not generate redundant notifications.
    await gesture.moveBy(const Offset(-40.0, 0.0));

    expect(log, isEmpty);

    await gesture.moveBy(const Offset(-40.0, 0.0));
    await tester.pump();

    await gesture.moveBy(const Offset(-40.0, 0.0));
    await tester.pump();

    await gesture.moveBy(const Offset(-40.0, 0.0));
    await tester.pump();

    expect(log, isEmpty);

    await gesture.up();
261
    await tester.pumpAndSettle();
262 263 264 265 266 267 268

    expect(log, isEmpty);

    expect(find.text('Alabama'), findsNothing);
    expect(find.text('Alaska'), findsOneWidget);
  });

269 270 271 272 273 274 275 276 277 278
  testWidgets('PageView viewportFraction', (WidgetTester tester) async {
    PageController controller = new PageController(viewportFraction: 7/8);

    Widget build(PageController controller) {
      return new PageView.builder(
        controller: controller,
        itemCount: kStates.length,
        itemBuilder: (BuildContext context, int index) {
          return new Container(
            height: 200.0,
279 280 281
            color: index % 2 == 0
                ? const Color(0xFF0000FF)
                : const Color(0xFF00FF00),
282 283
            child: new Text(kStates[index]),
          );
284
        },
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
      );
    }

    await tester.pumpWidget(build(controller));

    expect(tester.getTopLeft(find.text('Alabama')), const Point(50.0, 0.0));
    expect(tester.getTopLeft(find.text('Alaska')), const Point(750.0, 0.0));

    controller.jumpToPage(10);
    await tester.pump();

    expect(tester.getTopLeft(find.text('Georgia')), const Point(-650.0, 0.0));
    expect(tester.getTopLeft(find.text('Hawaii')), const Point(50.0, 0.0));
    expect(tester.getTopLeft(find.text('Idaho')), const Point(750.0, 0.0));

    controller = new PageController(viewportFraction: 39/40);

    await tester.pumpWidget(build(controller));

    expect(tester.getTopLeft(find.text('Georgia')), const Point(-770.0, 0.0));
    expect(tester.getTopLeft(find.text('Hawaii')), const Point(10.0, 0.0));
    expect(tester.getTopLeft(find.text('Idaho')), const Point(790.0, 0.0));
  });

  testWidgets('PageView small viewportFraction', (WidgetTester tester) async {
310
    final PageController controller = new PageController(viewportFraction: 1/8);
311 312 313 314 315 316 317 318

    Widget build(PageController controller) {
      return new PageView.builder(
        controller: controller,
        itemCount: kStates.length,
        itemBuilder: (BuildContext context, int index) {
          return new Container(
            height: 200.0,
319 320 321
            color: index % 2 == 0
                ? const Color(0xFF0000FF)
                : const Color(0xFF00FF00),
322 323
            child: new Text(kStates[index]),
          );
324
        },
325 326 327 328 329 330 331 332 333 334 335 336 337 338
      );
    }

    await tester.pumpWidget(build(controller));

    expect(tester.getTopLeft(find.text('Alabama')), const Point(350.0, 0.0));
    expect(tester.getTopLeft(find.text('Alaska')), const Point(450.0, 0.0));
    expect(tester.getTopLeft(find.text('Arizona')), const Point(550.0, 0.0));
    expect(tester.getTopLeft(find.text('Arkansas')), const Point(650.0, 0.0));
    expect(tester.getTopLeft(find.text('California')), const Point(750.0, 0.0));

    controller.jumpToPage(10);
    await tester.pump();

339
    expect(tester.getTopLeft(find.text('Connecticut')), const Point(-50.0, 0.0));
340 341 342 343 344 345 346 347 348 349 350
    expect(tester.getTopLeft(find.text('Delaware')), const Point(50.0, 0.0));
    expect(tester.getTopLeft(find.text('Florida')), const Point(150.0, 0.0));
    expect(tester.getTopLeft(find.text('Georgia')), const Point(250.0, 0.0));
    expect(tester.getTopLeft(find.text('Hawaii')), const Point(350.0, 0.0));
    expect(tester.getTopLeft(find.text('Idaho')), const Point(450.0, 0.0));
    expect(tester.getTopLeft(find.text('Illinois')), const Point(550.0, 0.0));
    expect(tester.getTopLeft(find.text('Indiana')), const Point(650.0, 0.0));
    expect(tester.getTopLeft(find.text('Iowa')), const Point(750.0, 0.0));
  });

  testWidgets('PageView large viewportFraction', (WidgetTester tester) async {
351 352
    final PageController controller =
        new PageController(viewportFraction: 5/4);
353 354 355 356 357 358 359 360

    Widget build(PageController controller) {
      return new PageView.builder(
        controller: controller,
        itemCount: kStates.length,
        itemBuilder: (BuildContext context, int index) {
          return new Container(
            height: 200.0,
361 362 363
            color: index % 2 == 0
                ? const Color(0xFF0000FF)
                : const Color(0xFF00FF00),
364 365
            child: new Text(kStates[index]),
          );
366
        },
367 368 369 370 371 372
      );
    }

    await tester.pumpWidget(build(controller));

    expect(tester.getTopLeft(find.text('Alabama')), const Point(-100.0, 0.0));
373
    expect(tester.getBottomRight(find.text('Alabama')), const Point(900.0, 600.0));
374 375 376 377 378 379

    controller.jumpToPage(10);
    await tester.pump();

    expect(tester.getTopLeft(find.text('Hawaii')), const Point(-100.0, 0.0));
  });
380 381 382

  testWidgets('PageView does not report page changed on overscroll',
      (WidgetTester tester) async {
383 384 385
    final PageController controller = new PageController(
      initialPage: kStates.length - 1,
    );
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
    int changeIndex = 0;
    Widget build() {
      return new PageView(
        children:
            kStates.map<Widget>((String state) => new Text(state)).toList(),
        controller: controller,
        onPageChanged: (int page) {
          changeIndex = page;
        },
      );
    }

    await tester.pumpWidget(build());
    controller.jumpToPage(kStates.length * 2); // try to move beyond max range
    // change index should be zero, shouldn't fire onPageChanged
    expect(changeIndex, 0);
    await tester.pump();
    expect(changeIndex, 0);
  });
Adam Barth's avatar
Adam Barth committed
405
}