routes_test.dart 9.29 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 19 20 21 22 23 24 25 26
class TestRoute extends Route<String> {
  TestRoute(this.name);
  final String name;

  List<OverlayEntry> get overlayEntries => _entries;

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

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

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

  void didPush() {
    log('didPush');
  }

  void didReplace(TestRoute oldRoute) {
    log('didReplace ${oldRoute.name}');
  }

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

  void didPopNext(TestRoute nextRoute) {
    log('didPopNext ${nextRoute.name}');
  }

Hixie's avatar
Hixie committed
58 59
  void didChangeNext(TestRoute nextRoute) {
    log('didChangeNext ${nextRoute?.name}');
60 61 62 63 64 65
  }

  void dispose() {
    log('dispose');
    _entries.forEach((OverlayEntry entry) { entry.remove(); });
    _entries.clear();
66
    routes.remove(this);
67 68 69 70 71 72 73
  }

}

void runNavigatorTest(
  WidgetTester tester,
  NavigatorState host,
Hixie's avatar
Hixie committed
74
  NavigatorTransactionCallback test,
75 76 77
  List<String> expectations
) {
  expect(host, isNotNull);
Hixie's avatar
Hixie committed
78
  host.openTransaction(test);
79 80 81 82 83 84
  expect(results, equals(expectations));
  results.clear();
  tester.pump();
}

void main() {
85
  test('Route management - push, replace, pop', () {
86 87 88 89 90 91 92 93 94 95
    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
96
        (NavigatorTransaction transaction) {
97 98 99 100
        },
        [
          'initial: install',
          'initial: didPush',
Hixie's avatar
Hixie committed
101
          'initial: didChangeNext null',
102 103 104 105 106 107
        ]
      );
      TestRoute second;
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
108
        (NavigatorTransaction transaction) {
109 110 111 112 113
          transaction.push(second = new TestRoute('second'));
        },
        [
          'second: install',
          'second: didPush',
Hixie's avatar
Hixie committed
114 115
          'second: didChangeNext null',
          'initial: didChangeNext second',
116 117 118 119 120
        ]
      );
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
121
        (NavigatorTransaction transaction) {
122 123 124 125 126
          transaction.push(new TestRoute('third'));
        },
        [
          'third: install',
          'third: didPush',
Hixie's avatar
Hixie committed
127 128
          'third: didChangeNext null',
          'second: didChangeNext third',
129 130 131 132 133
        ]
      );
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
134
        (NavigatorTransaction transaction) {
135 136 137 138 139
          transaction.replace(oldRoute: second, newRoute: new TestRoute('two'));
        },
        [
          'two: install',
          'two: didReplace second',
Hixie's avatar
Hixie committed
140 141
          'two: didChangeNext third',
          'initial: didChangeNext two',
142 143 144 145 146 147
          'second: dispose',
        ]
      );
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
148
        (NavigatorTransaction transaction) {
149 150 151 152
          transaction.pop('hello');
        },
        [
          'third: didPop hello',
153
          'third: dispose',
154 155 156 157 158 159
          'two: didPopNext third',
        ]
      );
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
160
        (NavigatorTransaction transaction) {
161 162 163 164
          transaction.pop('good bye');
        },
        [
          'two: didPop good bye',
165
          'two: dispose',
166 167 168
          'initial: didPopNext two',
        ]
      );
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
      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
187
        (NavigatorTransaction transaction) {
188 189 190 191
        },
        [
          'first: install',
          'first: didPush',
Hixie's avatar
Hixie committed
192
          'first: didChangeNext null',
193 194 195 196 197 198
        ]
      );
      TestRoute second;
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
199
        (NavigatorTransaction transaction) {
200 201 202 203 204
          transaction.push(second = new TestRoute('second'));
        },
        [
          'second: install',
          'second: didPush',
Hixie's avatar
Hixie committed
205 206
          'second: didChangeNext null',
          'first: didChangeNext second',
207 208 209 210 211
        ]
      );
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
212
        (NavigatorTransaction transaction) {
213 214 215 216 217
          transaction.push(new TestRoute('third'));
        },
        [
          'third: install',
          'third: didPush',
Hixie's avatar
Hixie committed
218 219
          'third: didChangeNext null',
          'second: didChangeNext third',
220 221 222 223 224
        ]
      );
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
225
        (NavigatorTransaction transaction) {
226 227 228 229 230 231 232 233 234
          transaction.removeRouteBefore(second);
        },
        [
          'first: dispose',
        ]
      );
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
235
        (NavigatorTransaction transaction) {
236 237 238 239 240 241 242 243 244 245 246
          transaction.pop('good bye');
        },
        [
          'third: didPop good bye',
          'third: dispose',
          'second: didPopNext third',
        ]
      );
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
247
        (NavigatorTransaction transaction) {
248 249 250 251 252
          transaction.push(new TestRoute('three'));
        },
        [
          'three: install',
          'three: didPush',
Hixie's avatar
Hixie committed
253 254
          'three: didChangeNext null',
          'second: didChangeNext three',
255 256 257 258 259 260
        ]
      );
      TestRoute four;
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
261
        (NavigatorTransaction transaction) {
262 263 264 265 266
          transaction.push(four = new TestRoute('four'));
        },
        [
          'four: install',
          'four: didPush',
Hixie's avatar
Hixie committed
267 268
          'four: didChangeNext null',
          'three: didChangeNext four',
269 270 271 272 273
        ]
      );
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
274
        (NavigatorTransaction transaction) {
275 276 277
          transaction.removeRouteBefore(four);
        },
        [
Hixie's avatar
Hixie committed
278
          'second: didChangeNext four',
279 280 281 282 283 284
          'three: dispose',
        ]
      );
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
285
        (NavigatorTransaction transaction) {
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
          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
312
        (NavigatorTransaction transaction) {
313 314 315 316
        },
        [
          'A: install',
          'A: didPush',
Hixie's avatar
Hixie committed
317
          'A: didChangeNext null',
318 319 320 321 322
        ]
      );
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
323
        (NavigatorTransaction transaction) {
324 325 326 327 328
          transaction.push(new TestRoute('B'));
        },
        [
          'B: install',
          'B: didPush',
Hixie's avatar
Hixie committed
329 330
          'B: didChangeNext null',
          'A: didChangeNext B',
331 332 333 334 335 336
        ]
      );
      TestRoute routeC;
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
337
        (NavigatorTransaction transaction) {
338 339 340 341 342
          transaction.push(routeC = new TestRoute('C'));
        },
        [
          'C: install',
          'C: didPush',
Hixie's avatar
Hixie committed
343 344
          'C: didChangeNext null',
          'B: didChangeNext C',
345 346 347 348 349 350
        ]
      );
      TestRoute routeB;
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
351
        (NavigatorTransaction transaction) {
352 353 354 355 356
          transaction.replaceRouteBefore(anchorRoute: routeC, newRoute: routeB = new TestRoute('b'));
        },
        [
          'b: install',
          'b: didReplace B',
Hixie's avatar
Hixie committed
357 358
          'b: didChangeNext C',
          'A: didChangeNext b',
359 360 361 362 363 364
          'B: dispose',
        ]
      );
      runNavigatorTest(
        tester,
        host,
Hixie's avatar
Hixie committed
365
        (NavigatorTransaction transaction) {
366 367 368 369 370 371 372 373 374 375 376 377
          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();
378 379 380
    });
  });
}