import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:go_router/go_router.dart';
void main() {
group('RouteMatch', () {
test('simple', () {
final route = GoRoute(path: '/users/:userId', builder: _builder);
final pathParameters = <String, String>{};
final List<RouteMatchBase> matches = RouteMatchBase.match(
route: route,
pathParameters: pathParameters,
uri: Uri.parse('/users/123'),
rootNavigatorKey: GlobalKey<NavigatorState>(),
);
expect(matches.length, 1);
final RouteMatchBase match = matches.first;
expect(match.route, route);
expect(match.matchedLocation, '/users/123');
expect(pathParameters['userId'], '123');
expect(match.pageKey, isNotNull);
});
test('ShellRoute has a unique pageKey', () {
final route = ShellRoute(
builder: _shellBuilder,
routes: <GoRoute>[GoRoute(path: '/users/:userId', builder: _builder)],
);
final pathParameters = <String, String>{};
final List<RouteMatchBase> matches = RouteMatchBase.match(
route: route,
uri: Uri.parse('/users/123'),
rootNavigatorKey: GlobalKey<NavigatorState>(),
pathParameters: pathParameters,
);
expect(matches.length, 1);
expect(matches.first.pageKey, isNotNull);
});
test('ShellRoute Match has stable unique key', () {
final route = ShellRoute(
builder: _shellBuilder,
routes: <GoRoute>[GoRoute(path: '/users/:userId', builder: _builder)],
);
final pathParameters = <String, String>{};
final List<RouteMatchBase> matches1 = RouteMatchBase.match(
route: route,
pathParameters: pathParameters,
uri: Uri.parse('/users/123'),
rootNavigatorKey: GlobalKey<NavigatorState>(),
);
final List<RouteMatchBase> matches2 = RouteMatchBase.match(
route: route,
pathParameters: pathParameters,
uri: Uri.parse('/users/1234'),
rootNavigatorKey: GlobalKey<NavigatorState>(),
);
expect(matches1.length, 1);
expect(matches2.length, 1);
expect(matches1.first.pageKey, matches2.first.pageKey);
});
test('GoRoute Match has stable unique key', () {
final route = GoRoute(path: '/users/:userId', builder: _builder);
final pathParameters = <String, String>{};
final List<RouteMatchBase> matches1 = RouteMatchBase.match(
route: route,
uri: Uri.parse('/users/123'),
rootNavigatorKey: GlobalKey<NavigatorState>(),
pathParameters: pathParameters,
);
final List<RouteMatchBase> matches2 = RouteMatchBase.match(
route: route,
uri: Uri.parse('/users/1234'),
rootNavigatorKey: GlobalKey<NavigatorState>(),
pathParameters: pathParameters,
);
expect(matches1.length, 1);
expect(matches2.length, 1);
expect(matches1.first.pageKey, matches2.first.pageKey);
});
});
test('complex parentNavigatorKey works', () {
final root = GlobalKey<NavigatorState>();
final shell1 = GlobalKey<NavigatorState>();
final shell2 = GlobalKey<NavigatorState>();
final route = GoRoute(
path: '/',
builder: _builder,
routes: <RouteBase>[
ShellRoute(
navigatorKey: shell1,
builder: _shellBuilder,
routes: <RouteBase>[
GoRoute(
path: 'a',
builder: _builder,
routes: <RouteBase>[
GoRoute(
parentNavigatorKey: root,
path: 'b',
builder: _builder,
routes: <RouteBase>[
ShellRoute(
navigatorKey: shell2,
builder: _shellBuilder,
routes: <RouteBase>[
GoRoute(
path: 'c',
builder: _builder,
routes: <RouteBase>[
GoRoute(
parentNavigatorKey: root,
path: 'd',
builder: _builder,
),
],
),
],
),
],
),
],
),
],
),
],
);
final pathParameters = <String, String>{};
final List<RouteMatchBase> matches = RouteMatchBase.match(
route: route,
pathParameters: pathParameters,
uri: Uri.parse('/a/b/c/d'),
rootNavigatorKey: root,
);
expect(matches.length, 4);
expect(
matches[0].route,
isA<GoRoute>().having((GoRoute route) => route.path, 'path', '/'),
);
expect(
matches[1].route,
isA<ShellRoute>().having(
(ShellRoute route) => route.navigatorKey,
'navigator key',
shell1,
),
);
expect(
matches[2].route,
isA<GoRoute>().having((GoRoute route) => route.path, 'path', 'b'),
);
expect(
matches[3].route,
isA<GoRoute>().having((GoRoute route) => route.path, 'path', 'd'),
);
});
group('ImperativeRouteMatch', () {
final matchList1 = RouteMatchList(
matches: <RouteMatch>[
RouteMatch(
route: GoRoute(path: '/', builder: (_, __) => const Text('hi')),
matchedLocation: '/',
pageKey: const ValueKey<String>('dummy'),
),
],
uri: Uri.parse('/'),
pathParameters: const <String, String>{},
);
final matchList2 = RouteMatchList(
matches: <RouteMatch>[
RouteMatch(
route: GoRoute(path: '/a', builder: (_, __) => const Text('a')),
matchedLocation: '/a',
pageKey: const ValueKey<String>('dummy'),
),
],
uri: Uri.parse('/a'),
pathParameters: const <String, String>{},
);
const key1 = ValueKey<String>('key1');
const key2 = ValueKey<String>('key2');
final completer1 = Completer<void>();
final completer2 = Completer<void>();
test('can equal and has', () async {
var match1 = ImperativeRouteMatch(
pageKey: key1,
matches: matchList1,
completer: completer1,
);
var match2 = ImperativeRouteMatch(
pageKey: key1,
matches: matchList1,
completer: completer1,
);
expect(match1 == match2, isTrue);
expect(match1.hashCode == match2.hashCode, isTrue);
match1 = ImperativeRouteMatch(
pageKey: key1,
matches: matchList1,
completer: completer1,
);
match2 = ImperativeRouteMatch(
pageKey: key2,
matches: matchList1,
completer: completer1,
);
expect(match1 == match2, isFalse);
expect(match1.hashCode == match2.hashCode, isFalse);
match1 = ImperativeRouteMatch(
pageKey: key1,
matches: matchList1,
completer: completer1,
);
match2 = ImperativeRouteMatch(
pageKey: key1,
matches: matchList2,
completer: completer1,
);
expect(match1 == match2, isFalse);
expect(match1.hashCode == match2.hashCode, isFalse);
match1 = ImperativeRouteMatch(
pageKey: key1,
matches: matchList1,
completer: completer1,
);
match2 = ImperativeRouteMatch(
pageKey: key1,
matches: matchList1,
completer: completer2,
);
expect(match1 == match2, isFalse);
expect(match1.hashCode == match2.hashCode, isFalse);
});
});
}
Widget _builder(BuildContext context, GoRouterState state) =>
const Placeholder();
Widget _shellBuilder(BuildContext context, GoRouterState state, Widget child) =>
const Placeholder();