Skip to content

Commit

Permalink
Change signature of builders to return RouteSettings
Browse files Browse the repository at this point in the history
Fixes #140
  • Loading branch information
Tom Gilder authored and Tom Gilder committed Jun 17, 2021
1 parent b9a15e7 commit f6db883
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# 0.9.4

* Fixed: an issue where pages were incorrectly rebuilding, causing state such as the active tab to reset
* Fixed: you can now use the ternary operator in page builders without having to do extra casts

# 0.9.3

Expand Down
44 changes: 32 additions & 12 deletions lib/routemaster.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ part 'src/observers.dart';
part 'src/route_data.dart';

/// A function that builds a [Page] from given [RouteData].
typedef PageBuilder = Page Function(RouteData route);
typedef PageBuilder = RouteSettings Function(RouteData route);

/// A function that returns a [Page] when the given [path] couldn't be found.
typedef UnknownRouteCallback = Page Function(String path);
typedef UnknownRouteCallback = RouteSettings Function(String path);

/// A standard simple routing table which takes a map of routes.
///
Expand Down Expand Up @@ -84,7 +84,7 @@ class RouteMap {
/// 2. Use the routing delegate to, for instance, redirect to another route
/// and return null.
///
Page onUnknownRoute(String path) {
RouteSettings onUnknownRoute(String path) {
if (_onUnknownRoute != null) {
return _onUnknownRoute!(path);
}
Expand Down Expand Up @@ -598,10 +598,13 @@ class RoutemasterDelegate extends RouterDelegate<RouteData>
);

// Get a page wrapper object for the current route
final page = routerData.builder(routeData);
_assertIsPage(page, routeData.fullPath);

final current = isLastRoute
? _createPageWrapper(
routeRequest: request,
page: routerData.builder(routeData),
page: page as Page,
routeData: routeData,
)
: _getOrCreatePageWrapper(
Expand Down Expand Up @@ -696,7 +699,7 @@ class RoutemasterDelegate extends RouterDelegate<RouteData>
// No current route, create a new one
return _createPageWrapper(
routeRequest: routeRequest,
page: routerResult.builder(routeData),
page: routerResult.builder(routeData) as Page,
routeData: routeData,
);
}
Expand All @@ -712,9 +715,12 @@ class RoutemasterDelegate extends RouterDelegate<RouteData>
isReplacement: routeRequest.isReplacement,
);

final page = routerResult.builder(routeData);
_assertIsPage(page, routeData.fullPath);

final wrapper = _createPageWrapper(
routeRequest: routeRequest,
page: routerResult.builder(routeData),
page: routerResult.builder(routeData) as Page,
routeData: routeData,
);

Expand Down Expand Up @@ -789,7 +795,10 @@ class RoutemasterDelegate extends RouterDelegate<RouteData>

List<PageWrapper> _onUnknownRoute(_RouteRequest routeRequest) {
final requestedPath = routeRequest.uri;
final result = _state.routeMap!.onUnknownRoute(requestedPath.toString());
final fullPath = requestedPath.toString();
final result = _state.routeMap!.onUnknownRoute(fullPath);

_assertIsPage(result, fullPath);

if (result is Redirect) {
final redirectResult = _createAllPageWrappers(
Expand All @@ -805,11 +814,15 @@ class RoutemasterDelegate extends RouterDelegate<RouteData>
}

// Return 404 page
final routeData = RouteData.fromUri(
requestedPath,
isReplacement: routeRequest.isReplacement,
);
return [PageWrapper.fromPage(routeData: routeData, page: result)];
return [
PageWrapper.fromPage(
routeData: RouteData.fromUri(
requestedPath,
isReplacement: routeRequest.isReplacement,
),
page: result as Page,
)
];
}

List<String> _debugCheckRedirectLoop(
Expand Down Expand Up @@ -1151,3 +1164,10 @@ class _StackNavigatorState extends NavigatorState {
super.dispose();
}
}

void _assertIsPage(RouteSettings page, String route) {
assert(
page is Page,
"Route builders must return a Page object. The route builder for '$route' instead returned an object of type '${page.runtimeType}'.",
);
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: routemaster
description: Easy-to-use Navigator 2.0 router for web, mobile and desktop. URL-based routing, simple navigation of tabs and nested routes.
version: 0.9.4-dev1
version: 0.9.4
homepage: https://github.com/tomgilder/routemaster

environment:
Expand Down
60 changes: 60 additions & 0 deletions test/router_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,64 @@ void main() {

expect(find.byType(PageTwo), findsOneWidget);
});

test('Can use ternary operator in route map', () {
const id = 0;

// This just needs to compile to pass
RouteMap(
onUnknownRoute: (_) {
return id == 0 ? const Redirect('/two') : const MaterialPageOne();
},
routes: {
'/two': (_) {
return id == 0 ? const NotFound() : const MaterialPageOne();
},
},
);
});

testWidgets('Asserts when Page not returned from not found', (tester) async {
final delegate = RoutemasterDelegate(
routesBuilder: (_) => RouteMap(
onUnknownRoute: (_) => NotAPage(),
routes: {'/': (_) => const MaterialPageOne()},
),
);

await tester.pumpWidget(
MaterialApp.router(
routeInformationParser: const RoutemasterParser(),
routerDelegate: delegate,
),
);

delegate.push('/404');
await tester.pump();

final exception = tester.takeException() as AssertionError;
expect(
exception.message,
"Route builders must return a Page object. The route builder for '/404' instead returned an object of type 'NotAPage'.",
);
});

testWidgets('Asserts when Page not returned from builder', (tester) async {
await tester.pumpWidget(
MaterialApp.router(
routeInformationParser: const RoutemasterParser(),
routerDelegate: RoutemasterDelegate(
routesBuilder: (_) => RouteMap(routes: {'/': (_) => NotAPage()}),
),
),
);

final exception = tester.takeException() as AssertionError;
expect(
exception.message,
"Route builders must return a Page object. The route builder for '/' instead returned an object of type 'NotAPage'.",
);
});
}

class QueryParamEcho extends StatelessWidget {
Expand All @@ -537,3 +595,5 @@ class QueryParamEcho extends StatelessWidget {
return Scaffold(body: Text(query));
}
}

class NotAPage extends RouteSettings {}

0 comments on commit f6db883

Please sign in to comment.