routes_test.dart 9.1 KB
Newer Older
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.

5 6
import 'dart:collection';

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

final List<String> results = <String>[];

12
Set<TestRoute> routes = new HashSet<TestRoute>();
13

14 15 16 17
class TestRoute extends Route<String> {
  TestRoute(this.name);
  final String name;

18
  @override
19 20 21 22 23 24 25 26
  List<OverlayEntry> get overlayEntries => _entries;

  List<OverlayEntry> _entries = <OverlayEntry>[];

  void log(String s) {
    results.add('$name: $s');
  }

27
  @override
Hixie's avatar
Hixie committed
28
  void install(OverlayEntry insertionPoint) {
29 30 31 32 33 34
    log('install');
    OverlayEntry entry = new OverlayEntry(
      builder: (BuildContext context) => new Container(),
      opaque: true
    );
    _entries.add(entry);
Hixie's avatar
Hixie committed
35
    navigator.overlay?.insert(entry, above: insertionPoint);
36
    routes.add(this);
37 38
  }

39
  @override
40 41 42 43
  void didPush() {
    log('didPush');
  }

44
  @override
45 46 47 48
  void didReplace(TestRoute oldRoute) {
    log('didReplace ${oldRoute.name}');
  }

49
  @override
50 51
  bool didPop(String result) {
    log('didPop $result');
52 53 54 55
    bool returnValue;
    if (returnValue = super.didPop(result))
      dispose();
    return returnValue;
56 57
  }

58
  @override
59 60 61 62
  void didPopNext(TestRoute nextRoute) {
    log('didPopNext ${nextRoute.name}');
  }

63
  @override
Hixie's avatar
Hixie committed
64 65
  void didChangeNext(TestRoute nextRoute) {
    log('didChangeNext ${nextRoute?.name}');
66 67
  }

68
  @override
69 70 71 72
  void dispose() {
    log('dispose');
    _entries.forEach((OverlayEntry entry) { entry.remove(); });
    _entries.clear();
73
    routes.remove(this);
74 75 76 77
  }

}

78
Future<Null> runNavigatorTest(
79 80
  WidgetTester tester,
  NavigatorState host,
Hixie's avatar
Hixie committed
81
  NavigatorTransactionCallback test,
82
  List<String> expectations
83
) async {
84
  expect(host, isNotNull);
Hixie's avatar
Hixie committed
85
  host.openTransaction(test);
86 87
  expect(results, equals(expectations));
  results.clear();
88
  await tester.pump();
89 90 91
}

void main() {
92
  testWidgets('Route management - push, replace, pop', (WidgetTester tester) async {
93
    GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
94
    await tester.pumpWidget(new Navigator(
95 96 97 98
      key: navigatorKey,
      onGenerateRoute: (_) => new TestRoute('initial')
    ));
    NavigatorState host = navigatorKey.currentState;
99
    await runNavigatorTest(
100 101 102 103
      tester,
      host,
      (NavigatorTransaction transaction) {
      },
104
      <String>[
105 106 107 108 109 110
        'initial: install',
        'initial: didPush',
        'initial: didChangeNext null',
      ]
    );
    TestRoute second;
111
    await runNavigatorTest(
112 113 114 115 116
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.push(second = new TestRoute('second'));
      },
117
      <String>[
118 119 120 121 122 123
        'second: install',
        'second: didPush',
        'second: didChangeNext null',
        'initial: didChangeNext second',
      ]
    );
124
    await runNavigatorTest(
125 126 127 128 129
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.push(new TestRoute('third'));
      },
130
      <String>[
131 132 133 134 135 136
        'third: install',
        'third: didPush',
        'third: didChangeNext null',
        'second: didChangeNext third',
      ]
    );
137
    await runNavigatorTest(
138 139 140 141 142
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.replace(oldRoute: second, newRoute: new TestRoute('two'));
      },
143
      <String>[
144 145 146 147 148 149 150
        'two: install',
        'two: didReplace second',
        'two: didChangeNext third',
        'initial: didChangeNext two',
        'second: dispose',
      ]
    );
151
    await runNavigatorTest(
152 153 154 155 156
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.pop('hello');
      },
157
      <String>[
158 159 160 161 162
        'third: didPop hello',
        'third: dispose',
        'two: didPopNext third',
      ]
    );
163
    await runNavigatorTest(
164 165 166 167 168
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.pop('good bye');
      },
169
      <String>[
170 171 172 173 174
        'two: didPop good bye',
        'two: dispose',
        'initial: didPopNext two',
      ]
    );
175
    await tester.pumpWidget(new Container());
176
    expect(results, equals(<String>['initial: dispose']));
177 178
    expect(routes.isEmpty, isTrue);
    results.clear();
179 180
  });

