-
Notifications
You must be signed in to change notification settings - Fork 27.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix janks and memory leaks in CupertinoPageTransition
and CupertinoFullscreenDialogTransition
[prod-leak-fix]
#146999
Changes from 3 commits
939d8db
a2758a1
72a5113
8f3c106
67f3775
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -12,7 +12,6 @@ import 'package:flutter/foundation.dart'; | |||||||||||||||||||||||||||||||||||
import 'package:flutter/material.dart'; | ||||||||||||||||||||||||||||||||||||
import 'package:flutter/rendering.dart'; | ||||||||||||||||||||||||||||||||||||
import 'package:flutter_test/flutter_test.dart'; | ||||||||||||||||||||||||||||||||||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
import '../widgets/semantics_tester.dart'; | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
@@ -712,11 +711,27 @@ void main() { | |||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(7.4, epsilon: 0.1)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 50)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(3, epsilon: 0.1)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 50)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(0, epsilon: 0.1)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Give time to the animation to finish and update its status to | ||||||||||||||||||||||||||||||||||||
// AnimationState.completed, so the reverse curved can be used in the next | ||||||||||||||||||||||||||||||||||||
// step. | ||||||||||||||||||||||||||||||||||||
await tester.pumpAndSettle(const Duration(milliseconds: 1)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Exit animation | ||||||||||||||||||||||||||||||||||||
await tester.tap(find.text('Close')); | ||||||||||||||||||||||||||||||||||||
await tester.pump(); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 50)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(156.3, epsilon: 0.1)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 50)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(308.1, epsilon: 0.1)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(411.03, epsilon: 0.1)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
@@ -818,10 +833,27 @@ void main() { | |||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-263.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 50)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-265.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 50)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-266.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Give time to the animation to finish and update its status to | ||||||||||||||||||||||||||||||||||||
// AnimationState.completed, so the reverse curved can be used in the next | ||||||||||||||||||||||||||||||||||||
// step. | ||||||||||||||||||||||||||||||||||||
await tester.pumpAndSettle(const Duration(milliseconds: 1)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Exit animation | ||||||||||||||||||||||||||||||||||||
await tester.tap(find.text('Close')); | ||||||||||||||||||||||||||||||||||||
await tester.pump(); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 50)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-197.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change from -83 to -197 looks alerting to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, I was trying to "fix" those changes in the tests. However, with my changes the behavior changes and I will have to update those values. Before, a new As a reminder, here are some useful values: Curves.easeInToLinear.transform(0.72); // 0.3149519026279449
- (800 / 3) * Curves.easeInToLinear.transform(0.72); // -83.98717403411865
Curves.linearToEaseOut.transform(0.72); // 0.979008914809674
- (800 / 3) * Curves.linearToEaseOut.transform(0.72); // -261.0690439492464 And the secondary animation is _secondPositionCurvedAnimation = CurvedAnimation(
parent: widget.secondaryRouteAnimation,
curve: Curves.linearToEaseOut,
reverseCurve: Curves.easeInToLinear,
); Before, the test was animating the push of the page from 0ms to 400ms (the entire duration of the push animation is 500ms) and then popping. So the push animation was not completed when being reversed. During the forward animation, the curve used is But this shouldn't happen, if the animation is not complete, it should use its forward curve during the reverse animation. I guess this is to prevent jumps and janks. This is what those lines are doing: flutter/packages/flutter/lib/src/animation/animations.dart Lines 427 to 432 in 89a4ffa
flutter/packages/flutter/lib/src/animation/animations.dart Lines 434 to 436 in 89a4ffa
flutter/packages/flutter/lib/src/animation/animations.dart Lines 450 to 457 in 89a4ffa
Now that the For the test, I decided the modify it so the push animation finishes and the pop uses the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than changing an existing test, can you add a new one? This feel like a potential regression. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 on leaving this test alone as much as possible. It does look like logically the animation wouldn't finish by the time the original test tries to go back, so the jump makes sense. I'd rather the test was left as it was to check for regression, even with the jump, and probably renamed. A new test that correctly waits for the animation to finish, then goes back would be preferable. Does the original test still fail, and how? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those were the minimum changes I found to "let this test alone as much as possible". What was happening in this test:
After my changes without any modification on the test:
await tester.pump(const Duration(milliseconds: 40));
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-83.0, epsilon: 1.0)); Expected: -83 (Comment for reference: https://github.com/flutter/flutter/pull/146999/files#r1575569345) To make this test pass, I have 2 options: a. I let the push being interrupted and I need to change the expected values to match the use of the forward curve instead of the reverse curved. I have implemented both options. The one linked to the comment is Is that what you are expecting? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @MitchellGoodwin , does this help? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the explanation. That all makes sense and the two tests LGTM. Thank you for adjusting the old on and adding a new one. |
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 50)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-129.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-83.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
@@ -837,6 +869,125 @@ void main() { | |||||||||||||||||||||||||||||||||||
await testParallax(tester, fromFullscreenDialog: true); | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
group('Interrupted push', () { | ||||||||||||||||||||||||||||||||||||
Future<void> testParallax(WidgetTester tester, {required bool fromFullscreenDialog}) async { | ||||||||||||||||||||||||||||||||||||
await tester.pumpWidget( | ||||||||||||||||||||||||||||||||||||
CupertinoApp( | ||||||||||||||||||||||||||||||||||||
onGenerateRoute: (RouteSettings settings) => CupertinoPageRoute<void>( | ||||||||||||||||||||||||||||||||||||
fullscreenDialog: fromFullscreenDialog, | ||||||||||||||||||||||||||||||||||||
settings: settings, | ||||||||||||||||||||||||||||||||||||
builder: (BuildContext context) { | ||||||||||||||||||||||||||||||||||||
return Column( | ||||||||||||||||||||||||||||||||||||
children: <Widget>[ | ||||||||||||||||||||||||||||||||||||
const Placeholder(), | ||||||||||||||||||||||||||||||||||||
CupertinoButton( | ||||||||||||||||||||||||||||||||||||
child: const Text('Button'), | ||||||||||||||||||||||||||||||||||||
onPressed: () { | ||||||||||||||||||||||||||||||||||||
Navigator.push<void>(context, CupertinoPageRoute<void>( | ||||||||||||||||||||||||||||||||||||
builder: (BuildContext context) { | ||||||||||||||||||||||||||||||||||||
return CupertinoButton( | ||||||||||||||||||||||||||||||||||||
child: const Text('Close'), | ||||||||||||||||||||||||||||||||||||
onPressed: () { | ||||||||||||||||||||||||||||||||||||
Navigator.pop<void>(context); | ||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||
)); | ||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||
], | ||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Enter animation. | ||||||||||||||||||||||||||||||||||||
await tester.tap(find.text('Button')); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(0.0, epsilon: 0.1)); | ||||||||||||||||||||||||||||||||||||
await tester.pump(); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// The push animation duration is 500ms. We let it run for 400ms before | ||||||||||||||||||||||||||||||||||||
// interrupting and popping it. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-55.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-111.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-161.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-200.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-226.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-242.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-251.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-257.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-261.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-263.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Exit animation | ||||||||||||||||||||||||||||||||||||
await tester.tap(find.text('Close')); | ||||||||||||||||||||||||||||||||||||
await tester.pump(); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// When the push animation is interrupted, the forward curved is used for | ||||||||||||||||||||||||||||||||||||
// the reversed animation to avoid discontinuities. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-261.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-257.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-251.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-242.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-226.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-200.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-161.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-111.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-55.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 40)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(0.0, epsilon: 1.0)); | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
testWidgets('CupertinoPageRoute has parallax when non fullscreenDialog route is pushed on top and gets popped before the end of the animation', (WidgetTester tester) async { | ||||||||||||||||||||||||||||||||||||
await testParallax(tester, fromFullscreenDialog: false); | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
testWidgets('FullscreenDialog CupertinoPageRoute has parallax when non fullscreenDialog route is pushed on top and gets popped before the end of the animation', (WidgetTester tester) async { | ||||||||||||||||||||||||||||||||||||
await testParallax(tester, fromFullscreenDialog: true); | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
Future<void> testNoParallax(WidgetTester tester, {required bool fromFullscreenDialog}) async{ | ||||||||||||||||||||||||||||||||||||
await tester.pumpWidget( | ||||||||||||||||||||||||||||||||||||
CupertinoApp( | ||||||||||||||||||||||||||||||||||||
|
@@ -944,6 +1095,11 @@ void main() { | |||||||||||||||||||||||||||||||||||
tester.state<NavigatorState>(find.byType(Navigator)).push(route2); | ||||||||||||||||||||||||||||||||||||
// The whole transition is 500ms based on CupertinoPageRoute.transitionDuration. | ||||||||||||||||||||||||||||||||||||
// Break it up into small chunks. | ||||||||||||||||||||||||||||||||||||
// | ||||||||||||||||||||||||||||||||||||
// The screen width is 800. | ||||||||||||||||||||||||||||||||||||
// The top left corner of the text 1 will go from 0 to -800 / 3 = - 266.67. | ||||||||||||||||||||||||||||||||||||
// The top left corner of the text 2 will go from 800 to 0. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(); | ||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 50)); | ||||||||||||||||||||||||||||||||||||
|
@@ -961,8 +1117,14 @@ void main() { | |||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Finish the rest of the animation | ||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 350)); | ||||||||||||||||||||||||||||||||||||
// Give time to the animation to finish and update its status to | ||||||||||||||||||||||||||||||||||||
// AnimationState.completed, so the reverse curved can be used in the next | ||||||||||||||||||||||||||||||||||||
// step. | ||||||||||||||||||||||||||||||||||||
await tester.pumpAndSettle(const Duration(milliseconds: 1)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
tester.state<NavigatorState>(find.byType(Navigator)).pop(); | ||||||||||||||||||||||||||||||||||||
// The top left corner of the text 1 will go from -800 / 3 = - 266.67 to 0. | ||||||||||||||||||||||||||||||||||||
// The top left corner of the text 2 will go from 0 to 800. | ||||||||||||||||||||||||||||||||||||
await tester.pump(); | ||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 50)); | ||||||||||||||||||||||||||||||||||||
expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-197, epsilon: 1)); | ||||||||||||||||||||||||||||||||||||
|
@@ -2432,53 +2594,6 @@ void main() { | |||||||||||||||||||||||||||||||||||
expect(tester.getBottomRight(find.byType(Placeholder)).dx, 390.0); | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
testWidgets( | ||||||||||||||||||||||||||||||||||||
// TODO(polina-c): remove when fixed https://github.com/flutter/flutter/issues/145600 [leak-tracking-opt-in] | ||||||||||||||||||||||||||||||||||||
experimentalLeakTesting: LeakTesting.settings.withTracked(classes: <String>['CurvedAnimation']), | ||||||||||||||||||||||||||||||||||||
'Fullscreen route does not leak CurveAnimation', (WidgetTester tester) async { | ||||||||||||||||||||||||||||||||||||
polina-c marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||
await tester.pumpWidget( | ||||||||||||||||||||||||||||||||||||
MaterialApp( | ||||||||||||||||||||||||||||||||||||
home: Builder( | ||||||||||||||||||||||||||||||||||||
builder: (BuildContext context) { | ||||||||||||||||||||||||||||||||||||
return CupertinoButton( | ||||||||||||||||||||||||||||||||||||
child: const Text('Button'), | ||||||||||||||||||||||||||||||||||||
onPressed: () { | ||||||||||||||||||||||||||||||||||||
Navigator.push<void>(context, CupertinoPageRoute<void>( | ||||||||||||||||||||||||||||||||||||
fullscreenDialog: true, | ||||||||||||||||||||||||||||||||||||
builder: (BuildContext context) { | ||||||||||||||||||||||||||||||||||||
return Column( | ||||||||||||||||||||||||||||||||||||
children: <Widget>[ | ||||||||||||||||||||||||||||||||||||
const Placeholder(), | ||||||||||||||||||||||||||||||||||||
CupertinoButton( | ||||||||||||||||||||||||||||||||||||
child: const Text('Close'), | ||||||||||||||||||||||||||||||||||||
onPressed: () { | ||||||||||||||||||||||||||||||||||||
Navigator.pop<void>(context); | ||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||
], | ||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||
)); | ||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Enter animation. | ||||||||||||||||||||||||||||||||||||
await tester.tap(find.text('Button')); | ||||||||||||||||||||||||||||||||||||
await tester.pump(); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 400)); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Exit animation | ||||||||||||||||||||||||||||||||||||
await tester.tap(find.text('Close')); | ||||||||||||||||||||||||||||||||||||
await tester.pump(); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
await tester.pump(const Duration(milliseconds: 400)); | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
class MockNavigatorObserver extends NavigatorObserver { | ||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this related to the memory leak? If not, maybe this should be a separate change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well now this PR is not about memory leaks anymore since #147133 got merged in between. Maybe I should rename this PR. Would "Fix jank in cupertino page transition" sounds nice to you ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds like a great idea. Can you update the PR description to what issue this is fixing now as well? Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the title and the description of the PR. Tell me if something is unclear