12f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard/* 22f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * Copyright (C) 2012 The Android Open Source Project 32f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * 42f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * Licensed under the Apache License, Version 2.0 (the "License"); 52f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * you may not use this file except in compliance with the License. 62f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * You may obtain a copy of the License at 72f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * 82f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * http://www.apache.org/licenses/LICENSE-2.0 92f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * 102f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * Unless required by applicable law or agreed to in writing, software 112f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * distributed under the License is distributed on an "AS IS" BASIS, 122f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * See the License for the specific language governing permissions and 142f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * limitations under the License. 152f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard */ 162f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 172f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardpackage com.android.inputmethod.latin; 182f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 19494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaokaimport android.content.res.Resources; 202f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport android.inputmethodservice.InputMethodService; 212f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport android.os.Parcel; 222f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport android.test.AndroidTestCase; 232f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport android.test.MoreAsserts; 242f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport android.test.suitebuilder.annotation.SmallTest; 252f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport android.text.SpannableString; 262f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport android.text.TextUtils; 272f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport android.text.style.SuggestionSpan; 282f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport android.view.inputmethod.ExtractedText; 292f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport android.view.inputmethod.ExtractedTextRequest; 302f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport android.view.inputmethod.InputConnection; 312f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport android.view.inputmethod.InputConnectionWrapper; 322f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 339342484e8d573a40f470b6a593df31c602fa4076Ken Wakasaimport com.android.inputmethod.latin.common.Constants; 344beeb9253a06482299e0c67467531d30436a02fcJean Chalardimport com.android.inputmethod.latin.common.StringUtils; 35494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaokaimport com.android.inputmethod.latin.settings.SpacingAndPunctuations; 36bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagiimport com.android.inputmethod.latin.utils.NgramContextUtils; 37494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaokaimport com.android.inputmethod.latin.utils.RunInLocale; 38292deb632cbab232334190e68d29184094d6d51bJean Chalardimport com.android.inputmethod.latin.utils.ScriptUtils; 39494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaokaimport com.android.inputmethod.latin.utils.TextRange; 40494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka 412f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport java.util.Locale; 422f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 432f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard@SmallTest 442f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardpublic class RichInputConnectionAndTextRangeTests extends AndroidTestCase { 452f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 462f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // The following is meant to be a reasonable default for 472f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // the "word_separators" resource. 48494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka private SpacingAndPunctuations mSpacingAndPunctuations; 492f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 502f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard @Override 512f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard protected void setUp() throws Exception { 522f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard super.setUp(); 53494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka final RunInLocale<SpacingAndPunctuations> job = new RunInLocale<SpacingAndPunctuations>() { 54494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka @Override 55494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka protected SpacingAndPunctuations job(final Resources res) { 56494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka return new SpacingAndPunctuations(res); 57494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka } 58494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka }; 59494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka final Resources res = getContext().getResources(); 60494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka mSpacingAndPunctuations = job.runInLocale(res, Locale.ENGLISH); 612f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 622f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 632f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard private class MockConnection extends InputConnectionWrapper { 642f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard final CharSequence mTextBefore; 652f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard final CharSequence mTextAfter; 662f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard final ExtractedText mExtractedText; 672f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 682f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard public MockConnection(final CharSequence text, final int cursorPosition) { 692f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard super(null, false); 702f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // Interaction of spans with Parcels is completely non-trivial, but in the actual case 712f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // the CharSequences do go through Parcels because they go through IPC. There 722f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // are some significant differences between the behavior of Spanned objects that 732f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // have and that have not gone through parceling, so it's much easier to simulate 742f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // the environment with Parcels than try to emulate things by hand. 752f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard final Parcel p = Parcel.obtain(); 762f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard TextUtils.writeToParcel(text.subSequence(0, cursorPosition), p, 0 /* flags */); 772f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard TextUtils.writeToParcel(text.subSequence(cursorPosition, text.length()), p, 782f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 0 /* flags */); 792f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard final byte[] marshalled = p.marshall(); 802f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard p.unmarshall(marshalled, 0, marshalled.length); 812f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard p.setDataPosition(0); 822f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mTextBefore = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p); 832f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mTextAfter = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p); 842f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mExtractedText = null; 852f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard p.recycle(); 862f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 872f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 882f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard public MockConnection(String textBefore, String textAfter, ExtractedText extractedText) { 892f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard super(null, false); 902f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mTextBefore = textBefore; 912f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mTextAfter = textAfter; 922f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mExtractedText = extractedText; 932f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 942f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 9572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard public int cursorPos() { 9672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard return mTextBefore.length(); 9772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard } 9872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 992f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard /* (non-Javadoc) 1002f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * @see android.view.inputmethod.InputConnectionWrapper#getTextBeforeCursor(int, int) 1012f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard */ 1022f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard @Override 1032f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard public CharSequence getTextBeforeCursor(int n, int flags) { 1042f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard return mTextBefore; 1052f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 1062f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 1072f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard /* (non-Javadoc) 1082f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * @see android.view.inputmethod.InputConnectionWrapper#getTextAfterCursor(int, int) 1092f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard */ 1102f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard @Override 1112f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard public CharSequence getTextAfterCursor(int n, int flags) { 1122f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard return mTextAfter; 1132f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 1142f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 1152f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard /* (non-Javadoc) 1162f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * @see android.view.inputmethod.InputConnectionWrapper#getExtractedText( 1172f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * ExtractedTextRequest, int) 1182f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard */ 1192f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard @Override 1202f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) { 1212f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard return mExtractedText; 1222f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 1232f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 1242f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard @Override 1252f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard public boolean beginBatchEdit() { 1262f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard return true; 1272f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 1282f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 1292f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard @Override 1302f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard public boolean endBatchEdit() { 1312f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard return true; 1322f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 1332f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 1342f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard @Override 1352f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard public boolean finishComposingText() { 1362f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard return true; 1372f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 1382f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 1392f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 1405f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka static class MockInputMethodService extends InputMethodService { 14172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard private MockConnection mMockConnection; 14272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard public void setInputConnection(final MockConnection mockConnection) { 14372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard mMockConnection = mockConnection; 14472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard } 14572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard public int cursorPos() { 14672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard return mMockConnection.cursorPos(); 1472f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 1482f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard @Override 1492f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard public InputConnection getCurrentInputConnection() { 15072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard return mMockConnection; 1512f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 1522f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 1532f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 1542f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard /************************** Tests ************************/ 1552f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 1562f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard /** 1572f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * Test for getting previous word (for bigram suggestions) 1582f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard */ 1592f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard public void testGetPreviousWord() { 1602f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // If one of the following cases breaks, the bigram suggestions won't work. 161bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 162bbd6a26be025bc419e342e32d86629c4ebd68dd8Keisuke Kuroyanagi "abc def", mSpacingAndPunctuations, 2).getNthPrevWord(1), "abc"); 163bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 164bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi "abc", mSpacingAndPunctuations, 2), NgramContext.BEGINNING_OF_SENTENCE); 165bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 166bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi "abc. def", mSpacingAndPunctuations, 2), NgramContext.BEGINNING_OF_SENTENCE); 16717f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi 168bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertFalse(NgramContextUtils.getNgramContextFromNthPreviousWord( 169bbd6a26be025bc419e342e32d86629c4ebd68dd8Keisuke Kuroyanagi "abc def", mSpacingAndPunctuations, 2).isBeginningOfSentenceContext()); 170bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertTrue(NgramContextUtils.getNgramContextFromNthPreviousWord( 171bbd6a26be025bc419e342e32d86629c4ebd68dd8Keisuke Kuroyanagi "abc", mSpacingAndPunctuations, 2).isBeginningOfSentenceContext()); 1721c2f1ada8305e36defa8572da687a4596bf083eaKeisuke Kuroyanagi 1731c2f1ada8305e36defa8572da687a4596bf083eaKeisuke Kuroyanagi // For n-gram 174bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 175bbd6a26be025bc419e342e32d86629c4ebd68dd8Keisuke Kuroyanagi "abc def", mSpacingAndPunctuations, 1).getNthPrevWord(1), "def"); 176bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 177bbd6a26be025bc419e342e32d86629c4ebd68dd8Keisuke Kuroyanagi "abc def", mSpacingAndPunctuations, 1).getNthPrevWord(2), "abc"); 178bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertTrue(NgramContextUtils.getNgramContextFromNthPreviousWord( 17911a3965f8c376db4d8fbdf3c6ea6ac54550ae6edAdrian Velicu "abc def", mSpacingAndPunctuations, 2).isNthPrevWordBeginningOfSentence(2)); 1801c2f1ada8305e36defa8572da687a4596bf083eaKeisuke Kuroyanagi 1812f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // The following tests reflect the current behavior of the function 1822f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // RichInputConnection#getNthPreviousWord. 1832f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // TODO: However at this time, the code does never go 1842f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // into such a path, so it should be safe to change the behavior of 1852f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // this function if needed - especially since it does not seem very 1862f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // logical. These tests are just there to catch any unintentional 1872f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // changes in the behavior of the RichInputConnection#getPreviousWord method. 188bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 189bbd6a26be025bc419e342e32d86629c4ebd68dd8Keisuke Kuroyanagi "abc def ", mSpacingAndPunctuations, 2).getNthPrevWord(1), "abc"); 190bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 191bbd6a26be025bc419e342e32d86629c4ebd68dd8Keisuke Kuroyanagi "abc def.", mSpacingAndPunctuations, 2).getNthPrevWord(1), "abc"); 192bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 193bbd6a26be025bc419e342e32d86629c4ebd68dd8Keisuke Kuroyanagi "abc def .", mSpacingAndPunctuations, 2).getNthPrevWord(1), "def"); 194bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertTrue(NgramContextUtils.getNgramContextFromNthPreviousWord( 195bbd6a26be025bc419e342e32d86629c4ebd68dd8Keisuke Kuroyanagi "abc ", mSpacingAndPunctuations, 2).isBeginningOfSentenceContext()); 19617f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi 197bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 198bbd6a26be025bc419e342e32d86629c4ebd68dd8Keisuke Kuroyanagi "abc def", mSpacingAndPunctuations, 1).getNthPrevWord(1), "def"); 199bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 200bbd6a26be025bc419e342e32d86629c4ebd68dd8Keisuke Kuroyanagi "abc def ", mSpacingAndPunctuations, 1).getNthPrevWord(1), "def"); 201bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 202bbd6a26be025bc419e342e32d86629c4ebd68dd8Keisuke Kuroyanagi "abc 'def", mSpacingAndPunctuations, 1).getNthPrevWord(1), "'def"); 203bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 204bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi "abc def.", mSpacingAndPunctuations, 1), NgramContext.BEGINNING_OF_SENTENCE); 205bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 206bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi "abc def .", mSpacingAndPunctuations, 1), NgramContext.BEGINNING_OF_SENTENCE); 207bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 208bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi "abc, def", mSpacingAndPunctuations, 2), NgramContext.EMPTY_PREV_WORDS_INFO); 20925433d7a0b9ed9a60dc70e5dd34ad329ef21b036Mohammadinamul Sheik // question mark is treated as the end of the sentence. Hence, beginning of the 21025433d7a0b9ed9a60dc70e5dd34ad329ef21b036Mohammadinamul Sheik // sentence is expected. 211bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 21225433d7a0b9ed9a60dc70e5dd34ad329ef21b036Mohammadinamul Sheik "abc? def", mSpacingAndPunctuations, 2), NgramContext.BEGINNING_OF_SENTENCE); 21325433d7a0b9ed9a60dc70e5dd34ad329ef21b036Mohammadinamul Sheik // Exclamation mark is treated as the end of the sentence. Hence, beginning of the 21425433d7a0b9ed9a60dc70e5dd34ad329ef21b036Mohammadinamul Sheik // sentence is expected. 215bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 21625433d7a0b9ed9a60dc70e5dd34ad329ef21b036Mohammadinamul Sheik "abc! def", mSpacingAndPunctuations, 2), NgramContext.BEGINNING_OF_SENTENCE); 217bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( 218bb0eca57054758ef17b032d2654c1fc5f6b32101Keisuke Kuroyanagi "abc 'def", mSpacingAndPunctuations, 2), NgramContext.EMPTY_PREV_WORDS_INFO); 2192f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 2202f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 2212f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard public void testGetWordRangeAtCursor() { 222914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard /** 223914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard * Test logic in getting the word range at the cursor. 224914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard */ 225914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard final SpacingAndPunctuations SPACE = new SpacingAndPunctuations( 226914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard mSpacingAndPunctuations, new int[] { Constants.CODE_SPACE }); 227914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard final SpacingAndPunctuations TAB = new SpacingAndPunctuations( 228914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard mSpacingAndPunctuations, new int[] { Constants.CODE_TAB }); 229914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard // A character that needs surrogate pair to represent its code point (U+2008A). 230914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard final String SUPPLEMENTARY_CHAR_STRING = "\uD840\uDC8A"; 231914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard final SpacingAndPunctuations SUPPLEMENTARY_CHAR = new SpacingAndPunctuations( 232914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard mSpacingAndPunctuations, StringUtils.toSortedCodePointArray( 233914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard SUPPLEMENTARY_CHAR_STRING)); 234914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard final String HIRAGANA_WORD = "\u3042\u3044\u3046\u3048\u304A"; // あいうえお 235914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard final String GREEK_WORD = "\u03BA\u03B1\u03B9"; // και 236914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard 2372f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard ExtractedText et = new ExtractedText(); 2382f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard final MockInputMethodService mockInputMethodService = new MockInputMethodService(); 2392f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard final RichInputConnection ic = new RichInputConnection(mockInputMethodService); 2402f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mockInputMethodService.setInputConnection(new MockConnection("word wo", "rd", et)); 2412f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard et.startOffset = 0; 2422f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard et.selectionStart = 7; 243675bcf191c3cdb5ba5af70efb9357ffceb389c2eJean Chalard TextRange r; 2442f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 2452f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard ic.beginBatchEdit(); 2462f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // basic case 247292deb632cbab232334190e68d29184094d6d51bJean Chalard r = ic.getWordRangeAtCursor(SPACE, ScriptUtils.SCRIPT_LATIN); 2482f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard assertTrue(TextUtils.equals("word", r.mWord)); 2492f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 2502f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // tab character instead of space 2512f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mockInputMethodService.setInputConnection(new MockConnection("one\tword\two", "rd", et)); 2522f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard ic.beginBatchEdit(); 253292deb632cbab232334190e68d29184094d6d51bJean Chalard r = ic.getWordRangeAtCursor(TAB, ScriptUtils.SCRIPT_LATIN); 2542f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard ic.endBatchEdit(); 25520c89b1cf5e30026844922d312163ffcd1c20b26Jean Chalard assertTrue(TextUtils.equals("word", r.mWord)); 2562f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 2572f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // splitting on supplementary character 2582f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mockInputMethodService.setInputConnection( 259914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard new MockConnection("one word" + SUPPLEMENTARY_CHAR_STRING + "wo", "rd", et)); 2602f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard ic.beginBatchEdit(); 261914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard r = ic.getWordRangeAtCursor(SUPPLEMENTARY_CHAR, ScriptUtils.SCRIPT_LATIN); 2622f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard ic.endBatchEdit(); 2632f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard assertTrue(TextUtils.equals("word", r.mWord)); 264292deb632cbab232334190e68d29184094d6d51bJean Chalard 265292deb632cbab232334190e68d29184094d6d51bJean Chalard // split on chars outside the specified script 266292deb632cbab232334190e68d29184094d6d51bJean Chalard mockInputMethodService.setInputConnection( 267292deb632cbab232334190e68d29184094d6d51bJean Chalard new MockConnection(HIRAGANA_WORD + "wo", "rd" + GREEK_WORD, et)); 268292deb632cbab232334190e68d29184094d6d51bJean Chalard ic.beginBatchEdit(); 269914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard r = ic.getWordRangeAtCursor(SUPPLEMENTARY_CHAR, ScriptUtils.SCRIPT_LATIN); 270292deb632cbab232334190e68d29184094d6d51bJean Chalard ic.endBatchEdit(); 271292deb632cbab232334190e68d29184094d6d51bJean Chalard assertTrue(TextUtils.equals("word", r.mWord)); 272292deb632cbab232334190e68d29184094d6d51bJean Chalard 273292deb632cbab232334190e68d29184094d6d51bJean Chalard // likewise for greek 274292deb632cbab232334190e68d29184094d6d51bJean Chalard mockInputMethodService.setInputConnection( 275292deb632cbab232334190e68d29184094d6d51bJean Chalard new MockConnection("text" + GREEK_WORD, "text", et)); 276292deb632cbab232334190e68d29184094d6d51bJean Chalard ic.beginBatchEdit(); 277914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard r = ic.getWordRangeAtCursor(SUPPLEMENTARY_CHAR, ScriptUtils.SCRIPT_GREEK); 278292deb632cbab232334190e68d29184094d6d51bJean Chalard ic.endBatchEdit(); 279292deb632cbab232334190e68d29184094d6d51bJean Chalard assertTrue(TextUtils.equals(GREEK_WORD, r.mWord)); 2802f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 2812f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 2822f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard /** 2832f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard * Test logic in getting the word range at the cursor. 2842f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard */ 2852f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard public void testGetSuggestionSpansAtWord() { 2862f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard helpTestGetSuggestionSpansAtWord(10); 2872f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard helpTestGetSuggestionSpansAtWord(12); 2882f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard helpTestGetSuggestionSpansAtWord(15); 2892f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard helpTestGetSuggestionSpansAtWord(16); 2902f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 2912f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 2922f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard private void helpTestGetSuggestionSpansAtWord(final int cursorPos) { 293914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard final SpacingAndPunctuations SPACE = new SpacingAndPunctuations( 294914078fd9198aeb3d7ffa034562321d688d588f7Jean Chalard mSpacingAndPunctuations, new int[] { Constants.CODE_SPACE }); 2952f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard final MockInputMethodService mockInputMethodService = new MockInputMethodService(); 2962f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard final RichInputConnection ic = new RichInputConnection(mockInputMethodService); 2972f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 2982f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard final String[] SUGGESTIONS1 = { "swing", "strong" }; 2992f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard final String[] SUGGESTIONS2 = { "storing", "strung" }; 3002f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 3012f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // Test the usual case. 3022f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard SpannableString text = new SpannableString("This is a string for test"); 3032f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS1, 0 /* flags */), 3042f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 10 /* start */, 16 /* end */, 0 /* flags */); 3052f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos)); 306675bcf191c3cdb5ba5af70efb9357ffceb389c2eJean Chalard TextRange r; 3072f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard SuggestionSpan[] suggestions; 3082f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 309292deb632cbab232334190e68d29184094d6d51bJean Chalard r = ic.getWordRangeAtCursor(SPACE, ScriptUtils.SCRIPT_LATIN); 3102f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard suggestions = r.getSuggestionSpansAtWord(); 3112f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard assertEquals(suggestions.length, 1); 3122f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1); 3132f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 3142f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // Test the case with 2 suggestion spans in the same place. 3152f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text = new SpannableString("This is a string for test"); 3162f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS1, 0 /* flags */), 3172f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 10 /* start */, 16 /* end */, 0 /* flags */); 3182f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */), 3192f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 10 /* start */, 16 /* end */, 0 /* flags */); 3202f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos)); 321292deb632cbab232334190e68d29184094d6d51bJean Chalard r = ic.getWordRangeAtCursor(SPACE, ScriptUtils.SCRIPT_LATIN); 3222f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard suggestions = r.getSuggestionSpansAtWord(); 3232f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard assertEquals(suggestions.length, 2); 3242f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1); 3252f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard MoreAsserts.assertEquals(suggestions[1].getSuggestions(), SUGGESTIONS2); 3262f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 3272f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // Test a case with overlapping spans, 2nd extending past the start of the word 3282f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text = new SpannableString("This is a string for test"); 3292f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS1, 0 /* flags */), 3302f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 10 /* start */, 16 /* end */, 0 /* flags */); 3312f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */), 3322f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 5 /* start */, 16 /* end */, 0 /* flags */); 3332f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos)); 334292deb632cbab232334190e68d29184094d6d51bJean Chalard r = ic.getWordRangeAtCursor(SPACE, ScriptUtils.SCRIPT_LATIN); 3352f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard suggestions = r.getSuggestionSpansAtWord(); 3362f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard assertEquals(suggestions.length, 1); 3372f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1); 3382f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 3392f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // Test a case with overlapping spans, 2nd extending past the end of the word 3402f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text = new SpannableString("This is a string for test"); 3412f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS1, 0 /* flags */), 3422f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 10 /* start */, 16 /* end */, 0 /* flags */); 3432f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */), 3442f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 10 /* start */, 20 /* end */, 0 /* flags */); 3452f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos)); 346292deb632cbab232334190e68d29184094d6d51bJean Chalard r = ic.getWordRangeAtCursor(SPACE, ScriptUtils.SCRIPT_LATIN); 3472f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard suggestions = r.getSuggestionSpansAtWord(); 3482f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard assertEquals(suggestions.length, 1); 3492f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1); 3502f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 3512f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // Test a case with overlapping spans, 2nd extending past both ends of the word 3522f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text = new SpannableString("This is a string for test"); 3532f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS1, 0 /* flags */), 3542f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 10 /* start */, 16 /* end */, 0 /* flags */); 3552f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */), 3562f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 5 /* start */, 20 /* end */, 0 /* flags */); 3572f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos)); 358292deb632cbab232334190e68d29184094d6d51bJean Chalard r = ic.getWordRangeAtCursor(SPACE, ScriptUtils.SCRIPT_LATIN); 3592f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard suggestions = r.getSuggestionSpansAtWord(); 3602f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard assertEquals(suggestions.length, 1); 3612f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1); 3622f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 3632f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard // Test a case with overlapping spans, none right on the word 3642f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text = new SpannableString("This is a string for test"); 3652f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS1, 0 /* flags */), 3662f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 5 /* start */, 16 /* end */, 0 /* flags */); 3672f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */), 3682f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard 5 /* start */, 20 /* end */, 0 /* flags */); 3692f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos)); 370292deb632cbab232334190e68d29184094d6d51bJean Chalard r = ic.getWordRangeAtCursor(SPACE, ScriptUtils.SCRIPT_LATIN); 3712f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard suggestions = r.getSuggestionSpansAtWord(); 3722f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard assertEquals(suggestions.length, 0); 3732f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard } 37472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 37572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard public void testCursorTouchingWord() { 37672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard final MockInputMethodService ims = new MockInputMethodService(); 37772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard final RichInputConnection ic = new RichInputConnection(ims); 37872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard final SpacingAndPunctuations sap = mSpacingAndPunctuations; 37972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 38072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection("users", 5)); 38172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 382f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertTrue(ic.isCursorTouchingWord(sap, true /* checkTextAfter */)); 38372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 38472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection("users'", 5)); 38572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 386f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertTrue(ic.isCursorTouchingWord(sap, true)); 38772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 38872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection("users'", 6)); 38972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 390f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertTrue(ic.isCursorTouchingWord(sap, true)); 39172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 39272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection("'users'", 6)); 39372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 394f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertTrue(ic.isCursorTouchingWord(sap, true)); 39572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 39672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection("'users'", 7)); 39772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 398f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertTrue(ic.isCursorTouchingWord(sap, true)); 39972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 40072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection("users '", 6)); 40172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 402f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertFalse(ic.isCursorTouchingWord(sap, true)); 40372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 40472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection("users '", 7)); 40572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 406f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertFalse(ic.isCursorTouchingWord(sap, true)); 40772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 40872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection("re-", 3)); 40972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 410f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertTrue(ic.isCursorTouchingWord(sap, true)); 41172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 41272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection("re--", 4)); 41372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 414f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertFalse(ic.isCursorTouchingWord(sap, true)); 41572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 41672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection("-", 1)); 41772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 418f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertFalse(ic.isCursorTouchingWord(sap, true)); 41972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 42072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection("--", 2)); 42172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 422f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertFalse(ic.isCursorTouchingWord(sap, true)); 42372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 42472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection(" -", 2)); 42572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 426f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertFalse(ic.isCursorTouchingWord(sap, true)); 42772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 42872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection(" --", 3)); 42972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 430f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertFalse(ic.isCursorTouchingWord(sap, true)); 43172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 43272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection(" users '", 1)); 43372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 434f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertTrue(ic.isCursorTouchingWord(sap, true)); 43572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 43672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection(" users '", 3)); 43772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 438f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertTrue(ic.isCursorTouchingWord(sap, true)); 43972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 44072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection(" users '", 7)); 44172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 442f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertFalse(ic.isCursorTouchingWord(sap, true)); 44372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 44472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection(" users are", 7)); 44572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 446f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertTrue(ic.isCursorTouchingWord(sap, true)); 44772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard 44872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ims.setInputConnection(new MockConnection(" users 'are", 7)); 44972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true); 450f470729df26c67f48bd55bbf16a3d6066eac2a2fTom Ouyang assertFalse(ic.isCursorTouchingWord(sap, true)); 45172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard } 4522f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard} 453