blob: 544ed979dbeda8ae026479e81010b306a3157c1b [file] [log] [blame]
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets(
'default search field has a border radius',
(WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Center(
child: CupertinoSearchTextField(),
),
),
);
final BoxDecoration decoration = tester
.widget<DecoratedBox>(
find.descendant(
of: find.byType(CupertinoSearchTextField),
matching: find.byType(DecoratedBox),
),
)
.decoration as BoxDecoration;
expect(
decoration.borderRadius,
const BorderRadius.all(Radius.circular(9)),
);
},
);
testWidgets(
'decoration overrides default background color',
(WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
decoration: BoxDecoration(color: Color.fromARGB(1, 1, 1, 1)),
),
),
),
);
final BoxDecoration decoration = tester
.widget<DecoratedBox>(
find.descendant(
of: find.byType(CupertinoSearchTextField),
matching: find.byType(DecoratedBox),
),
)
.decoration as BoxDecoration;
expect(
decoration.color,
const Color.fromARGB(1, 1, 1, 1),
);
},
);
testWidgets(
'decoration overrides default border radius',
(WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
decoration: BoxDecoration(borderRadius: BorderRadius.zero),
),
),
),
);
final BoxDecoration decoration = tester
.widget<DecoratedBox>(
find.descendant(
of: find.byType(CupertinoSearchTextField),
matching: find.byType(DecoratedBox),
),
)
.decoration as BoxDecoration;
expect(
decoration.borderRadius,
BorderRadius.zero,
);
},
);
testWidgets(
'text entries are padded by default',
(WidgetTester tester) async {
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
controller: TextEditingController(text: 'initial'),
),
),
),
);
expect(
tester.getTopLeft(find.text('initial')) -
tester.getTopLeft(find.byType(CupertinoSearchTextField)),
const Offset(29.8, 8.0),
);
},
);
testWidgets(
'can control text content via controller',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
controller: controller,
),
),
),
);
controller.text = 'controller text';
await tester.pump();
expect(find.text('controller text'), findsOneWidget);
controller.text = '';
await tester.pump();
expect(find.text('controller text'), findsNothing);
},
);
testWidgets('placeholder color', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
theme: CupertinoThemeData(brightness: Brightness.dark),
home: Center(
child: CupertinoSearchTextField(),
),
),
);
Text placeholder = tester.widget(find.text('Search'));
expect(placeholder.style!.color!.value, CupertinoColors.systemGrey.darkColor.value);
await tester.pumpAndSettle();
await tester.pumpWidget(
const CupertinoApp(
theme: CupertinoThemeData(brightness: Brightness.light),
home: Center(
child: CupertinoSearchTextField(),
),
),
);
placeholder = tester.widget(find.text('Search'));
expect(placeholder.style!.color!.value, CupertinoColors.systemGrey.color.value);
});
testWidgets(
"placeholderStyle modifies placeholder's style and doesn't affect text's style",
(WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
placeholder: 'placeholder',
style: TextStyle(
color: Color(0x00FFFFFF),
fontWeight: FontWeight.w300,
),
placeholderStyle: TextStyle(
color: Color(0xAAFFFFFF),
fontWeight: FontWeight.w600,
),
),
),
),
);
final Text placeholder = tester.widget(find.text('placeholder'));
expect(placeholder.style!.color, const Color(0xAAFFFFFF));
expect(placeholder.style!.fontWeight, FontWeight.w600);
await tester.enterText(find.byType(CupertinoSearchTextField), 'input');
await tester.pump();
final EditableText inputText = tester.widget(find.text('input'));
expect(inputText.style.color, const Color(0x00FFFFFF));
expect(inputText.style.fontWeight, FontWeight.w300);
},
);
testWidgets(
'prefix widget is in front of the text',
(WidgetTester tester) async {
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
controller: TextEditingController(text: 'input'),
),
),
),
);
expect(
tester.getTopRight(find.byIcon(CupertinoIcons.search)).dx + 3.8,
tester.getTopLeft(find.byType(EditableText)).dx,
);
expect(
tester.getTopLeft(find.byType(EditableText)).dx,
tester.getTopLeft(find.byType(CupertinoSearchTextField)).dx +
tester.getSize(find.byIcon(CupertinoIcons.search)).width +
9.8,
);
},
);
testWidgets(
'suffix widget is after the text',
(WidgetTester tester) async {
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
controller: TextEditingController(text: 'Hi'),
),
),
),
);
expect(
tester.getTopRight(find.byType(EditableText)).dx + 5.0,
tester.getTopLeft(find.byIcon(CupertinoIcons.xmark_circle_fill)).dx,
);
expect(
tester.getTopRight(find.byType(EditableText)).dx,
tester.getTopRight(find.byType(CupertinoSearchTextField)).dx -
tester
.getSize(find.byIcon(CupertinoIcons.xmark_circle_fill))
.width -
10.0,
);
},
);
testWidgets('prefix widget visibility', (WidgetTester tester) async {
const Key prefixIcon = Key('prefix');
await tester.pumpWidget(
const CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
prefixIcon: SizedBox(
key: prefixIcon,
width: 50,
height: 50,
),
),
),
),
);
expect(find.byIcon(CupertinoIcons.search), findsNothing);
expect(find.byKey(prefixIcon), findsOneWidget);
await tester.enterText(
find.byType(CupertinoSearchTextField), 'text input');
await tester.pump();
expect(find.text('text input'), findsOneWidget);
expect(find.byIcon(CupertinoIcons.search), findsNothing);
expect(find.byKey(prefixIcon), findsOneWidget);
});
testWidgets(
'suffix widget respects visibility mode',
(WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
suffixMode: OverlayVisibilityMode.notEditing,
),
),
),
);
expect(find.byIcon(CupertinoIcons.xmark_circle_fill), findsOneWidget);
await tester.enterText(find.byType(CupertinoSearchTextField), 'text input');
await tester.pump();
expect(find.text('text input'), findsOneWidget);
expect(find.byIcon(CupertinoIcons.xmark_circle_fill), findsNothing);
},
);
testWidgets(
'clear button shows with right visibility mode',
(WidgetTester tester) async {
TextEditingController controller = TextEditingController();
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
controller: controller,
placeholder: 'placeholder does not affect clear button',
),
),
),
);
expect(find.byIcon(CupertinoIcons.xmark_circle_fill), findsNothing);
await tester.enterText(find.byType(CupertinoSearchTextField), 'text input');
await tester.pump();
expect(find.byIcon(CupertinoIcons.xmark_circle_fill), findsOneWidget);
expect(find.text('text input'), findsOneWidget);
controller = TextEditingController();
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
controller: controller,
placeholder: 'placeholder does not affect clear button',
suffixMode: OverlayVisibilityMode.notEditing,
),
),
),
);
expect(find.byIcon(CupertinoIcons.xmark_circle_fill), findsOneWidget);
controller.text = 'input';
await tester.pump();
expect(find.byIcon(CupertinoIcons.xmark_circle_fill), findsNothing);
},
);
testWidgets(
'clear button removes text',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
controller: controller,
),
),
),
);
controller.text = 'text entry';
await tester.pump();
await tester.tap(find.byIcon(CupertinoIcons.xmark_circle_fill));
await tester.pump();
expect(controller.text, '');
expect(find.text('Search'), findsOneWidget);
expect(find.text('text entry'), findsNothing);
expect(find.byIcon(CupertinoIcons.xmark_circle_fill), findsNothing);
},
);
testWidgets(
'tapping clear button also calls onChanged when text not empty',
(WidgetTester tester) async {
String value = 'text entry';
final TextEditingController controller = TextEditingController();
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
controller: controller,
placeholder: 'placeholder',
onChanged: (String newValue) => value = newValue,
),
),
),
);
controller.text = value;
await tester.pump();
await tester.tap(find.byIcon(CupertinoIcons.xmark_circle_fill));
await tester.pump();
expect(controller.text, isEmpty);
expect(find.text('text entry'), findsNothing);
expect(value, isEmpty);
},
);
testWidgets(
'RTL puts attachments to the right places',
(WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Directionality(
textDirection: TextDirection.rtl,
child: Center(
child: CupertinoSearchTextField(
suffixMode: OverlayVisibilityMode.always,
),
),
),
),
);
expect(
tester.getTopLeft(find.byIcon(CupertinoIcons.search)).dx,
800.0 - 26.0,
);
expect(
tester.getTopRight(find.byIcon(CupertinoIcons.xmark_circle_fill)).dx,
25.0,
);
},
);
testWidgets(
'Can modify prefix and suffix insets',
(WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
suffixMode: OverlayVisibilityMode.always,
prefixInsets: EdgeInsets.zero,
suffixInsets: EdgeInsets.zero,
),
),
),
);
expect(
tester.getTopLeft(find.byIcon(CupertinoIcons.search)).dx,
0.0,
);
expect(
tester.getTopRight(find.byIcon(CupertinoIcons.xmark_circle_fill)).dx,
800.0,
);
},
);
testWidgets(
'custom suffix onTap overrides default clearing behavior',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(text: 'Text');
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
controller: controller,
onSuffixTap: () {},
),
),
),
);
await tester.pump();
await tester.tap(find.byIcon(CupertinoIcons.xmark_circle_fill));
await tester.pump();
expect(controller.text, isNotEmpty);
expect(find.text('Text'), findsOneWidget);
},
);
testWidgets('onTap is properly forwarded to the inner text field', (WidgetTester tester) async {
int onTapCallCount = 0;
// onTap can be null.
await tester.pumpWidget(
const CupertinoApp(
home: Center(
child: CupertinoSearchTextField(),
),
),
);
// onTap callback is called if not null.
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
onTap: () {
onTapCallCount++;
},
),
),
),
);
expect(onTapCallCount, 0);
await tester.tap(find.byType(CupertinoTextField));
expect(onTapCallCount, 1);
});
testWidgets('autocorrect is properly forwarded to the inner text field', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
autocorrect: false,
),
),
),
);
final CupertinoTextField textField = tester.widget(find.byType(CupertinoTextField));
expect(textField.autocorrect, false);
});
testWidgets('enabled is properly forwarded to the inner text field', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
enabled: false,
),
),
),
);
final CupertinoTextField textField = tester.widget(find.byType(CupertinoTextField));
expect(textField.enabled, false);
});
testWidgets('textInputAction is set to TextInputAction.search by default', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Center(
child: CupertinoSearchTextField(),
),
),
);
final CupertinoTextField textField = tester.widget(find.byType(CupertinoTextField));
expect(textField.textInputAction, TextInputAction.search);
});
testWidgets('autofocus:true gives focus to the widget', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoSearchTextField(
focusNode: focusNode,
autofocus: true,
),
),
),
);
expect(focusNode.hasFocus, isTrue);
});
}