From 64866862f623ceeb45fd8be4782e8db8b58910c0 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Wed, 18 Feb 2026 13:18:20 +0100 Subject: [PATCH] Clean up cross imports in single_child_scroll_view_test.dart, decorated_sliver_test.dart, draggable_scrollable_sheet_test.dart (#181613) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR cleans up cross imports in - single_child_scroll_view_test.dart - decorated_sliver_test.dart - draggable_scrollable_sheet_test.dart Part of [#177415](https://github.com/flutter/flutter/issues/177415) *If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].* ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md --- dev/bots/check_tests_cross_imports.dart | 3 - .../flutter/test/material/scaffold_test.dart | 38 ++++ .../test/widgets/decorated_sliver_test.dart | 201 ++++++++++-------- .../draggable_scrollable_sheet_test.dart | 21 +- .../single_child_scroll_view_test.dart | 73 ++----- 5 files changed, 176 insertions(+), 160 deletions(-) diff --git a/dev/bots/check_tests_cross_imports.dart b/dev/bots/check_tests_cross_imports.dart index 9147cf365fb..38e52ecf20a 100644 --- a/dev/bots/check_tests_cross_imports.dart +++ b/dev/bots/check_tests_cross_imports.dart @@ -122,7 +122,6 @@ class TestsCrossImportChecker { 'packages/flutter/test/widgets/sliver_floating_header_test.dart', 'packages/flutter/test/widgets/page_transitions_test.dart', 'packages/flutter/test/widgets/editable_text_scribble_test.dart', - 'packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart', 'packages/flutter/test/widgets/autofill_group_test.dart', 'packages/flutter/test/widgets/range_maintaining_scroll_physics_test.dart', 'packages/flutter/test/widgets/interactive_viewer_test.dart', @@ -148,7 +147,6 @@ class TestsCrossImportChecker { 'packages/flutter/test/widgets/sliver_semantics_test.dart', 'packages/flutter/test/widgets/sliver_constraints_test.dart', 'packages/flutter/test/widgets/autocomplete_test.dart', - 'packages/flutter/test/widgets/decorated_sliver_test.dart', 'packages/flutter/test/widgets/shadow_test.dart', 'packages/flutter/test/widgets/routes_transition_test.dart', 'packages/flutter/test/widgets/route_notification_messages_test.dart', @@ -211,7 +209,6 @@ class TestsCrossImportChecker { 'packages/flutter/test/widgets/baseline_test.dart', 'packages/flutter/test/widgets/selection_container_test.dart', 'packages/flutter/test/widgets/scrollable_semantics_test.dart', - 'packages/flutter/test/widgets/single_child_scroll_view_test.dart', 'packages/flutter/test/widgets/pinned_header_sliver_test.dart', 'packages/flutter/test/widgets/form_test.dart', }; diff --git a/packages/flutter/test/material/scaffold_test.dart b/packages/flutter/test/material/scaffold_test.dart index 738fbdcfcef..e9ed73ef538 100644 --- a/packages/flutter/test/material/scaffold_test.dart +++ b/packages/flutter/test/material/scaffold_test.dart @@ -53,6 +53,44 @@ void main() { expect(controller.position.pixels, 100.0); }); + testWidgets('keyboardDismissBehavior.OnDrag with drawer tests', (WidgetTester tester) async { + final scaffoldKey = GlobalKey(); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + key: scaffoldKey, + drawer: Container(), + body: Column( + children: [ + const TextField(), + Expanded( + child: SingleChildScrollView( + keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, + child: Container(height: 1000), + ), + ), + ], + ), + ), + ), + ); + + expect(tester.testTextInput.isVisible, isFalse); + final Finder finder = find.byType(TextField).first; + await tester.tap(finder); + expect(tester.testTextInput.isVisible, isTrue); + + await tester.drag(find.byType(SingleChildScrollView).first, const Offset(0.0, -40.0)); + await tester.pumpAndSettle(); + + expect(tester.testTextInput.isVisible, isFalse); + scaffoldKey.currentState!.openDrawer(); + await tester.pumpAndSettle(); + + expect(tester.testTextInput.isVisible, isFalse); + }); + testWidgets('Scaffold drawer callback test', (WidgetTester tester) async { var isDrawerOpen = false; var isEndDrawerOpen = false; diff --git a/packages/flutter/test/widgets/decorated_sliver_test.dart b/packages/flutter/test/widgets/decorated_sliver_test.dart index 27791ee2edf..1d1e1953e0c 100644 --- a/packages/flutter/test/widgets/decorated_sliver_test.dart +++ b/packages/flutter/test/widgets/decorated_sliver_test.dart @@ -7,25 +7,26 @@ @Tags(['reduced-test-set']) library; -import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'widgets_app_tester.dart'; + void main() { testWidgets('DecoratedSliver creates, paints, and disposes BoxPainter', ( WidgetTester tester, ) async { final decoration = TestDecoration(); await tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: CustomScrollView( - slivers: [ - DecoratedSliver( - decoration: decoration, - sliver: const SliverToBoxAdapter(child: SizedBox(width: 100, height: 100)), - ), - ], - ), + TestWidgetsApp( + home: CustomScrollView( + slivers: [ + DecoratedSliver( + decoration: decoration, + sliver: const SliverToBoxAdapter(child: SizedBox(width: 100, height: 100)), + ), + ], ), ), ); @@ -48,21 +49,19 @@ void main() { Decoration activateDecoration = decorationA; late StateSetter localSetState; await tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - localSetState = setState; - return CustomScrollView( - slivers: [ - DecoratedSliver( - decoration: activateDecoration, - sliver: const SliverToBoxAdapter(child: SizedBox(width: 100, height: 100)), - ), - ], - ); - }, - ), + TestWidgetsApp( + home: StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + localSetState = setState; + return CustomScrollView( + slivers: [ + DecoratedSliver( + decoration: activateDecoration, + sliver: const SliverToBoxAdapter(child: SizedBox(width: 100, height: 100)), + ), + ], + ); + }, ), ), ); @@ -87,22 +86,20 @@ void main() { DecorationPosition activePosition = DecorationPosition.foreground; late StateSetter localSetState; await tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - localSetState = setState; - return CustomScrollView( - slivers: [ - DecoratedSliver( - decoration: decoration, - position: activePosition, - sliver: const SliverToBoxAdapter(child: SizedBox(width: 100, height: 100)), - ), - ], - ); - }, - ), + TestWidgetsApp( + home: StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + localSetState = setState; + return CustomScrollView( + slivers: [ + DecoratedSliver( + decoration: decoration, + position: activePosition, + sliver: const SliverToBoxAdapter(child: SizedBox(width: 100, height: 100)), + ), + ], + ); + }, ), ), ); @@ -120,31 +117,31 @@ void main() { }); testWidgets('DecoratedSliver golden test', (WidgetTester tester) async { - const decoration = BoxDecoration(color: Colors.blue); + const decoration = BoxDecoration(color: Color(0xFF2196F3)); + const redColor = Color(0xFFF44336); + const yellowColor = Color(0xFFFFEB3B); final Key backgroundKey = UniqueKey(); await tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: RepaintBoundary( - key: backgroundKey, - child: CustomScrollView( - slivers: [ - DecoratedSliver( - decoration: decoration, - sliver: SliverPadding( - padding: const EdgeInsets.all(16), - sliver: SliverList( - delegate: SliverChildListDelegate.fixed([ - Container(height: 100, color: Colors.red), - Container(height: 100, color: Colors.yellow), - Container(height: 100, color: Colors.red), - ]), - ), + TestWidgetsApp( + home: RepaintBoundary( + key: backgroundKey, + child: CustomScrollView( + slivers: [ + DecoratedSliver( + decoration: decoration, + sliver: SliverPadding( + padding: const EdgeInsets.all(16), + sliver: SliverList( + delegate: SliverChildListDelegate.fixed([ + Container(height: 100, color: redColor), + Container(height: 100, color: yellowColor), + Container(height: 100, color: redColor), + ]), ), ), - ], - ), + ), + ], ), ), ), @@ -157,28 +154,26 @@ void main() { final Key foregroundKey = UniqueKey(); await tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: RepaintBoundary( - key: foregroundKey, - child: CustomScrollView( - slivers: [ - DecoratedSliver( - decoration: decoration, - position: DecorationPosition.foreground, - sliver: SliverPadding( - padding: const EdgeInsets.all(16), - sliver: SliverList( - delegate: SliverChildListDelegate.fixed([ - Container(height: 100, color: Colors.red), - Container(height: 100, color: Colors.yellow), - Container(height: 100, color: Colors.red), - ]), - ), + TestWidgetsApp( + home: RepaintBoundary( + key: foregroundKey, + child: CustomScrollView( + slivers: [ + DecoratedSliver( + decoration: decoration, + position: DecorationPosition.foreground, + sliver: SliverPadding( + padding: const EdgeInsets.all(16), + sliver: SliverList( + delegate: SliverChildListDelegate.fixed([ + Container(height: 100, color: redColor), + Container(height: 100, color: yellowColor), + Container(height: 100, color: redColor), + ]), ), ), - ], - ), + ), + ], ), ), ), @@ -568,7 +563,7 @@ void main() { const key = Key('DecoratedSliver with border'); await tester.pumpWidget( - MaterialApp( + TestWidgetsApp( home: Align( alignment: Alignment.topLeft, child: SizedBox( @@ -579,11 +574,14 @@ void main() { slivers: [ DecoratedSliver( key: key, - decoration: BoxDecoration(border: Border.all()), - sliver: const SliverAppBar( + decoration: BoxDecoration( + border: Border.all(strokeAlign: BorderSide.strokeAlignCenter), + ), + sliver: SliverPersistentHeader( pinned: true, - stretch: true, - title: SizedBox(height: 50, width: 300), + delegate: TestDelegate( + stretchConfiguration: OverScrollHeaderStretchConfiguration(), + ), ), ), const SliverToBoxAdapter(child: SizedBox(height: 1000)), @@ -600,11 +598,13 @@ void main() { expect( find.byKey(key), paints..something((methodName, arguments) { - if (methodName != #drawRRect) { + if (methodName != #drawRect) { return false; } - final Rect rect = (arguments[0] as RRect).outerRect; - expect(rect, rectMoreOrLessEquals(const Rect.fromLTRB(0, 0, 300, 81.08), epsilon: 0.01)); + final rect = arguments[0] as Rect; + + // 225.1 is the result of maxExtent (200) + the physics-diminished drag (the 45 pixels from the gesture) + expect(rect, rectMoreOrLessEquals(const Rect.fromLTRB(0, 0, 300, 225.1), epsilon: 0.03)); return true; }), ); @@ -642,3 +642,24 @@ class TestBoxPainter extends BoxPainter { super.dispose(); } } + +class TestDelegate extends SliverPersistentHeaderDelegate { + TestDelegate({this.stretchConfiguration}); + + @override + double get maxExtent => 200.0; + + @override + double get minExtent => 0; + + @override + Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { + return SizedBox(height: maxExtent, width: 300); + } + + @override + bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) => false; + + @override + final OverScrollHeaderStretchConfiguration? stretchConfiguration; +} diff --git a/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart b/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart index e62a167eebc..7d895005fe7 100644 --- a/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart +++ b/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart @@ -3,13 +3,12 @@ // found in the LICENSE file. import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'utils.dart'; - -// TODO(navaronbracke): Remove MaterialApp and material import +import 'widgets_app_tester.dart'; void main() { Widget boilerplateWidget( @@ -796,7 +795,7 @@ void main() { (WidgetTester tester) async { var s = 0; await tester.pumpWidget( - MaterialApp( + TestWidgetsApp( home: StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return DraggableScrollableSheet( @@ -1628,7 +1627,7 @@ void main() { final controller = DraggableScrollableController(); addTearDown(controller.dispose); Widget buildFrame(ScrollPhysics? physics) { - return MaterialApp( + return TestWidgetsApp( home: DraggableScrollableSheet( controller: controller, initialChildSize: 0.25, @@ -1671,7 +1670,7 @@ void main() { // Regression test for https://github.com/flutter/flutter/issues/67219 var buildCount = 0; await tester.pumpWidget( - MaterialApp( + TestWidgetsApp( home: StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return DraggableScrollableSheet( @@ -1719,7 +1718,7 @@ void main() { var controller = controller1; await tester.pumpWidget( - MaterialApp( + TestWidgetsApp( home: StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return DraggableScrollableSheet( @@ -1779,7 +1778,7 @@ void main() { var controller = controller1; await tester.pumpWidget( - MaterialApp( + TestWidgetsApp( home: StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return DraggableScrollableSheet( @@ -1916,7 +1915,7 @@ void main() { children.insert(0, Container(color: const Color(0xFF00FF00), height: 100)); await tester.pumpWidget( - MaterialApp( + TestWidgetsApp( home: StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return DraggableScrollableSheet( @@ -1961,13 +1960,13 @@ void main() { await tester.fling(find.text('Item 0'), Offset(0, -itemHeight), 100); await tester.pumpFrames( - tester.widget(find.byType(MaterialApp)), + tester.widget(find.byType(TestWidgetsApp)), const Duration(milliseconds: 500), ); await tester.fling(find.text('Item 2'), Offset(0, itemHeight), 500); await tester.pumpFrames( - tester.widget(find.byType(MaterialApp)), + tester.widget(find.byType(TestWidgetsApp)), const Duration(milliseconds: 500), ); diff --git a/packages/flutter/test/widgets/single_child_scroll_view_test.dart b/packages/flutter/test/widgets/single_child_scroll_view_test.dart index 6db8666054b..0d92eca7c81 100644 --- a/packages/flutter/test/widgets/single_child_scroll_view_test.dart +++ b/packages/flutter/test/widgets/single_child_scroll_view_test.dart @@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import '../rendering/rendering_tester.dart' show TestClipPaintingContext; import 'editable_text_utils.dart' show TestTextField; import 'semantics_tester.dart'; +import 'widgets_app_tester.dart'; class TestScrollPosition extends ScrollPositionWithSingleContext { TestScrollPosition({ @@ -1048,16 +1049,14 @@ void main() { Future boilerplate(ScrollViewKeyboardDismissBehavior behavior) { return tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: SingleChildScrollView( - padding: EdgeInsets.zero, - keyboardDismissBehavior: behavior, - child: Column( - children: focusNodes.map((FocusNode focusNode) { - return SizedBox(height: 50, child: TestTextField(focusNode: focusNode)); - }).toList(), - ), + TestWidgetsApp( + home: SingleChildScrollView( + padding: EdgeInsets.zero, + keyboardDismissBehavior: behavior, + child: Column( + children: focusNodes.map((FocusNode focusNode) { + return SizedBox(height: 50, child: TestTextField(focusNode: focusNode)); + }).toList(), ), ), ), @@ -1067,63 +1066,25 @@ void main() { // ScrollViewKeyboardDismissBehavior.onDrag dismiss keyboard on drag await boilerplate(ScrollViewKeyboardDismissBehavior.onDrag); - Finder finder = find.byType(TestTextField).first; - TestTextField textField = tester.widget(finder); + Finder finder = find.byType(EditableText).first; + EditableText textField = tester.widget(finder); await tester.showKeyboard(finder); - expect(textField.focusNode!.hasFocus, isTrue); + expect(textField.focusNode.hasFocus, isTrue); await tester.drag(finder, const Offset(0.0, -40.0)); await tester.pumpAndSettle(); - expect(textField.focusNode!.hasFocus, isFalse); + expect(textField.focusNode.hasFocus, isFalse); // ScrollViewKeyboardDismissBehavior.manual does no dismiss the keyboard await boilerplate(ScrollViewKeyboardDismissBehavior.manual); - finder = find.byType(TestTextField).first; + finder = find.byType(EditableText).first; textField = tester.widget(finder); await tester.showKeyboard(finder); - expect(textField.focusNode!.hasFocus, isTrue); + expect(textField.focusNode.hasFocus, isTrue); await tester.drag(finder, const Offset(0.0, -40.0)); await tester.pumpAndSettle(); - expect(textField.focusNode!.hasFocus, isTrue); - }); - - testWidgets('keyboardDismissBehavior.OnDrag with drawer tests', (WidgetTester tester) async { - final scaffoldKey = GlobalKey(); - - await tester.pumpWidget( - MaterialApp( - home: Scaffold( - key: scaffoldKey, - drawer: Container(), - body: Column( - children: [ - const TestTextField(), - Expanded( - child: SingleChildScrollView( - keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, - child: Container(height: 1000), - ), - ), - ], - ), - ), - ), - ); - - expect(tester.testTextInput.isVisible, isFalse); - final Finder finder = find.byType(TestTextField).first; - await tester.tap(finder); - expect(tester.testTextInput.isVisible, isTrue); - - await tester.drag(find.byType(SingleChildScrollView).first, const Offset(0.0, -40.0)); - await tester.pumpAndSettle(); - - expect(tester.testTextInput.isVisible, isFalse); - scaffoldKey.currentState!.openDrawer(); - await tester.pumpAndSettle(); - - expect(tester.testTextInput.isVisible, isFalse); + expect(textField.focusNode.hasFocus, isTrue); }); }