Commit 1a62c28b authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Correct handling for nulling TextField controller (#12190)

Correctly handle the case where the TextEditingController associated
with a TextField is set to null. Due to a typo (= vs ==), previously
this was a no-op and the existing TextEditingController was retained,
rather than copied.
parent cb2204d1
......@@ -213,7 +213,7 @@ class _TextFieldState extends State<TextField> {
void didUpdateWidget(TextField oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.controller == null && oldWidget.controller != null)
_controller == new TextEditingController.fromValue(oldWidget.controller.value);
_controller = new TextEditingController.fromValue(oldWidget.controller.value);
else if (widget.controller != null && oldWidget.controller == null)
_controller = null;
}
......
......@@ -1233,14 +1233,14 @@ void main() {
});
testWidgets('Controller can update server', (WidgetTester tester) async {
final TextEditingController controller = new TextEditingController(
final TextEditingController controller1 = new TextEditingController(
text: 'Initial Text',
);
final TextEditingController controller2 = new TextEditingController(
text: 'More Text',
);
TextEditingController currentController = controller;
TextEditingController currentController;
StateSetter setState;
await tester.pumpWidget(
......@@ -1255,36 +1255,64 @@ void main() {
);
expect(tester.testTextInput.editingState['text'], isEmpty);
// Initial state with null controller.
await tester.tap(find.byType(TextField));
await tester.pump();
expect(tester.testTextInput.editingState['text'], isEmpty);
// Update the controller from null to controller1.
setState(() {
currentController = controller1;
});
await tester.pump();
expect(tester.testTextInput.editingState['text'], equals('Initial Text'));
controller.text = 'Updated Text';
// Verify that updates to controller1 are handled.
controller1.text = 'Updated Text';
await tester.idle();
expect(tester.testTextInput.editingState['text'], equals('Updated Text'));
// Verify that switching from controller1 to controller2 is handled.
setState(() {
currentController = controller2;
});
await tester.pump();
expect(tester.testTextInput.editingState['text'], equals('More Text'));
controller.text = 'Ignored Text';
// Verify that updates to controller1 are ignored.
controller1.text = 'Ignored Text';
await tester.idle();
expect(tester.testTextInput.editingState['text'], equals('More Text'));
// Verify that updates to controller text are handled.
controller2.text = 'Additional Text';
await tester.idle();
expect(tester.testTextInput.editingState['text'], equals('Additional Text'));
// Verify that updates to controller selection are handled.
controller2.selection = const TextSelection(baseOffset: 0, extentOffset: 5);
await tester.idle();
expect(tester.testTextInput.editingState['selectionBase'], equals(0));
expect(tester.testTextInput.editingState['selectionExtent'], equals(5));
// Verify that calling clear() clears the text.
controller2.clear();
await tester.idle();
expect(tester.testTextInput.editingState['text'], equals(''));
// Verify that switching from controller2 to null preserves current text.
controller2.text = 'The Final Cut';
await tester.idle();
expect(tester.testTextInput.editingState['text'], equals('The Final Cut'));
setState(() {
currentController = null;
});
await tester.pump();
expect(tester.testTextInput.editingState['text'], equals('The Final Cut'));
// Verify that changes to controller2 are ignored.
controller2.text = 'Goodbye Cruel World';
expect(tester.testTextInput.editingState['text'], equals('The Final Cut'));
});
testWidgets('Cannot enter new lines onto single line TextField', (WidgetTester tester) async {
......
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