SearchAnchor should dispose created FocusNode and SearchController. (#136120)
This commit is contained in:
parent
e0b8ec0782
commit
7d79472531
@ -310,15 +310,12 @@ class _SearchAnchorState extends State<SearchAnchor> {
|
|||||||
bool _anchorIsVisible = true;
|
bool _anchorIsVisible = true;
|
||||||
final GlobalKey _anchorKey = GlobalKey();
|
final GlobalKey _anchorKey = GlobalKey();
|
||||||
bool get _viewIsOpen => !_anchorIsVisible;
|
bool get _viewIsOpen => !_anchorIsVisible;
|
||||||
late SearchController? _internalSearchController;
|
SearchController? _internalSearchController;
|
||||||
SearchController get _searchController => widget.searchController ?? _internalSearchController!;
|
SearchController get _searchController => widget.searchController ?? (_internalSearchController ??= SearchController());
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
if (widget.searchController == null) {
|
|
||||||
_internalSearchController = SearchController();
|
|
||||||
}
|
|
||||||
_searchController._attach(this);
|
_searchController._attach(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,11 +331,21 @@ class _SearchAnchorState extends State<SearchAnchor> {
|
|||||||
_screenSize = updatedScreenSize;
|
_screenSize = updatedScreenSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(SearchAnchor oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
if (oldWidget.searchController != widget.searchController) {
|
||||||
|
oldWidget.searchController?._detach(this);
|
||||||
|
_searchController._attach(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
_searchController._detach(this);
|
widget.searchController?._detach(this);
|
||||||
_internalSearchController = null;
|
_internalSearchController?._detach(this);
|
||||||
|
_internalSearchController?.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _openView() {
|
void _openView() {
|
||||||
@ -680,12 +687,6 @@ class _ViewContentState extends State<_ViewContent> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose(){
|
|
||||||
_controller.removeListener(updateSuggestions);
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(covariant _ViewContent oldWidget) {
|
void didUpdateWidget(covariant _ViewContent oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
@ -710,6 +711,13 @@ class _ViewContentState extends State<_ViewContent> {
|
|||||||
unawaited(updateSuggestions());
|
unawaited(updateSuggestions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.removeListener(updateSuggestions);
|
||||||
|
_focusNode.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
Widget viewBuilder(Iterable<Widget> suggestions) {
|
Widget viewBuilder(Iterable<Widget> suggestions) {
|
||||||
if (widget.viewBuilder == null) {
|
if (widget.viewBuilder == null) {
|
||||||
return MediaQuery.removePadding(
|
return MediaQuery.removePadding(
|
||||||
@ -949,15 +957,18 @@ class SearchController extends TextEditingController {
|
|||||||
// it controls.
|
// it controls.
|
||||||
_SearchAnchorState? _anchor;
|
_SearchAnchorState? _anchor;
|
||||||
|
|
||||||
|
/// Whether this controller has associated search anchor.
|
||||||
|
bool get isAttached => _anchor != null;
|
||||||
|
|
||||||
/// Whether or not the associated search view is currently open.
|
/// Whether or not the associated search view is currently open.
|
||||||
bool get isOpen {
|
bool get isOpen {
|
||||||
assert(_anchor != null);
|
assert(isAttached);
|
||||||
return _anchor!._viewIsOpen;
|
return _anchor!._viewIsOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opens the search view that this controller is associated with.
|
/// Opens the search view that this controller is associated with.
|
||||||
void openView() {
|
void openView() {
|
||||||
assert(_anchor != null);
|
assert(isAttached);
|
||||||
_anchor!._openView();
|
_anchor!._openView();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -966,7 +977,7 @@ class SearchController extends TextEditingController {
|
|||||||
/// If `selectedText` is given, then the text value of the controller is set to
|
/// If `selectedText` is given, then the text value of the controller is set to
|
||||||
/// `selectedText`.
|
/// `selectedText`.
|
||||||
void closeView(String? selectedText) {
|
void closeView(String? selectedText) {
|
||||||
assert(_anchor != null);
|
assert(isAttached);
|
||||||
_anchor!._closeView(selectedText);
|
_anchor!._closeView(selectedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1166,7 +1177,8 @@ class SearchBar extends StatefulWidget {
|
|||||||
|
|
||||||
class _SearchBarState extends State<SearchBar> {
|
class _SearchBarState extends State<SearchBar> {
|
||||||
late final MaterialStatesController _internalStatesController;
|
late final MaterialStatesController _internalStatesController;
|
||||||
late final FocusNode _focusNode;
|
FocusNode? _internalFocusNode;
|
||||||
|
FocusNode get _focusNode => widget.focusNode ?? (_internalFocusNode ??= FocusNode());
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -1175,15 +1187,12 @@ class _SearchBarState extends State<SearchBar> {
|
|||||||
_internalStatesController.addListener(() {
|
_internalStatesController.addListener(() {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
});
|
});
|
||||||
_focusNode = widget.focusNode ?? FocusNode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_internalStatesController.dispose();
|
_internalStatesController.dispose();
|
||||||
if (widget.focusNode == null) {
|
_internalFocusNode?.dispose();
|
||||||
_focusNode.dispose();
|
|
||||||
}
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +33,10 @@ void main() {
|
|||||||
checkSearchBarDefaults(tester, colorScheme, material);
|
checkSearchBarDefaults(tester, colorScheme, material);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects controller property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects controller property', (WidgetTester tester) async {
|
||||||
const String defaultText = 'default text';
|
const String defaultText = 'default text';
|
||||||
final TextEditingController controller = TextEditingController(text: defaultText);
|
final TextEditingController controller = TextEditingController(text: defaultText);
|
||||||
|
addTearDown(controller.dispose);
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
@ -57,8 +58,10 @@ void main() {
|
|||||||
expect(find.text(updatedText), findsOneWidget);
|
expect(find.text(updatedText), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects focusNode property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects focusNode property', (WidgetTester tester) async {
|
||||||
final FocusNode node = FocusNode();
|
final FocusNode node = FocusNode();
|
||||||
|
addTearDown(node.dispose);
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
@ -80,7 +83,74 @@ void main() {
|
|||||||
expect(node.hasFocus, false);
|
expect(node.hasFocus, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar has correct default layout and padding LTR', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar focusNode is hot swappable', (WidgetTester tester) async {
|
||||||
|
final FocusNode node1 = FocusNode();
|
||||||
|
addTearDown(node1.dispose);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Material(
|
||||||
|
child: SearchBar(
|
||||||
|
focusNode: node1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(node1.hasFocus, isFalse);
|
||||||
|
|
||||||
|
node1.requestFocus();
|
||||||
|
await tester.pump();
|
||||||
|
expect(node1.hasFocus, isTrue);
|
||||||
|
|
||||||
|
node1.unfocus();
|
||||||
|
await tester.pump();
|
||||||
|
expect(node1.hasFocus, isFalse);
|
||||||
|
|
||||||
|
final FocusNode node2 = FocusNode();
|
||||||
|
addTearDown(node2.dispose);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Material(
|
||||||
|
child: SearchBar(
|
||||||
|
focusNode: node2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(node1.hasFocus, isFalse);
|
||||||
|
expect(node2.hasFocus, isFalse);
|
||||||
|
|
||||||
|
node2.requestFocus();
|
||||||
|
await tester.pump();
|
||||||
|
expect(node1.hasFocus, isFalse);
|
||||||
|
expect(node2.hasFocus, isTrue);
|
||||||
|
|
||||||
|
node2.unfocus();
|
||||||
|
await tester.pump();
|
||||||
|
expect(node1.hasFocus, isFalse);
|
||||||
|
expect(node2.hasFocus, isFalse);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
const MaterialApp(
|
||||||
|
home: Material(
|
||||||
|
child: SearchBar(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(node1.hasFocus, isFalse);
|
||||||
|
expect(node2.hasFocus, isFalse);
|
||||||
|
|
||||||
|
await tester.tap(find.byType(SearchBar));
|
||||||
|
await tester.pump();
|
||||||
|
expect(node1.hasFocus, isFalse);
|
||||||
|
expect(node2.hasFocus, isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgetsWithLeakTracking('SearchBar has correct default layout and padding LTR', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Center(
|
home: Center(
|
||||||
@ -117,7 +187,7 @@ void main() {
|
|||||||
expect(trailingIcon.right, equals(barRect.right - 8.0));
|
expect(trailingIcon.right, equals(barRect.right - 8.0));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar has correct default layout and padding - RTL', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar has correct default layout and padding - RTL', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Directionality(
|
home: Directionality(
|
||||||
@ -157,7 +227,7 @@ void main() {
|
|||||||
expect(trailingIcon.left, equals(barRect.left + 8.0));
|
expect(trailingIcon.left, equals(barRect.left + 8.0));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects hintText property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects hintText property', (WidgetTester tester) async {
|
||||||
const String hintText = 'hint text';
|
const String hintText = 'hint text';
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
const MaterialApp(
|
const MaterialApp(
|
||||||
@ -172,7 +242,7 @@ void main() {
|
|||||||
expect(find.text(hintText), findsOneWidget);
|
expect(find.text(hintText), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects leading property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects leading property', (WidgetTester tester) async {
|
||||||
final ThemeData theme = ThemeData();
|
final ThemeData theme = ThemeData();
|
||||||
final ColorScheme colorScheme = theme.colorScheme;
|
final ColorScheme colorScheme = theme.colorScheme;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
@ -193,7 +263,7 @@ void main() {
|
|||||||
expect(iconColor, colorScheme.onSurface); // Default icon color.
|
expect(iconColor, colorScheme.onSurface); // Default icon color.
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects trailing property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects trailing property', (WidgetTester tester) async {
|
||||||
final ThemeData theme = ThemeData();
|
final ThemeData theme = ThemeData();
|
||||||
final ColorScheme colorScheme = theme.colorScheme;
|
final ColorScheme colorScheme = theme.colorScheme;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
@ -216,7 +286,7 @@ void main() {
|
|||||||
expect(iconColor, colorScheme.onSurfaceVariant); // Default icon color.
|
expect(iconColor, colorScheme.onSurfaceVariant); // Default icon color.
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects onTap property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects onTap property', (WidgetTester tester) async {
|
||||||
int tapCount = 0;
|
int tapCount = 0;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
@ -242,7 +312,7 @@ void main() {
|
|||||||
expect(tapCount, 2);
|
expect(tapCount, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects onChanged property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects onChanged property', (WidgetTester tester) async {
|
||||||
int changeCount = 0;
|
int changeCount = 0;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
@ -269,7 +339,7 @@ void main() {
|
|||||||
expect(changeCount, 2);
|
expect(changeCount, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects onSubmitted property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects onSubmitted property', (WidgetTester tester) async {
|
||||||
String submittedQuery = '';
|
String submittedQuery = '';
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
@ -289,7 +359,7 @@ void main() {
|
|||||||
expect(submittedQuery, equals('query'));
|
expect(submittedQuery, equals('query'));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects constraints property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects constraints property', (WidgetTester tester) async {
|
||||||
const BoxConstraints constraints = BoxConstraints(maxWidth: 350.0, minHeight: 80);
|
const BoxConstraints constraints = BoxConstraints(maxWidth: 350.0, minHeight: 80);
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
const MaterialApp(
|
const MaterialApp(
|
||||||
@ -307,7 +377,7 @@ void main() {
|
|||||||
expect(barRect.size, const Size(350.0, 80.0));
|
expect(barRect.size, const Size(350.0, 80.0));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects elevation property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects elevation property', (WidgetTester tester) async {
|
||||||
const double pressedElevation = 0.0;
|
const double pressedElevation = 0.0;
|
||||||
const double hoveredElevation = 1.0;
|
const double hoveredElevation = 1.0;
|
||||||
const double focusedElevation = 2.0;
|
const double focusedElevation = 2.0;
|
||||||
@ -363,7 +433,7 @@ void main() {
|
|||||||
expect(material.elevation, focusedElevation);
|
expect(material.elevation, focusedElevation);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects backgroundColor property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects backgroundColor property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Center(
|
home: Center(
|
||||||
@ -403,7 +473,7 @@ void main() {
|
|||||||
expect(material.color, focusedColor);
|
expect(material.color, focusedColor);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects shadowColor property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects shadowColor property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Center(
|
home: Center(
|
||||||
@ -443,7 +513,7 @@ void main() {
|
|||||||
expect(material.shadowColor, focusedColor);
|
expect(material.shadowColor, focusedColor);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects surfaceTintColor property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects surfaceTintColor property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Center(
|
home: Center(
|
||||||
@ -483,8 +553,10 @@ void main() {
|
|||||||
expect(material.surfaceTintColor, focusedColor);
|
expect(material.surfaceTintColor, focusedColor);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects overlayColor property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects overlayColor property', (WidgetTester tester) async {
|
||||||
final FocusNode focusNode = FocusNode();
|
final FocusNode focusNode = FocusNode();
|
||||||
|
addTearDown(focusNode.dispose);
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Center(
|
home: Center(
|
||||||
@ -521,7 +593,7 @@ void main() {
|
|||||||
expect(inkFeatures, paints..rect()..rect(color: focusedColor.withOpacity(1.0)));
|
expect(inkFeatures, paints..rect()..rect(color: focusedColor.withOpacity(1.0)));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects side and shape properties', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects side and shape properties', (WidgetTester tester) async {
|
||||||
const BorderSide pressedSide = BorderSide(width: 2.0);
|
const BorderSide pressedSide = BorderSide(width: 2.0);
|
||||||
const BorderSide hoveredSide = BorderSide(width: 3.0);
|
const BorderSide hoveredSide = BorderSide(width: 3.0);
|
||||||
const BorderSide focusedSide = BorderSide(width: 4.0);
|
const BorderSide focusedSide = BorderSide(width: 4.0);
|
||||||
@ -595,7 +667,7 @@ void main() {
|
|||||||
expect(material.shape, focusedShape.copyWith(side: focusedSide));
|
expect(material.shape, focusedShape.copyWith(side: focusedSide));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects padding property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects padding property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
const MaterialApp(
|
const MaterialApp(
|
||||||
home: Center(
|
home: Center(
|
||||||
@ -623,7 +695,7 @@ void main() {
|
|||||||
expect(trailingRect.right, barRect.right - 16.0);
|
expect(trailingRect.right, barRect.right - 16.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects hintStyle property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects hintStyle property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Center(
|
home: Center(
|
||||||
@ -657,8 +729,10 @@ void main() {
|
|||||||
expect(helperText.style?.color, focusedColor);
|
expect(helperText.style?.color, focusedColor);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects textStyle property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects textStyle property', (WidgetTester tester) async {
|
||||||
final TextEditingController controller = TextEditingController(text: 'input text');
|
final TextEditingController controller = TextEditingController(text: 'input text');
|
||||||
|
addTearDown(controller.dispose);
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Center(
|
home: Center(
|
||||||
@ -692,7 +766,7 @@ void main() {
|
|||||||
expect(inputText.style.color, focusedColor);
|
expect(inputText.style.color, focusedColor);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchBar respects textCapitalization property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchBar respects textCapitalization property', (WidgetTester tester) async {
|
||||||
Widget buildSearchBar(TextCapitalization textCapitalization) {
|
Widget buildSearchBar(TextCapitalization textCapitalization) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
home: Center(
|
home: Center(
|
||||||
@ -725,7 +799,7 @@ void main() {
|
|||||||
expect(textField.textCapitalization, TextCapitalization.none);
|
expect(textField.textCapitalization, TextCapitalization.none);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects textCapitalization property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects textCapitalization property', (WidgetTester tester) async {
|
||||||
Widget buildSearchAnchor(TextCapitalization textCapitalization) {
|
Widget buildSearchAnchor(TextCapitalization textCapitalization) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
home: Center(
|
home: Center(
|
||||||
@ -765,7 +839,7 @@ void main() {
|
|||||||
expect(textField.textCapitalization, TextCapitalization.none);
|
expect(textField.textCapitalization, TextCapitalization.none);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor.bar respects textCapitalization property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor.bar respects textCapitalization property', (WidgetTester tester) async {
|
||||||
Widget buildSearchAnchor(TextCapitalization textCapitalization) {
|
Widget buildSearchAnchor(TextCapitalization textCapitalization) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
home: Center(
|
home: Center(
|
||||||
@ -794,7 +868,7 @@ void main() {
|
|||||||
expect(textField.textCapitalization, TextCapitalization.characters);
|
expect(textField.textCapitalization, TextCapitalization.characters);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('hintStyle can override textStyle for hintText', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('hintStyle can override textStyle for hintText', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Center(
|
home: Center(
|
||||||
@ -830,7 +904,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Regression test for https://github.com/flutter/flutter/issues/127092.
|
// Regression test for https://github.com/flutter/flutter/issues/127092.
|
||||||
testWidgets('The text is still centered when SearchBar text field is smaller than 48', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('The text is still centered when SearchBar text field is smaller than 48', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
theme: ThemeData(useMaterial3: true),
|
theme: ThemeData(useMaterial3: true),
|
||||||
@ -852,7 +926,7 @@ void main() {
|
|||||||
expect(textCenterY, searchBarCenterY);
|
expect(textCenterY, searchBarCenterY);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('The search view defaults', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('The search view defaults', (WidgetTester tester) async {
|
||||||
final ThemeData theme = ThemeData(useMaterial3: true);
|
final ThemeData theme = ThemeData(useMaterial3: true);
|
||||||
final ColorScheme colorScheme = theme.colorScheme;
|
final ColorScheme colorScheme = theme.colorScheme;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
@ -912,7 +986,7 @@ void main() {
|
|||||||
expect(inputText.style.fontWeight, FontWeight.w400);
|
expect(inputText.style.fontWeight, FontWeight.w400);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('The search view default size on different platforms', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('The search view default size on different platforms', (WidgetTester tester) async {
|
||||||
// The search view should be is full-screen on mobile platforms,
|
// The search view should be is full-screen on mobile platforms,
|
||||||
// and have a size of (360, 2/3 screen height) on other platforms
|
// and have a size of (360, 2/3 screen height) on other platforms
|
||||||
Widget buildSearchAnchor(TargetPlatform platform) {
|
Widget buildSearchAnchor(TargetPlatform platform) {
|
||||||
@ -959,7 +1033,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects isFullScreen property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects isFullScreen property', (WidgetTester tester) async {
|
||||||
Widget buildSearchAnchor(TargetPlatform platform) {
|
Widget buildSearchAnchor(TargetPlatform platform) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
theme: ThemeData(platform: platform),
|
theme: ThemeData(platform: platform),
|
||||||
@ -995,9 +1069,10 @@ void main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects controller property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects controller property', (WidgetTester tester) async {
|
||||||
const String defaultText = 'initial text';
|
const String defaultText = 'initial text';
|
||||||
final SearchController controller = SearchController();
|
final SearchController controller = SearchController();
|
||||||
|
addTearDown(controller.dispose);
|
||||||
controller.text = defaultText;
|
controller.text = defaultText;
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
@ -1030,7 +1105,82 @@ void main() {
|
|||||||
expect(find.text(updatedText), findsOneWidget);
|
expect(find.text(updatedText), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects viewBuilder property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor attaches and detaches controllers property', (WidgetTester tester) async {
|
||||||
|
Widget builder(BuildContext context, SearchController controller) {
|
||||||
|
return const Icon(Icons.search);
|
||||||
|
}
|
||||||
|
List<Widget> suggestionsBuilder(BuildContext context, SearchController controller) {
|
||||||
|
return const <Widget>[];
|
||||||
|
}
|
||||||
|
|
||||||
|
final SearchController controller1 = SearchController();
|
||||||
|
addTearDown(controller1.dispose);
|
||||||
|
|
||||||
|
expect(controller1.isAttached, isFalse);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Material(
|
||||||
|
child: SearchAnchor(
|
||||||
|
searchController: controller1,
|
||||||
|
builder: builder,
|
||||||
|
suggestionsBuilder: suggestionsBuilder,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(controller1.isAttached, isTrue);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Material(
|
||||||
|
child: SearchAnchor(
|
||||||
|
builder: builder,
|
||||||
|
suggestionsBuilder: suggestionsBuilder,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(controller1.isAttached, isFalse);
|
||||||
|
|
||||||
|
final SearchController controller2 = SearchController();
|
||||||
|
addTearDown(controller2.dispose);
|
||||||
|
|
||||||
|
expect(controller2.isAttached, isFalse);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Material(
|
||||||
|
child: SearchAnchor(
|
||||||
|
searchController: controller2,
|
||||||
|
builder: builder,
|
||||||
|
suggestionsBuilder: suggestionsBuilder,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(controller1.isAttached, isFalse);
|
||||||
|
expect(controller2.isAttached, isTrue);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Material(
|
||||||
|
child: SearchAnchor(
|
||||||
|
builder: builder,
|
||||||
|
suggestionsBuilder: suggestionsBuilder,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(controller1.isAttached, isFalse);
|
||||||
|
expect(controller2.isAttached, isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgetsWithLeakTracking('SearchAnchor respects viewBuilder property', (WidgetTester tester) async {
|
||||||
Widget buildAnchor({ViewBuilder? viewBuilder}) {
|
Widget buildAnchor({ViewBuilder? viewBuilder}) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
@ -1065,7 +1215,7 @@ void main() {
|
|||||||
expect(find.byType(GridView), findsOneWidget);
|
expect(find.byType(GridView), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects viewLeading property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects viewLeading property', (WidgetTester tester) async {
|
||||||
Widget buildAnchor({Widget? viewLeading}) {
|
Widget buildAnchor({Widget? viewLeading}) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
@ -1098,7 +1248,7 @@ void main() {
|
|||||||
expect(find.byIcon(Icons.history), findsOneWidget);
|
expect(find.byIcon(Icons.history), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects viewTrailing property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects viewTrailing property', (WidgetTester tester) async {
|
||||||
Widget buildAnchor({Iterable<Widget>? viewTrailing}) {
|
Widget buildAnchor({Iterable<Widget>? viewTrailing}) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
@ -1131,7 +1281,7 @@ void main() {
|
|||||||
expect(find.byIcon(Icons.history), findsOneWidget);
|
expect(find.byIcon(Icons.history), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects viewHintText property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects viewHintText property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: SearchAnchor(
|
child: SearchAnchor(
|
||||||
@ -1152,7 +1302,7 @@ void main() {
|
|||||||
expect(find.text('hint text'), findsOneWidget);
|
expect(find.text('hint text'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects viewBackgroundColor property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects viewBackgroundColor property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: SearchAnchor(
|
child: SearchAnchor(
|
||||||
@ -1174,7 +1324,7 @@ void main() {
|
|||||||
expect(getSearchViewMaterial(tester).color, Colors.purple);
|
expect(getSearchViewMaterial(tester).color, Colors.purple);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects viewElevation property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects viewElevation property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: SearchAnchor(
|
child: SearchAnchor(
|
||||||
@ -1196,7 +1346,7 @@ void main() {
|
|||||||
expect(getSearchViewMaterial(tester).elevation, 3.0);
|
expect(getSearchViewMaterial(tester).elevation, 3.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects viewSurfaceTint property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects viewSurfaceTint property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: SearchAnchor(
|
child: SearchAnchor(
|
||||||
@ -1218,7 +1368,7 @@ void main() {
|
|||||||
expect(getSearchViewMaterial(tester).surfaceTintColor, Colors.purple);
|
expect(getSearchViewMaterial(tester).surfaceTintColor, Colors.purple);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects viewSide property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects viewSide property', (WidgetTester tester) async {
|
||||||
const BorderSide side = BorderSide(color: Colors.purple, width: 5.0);
|
const BorderSide side = BorderSide(color: Colors.purple, width: 5.0);
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
@ -1242,7 +1392,7 @@ void main() {
|
|||||||
expect(getSearchViewMaterial(tester).shape, RoundedRectangleBorder(side: side, borderRadius: BorderRadius.circular(28.0)));
|
expect(getSearchViewMaterial(tester).shape, RoundedRectangleBorder(side: side, borderRadius: BorderRadius.circular(28.0)));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects viewShape property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects viewShape property', (WidgetTester tester) async {
|
||||||
const BorderSide side = BorderSide(color: Colors.purple, width: 5.0);
|
const BorderSide side = BorderSide(color: Colors.purple, width: 5.0);
|
||||||
const OutlinedBorder shape = StadiumBorder(side: side);
|
const OutlinedBorder shape = StadiumBorder(side: side);
|
||||||
|
|
||||||
@ -1268,7 +1418,7 @@ void main() {
|
|||||||
expect(getSearchViewMaterial(tester).shape, shape);
|
expect(getSearchViewMaterial(tester).shape, shape);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects headerTextStyle property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects headerTextStyle property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: SearchAnchor(
|
child: SearchAnchor(
|
||||||
@ -1294,7 +1444,7 @@ void main() {
|
|||||||
expect(inputText.style.color, Colors.red);
|
expect(inputText.style.color, Colors.red);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects headerHintStyle property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects headerHintStyle property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: SearchAnchor(
|
child: SearchAnchor(
|
||||||
@ -1319,7 +1469,7 @@ void main() {
|
|||||||
expect(inputText.style?.color, Colors.orange);
|
expect(inputText.style?.color, Colors.orange);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects dividerColor property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects dividerColor property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: SearchAnchor(
|
child: SearchAnchor(
|
||||||
@ -1345,7 +1495,7 @@ void main() {
|
|||||||
expect(decoration.border!.bottom.color, Colors.red);
|
expect(decoration.border!.bottom.color, Colors.red);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects viewConstraints property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects viewConstraints property', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: Center(
|
child: Center(
|
||||||
@ -1373,7 +1523,7 @@ void main() {
|
|||||||
expect(sizedBox.height, 390.0);
|
expect(sizedBox.height, 390.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects builder property - LTR', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects builder property - LTR', (WidgetTester tester) async {
|
||||||
Widget buildAnchor({required SearchAnchorChildBuilder builder}) {
|
Widget buildAnchor({required SearchAnchorChildBuilder builder}) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
@ -1409,7 +1559,7 @@ void main() {
|
|||||||
expect(searchViewRect.topLeft, anchorRect.topLeft);
|
expect(searchViewRect.topLeft, anchorRect.topLeft);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects builder property - RTL', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects builder property - RTL', (WidgetTester tester) async {
|
||||||
Widget buildAnchor({required SearchAnchorChildBuilder builder}) {
|
Widget buildAnchor({required SearchAnchorChildBuilder builder}) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
home: Directionality(
|
home: Directionality(
|
||||||
@ -1446,8 +1596,9 @@ void main() {
|
|||||||
expect(searchViewRect.topRight, anchorRect.topRight);
|
expect(searchViewRect.topRight, anchorRect.topRight);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor respects suggestionsBuilder property', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor respects suggestionsBuilder property', (WidgetTester tester) async {
|
||||||
final SearchController controller = SearchController();
|
final SearchController controller = SearchController();
|
||||||
|
addTearDown(controller.dispose);
|
||||||
const String suggestion = 'suggestion text';
|
const String suggestion = 'suggestion text';
|
||||||
|
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
@ -1490,7 +1641,7 @@ void main() {
|
|||||||
expect(controller.value.text, suggestion);
|
expect(controller.value.text, suggestion);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor should update suggestions on changes to search controller', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor should update suggestions on changes to search controller', (WidgetTester tester) async {
|
||||||
final SearchController controller = SearchController();
|
final SearchController controller = SearchController();
|
||||||
const List<String> suggestions = <String>['foo','far','bim'];
|
const List<String> suggestions = <String>['foo','far','bim'];
|
||||||
addTearDown(controller.dispose);
|
addTearDown(controller.dispose);
|
||||||
@ -1579,8 +1730,9 @@ void main() {
|
|||||||
expect(listTile3, findsNothing);
|
expect(listTile3, findsNothing);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor suggestionsBuilder property could be async', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor suggestionsBuilder property could be async', (WidgetTester tester) async {
|
||||||
final SearchController controller = SearchController();
|
final SearchController controller = SearchController();
|
||||||
|
addTearDown(controller.dispose);
|
||||||
const String suggestion = 'suggestion text';
|
const String suggestion = 'suggestion text';
|
||||||
|
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
@ -1624,7 +1776,7 @@ void main() {
|
|||||||
expect(controller.value.text, suggestion);
|
expect(controller.value.text, suggestion);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor.bar has a default search bar as the anchor', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor.bar has a default search bar as the anchor', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: Align(
|
child: Align(
|
||||||
@ -1654,8 +1806,10 @@ void main() {
|
|||||||
expect(searchViewRect.width, anchorRect.width);
|
expect(searchViewRect.width, anchorRect.width);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchController can open/close view', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchController can open/close view', (WidgetTester tester) async {
|
||||||
final SearchController controller = SearchController();
|
final SearchController controller = SearchController();
|
||||||
|
addTearDown(controller.dispose);
|
||||||
|
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: SearchAnchor.bar(
|
child: SearchAnchor.bar(
|
||||||
@ -1687,7 +1841,7 @@ void main() {
|
|||||||
expect(controller.isOpen, true);
|
expect(controller.isOpen, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Search view does not go off the screen - LTR', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('Search view does not go off the screen - LTR', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: Align(
|
child: Align(
|
||||||
@ -1724,7 +1878,7 @@ void main() {
|
|||||||
expect(searchViewRect, equals(const Rect.fromLTRB(440.0, 200.0, 800.0, 600.0)));
|
expect(searchViewRect, equals(const Rect.fromLTRB(440.0, 200.0, 800.0, 600.0)));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Search view does not go off the screen - RTL', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('Search view does not go off the screen - RTL', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Directionality(
|
home: Directionality(
|
||||||
textDirection: TextDirection.rtl,
|
textDirection: TextDirection.rtl,
|
||||||
@ -1763,7 +1917,7 @@ void main() {
|
|||||||
expect(searchViewRect, equals(const Rect.fromLTRB(0.0, 200.0, 360.0, 600.0)));
|
expect(searchViewRect, equals(const Rect.fromLTRB(0.0, 200.0, 360.0, 600.0)));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Search view becomes smaller if the window size is smaller than the view size', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('Search view becomes smaller if the window size is smaller than the view size', (WidgetTester tester) async {
|
||||||
addTearDown(tester.view.reset);
|
addTearDown(tester.view.reset);
|
||||||
tester.view.physicalSize = const Size(200.0, 200.0);
|
tester.view.physicalSize = const Size(200.0, 200.0);
|
||||||
tester.view.devicePixelRatio = 1.0;
|
tester.view.devicePixelRatio = 1.0;
|
||||||
@ -1824,7 +1978,7 @@ void main() {
|
|||||||
expect(searchViewRectRTL, equals(const Rect.fromLTRB(0.0, 0.0, 200.0, 200.0)));
|
expect(searchViewRectRTL, equals(const Rect.fromLTRB(0.0, 0.0, 200.0, 200.0)));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Docked search view route is popped if the window size changes', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('Docked search view route is popped if the window size changes', (WidgetTester tester) async {
|
||||||
addTearDown(tester.view.reset);
|
addTearDown(tester.view.reset);
|
||||||
tester.view.physicalSize = const Size(500.0, 600.0);
|
tester.view.physicalSize = const Size(500.0, 600.0);
|
||||||
tester.view.devicePixelRatio = 1.0;
|
tester.view.devicePixelRatio = 1.0;
|
||||||
@ -1863,7 +2017,7 @@ void main() {
|
|||||||
expect(find.byIcon(Icons.arrow_back), findsNothing);
|
expect(find.byIcon(Icons.arrow_back), findsNothing);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Full-screen search view route should stay if the window size changes', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('Full-screen search view route should stay if the window size changes', (WidgetTester tester) async {
|
||||||
addTearDown(tester.view.reset);
|
addTearDown(tester.view.reset);
|
||||||
tester.view.physicalSize = const Size(500.0, 600.0);
|
tester.view.physicalSize = const Size(500.0, 600.0);
|
||||||
tester.view.devicePixelRatio = 1.0;
|
tester.view.devicePixelRatio = 1.0;
|
||||||
@ -1902,7 +2056,7 @@ void main() {
|
|||||||
expect(find.byIcon(Icons.arrow_back), findsOneWidget);
|
expect(find.byIcon(Icons.arrow_back), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Search view route does not throw exception during pop animation', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('Search view route does not throw exception during pop animation', (WidgetTester tester) async {
|
||||||
// Regression test for https://github.com/flutter/flutter/issues/126590.
|
// Regression test for https://github.com/flutter/flutter/issues/126590.
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
@ -1942,7 +2096,7 @@ void main() {
|
|||||||
// No exception.
|
// No exception.
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Docked search should position itself correctly based on closest navigator', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('Docked search should position itself correctly based on closest navigator', (WidgetTester tester) async {
|
||||||
const double rootSpacing = 100.0;
|
const double rootSpacing = 100.0;
|
||||||
|
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
@ -1979,7 +2133,7 @@ void main() {
|
|||||||
expect(searchViewRect.topLeft, equals(const Offset(rootSpacing, rootSpacing)));
|
expect(searchViewRect.topLeft, equals(const Offset(rootSpacing, rootSpacing)));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Docked search view with nested navigator does not go off the screen', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('Docked search view with nested navigator does not go off the screen', (WidgetTester tester) async {
|
||||||
addTearDown(tester.view.reset);
|
addTearDown(tester.view.reset);
|
||||||
tester.view.physicalSize = const Size(400.0, 400.0);
|
tester.view.physicalSize = const Size(400.0, 400.0);
|
||||||
tester.view.devicePixelRatio = 1.0;
|
tester.view.devicePixelRatio = 1.0;
|
||||||
@ -2070,7 +2224,7 @@ void main() {
|
|||||||
expect(decoration?.hintStyle?.color, theme.colorScheme.onSurfaceVariant);
|
expect(decoration?.hintStyle?.color, theme.colorScheme.onSurfaceVariant);
|
||||||
}
|
}
|
||||||
|
|
||||||
testWidgets('Overall InputDecorationTheme does not override text field style'
|
testWidgetsWithLeakTracking('Overall InputDecorationTheme does not override text field style'
|
||||||
' in SearchBar', (WidgetTester tester) async {
|
' in SearchBar', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
@ -2096,7 +2250,7 @@ void main() {
|
|||||||
checkSearchBarDefaults(tester, theme.colorScheme, material);
|
checkSearchBarDefaults(tester, theme.colorScheme, material);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Overall InputDecorationTheme does not override text field style'
|
testWidgetsWithLeakTracking('Overall InputDecorationTheme does not override text field style'
|
||||||
' in the search view route', (WidgetTester tester) async {
|
' in the search view route', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
@ -2145,7 +2299,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('SearchAnchor view respects theme brightness', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('SearchAnchor view respects theme brightness', (WidgetTester tester) async {
|
||||||
Widget buildSearchAnchor(ThemeData theme) {
|
Widget buildSearchAnchor(ThemeData theme) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
theme: theme,
|
theme: theme,
|
||||||
@ -2190,7 +2344,7 @@ void main() {
|
|||||||
expect(material.color, theme.colorScheme.surface);
|
expect(material.color, theme.colorScheme.surface);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Search view widgets can inherit local themes', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('Search view widgets can inherit local themes', (WidgetTester tester) async {
|
||||||
final ThemeData globalTheme = ThemeData(colorSchemeSeed: Colors.red);
|
final ThemeData globalTheme = ThemeData(colorSchemeSeed: Colors.red);
|
||||||
final ThemeData localTheme = ThemeData(
|
final ThemeData localTheme = ThemeData(
|
||||||
colorSchemeSeed: Colors.green,
|
colorSchemeSeed: Colors.green,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user