blob: a5902d47dfee1003ab1af9853e56cbd3b2908a24 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:go_router/go_router.dart';
import 'test_helpers.dart';
void main() {
group('updateShouldNotify', () {
test('does not update when goRouter does not change', () {
final GoRouter goRouter = GoRouter(
routes: <GoRoute>[
GoRoute(
path: '/',
builder: (_, __) => const Page1(),
),
],
);
final bool shouldNotify = setupInheritedGoRouterChange(
oldGoRouter: goRouter,
newGoRouter: goRouter,
);
expect(shouldNotify, false);
});
test('does not update even when goRouter changes', () {
final GoRouter oldGoRouter = GoRouter(
routes: <GoRoute>[
GoRoute(
path: '/',
builder: (_, __) => const Page1(),
),
],
);
final GoRouter newGoRouter = GoRouter(
routes: <GoRoute>[
GoRoute(
path: '/',
builder: (_, __) => const Page2(),
),
],
);
final bool shouldNotify = setupInheritedGoRouterChange(
oldGoRouter: oldGoRouter,
newGoRouter: newGoRouter,
);
expect(shouldNotify, false);
});
});
test('adds [goRouter] as a diagnostics property', () {
final GoRouter goRouter = GoRouter(
routes: <GoRoute>[
GoRoute(
path: '/',
builder: (_, __) => const Page1(),
),
],
);
final InheritedGoRouter inheritedGoRouter = InheritedGoRouter(
goRouter: goRouter,
child: Container(),
);
final DiagnosticPropertiesBuilder properties =
DiagnosticPropertiesBuilder();
inheritedGoRouter.debugFillProperties(properties);
expect(properties.properties.length, 1);
expect(properties.properties.first, isA<DiagnosticsProperty<GoRouter>>());
expect(properties.properties.first.value, goRouter);
});
testWidgets("mediates Widget's access to GoRouter.",
(WidgetTester tester) async {
final MockGoRouter router = MockGoRouter();
await tester.pumpWidget(MaterialApp(
home: InheritedGoRouter(goRouter: router, child: const _MyWidget())));
await tester.tap(find.text('My Page'));
expect(router.latestPushedName, 'my_page');
});
testWidgets('builder can access GoRouter', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/110512.
late final GoRouter buildContextRouter;
final GoRouter router = GoRouter(
initialLocation: '/',
routes: <GoRoute>[
GoRoute(
path: '/',
builder: (BuildContext context, __) {
buildContextRouter = GoRouter.of(context);
return const DummyScreen();
},
)
],
);
addTearDown(router.dispose);
await tester.pumpWidget(
MaterialApp.router(
routeInformationProvider: router.routeInformationProvider,
routeInformationParser: router.routeInformationParser,
routerDelegate: router.routerDelegate),
);
expect(buildContextRouter, isNotNull);
expect(buildContextRouter, equals(router));
});
}
bool setupInheritedGoRouterChange({
required GoRouter oldGoRouter,
required GoRouter newGoRouter,
}) {
final InheritedGoRouter oldInheritedGoRouter = InheritedGoRouter(
goRouter: oldGoRouter,
child: Container(),
);
final InheritedGoRouter newInheritedGoRouter = InheritedGoRouter(
goRouter: newGoRouter,
child: Container(),
);
return newInheritedGoRouter.updateShouldNotify(
oldInheritedGoRouter,
);
}
class Page1 extends StatelessWidget {
const Page1({super.key});
@override
Widget build(BuildContext context) => Container();
}
class Page2 extends StatelessWidget {
const Page2({super.key});
@override
Widget build(BuildContext context) => Container();
}
class _MyWidget extends StatelessWidget {
const _MyWidget();
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => context.pushNamed('my_page'),
child: const Text('My Page'));
}
}
class MockGoRouter extends GoRouter {
MockGoRouter()
: super.routingConfig(
routingConfig: const ConstantRoutingConfig(
RoutingConfig(routes: <RouteBase>[])));
late String latestPushedName;
@override
Future<T?> pushNamed<T extends Object?>(String name,
{Map<String, String> pathParameters = const <String, String>{},
Map<String, dynamic> queryParameters = const <String, dynamic>{},
Object? extra}) {
latestPushedName = name;
return Future<T?>.value();
}
@override
BackButtonDispatcher get backButtonDispatcher => RootBackButtonDispatcher();
}