futures_test.dart 7.34 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
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/animation.dart';
import 'package:flutter/widgets.dart';
7
import 'package:flutter_test/flutter_test.dart';
8 9 10

void main() {
  testWidgets('awaiting animation controllers - using direct future', (WidgetTester tester) async {
11
    final AnimationController controller1 = AnimationController(
12 13 14
      duration: const Duration(milliseconds: 100),
      vsync: const TestVSync(),
    );
15
    final AnimationController controller2 = AnimationController(
16 17 18
      duration: const Duration(milliseconds: 600),
      vsync: const TestVSync(),
    );
19
    final AnimationController controller3 = AnimationController(
20 21 22 23
      duration: const Duration(milliseconds: 300),
      vsync: const TestVSync(),
    );
    final List<String> log = <String>[];
24
    Future<void> runTest() async {
25 26 27
      log.add('a'); // t=0
      await controller1.forward(); // starts at t=0 again
      log.add('b'); // wants to end at t=100 but missed frames until t=150
28 29 30 31
      await controller2.forward(); // starts at t=150
      log.add('c'); // wants to end at t=750 but missed frames until t=799
      await controller3.forward(); // starts at t=799
      log.add('d'); // wants to end at t=1099 but missed frames until t=1200
32 33
    }
    log.add('start');
34
    runTest().then((void value) {
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
      log.add('end');
    });
    await tester.pump(); // t=0
    expect(log, <String>['start', 'a']);
    await tester.pump(); // t=0 again
    expect(log, <String>['start', 'a']);
    await tester.pump(const Duration(milliseconds: 50)); // t=50
    expect(log, <String>['start', 'a']);
    await tester.pump(const Duration(milliseconds: 100)); // t=150
    expect(log, <String>['start', 'a', 'b']);
    await tester.pump(const Duration(milliseconds: 50)); // t=200
    expect(log, <String>['start', 'a', 'b']);
    await tester.pump(const Duration(milliseconds: 400)); // t=600
    expect(log, <String>['start', 'a', 'b']);
    await tester.pump(const Duration(milliseconds: 199)); // t=799
50
    expect(log, <String>['start', 'a', 'b', 'c']);
51 52 53
    await tester.pump(const Duration(milliseconds: 51)); // t=850
    expect(log, <String>['start', 'a', 'b', 'c']);
    await tester.pump(const Duration(milliseconds: 400)); // t=1200
54
    expect(log, <String>['start', 'a', 'b', 'c', 'd', 'end']);
55 56 57 58 59
    await tester.pump(const Duration(milliseconds: 400)); // t=1600
    expect(log, <String>['start', 'a', 'b', 'c', 'd', 'end']);
  });

  testWidgets('awaiting animation controllers - using orCancel', (WidgetTester tester) async {
60
    final AnimationController controller1 = AnimationController(
61 62 63
      duration: const Duration(milliseconds: 100),
      vsync: const TestVSync(),
    );
64
    final AnimationController controller2 = AnimationController(
65 66 67
      duration: const Duration(milliseconds: 600),
      vsync: const TestVSync(),
    );
68
    final AnimationController controller3 = AnimationController(
69 70 71 72
      duration: const Duration(milliseconds: 300),
      vsync: const TestVSync(),
    );
    final List<String> log = <String>[];
73
    Future<void> runTest() async {
74 75 76
      log.add('a'); // t=0
      await controller1.forward().orCancel; // starts at t=0 again
      log.add('b'); // wants to end at t=100 but missed frames until t=150
77 78 79 80
      await controller2.forward().orCancel; // starts at t=150
      log.add('c'); // wants to end at t=750 but missed frames until t=799
      await controller3.forward().orCancel; // starts at t=799
      log.add('d'); // wants to end at t=1099 but missed frames until t=1200
81 82
    }
    log.add('start');
83
    runTest().then((void value) {
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
      log.add('end');
    });
    await tester.pump(); // t=0
    expect(log, <String>['start', 'a']);
    await tester.pump(); // t=0 again
    expect(log, <String>['start', 'a']);
    await tester.pump(const Duration(milliseconds: 50)); // t=50
    expect(log, <String>['start', 'a']);
    await tester.pump(const Duration(milliseconds: 100)); // t=150
    expect(log, <String>['start', 'a', 'b']);
    await tester.pump(const Duration(milliseconds: 50)); // t=200
    expect(log, <String>['start', 'a', 'b']);
    await tester.pump(const Duration(milliseconds: 400)); // t=600
    expect(log, <String>['start', 'a', 'b']);
    await tester.pump(const Duration(milliseconds: 199)); // t=799
99
    expect(log, <String>['start', 'a', 'b', 'c']);
100 101 102
    await tester.pump(const Duration(milliseconds: 51)); // t=850
    expect(log, <String>['start', 'a', 'b', 'c']);
    await tester.pump(const Duration(milliseconds: 400)); // t=1200
103
    expect(log, <String>['start', 'a', 'b', 'c', 'd', 'end']);
104 105 106 107 108
    await tester.pump(const Duration(milliseconds: 400)); // t=1600
    expect(log, <String>['start', 'a', 'b', 'c', 'd', 'end']);
  });

  testWidgets('awaiting animation controllers and failing', (WidgetTester tester) async {
109
    final AnimationController controller1 = AnimationController(
110 111 112 113
      duration: const Duration(milliseconds: 100),
      vsync: const TestVSync(),
    );
    final List<String> log = <String>[];
114
    Future<void> runTest() async {
115 116 117 118 119 120 121 122
      try {
        log.add('start');
        await controller1.forward().orCancel;
        log.add('fail');
      } on TickerCanceled {
        log.add('caught');
      }
    }
123
    runTest().then((void value) {
124 125 126 127 128 129 130 131 132 133 134 135 136
      log.add('end');
    });
    await tester.pump(); // start ticker
    expect(log, <String>['start']);
    await tester.pump(const Duration(milliseconds: 50));
    expect(log, <String>['start']);
    controller1.dispose();
    expect(log, <String>['start']);
    await tester.idle();
    expect(log, <String>['start', 'caught', 'end']);
  });

  testWidgets('creating orCancel future later', (WidgetTester tester) async {
137
    final AnimationController controller1 = AnimationController(
138 139 140 141 142 143 144 145 146 147 148 149
      duration: const Duration(milliseconds: 100),
      vsync: const TestVSync(),
    );
    final TickerFuture f = controller1.forward();
    await tester.pump(); // start ticker
    await tester.pump(const Duration(milliseconds: 200)); // end ticker
    await f; // should be a no-op
    await f.orCancel; // should create a resolved future
    expect(true, isTrue); // should reach here
  });

  testWidgets('creating orCancel future later', (WidgetTester tester) async {
150
    final AnimationController controller1 = AnimationController(
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
      duration: const Duration(milliseconds: 100),
      vsync: const TestVSync(),
    );
    final TickerFuture f = controller1.forward();
    await tester.pump(); // start ticker
    controller1.stop(); // cancel ticker
    bool ok = false;
    try {
      await f.orCancel; // should create a resolved future
    } on TickerCanceled {
      ok = true;
    }
    expect(ok, isTrue); // should reach here
  });

  testWidgets('TickerFuture is a Future', (WidgetTester tester) async {
167
    final AnimationController controller1 = AnimationController(
168 169 170 171 172 173
      duration: const Duration(milliseconds: 100),
      vsync: const TestVSync(),
    );
    final TickerFuture f = controller1.forward();
    await tester.pump(); // start ticker
    await tester.pump(const Duration(milliseconds: 200)); // end ticker
Dan Field's avatar
Dan Field committed
174
    expect(f.asStream().single, isA<Future<void>>());
175
    await f.catchError((dynamic e) { throw 'do not reach'; });
176
    expect(await f.then<bool>((_) => true), isTrue);
Dan Field's avatar
Dan Field committed
177 178
    expect(f.whenComplete(() => false), isA<Future<void>>());
    expect(f.timeout(const Duration(seconds: 5)), isA<Future<void>>());
179 180
  });
}