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