Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
0343555a
Unverified
Commit
0343555a
authored
Oct 13, 2020
by
Michael Goderbauer
Committed by
GitHub
Oct 13, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate more tests (#68037)
* Migrate more tests * fix
parent
dbf8cd4b
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
558 additions
and
582 deletions
+558
-582
mouse_region_test.dart
packages/flutter/test/widgets/mouse_region_test.dart
+85
-87
multichild_test.dart
packages/flutter/test/widgets/multichild_test.dart
+14
-19
multichildobject_with_keys_test.dart
...flutter/test/widgets/multichildobject_with_keys_test.dart
+1
-3
navigator_and_layers_test.dart
packages/flutter/test/widgets/navigator_and_layers_test.dart
+1
-3
navigator_replacement_test.dart
...ages/flutter/test/widgets/navigator_replacement_test.dart
+4
-6
navigator_restoration_test.dart
...ages/flutter/test/widgets/navigator_restoration_test.dart
+53
-51
navigator_test.dart
packages/flutter/test/widgets/navigator_test.dart
+253
-255
nested_scroll_view_test.dart
packages/flutter/test/widgets/nested_scroll_view_test.dart
+138
-140
notification_test.dart
packages/flutter/test/widgets/notification_test.dart
+0
-2
obscured_animated_image_test.dart
...es/flutter/test/widgets/obscured_animated_image_test.dart
+5
-8
opacity_test.dart
packages/flutter/test/widgets/opacity_test.dart
+1
-3
overflow_bar_test.dart
packages/flutter/test/widgets/overflow_bar_test.dart
+3
-5
No files found.
packages/flutter/test/widgets/mouse_region_test.dart
View file @
0343555a
...
...
@@ -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
;
...
...
packages/flutter/test/widgets/multichild_test.dart
View file @
0343555a
...
...
@@ -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
);
});
}
packages/flutter/test/widgets/multichildobject_with_keys_test.dart
View file @
0343555a
...
...
@@ -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
;
}
packages/flutter/test/widgets/navigator_and_layers_test.dart
View file @
0343555a
...
...
@@ -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
;
...
...
packages/flutter/test/widgets/navigator_replacement_test.dart
View file @
0343555a
...
...
@@ -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}
'
);
};
...
...
packages/flutter/test/widgets/navigator_restoration_test.dart
View file @
0343555a
...
...
@@ -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
>
{}
packages/flutter/test/widgets/navigator_test.dart
View file @
0343555a
...
...
@@ -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
;
...
...
packages/flutter/test/widgets/nested_scroll_view_test.dart
View file @
0343555a
...
...
@@ -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
...
...
packages/flutter/test/widgets/notification_test.dart
View file @
0343555a
...
...
@@ -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'
;
...
...
packages/flutter/test/widgets/obscured_animated_image_test.dart
View file @
0343555a
...
...
@@ -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
));
});
}
packages/flutter/test/widgets/opacity_test.dart
View file @
0343555a
...
...
@@ -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
}
packages/flutter/test/widgets/overflow_bar_test.dart
View file @
0343555a
...
...
@@ -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
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment