RichInputConnectionAndTextRangeTests.java revision 17f326b7458c2bde2569e283a96e703755485328
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
33494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaokaimport com.android.inputmethod.latin.settings.SpacingAndPunctuations;
34494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaokaimport com.android.inputmethod.latin.utils.RunInLocale;
35c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaokaimport com.android.inputmethod.latin.utils.StringUtils;
36494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaokaimport com.android.inputmethod.latin.utils.TextRange;
37494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka
382f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardimport java.util.Locale;
392f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
402f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard@SmallTest
412f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalardpublic class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
422f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
432f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    // The following is meant to be a reasonable default for
442f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    // the "word_separators" resource.
45494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka    private SpacingAndPunctuations mSpacingAndPunctuations;
462f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
472f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    @Override
482f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    protected void setUp() throws Exception {
492f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        super.setUp();
50494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka        final RunInLocale<SpacingAndPunctuations> job = new RunInLocale<SpacingAndPunctuations>() {
51494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka            @Override
52494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka            protected SpacingAndPunctuations job(final Resources res) {
53494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka                return new SpacingAndPunctuations(res);
54494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka            }
55494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka        };
56494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka        final Resources res = getContext().getResources();
57494e2d6c17cdbf27615a2fbc02b12d2562bf7cd3Tadashi G. Takaoka        mSpacingAndPunctuations = job.runInLocale(res, Locale.ENGLISH);
582f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    }
592f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
602f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    private class MockConnection extends InputConnectionWrapper {
612f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        final CharSequence mTextBefore;
622f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        final CharSequence mTextAfter;
632f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        final ExtractedText mExtractedText;
642f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
652f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        public MockConnection(final CharSequence text, final int cursorPosition) {
662f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            super(null, false);
672f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            // Interaction of spans with Parcels is completely non-trivial, but in the actual case
682f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            // the CharSequences do go through Parcels because they go through IPC. There
692f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            // are some significant differences between the behavior of Spanned objects that
702f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            // have and that have not gone through parceling, so it's much easier to simulate
712f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            // the environment with Parcels than try to emulate things by hand.
722f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            final Parcel p = Parcel.obtain();
732f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            TextUtils.writeToParcel(text.subSequence(0, cursorPosition), p, 0 /* flags */);
742f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            TextUtils.writeToParcel(text.subSequence(cursorPosition, text.length()), p,
752f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard                    0 /* flags */);
762f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            final byte[] marshalled = p.marshall();
772f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            p.unmarshall(marshalled, 0, marshalled.length);
782f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            p.setDataPosition(0);
792f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            mTextBefore = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
802f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            mTextAfter = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
812f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            mExtractedText = null;
822f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            p.recycle();
832f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        }
842f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
852f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        public MockConnection(String textBefore, String textAfter, ExtractedText extractedText) {
862f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            super(null, false);
872f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            mTextBefore = textBefore;
882f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            mTextAfter = textAfter;
892f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            mExtractedText = extractedText;
902f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        }
912f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
9272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        public int cursorPos() {
9372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard            return mTextBefore.length();
9472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        }
9572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
962f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        /* (non-Javadoc)
972f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard         * @see android.view.inputmethod.InputConnectionWrapper#getTextBeforeCursor(int, int)
982f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard         */
992f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        @Override
1002f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        public CharSequence getTextBeforeCursor(int n, int flags) {
1012f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            return mTextBefore;
1022f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        }
1032f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
1042f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        /* (non-Javadoc)
1052f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard         * @see android.view.inputmethod.InputConnectionWrapper#getTextAfterCursor(int, int)
1062f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard         */
1072f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        @Override
1082f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        public CharSequence getTextAfterCursor(int n, int flags) {
1092f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            return mTextAfter;
1102f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        }
1112f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
1122f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        /* (non-Javadoc)
1132f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard         * @see android.view.inputmethod.InputConnectionWrapper#getExtractedText(
1142f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard         *         ExtractedTextRequest, int)
1152f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard         */
1162f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        @Override
1172f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
1182f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            return mExtractedText;
1192f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        }
1202f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
1212f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        @Override
1222f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        public boolean beginBatchEdit() {
1232f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            return true;
1242f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        }
1252f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
1262f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        @Override
1272f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        public boolean endBatchEdit() {
1282f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            return true;
1292f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        }
1302f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
1312f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        @Override
1322f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        public boolean finishComposingText() {
1332f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard            return true;
1342f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        }
1352f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    }
1362f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
1372f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    private class MockInputMethodService extends InputMethodService {
13872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        private MockConnection mMockConnection;
13972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        public void setInputConnection(final MockConnection mockConnection) {
14072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard            mMockConnection = mockConnection;
14172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        }
14272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        public int cursorPos() {
14372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard            return mMockConnection.cursorPos();
1442f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        }
1452f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        @Override
1462f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        public InputConnection getCurrentInputConnection() {
14772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard            return mMockConnection;
1482f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        }
1492f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    }
1502f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
1512f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    /************************** Tests ************************/
1522f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
1532f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    /**
1542f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard     * Test for getting previous word (for bigram suggestions)
1552f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard     */
1562f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    public void testGetPreviousWord() {
1572f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // If one of the following cases breaks, the bigram suggestions won't work.
15817f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertEquals(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
15917f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc def", mSpacingAndPunctuations, 2).mPrevWord, "abc");
16017f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertNull(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
16117f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc", mSpacingAndPunctuations, 2).mPrevWord);
16217f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertNull(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
16317f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc. def", mSpacingAndPunctuations, 2).mPrevWord);
16417f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi
16517f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertFalse(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
16617f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc def", mSpacingAndPunctuations, 2).mIsBeginningOfSentence);
16717f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertTrue(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
16817f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc", mSpacingAndPunctuations, 2).mIsBeginningOfSentence);
1692f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // The following tests reflect the current behavior of the function
1702f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // RichInputConnection#getNthPreviousWord.
1712f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // TODO: However at this time, the code does never go
1722f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // into such a path, so it should be safe to change the behavior of
1732f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // this function if needed - especially since it does not seem very
1742f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // logical. These tests are just there to catch any unintentional
1752f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // changes in the behavior of the RichInputConnection#getPreviousWord method.
17617f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertEquals(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
17717f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc def ", mSpacingAndPunctuations, 2).mPrevWord, "abc");
17817f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertEquals(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
17917f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc def.", mSpacingAndPunctuations, 2).mPrevWord, "abc");
18017f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertEquals(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
18117f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc def .", mSpacingAndPunctuations, 2).mPrevWord, "def");
18217f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertEquals(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
18317f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc ", mSpacingAndPunctuations, 2).mPrevWord, null);
18417f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi
18517f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertEquals(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
18617f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc def", mSpacingAndPunctuations, 1).mPrevWord, "def");
18717f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertEquals(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
18817f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc def ", mSpacingAndPunctuations, 1).mPrevWord, "def");
18917f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertNull(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
19017f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc def.", mSpacingAndPunctuations, 1).mPrevWord);
19117f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi        assertNull(RichInputConnection.getPrevWordsInfoFromNthPreviousWord(
19217f326b7458c2bde2569e283a96e703755485328Keisuke Kuroyanagi                "abc def .", mSpacingAndPunctuations, 1).mPrevWord);
1932f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    }
1942f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
1952f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    /**
1962f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard     * Test logic in getting the word range at the cursor.
1972f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard     */
198c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka    private static final int[] SPACE = { Constants.CODE_SPACE };
199c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka    static final int[] TAB = { Constants.CODE_TAB };
200c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka    private static final int[] SPACE_TAB = StringUtils.toSortedCodePointArray(" \t");
201c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka    // A character that needs surrogate pair to represent its code point (U+2008A).
202c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka    private static final String SUPPLEMENTARY_CHAR = "\uD840\uDC8A";
203c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka
2042f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    public void testGetWordRangeAtCursor() {
2052f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ExtractedText et = new ExtractedText();
2062f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        final MockInputMethodService mockInputMethodService = new MockInputMethodService();
2072f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        final RichInputConnection ic = new RichInputConnection(mockInputMethodService);
2082f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        mockInputMethodService.setInputConnection(new MockConnection("word wo", "rd", et));
2092f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        et.startOffset = 0;
2102f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        et.selectionStart = 7;
211675bcf191c3cdb5ba5af70efb9357ffceb389c2eJean Chalard        TextRange r;
2122f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
2132f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ic.beginBatchEdit();
2142f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // basic case
215c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(SPACE, 0);
2162f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        assertTrue(TextUtils.equals("word", r.mWord));
2172f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
2182f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // more than one word
219c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(SPACE, 1);
2202f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        assertTrue(TextUtils.equals("word word", r.mWord));
2212f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ic.endBatchEdit();
2222f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
2232f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // tab character instead of space
2242f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        mockInputMethodService.setInputConnection(new MockConnection("one\tword\two", "rd", et));
2252f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ic.beginBatchEdit();
226c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(TAB, 1);
2272f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ic.endBatchEdit();
2282f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        assertTrue(TextUtils.equals("word\tword", r.mWord));
2292f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
2302f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // only one word doesn't go too far
2312f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        mockInputMethodService.setInputConnection(new MockConnection("one\tword\two", "rd", et));
2322f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ic.beginBatchEdit();
233c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(TAB, 1);
2342f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ic.endBatchEdit();
2352f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        assertTrue(TextUtils.equals("word\tword", r.mWord));
2362f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
2372f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // tab or space
2382f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        mockInputMethodService.setInputConnection(new MockConnection("one word\two", "rd", et));
2392f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ic.beginBatchEdit();
240c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(SPACE_TAB, 1);
2412f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ic.endBatchEdit();
2422f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        assertTrue(TextUtils.equals("word\tword", r.mWord));
2432f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
2442f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // tab or space multiword
2452f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        mockInputMethodService.setInputConnection(new MockConnection("one word\two", "rd", et));
2462f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ic.beginBatchEdit();
247c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(SPACE_TAB, 2);
2482f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ic.endBatchEdit();
2492f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        assertTrue(TextUtils.equals("one word\tword", r.mWord));
2502f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
2512f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // splitting on supplementary character
2522f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        mockInputMethodService.setInputConnection(
253c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka                new MockConnection("one word" + SUPPLEMENTARY_CHAR + "wo", "rd", et));
2542f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ic.beginBatchEdit();
255c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(StringUtils.toSortedCodePointArray(SUPPLEMENTARY_CHAR), 0);
2562f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        ic.endBatchEdit();
2572f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        assertTrue(TextUtils.equals("word", r.mWord));
2582f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    }
2592f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
2602f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    /**
2612f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard     * Test logic in getting the word range at the cursor.
2622f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard     */
2632f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    public void testGetSuggestionSpansAtWord() {
2642f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        helpTestGetSuggestionSpansAtWord(10);
2652f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        helpTestGetSuggestionSpansAtWord(12);
2662f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        helpTestGetSuggestionSpansAtWord(15);
2672f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        helpTestGetSuggestionSpansAtWord(16);
2682f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    }
2692f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
2702f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    private void helpTestGetSuggestionSpansAtWord(final int cursorPos) {
2712f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        final MockInputMethodService mockInputMethodService = new MockInputMethodService();
2722f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        final RichInputConnection ic = new RichInputConnection(mockInputMethodService);
2732f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
2742f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        final String[] SUGGESTIONS1 = { "swing", "strong" };
2752f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        final String[] SUGGESTIONS2 = { "storing", "strung" };
2762f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
2772f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // Test the usual case.
2782f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        SpannableString text = new SpannableString("This is a string for test");
2792f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS1, 0 /* flags */),
2802f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard                10 /* start */, 16 /* end */, 0 /* flags */);
2812f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos));
282675bcf191c3cdb5ba5af70efb9357ffceb389c2eJean Chalard        TextRange r;
2832f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        SuggestionSpan[] suggestions;
2842f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
285c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(SPACE, 0);
2862f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        suggestions = r.getSuggestionSpansAtWord();
2872f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        assertEquals(suggestions.length, 1);
2882f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1);
2892f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
2902f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // Test the case with 2 suggestion spans in the same place.
2912f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        text = new SpannableString("This is a string for test");
2922f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS1, 0 /* flags */),
2932f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard                10 /* start */, 16 /* end */, 0 /* flags */);
2942f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */),
2952f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard                10 /* start */, 16 /* end */, 0 /* flags */);
2962f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos));
297c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(SPACE, 0);
2982f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        suggestions = r.getSuggestionSpansAtWord();
2992f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        assertEquals(suggestions.length, 2);
3002f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1);
3012f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        MoreAsserts.assertEquals(suggestions[1].getSuggestions(), SUGGESTIONS2);
3022f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
3032f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // Test a case with overlapping spans, 2nd extending past the start of the word
3042f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        text = new SpannableString("This is a string for test");
3052f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS1, 0 /* flags */),
3062f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard                10 /* start */, 16 /* end */, 0 /* flags */);
3072f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */),
3082f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard                5 /* start */, 16 /* end */, 0 /* flags */);
3092f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos));
310c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(SPACE, 0);
3112f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        suggestions = r.getSuggestionSpansAtWord();
3122f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        assertEquals(suggestions.length, 1);
3132f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1);
3142f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
3152f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // Test a case with overlapping spans, 2nd extending past the end of the word
3162f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        text = new SpannableString("This is a string for test");
3172f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS1, 0 /* flags */),
3182f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard                10 /* start */, 16 /* end */, 0 /* flags */);
3192f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */),
3202f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard                10 /* start */, 20 /* end */, 0 /* flags */);
3212f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos));
322c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(SPACE, 0);
3232f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        suggestions = r.getSuggestionSpansAtWord();
3242f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        assertEquals(suggestions.length, 1);
3252f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1);
3262f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard
3272f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        // Test a case with overlapping spans, 2nd extending past both ends 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 */, 20 /* end */, 0 /* flags */);
3332f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos));
334c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(SPACE, 0);
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, none right on 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                5 /* start */, 16 /* end */, 0 /* flags */);
3432f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */),
3442f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard                5 /* start */, 20 /* end */, 0 /* flags */);
3452f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos));
346c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        r = ic.getWordRangeAtCursor(SPACE, 0);
3472f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        suggestions = r.getSuggestionSpansAtWord();
3482f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard        assertEquals(suggestions.length, 0);
3492f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard    }
35072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
35172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard    public void testCursorTouchingWord() {
35272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        final MockInputMethodService ims = new MockInputMethodService();
35372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        final RichInputConnection ic = new RichInputConnection(ims);
35472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        final SpacingAndPunctuations sap = mSpacingAndPunctuations;
35572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
35672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection("users", 5));
35772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
35872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertTrue(ic.isCursorTouchingWord(sap));
35972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
36072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection("users'", 5));
36172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
36272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertTrue(ic.isCursorTouchingWord(sap));
36372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
36472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection("users'", 6));
36572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
36672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertTrue(ic.isCursorTouchingWord(sap));
36772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
36872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection("'users'", 6));
36972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
37072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertTrue(ic.isCursorTouchingWord(sap));
37172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
37272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection("'users'", 7));
37372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
37472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertTrue(ic.isCursorTouchingWord(sap));
37572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
37672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection("users '", 6));
37772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
37872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertFalse(ic.isCursorTouchingWord(sap));
37972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
38072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection("users '", 7));
38172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
38272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertFalse(ic.isCursorTouchingWord(sap));
38372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
38472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection("re-", 3));
38572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
38672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertTrue(ic.isCursorTouchingWord(sap));
38772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
38872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection("re--", 4));
38972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
39072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertFalse(ic.isCursorTouchingWord(sap));
39172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
39272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection("-", 1));
39372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
39472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertFalse(ic.isCursorTouchingWord(sap));
39572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
39672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection("--", 2));
39772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
39872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertFalse(ic.isCursorTouchingWord(sap));
39972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
40072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection(" -", 2));
40172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
40272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertFalse(ic.isCursorTouchingWord(sap));
40372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
40472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection(" --", 3));
40572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
40672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertFalse(ic.isCursorTouchingWord(sap));
40772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
40872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection(" users '", 1));
40972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
41072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertTrue(ic.isCursorTouchingWord(sap));
41172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
41272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection(" users '", 3));
41372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
41472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertTrue(ic.isCursorTouchingWord(sap));
41572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
41672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection(" users '", 7));
41772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
41872b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertFalse(ic.isCursorTouchingWord(sap));
41972b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
42072b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection(" users are", 7));
42172b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
42272b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertTrue(ic.isCursorTouchingWord(sap));
42372b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard
42472b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ims.setInputConnection(new MockConnection(" users 'are", 7));
42572b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        ic.resetCachesUponCursorMoveAndReturnSuccess(ims.cursorPos(), ims.cursorPos(), true);
42672b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard        assertFalse(ic.isCursorTouchingWord(sap));
42772b67f65411cf07cb8cb2d52e859f46d9d5b91d4Jean Chalard    }
4282f7f6257b66fc1ed19b600f3d55902fd0de2e338Jean Chalard}
429