181
  testWidgets('Route management - push, remove, pop', (WidgetTester tester) async {
182
    GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
183
    await tester.pumpWidget(new Navigator(
184 185 186 187
      key: navigatorKey,
      onGenerateRoute: (_) => new TestRoute('first')
    ));
    NavigatorState host = navigatorKey.currentState;
188
    await runNavigatorTest(
189 190 191 192
      tester,
      host,
      (NavigatorTransaction transaction) {
      },
193
      <String>[
194 195 196 197 198 199
        'first: install',
        'first: didPush',
        'first: didChangeNext null',
      ]
    );
    TestRoute second;
200
    await runNavigatorTest(
201 202 203 204 205
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.push(second = new TestRoute('second'));
      },
206
      <String>[
207 208 209 210 211 212
        'second: install',
        'second: didPush',
        'second: didChangeNext null',
        'first: didChangeNext second',
      ]
    );
213
    await runNavigatorTest(
214 215 216 217 218
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.push(new TestRoute('third'));
      },
219
      <String>[
220 221 222 223 224 225
        'third: install',
        'third: didPush',
        'third: didChangeNext null',
        'second: didChangeNext third',
      ]
    );
226
    await runNavigatorTest(
227 228 229 230 231
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.removeRouteBefore(second);
      },
232
      <String>[
233 234 235
        'first: dispose',
      ]
    );
236
    await runNavigatorTest(
237 238 239 240 241
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.pop('good bye');
      },
242
      <String>[
243 244 245 246 247
        'third: didPop good bye',
        'third: dispose',
        'second: didPopNext third',
      ]
    );
248
    await runNavigatorTest(
249 250 251 252 253
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.push(new TestRoute('three'));
      },
254
      <String>[
255 256 257 258 259 260 261
        'three: install',
        'three: didPush',
        'three: didChangeNext null',
        'second: didChangeNext three',
      ]
    );
    TestRoute four;
262
    await runNavigatorTest(
263 264 265 266 267
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.push(four = new TestRoute('four'));
      },
268
      <String>[
269 270 271 272 273 274
        'four: install',
        'four: didPush',
        'four: didChangeNext null',
        'three: didChangeNext four',
      ]
    );
275
    await runNavigatorTest(
276 277 278 279 280
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.removeRouteBefore(four);
      },
281
      <String>[
282 283 284 285
        'second: didChangeNext four',
        'three: dispose',
      ]
    );
286
    await runNavigatorTest(
287 288 289 290 291
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.pop('the end');
      },
292
      <String>[
293 294 295 296 297
        'four: didPop the end',
        'four: dispose',
        'second: didPopNext four',
      ]
    );
298
    await tester.pumpWidget(new Container());
299
    expect(results, equals(<String>['second: dispose']));
300 301
    expect(routes.isEmpty, isTrue);
    results.clear();
302 303
  });

304
  testWidgets('Route management - push, replace, popUntil', (WidgetTester tester) async {
305
    GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
306
    await tester.pumpWidget(new Navigator(
307 308 309 310
      key: navigatorKey,
      onGenerateRoute: (_) => new TestRoute('A')
    ));
    NavigatorState host = navigatorKey.currentState;
311
    await runNavigatorTest(
312 313 314 315
      tester,
      host,
      (NavigatorTransaction transaction) {
      },
316
      <String>[
317 318 319 320 321
        'A: install',
        'A: didPush',
        'A: didChangeNext null',
      ]
    );
322
    await runNavigatorTest(
323 324 325 326 327
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.push(new TestRoute('B'));
      },
328
      <String>[
329 330 331 332 333 334 335
        'B: install',
        'B: didPush',
        'B: didChangeNext null',
        'A: didChangeNext B',
      ]
    );
    TestRoute routeC;
336
    await runNavigatorTest(
337 338 339 340 341
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.push(routeC = new TestRoute('C'));
      },
342
      <String>[
343 344 345 346 347 348 349
        'C: install',
        'C: didPush',
        'C: didChangeNext null',
        'B: didChangeNext C',
      ]
    );
    TestRoute routeB;
350
    await runNavigatorTest(
351 352 353 354 355
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.replaceRouteBefore(anchorRoute: routeC, newRoute: routeB = new TestRoute('b'));
      },
356
      <String>[
357 358 359 360 361 362 363
        'b: install',
        'b: didReplace B',
        'b: didChangeNext C',
        'A: didChangeNext b',
        'B: dispose',
      ]
    );
364
    await runNavigatorTest(
365 366 367 368 369
      tester,
      host,
      (NavigatorTransaction transaction) {
        transaction.popUntil(routeB);
      },
370
      <String>[
371 372 373 374 375
        'C: didPop null',
        'C: dispose',
        'b: didPopNext C',
      ]
    );
376
    await tester.pumpWidget(new Container());
377
    expect(results, equals(<String>['A: dispose', 'b: dispose']));
378 379
    expect(routes.isEmpty, isTrue);
    results.clear();
380 381
  });
}