@@ -270,6 +270,49 @@ public void testMethod_getExtractedText() {
270270 assertEquals (extractedText .selectionEnd , selStart );
271271 }
272272
273+ @ Test
274+ public void inputConnectionAdaptor_RepeatFilter () throws NullPointerException {
275+ View testView = new View (RuntimeEnvironment .application );
276+ FlutterJNI mockFlutterJni = mock (FlutterJNI .class );
277+ DartExecutor dartExecutor = spy (new DartExecutor (mockFlutterJni , mock (AssetManager .class )));
278+ int inputTargetId = 0 ;
279+ TestTextInputChannel textInputChannel = new TestTextInputChannel (dartExecutor );
280+ Editable mEditable = Editable .Factory .getInstance ().newEditable ("" );
281+ Editable spyEditable = spy (mEditable );
282+ EditorInfo outAttrs = new EditorInfo ();
283+ outAttrs .inputType = InputType .TYPE_CLASS_TEXT | InputType .TYPE_TEXT_FLAG_MULTI_LINE ;
284+
285+ InputConnectionAdaptor inputConnectionAdaptor =
286+ new InputConnectionAdaptor (
287+ testView , inputTargetId , textInputChannel , spyEditable , outAttrs );
288+
289+ inputConnectionAdaptor .beginBatchEdit ();
290+ assertEquals (textInputChannel .updateEditingStateInvocations , 0 );
291+ inputConnectionAdaptor .setComposingText ("I do not fear computers. I fear the lack of them." , 1 );
292+ assertEquals (textInputChannel .text , null );
293+ assertEquals (textInputChannel .updateEditingStateInvocations , 0 );
294+ inputConnectionAdaptor .endBatchEdit ();
295+ assertEquals (textInputChannel .updateEditingStateInvocations , 1 );
296+ assertEquals (textInputChannel .text , "I do not fear computers. I fear the lack of them." );
297+
298+ inputConnectionAdaptor .beginBatchEdit ();
299+ assertEquals (textInputChannel .updateEditingStateInvocations , 1 );
300+ inputConnectionAdaptor .endBatchEdit ();
301+ assertEquals (textInputChannel .updateEditingStateInvocations , 1 );
302+
303+ inputConnectionAdaptor .beginBatchEdit ();
304+ assertEquals (textInputChannel .text , "I do not fear computers. I fear the lack of them." );
305+ assertEquals (textInputChannel .updateEditingStateInvocations , 1 );
306+ inputConnectionAdaptor .setSelection (3 , 4 );
307+ assertEquals (textInputChannel .updateEditingStateInvocations , 1 );
308+ assertEquals (textInputChannel .selectionStart , 49 );
309+ assertEquals (textInputChannel .selectionEnd , 49 );
310+ inputConnectionAdaptor .endBatchEdit ();
311+ assertEquals (textInputChannel .updateEditingStateInvocations , 2 );
312+ assertEquals (textInputChannel .selectionStart , 3 );
313+ assertEquals (textInputChannel .selectionEnd , 4 );
314+ }
315+
273316 private static final String SAMPLE_TEXT =
274317 "Lorem ipsum dolor sit amet," + "\n consectetur adipiscing elit." ;
275318
@@ -285,4 +328,35 @@ private static InputConnectionAdaptor sampleInputConnectionAdaptor(Editable edit
285328 TextInputChannel textInputChannel = mock (TextInputChannel .class );
286329 return new InputConnectionAdaptor (testView , client , textInputChannel , editable , null );
287330 }
331+
332+ private class TestTextInputChannel extends TextInputChannel {
333+ public TestTextInputChannel (DartExecutor dartExecutor ) {
334+ super (dartExecutor );
335+ }
336+
337+ public int inputClientId ;
338+ public String text ;
339+ public int selectionStart ;
340+ public int selectionEnd ;
341+ public int composingStart ;
342+ public int composingEnd ;
343+ public int updateEditingStateInvocations = 0 ;
344+
345+ @ Override
346+ public void updateEditingState (
347+ int inputClientId ,
348+ String text ,
349+ int selectionStart ,
350+ int selectionEnd ,
351+ int composingStart ,
352+ int composingEnd ) {
353+ this .inputClientId = inputClientId ;
354+ this .text = text ;
355+ this .selectionStart = selectionStart ;
356+ this .selectionEnd = selectionEnd ;
357+ this .composingStart = composingStart ;
358+ this .composingEnd = composingEnd ;
359+ updateEditingStateInvocations ++;
360+ }
361+ }
288362}
0 commit comments