diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart index 946cbe7eb0..a67a197c8d 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart @@ -136,31 +136,12 @@ class _SelectOptionTextFieldState extends State { return; } - final trimmedText = text.trimLeft(); - List splits = []; - String currentString = ''; + final result = splitInput(text.trimLeft(), widget.textSeparators); - // split the string into tokens - for (final char in trimmedText.split('')) { - if (widget.textSeparators.contains(char)) { - if (currentString.isNotEmpty) { - splits.add(currentString.trim()); - } - currentString = ''; - continue; - } - currentString += char; - } - // add the remainder (might be '') - splits.add(currentString); - - final submittedOptions = splits.sublist(0, splits.length - 1).toList(); - - final remainder = splits.elementAt(splits.length - 1).trimLeft(); - editingController.text = remainder; + editingController.text = result[1]; editingController.selection = TextSelection.collapsed(offset: controller.text.length); - widget.onPaste(submittedOptions, remainder); + widget.onPaste(result[0], result[1]); } Widget? _renderTags(BuildContext context, ScrollController sc) { @@ -193,3 +174,28 @@ class _SelectOptionTextFieldState extends State { ); } } + +@visibleForTesting +List splitInput(String input, List textSeparators) { + List splits = []; + String currentString = ''; + + // split the string into tokens + for (final char in input.split('')) { + if (textSeparators.contains(char)) { + if (currentString.trim().isNotEmpty) { + splits.add(currentString.trim()); + } + currentString = ''; + continue; + } + currentString += char; + } + // add the remainder (might be '') + splits.add(currentString); + + final submittedOptions = splits.sublist(0, splits.length - 1).toList(); + final remainder = splits.elementAt(splits.length - 1).trimLeft(); + + return [submittedOptions, remainder]; +} diff --git a/frontend/app_flowy/test/unit_test/select_option_split_text_input.dart b/frontend/app_flowy/test/unit_test/select_option_split_text_input.dart new file mode 100644 index 0000000000..892b0dba91 --- /dev/null +++ b/frontend/app_flowy/test/unit_test/select_option_split_text_input.dart @@ -0,0 +1,46 @@ +import 'package:app_flowy/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + const textSeparators = [',']; + + group('split input unit test', () { + test('empty input', () { + List result = splitInput(' ', textSeparators); + expect(result[0], []); + expect(result[1], ''); + + result = splitInput(', , , ', textSeparators); + expect(result[0], []); + expect(result[1], ''); + }); + + test('simple input', () { + List result = splitInput('exampleTag', textSeparators); + expect(result[0], []); + expect(result[1], 'exampleTag'); + + result = splitInput('tag with longer name', textSeparators); + expect(result[0], []); + expect(result[1], 'tag with longer name'); + + result = splitInput('trailing space ', textSeparators); + expect(result[0], []); + expect(result[1], 'trailing space '); + }); + + test('input with commas', () { + List result = splitInput('a, b, c', textSeparators); + expect(result[0], ['a', 'b']); + expect(result[1], 'c'); + + result = splitInput('a, b, c, ', textSeparators); + expect(result[0], ['a', 'b', 'c']); + expect(result[1], ''); + + result = splitInput(',tag 1 ,2nd tag, third tag ', textSeparators); + expect(result[0], ['tag 1', '2nd tag']); + expect(result[1], 'third tag '); + }); + }); +} diff --git a/frontend/app_flowy/test/widget_test/select_option_text_field_test.dart b/frontend/app_flowy/test/widget_test/select_option_text_field_test.dart index 56f63e9bb1..01e36edd85 100644 --- a/frontend/app_flowy/test/widget_test/select_option_text_field_test.dart +++ b/frontend/app_flowy/test/widget_test/select_option_text_field_test.dart @@ -1,11 +1,9 @@ import 'dart:collection'; import 'package:app_flowy/plugins/grid/presentation/widgets/cell/select_option_cell/text_field.dart'; -import 'package:flowy_infra/theme.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:provider/provider.dart'; import 'package:textfield_tags/textfield_tags.dart'; import '../bloc_test/grid_test/util.dart'; @@ -30,7 +28,7 @@ void main() { remainder = remaining; select = options; }, - newText: (_) {}, + newText: (text) => remainder = text, textSeparators: const [','], textController: TextEditingController(), ); @@ -40,10 +38,7 @@ void main() { await tester.pumpWidget( MaterialApp( home: Material( - child: Provider.value( - value: AppTheme.fromType(Brightness.light), - child: textField, - ), + child: textField, ), ), ); @@ -63,28 +58,15 @@ void main() { await tester.testTextInput.receiveAction(TextInputAction.done); expect(submit, 'an option'); - await tester.enterText(find.byType(TextField), ' another one '); + submit = ''; + await tester.enterText(find.byType(TextField), ' '); await tester.testTextInput.receiveAction(TextInputAction.done); - expect(submit, 'another one'); + expect(submit, ''); // test inputs containing commas - await tester.enterText(find.byType(TextField), ' abcd,'); - expect(remainder, ''); - expect(select, ['abcd']); - - await tester.enterText(find.byType(TextField), ',acd, aaaa '); - expect(remainder, 'aaaa '); - expect(select, ['acd']); - - await tester.enterText(find.byType(TextField), 'a a, bbbb , '); - expect(remainder, ''); + await tester.enterText(find.byType(TextField), 'a a, bbbb , c'); + expect(remainder, 'c'); expect(select, ['a a', 'bbbb']); - - // test paste followed by submit - await tester.enterText(find.byType(TextField), 'aaa, bbb, c'); - await tester.testTextInput.receiveAction(TextInputAction.done); - expect(select, ['aaa', 'bbb']); - expect(submit, 'c'); }); }); }