diff --git a/lib/src/generators/router/generator/router_class/router_class_builder_helper.dart b/lib/src/generators/router/generator/router_class/router_class_builder_helper.dart index a5c6348..5369e70 100644 --- a/lib/src/generators/router/generator/router_class/router_class_builder_helper.dart +++ b/lib/src/generators/router/generator/router_class/router_class_builder_helper.dart @@ -156,6 +156,13 @@ mixin class RouterClassBuilderHelper { routeTypeImport: 'package:flutter/material.dart', ); } else if (route.routeType == RouteType.custom) { + // Navigator 1 has no BuildContext to call customRouteBuilder with. + if (route.customRouteBuilder != null) { + // ignore: avoid_print + print( + '\nWARNING => CustomRoute.customRouteBuilder on \'${route.routeName}\' is only supported by the Navigator 2 router.\n' + 'Set `navigator2: true` in the stacked_generator|stackedRouterGenerator builder options in build.yaml to use it; it is ignored by the default router.\n'); + } return route.getRouteRegisterCode( routeType: 'PageRouteBuilder', routeTypeImport: 'package:flutter/material.dart', diff --git a/test/router/router_class/router_class_builder_helper_test.dart b/test/router/router_class/router_class_builder_helper_test.dart index 28a17b4..5329787 100644 --- a/test/router/router_class/router_class_builder_helper_test.dart +++ b/test/router/router_class/router_class_builder_helper_test.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:stacked_generator/src/generators/router/generator/router_class/router_class_builder.dart'; import 'package:stacked_generator/src/generators/router/route_config/material_route_config.dart'; import 'package:stacked_generator/src/generators/router_common/models/importable_type.dart'; @@ -93,6 +95,115 @@ void main() { expect(generatedCode, contains('MaterialPageRoute'), reason: 'Should contain MaterialPageRoute for routes'); }, ); + + test( + 'a CustomRoute with a customRouteBuilder still generates the same PageRouteBuilder output ' + '(Navigator 1 cannot invoke customRouteBuilder without a BuildContext)', + () { + const withoutBuilder = RouteConfig( + name: 'bottomSheetView', + pathName: 'bottomSheetPath', + className: 'BottomSheetClass', + classImport: 'ui/bottom_sheet_class.dart', + routeType: RouteType.custom, + ); + + final withBuilder = RouteConfig( + name: 'bottomSheetView', + pathName: 'bottomSheetPath', + className: 'BottomSheetClass', + classImport: 'ui/bottom_sheet_class.dart', + routeType: RouteType.custom, + customRouteBuilder: ResolvedType( + name: 'RouteBuilders.bottomSheetBuilder', + import: 'ui/route_builders.dart', + ), + ); + + final generatedWithout = routerClassBuilderHelper + .mapOfPages([withoutBuilder]).buildLibraryForClass; + final generatedWith = runZoned( + () => routerClassBuilderHelper + .mapOfPages([withBuilder]).buildLibraryForClass, + zoneSpecification: ZoneSpecification( + print: (self, parent, zone, line) {}, + ), + ); + + expect(generatedWith, equals(generatedWithout), + reason: + 'Setting customRouteBuilder must not change the Navigator 1 output: ' + 'it still falls back to PageRouteBuilder unchanged, since Navigator 1 ' + 'has no BuildContext to invoke the builder with.'); + expect(generatedWith, contains('PageRouteBuilder')); + expect(generatedWith, isNot(contains('bottomSheetBuilder'))); + }, + ); + + test( + 'a CustomRoute with a customRouteBuilder emits a warning pointing to navigator2', + () async { + final routes = [ + RouteConfig( + name: 'bottomSheetView', + pathName: 'bottomSheetPath', + className: 'BottomSheetClass', + classImport: 'ui/bottom_sheet_class.dart', + routeType: RouteType.custom, + customRouteBuilder: ResolvedType( + name: 'RouteBuilders.bottomSheetBuilder', + import: 'ui/route_builders.dart', + ), + ), + ]; + + final printedLines = []; + await runZoned( + () async { + routerClassBuilderHelper.mapOfPages(routes); + }, + zoneSpecification: ZoneSpecification( + print: (self, parent, zone, line) => printedLines.add(line), + ), + ); + + final combined = printedLines.join('\n'); + expect(combined, contains('WARNING')); + expect(combined, contains('customRouteBuilder')); + expect(combined, contains(routes.first.routeName)); + expect(combined, contains('navigator2: true')); + expect(combined, contains('Navigator 2')); + }, + ); + + test( + 'a CustomRoute without a customRouteBuilder does not emit any warning', + () async { + final routes = [ + const RouteConfig( + name: 'bottomSheetView', + pathName: 'bottomSheetPath', + className: 'BottomSheetClass', + classImport: 'ui/bottom_sheet_class.dart', + routeType: RouteType.custom, + ), + ]; + + final printedLines = []; + await runZoned( + () async { + routerClassBuilderHelper.mapOfPages(routes); + }, + zoneSpecification: ZoneSpecification( + print: (self, parent, zone, line) => printedLines.add(line), + ), + ); + + expect(printedLines, isEmpty, + reason: + 'No warning should be printed when customRouteBuilder is not set'); + }, + ); }); }); }