Unverified Commit 0343555a authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Migrate more tests (#68037)

* Migrate more tests

* fix
parent dbf8cd4b
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
...@@ -13,17 +11,17 @@ import 'package:flutter/gestures.dart'; ...@@ -13,17 +11,17 @@ import 'package:flutter/gestures.dart';
class HoverClient extends StatefulWidget { class HoverClient extends StatefulWidget {
const HoverClient({ const HoverClient({
Key key, Key? key,
this.onHover, this.onHover,
this.child, this.child,
this.onEnter, this.onEnter,
this.onExit, this.onExit,
}) : super(key: key); }) : super(key: key);
final ValueChanged<bool> onHover; final ValueChanged<bool>? onHover;
final Widget child; final Widget? child;
final VoidCallback onEnter; final VoidCallback? onEnter;
final VoidCallback onExit; final VoidCallback? onExit;
@override @override
HoverClientState createState() => HoverClientState(); HoverClientState createState() => HoverClientState();
...@@ -32,19 +30,19 @@ class HoverClient extends StatefulWidget { ...@@ -32,19 +30,19 @@ class HoverClient extends StatefulWidget {
class HoverClientState extends State<HoverClient> { class HoverClientState extends State<HoverClient> {
void _onExit(PointerExitEvent details) { void _onExit(PointerExitEvent details) {
if (widget.onExit != null) { if (widget.onExit != null) {
widget.onExit(); widget.onExit!();
} }
if (widget.onHover != null) { if (widget.onHover != null) {
widget.onHover(false); widget.onHover!(false);
} }
} }
void _onEnter(PointerEnterEvent details) { void _onEnter(PointerEnterEvent details) {
if (widget.onEnter != null) { if (widget.onEnter != null) {
widget.onEnter(); widget.onEnter!();
} }
if (widget.onHover != null) { if (widget.onHover != null) {
widget.onHover(true); widget.onHover!(true);
} }
} }
...@@ -59,10 +57,10 @@ class HoverClientState extends State<HoverClient> { ...@@ -59,10 +57,10 @@ class HoverClientState extends State<HoverClient> {
} }
class HoverFeedback extends StatefulWidget { class HoverFeedback extends StatefulWidget {
const HoverFeedback({Key key, this.onEnter, this.onExit}) : super(key: key); const HoverFeedback({Key? key, this.onEnter, this.onExit}) : super(key: key);
final VoidCallback onEnter; final VoidCallback? onEnter;
final VoidCallback onExit; final VoidCallback? onExit;
@override @override
_HoverFeedbackState createState() => _HoverFeedbackState(); _HoverFeedbackState createState() => _HoverFeedbackState();
...@@ -87,9 +85,9 @@ class _HoverFeedbackState extends State<HoverFeedback> { ...@@ -87,9 +85,9 @@ class _HoverFeedbackState extends State<HoverFeedback> {
void main() { void main() {
testWidgets('detects pointer enter', (WidgetTester tester) async { testWidgets('detects pointer enter', (WidgetTester tester) async {
PointerEnterEvent enter; PointerEnterEvent? enter;
PointerHoverEvent move; PointerHoverEvent? move;
PointerExitEvent exit; PointerExitEvent? exit;
await tester.pumpWidget(Center( await tester.pumpWidget(Center(
child: MouseRegion( child: MouseRegion(
child: Container( child: Container(
...@@ -111,18 +109,18 @@ void main() { ...@@ -111,18 +109,18 @@ void main() {
exit = null; exit = null;
await gesture.moveTo(const Offset(400.0, 300.0)); await gesture.moveTo(const Offset(400.0, 300.0));
expect(move, isNotNull); expect(move, isNotNull);
expect(move.position, equals(const Offset(400.0, 300.0))); expect(move!.position, equals(const Offset(400.0, 300.0)));
expect(move.localPosition, equals(const Offset(50.0, 50.0))); expect(move!.localPosition, equals(const Offset(50.0, 50.0)));
expect(enter, isNotNull); expect(enter, isNotNull);
expect(enter.position, equals(const Offset(400.0, 300.0))); expect(enter!.position, equals(const Offset(400.0, 300.0)));
expect(enter.localPosition, equals(const Offset(50.0, 50.0))); expect(enter!.localPosition, equals(const Offset(50.0, 50.0)));
expect(exit, isNull); expect(exit, isNull);
}); });
testWidgets('detects pointer exiting', (WidgetTester tester) async { testWidgets('detects pointer exiting', (WidgetTester tester) async {
PointerEnterEvent enter; PointerEnterEvent? enter;
PointerHoverEvent move; PointerHoverEvent? move;
PointerExitEvent exit; PointerExitEvent? exit;
await tester.pumpWidget(Center( await tester.pumpWidget(Center(
child: MouseRegion( child: MouseRegion(
child: Container( child: Container(
...@@ -147,14 +145,14 @@ void main() { ...@@ -147,14 +145,14 @@ void main() {
expect(move, isNull); expect(move, isNull);
expect(enter, isNull); expect(enter, isNull);
expect(exit, isNotNull); expect(exit, isNotNull);
expect(exit.position, equals(const Offset(1.0, 1.0))); expect(exit!.position, equals(const Offset(1.0, 1.0)));
expect(exit.localPosition, equals(const Offset(-349.0, -249.0))); expect(exit!.localPosition, equals(const Offset(-349.0, -249.0)));
}); });
testWidgets('triggers pointer enter when a mouse is connected', (WidgetTester tester) async { testWidgets('triggers pointer enter when a mouse is connected', (WidgetTester tester) async {
PointerEnterEvent enter; PointerEnterEvent? enter;
PointerHoverEvent move; PointerHoverEvent? move;
PointerExitEvent exit; PointerExitEvent? exit;
await tester.pumpWidget(Center( await tester.pumpWidget(Center(
child: MouseRegion( child: MouseRegion(
child: const SizedBox( child: const SizedBox(
...@@ -173,15 +171,15 @@ void main() { ...@@ -173,15 +171,15 @@ void main() {
addTearDown(gesture.removePointer); addTearDown(gesture.removePointer);
expect(move, isNull); expect(move, isNull);
expect(enter, isNotNull); expect(enter, isNotNull);
expect(enter.position, equals(const Offset(400.0, 300.0))); expect(enter!.position, equals(const Offset(400.0, 300.0)));
expect(enter.localPosition, equals(const Offset(50.0, 50.0))); expect(enter!.localPosition, equals(const Offset(50.0, 50.0)));
expect(exit, isNull); expect(exit, isNull);
}); });
testWidgets('triggers pointer exit when a mouse is disconnected', (WidgetTester tester) async { testWidgets('triggers pointer exit when a mouse is disconnected', (WidgetTester tester) async {
PointerEnterEvent enter; PointerEnterEvent? enter;
PointerHoverEvent move; PointerHoverEvent? move;
PointerExitEvent exit; PointerExitEvent? exit;
await tester.pumpWidget(Center( await tester.pumpWidget(Center(
child: MouseRegion( child: MouseRegion(
child: const SizedBox( child: const SizedBox(
...@@ -195,7 +193,7 @@ void main() { ...@@ -195,7 +193,7 @@ void main() {
)); ));
await tester.pump(); await tester.pump();
TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse); TestGesture? gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.addPointer(location: const Offset(400, 300)); await gesture.addPointer(location: const Offset(400, 300));
addTearDown(() => gesture?.removePointer); addTearDown(() => gesture?.removePointer);
await tester.pump(); await tester.pump();
...@@ -207,8 +205,8 @@ void main() { ...@@ -207,8 +205,8 @@ void main() {
expect(move, isNull); expect(move, isNull);
expect(enter, isNull); expect(enter, isNull);
expect(exit, isNotNull); expect(exit, isNotNull);
expect(exit.position, equals(const Offset(400.0, 300.0))); expect(exit!.position, equals(const Offset(400.0, 300.0)));
expect(exit.localPosition, equals(const Offset(50.0, 50.0))); expect(exit!.localPosition, equals(const Offset(50.0, 50.0)));
exit = null; exit = null;
await tester.pump(); await tester.pump();
expect(move, isNull); expect(move, isNull);
...@@ -217,9 +215,9 @@ void main() { ...@@ -217,9 +215,9 @@ void main() {
}); });
testWidgets('triggers pointer enter when widget appears', (WidgetTester tester) async { testWidgets('triggers pointer enter when widget appears', (WidgetTester tester) async {
PointerEnterEvent enter; PointerEnterEvent? enter;
PointerHoverEvent move; PointerHoverEvent? move;
PointerExitEvent exit; PointerExitEvent? exit;
await tester.pumpWidget(const Center( await tester.pumpWidget(const Center(
child: SizedBox( child: SizedBox(
width: 100.0, width: 100.0,
...@@ -248,15 +246,15 @@ void main() { ...@@ -248,15 +246,15 @@ void main() {
await tester.pump(); await tester.pump();
expect(move, isNull); expect(move, isNull);
expect(enter, isNotNull); expect(enter, isNotNull);
expect(enter.position, equals(const Offset(400.0, 300.0))); expect(enter!.position, equals(const Offset(400.0, 300.0)));
expect(enter.localPosition, equals(const Offset(50.0, 50.0))); expect(enter!.localPosition, equals(const Offset(50.0, 50.0)));
expect(exit, isNull); expect(exit, isNull);
}); });
testWidgets("doesn't trigger pointer exit when widget disappears", (WidgetTester tester) async { testWidgets("doesn't trigger pointer exit when widget disappears", (WidgetTester tester) async {
PointerEnterEvent enter; PointerEnterEvent? enter;
PointerHoverEvent move; PointerHoverEvent? move;
PointerExitEvent exit; PointerExitEvent? exit;
await tester.pumpWidget(Center( await tester.pumpWidget(Center(
child: MouseRegion( child: MouseRegion(
child: const SizedBox( child: const SizedBox(
...@@ -288,9 +286,9 @@ void main() { ...@@ -288,9 +286,9 @@ void main() {
}); });
testWidgets('triggers pointer enter when widget moves in', (WidgetTester tester) async { testWidgets('triggers pointer enter when widget moves in', (WidgetTester tester) async {
PointerEnterEvent enter; PointerEnterEvent? enter;
PointerHoverEvent move; PointerHoverEvent? move;
PointerExitEvent exit; PointerExitEvent? exit;
await tester.pumpWidget(Container( await tester.pumpWidget(Container(
alignment: Alignment.topLeft, alignment: Alignment.topLeft,
child: MouseRegion( child: MouseRegion(
...@@ -324,16 +322,16 @@ void main() { ...@@ -324,16 +322,16 @@ void main() {
)); ));
await tester.pump(); await tester.pump();
expect(enter, isNotNull); expect(enter, isNotNull);
expect(enter.position, equals(const Offset(401.0, 301.0))); expect(enter!.position, equals(const Offset(401.0, 301.0)));
expect(enter.localPosition, equals(const Offset(51.0, 51.0))); expect(enter!.localPosition, equals(const Offset(51.0, 51.0)));
expect(move, isNull); expect(move, isNull);
expect(exit, isNull); expect(exit, isNull);
}); });
testWidgets('triggers pointer exit when widget moves out', (WidgetTester tester) async { testWidgets('triggers pointer exit when widget moves out', (WidgetTester tester) async {
PointerEnterEvent enter; PointerEnterEvent? enter;
PointerHoverEvent move; PointerHoverEvent? move;
PointerExitEvent exit; PointerExitEvent? exit;
await tester.pumpWidget(Container( await tester.pumpWidget(Container(
alignment: Alignment.center, alignment: Alignment.center,
child: MouseRegion( child: MouseRegion(
...@@ -369,14 +367,14 @@ void main() { ...@@ -369,14 +367,14 @@ void main() {
expect(enter, isNull); expect(enter, isNull);
expect(move, isNull); expect(move, isNull);
expect(exit, isNotNull); expect(exit, isNotNull);
expect(exit.position, equals(const Offset(400, 300))); expect(exit!.position, equals(const Offset(400, 300)));
expect(exit.localPosition, equals(const Offset(50, 50))); expect(exit!.localPosition, equals(const Offset(50, 50)));
}); });
testWidgets('detects hover from touch devices', (WidgetTester tester) async { testWidgets('detects hover from touch devices', (WidgetTester tester) async {
PointerEnterEvent enter; PointerEnterEvent? enter;
PointerHoverEvent move; PointerHoverEvent? move;
PointerExitEvent exit; PointerExitEvent? exit;
await tester.pumpWidget(Center( await tester.pumpWidget(Center(
child: MouseRegion( child: MouseRegion(
child: Container( child: Container(
...@@ -398,8 +396,8 @@ void main() { ...@@ -398,8 +396,8 @@ void main() {
exit = null; exit = null;
await gesture.moveTo(const Offset(400.0, 300.0)); await gesture.moveTo(const Offset(400.0, 300.0));
expect(move, isNotNull); expect(move, isNotNull);
expect(move.position, equals(const Offset(400.0, 300.0))); expect(move!.position, equals(const Offset(400.0, 300.0)));
expect(move.localPosition, equals(const Offset(50.0, 50.0))); expect(move!.localPosition, equals(const Offset(50.0, 50.0)));
expect(enter, isNull); expect(enter, isNull);
expect(exit, isNull); expect(exit, isNull);
}); });
...@@ -589,21 +587,21 @@ void main() { ...@@ -589,21 +587,21 @@ void main() {
addTearDown(gesture.removePointer); addTearDown(gesture.removePointer);
await tester.pump(); await tester.pump();
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic); expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
await gesture.moveTo(const Offset(5, 5)); await gesture.moveTo(const Offset(5, 5));
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text); expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
await gesture.moveTo(const Offset(100, 100)); await gesture.moveTo(const Offset(100, 100));
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic); expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
}); });
testWidgets('MouseRegion uses updated callbacks', (WidgetTester tester) async { testWidgets('MouseRegion uses updated callbacks', (WidgetTester tester) async {
final List<String> logs = <String>[]; final List<String> logs = <String>[];
Widget hoverableContainer({ Widget hoverableContainer({
PointerEnterEventListener onEnter, PointerEnterEventListener? onEnter,
PointerHoverEventListener onHover, PointerHoverEventListener? onHover,
PointerExitEventListener onExit, PointerExitEventListener? onExit,
}) { }) {
return Container( return Container(
alignment: Alignment.topLeft, alignment: Alignment.topLeft,
...@@ -894,7 +892,7 @@ void main() { ...@@ -894,7 +892,7 @@ void main() {
); );
// Plug-in a mouse and move it to the center of the container. // Plug-in a mouse and move it to the center of the container.
TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse); TestGesture? gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.addPointer(location: Offset.zero); await gesture.addPointer(location: Offset.zero);
addTearDown(() => gesture?.removePointer()); addTearDown(() => gesture?.removePointer());
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -1072,7 +1070,7 @@ void main() { ...@@ -1072,7 +1070,7 @@ void main() {
bool hovered = false; bool hovered = false;
final List<bool> logHovered = <bool>[]; final List<bool> logHovered = <bool>[];
bool moved = false; bool moved = false;
StateSetter mySetState; late StateSetter mySetState;
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse); final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.addPointer(location: const Offset(5, 5)); await gesture.addPointer(location: const Offset(5, 5));
...@@ -1140,14 +1138,14 @@ void main() { ...@@ -1140,14 +1138,14 @@ void main() {
// | ——————————— | 130 // | ——————————— | 130
// —————————————————————— 150 // —————————————————————— 150
// x 0 20 50 100 130 150 // x 0 20 50 100 130 150
Widget tripleRegions({bool opaqueC, void Function(String) addLog}) { Widget tripleRegions({bool? opaqueC, required void Function(String) addLog}) {
// Same as MouseRegion, but when opaque is null, use the default value. // Same as MouseRegion, but when opaque is null, use the default value.
Widget mouseRegionWithOptionalOpaque({ Widget mouseRegionWithOptionalOpaque({
void Function(PointerEnterEvent e) onEnter, void Function(PointerEnterEvent e)? onEnter,
void Function(PointerHoverEvent e) onHover, void Function(PointerHoverEvent e)? onHover,
void Function(PointerExitEvent e) onExit, void Function(PointerExitEvent e)? onExit,
Widget child, Widget? child,
bool opaque, bool? opaque,
}) { }) {
if (opaque == null) { if (opaque == null) {
return MouseRegion(onEnter: onEnter, onHover: onHover, onExit: onExit, child: child); return MouseRegion(onEnter: onEnter, onHover: onHover, onExit: onExit, child: child);
...@@ -1492,7 +1490,7 @@ void main() { ...@@ -1492,7 +1490,7 @@ void main() {
await gesture.moveTo(const Offset(5, 5)); await gesture.moveTo(const Offset(5, 5));
expect(logPaints, <String>['paint']); expect(logPaints, <String>['paint']);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.forbidden); expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.forbidden);
expect(logEnters, <String>['enter']); expect(logEnters, <String>['enter']);
logPaints.clear(); logPaints.clear();
logEnters.clear(); logEnters.clear();
...@@ -1511,7 +1509,7 @@ void main() { ...@@ -1511,7 +1509,7 @@ void main() {
)); ));
expect(logPaints, <String>['paint']); expect(logPaints, <String>['paint']);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text); expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
expect(logEnters, isEmpty); expect(logEnters, isEmpty);
logPaints.clear(); logPaints.clear();
logEnters.clear(); logEnters.clear();
...@@ -1545,7 +1543,7 @@ void main() { ...@@ -1545,7 +1543,7 @@ void main() {
expect(logPaints, <String>['paint']); expect(logPaints, <String>['paint']);
expect(logEnters, <String>['enter']); expect(logEnters, <String>['enter']);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text); expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
logPaints.clear(); logPaints.clear();
logEnters.clear(); logEnters.clear();
...@@ -1566,7 +1564,7 @@ void main() { ...@@ -1566,7 +1564,7 @@ void main() {
expect(logPaints, <String>['paint']); expect(logPaints, <String>['paint']);
expect(logEnters, isEmpty); expect(logEnters, isEmpty);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.forbidden); expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.forbidden);
logPaints.clear(); logPaints.clear();
logEnters.clear(); logEnters.clear();
...@@ -1586,7 +1584,7 @@ void main() { ...@@ -1586,7 +1584,7 @@ void main() {
)); ));
expect(logPaints, <String>['paint']); expect(logPaints, <String>['paint']);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text); expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
expect(logEnters, isEmpty); expect(logEnters, isEmpty);
logPaints.clear(); logPaints.clear();
logEnters.clear(); logEnters.clear();
...@@ -1638,7 +1636,7 @@ void main() { ...@@ -1638,7 +1636,7 @@ void main() {
expect(logEnters, <String>['enter']); expect(logEnters, <String>['enter']);
expect(logExits, isEmpty); expect(logExits, isEmpty);
expect(logCursors, isNotEmpty); expect(logCursors, isNotEmpty);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click); expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click);
logEnters.clear(); logEnters.clear();
logExits.clear(); logExits.clear();
logCursors.clear(); logCursors.clear();
...@@ -1673,7 +1671,7 @@ void main() { ...@@ -1673,7 +1671,7 @@ void main() {
expect(logEnters, isEmpty); expect(logEnters, isEmpty);
expect(logExits, isEmpty); expect(logExits, isEmpty);
expect(logCursors, isEmpty); expect(logCursors, isEmpty);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click); expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click);
}); });
testWidgets("RenderMouseRegion's debugFillProperties when default", (WidgetTester tester) async { testWidgets("RenderMouseRegion's debugFillProperties when default", (WidgetTester tester) async {
...@@ -1737,8 +1735,8 @@ void main() { ...@@ -1737,8 +1735,8 @@ void main() {
class _Scaffold extends StatelessWidget { class _Scaffold extends StatelessWidget {
const _Scaffold({this.topLeft, this.background}); const _Scaffold({this.topLeft, this.background});
final Widget topLeft; final Widget? topLeft;
final Widget background; final Widget? background;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -1746,7 +1744,7 @@ class _Scaffold extends StatelessWidget { ...@@ -1746,7 +1744,7 @@ class _Scaffold extends StatelessWidget {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Stack( child: Stack(
children: <Widget>[ children: <Widget>[
if (background != null) background, if (background != null) background!,
Align( Align(
alignment: Alignment.topLeft, alignment: Alignment.topLeft,
child: topLeft, child: topLeft,
...@@ -1758,8 +1756,8 @@ class _Scaffold extends StatelessWidget { ...@@ -1758,8 +1756,8 @@ class _Scaffold extends StatelessWidget {
} }
class _DelegatedPainter extends CustomPainter { class _DelegatedPainter extends CustomPainter {
_DelegatedPainter({this.key, this.onPaint}); _DelegatedPainter({this.key, required this.onPaint});
final Key key; final Key? key;
final VoidCallback onPaint; final VoidCallback onPaint;
@override @override
...@@ -1804,7 +1802,7 @@ class _HoverClientWithClosuresState extends State<_HoverClientWithClosures> { ...@@ -1804,7 +1802,7 @@ class _HoverClientWithClosuresState extends State<_HoverClientWithClosures> {
// A column that aligns to the top left. // A column that aligns to the top left.
class _ColumnContainer extends StatelessWidget { class _ColumnContainer extends StatelessWidget {
const _ColumnContainer({ const _ColumnContainer({
@required this.children, required this.children,
}) : assert(children != null); }) : assert(children != null);
final List<Widget> children; final List<Widget> children;
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
...@@ -18,12 +16,12 @@ void checkTree(WidgetTester tester, List<BoxDecoration> expectedDecorations) { ...@@ -18,12 +16,12 @@ void checkTree(WidgetTester tester, List<BoxDecoration> expectedDecorations) {
expect(element.renderObject, isA<RenderStack>()); expect(element.renderObject, isA<RenderStack>());
final RenderStack renderObject = element.renderObject as RenderStack; final RenderStack renderObject = element.renderObject as RenderStack;
try { try {
RenderObject child = renderObject.firstChild; RenderObject? child = renderObject.firstChild;
for (final BoxDecoration decoration in expectedDecorations) { for (final BoxDecoration decoration in expectedDecorations) {
expect(child, isA<RenderDecoratedBox>()); expect(child, isA<RenderDecoratedBox>());
final RenderDecoratedBox decoratedBox = child as RenderDecoratedBox; final RenderDecoratedBox decoratedBox = child! as RenderDecoratedBox;
expect(decoratedBox.decoration, equals(decoration)); expect(decoratedBox.decoration, equals(decoration));
final StackParentData decoratedBoxParentData = decoratedBox.parentData as StackParentData; final StackParentData decoratedBoxParentData = decoratedBox.parentData! as StackParentData;
child = decoratedBoxParentData.nextSibling; child = decoratedBoxParentData.nextSibling;
} }
expect(child, isNull); expect(child, isNull);
...@@ -34,10 +32,13 @@ void checkTree(WidgetTester tester, List<BoxDecoration> expectedDecorations) { ...@@ -34,10 +32,13 @@ void checkTree(WidgetTester tester, List<BoxDecoration> expectedDecorations) {
} }
class MockMultiChildRenderObjectWidget extends MultiChildRenderObjectWidget { class MockMultiChildRenderObjectWidget extends MultiChildRenderObjectWidget {
MockMultiChildRenderObjectWidget({ Key key, List<Widget> children }) : super(key: key, children: children); MockMultiChildRenderObjectWidget({ Key? key, required List<Widget> children }) : super(key: key, children: children);
@override @override
RenderObject createRenderObject(BuildContext context) => null; RenderObject createRenderObject(BuildContext context) {
assert(false);
return FakeRenderObject();
}
} }
void main() { void main() {
...@@ -354,17 +355,11 @@ void main() { ...@@ -354,17 +355,11 @@ void main() {
checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationC]); checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationC]);
}); });
}
// Regression test for https://github.com/flutter/flutter/issues/37136. class FakeRenderObject extends RenderBox {
test('provides useful assertion message when one of the children is null', () { @override
bool assertionTriggered = false; void performLayout() {
try { size = constraints.biggest;
MockMultiChildRenderObjectWidget(children: const <Widget>[null]);
} catch (e) {
expect(e.toString(), contains("MockMultiChildRenderObjectWidget's children must not contain any null values,"));
assertionTriggered = true;
} }
expect(assertionTriggered, isTrue);
});
} }
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
...@@ -68,7 +66,7 @@ void main() { ...@@ -68,7 +66,7 @@ void main() {
List<String> _getChildOrder(RenderFlex flex) { List<String> _getChildOrder(RenderFlex flex) {
final List<String> childOrder = <String>[]; final List<String> childOrder = <String>[];
flex.visitChildren((RenderObject child) { flex.visitChildren((RenderObject child) {
childOrder.add(((child as RenderParagraph).text as TextSpan).text); childOrder.add(((child as RenderParagraph).text as TextSpan).text!);
}); });
return childOrder; return childOrder;
} }
...@@ -2,15 +2,13 @@ ...@@ -2,15 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'test_widgets.dart'; import 'test_widgets.dart';
class TestCustomPainter extends CustomPainter { class TestCustomPainter extends CustomPainter {
TestCustomPainter({ this.log, this.name }); TestCustomPainter({ required this.log, required this.name });
final List<String> log; final List<String> log;
final String name; final String name;
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
...@@ -60,11 +58,11 @@ void main() { ...@@ -60,11 +58,11 @@ void main() {
final NavigatorState navigator = tester.state(find.byType(Navigator)); final NavigatorState navigator = tester.state(find.byType(Navigator));
final List<String> log = <String>[]; final List<String> log = <String>[];
observer observer
..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
log.add('${route.settings.name} pushed, previous route: ${previousRoute.settings.name}'); log.add('${route!.settings.name} pushed, previous route: ${previousRoute!.settings.name}');
} }
..onRemoved = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onRemoved = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
log.add('${route.settings.name} removed, previous route: ${previousRoute?.settings?.name}'); log.add('${route!.settings.name} removed, previous route: ${previousRoute?.settings.name}');
}; };
......
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../flutter_test_alternative.dart' show Fake;
void main() { void main() {
testWidgets('Restoration Smoke Test', (WidgetTester tester) async { testWidgets('Restoration Smoke Test', (WidgetTester tester) async {
await tester.pumpWidget(const TestWidget()); await tester.pumpWidget(const TestWidget());
...@@ -306,7 +306,7 @@ void main() { ...@@ -306,7 +306,7 @@ void main() {
await tester.pumpWidget(const TestWidget()); await tester.pumpWidget(const TestWidget());
expect(findRoute('home', count: 0), findsOneWidget); expect(findRoute('home', count: 0), findsOneWidget);
final Route<Object> oldRoute = ModalRoute.of(tester.element(find.text('Route: home'))); final Route<Object> oldRoute = ModalRoute.of(tester.element(find.text('Route: home')))!;
expect(oldRoute.settings.name, 'home'); expect(oldRoute.settings.name, 'home');
tester.state<NavigatorState>(find.byType(Navigator)).restorableReplace(newRouteBuilder: _routeBuilder, arguments: 'Foo', oldRoute: oldRoute); tester.state<NavigatorState>(find.byType(Navigator)).restorableReplace(newRouteBuilder: _routeBuilder, arguments: 'Foo', oldRoute: oldRoute);
...@@ -342,7 +342,7 @@ void main() { ...@@ -342,7 +342,7 @@ void main() {
await tester.pumpWidget(const TestWidget()); await tester.pumpWidget(const TestWidget());
expect(findRoute('home', count: 0), findsOneWidget); expect(findRoute('home', count: 0), findsOneWidget);
final Route<Object> oldRoute = ModalRoute.of(tester.element(find.text('Route: home'))); final Route<Object> oldRoute = ModalRoute.of(tester.element(find.text('Route: home')))!;
expect(oldRoute.settings.name, 'home'); expect(oldRoute.settings.name, 'home');
tester.state<NavigatorState>(find.byType(Navigator)).restorableReplace(newRouteBuilder: _routeBuilder, arguments: 'Foo', oldRoute: oldRoute); tester.state<NavigatorState>(find.byType(Navigator)).restorableReplace(newRouteBuilder: _routeBuilder, arguments: 'Foo', oldRoute: oldRoute);
...@@ -362,7 +362,7 @@ void main() { ...@@ -362,7 +362,7 @@ void main() {
expect(findRoute('home', count: 0, skipOffstage: false), findsOneWidget); expect(findRoute('home', count: 0, skipOffstage: false), findsOneWidget);
expect(findRoute('Anchor', count: 1), findsOneWidget); expect(findRoute('Anchor', count: 1), findsOneWidget);
final Route<Object> anchor = ModalRoute.of(tester.element(find.text('Route: Anchor'))); final Route<Object> anchor = ModalRoute.of(tester.element(find.text('Route: Anchor')))!;
expect(anchor.settings.name, 'Anchor'); expect(anchor.settings.name, 'Anchor');
tester.state<NavigatorState>(find.byType(Navigator)).restorableReplaceRouteBelow(newRouteBuilder: _routeBuilder, arguments: 'Foo', anchorRoute: anchor); tester.state<NavigatorState>(find.byType(Navigator)).restorableReplaceRouteBelow(newRouteBuilder: _routeBuilder, arguments: 'Foo', anchorRoute: anchor);
...@@ -408,7 +408,7 @@ void main() { ...@@ -408,7 +408,7 @@ void main() {
expect(findRoute('home', count: 0, skipOffstage: false), findsOneWidget); expect(findRoute('home', count: 0, skipOffstage: false), findsOneWidget);
expect(findRoute('Anchor', count: 1), findsOneWidget); expect(findRoute('Anchor', count: 1), findsOneWidget);
final Route<Object> anchor = ModalRoute.of(tester.element(find.text('Route: Anchor'))); final Route<Object> anchor = ModalRoute.of(tester.element(find.text('Route: Anchor')))!;
expect(anchor.settings.name, 'Anchor'); expect(anchor.settings.name, 'Anchor');
tester.state<NavigatorState>(find.byType(Navigator)).restorableReplaceRouteBelow(newRouteBuilder: _routeBuilder, arguments: 'Foo', anchorRoute: anchor); tester.state<NavigatorState>(find.byType(Navigator)).restorableReplaceRouteBelow(newRouteBuilder: _routeBuilder, arguments: 'Foo', anchorRoute: anchor);
...@@ -479,22 +479,22 @@ void main() { ...@@ -479,22 +479,22 @@ void main() {
expect(findRoute('Foo'), findsOneWidget); expect(findRoute('Foo'), findsOneWidget);
// Push is in progress. // Push is in progress.
final ModalRoute<Object> route1 = ModalRoute.of(tester.element(find.text('Route: Foo'))); final ModalRoute<Object> route1 = ModalRoute.of(tester.element(find.text('Route: Foo')))!;
final String route1id = route1.restorationScopeId.value; final String route1id = route1.restorationScopeId.value!;
expect(route1id, isNotNull); expect(route1id, isNotNull);
expect(route1.settings.name, 'Foo'); expect(route1.settings.name, 'Foo');
expect(route1.animation.isCompleted, isFalse); expect(route1.animation!.isCompleted, isFalse);
expect(route1.animation.isDismissed, isFalse); expect(route1.animation!.isDismissed, isFalse);
expect(route1.isActive, isTrue); expect(route1.isActive, isTrue);
await tester.restartAndRestore(); await tester.restartAndRestore();
expect(findRoute('Foo'), findsOneWidget); expect(findRoute('Foo'), findsOneWidget);
expect(findRoute('home', skipOffstage: false), findsOneWidget); expect(findRoute('home', skipOffstage: false), findsOneWidget);
final ModalRoute<Object> route2 = ModalRoute.of(tester.element(find.text('Route: Foo'))); final ModalRoute<Object> route2 = ModalRoute.of(tester.element(find.text('Route: Foo')))!;
expect(route2, isNot(same(route1))); expect(route2, isNot(same(route1)));
expect(route1.restorationScopeId.value, route1id); expect(route1.restorationScopeId.value, route1id);
expect(route2.animation.isCompleted, isTrue); expect(route2.animation!.isCompleted, isTrue);
expect(route2.isActive, isTrue); expect(route2.isActive, isTrue);
}); });
...@@ -506,14 +506,14 @@ void main() { ...@@ -506,14 +506,14 @@ void main() {
tester.state<NavigatorState>(find.byType(Navigator)).restorablePushNamed('Foo'); tester.state<NavigatorState>(find.byType(Navigator)).restorablePushNamed('Foo');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final ModalRoute<Object> route1 = ModalRoute.of(tester.element(find.text('Route: Foo'))); final ModalRoute<Object> route1 = ModalRoute.of(tester.element(find.text('Route: Foo')))!;
int notifyCount = 0; int notifyCount = 0;
route1.restorationScopeId.addListener(() { route1.restorationScopeId.addListener(() {
notifyCount++; notifyCount++;
}); });
expect(route1.isActive, isTrue); expect(route1.isActive, isTrue);
expect(route1.restorationScopeId.value, isNotNull); expect(route1.restorationScopeId.value, isNotNull);
expect(route1.animation.isCompleted, isTrue); expect(route1.animation!.isCompleted, isTrue);
expect(notifyCount, 0); expect(notifyCount, 0);
tester.state<NavigatorState>(find.byType(Navigator)).pop(); tester.state<NavigatorState>(find.byType(Navigator)).pop();
...@@ -524,8 +524,8 @@ void main() { ...@@ -524,8 +524,8 @@ void main() {
// Pop is in progress. // Pop is in progress.
expect(route1.restorationScopeId.value, isNull); expect(route1.restorationScopeId.value, isNull);
expect(route1.settings.name, 'Foo'); expect(route1.settings.name, 'Foo');
expect(route1.animation.isCompleted, isFalse); expect(route1.animation!.isCompleted, isFalse);
expect(route1.animation.isDismissed, isFalse); expect(route1.animation!.isDismissed, isFalse);
expect(route1.isActive, isFalse); expect(route1.isActive, isFalse);
await tester.restartAndRestore(); await tester.restartAndRestore();
...@@ -622,7 +622,7 @@ void main() { ...@@ -622,7 +622,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(findRoute('route5'), findsOneWidget); expect(findRoute('route5'), findsOneWidget);
final Route<Object> route = ModalRoute.of(tester.element(find.text('Route: route3', skipOffstage: false))); final Route<Object> route = ModalRoute.of(tester.element(find.text('Route: route3', skipOffstage: false)))!;
expect(route.settings.name, 'route3'); expect(route.settings.name, 'route3');
tester.state<NavigatorState>(find.byType(Navigator)).removeRoute(route); tester.state<NavigatorState>(find.byType(Navigator)).removeRoute(route);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -655,7 +655,7 @@ void main() { ...@@ -655,7 +655,7 @@ void main() {
routeFuture.present('Foo'); routeFuture.present('Foo');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('Route: Foo'), findsOneWidget); expect(find.text('Route: Foo'), findsOneWidget);
expect(routeFuture.route.settings.name, 'Foo'); expect(routeFuture.route!.settings.name, 'Foo');
expect(routeFuture.isPresent, isTrue); expect(routeFuture.isPresent, isTrue);
expect(routeFuture.enabled, isTrue); expect(routeFuture.enabled, isTrue);
...@@ -665,7 +665,7 @@ void main() { ...@@ -665,7 +665,7 @@ void main() {
final RestorableRouteFuture<int> restoredRouteFuture = tester final RestorableRouteFuture<int> restoredRouteFuture = tester
.state<RouteFutureWidgetState>(find.byType(RouteFutureWidget, skipOffstage: false)) .state<RouteFutureWidgetState>(find.byType(RouteFutureWidget, skipOffstage: false))
.routeFuture; .routeFuture;
expect(restoredRouteFuture.route.settings.name, 'Foo'); expect(restoredRouteFuture.route!.settings.name, 'Foo');
expect(restoredRouteFuture.isPresent, isTrue); expect(restoredRouteFuture.isPresent, isTrue);
expect(restoredRouteFuture.enabled, isTrue); expect(restoredRouteFuture.enabled, isTrue);
...@@ -699,7 +699,7 @@ void main() { ...@@ -699,7 +699,7 @@ void main() {
routeFuture.present('Foo'); routeFuture.present('Foo');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('Route: Foo'), findsOneWidget); expect(find.text('Route: Foo'), findsOneWidget);
expect(routeFuture.route.settings.name, 'Foo'); expect(routeFuture.route!.settings.name, 'Foo');
expect(routeFuture.isPresent, isTrue); expect(routeFuture.isPresent, isTrue);
expect(routeFuture.enabled, isFalse); expect(routeFuture.enabled, isFalse);
...@@ -713,7 +713,7 @@ void main() { ...@@ -713,7 +713,7 @@ void main() {
tester.state<NavigatorState>(find.byType(Navigator)).restorablePushNamed('Bar'); tester.state<NavigatorState>(find.byType(Navigator)).restorablePushNamed('Bar');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final Route<Object> oldRoute = ModalRoute.of(tester.element(find.text('Route: Bar'))); final Route<Object> oldRoute = ModalRoute.of(tester.element(find.text('Route: Bar')))!;
expect(oldRoute.settings.name, 'Bar'); expect(oldRoute.settings.name, 'Bar');
final Matcher throwsArgumentsAssertionError = throwsA(isAssertionError.having( final Matcher throwsArgumentsAssertionError = throwsA(isAssertionError.having(
...@@ -740,7 +740,7 @@ void main() { ...@@ -740,7 +740,7 @@ void main() {
throwsArgumentsAssertionError, throwsArgumentsAssertionError,
); );
expect( expect(
() => tester.state<NavigatorState>(find.byType(Navigator)).restorablePushNamedAndRemoveUntil('Foo', (Route<Object> _) => false, arguments: Object()), () => tester.state<NavigatorState>(find.byType(Navigator)).restorablePushNamedAndRemoveUntil('Foo', (Route<Object?> _) => false, arguments: Object()),
throwsArgumentsAssertionError, throwsArgumentsAssertionError,
); );
expect( expect(
...@@ -752,7 +752,7 @@ void main() { ...@@ -752,7 +752,7 @@ void main() {
throwsArgumentsAssertionError, throwsArgumentsAssertionError,
); );
expect( expect(
() => tester.state<NavigatorState>(find.byType(Navigator)).restorablePushAndRemoveUntil(_routeBuilder, (Route<Object> _) => false, arguments: Object()), () => tester.state<NavigatorState>(find.byType(Navigator)).restorablePushAndRemoveUntil(_routeBuilder, (Route<Object?> _) => false, arguments: Object()),
throwsArgumentsAssertionError, throwsArgumentsAssertionError,
); );
expect( expect(
...@@ -765,27 +765,27 @@ void main() { ...@@ -765,27 +765,27 @@ void main() {
); );
expect( expect(
() => tester.state<NavigatorState>(find.byType(Navigator)).restorablePush((BuildContext _, Object __) => null), () => tester.state<NavigatorState>(find.byType(Navigator)).restorablePush((BuildContext _, Object? __) => FakeRoute()),
throwsBuilderAssertionError, throwsBuilderAssertionError,
skip: isBrowser, // https://github.com/flutter/flutter/issues/33615 skip: isBrowser, // https://github.com/flutter/flutter/issues/33615
); );
expect( expect(
() => tester.state<NavigatorState>(find.byType(Navigator)).restorablePushReplacement((BuildContext _, Object __) => null), () => tester.state<NavigatorState>(find.byType(Navigator)).restorablePushReplacement((BuildContext _, Object? __) => FakeRoute()),
throwsBuilderAssertionError, throwsBuilderAssertionError,
skip: isBrowser, // https://github.com/flutter/flutter/issues/33615 skip: isBrowser, // https://github.com/flutter/flutter/issues/33615
); );
expect( expect(
() => tester.state<NavigatorState>(find.byType(Navigator)).restorablePushAndRemoveUntil((BuildContext _, Object __) => null, (Route<Object> _) => false), () => tester.state<NavigatorState>(find.byType(Navigator)).restorablePushAndRemoveUntil((BuildContext _, Object? __) => FakeRoute(), (Route<Object?> _) => false),
throwsBuilderAssertionError, throwsBuilderAssertionError,
skip: isBrowser, // https://github.com/flutter/flutter/issues/33615 skip: isBrowser, // https://github.com/flutter/flutter/issues/33615
); );
expect( expect(
() => tester.state<NavigatorState>(find.byType(Navigator)).restorableReplace(newRouteBuilder: (BuildContext _, Object __) => null, oldRoute: oldRoute), () => tester.state<NavigatorState>(find.byType(Navigator)).restorableReplace(newRouteBuilder: (BuildContext _, Object? __) => FakeRoute(), oldRoute: oldRoute),
throwsBuilderAssertionError, throwsBuilderAssertionError,
skip: isBrowser, // https://github.com/flutter/flutter/issues/33615 skip: isBrowser, // https://github.com/flutter/flutter/issues/33615
); );
expect( expect(
() => tester.state<NavigatorState>(find.byType(Navigator)).restorableReplaceRouteBelow(newRouteBuilder: (BuildContext _, Object __) => null, anchorRoute: oldRoute), () => tester.state<NavigatorState>(find.byType(Navigator)).restorableReplaceRouteBelow(newRouteBuilder: (BuildContext _, Object? __) => FakeRoute(), anchorRoute: oldRoute),
throwsBuilderAssertionError, throwsBuilderAssertionError,
skip: isBrowser, // https://github.com/flutter/flutter/issues/33615 skip: isBrowser, // https://github.com/flutter/flutter/issues/33615
); );
...@@ -983,17 +983,17 @@ void main() { ...@@ -983,17 +983,17 @@ void main() {
}); });
} }
Route<void> _routeBuilder(BuildContext context, Object arguments) { Route<void> _routeBuilder(BuildContext context, Object? arguments) {
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
builder: (BuildContext context) { builder: (BuildContext context) {
return RouteWidget( return RouteWidget(
name: arguments as String, name: arguments! as String,
); );
}, },
); );
} }
Route<void> _routeFutureBuilder(BuildContext context, Object arguments) { Route<void> _routeFutureBuilder(BuildContext context, Object? arguments) {
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
builder: (BuildContext context) { builder: (BuildContext context) {
return RouteFutureWidget(); return RouteFutureWidget();
...@@ -1026,7 +1026,7 @@ class PagedTestNavigator extends StatefulWidget { ...@@ -1026,7 +1026,7 @@ class PagedTestNavigator extends StatefulWidget {
class PagedTestNavigatorState extends State<PagedTestNavigator> with RestorationMixin { class PagedTestNavigatorState extends State<PagedTestNavigator> with RestorationMixin {
final RestorableString _routes = RestorableString('r-home'); final RestorableString _routes = RestorableString('r-home');
void addPage(String name, {bool restoreState = true, int index}) { void addPage(String name, {bool restoreState = true, int? index}) {
assert(!name.contains(',')); assert(!name.contains(','));
assert(!name.startsWith('r-')); assert(!name.startsWith('r-'));
final List<String> routes = _routes.value.split(','); final List<String> routes = _routes.value.split(',');
...@@ -1058,12 +1058,12 @@ class PagedTestNavigatorState extends State<PagedTestNavigator> with Restoration ...@@ -1058,12 +1058,12 @@ class PagedTestNavigatorState extends State<PagedTestNavigator> with Restoration
restorationScopeId: 'nav', restorationScopeId: 'nav',
onPopPage: (Route<dynamic> route, dynamic result) { onPopPage: (Route<dynamic> route, dynamic result) {
if (route.didPop(result)) { if (route.didPop(result)) {
removePage(route.settings.name); removePage(route.settings.name!);
return true; return true;
} }
return false; return false;
}, },
pages: _routes.value.isEmpty ? const <Page<Object>>[] : _routes.value.split(',').map((String name) { pages: _routes.value.isEmpty ? const <Page<Object?>>[] : _routes.value.split(',').map((String name) {
if (name.startsWith('r-')) { if (name.startsWith('r-')) {
name = name.substring(2); name = name.substring(2);
return TestPage( return TestPage(
...@@ -1082,7 +1082,7 @@ class PagedTestNavigatorState extends State<PagedTestNavigator> with Restoration ...@@ -1082,7 +1082,7 @@ class PagedTestNavigatorState extends State<PagedTestNavigator> with Restoration
settings: settings, settings: settings,
builder: (BuildContext context) { builder: (BuildContext context) {
return RouteWidget( return RouteWidget(
name: settings.name, name: settings.name!,
arguments: settings.arguments, arguments: settings.arguments,
); );
}, },
...@@ -1095,7 +1095,7 @@ class PagedTestNavigatorState extends State<PagedTestNavigator> with Restoration ...@@ -1095,7 +1095,7 @@ class PagedTestNavigatorState extends State<PagedTestNavigator> with Restoration
String get restorationId => 'router'; String get restorationId => 'router';
@override @override
void restoreState(RestorationBucket oldBucket, bool initialRestore) { void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(_routes, 'routes'); registerForRestoration(_routes, 'routes');
} }
...@@ -1107,7 +1107,7 @@ class PagedTestNavigatorState extends State<PagedTestNavigator> with Restoration ...@@ -1107,7 +1107,7 @@ class PagedTestNavigatorState extends State<PagedTestNavigator> with Restoration
} }
class TestPage extends Page<void> { class TestPage extends Page<void> {
const TestPage({LocalKey key, String name, String restorationId}) : super(name: name, key: key, restorationId: restorationId); const TestPage({LocalKey? key, required String name, String? restorationId}) : super(name: name, key: key, restorationId: restorationId);
@override @override
Route<void> createRoute(BuildContext context) { Route<void> createRoute(BuildContext context) {
...@@ -1115,7 +1115,7 @@ class TestPage extends Page<void> { ...@@ -1115,7 +1115,7 @@ class TestPage extends Page<void> {
settings: this, settings: this,
builder: (BuildContext context) { builder: (BuildContext context) {
return RouteWidget( return RouteWidget(
name: name, name: name!,
); );
} }
); );
...@@ -1125,7 +1125,7 @@ class TestPage extends Page<void> { ...@@ -1125,7 +1125,7 @@ class TestPage extends Page<void> {
class TestWidget extends StatelessWidget { class TestWidget extends StatelessWidget {
const TestWidget({this.restorationId = 'app'}); const TestWidget({this.restorationId = 'app'});
final String restorationId; final String? restorationId;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -1141,7 +1141,7 @@ class TestWidget extends StatelessWidget { ...@@ -1141,7 +1141,7 @@ class TestWidget extends StatelessWidget {
settings: settings, settings: settings,
builder: (BuildContext context) { builder: (BuildContext context) {
return RouteWidget( return RouteWidget(
name: settings.name, name: settings.name!,
arguments: settings.arguments, arguments: settings.arguments,
); );
}, },
...@@ -1154,10 +1154,10 @@ class TestWidget extends StatelessWidget { ...@@ -1154,10 +1154,10 @@ class TestWidget extends StatelessWidget {
} }
class RouteWidget extends StatefulWidget { class RouteWidget extends StatefulWidget {
const RouteWidget({Key key, this.name, this.arguments}) : super(key: key); const RouteWidget({Key? key, required this.name, this.arguments}) : super(key: key);
final String name; final String name;
final Object arguments; final Object? arguments;
@override @override
State<RouteWidget> createState() => RouteWidgetState(); State<RouteWidget> createState() => RouteWidgetState();
...@@ -1167,7 +1167,7 @@ class RouteWidgetState extends State<RouteWidget> with RestorationMixin { ...@@ -1167,7 +1167,7 @@ class RouteWidgetState extends State<RouteWidget> with RestorationMixin {
final RestorableInt counter = RestorableInt(0); final RestorableInt counter = RestorableInt(0);
@override @override
void restoreState(RestorationBucket oldBucket, bool initialRestore) { void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(counter, 'counter'); registerForRestoration(counter, 'counter');
} }
...@@ -1208,15 +1208,15 @@ class RouteFutureWidget extends StatefulWidget { ...@@ -1208,15 +1208,15 @@ class RouteFutureWidget extends StatefulWidget {
} }
class RouteFutureWidgetState extends State<RouteFutureWidget> with RestorationMixin { class RouteFutureWidgetState extends State<RouteFutureWidget> with RestorationMixin {
RestorableRouteFuture<int> routeFuture; late RestorableRouteFuture<int> routeFuture;
int value; int? value;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
routeFuture = RestorableRouteFuture<int>( routeFuture = RestorableRouteFuture<int>(
onPresent: (NavigatorState navigatorState, Object arguments) { onPresent: (NavigatorState navigatorState, Object? arguments) {
return navigatorState.restorablePushNamed(arguments as String); return navigatorState.restorablePushNamed(arguments! as String);
}, },
onComplete: (int i) { onComplete: (int i) {
setState(() { setState(() {
...@@ -1227,7 +1227,7 @@ class RouteFutureWidgetState extends State<RouteFutureWidget> with RestorationMi ...@@ -1227,7 +1227,7 @@ class RouteFutureWidgetState extends State<RouteFutureWidget> with RestorationMi
} }
@override @override
void restoreState(RestorationBucket oldBucket, bool initialRestore) { void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(routeFuture, 'routeFuture'); registerForRestoration(routeFuture, 'routeFuture');
} }
...@@ -1248,7 +1248,7 @@ class RouteFutureWidgetState extends State<RouteFutureWidget> with RestorationMi ...@@ -1248,7 +1248,7 @@ class RouteFutureWidgetState extends State<RouteFutureWidget> with RestorationMi
} }
} }
Finder findRoute(String name, { Object arguments, int count, bool skipOffstage = true }) => _RouteFinder(name, arguments: arguments, count: count, skipOffstage: skipOffstage); Finder findRoute(String name, { Object? arguments, int? count, bool skipOffstage = true }) => _RouteFinder(name, arguments: arguments, count: count, skipOffstage: skipOffstage);
Future<void> tapRouteCounter(String name, WidgetTester tester) async { Future<void> tapRouteCounter(String name, WidgetTester tester) async {
await tester.tap(find.text('Route: $name')); await tester.tap(find.text('Route: $name'));
...@@ -1259,8 +1259,8 @@ class _RouteFinder extends MatchFinder { ...@@ -1259,8 +1259,8 @@ class _RouteFinder extends MatchFinder {
_RouteFinder(this.name, { this.arguments, this.count, bool skipOffstage = true }) : super(skipOffstage: skipOffstage); _RouteFinder(this.name, { this.arguments, this.count, bool skipOffstage = true }) : super(skipOffstage: skipOffstage);
final String name; final String name;
final Object arguments; final Object? arguments;
final int count; final int? count;
@override @override
String get description { String get description {
...@@ -1293,3 +1293,5 @@ class _RouteFinder extends MatchFinder { ...@@ -1293,3 +1293,5 @@ class _RouteFinder extends MatchFinder {
return false; return false;
} }
} }
class FakeRoute extends Fake implements Route<void> {}
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
...@@ -15,7 +13,7 @@ import 'observer_tester.dart'; ...@@ -15,7 +13,7 @@ import 'observer_tester.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
class FirstWidget extends StatelessWidget { class FirstWidget extends StatelessWidget {
const FirstWidget({ Key key }) : super(key: key); const FirstWidget({ Key? key }) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return GestureDetector(
...@@ -31,7 +29,7 @@ class FirstWidget extends StatelessWidget { ...@@ -31,7 +29,7 @@ class FirstWidget extends StatelessWidget {
} }
class SecondWidget extends StatefulWidget { class SecondWidget extends StatefulWidget {
const SecondWidget({ Key key }) : super(key: key); const SecondWidget({ Key? key }) : super(key: key);
@override @override
SecondWidgetState createState() => SecondWidgetState(); SecondWidgetState createState() => SecondWidgetState();
} }
...@@ -52,7 +50,7 @@ class SecondWidgetState extends State<SecondWidget> { ...@@ -52,7 +50,7 @@ class SecondWidgetState extends State<SecondWidget> {
typedef ExceptionCallback = void Function(dynamic exception); typedef ExceptionCallback = void Function(dynamic exception);
class ThirdWidget extends StatelessWidget { class ThirdWidget extends StatelessWidget {
const ThirdWidget({ Key key, this.targetKey, this.onException }) : super(key: key); const ThirdWidget({ Key? key, required this.targetKey, required this.onException }) : super(key: key);
final Key targetKey; final Key targetKey;
final ExceptionCallback onException; final ExceptionCallback onException;
...@@ -74,10 +72,10 @@ class ThirdWidget extends StatelessWidget { ...@@ -74,10 +72,10 @@ class ThirdWidget extends StatelessWidget {
} }
class OnTapPage extends StatelessWidget { class OnTapPage extends StatelessWidget {
const OnTapPage({ Key key, this.id, this.onTap }) : super(key: key); const OnTapPage({ Key? key, required this.id, this.onTap }) : super(key: key);
final String id; final String id;
final VoidCallback onTap; final VoidCallback? onTap;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -88,7 +86,7 @@ class OnTapPage extends StatelessWidget { ...@@ -88,7 +86,7 @@ class OnTapPage extends StatelessWidget {
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
child: Container( child: Container(
child: Center( child: Center(
child: Text(id, style: Theme.of(context).textTheme.headline3), child: Text(id, style: Theme.of(context)!.textTheme.headline3),
), ),
), ),
), ),
...@@ -97,7 +95,7 @@ class OnTapPage extends StatelessWidget { ...@@ -97,7 +95,7 @@ class OnTapPage extends StatelessWidget {
} }
class SlideInOutPageRoute<T> extends PageRouteBuilder<T> { class SlideInOutPageRoute<T> extends PageRouteBuilder<T> {
SlideInOutPageRoute({WidgetBuilder bodyBuilder, RouteSettings settings}) : super( SlideInOutPageRoute({required WidgetBuilder bodyBuilder, RouteSettings? settings}) : super(
settings: settings, settings: settings,
pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) => bodyBuilder(context), pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) => bodyBuilder(context),
transitionsBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) { transitionsBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
...@@ -118,7 +116,7 @@ class SlideInOutPageRoute<T> extends PageRouteBuilder<T> { ...@@ -118,7 +116,7 @@ class SlideInOutPageRoute<T> extends PageRouteBuilder<T> {
); );
@override @override
AnimationController get controller => super.controller; AnimationController? get controller => super.controller;
} }
void main() { void main() {
...@@ -206,13 +204,13 @@ void main() { ...@@ -206,13 +204,13 @@ void main() {
return ElevatedButton( return ElevatedButton(
child: const Text('Next'), child: const Text('Next'),
onPressed: () { onPressed: () {
Navigator.of(context).push( Navigator.of(context)!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) { builder: (BuildContext context) {
return ElevatedButton( return ElevatedButton(
child: const Text('Inner page'), child: const Text('Inner page'),
onPressed: () { onPressed: () {
Navigator.of(context, rootNavigator: true).push( Navigator.of(context, rootNavigator: true)!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) { builder: (BuildContext context) {
return const Text('Dialog'); return const Text('Dialog');
...@@ -378,13 +376,13 @@ void main() { ...@@ -378,13 +376,13 @@ void main() {
bool isPushed = false; bool isPushed = false;
bool isPopped = false; bool isPopped = false;
final TestObserver observer = TestObserver() final TestObserver observer = TestObserver()
..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
// Pushes the initial route. // Pushes the initial route.
expect(route is PageRoute && route.settings.name == '/', isTrue); expect(route is PageRoute && route.settings.name == '/', isTrue);
expect(previousRoute, isNull); expect(previousRoute, isNull);
isPushed = true; isPushed = true;
} }
..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPopped = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
isPopped = true; isPopped = true;
}; };
...@@ -399,7 +397,7 @@ void main() { ...@@ -399,7 +397,7 @@ void main() {
isPushed = false; isPushed = false;
isPopped = false; isPopped = false;
observer.onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { observer.onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
expect(route is PageRoute && route.settings.name == '/A', isTrue); expect(route is PageRoute && route.settings.name == '/A', isTrue);
expect(previousRoute is PageRoute && previousRoute.settings.name == '/', isTrue); expect(previousRoute is PageRoute && previousRoute.settings.name == '/', isTrue);
isPushed = true; isPushed = true;
...@@ -415,7 +413,7 @@ void main() { ...@@ -415,7 +413,7 @@ void main() {
isPushed = false; isPushed = false;
isPopped = false; isPopped = false;
observer.onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) { observer.onPopped = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
expect(route is PageRoute && route.settings.name == '/A', isTrue); expect(route is PageRoute && route.settings.name == '/A', isTrue);
expect(previousRoute is PageRoute && previousRoute.settings.name == '/', isTrue); expect(previousRoute is PageRoute && previousRoute.settings.name == '/', isTrue);
isPopped = true; isPopped = true;
...@@ -439,10 +437,10 @@ void main() { ...@@ -439,10 +437,10 @@ void main() {
bool isPopped = false; bool isPopped = false;
final TestObserver observer1 = TestObserver(); final TestObserver observer1 = TestObserver();
final TestObserver observer2 = TestObserver() final TestObserver observer2 = TestObserver()
..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
isPushed = true; isPushed = true;
} }
..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPopped = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
isPopped = true; isPopped = true;
}; };
...@@ -485,12 +483,12 @@ void main() { ...@@ -485,12 +483,12 @@ void main() {
}; };
final List<NavigatorObservation> observations = <NavigatorObservation>[]; final List<NavigatorObservation> observations = <NavigatorObservation>[];
final TestObserver observer = TestObserver() final TestObserver observer = TestObserver()
..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
// Pushes the initial route. // Pushes the initial route.
observations.add( observations.add(
NavigatorObservation( NavigatorObservation(
current: route?.settings?.name, current: route?.settings.name,
previous: previousRoute?.settings?.name, previous: previousRoute?.settings.name,
operation: 'push' operation: 'push'
) )
); );
...@@ -645,37 +643,37 @@ void main() { ...@@ -645,37 +643,37 @@ void main() {
'/C': (BuildContext context) => OnTapPage( '/C': (BuildContext context) => OnTapPage(
id: 'C', id: 'C',
onTap: () { onTap: () {
Navigator.removeRoute(context, routes['/']); Navigator.removeRoute(context, routes['/']!);
}, },
), ),
}; };
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
final SlideInOutPageRoute<dynamic> ret = SlideInOutPageRoute<dynamic>(bodyBuilder: builders[settings.name], settings: settings); final SlideInOutPageRoute<dynamic> ret = SlideInOutPageRoute<dynamic>(bodyBuilder: builders[settings.name]!, settings: settings);
routes[settings.name] = ret; routes[settings.name!] = ret;
return ret; return ret;
} }
)); ));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
await tester.tap(find.text('/')); await tester.tap(find.text('/'));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final double a2 = routes['/A'].secondaryAnimation.value; final double a2 = routes['/A']!.secondaryAnimation!.value;
await tester.tap(find.text('A')); await tester.tap(find.text('A'));
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 16)); await tester.pump(const Duration(milliseconds: 16));
expect(routes['/A'].secondaryAnimation.value, greaterThan(a2)); expect(routes['/A']!.secondaryAnimation!.value, greaterThan(a2));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
await tester.tap(find.text('B')); await tester.tap(find.text('B'));
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 200)); await tester.pump(const Duration(milliseconds: 200));
expect(routes['/A'].secondaryAnimation.value, equals(1.0)); expect(routes['/A']!.secondaryAnimation!.value, equals(1.0));
await tester.tap(find.text('C')); await tester.tap(find.text('C'));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('C'), isOnstage); expect(find.text('C'), isOnstage);
expect(routes['/A'].secondaryAnimation.value, equals(routes['/C'].animation.value)); expect(routes['/A']!.secondaryAnimation!.value, equals(routes['/C']!.animation!.value));
final AnimationController controller = routes['/C'].controller; final AnimationController controller = routes['/C']!.controller!;
controller.value = 1 - controller.value; controller.value = 1 - controller.value;
expect(routes['/A'].secondaryAnimation.value, equals(routes['/C'].animation.value)); expect(routes['/A']!.secondaryAnimation!.value, equals(routes['/C']!.animation!.value));
}); });
testWidgets('new route removed from navigator history during pushReplacement transition', (WidgetTester tester) async { testWidgets('new route removed from navigator history during pushReplacement transition', (WidgetTester tester) async {
...@@ -696,14 +694,14 @@ void main() { ...@@ -696,14 +694,14 @@ void main() {
'/B': (BuildContext context) => OnTapPage( '/B': (BuildContext context) => OnTapPage(
id: 'B', id: 'B',
onTap: () { onTap: () {
Navigator.removeRoute(context, routes['/B']); Navigator.removeRoute(context, routes['/B']!);
}, },
), ),
}; };
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
final SlideInOutPageRoute<dynamic> ret = SlideInOutPageRoute<dynamic>(bodyBuilder: builders[settings.name], settings: settings); final SlideInOutPageRoute<dynamic> ret = SlideInOutPageRoute<dynamic>(bodyBuilder: builders[settings.name]!, settings: settings);
routes[settings.name] = ret; routes[settings.name!] = ret;
return ret; return ret;
} }
)); ));
...@@ -720,8 +718,8 @@ void main() { ...@@ -720,8 +718,8 @@ void main() {
expect(find.text('/'), isOnstage); expect(find.text('/'), isOnstage);
expect(find.text('B'), findsNothing); expect(find.text('B'), findsNothing);
expect(find.text('A'), findsNothing); expect(find.text('A'), findsNothing);
expect(routes['/'].secondaryAnimation.value, equals(0.0)); expect(routes['/']!.secondaryAnimation!.value, equals(0.0));
expect(routes['/'].animation.value, equals(1.0)); expect(routes['/']!.animation!.value, equals(1.0));
}); });
testWidgets('pushReplacement triggers secondaryAnimation', (WidgetTester tester) async { testWidgets('pushReplacement triggers secondaryAnimation', (WidgetTester tester) async {
...@@ -743,7 +741,7 @@ void main() { ...@@ -743,7 +741,7 @@ void main() {
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
return SlideInOutPageRoute<dynamic>(bodyBuilder: routes[settings.name]); return SlideInOutPageRoute<dynamic>(bodyBuilder: routes[settings.name]!);
} }
)); ));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -785,8 +783,8 @@ void main() { ...@@ -785,8 +783,8 @@ void main() {
'/A/B': (BuildContext context) => OnTapPage( '/A/B': (BuildContext context) => OnTapPage(
id: 'B', id: 'B',
onTap: (){ onTap: (){
Navigator.of(context).popUntil((Route<dynamic> route) => route.isFirst); Navigator.of(context)!.popUntil((Route<dynamic> route) => route.isFirst);
Navigator.of(context).pushReplacementNamed('/C'); Navigator.of(context)!.pushReplacementNamed('/C');
}, },
), ),
'/C': (BuildContext context) => const OnTapPage(id: 'C', '/C': (BuildContext context) => const OnTapPage(id: 'C',
...@@ -794,20 +792,20 @@ void main() { ...@@ -794,20 +792,20 @@ void main() {
}; };
final List<NavigatorObservation> observations = <NavigatorObservation>[]; final List<NavigatorObservation> observations = <NavigatorObservation>[];
final TestObserver observer = TestObserver() final TestObserver observer = TestObserver()
..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPopped = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
observations.add( observations.add(
NavigatorObservation( NavigatorObservation(
current: route.settings.name, current: route?.settings.name,
previous: previousRoute.settings.name, previous: previousRoute?.settings.name,
operation: 'didPop' operation: 'didPop'
) )
); );
} }
..onReplaced = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onReplaced = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
observations.add( observations.add(
NavigatorObservation( NavigatorObservation(
current: route.settings.name, current: route?.settings.name,
previous: previousRoute.settings.name, previous: previousRoute?.settings.name,
operation: 'didReplace' operation: 'didReplace'
) )
); );
...@@ -853,7 +851,7 @@ void main() { ...@@ -853,7 +851,7 @@ void main() {
id: 'B', id: 'B',
onTap: (){ onTap: (){
// Pops all routes with bad predicate. // Pops all routes with bad predicate.
Navigator.of(context).popUntil((Route<dynamic> route) => false); Navigator.of(context)!.popUntil((Route<dynamic> route) => false);
}, },
), ),
}; };
...@@ -887,7 +885,7 @@ void main() { ...@@ -887,7 +885,7 @@ void main() {
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
return SlideInOutPageRoute<dynamic>(bodyBuilder: routes[settings.name]); return SlideInOutPageRoute<dynamic>(bodyBuilder: routes[settings.name]!);
} }
)); ));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -931,7 +929,7 @@ void main() { ...@@ -931,7 +929,7 @@ void main() {
'/A/B': (BuildContext context) => OnTapPage( '/A/B': (BuildContext context) => OnTapPage(
id: 'B', id: 'B',
onTap: () { onTap: () {
Navigator.of(context).pushNamedAndRemoveUntil('/D', ModalRoute.withName('/A')); Navigator.of(context)!.pushNamedAndRemoveUntil('/D', ModalRoute.withName('/A'));
}, },
), ),
'/D': (BuildContext context) => const Text('page D'), '/D': (BuildContext context) => const Text('page D'),
...@@ -949,17 +947,17 @@ void main() { ...@@ -949,17 +947,17 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('page D'), isOnstage); expect(find.text('page D'), isOnstage);
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('page A'), isOnstage); expect(find.text('page A'), isOnstage);
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('home'), isOnstage); expect(find.text('home'), isOnstage);
}); });
testWidgets('replaceNamed returned value', (WidgetTester tester) async { testWidgets('replaceNamed returned value', (WidgetTester tester) async {
Future<String> value; late Future<String> value;
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{ final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }), '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }),
...@@ -972,7 +970,7 @@ void main() { ...@@ -972,7 +970,7 @@ void main() {
return PageRouteBuilder<String>( return PageRouteBuilder<String>(
settings: settings, settings: settings,
pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) { pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
return routes[settings.name](context); return routes[settings.name]!(context);
}, },
); );
} }
...@@ -1015,22 +1013,22 @@ void main() { ...@@ -1015,22 +1013,22 @@ void main() {
}; };
final Map<String, Route<String>> routes = <String, Route<String>>{}; final Map<String, Route<String>> routes = <String, Route<String>>{};
Route<String> removedRoute; late Route<String> removedRoute;
Route<String> previousRoute; late Route<String> previousRoute;
final TestObserver observer = TestObserver() final TestObserver observer = TestObserver()
..onRemoved = (Route<dynamic> route, Route<dynamic> previous) { ..onRemoved = (Route<dynamic>? route, Route<dynamic>? previous) {
removedRoute = route as Route<String>; removedRoute = route! as Route<String>;
previousRoute = previous as Route<String>; previousRoute = previous! as Route<String>;
}; };
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
navigatorObservers: <NavigatorObserver>[observer], navigatorObservers: <NavigatorObserver>[observer],
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
routes[settings.name] = PageRouteBuilder<String>( routes[settings.name!] = PageRouteBuilder<String>(
settings: settings, settings: settings,
pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) { pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
return pageBuilders[settings.name](context); return pageBuilders[settings.name!]!(context);
}, },
); );
return routes[settings.name]; return routes[settings.name];
...@@ -1054,47 +1052,47 @@ void main() { ...@@ -1054,47 +1052,47 @@ void main() {
expect(find.text('B'), findsOneWidget); expect(find.text('B'), findsOneWidget);
// Verify that the navigator's stack is ordered as expected. // Verify that the navigator's stack is ordered as expected.
expect(routes['/'].isActive, true); expect(routes['/']!.isActive, true);
expect(routes['/A'].isActive, true); expect(routes['/A']!.isActive, true);
expect(routes['/B'].isActive, true); expect(routes['/B']!.isActive, true);
expect(routes['/'].isFirst, true); expect(routes['/']!.isFirst, true);
expect(routes['/B'].isCurrent, true); expect(routes['/B']!.isCurrent, true);
final NavigatorState navigator = tester.state<NavigatorState>(find.byType(Navigator)); final NavigatorState navigator = tester.state<NavigatorState>(find.byType(Navigator));
navigator.removeRoute(routes['/B']); // stack becomes /, /A navigator.removeRoute(routes['/B']!); // stack becomes /, /A
await tester.pump(); await tester.pump();
expect(find.text('/'), findsNothing); expect(find.text('/'), findsNothing);
expect(find.text('A'), findsOneWidget); expect(find.text('A'), findsOneWidget);
expect(find.text('B'), findsNothing); expect(find.text('B'), findsNothing);
// Verify that the navigator's stack no longer includes /B // Verify that the navigator's stack no longer includes /B
expect(routes['/'].isActive, true); expect(routes['/']!.isActive, true);
expect(routes['/A'].isActive, true); expect(routes['/A']!.isActive, true);
expect(routes['/B'].isActive, false); expect(routes['/B']!.isActive, false);
expect(routes['/'].isFirst, true); expect(routes['/']!.isFirst, true);
expect(routes['/A'].isCurrent, true); expect(routes['/A']!.isCurrent, true);
expect(removedRoute, routes['/B']); expect(removedRoute, routes['/B']);
expect(previousRoute, routes['/A']); expect(previousRoute, routes['/A']);
navigator.removeRoute(routes['/A']); // stack becomes just / navigator.removeRoute(routes['/A']!); // stack becomes just /
await tester.pump(); await tester.pump();
expect(find.text('/'), findsOneWidget); expect(find.text('/'), findsOneWidget);
expect(find.text('A'), findsNothing); expect(find.text('A'), findsNothing);
expect(find.text('B'), findsNothing); expect(find.text('B'), findsNothing);
// Verify that the navigator's stack no longer includes /A // Verify that the navigator's stack no longer includes /A
expect(routes['/'].isActive, true); expect(routes['/']!.isActive, true);
expect(routes['/A'].isActive, false); expect(routes['/A']!.isActive, false);
expect(routes['/B'].isActive, false); expect(routes['/B']!.isActive, false);
expect(routes['/'].isFirst, true); expect(routes['/']!.isFirst, true);
expect(routes['/'].isCurrent, true); expect(routes['/']!.isCurrent, true);
expect(removedRoute, routes['/A']); expect(removedRoute, routes['/A']);
expect(previousRoute, routes['/']); expect(previousRoute, routes['/']);
}); });
testWidgets('remove a route whose value is awaited', (WidgetTester tester) async { testWidgets('remove a route whose value is awaited', (WidgetTester tester) async {
Future<String> pageValue; late Future<String> pageValue;
final Map<String, WidgetBuilder> pageBuilders = <String, WidgetBuilder>{ final Map<String, WidgetBuilder> pageBuilders = <String, WidgetBuilder>{
'/': (BuildContext context) => OnTapPage(id: '/', onTap: () { pageValue = Navigator.pushNamed(context, '/A'); }), '/': (BuildContext context) => OnTapPage(id: '/', onTap: () { pageValue = Navigator.pushNamed(context, '/A'); }),
'/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context, 'A'); }), '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context, 'A'); }),
...@@ -1103,10 +1101,10 @@ void main() { ...@@ -1103,10 +1101,10 @@ void main() {
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
routes[settings.name] = PageRouteBuilder<String>( routes[settings.name!] = PageRouteBuilder<String>(
settings: settings, settings: settings,
pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) { pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
return pageBuilders[settings.name](context); return pageBuilders[settings.name!]!(context);
}, },
); );
return routes[settings.name]; return routes[settings.name];
...@@ -1118,45 +1116,45 @@ void main() { ...@@ -1118,45 +1116,45 @@ void main() {
pageValue.then((String value) { assert(false); }); pageValue.then((String value) { assert(false); });
final NavigatorState navigator = tester.state<NavigatorState>(find.byType(Navigator)); final NavigatorState navigator = tester.state<NavigatorState>(find.byType(Navigator));
navigator.removeRoute(routes['/A']); // stack becomes /, pageValue will not complete navigator.removeRoute(routes['/A']!); // stack becomes /, pageValue will not complete
}); });
testWidgets('replacing route can be observed', (WidgetTester tester) async { testWidgets('replacing route can be observed', (WidgetTester tester) async {
final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();
final List<String> log = <String>[]; final List<String> log = <String>[];
final TestObserver observer = TestObserver() final TestObserver observer = TestObserver()
..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
log.add('pushed ${route.settings.name} (previous is ${previousRoute == null ? "<none>" : previousRoute.settings.name})'); log.add('pushed ${route!.settings.name} (previous is ${previousRoute == null ? "<none>" : previousRoute.settings.name})');
} }
..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPopped = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
log.add('popped ${route.settings.name} (previous is ${previousRoute == null ? "<none>" : previousRoute.settings.name})'); log.add('popped ${route!.settings.name} (previous is ${previousRoute == null ? "<none>" : previousRoute.settings.name})');
} }
..onRemoved = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onRemoved = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
log.add('removed ${route.settings.name} (previous is ${previousRoute == null ? "<none>" : previousRoute.settings.name})'); log.add('removed ${route!.settings.name} (previous is ${previousRoute == null ? "<none>" : previousRoute.settings.name})');
} }
..onReplaced = (Route<dynamic> newRoute, Route<dynamic> oldRoute) { ..onReplaced = (Route<dynamic>? newRoute, Route<dynamic>? oldRoute) {
log.add('replaced ${oldRoute.settings.name} with ${newRoute.settings.name}'); log.add('replaced ${oldRoute!.settings.name} with ${newRoute!.settings.name}');
}; };
Route<void> routeB; late Route<void> routeB;
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
navigatorKey: key, navigatorKey: key,
navigatorObservers: <NavigatorObserver>[observer], navigatorObservers: <NavigatorObserver>[observer],
home: TextButton( home: TextButton(
child: const Text('A'), child: const Text('A'),
onPressed: () { onPressed: () {
key.currentState.push<void>(routeB = MaterialPageRoute<void>( key.currentState!.push<void>(routeB = MaterialPageRoute<void>(
settings: const RouteSettings(name: 'B'), settings: const RouteSettings(name: 'B'),
builder: (BuildContext context) { builder: (BuildContext context) {
return TextButton( return TextButton(
child: const Text('B'), child: const Text('B'),
onPressed: () { onPressed: () {
key.currentState.push<void>(MaterialPageRoute<int>( key.currentState!.push<void>(MaterialPageRoute<int>(
settings: const RouteSettings(name: 'C'), settings: const RouteSettings(name: 'C'),
builder: (BuildContext context) { builder: (BuildContext context) {
return TextButton( return TextButton(
child: const Text('C'), child: const Text('C'),
onPressed: () { onPressed: () {
key.currentState.replace( key.currentState!.replace(
oldRoute: routeB, oldRoute: routeB,
newRoute: MaterialPageRoute<int>( newRoute: MaterialPageRoute<int>(
settings: const RouteSettings(name: 'D'), settings: const RouteSettings(name: 'D'),
...@@ -1197,12 +1195,12 @@ void main() { ...@@ -1197,12 +1195,12 @@ void main() {
'/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context); }), '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context); }),
}; };
Route<dynamic> observedRoute; late Route<dynamic> observedRoute;
Route<dynamic> observedPreviousRoute; late Route<dynamic> observedPreviousRoute;
final TestObserver observer = TestObserver() final TestObserver observer = TestObserver()
..onStartUserGesture = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onStartUserGesture = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
observedRoute = route; observedRoute = route!;
observedPreviousRoute = previousRoute; observedPreviousRoute = previousRoute!;
}; };
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
...@@ -1225,7 +1223,7 @@ void main() { ...@@ -1225,7 +1223,7 @@ void main() {
testWidgets('ModalRoute.of sets up a route to rebuild if its state changes', (WidgetTester tester) async { testWidgets('ModalRoute.of sets up a route to rebuild if its state changes', (WidgetTester tester) async {
final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();
final List<String> log = <String>[]; final List<String> log = <String>[];
Route<void> routeB; late Route<void> routeB;
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
navigatorKey: key, navigatorKey: key,
theme: ThemeData( theme: ThemeData(
...@@ -1238,22 +1236,22 @@ void main() { ...@@ -1238,22 +1236,22 @@ void main() {
home: TextButton( home: TextButton(
child: const Text('A'), child: const Text('A'),
onPressed: () { onPressed: () {
key.currentState.push<void>(routeB = MaterialPageRoute<void>( key.currentState!.push<void>(routeB = MaterialPageRoute<void>(
settings: const RouteSettings(name: 'B'), settings: const RouteSettings(name: 'B'),
builder: (BuildContext context) { builder: (BuildContext context) {
log.add('building B'); log.add('building B');
return TextButton( return TextButton(
child: const Text('B'), child: const Text('B'),
onPressed: () { onPressed: () {
key.currentState.push<void>(MaterialPageRoute<int>( key.currentState!.push<void>(MaterialPageRoute<int>(
settings: const RouteSettings(name: 'C'), settings: const RouteSettings(name: 'C'),
builder: (BuildContext context) { builder: (BuildContext context) {
log.add('building C'); log.add('building C');
log.add('found ${ModalRoute.of(context).settings.name}'); log.add('found ${ModalRoute.of(context)!.settings.name}');
return TextButton( return TextButton(
child: const Text('C'), child: const Text('C'),
onPressed: () { onPressed: () {
key.currentState.replace( key.currentState!.replace(
oldRoute: routeB, oldRoute: routeB,
newRoute: MaterialPageRoute<int>( newRoute: MaterialPageRoute<int>(
settings: const RouteSettings(name: 'D'), settings: const RouteSettings(name: 'D'),
...@@ -1284,7 +1282,7 @@ void main() { ...@@ -1284,7 +1282,7 @@ void main() {
await tester.tap(find.text('C')); await tester.tap(find.text('C'));
await tester.pumpAndSettle(const Duration(milliseconds: 10)); await tester.pumpAndSettle(const Duration(milliseconds: 10));
expect(log, <String>['building B', 'building C', 'found C', 'building D']); expect(log, <String>['building B', 'building C', 'found C', 'building D']);
key.currentState.pop<void>(); key.currentState!.pop<void>();
await tester.pumpAndSettle(const Duration(milliseconds: 10)); await tester.pumpAndSettle(const Duration(milliseconds: 10));
expect(log, <String>['building B', 'building C', 'found C', 'building D']); expect(log, <String>['building B', 'building C', 'found C', 'building D']);
}); });
...@@ -1292,9 +1290,9 @@ void main() { ...@@ -1292,9 +1290,9 @@ void main() {
testWidgets('Routes don\'t rebuild just because their animations ended', (WidgetTester tester) async { testWidgets('Routes don\'t rebuild just because their animations ended', (WidgetTester tester) async {
final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();
final List<String> log = <String>[]; final List<String> log = <String>[];
Route<dynamic> nextRoute = PageRouteBuilder<int>( Route<dynamic>? nextRoute = PageRouteBuilder<int>(
pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) { pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
log.add('building page 1 - ${ModalRoute.of(context).canPop}'); log.add('building page 1 - ${ModalRoute.of(context)!.canPop}');
return const Placeholder(); return const Placeholder();
}, },
); );
...@@ -1302,15 +1300,15 @@ void main() { ...@@ -1302,15 +1300,15 @@ void main() {
navigatorKey: key, navigatorKey: key,
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
assert(nextRoute != null); assert(nextRoute != null);
final Route<dynamic> result = nextRoute; final Route<dynamic> result = nextRoute!;
nextRoute = null; nextRoute = null;
return result; return result;
}, },
)); ));
expect(log, <String>['building page 1 - false']); expect(log, <String>['building page 1 - false']);
key.currentState.pushReplacement(PageRouteBuilder<int>( key.currentState!.pushReplacement(PageRouteBuilder<int>(
pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) { pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
log.add('building page 2 - ${ModalRoute.of(context).canPop}'); log.add('building page 2 - ${ModalRoute.of(context)!.canPop}');
return const Placeholder(); return const Placeholder();
}, },
)); ));
...@@ -1319,9 +1317,9 @@ void main() { ...@@ -1319,9 +1317,9 @@ void main() {
expect(log, <String>['building page 1 - false', 'building page 2 - false']); expect(log, <String>['building page 1 - false', 'building page 2 - false']);
await tester.pump(const Duration(milliseconds: 150)); await tester.pump(const Duration(milliseconds: 150));
expect(log, <String>['building page 1 - false', 'building page 2 - false']); expect(log, <String>['building page 1 - false', 'building page 2 - false']);
key.currentState.pushReplacement(PageRouteBuilder<int>( key.currentState!.pushReplacement(PageRouteBuilder<int>(
pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) { pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
log.add('building page 3 - ${ModalRoute.of(context).canPop}'); log.add('building page 3 - ${ModalRoute.of(context)!.canPop}');
return const Placeholder(); return const Placeholder();
}, },
)); ));
...@@ -1390,15 +1388,15 @@ void main() { ...@@ -1390,15 +1388,15 @@ void main() {
}); });
testWidgets('arguments for named routes on Navigator', (WidgetTester tester) async { testWidgets('arguments for named routes on Navigator', (WidgetTester tester) async {
GlobalKey currentRouteKey; late GlobalKey currentRouteKey;
final List<Object> arguments = <Object>[]; final List<Object?> arguments = <Object?>[];
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
arguments.add(settings.arguments); arguments.add(settings.arguments);
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
settings: settings, settings: settings,
builder: (BuildContext context) => Center(key: currentRouteKey = GlobalKey(), child: Text(settings.name)), builder: (BuildContext context) => Center(key: currentRouteKey = GlobalKey(), child: Text(settings.name!)),
); );
}, },
)); ));
...@@ -1408,7 +1406,7 @@ void main() { ...@@ -1408,7 +1406,7 @@ void main() {
arguments.clear(); arguments.clear();
Navigator.pushNamed( Navigator.pushNamed(
currentRouteKey.currentContext, currentRouteKey.currentContext!,
'/A', '/A',
arguments: 'pushNamed', arguments: 'pushNamed',
); );
...@@ -1420,7 +1418,7 @@ void main() { ...@@ -1420,7 +1418,7 @@ void main() {
arguments.clear(); arguments.clear();
Navigator.popAndPushNamed( Navigator.popAndPushNamed(
currentRouteKey.currentContext, currentRouteKey.currentContext!,
'/B', '/B',
arguments: 'popAndPushNamed', arguments: 'popAndPushNamed',
); );
...@@ -1433,7 +1431,7 @@ void main() { ...@@ -1433,7 +1431,7 @@ void main() {
arguments.clear(); arguments.clear();
Navigator.pushNamedAndRemoveUntil( Navigator.pushNamedAndRemoveUntil(
currentRouteKey.currentContext, currentRouteKey.currentContext!,
'/C', '/C',
(Route<dynamic> route) => route.isFirst, (Route<dynamic> route) => route.isFirst,
arguments: 'pushNamedAndRemoveUntil', arguments: 'pushNamedAndRemoveUntil',
...@@ -1448,7 +1446,7 @@ void main() { ...@@ -1448,7 +1446,7 @@ void main() {
arguments.clear(); arguments.clear();
Navigator.pushReplacementNamed( Navigator.pushReplacementNamed(
currentRouteKey.currentContext, currentRouteKey.currentContext!,
'/D', '/D',
arguments: 'pushReplacementNamed', arguments: 'pushReplacementNamed',
); );
...@@ -1465,7 +1463,7 @@ void main() { ...@@ -1465,7 +1463,7 @@ void main() {
testWidgets('arguments for named routes on NavigatorState', (WidgetTester tester) async { testWidgets('arguments for named routes on NavigatorState', (WidgetTester tester) async {
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
final List<Object> arguments = <Object>[]; final List<Object?> arguments = <Object?>[];
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
navigatorKey: navigatorKey, navigatorKey: navigatorKey,
...@@ -1473,7 +1471,7 @@ void main() { ...@@ -1473,7 +1471,7 @@ void main() {
arguments.add(settings.arguments); arguments.add(settings.arguments);
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
settings: settings, settings: settings,
builder: (BuildContext context) => Center(child: Text(settings.name)), builder: (BuildContext context) => Center(child: Text(settings.name!)),
); );
}, },
)); ));
...@@ -1482,7 +1480,7 @@ void main() { ...@@ -1482,7 +1480,7 @@ void main() {
expect(arguments.single, isNull); expect(arguments.single, isNull);
arguments.clear(); arguments.clear();
navigatorKey.currentState.pushNamed( navigatorKey.currentState!.pushNamed(
'/A', '/A',
arguments:'pushNamed', arguments:'pushNamed',
); );
...@@ -1493,7 +1491,7 @@ void main() { ...@@ -1493,7 +1491,7 @@ void main() {
expect(arguments.single, 'pushNamed'); expect(arguments.single, 'pushNamed');
arguments.clear(); arguments.clear();
navigatorKey.currentState.popAndPushNamed( navigatorKey.currentState!.popAndPushNamed(
'/B', '/B',
arguments: 'popAndPushNamed', arguments: 'popAndPushNamed',
); );
...@@ -1505,7 +1503,7 @@ void main() { ...@@ -1505,7 +1503,7 @@ void main() {
expect(arguments.single, 'popAndPushNamed'); expect(arguments.single, 'popAndPushNamed');
arguments.clear(); arguments.clear();
navigatorKey.currentState.pushNamedAndRemoveUntil( navigatorKey.currentState!.pushNamedAndRemoveUntil(
'/C', '/C',
(Route<dynamic> route) => route.isFirst, (Route<dynamic> route) => route.isFirst,
arguments: 'pushNamedAndRemoveUntil', arguments: 'pushNamedAndRemoveUntil',
...@@ -1519,7 +1517,7 @@ void main() { ...@@ -1519,7 +1517,7 @@ void main() {
expect(arguments.single, 'pushNamedAndRemoveUntil'); expect(arguments.single, 'pushNamedAndRemoveUntil');
arguments.clear(); arguments.clear();
navigatorKey.currentState.pushReplacementNamed( navigatorKey.currentState!.pushReplacementNamed(
'/D', '/D',
arguments: 'pushReplacementNamed', arguments: 'pushReplacementNamed',
); );
...@@ -1558,7 +1556,7 @@ void main() { ...@@ -1558,7 +1556,7 @@ void main() {
expect(find.byKey(keyA, skipOffstage: false), findsOneWidget); expect(find.byKey(keyA, skipOffstage: false), findsOneWidget);
expect(find.byKey(keyABC), findsOneWidget); expect(find.byKey(keyABC), findsOneWidget);
keyNav.currentState.pop(); keyNav.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.byKey(keyRoot, skipOffstage: false), findsOneWidget); expect(find.byKey(keyRoot, skipOffstage: false), findsOneWidget);
expect(find.byKey(keyA), findsOneWidget); expect(find.byKey(keyA), findsOneWidget);
...@@ -1599,20 +1597,20 @@ void main() { ...@@ -1599,20 +1597,20 @@ void main() {
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{ final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () {
Navigator.pushNamed(context, '/A'); Navigator.pushNamed(context, '/A');
Navigator.of(context).pop(); Navigator.of(context)!.pop();
}), }),
'/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context); }), '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context); }),
}; };
bool isPushed = false; bool isPushed = false;
bool isPopped = false; bool isPopped = false;
final TestObserver observer = TestObserver() final TestObserver observer = TestObserver()
..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
// Pushes the initial route. // Pushes the initial route.
expect(route is PageRoute && route.settings.name == '/', isTrue); expect(route is PageRoute && route.settings.name == '/', isTrue);
expect(previousRoute, isNull); expect(previousRoute, isNull);
isPushed = true; isPushed = true;
} }
..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPopped = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
isPopped = true; isPopped = true;
}; };
...@@ -1627,7 +1625,7 @@ void main() { ...@@ -1627,7 +1625,7 @@ void main() {
isPushed = false; isPushed = false;
isPopped = false; isPopped = false;
observer.onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { observer.onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
expect(route is PageRoute && route.settings.name == '/A', isTrue); expect(route is PageRoute && route.settings.name == '/A', isTrue);
expect(previousRoute is PageRoute && previousRoute.settings.name == '/', isTrue); expect(previousRoute is PageRoute && previousRoute.settings.name == '/', isTrue);
isPushed = true; isPushed = true;
...@@ -1713,7 +1711,7 @@ void main() { ...@@ -1713,7 +1711,7 @@ void main() {
), ),
); );
expect(ModalRoute.of(topmost.currentContext).overlayEntries.first.opaque, isTrue); expect(ModalRoute.of(topmost.currentContext!)!.overlayEntries.first.opaque, isTrue);
expect(find.byKey(root), findsNothing); // hidden by opaque Route expect(find.byKey(root), findsNothing); // hidden by opaque Route
expect(find.byKey(intermediate), findsNothing); // hidden by opaque Route expect(find.byKey(intermediate), findsNothing); // hidden by opaque Route
...@@ -1730,18 +1728,18 @@ void main() { ...@@ -1730,18 +1728,18 @@ void main() {
initialRoute: '/', initialRoute: '/',
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
return NoAnimationPageRoute( return NoAnimationPageRoute(
pageBuilder: (_) => Container(key: ValueKey<String>(settings.name)), pageBuilder: (_) => Container(key: ValueKey<String>(settings.name!)),
); );
}, },
), ),
); );
expect(find.byKey(const ValueKey<String>('/')), findsOneWidget); expect(find.byKey(const ValueKey<String>('/')), findsOneWidget);
navigator.currentState.pushNamed('/A'); navigator.currentState!.pushNamed('/A');
await tester.pump(); await tester.pump();
final BuildContext topMostContext = tester.element(find.byKey(const ValueKey<String>('/A'))); final BuildContext topMostContext = tester.element(find.byKey(const ValueKey<String>('/A')));
expect(ModalRoute.of(topMostContext).overlayEntries.first.opaque, isTrue); expect(ModalRoute.of(topMostContext)!.overlayEntries.first.opaque, isTrue);
expect(find.byKey(const ValueKey<String>('/')), findsNothing); // hidden by /A expect(find.byKey(const ValueKey<String>('/')), findsNothing); // hidden by /A
expect(find.byKey(const ValueKey<String>('/A')), findsOneWidget); expect(find.byKey(const ValueKey<String>('/A')), findsOneWidget);
...@@ -1757,7 +1755,7 @@ void main() { ...@@ -1757,7 +1755,7 @@ void main() {
initialRoute: '/A/B', initialRoute: '/A/B',
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
return NoAnimationPageRoute( return NoAnimationPageRoute(
pageBuilder: (_) => Container(key: ValueKey<String>(settings.name)), pageBuilder: (_) => Container(key: ValueKey<String>(settings.name!)),
); );
}, },
), ),
...@@ -1768,12 +1766,12 @@ void main() { ...@@ -1768,12 +1766,12 @@ void main() {
final Route<dynamic> oldRoute = ModalRoute.of( final Route<dynamic> oldRoute = ModalRoute.of(
tester.element(find.byKey(const ValueKey<String>('/A'), skipOffstage: false)), tester.element(find.byKey(const ValueKey<String>('/A'), skipOffstage: false)),
); )!;
final Route<void> newRoute = NoAnimationPageRoute( final Route<void> newRoute = NoAnimationPageRoute(
pageBuilder: (_) => Container(key: const ValueKey<String>('/C')), pageBuilder: (_) => Container(key: const ValueKey<String>('/C')),
); );
navigator.currentState.replace<void>(oldRoute: oldRoute, newRoute: newRoute); navigator.currentState!.replace<void>(oldRoute: oldRoute, newRoute: newRoute);
await tester.pump(); await tester.pump();
expect(newRoute.overlayEntries.first.opaque, isTrue); expect(newRoute.overlayEntries.first.opaque, isTrue);
...@@ -1783,7 +1781,7 @@ void main() { ...@@ -1783,7 +1781,7 @@ void main() {
expect(find.byKey(const ValueKey<String>('/C')), findsNothing); // hidden by /A/B expect(find.byKey(const ValueKey<String>('/C')), findsNothing); // hidden by /A/B
expect(find.byKey(const ValueKey<String>('/A/B')), findsOneWidget); expect(find.byKey(const ValueKey<String>('/A/B')), findsOneWidget);
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.byKey(const ValueKey<String>('/')), findsNothing); // hidden by /C expect(find.byKey(const ValueKey<String>('/')), findsNothing); // hidden by /C
...@@ -1816,7 +1814,7 @@ void main() { ...@@ -1816,7 +1814,7 @@ void main() {
); );
expect(tester.state<StatefulTestState>(find.byKey(bottomRoute)).rebuildCount, 1); expect(tester.state<StatefulTestState>(find.byKey(bottomRoute)).rebuildCount, 1);
navigator.currentState.pushNamed('/a'); navigator.currentState!.pushNamed('/a');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
// Bottom route is offstage and did not rebuild. // Bottom route is offstage and did not rebuild.
...@@ -1852,7 +1850,7 @@ void main() { ...@@ -1852,7 +1850,7 @@ void main() {
expect(find.text('+/a+', skipOffstage: false), findsOneWidget); expect(find.text('+/a+', skipOffstage: false), findsOneWidget);
expect(find.text('+/a/b+'), findsOneWidget); expect(find.text('+/a/b+'), findsOneWidget);
g.currentState.pop(); g.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('+/+'), findsNothing); expect(find.text('+/+'), findsNothing);
...@@ -1860,7 +1858,7 @@ void main() { ...@@ -1860,7 +1858,7 @@ void main() {
expect(find.text('+/a+'), findsOneWidget); expect(find.text('+/a+'), findsOneWidget);
expect(find.text('+/a/b+'), findsNothing); expect(find.text('+/a/b+'), findsNothing);
g.currentState.pop(); g.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('+/+'), findsOneWidget); expect(find.text('+/+'), findsOneWidget);
...@@ -1895,7 +1893,7 @@ void main() { ...@@ -1895,7 +1893,7 @@ void main() {
expect(find.text('Hello'), findsNothing); expect(find.text('Hello'), findsNothing);
expect(find.text('World'), findsOneWidget); expect(find.text('World'), findsOneWidget);
g.currentState.pop(); g.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('Hello'), findsOneWidget); expect(find.text('Hello'), findsOneWidget);
...@@ -1911,7 +1909,7 @@ void main() { ...@@ -1911,7 +1909,7 @@ void main() {
) )
); );
final NavigatorState state = Navigator.of(g.currentContext); final NavigatorState state = Navigator.of(g.currentContext!)!;
expect(state, g.currentState); expect(state, g.currentState);
}); });
...@@ -1933,7 +1931,7 @@ void main() { ...@@ -1933,7 +1931,7 @@ void main() {
) )
); );
final NavigatorState state = Navigator.of(sub.currentContext, rootNavigator: true); final NavigatorState state = Navigator.of(sub.currentContext!, rootNavigator: true)!;
expect(state, root.currentState); expect(state, root.currentState);
}); });
...@@ -1954,7 +1952,7 @@ void main() { ...@@ -1954,7 +1952,7 @@ void main() {
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
settings: settings, settings: settings,
builder: (BuildContext context) { builder: (BuildContext context) {
routeNameToContext[settings.name] = ModalRoute.of(context) as MaterialPageRoute<dynamic>; routeNameToContext[settings.name!] = ModalRoute.of(context)! as MaterialPageRoute<dynamic>;
return Text('Route: ${settings.name}'); return Text('Route: ${settings.name}');
}, },
); );
...@@ -1965,17 +1963,17 @@ void main() { ...@@ -1965,17 +1963,17 @@ void main() {
expect(find.text('Route: root'), findsOneWidget); expect(find.text('Route: root'), findsOneWidget);
navigator.currentState.pushNamed('1'); navigator.currentState!.pushNamed('1');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('Route: 1'), findsOneWidget); expect(find.text('Route: 1'), findsOneWidget);
navigator.currentState.pushNamed('2'); navigator.currentState!.pushNamed('2');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('Route: 2'), findsOneWidget); expect(find.text('Route: 2'), findsOneWidget);
navigator.currentState.pushNamed('3'); navigator.currentState!.pushNamed('3');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('Route: 3'), findsOneWidget); expect(find.text('Route: 3'), findsOneWidget);
...@@ -1983,12 +1981,12 @@ void main() { ...@@ -1983,12 +1981,12 @@ void main() {
expect(find.text('Route: 1', skipOffstage: false), findsOneWidget); expect(find.text('Route: 1', skipOffstage: false), findsOneWidget);
expect(find.text('Route: root', skipOffstage: false), findsOneWidget); expect(find.text('Route: root', skipOffstage: false), findsOneWidget);
navigator.currentState.pushNamedAndRemoveUntil('4', (Route<dynamic> route) => route.isFirst); navigator.currentState!.pushNamedAndRemoveUntil('4', (Route<dynamic> route) => route.isFirst);
await tester.pump(); await tester.pump();
expect(find.text('Route: 3'), findsOneWidget); expect(find.text('Route: 3'), findsOneWidget);
expect(find.text('Route: 4'), findsOneWidget); expect(find.text('Route: 4'), findsOneWidget);
final Animation<double> route4Entry = routeNameToContext['4'].animation; final Animation<double> route4Entry = routeNameToContext['4']!.animation!;
expect(route4Entry.value, 0.0); // Entry animation has not started. expect(route4Entry.value, 0.0); // Entry animation has not started.
await tester.pump(kFourTenthsOfTheTransitionDuration); await tester.pump(kFourTenthsOfTheTransitionDuration);
...@@ -2013,7 +2011,7 @@ void main() { ...@@ -2013,7 +2011,7 @@ void main() {
expect(find.text('Route: 1', skipOffstage: false), findsNothing); expect(find.text('Route: 1', skipOffstage: false), findsNothing);
expect(find.text('Route: root', skipOffstage: false), findsOneWidget); expect(find.text('Route: root', skipOffstage: false), findsOneWidget);
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('Route: root'), findsOneWidget); expect(find.text('Route: root'), findsOneWidget);
...@@ -2022,7 +2020,7 @@ void main() { ...@@ -2022,7 +2020,7 @@ void main() {
testWidgets('Wrapping TickerMode can turn off ticking in routes', (WidgetTester tester) async { testWidgets('Wrapping TickerMode can turn off ticking in routes', (WidgetTester tester) async {
int tickCount = 0; int tickCount = 0;
Widget widgetUnderTest({bool enabled}) { Widget widgetUnderTest({required bool enabled}) {
return TickerMode( return TickerMode(
enabled: enabled, enabled: enabled,
child: Directionality( child: Directionality(
...@@ -2065,15 +2063,15 @@ void main() { ...@@ -2065,15 +2063,15 @@ void main() {
testWidgets('Route announce correctly for first route and last route', (WidgetTester tester) async { testWidgets('Route announce correctly for first route and last route', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/57133. // Regression test for https://github.com/flutter/flutter/issues/57133.
Route<void> previousOfFirst = NotAnnounced(); Route<void>? previousOfFirst = NotAnnounced();
Route<void> nextOfFirst = NotAnnounced(); Route<void>? nextOfFirst = NotAnnounced();
Route<void> popNextOfFirst = NotAnnounced(); Route<void>? popNextOfFirst = NotAnnounced();
Route<void> firstRoute; Route<void>? firstRoute;
Route<void> previousOfSecond = NotAnnounced(); Route<void>? previousOfSecond = NotAnnounced();
Route<void> nextOfSecond = NotAnnounced(); Route<void>? nextOfSecond = NotAnnounced();
Route<void> popNextOfSecond = NotAnnounced(); Route<void>? popNextOfSecond = NotAnnounced();
Route<void> secondRoute; Route<void>? secondRoute;
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
await tester.pumpWidget( await tester.pumpWidget(
...@@ -2083,17 +2081,17 @@ void main() { ...@@ -2083,17 +2081,17 @@ void main() {
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
if (settings.name == '/') { if (settings.name == '/') {
firstRoute = RouteAnnouncementSpy( firstRoute = RouteAnnouncementSpy(
onDidChangeNext: (Route<void> next) => nextOfFirst = next, onDidChangeNext: (Route<void>? next) => nextOfFirst = next,
onDidChangePrevious: (Route<void> previous) => previousOfFirst = previous, onDidChangePrevious: (Route<void>? previous) => previousOfFirst = previous,
onDidPopNext: (Route<void> next) => popNextOfFirst = next, onDidPopNext: (Route<void>? next) => popNextOfFirst = next,
settings: settings, settings: settings,
); );
return firstRoute; return firstRoute;
} }
secondRoute = RouteAnnouncementSpy( secondRoute = RouteAnnouncementSpy(
onDidChangeNext: (Route<void> next) => nextOfSecond = next, onDidChangeNext: (Route<void>? next) => nextOfSecond = next,
onDidChangePrevious: (Route<void> previous) => previousOfSecond = previous, onDidChangePrevious: (Route<void>? previous) => previousOfSecond = previous,
onDidPopNext: (Route<void> next) => popNextOfSecond = next, onDidPopNext: (Route<void>? next) => popNextOfSecond = next,
settings: settings, settings: settings,
); );
return secondRoute; return secondRoute;
...@@ -2110,7 +2108,7 @@ void main() { ...@@ -2110,7 +2108,7 @@ void main() {
expect(nextOfSecond, isNull); expect(nextOfSecond, isNull);
expect(popNextOfSecond, isA<NotAnnounced>()); expect(popNextOfSecond, isA<NotAnnounced>());
navigator.currentState.pop(); navigator.currentState!.pop();
expect(popNextOfFirst, secondRoute); expect(popNextOfFirst, secondRoute);
}); });
...@@ -2120,11 +2118,11 @@ void main() { ...@@ -2120,11 +2118,11 @@ void main() {
final List<NavigatorObservation> observations = <NavigatorObservation>[]; final List<NavigatorObservation> observations = <NavigatorObservation>[];
final HeroControllerSpy spy = HeroControllerSpy() final HeroControllerSpy spy = HeroControllerSpy()
..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
observations.add( observations.add(
NavigatorObservation( NavigatorObservation(
current: route?.settings?.name, current: route?.settings.name,
previous: previousRoute?.settings?.name, previous: previousRoute?.settings.name,
operation: 'didPush' operation: 'didPush'
) )
); );
...@@ -2165,7 +2163,7 @@ void main() { ...@@ -2165,7 +2163,7 @@ void main() {
expect(observations[0].current, 'top1'); expect(observations[0].current, 'top1');
expect(observations[0].previous, isNull); expect(observations[0].previous, isNull);
sub.currentState.push(MaterialPageRoute<void>( sub.currentState!.push(MaterialPageRoute<void>(
settings: const RouteSettings(name:'sub2'), settings: const RouteSettings(name:'sub2'),
builder: (BuildContext context) => const Text('sub2') builder: (BuildContext context) => const Text('sub2')
)); ));
...@@ -2175,7 +2173,7 @@ void main() { ...@@ -2175,7 +2173,7 @@ void main() {
// It should not record sub navigator. // It should not record sub navigator.
expect(observations.length, 1); expect(observations.length, 1);
top.currentState.push(MaterialPageRoute<void>( top.currentState!.push(MaterialPageRoute<void>(
settings: const RouteSettings(name:'top2'), settings: const RouteSettings(name:'top2'),
builder: (BuildContext context) => const Text('top2') builder: (BuildContext context) => const Text('top2')
)); ));
...@@ -2191,11 +2189,11 @@ void main() { ...@@ -2191,11 +2189,11 @@ void main() {
final List<NavigatorObservation> observations = <NavigatorObservation>[]; final List<NavigatorObservation> observations = <NavigatorObservation>[];
final HeroControllerSpy spy = HeroControllerSpy() final HeroControllerSpy spy = HeroControllerSpy()
..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
observations.add( observations.add(
NavigatorObservation( NavigatorObservation(
current: route?.settings?.name, current: route?.settings.name,
previous: previousRoute?.settings?.name, previous: previousRoute?.settings.name,
operation: 'didPush' operation: 'didPush'
) )
); );
...@@ -2243,7 +2241,7 @@ void main() { ...@@ -2243,7 +2241,7 @@ void main() {
); );
observations.clear(); observations.clear();
key2.currentState.push(MaterialPageRoute<void>( key2.currentState!.push(MaterialPageRoute<void>(
settings: const RouteSettings(name:'new route'), settings: const RouteSettings(name:'new route'),
builder: (BuildContext context) => const Text('new route') builder: (BuildContext context) => const Text('new route')
)); ));
...@@ -2262,22 +2260,22 @@ void main() { ...@@ -2262,22 +2260,22 @@ void main() {
final List<NavigatorObservation> observations1 = <NavigatorObservation>[]; final List<NavigatorObservation> observations1 = <NavigatorObservation>[];
final HeroControllerSpy spy1 = HeroControllerSpy() final HeroControllerSpy spy1 = HeroControllerSpy()
..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
observations1.add( observations1.add(
NavigatorObservation( NavigatorObservation(
current: route?.settings?.name, current: route?.settings.name,
previous: previousRoute?.settings?.name, previous: previousRoute?.settings.name,
operation: 'didPush' operation: 'didPush'
) )
); );
}; };
final List<NavigatorObservation> observations2 = <NavigatorObservation>[]; final List<NavigatorObservation> observations2 = <NavigatorObservation>[];
final HeroControllerSpy spy2 = HeroControllerSpy() final HeroControllerSpy spy2 = HeroControllerSpy()
..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
observations2.add( observations2.add(
NavigatorObservation( NavigatorObservation(
current: route?.settings?.name, current: route?.settings.name,
previous: previousRoute?.settings?.name, previous: previousRoute?.settings.name,
operation: 'didPush' operation: 'didPush'
) )
); );
...@@ -2370,7 +2368,7 @@ void main() { ...@@ -2370,7 +2368,7 @@ void main() {
); );
// Pushes a route to navigator2. // Pushes a route to navigator2.
key2.currentState.push(MaterialPageRoute<void>( key2.currentState!.push(MaterialPageRoute<void>(
settings: const RouteSettings(name:'new route2'), settings: const RouteSettings(name:'new route2'),
builder: (BuildContext context) => const Text('new route2') builder: (BuildContext context) => const Text('new route2')
)); ));
...@@ -2384,7 +2382,7 @@ void main() { ...@@ -2384,7 +2382,7 @@ void main() {
expect(observations2.length, 1); expect(observations2.length, 1);
// Pushes a route to navigator1 // Pushes a route to navigator1
key1.currentState.push(MaterialPageRoute<void>( key1.currentState!.push(MaterialPageRoute<void>(
settings: const RouteSettings(name:'new route1'), settings: const RouteSettings(name:'new route1'),
builder: (BuildContext context) => const Text('new route1') builder: (BuildContext context) => const Text('new route1')
)); ));
...@@ -2439,14 +2437,14 @@ void main() { ...@@ -2439,14 +2437,14 @@ void main() {
group('Page api', (){ group('Page api', (){
Widget buildNavigator({ Widget buildNavigator({
List<Page<dynamic>> pages, required List<Page<dynamic>> pages,
PopPageCallback onPopPage, required PopPageCallback onPopPage,
GlobalKey<NavigatorState> key, GlobalKey<NavigatorState>? key,
TransitionDelegate<dynamic> transitionDelegate, TransitionDelegate<dynamic>? transitionDelegate,
List<NavigatorObserver> observers = const <NavigatorObserver>[], List<NavigatorObserver> observers = const <NavigatorObserver>[],
}) { }) {
return MediaQuery( return MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance.window), data: MediaQueryData.fromWindow(WidgetsBinding.instance!.window),
child: Localizations( child: Localizations(
locale: const Locale('en', 'US'), locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[ delegates: const <LocalizationsDelegate<dynamic>>[
...@@ -2487,13 +2485,13 @@ void main() { ...@@ -2487,13 +2485,13 @@ void main() {
expect(find.text('second'), findsNothing); expect(find.text('second'), findsNothing);
expect(find.text('initial'), findsNothing); expect(find.text('initial'), findsNothing);
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('third'), findsNothing); expect(find.text('third'), findsNothing);
expect(find.text('second'), findsOneWidget); expect(find.text('second'), findsOneWidget);
expect(find.text('initial'), findsNothing); expect(find.text('initial'), findsNothing);
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('third'), findsNothing); expect(find.text('third'), findsNothing);
expect(find.text('second'), findsNothing); expect(find.text('second'), findsNothing);
...@@ -2501,12 +2499,12 @@ void main() { ...@@ -2501,12 +2499,12 @@ void main() {
}); });
testWidgets('can push and pop pages using page api', (WidgetTester tester) async { testWidgets('can push and pop pages using page api', (WidgetTester tester) async {
Animation<double> secondaryAnimationOfRouteOne; late Animation<double> secondaryAnimationOfRouteOne;
Animation<double> primaryAnimationOfRouteOne; late Animation<double> primaryAnimationOfRouteOne;
Animation<double> secondaryAnimationOfRouteTwo; late Animation<double> secondaryAnimationOfRouteTwo;
Animation<double> primaryAnimationOfRouteTwo; late Animation<double> primaryAnimationOfRouteTwo;
Animation<double> secondaryAnimationOfRouteThree; late Animation<double> secondaryAnimationOfRouteThree;
Animation<double> primaryAnimationOfRouteThree; late Animation<double> primaryAnimationOfRouteThree;
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
List<Page<dynamic>> myPages = <Page<dynamic>>[ List<Page<dynamic>> myPages = <Page<dynamic>>[
BuilderPage( BuilderPage(
...@@ -2636,12 +2634,12 @@ void main() { ...@@ -2636,12 +2634,12 @@ void main() {
testWidgets('can modify routes history and secondary animation still works', (WidgetTester tester) async { testWidgets('can modify routes history and secondary animation still works', (WidgetTester tester) async {
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
Animation<double> secondaryAnimationOfRouteOne; late Animation<double> secondaryAnimationOfRouteOne;
Animation<double> primaryAnimationOfRouteOne; late Animation<double> primaryAnimationOfRouteOne;
Animation<double> secondaryAnimationOfRouteTwo; late Animation<double> secondaryAnimationOfRouteTwo;
Animation<double> primaryAnimationOfRouteTwo; late Animation<double> primaryAnimationOfRouteTwo;
Animation<double> secondaryAnimationOfRouteThree; late Animation<double> secondaryAnimationOfRouteThree;
Animation<double> primaryAnimationOfRouteThree; late Animation<double> primaryAnimationOfRouteThree;
List<Page<dynamic>> myPages = <Page<void>>[ List<Page<dynamic>> myPages = <Page<void>>[
BuilderPage( BuilderPage(
key: const ValueKey<String>('1'), key: const ValueKey<String>('1'),
...@@ -2700,7 +2698,7 @@ void main() { ...@@ -2700,7 +2698,7 @@ void main() {
expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed); expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed); expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 30)); await tester.pump(const Duration(milliseconds: 30));
expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value); expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value);
...@@ -2717,7 +2715,7 @@ void main() { ...@@ -2717,7 +2715,7 @@ void main() {
expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed); expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
expect(primaryAnimationOfRouteOne.status, AnimationStatus.dismissed); expect(primaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 30)); await tester.pump(const Duration(milliseconds: 30));
expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value); expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value);
...@@ -2753,13 +2751,13 @@ void main() { ...@@ -2753,13 +2751,13 @@ void main() {
expect(find.text('second'), findsOneWidget); expect(find.text('second'), findsOneWidget);
expect(find.text('initial'), findsNothing); expect(find.text('initial'), findsNothing);
// Pushes two pageless routes to second page route // Pushes two pageless routes to second page route
navigator.currentState.push( navigator.currentState!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) => const Text('second-pageless1'), builder: (BuildContext context) => const Text('second-pageless1'),
settings: null, settings: null,
) )
); );
navigator.currentState.push( navigator.currentState!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) => const Text('second-pageless2'), builder: (BuildContext context) => const Text('second-pageless2'),
settings: null, settings: null,
...@@ -2789,7 +2787,7 @@ void main() { ...@@ -2789,7 +2787,7 @@ void main() {
expect(find.text('third'), findsOneWidget); expect(find.text('third'), findsOneWidget);
// Pushes one pageless routes to third page route // Pushes one pageless routes to third page route
navigator.currentState.push( navigator.currentState!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) => const Text('third-pageless1'), builder: (BuildContext context) => const Text('third-pageless1'),
settings: null, settings: null,
...@@ -2824,7 +2822,7 @@ void main() { ...@@ -2824,7 +2822,7 @@ void main() {
expect(find.text('second-pageless1'), findsNothing); expect(find.text('second-pageless1'), findsNothing);
expect(find.text('second-pageless2'), findsOneWidget); expect(find.text('second-pageless2'), findsOneWidget);
// Pops the route one by one to make sure the order is correct. // Pops the route one by one to make sure the order is correct.
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('initial'), findsNothing); expect(find.text('initial'), findsNothing);
expect(find.text('third'), findsNothing); expect(find.text('third'), findsNothing);
...@@ -2833,7 +2831,7 @@ void main() { ...@@ -2833,7 +2831,7 @@ void main() {
expect(find.text('second-pageless1'), findsOneWidget); expect(find.text('second-pageless1'), findsOneWidget);
expect(find.text('second-pageless2'), findsNothing); expect(find.text('second-pageless2'), findsNothing);
expect(myPages.length, 3); expect(myPages.length, 3);
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('initial'), findsNothing); expect(find.text('initial'), findsNothing);
expect(find.text('third'), findsNothing); expect(find.text('third'), findsNothing);
...@@ -2842,7 +2840,7 @@ void main() { ...@@ -2842,7 +2840,7 @@ void main() {
expect(find.text('second-pageless1'), findsNothing); expect(find.text('second-pageless1'), findsNothing);
expect(find.text('second-pageless2'), findsNothing); expect(find.text('second-pageless2'), findsNothing);
expect(myPages.length, 3); expect(myPages.length, 3);
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('initial'), findsNothing); expect(find.text('initial'), findsNothing);
expect(find.text('third'), findsNothing); expect(find.text('third'), findsNothing);
...@@ -2851,7 +2849,7 @@ void main() { ...@@ -2851,7 +2849,7 @@ void main() {
expect(find.text('second-pageless1'), findsNothing); expect(find.text('second-pageless1'), findsNothing);
expect(find.text('second-pageless2'), findsNothing); expect(find.text('second-pageless2'), findsNothing);
expect(myPages.length, 2); expect(myPages.length, 2);
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('initial'), findsNothing); expect(find.text('initial'), findsNothing);
expect(find.text('third'), findsOneWidget); expect(find.text('third'), findsOneWidget);
...@@ -2860,7 +2858,7 @@ void main() { ...@@ -2860,7 +2858,7 @@ void main() {
expect(find.text('second-pageless1'), findsNothing); expect(find.text('second-pageless1'), findsNothing);
expect(find.text('second-pageless2'), findsNothing); expect(find.text('second-pageless2'), findsNothing);
expect(myPages.length, 2); expect(myPages.length, 2);
navigator.currentState.pop(); navigator.currentState!.pop();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('initial'), findsOneWidget); expect(find.text('initial'), findsOneWidget);
expect(find.text('third'), findsNothing); expect(find.text('third'), findsNothing);
...@@ -2886,7 +2884,7 @@ void main() { ...@@ -2886,7 +2884,7 @@ void main() {
buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator) buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
); );
bool initialPageless1Completed = false; bool initialPageless1Completed = false;
navigator.currentState.push( navigator.currentState!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) => const Text('initial-pageless1'), builder: (BuildContext context) => const Text('initial-pageless1'),
settings: null, settings: null,
...@@ -2904,7 +2902,7 @@ void main() { ...@@ -2904,7 +2902,7 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
bool secondPageless1Completed = false; bool secondPageless1Completed = false;
navigator.currentState.push( navigator.currentState!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) => const Text('second-pageless1'), builder: (BuildContext context) => const Text('second-pageless1'),
settings: null, settings: null,
...@@ -2912,7 +2910,7 @@ void main() { ...@@ -2912,7 +2910,7 @@ void main() {
).then((_) => secondPageless1Completed = true); ).then((_) => secondPageless1Completed = true);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
bool secondPageless2Completed = false; bool secondPageless2Completed = false;
navigator.currentState.push( navigator.currentState!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) => const Text('second-pageless2'), builder: (BuildContext context) => const Text('second-pageless2'),
settings: null, settings: null,
...@@ -2931,7 +2929,7 @@ void main() { ...@@ -2931,7 +2929,7 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
bool thirdPageless1Completed = false; bool thirdPageless1Completed = false;
navigator.currentState.push( navigator.currentState!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) => const Text('third-pageless1'), builder: (BuildContext context) => const Text('third-pageless1'),
settings: null, settings: null,
...@@ -3002,7 +3000,7 @@ void main() { ...@@ -3002,7 +3000,7 @@ void main() {
) )
); );
bool initialPageless1Completed = false; bool initialPageless1Completed = false;
navigator.currentState.push( navigator.currentState!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) => const Text('initial-pageless1'), builder: (BuildContext context) => const Text('initial-pageless1'),
settings: null, settings: null,
...@@ -3024,7 +3022,7 @@ void main() { ...@@ -3024,7 +3022,7 @@ void main() {
) )
); );
bool secondPageless1Completed = false; bool secondPageless1Completed = false;
navigator.currentState.push( navigator.currentState!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) => const Text('second-pageless1'), builder: (BuildContext context) => const Text('second-pageless1'),
settings: null, settings: null,
...@@ -3032,7 +3030,7 @@ void main() { ...@@ -3032,7 +3030,7 @@ void main() {
).then((_) => secondPageless1Completed = true); ).then((_) => secondPageless1Completed = true);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
bool secondPageless2Completed = false; bool secondPageless2Completed = false;
navigator.currentState.push( navigator.currentState!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) => const Text('second-pageless2'), builder: (BuildContext context) => const Text('second-pageless2'),
settings: null, settings: null,
...@@ -3055,7 +3053,7 @@ void main() { ...@@ -3055,7 +3053,7 @@ void main() {
) )
); );
bool thirdPageless1Completed = false; bool thirdPageless1Completed = false;
navigator.currentState.push( navigator.currentState!.push(
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (BuildContext context) => const Text('third-pageless1'), builder: (BuildContext context) => const Text('third-pageless1'),
settings: null, settings: null,
...@@ -3206,20 +3204,20 @@ void main() { ...@@ -3206,20 +3204,20 @@ void main() {
]; ];
final List<NavigatorObservation> observations = <NavigatorObservation>[]; final List<NavigatorObservation> observations = <NavigatorObservation>[];
final TestObserver observer = TestObserver() final TestObserver observer = TestObserver()
..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onPushed = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
observations.add( observations.add(
NavigatorObservation( NavigatorObservation(
current: route?.settings?.name, current: route?.settings.name,
previous: previousRoute?.settings?.name, previous: previousRoute?.settings.name,
operation: 'push' operation: 'push'
) )
); );
} }
..onRemoved = (Route<dynamic> route, Route<dynamic> previousRoute) { ..onRemoved = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
observations.add( observations.add(
NavigatorObservation( NavigatorObservation(
current: route?.settings?.name, current: route?.settings.name,
previous: previousRoute?.settings?.name, previous: previousRoute?.settings.name,
operation: 'remove' operation: 'remove'
) )
); );
...@@ -3289,7 +3287,7 @@ void main() { ...@@ -3289,7 +3287,7 @@ void main() {
}); });
} }
typedef AnnouncementCallBack = void Function(Route<dynamic>); typedef AnnouncementCallBack = void Function(Route<dynamic>?);
class NotAnnounced extends Route<void> {/* A place holder for not announced route*/} class NotAnnounced extends Route<void> {/* A place holder for not announced route*/}
...@@ -3298,11 +3296,11 @@ class RouteAnnouncementSpy extends Route<void> { ...@@ -3298,11 +3296,11 @@ class RouteAnnouncementSpy extends Route<void> {
this.onDidChangePrevious, this.onDidChangePrevious,
this.onDidChangeNext, this.onDidChangeNext,
this.onDidPopNext, this.onDidPopNext,
RouteSettings settings, RouteSettings? settings,
}) : super(settings: settings); }) : super(settings: settings);
final AnnouncementCallBack onDidChangePrevious; final AnnouncementCallBack? onDidChangePrevious;
final AnnouncementCallBack onDidChangeNext; final AnnouncementCallBack? onDidChangeNext;
final AnnouncementCallBack onDidPopNext; final AnnouncementCallBack? onDidPopNext;
@override @override
List<OverlayEntry> get overlayEntries => <OverlayEntry>[ List<OverlayEntry> get overlayEntries => <OverlayEntry>[
...@@ -3312,29 +3310,29 @@ class RouteAnnouncementSpy extends Route<void> { ...@@ -3312,29 +3310,29 @@ class RouteAnnouncementSpy extends Route<void> {
]; ];
@override @override
void didChangeNext(Route<dynamic> nextRoute) { void didChangeNext(Route<dynamic>? nextRoute) {
super.didChangeNext(nextRoute); super.didChangeNext(nextRoute);
if (onDidChangeNext != null) if (onDidChangeNext != null)
onDidChangeNext(nextRoute); onDidChangeNext!(nextRoute);
} }
@override @override
void didChangePrevious(Route<dynamic> previousRoute) { void didChangePrevious(Route<dynamic>? previousRoute) {
super.didChangePrevious(previousRoute); super.didChangePrevious(previousRoute);
if (onDidChangePrevious != null) if (onDidChangePrevious != null)
onDidChangePrevious(previousRoute); onDidChangePrevious!(previousRoute);
} }
@override @override
void didPopNext(Route<dynamic> nextRoute) { void didPopNext(Route<dynamic> nextRoute) {
super.didPopNext(nextRoute); super.didPopNext(nextRoute);
if (onDidPopNext != null) if (onDidPopNext != null)
onDidPopNext(nextRoute); onDidPopNext!(nextRoute);
} }
} }
class _TickingWidget extends StatefulWidget { class _TickingWidget extends StatefulWidget {
const _TickingWidget({this.onTick}); const _TickingWidget({required this.onTick});
final VoidCallback onTick; final VoidCallback onTick;
...@@ -3343,7 +3341,7 @@ class _TickingWidget extends StatefulWidget { ...@@ -3343,7 +3341,7 @@ class _TickingWidget extends StatefulWidget {
} }
class _TickingWidgetState extends State<_TickingWidget> with SingleTickerProviderStateMixin { class _TickingWidgetState extends State<_TickingWidget> with SingleTickerProviderStateMixin {
Ticker _ticker; late Ticker _ticker;
@override @override
void initState() { void initState() {
...@@ -3368,21 +3366,21 @@ class _TickingWidgetState extends State<_TickingWidget> with SingleTickerProvide ...@@ -3368,21 +3366,21 @@ class _TickingWidgetState extends State<_TickingWidget> with SingleTickerProvide
class AlwaysRemoveTransitionDelegate extends TransitionDelegate<void> { class AlwaysRemoveTransitionDelegate extends TransitionDelegate<void> {
@override @override
Iterable<RouteTransitionRecord> resolve({ Iterable<RouteTransitionRecord> resolve({
List<RouteTransitionRecord> newPageRouteHistory, required List<RouteTransitionRecord> newPageRouteHistory,
Map<RouteTransitionRecord, RouteTransitionRecord> locationToExitingPageRoute, required Map<RouteTransitionRecord?, RouteTransitionRecord> locationToExitingPageRoute,
Map<RouteTransitionRecord, List<RouteTransitionRecord>> pageRouteToPagelessRoutes, required Map<RouteTransitionRecord?, List<RouteTransitionRecord>> pageRouteToPagelessRoutes,
}) { }) {
final List<RouteTransitionRecord> results = <RouteTransitionRecord>[]; final List<RouteTransitionRecord> results = <RouteTransitionRecord>[];
void handleExitingRoute(RouteTransitionRecord location) { void handleExitingRoute(RouteTransitionRecord? location) {
if (!locationToExitingPageRoute.containsKey(location)) if (!locationToExitingPageRoute.containsKey(location))
return; return;
final RouteTransitionRecord exitingPageRoute = locationToExitingPageRoute[location]; final RouteTransitionRecord exitingPageRoute = locationToExitingPageRoute[location]!;
if (exitingPageRoute.isWaitingForExitingDecision) { if (exitingPageRoute.isWaitingForExitingDecision) {
final bool hasPagelessRoute = pageRouteToPagelessRoutes.containsKey(exitingPageRoute); final bool hasPagelessRoute = pageRouteToPagelessRoutes.containsKey(exitingPageRoute);
exitingPageRoute.markForRemove(); exitingPageRoute.markForRemove();
if (hasPagelessRoute) { if (hasPagelessRoute) {
final List<RouteTransitionRecord> pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute]; final List<RouteTransitionRecord> pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute]!;
for (final RouteTransitionRecord pagelessRoute in pagelessRoutes) { for (final RouteTransitionRecord pagelessRoute in pagelessRoutes) {
pagelessRoute.markForRemove(); pagelessRoute.markForRemove();
} }
...@@ -3408,22 +3406,22 @@ class AlwaysRemoveTransitionDelegate extends TransitionDelegate<void> { ...@@ -3408,22 +3406,22 @@ class AlwaysRemoveTransitionDelegate extends TransitionDelegate<void> {
class TestPage extends Page<void> { class TestPage extends Page<void> {
const TestPage({ const TestPage({
LocalKey key, LocalKey? key,
String name, required String name,
Object arguments, Object? arguments,
}) : super(key: key, name: name, arguments: arguments); }) : super(key: key, name: name, arguments: arguments);
@override @override
Route<void> createRoute(BuildContext context) { Route<void> createRoute(BuildContext context) {
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
builder: (BuildContext context) => Text(name), builder: (BuildContext context) => Text(name!),
settings: this, settings: this,
); );
} }
} }
class NoAnimationPageRoute extends PageRouteBuilder<void> { class NoAnimationPageRoute extends PageRouteBuilder<void> {
NoAnimationPageRoute({WidgetBuilder pageBuilder}) NoAnimationPageRoute({required WidgetBuilder pageBuilder})
: super(pageBuilder: (BuildContext context, __, ___) { : super(pageBuilder: (BuildContext context, __, ___) {
return pageBuilder(context); return pageBuilder(context);
}); });
...@@ -3435,7 +3433,7 @@ class NoAnimationPageRoute extends PageRouteBuilder<void> { ...@@ -3435,7 +3433,7 @@ class NoAnimationPageRoute extends PageRouteBuilder<void> {
} }
class StatefulTestWidget extends StatefulWidget { class StatefulTestWidget extends StatefulWidget {
const StatefulTestWidget({Key key}) : super(key: key); const StatefulTestWidget({Key? key}) : super(key: key);
@override @override
State<StatefulTestWidget> createState() => StatefulTestState(); State<StatefulTestWidget> createState() => StatefulTestState();
...@@ -3452,24 +3450,24 @@ class StatefulTestState extends State<StatefulTestWidget> { ...@@ -3452,24 +3450,24 @@ class StatefulTestState extends State<StatefulTestWidget> {
} }
class HeroControllerSpy extends HeroController { class HeroControllerSpy extends HeroController {
OnObservation onPushed; OnObservation? onPushed;
@override @override
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) { void didPush(Route<dynamic>? route, Route<dynamic>? previousRoute) {
if (onPushed != null) { if (onPushed != null) {
onPushed(route, previousRoute); onPushed!(route, previousRoute);
} }
} }
} }
class NavigatorObservation { class NavigatorObservation {
const NavigatorObservation({this.previous, this.current, this.operation}); const NavigatorObservation({this.previous, this.current, required this.operation});
final String previous; final String? previous;
final String current; final String? current;
final String operation; final String operation;
} }
class BuilderPage extends Page<void> { class BuilderPage extends Page<void> {
const BuilderPage({LocalKey key, String name, this.pageBuilder}) : super(key: key, name: name); const BuilderPage({LocalKey? key, String? name, required this.pageBuilder}) : super(key: key, name: name);
final RoutePageBuilder pageBuilder; final RoutePageBuilder pageBuilder;
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
...@@ -13,10 +11,10 @@ import 'package:flutter/rendering.dart'; ...@@ -13,10 +11,10 @@ import 'package:flutter/rendering.dart';
import '../rendering/rendering_tester.dart'; import '../rendering/rendering_tester.dart';
class _CustomPhysics extends ClampingScrollPhysics { class _CustomPhysics extends ClampingScrollPhysics {
const _CustomPhysics({ ScrollPhysics parent }) : super(parent: parent); const _CustomPhysics({ ScrollPhysics? parent }) : super(parent: parent);
@override @override
_CustomPhysics applyTo(ScrollPhysics ancestor) { _CustomPhysics applyTo(ScrollPhysics? ancestor) {
return _CustomPhysics(parent: buildParent(ancestor)); return _CustomPhysics(parent: buildParent(ancestor));
} }
...@@ -27,9 +25,9 @@ class _CustomPhysics extends ClampingScrollPhysics { ...@@ -27,9 +25,9 @@ class _CustomPhysics extends ClampingScrollPhysics {
} }
Widget buildTest({ Widget buildTest({
ScrollController controller, ScrollController? controller,
String title = 'TTTTTTTT', String title = 'TTTTTTTT',
Key key, Key? key,
bool expanded = true, bool expanded = true,
}) { }) {
return Localizations( return Localizations(
...@@ -298,7 +296,7 @@ void main() { ...@@ -298,7 +296,7 @@ void main() {
initialScrollOffset: 50.0, initialScrollOffset: 50.0,
); );
double scrollOffset; late double scrollOffset;
controller.addListener(() { controller.addListener(() {
scrollOffset = controller.offset; scrollOffset = controller.offset;
}); });
...@@ -594,15 +592,15 @@ void main() { ...@@ -594,15 +592,15 @@ void main() {
)), )),
); );
PhysicalModelLayer _dfsFindPhysicalLayer(ContainerLayer layer) { PhysicalModelLayer? _dfsFindPhysicalLayer(ContainerLayer layer) {
expect(layer, isNotNull); expect(layer, isNotNull);
Layer child = layer.firstChild; Layer? child = layer.firstChild;
while (child != null) { while (child != null) {
if (child is PhysicalModelLayer) { if (child is PhysicalModelLayer) {
return child; return child;
} }
if (child is ContainerLayer) { if (child is ContainerLayer) {
final PhysicalModelLayer candidate = _dfsFindPhysicalLayer(child); final PhysicalModelLayer? candidate = _dfsFindPhysicalLayer(child);
if (candidate != null) { if (candidate != null) {
return candidate; return candidate;
} }
...@@ -612,11 +610,11 @@ void main() { ...@@ -612,11 +610,11 @@ void main() {
return null; return null;
} }
final ContainerLayer nestedScrollViewLayer = find.byType(NestedScrollView).evaluate().first.renderObject.debugLayer; final ContainerLayer nestedScrollViewLayer = find.byType(NestedScrollView).evaluate().first.renderObject!.debugLayer!;
void _checkPhysicalLayer({@required double elevation}) { void _checkPhysicalLayer({required double elevation}) {
final PhysicalModelLayer layer = _dfsFindPhysicalLayer(nestedScrollViewLayer); final PhysicalModelLayer? layer = _dfsFindPhysicalLayer(nestedScrollViewLayer);
expect(layer, isNotNull); expect(layer, isNotNull);
expect(layer.elevation, equals(elevation)); expect(layer!.elevation, equals(elevation));
} }
int expectedBuildCount = 0; int expectedBuildCount = 0;
...@@ -861,8 +859,8 @@ void main() { ...@@ -861,8 +859,8 @@ void main() {
double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height; double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
expect(appBarHeight, 104.0); expect(appBarHeight, 104.0);
final double scrollExtent = appBarHeight - 50.0; final double scrollExtent = appBarHeight - 50.0;
expect(globalKey.currentState.outerController.offset, 0.0); expect(globalKey.currentState!.outerController.offset, 0.0);
expect(globalKey.currentState.innerController.offset, 0.0); expect(globalKey.currentState!.innerController.offset, 0.0);
// The scroll gesture should occur in the inner body, so the whole // The scroll gesture should occur in the inner body, so the whole
// scroll view is scrolled. // scroll view is scrolled.
...@@ -878,9 +876,9 @@ void main() { ...@@ -878,9 +876,9 @@ void main() {
expect(appBarHeight, 104.0); expect(appBarHeight, 104.0);
// The outer scroll controller should show an offset of the applied // The outer scroll controller should show an offset of the applied
// scrollExtent. // scrollExtent.
expect(globalKey.currentState.outerController.offset, 54.0); expect(globalKey.currentState!.outerController.offset, 54.0);
// the inner scroll controller should not have scrolled. // the inner scroll controller should not have scrolled.
expect(globalKey.currentState.innerController.offset, 0.0); expect(globalKey.currentState!.innerController.offset, 0.0);
}); });
testWidgets('Scrolling by exactly the outer extent does not scroll the inner body', (WidgetTester tester) async { testWidgets('Scrolling by exactly the outer extent does not scroll the inner body', (WidgetTester tester) async {
...@@ -893,8 +891,8 @@ void main() { ...@@ -893,8 +891,8 @@ void main() {
double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height; double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
expect(appBarHeight, 104.0); expect(appBarHeight, 104.0);
final double scrollExtent = appBarHeight; final double scrollExtent = appBarHeight;
expect(globalKey.currentState.outerController.offset, 0.0); expect(globalKey.currentState!.outerController.offset, 0.0);
expect(globalKey.currentState.innerController.offset, 0.0); expect(globalKey.currentState!.innerController.offset, 0.0);
// The scroll gesture should occur in the inner body, so the whole // The scroll gesture should occur in the inner body, so the whole
// scroll view is scrolled. // scroll view is scrolled.
...@@ -910,9 +908,9 @@ void main() { ...@@ -910,9 +908,9 @@ void main() {
expect(appBarHeight, 104.0); expect(appBarHeight, 104.0);
// The outer scroll controller should show an offset of the applied // The outer scroll controller should show an offset of the applied
// scrollExtent. // scrollExtent.
expect(globalKey.currentState.outerController.offset, 104.0); expect(globalKey.currentState!.outerController.offset, 104.0);
// the inner scroll controller should not have scrolled. // the inner scroll controller should not have scrolled.
expect(globalKey.currentState.innerController.offset, 0.0); expect(globalKey.currentState!.innerController.offset, 0.0);
}); });
testWidgets('Scrolling by greater than the outer extent scrolls the inner body', (WidgetTester tester) async { testWidgets('Scrolling by greater than the outer extent scrolls the inner body', (WidgetTester tester) async {
...@@ -925,8 +923,8 @@ void main() { ...@@ -925,8 +923,8 @@ void main() {
double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height; double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
expect(appBarHeight, 104.0); expect(appBarHeight, 104.0);
final double scrollExtent = appBarHeight + 50.0; final double scrollExtent = appBarHeight + 50.0;
expect(globalKey.currentState.outerController.offset, 0.0); expect(globalKey.currentState!.outerController.offset, 0.0);
expect(globalKey.currentState.innerController.offset, 0.0); expect(globalKey.currentState!.innerController.offset, 0.0);
// The scroll gesture should occur in the inner body, so the whole // The scroll gesture should occur in the inner body, so the whole
// scroll view is scrolled. // scroll view is scrolled.
...@@ -942,11 +940,11 @@ void main() { ...@@ -942,11 +940,11 @@ void main() {
expect(appBarHeight, 104.0); expect(appBarHeight, 104.0);
// The outer scroll controller should show an offset of the applied // The outer scroll controller should show an offset of the applied
// scrollExtent. // scrollExtent.
expect(globalKey.currentState.outerController.offset, appBarHeight); expect(globalKey.currentState!.outerController.offset, appBarHeight);
// the inner scroll controller should have scrolled equivalent to the // the inner scroll controller should have scrolled equivalent to the
// difference between the applied scrollExtent and the outer extent. // difference between the applied scrollExtent and the outer extent.
expect( expect(
globalKey.currentState.innerController.offset, globalKey.currentState!.innerController.offset,
scrollExtent - appBarHeight, scrollExtent - appBarHeight,
); );
}); });
...@@ -958,8 +956,8 @@ void main() { ...@@ -958,8 +956,8 @@ void main() {
double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height; double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
expect(appBarHeight, 200.0); expect(appBarHeight, 200.0);
final double scrollExtent = appBarHeight - 50.0; final double scrollExtent = appBarHeight - 50.0;
expect(globalKey.currentState.outerController.offset, 0.0); expect(globalKey.currentState!.outerController.offset, 0.0);
expect(globalKey.currentState.innerController.offset, 0.0); expect(globalKey.currentState!.innerController.offset, 0.0);
// The scroll gesture should occur in the inner body, so the whole // The scroll gesture should occur in the inner body, so the whole
// scroll view is scrolled. // scroll view is scrolled.
...@@ -975,9 +973,9 @@ void main() { ...@@ -975,9 +973,9 @@ void main() {
expect(appBarHeight, 104.0); expect(appBarHeight, 104.0);
// The outer scroll controller should show an offset of the applied // The outer scroll controller should show an offset of the applied
// scrollExtent. // scrollExtent.
expect(globalKey.currentState.outerController.offset, 150.0); expect(globalKey.currentState!.outerController.offset, 150.0);
// the inner scroll controller should not have scrolled. // the inner scroll controller should not have scrolled.
expect(globalKey.currentState.innerController.offset, 0.0); expect(globalKey.currentState!.innerController.offset, 0.0);
}); });
testWidgets('scrolling by exactly the expanded outer extent does not scroll the inner body', (WidgetTester tester) async { testWidgets('scrolling by exactly the expanded outer extent does not scroll the inner body', (WidgetTester tester) async {
...@@ -987,8 +985,8 @@ void main() { ...@@ -987,8 +985,8 @@ void main() {
double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height; double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
expect(appBarHeight, 200.0); expect(appBarHeight, 200.0);
final double scrollExtent = appBarHeight; final double scrollExtent = appBarHeight;
expect(globalKey.currentState.outerController.offset, 0.0); expect(globalKey.currentState!.outerController.offset, 0.0);
expect(globalKey.currentState.innerController.offset, 0.0); expect(globalKey.currentState!.innerController.offset, 0.0);
// The scroll gesture should occur in the inner body, so the whole // The scroll gesture should occur in the inner body, so the whole
// scroll view is scrolled. // scroll view is scrolled.
...@@ -1004,9 +1002,9 @@ void main() { ...@@ -1004,9 +1002,9 @@ void main() {
expect(appBarHeight, 104.0); expect(appBarHeight, 104.0);
// The outer scroll controller should show an offset of the applied // The outer scroll controller should show an offset of the applied
// scrollExtent. // scrollExtent.
expect(globalKey.currentState.outerController.offset, 200.0); expect(globalKey.currentState!.outerController.offset, 200.0);
// the inner scroll controller should not have scrolled. // the inner scroll controller should not have scrolled.
expect(globalKey.currentState.innerController.offset, 0.0); expect(globalKey.currentState!.innerController.offset, 0.0);
}); });
testWidgets('scrolling by greater than the expanded outer extent scrolls the inner body', (WidgetTester tester) async { testWidgets('scrolling by greater than the expanded outer extent scrolls the inner body', (WidgetTester tester) async {
...@@ -1016,8 +1014,8 @@ void main() { ...@@ -1016,8 +1014,8 @@ void main() {
double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height; double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
expect(appBarHeight, 200.0); expect(appBarHeight, 200.0);
final double scrollExtent = appBarHeight + 50.0; final double scrollExtent = appBarHeight + 50.0;
expect(globalKey.currentState.outerController.offset, 0.0); expect(globalKey.currentState!.outerController.offset, 0.0);
expect(globalKey.currentState.innerController.offset, 0.0); expect(globalKey.currentState!.innerController.offset, 0.0);
// The scroll gesture should occur in the inner body, so the whole // The scroll gesture should occur in the inner body, so the whole
// scroll view is scrolled. // scroll view is scrolled.
...@@ -1033,10 +1031,10 @@ void main() { ...@@ -1033,10 +1031,10 @@ void main() {
expect(appBarHeight, 104.0); expect(appBarHeight, 104.0);
// The outer scroll controller should show an offset of the applied // The outer scroll controller should show an offset of the applied
// scrollExtent. // scrollExtent.
expect(globalKey.currentState.outerController.offset, 200.0); expect(globalKey.currentState!.outerController.offset, 200.0);
// the inner scroll controller should have scrolled equivalent to the // the inner scroll controller should have scrolled equivalent to the
// difference between the applied scrollExtent and the outer extent. // difference between the applied scrollExtent and the outer extent.
expect(globalKey.currentState.innerController.offset, 50.0); expect(globalKey.currentState!.innerController.offset, 50.0);
}); });
testWidgets('NestedScrollViewState.outerController should correspond to NestedScrollView.controller', ( testWidgets('NestedScrollViewState.outerController should correspond to NestedScrollView.controller', (
...@@ -1059,11 +1057,11 @@ void main() { ...@@ -1059,11 +1057,11 @@ void main() {
expect( expect(
scrollController.offset, scrollController.offset,
globalKey.currentState.outerController.offset, globalKey.currentState!.outerController.offset,
); );
expect( expect(
tester.widget<NestedScrollView>(find.byType(NestedScrollView)).controller.offset, tester.widget<NestedScrollView>(find.byType(NestedScrollView)).controller!.offset,
globalKey.currentState.outerController.offset, globalKey.currentState!.outerController.offset,
); );
}); });
...@@ -1074,21 +1072,21 @@ void main() { ...@@ -1074,21 +1072,21 @@ void main() {
key: globalKey1, key: globalKey1,
expanded: false, expanded: false,
)); ));
expect(globalKey1.currentState.outerController.position.pixels, 0.0); expect(globalKey1.currentState!.outerController.position.pixels, 0.0);
expect(globalKey1.currentState.innerController.position.pixels, 0.0); expect(globalKey1.currentState!.innerController.position.pixels, 0.0);
final double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height; final double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
// Manipulating Inner // Manipulating Inner
globalKey1.currentState.innerController.jumpTo(100.0); globalKey1.currentState!.innerController.jumpTo(100.0);
expect(globalKey1.currentState.innerController.position.pixels, 100.0); expect(globalKey1.currentState!.innerController.position.pixels, 100.0);
expect( expect(
globalKey1.currentState.outerController.position.pixels, globalKey1.currentState!.outerController.position.pixels,
appBarHeight, appBarHeight,
); );
globalKey1.currentState.innerController.jumpTo(0.0); globalKey1.currentState!.innerController.jumpTo(0.0);
expect(globalKey1.currentState.innerController.position.pixels, 0.0); expect(globalKey1.currentState!.innerController.position.pixels, 0.0);
expect( expect(
globalKey1.currentState.outerController.position.pixels, globalKey1.currentState!.outerController.position.pixels,
appBarHeight, appBarHeight,
); );
...@@ -1098,16 +1096,16 @@ void main() { ...@@ -1098,16 +1096,16 @@ void main() {
key: globalKey2, key: globalKey2,
expanded: false, expanded: false,
)); ));
expect(globalKey2.currentState.outerController.position.pixels, 0.0); expect(globalKey2.currentState!.outerController.position.pixels, 0.0);
expect(globalKey2.currentState.innerController.position.pixels, 0.0); expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
// Manipulating Outer // Manipulating Outer
globalKey2.currentState.outerController.jumpTo(100.0); globalKey2.currentState!.outerController.jumpTo(100.0);
expect(globalKey2.currentState.innerController.position.pixels, 0.0); expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
expect(globalKey2.currentState.outerController.position.pixels, 100.0); expect(globalKey2.currentState!.outerController.position.pixels, 100.0);
globalKey2.currentState.outerController.jumpTo(0.0); globalKey2.currentState!.outerController.jumpTo(0.0);
expect(globalKey2.currentState.innerController.position.pixels, 0.0); expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
expect(globalKey2.currentState.outerController.position.pixels, 0.0); expect(globalKey2.currentState!.outerController.position.pixels, 0.0);
}); });
testWidgets('outer: not scrolled, inner: scrolled', (WidgetTester tester) async { testWidgets('outer: not scrolled, inner: scrolled', (WidgetTester tester) async {
...@@ -1116,22 +1114,22 @@ void main() { ...@@ -1116,22 +1114,22 @@ void main() {
key: globalKey1, key: globalKey1,
expanded: false, expanded: false,
)); ));
expect(globalKey1.currentState.outerController.position.pixels, 0.0); expect(globalKey1.currentState!.outerController.position.pixels, 0.0);
globalKey1.currentState.innerController.position.setPixels(10.0); globalKey1.currentState!.innerController.position.setPixels(10.0);
expect(globalKey1.currentState.innerController.position.pixels, 10.0); expect(globalKey1.currentState!.innerController.position.pixels, 10.0);
final double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height; final double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
// Manipulating Inner // Manipulating Inner
globalKey1.currentState.innerController.jumpTo(100.0); globalKey1.currentState!.innerController.jumpTo(100.0);
expect(globalKey1.currentState.innerController.position.pixels, 100.0); expect(globalKey1.currentState!.innerController.position.pixels, 100.0);
expect( expect(
globalKey1.currentState.outerController.position.pixels, globalKey1.currentState!.outerController.position.pixels,
appBarHeight, appBarHeight,
); );
globalKey1.currentState.innerController.jumpTo(0.0); globalKey1.currentState!.innerController.jumpTo(0.0);
expect(globalKey1.currentState.innerController.position.pixels, 0.0); expect(globalKey1.currentState!.innerController.position.pixels, 0.0);
expect( expect(
globalKey1.currentState.outerController.position.pixels, globalKey1.currentState!.outerController.position.pixels,
appBarHeight, appBarHeight,
); );
...@@ -1141,17 +1139,17 @@ void main() { ...@@ -1141,17 +1139,17 @@ void main() {
key: globalKey2, key: globalKey2,
expanded: false, expanded: false,
)); ));
expect(globalKey2.currentState.outerController.position.pixels, 0.0); expect(globalKey2.currentState!.outerController.position.pixels, 0.0);
globalKey2.currentState.innerController.position.setPixels(10.0); globalKey2.currentState!.innerController.position.setPixels(10.0);
expect(globalKey2.currentState.innerController.position.pixels, 10.0); expect(globalKey2.currentState!.innerController.position.pixels, 10.0);
// Manipulating Outer // Manipulating Outer
globalKey2.currentState.outerController.jumpTo(100.0); globalKey2.currentState!.outerController.jumpTo(100.0);
expect(globalKey2.currentState.innerController.position.pixels, 0.0); expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
expect(globalKey2.currentState.outerController.position.pixels, 100.0); expect(globalKey2.currentState!.outerController.position.pixels, 100.0);
globalKey2.currentState.outerController.jumpTo(0.0); globalKey2.currentState!.outerController.jumpTo(0.0);
expect(globalKey2.currentState.innerController.position.pixels, 0.0); expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
expect(globalKey2.currentState.outerController.position.pixels, 0.0); expect(globalKey2.currentState!.outerController.position.pixels, 0.0);
}); });
testWidgets('outer: scrolled, inner: not scrolled', (WidgetTester tester) async { testWidgets('outer: scrolled, inner: not scrolled', (WidgetTester tester) async {
...@@ -1160,22 +1158,22 @@ void main() { ...@@ -1160,22 +1158,22 @@ void main() {
key: globalKey1, key: globalKey1,
expanded: false, expanded: false,
)); ));
expect(globalKey1.currentState.innerController.position.pixels, 0.0); expect(globalKey1.currentState!.innerController.position.pixels, 0.0);
globalKey1.currentState.outerController.position.setPixels(10.0); globalKey1.currentState!.outerController.position.setPixels(10.0);
expect(globalKey1.currentState.outerController.position.pixels, 10.0); expect(globalKey1.currentState!.outerController.position.pixels, 10.0);
final double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height; final double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
// Manipulating Inner // Manipulating Inner
globalKey1.currentState.innerController.jumpTo(100.0); globalKey1.currentState!.innerController.jumpTo(100.0);
expect(globalKey1.currentState.innerController.position.pixels, 100.0); expect(globalKey1.currentState!.innerController.position.pixels, 100.0);
expect( expect(
globalKey1.currentState.outerController.position.pixels, globalKey1.currentState!.outerController.position.pixels,
appBarHeight, appBarHeight,
); );
globalKey1.currentState.innerController.jumpTo(0.0); globalKey1.currentState!.innerController.jumpTo(0.0);
expect(globalKey1.currentState.innerController.position.pixels, 0.0); expect(globalKey1.currentState!.innerController.position.pixels, 0.0);
expect( expect(
globalKey1.currentState.outerController.position.pixels, globalKey1.currentState!.outerController.position.pixels,
appBarHeight, appBarHeight,
); );
...@@ -1185,17 +1183,17 @@ void main() { ...@@ -1185,17 +1183,17 @@ void main() {
key: globalKey2, key: globalKey2,
expanded: false, expanded: false,
)); ));
expect(globalKey2.currentState.innerController.position.pixels, 0.0); expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
globalKey2.currentState.outerController.position.setPixels(10.0); globalKey2.currentState!.outerController.position.setPixels(10.0);
expect(globalKey2.currentState.outerController.position.pixels, 10.0); expect(globalKey2.currentState!.outerController.position.pixels, 10.0);
// Manipulating Outer // Manipulating Outer
globalKey2.currentState.outerController.jumpTo(100.0); globalKey2.currentState!.outerController.jumpTo(100.0);
expect(globalKey2.currentState.innerController.position.pixels, 0.0); expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
expect(globalKey2.currentState.outerController.position.pixels, 100.0); expect(globalKey2.currentState!.outerController.position.pixels, 100.0);
globalKey2.currentState.outerController.jumpTo(0.0); globalKey2.currentState!.outerController.jumpTo(0.0);
expect(globalKey2.currentState.innerController.position.pixels, 0.0); expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
expect(globalKey2.currentState.outerController.position.pixels, 0.0); expect(globalKey2.currentState!.outerController.position.pixels, 0.0);
}); });
testWidgets('outer: scrolled, inner: scrolled', (WidgetTester tester) async { testWidgets('outer: scrolled, inner: scrolled', (WidgetTester tester) async {
...@@ -1204,23 +1202,23 @@ void main() { ...@@ -1204,23 +1202,23 @@ void main() {
key: globalKey1, key: globalKey1,
expanded: false, expanded: false,
)); ));
globalKey1.currentState.innerController.position.setPixels(10.0); globalKey1.currentState!.innerController.position.setPixels(10.0);
expect(globalKey1.currentState.innerController.position.pixels, 10.0); expect(globalKey1.currentState!.innerController.position.pixels, 10.0);
globalKey1.currentState.outerController.position.setPixels(10.0); globalKey1.currentState!.outerController.position.setPixels(10.0);
expect(globalKey1.currentState.outerController.position.pixels, 10.0); expect(globalKey1.currentState!.outerController.position.pixels, 10.0);
final double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height; final double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
// Manipulating Inner // Manipulating Inner
globalKey1.currentState.innerController.jumpTo(100.0); globalKey1.currentState!.innerController.jumpTo(100.0);
expect(globalKey1.currentState.innerController.position.pixels, 100.0); expect(globalKey1.currentState!.innerController.position.pixels, 100.0);
expect( expect(
globalKey1.currentState.outerController.position.pixels, globalKey1.currentState!.outerController.position.pixels,
appBarHeight, appBarHeight,
); );
globalKey1.currentState.innerController.jumpTo(0.0); globalKey1.currentState!.innerController.jumpTo(0.0);
expect(globalKey1.currentState.innerController.position.pixels, 0.0); expect(globalKey1.currentState!.innerController.position.pixels, 0.0);
expect( expect(
globalKey1.currentState.outerController.position.pixels, globalKey1.currentState!.outerController.position.pixels,
appBarHeight, appBarHeight,
); );
...@@ -1230,18 +1228,18 @@ void main() { ...@@ -1230,18 +1228,18 @@ void main() {
key: globalKey2, key: globalKey2,
expanded: false, expanded: false,
)); ));
globalKey2.currentState.innerController.position.setPixels(10.0); globalKey2.currentState!.innerController.position.setPixels(10.0);
expect(globalKey2.currentState.innerController.position.pixels, 10.0); expect(globalKey2.currentState!.innerController.position.pixels, 10.0);
globalKey2.currentState.outerController.position.setPixels(10.0); globalKey2.currentState!.outerController.position.setPixels(10.0);
expect(globalKey2.currentState.outerController.position.pixels, 10.0); expect(globalKey2.currentState!.outerController.position.pixels, 10.0);
// Manipulating Outer // Manipulating Outer
globalKey2.currentState.outerController.jumpTo(100.0); globalKey2.currentState!.outerController.jumpTo(100.0);
expect(globalKey2.currentState.innerController.position.pixels, 0.0); expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
expect(globalKey2.currentState.outerController.position.pixels, 100.0); expect(globalKey2.currentState!.outerController.position.pixels, 100.0);
globalKey2.currentState.outerController.jumpTo(0.0); globalKey2.currentState!.outerController.jumpTo(0.0);
expect(globalKey2.currentState.innerController.position.pixels, 0.0); expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
expect(globalKey2.currentState.outerController.position.pixels, 0.0); expect(globalKey2.currentState!.outerController.position.pixels, 0.0);
}); });
}); });
}); });
...@@ -1254,9 +1252,9 @@ void main() { ...@@ -1254,9 +1252,9 @@ void main() {
group('NestedScrollView can float outer sliver with inner scroll view:', () { group('NestedScrollView can float outer sliver with inner scroll view:', () {
Widget buildFloatTest({ Widget buildFloatTest({
GlobalKey appBarKey, GlobalKey? appBarKey,
GlobalKey nestedKey, GlobalKey? nestedKey,
ScrollController controller, ScrollController? controller,
bool floating = false, bool floating = false,
bool pinned = false, bool pinned = false,
bool snap = false, bool snap = false,
...@@ -1306,14 +1304,14 @@ void main() { ...@@ -1306,14 +1304,14 @@ void main() {
} }
double verifyGeometry({ double verifyGeometry({
GlobalKey key, required GlobalKey key,
double paintExtent, required double paintExtent,
bool extentGreaterThan = false, bool extentGreaterThan = false,
bool extentLessThan = false, bool extentLessThan = false,
bool visible, required bool visible,
}) { }) {
final RenderSliver target = key.currentContext.findRenderObject() as RenderSliver; final RenderSliver target = key.currentContext!.findRenderObject()! as RenderSliver;
final SliverGeometry geometry = target.geometry; final SliverGeometry geometry = target.geometry!;
expect(target.parent, isA<RenderSliverOverlapAbsorber>()); expect(target.parent, isA<RenderSliverOverlapAbsorber>());
expect(geometry.visible, visible); expect(geometry.visible, visible);
if (extentGreaterThan) if (extentGreaterThan)
...@@ -1461,7 +1459,7 @@ void main() { ...@@ -1461,7 +1459,7 @@ void main() {
verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false); verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
// The outer scroll view should be at its full extent, here the size of // The outer scroll view should be at its full extent, here the size of
// the app bar. // the app bar.
expect(nestedKey.currentState.outerController.offset, 56.0); expect(nestedKey.currentState!.outerController.offset, 56.0);
// Animate In // Animate In
...@@ -1474,7 +1472,7 @@ void main() { ...@@ -1474,7 +1472,7 @@ void main() {
expect(find.text('Item 1'), findsNothing); expect(find.text('Item 1'), findsNothing);
expect(find.text('Item 5'), findsOneWidget); expect(find.text('Item 5'), findsOneWidget);
verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false); verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
expect(nestedKey.currentState.outerController.offset, 56.0); expect(nestedKey.currentState!.outerController.offset, 56.0);
await animateInGesture.moveBy(const Offset(0.0, -50.0)); // No float out await animateInGesture.moveBy(const Offset(0.0, -50.0)); // No float out
await tester.pump(); await tester.pump();
...@@ -1482,7 +1480,7 @@ void main() { ...@@ -1482,7 +1480,7 @@ void main() {
expect(find.text('Item 1'), findsNothing); expect(find.text('Item 1'), findsNothing);
expect(find.text('Item 5'), findsOneWidget); expect(find.text('Item 5'), findsOneWidget);
verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false); verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
expect(nestedKey.currentState.outerController.offset, 56.0); expect(nestedKey.currentState!.outerController.offset, 56.0);
// Trigger the snap open animation: drag down and release // Trigger the snap open animation: drag down and release
await animateInGesture.moveBy(const Offset(0.0, 10.0)); await animateInGesture.moveBy(const Offset(0.0, 10.0));
...@@ -1501,7 +1499,7 @@ void main() { ...@@ -1501,7 +1499,7 @@ void main() {
visible: true, visible: true,
); );
// The outer scroll offset should remain unchanged. // The outer scroll offset should remain unchanged.
expect(nestedKey.currentState.outerController.offset, 56.0); expect(nestedKey.currentState!.outerController.offset, 56.0);
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 50)); await tester.pump(const Duration(milliseconds: 50));
...@@ -1514,7 +1512,7 @@ void main() { ...@@ -1514,7 +1512,7 @@ void main() {
extentGreaterThan: true, extentGreaterThan: true,
visible: true, visible: true,
); );
expect(nestedKey.currentState.outerController.offset, 56.0); expect(nestedKey.currentState!.outerController.offset, 56.0);
// The animation finishes when the appbar is full height. // The animation finishes when the appbar is full height.
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -1522,7 +1520,7 @@ void main() { ...@@ -1522,7 +1520,7 @@ void main() {
expect(find.text('Item 1'), findsNothing); expect(find.text('Item 1'), findsNothing);
expect(find.text('Item 5'), findsOneWidget); expect(find.text('Item 5'), findsOneWidget);
verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true); verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);
expect(nestedKey.currentState.outerController.offset, 56.0); expect(nestedKey.currentState!.outerController.offset, 56.0);
// Animate Out // Animate Out
...@@ -1543,7 +1541,7 @@ void main() { ...@@ -1543,7 +1541,7 @@ void main() {
extentLessThan: true, extentLessThan: true,
visible: true, visible: true,
); );
expect(nestedKey.currentState.outerController.offset, 56.0); expect(nestedKey.currentState!.outerController.offset, 56.0);
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 50)); await tester.pump(const Duration(milliseconds: 50));
...@@ -1556,7 +1554,7 @@ void main() { ...@@ -1556,7 +1554,7 @@ void main() {
extentLessThan: true, extentLessThan: true,
visible: true, visible: true,
); );
expect(nestedKey.currentState.outerController.offset, 56.0); expect(nestedKey.currentState!.outerController.offset, 56.0);
// The animation finishes when the appbar is no longer in view. // The animation finishes when the appbar is no longer in view.
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -1564,7 +1562,7 @@ void main() { ...@@ -1564,7 +1562,7 @@ void main() {
expect(find.text('Item 1'), findsNothing); expect(find.text('Item 1'), findsNothing);
expect(find.text('Item 5'), findsOneWidget); expect(find.text('Item 5'), findsOneWidget);
verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false); verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
expect(nestedKey.currentState.outerController.offset, 56.0); expect(nestedKey.currentState!.outerController.offset, 56.0);
}); });
testWidgets('only snap expanded', (WidgetTester tester) async { testWidgets('only snap expanded', (WidgetTester tester) async {
...@@ -1597,7 +1595,7 @@ void main() { ...@@ -1597,7 +1595,7 @@ void main() {
verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false); verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
// The outer scroll view should be at its full extent, here the size of // The outer scroll view should be at its full extent, here the size of
// the app bar. // the app bar.
expect(nestedKey.currentState.outerController.offset, 200.0); expect(nestedKey.currentState!.outerController.offset, 200.0);
// Animate In // Animate In
...@@ -1610,7 +1608,7 @@ void main() { ...@@ -1610,7 +1608,7 @@ void main() {
expect(find.text('Item 1'), findsNothing); expect(find.text('Item 1'), findsNothing);
expect(find.text('Item 5'), findsOneWidget); expect(find.text('Item 5'), findsOneWidget);
verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false); verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
expect(nestedKey.currentState.outerController.offset, 200.0); expect(nestedKey.currentState!.outerController.offset, 200.0);
await animateInGesture.moveBy(const Offset(0.0, -50.0)); // No float out await animateInGesture.moveBy(const Offset(0.0, -50.0)); // No float out
await tester.pump(); await tester.pump();
...@@ -1618,7 +1616,7 @@ void main() { ...@@ -1618,7 +1616,7 @@ void main() {
expect(find.text('Item 1'), findsNothing); expect(find.text('Item 1'), findsNothing);
expect(find.text('Item 5'), findsOneWidget); expect(find.text('Item 5'), findsOneWidget);
verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false); verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
expect(nestedKey.currentState.outerController.offset, 200.0); expect(nestedKey.currentState!.outerController.offset, 200.0);
// Trigger the snap open animation: drag down and release // Trigger the snap open animation: drag down and release
await animateInGesture.moveBy(const Offset(0.0, 10.0)); await animateInGesture.moveBy(const Offset(0.0, 10.0));
...@@ -1637,7 +1635,7 @@ void main() { ...@@ -1637,7 +1635,7 @@ void main() {
visible: true, visible: true,
); );
// The outer scroll offset should remain unchanged. // The outer scroll offset should remain unchanged.
expect(nestedKey.currentState.outerController.offset, 200.0); expect(nestedKey.currentState!.outerController.offset, 200.0);
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 50)); await tester.pump(const Duration(milliseconds: 50));
...@@ -1650,7 +1648,7 @@ void main() { ...@@ -1650,7 +1648,7 @@ void main() {
extentGreaterThan: true, extentGreaterThan: true,
visible: true, visible: true,
); );
expect(nestedKey.currentState.outerController.offset, 200.0); expect(nestedKey.currentState!.outerController.offset, 200.0);
// The animation finishes when the appbar is full height. // The animation finishes when the appbar is full height.
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -1658,7 +1656,7 @@ void main() { ...@@ -1658,7 +1656,7 @@ void main() {
expect(find.text('Item 1'), findsNothing); expect(find.text('Item 1'), findsNothing);
expect(find.text('Item 5'), findsOneWidget); expect(find.text('Item 5'), findsOneWidget);
verifyGeometry(key: appBarKey, paintExtent: 200.0, visible: true); verifyGeometry(key: appBarKey, paintExtent: 200.0, visible: true);
expect(nestedKey.currentState.outerController.offset, 200.0); expect(nestedKey.currentState!.outerController.offset, 200.0);
// Animate Out // Animate Out
...@@ -1679,7 +1677,7 @@ void main() { ...@@ -1679,7 +1677,7 @@ void main() {
extentLessThan: true, extentLessThan: true,
visible: true, visible: true,
); );
expect(nestedKey.currentState.outerController.offset, 200.0); expect(nestedKey.currentState!.outerController.offset, 200.0);
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 50)); await tester.pump(const Duration(milliseconds: 50));
...@@ -1692,7 +1690,7 @@ void main() { ...@@ -1692,7 +1690,7 @@ void main() {
extentLessThan: true, extentLessThan: true,
visible: true, visible: true,
); );
expect(nestedKey.currentState.outerController.offset, 200.0); expect(nestedKey.currentState!.outerController.offset, 200.0);
// The animation finishes when the appbar is no longer in view. // The animation finishes when the appbar is no longer in view.
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -1700,7 +1698,7 @@ void main() { ...@@ -1700,7 +1698,7 @@ void main() {
expect(find.text('Item 1'), findsNothing); expect(find.text('Item 1'), findsNothing);
expect(find.text('Item 5'), findsOneWidget); expect(find.text('Item 5'), findsOneWidget);
verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false); verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
expect(nestedKey.currentState.outerController.offset, 200.0); expect(nestedKey.currentState!.outerController.offset, 200.0);
}); });
testWidgets('float pinned', (WidgetTester tester) async { testWidgets('float pinned', (WidgetTester tester) async {
...@@ -1912,7 +1910,7 @@ void main() { ...@@ -1912,7 +1910,7 @@ void main() {
class TestHeader extends SliverPersistentHeaderDelegate { class TestHeader extends SliverPersistentHeaderDelegate {
const TestHeader({ this.key }); const TestHeader({ this.key });
final Key key; final Key? key;
@override @override
double get minExtent => 100.0; double get minExtent => 100.0;
@override @override
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:ui' as ui show Image; import 'dart:ui' as ui show Image;
...@@ -30,21 +28,20 @@ Future<void> main() async { ...@@ -30,21 +28,20 @@ Future<void> main() async {
), ),
); );
final RenderImage renderImage = tester.renderObject(find.byType(Image)); final RenderImage renderImage = tester.renderObject(find.byType(Image));
final ui.Image image1 = renderImage.image; final ui.Image? image1 = renderImage.image;
await tester.pump(const Duration(milliseconds: 100)); await tester.pump(const Duration(milliseconds: 100));
final ui.Image image2 = renderImage.image; final ui.Image? image2 = renderImage.image;
expect(image1, isNot(same(image2))); expect(image1, isNot(same(image2)));
Navigator.pushNamed(imageKey.currentContext!, '/page');
Navigator.pushNamed(imageKey.currentContext, '/page');
await tester.pump(); // Starts the page animation. await tester.pump(); // Starts the page animation.
await tester.pump(const Duration(seconds: 1)); // Let the page animation complete. await tester.pump(const Duration(seconds: 1)); // Let the page animation complete.
// The image is now obscured by another page, it should not be changing // The image is now obscured by another page, it should not be changing
// frames. // frames.
final ui.Image image3 = renderImage.image; final ui.Image? image3 = renderImage.image;
await tester.pump(const Duration(milliseconds: 100)); await tester.pump(const Duration(milliseconds: 100));
final ui.Image image4 = renderImage.image; final ui.Image? image4 = renderImage.image;
expect(image3, same(image4)); expect(image3, same(image4));
}); });
} }
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
...@@ -191,7 +189,7 @@ void main() { ...@@ -191,7 +189,7 @@ void main() {
final Element element = find.byType(RepaintBoundary).first.evaluate().single; final Element element = find.byType(RepaintBoundary).first.evaluate().single;
// The following line will send the layer to engine and cause crash if an // The following line will send the layer to engine and cause crash if an
// empty opacity layer is sent. // empty opacity layer is sent.
final OffsetLayer offsetLayer = element.renderObject.debugLayer as OffsetLayer; final OffsetLayer offsetLayer = element.renderObject!.debugLayer! as OffsetLayer;
await offsetLayer.toImage(const Rect.fromLTRB(0.0, 0.0, 1.0, 1.0)); await offsetLayer.toImage(const Rect.fromLTRB(0.0, 0.0, 1.0, 1.0));
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/42767 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/42767
} }
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
...@@ -52,7 +50,7 @@ void main() { ...@@ -52,7 +50,7 @@ void main() {
final Key child2Key = UniqueKey(); final Key child2Key = UniqueKey();
final Key child3Key = UniqueKey(); final Key child3Key = UniqueKey();
Widget buildFrame({ double spacing, TextDirection textDirection }) { Widget buildFrame({ required double spacing, required TextDirection textDirection }) {
return Directionality( return Directionality(
textDirection: textDirection, textDirection: textDirection,
child: Align( child: Align(
...@@ -176,7 +174,7 @@ void main() { ...@@ -176,7 +174,7 @@ void main() {
}); });
testWidgets('OverflowBar intrinsic width', (WidgetTester tester) async { testWidgets('OverflowBar intrinsic width', (WidgetTester tester) async {
Widget buildFrame({ double width }) { Widget buildFrame({ required double width }) {
return Directionality( return Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Center( child: Center(
...@@ -207,7 +205,7 @@ void main() { ...@@ -207,7 +205,7 @@ void main() {
}); });
testWidgets('OverflowBar intrinsic height', (WidgetTester tester) async { testWidgets('OverflowBar intrinsic height', (WidgetTester tester) async {
Widget buildFrame({ double maxWidth }) { Widget buildFrame({ required double maxWidth }) {
return Directionality( return Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Center( child: Center(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment