Unbreak WidgetsApp when only a builder specified (#23976)
* update assert add test
* update docs
diff --git a/packages/flutter/lib/src/widgets/app.dart b/packages/flutter/lib/src/widgets/app.dart
index ed6d941..986dc13 100644
--- a/packages/flutter/lib/src/widgets/app.dart
+++ b/packages/flutter/lib/src/widgets/app.dart
@@ -71,14 +71,41 @@
///
/// The boolean arguments, [color], and [navigatorObservers] must not be null.
///
- /// If the [builder] is null, the [onGenerateRoute] and [pageRouteBuilder]
- /// arguments are required. The [onGenerateRoute] parameter corresponds to
- /// [Navigator.onGenerateRoute], and [pageRouteBuilder] will create a [PageRoute]
- /// that wraps newly built routes. If the [builder] is non-null
- /// and the [onGenerateRoute] argument is null, then the [builder] will not be
- /// provided with a [Navigator]. If [onGenerateRoute] is not provided,
- /// [navigatorKey], [onUnknownRoute], [navigatorObservers], and [initialRoute]
- /// must have their default values, as they will have no effect.
+ /// Most callers will want to use the [home] or [routes] parameters, or both.
+ /// The [home] parameter is a convenience for the following [routes] map:
+ ///
+ /// ```dart
+ /// <String, WidgetBuilder>{ '/': (BuildContext context) => myWidget }
+ /// ```
+ ///
+ /// It is possible to specify both [home] and [routes], but only if [routes] does
+ /// _not_ contain an entry for `'/'`. Conversely, if [home] is omitted, [routes]
+ /// _must_ contain an entry for `'/'`.
+ ///
+ /// If [home] or [routes] are not null, then either the [pageRoutebuilder] or
+ /// the [builder] parameter is required. These parameters will be used so
+ /// that the default routing implementation in [WidgetsApp] can wrap routes in
+ /// appropriate transitions. For example, [MaterialApp] will provide a
+ /// [pageRoutebuilder] that creates Material compliant hero animations between
+ /// routes, whereas the [CupertinoApp] provides Cupertino compliant hero
+ /// animations. Other implementations can provide other custom transitions here.
+ ///
+ /// The [builder] parameter is optional in all cases. It can be used to ensure that
+ /// all route entries get wrapped in another widget. It is invoked during the build
+ /// phase of this widget. If it is specified,
+ ///
+ /// It is also possible to provide a custom implementation of routing via the
+ /// [onGeneratedRoute] and [onUnknownRoute] parameters. These parameters correspond
+ /// to [Navigator.onGenerateRoute] and [Navigator.onUnknownRoute]. If [home], [routes],
+ /// and [builder] are null, or if they fail to create a requested route,
+ /// [onGeneratedRoute] will be invoked. If that fails, [onUnknownRoute] will be invoked.
+ ///
+ /// The [pageRouteBuilder] will create a [PageRoute] that wraps newly built routes.
+ /// If the [builder] is non-null and the [onGenerateRoute] argument is null, then the
+ /// [builder] will not be provided only with the context and the child widget, whereas
+ /// the [pageRouteBuilder] will be provided with [RouteSettings]. If [onGenerateRoute]
+ /// is not provided, [navigatorKey], [onUnknownRoute], [navigatorObservers], and
+ /// [initialRoute] must have their default values, as they will have no effect.
///
/// The `supportedLocales` argument must be a list of one or more elements.
/// By default supportedLocales is `[const Locale('en', 'US')]`.
@@ -148,10 +175,14 @@
'must have their initial values '
'(null, null, and the empty list, respectively).'
),
- assert(onGenerateRoute != null || pageRouteBuilder != null,
- 'If onGenerateRoute is not provided, the pageRouteBuilder must be specified '
- 'so that the default handler will know what kind of PageRoute transition '
- 'bo build.'),
+ assert(
+ builder != null ||
+ onGenerateRoute != null ||
+ pageRouteBuilder != null,
+ 'If neither builder nor onGenerateRoute are provided, the '
+ 'pageRouteBuilder must be specified so that the default handler '
+ 'will know what kind of PageRoute transition to build.'
+ ),
assert(title != null),
assert(color != null),
assert(supportedLocales != null && supportedLocales.isNotEmpty),
diff --git a/packages/flutter/test/widgets/app_test.dart b/packages/flutter/test/widgets/app_test.dart
new file mode 100644
index 0000000..08a7410
--- /dev/null
+++ b/packages/flutter/test/widgets/app_test.dart
@@ -0,0 +1,18 @@
+import 'package:flutter/widgets.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+ testWidgets('WidgetsApp with builder only', (WidgetTester tester) async {
+ final GlobalKey key = GlobalKey();
+ await tester.pumpWidget(
+ WidgetsApp(
+ key: key,
+ builder: (BuildContext context, Widget child) {
+ return const Placeholder();
+ },
+ color: const Color(0xFF123456),
+ ),
+ );
+ expect(find.byKey(key), findsOneWidget);
+ });
+}