routes_test.dart 9.38 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 12
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
import 'package:test/test.dart';

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

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

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

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

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

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

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

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

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

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

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

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

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

}

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

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

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

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