futures_test.dart 7.4 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
// @dart = 2.8

7 8
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/animation.dart';
9
import 'package:flutter/scheduler.dart';
10 11 12 13
import 'package:flutter/widgets.dart';

void main() {
  testWidgets('awaiting animation controllers - using direct future', (WidgetTester tester) async {
14
    final AnimationController controller1 = AnimationController(
15 16 17
      duration: const Duration(milliseconds: 100),
      vsync: const TestVSync(),
    );
18
    final AnimationController controller2 = AnimationController(
19 20 21
      duration: const Duration(milliseconds: 600),
      vsync: const TestVSync(),
    );
22
    final AnimationController controller3 = AnimationController(
23 24 25 26
      duration: const Duration(milliseconds: 300),
      vsync: const TestVSync(),
    );
    final List<String> log = <String>[];
27
    Future<void> runTest() async {
28 29 30
      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
31 32 33 34
      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
35 36
    }
    log.add('start');
37
    runTest().then((void value) {
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
      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
53
    expect(log, <String>['start', 'a', 'b', 'c']);
54 55 56
    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
57
    expect(log, <String>['start', 'a', 'b', 'c', 'd', 'end']);
58 59 60 61 62
    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 {
63
    final AnimationController controller1 = AnimationController(
64 65 66
      duration: const Duration(milliseconds: 100),
      vsync: const TestVSync(),
    );
67
    final AnimationController controller2 = AnimationController(
68 69 70
      duration: const Duration(milliseconds: 600),
      vsync: const TestVSync(),
    );
71
    final AnimationController controller3 = AnimationController(
72 73 74 75
      duration: const Duration(milliseconds: 300),
      vsync: const TestVSync(),
    );
    final List<String> log = <String>[];
76
    Future<void> runTest() async {
77 78 79
      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
80 81 82 83
      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
84 85
    }
    log.add('start');
86
    runTest().then((void value) {
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
      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
102
    expect(log, <String>['start', 'a', 'b', 'c']);
103 104 105
    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
106
    expect(log, <String>['start', 'a', 'b', 'c', 'd', 'end']);
107 108 109 110 111
    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 {
112
    final AnimationController controller1 = AnimationController(
113 114 115 116
      duration: const Duration(milliseconds: 100),
      vsync: const TestVSync(),
    );
    final List<String> log = <String>[];
117
    Future<void> runTest() async {
118 119 120 121 122 123 124 125
      try {
        log.add('start');
        await controller1.forward().orCancel;
        log.add('fail');
      } on TickerCanceled {
        log.add('caught');
      }
    }
126
    runTest().then((void value) {
127 128 129 130 131 132 133 134 135 136 137 138 139
      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 {
140
    final AnimationController controller1 = AnimationController(
141 142 143 144 145 146 147 148 149 150 151 152
      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 {
153
    final AnimationController controller1 = AnimationController(
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
      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 {
170
    final AnimationController controller1 = AnimationController(
171 172 173 174 175 176
      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
177
    expect(f.asStream().single, isA<Future<void>>());
178
    await f.catchError((dynamic e) { throw 'do not reach'; });
179
    expect(await f.then<bool>((_) => true), isTrue);
Dan Field's avatar
Dan Field committed
180 181
    expect(f.whenComplete(() => false), isA<Future<void>>());
    expect(f.timeout(const Duration(seconds: 5)), isA<Future<void>>());
182 183
  });
}