Unverified Commit 79caa837 authored by Edgar Jan's avatar Edgar Jan Committed by GitHub

Fix and Test Conditional Validator Behavior in FormField (#132714)

In the FormField widget, if a validator is initially set (and validation fails), then subsequently the validator is set to null, the form incorrectly retains its error state. This is not expected behavior as removing the validator should clear any validation errors.
parent fffbbf27
...@@ -524,6 +524,8 @@ class FormFieldState<T> extends State<FormField<T>> with RestorationMixin { ...@@ -524,6 +524,8 @@ class FormFieldState<T> extends State<FormField<T>> with RestorationMixin {
void _validate() { void _validate() {
if (widget.validator != null) { if (widget.validator != null) {
_errorText.value = widget.validator!(_value); _errorText.value = widget.validator!(_value);
} else {
_errorText.value = null;
} }
} }
......
...@@ -945,4 +945,71 @@ void main() { ...@@ -945,4 +945,71 @@ void main() {
fieldKey.currentState!.reset(); fieldKey.currentState!.reset();
expect(fieldKey.currentState!.hasInteractedByUser, isFalse); expect(fieldKey.currentState!.hasInteractedByUser, isFalse);
}); });
testWidgets('Validator is nullified and error text behaves accordingly',
(WidgetTester tester) async {
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
bool useValidator = false;
late StateSetter setState;
String? validator(String? value) {
if (value == null || value.isEmpty) {
return 'test_error';
}
return null;
}
Widget builder() {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setter) {
setState = setter;
return MaterialApp(
home: MediaQuery(
data: const MediaQueryData(),
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Material(
child: Form(
key: formKey,
child: TextFormField(
validator: useValidator ? validator : null,
),
),
),
),
),
),
);
},
);
}
await tester.pumpWidget(builder());
// Start with no validator.
await tester.enterText(find.byType(TextFormField), '');
await tester.pump();
formKey.currentState!.validate();
await tester.pump();
expect(find.text('test_error'), findsNothing);
// Now use the validator.
setState(() {
useValidator = true;
});
await tester.pump();
formKey.currentState!.validate();
await tester.pump();
expect(find.text('test_error'), findsOneWidget);
// Remove the validator again and expect the error to disappear.
setState(() {
useValidator = false;
});
await tester.pump();
formKey.currentState!.validate();
await tester.pump();
expect(find.text('test_error'), findsNothing);
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment