183c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard/*
283c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard * Copyright (C) 2012 The Android Open Source Project
383c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard *
4ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License");
5ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * you may not use this file except in compliance with the License.
6ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * You may obtain a copy of the License at
783c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard *
8ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka *      http://www.apache.org/licenses/LICENSE-2.0
983c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard *
1083c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard * Unless required by applicable law or agreed to in writing, software
11ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS,
12ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * See the License for the specific language governing permissions and
14ce6bcdd1a547c9874f05a08074cafdfea16196d6Tadashi G. Takaoka * limitations under the License.
1583c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard */
1683c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard
1783c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalardpackage com.android.inputmethod.latin;
1883c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard
19b4598f7d05d6afd01ddc7ea0bed71dda837d1debTadashi G. Takaokaimport android.test.suitebuilder.annotation.LargeTest;
20c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalardimport android.view.inputmethod.BaseInputConnection;
21b4598f7d05d6afd01ddc7ea0bed71dda837d1debTadashi G. Takaoka
22b4598f7d05d6afd01ddc7ea0bed71dda837d1debTadashi G. Takaoka@LargeTest
238592ed408e8e81138172eefe2df28f00807a1e1fJean Chalardpublic class InputLogicTests extends InputTestsBase {
24f717c5685e3299349d5abe1ecc7d13446b9779bcJean Chalard
2583c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard    public void testTypeWord() {
261e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        final String WORD_TO_TYPE = "abcd";
271e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        type(WORD_TO_TYPE);
28d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka        assertEquals("type word", WORD_TO_TYPE, mEditText.getText().toString());
2983c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard    }
3083c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard
3183c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard    public void testPickSuggestionThenBackspace() {
329159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard        final String WORD_TO_TYPE = "this";
33f83a6821bbf3863415378ea39d3b705954318e41Jean Chalard        final String EXPECTED_RESULT = "thi";
341e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        type(WORD_TO_TYPE);
359bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge        pickSuggestionManually(0, WORD_TO_TYPE);
369159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard        mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1);
37240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka        type(Constants.CODE_DELETE);
389159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard        assertEquals("press suggestion then backspace", EXPECTED_RESULT,
39d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
409159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard    }
419159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard
42bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard    public void testPickAutoCorrectionThenBackspace() {
43bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        final String WORD_TO_TYPE = "tgis";
44bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        final String WORD_TO_PICK = "this";
45f83a6821bbf3863415378ea39d3b705954318e41Jean Chalard        final String EXPECTED_RESULT = "thi";
46bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        type(WORD_TO_TYPE);
47bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        // Choose the auto-correction, which is always in position 0. For "tgis", the
48bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        // auto-correction should be "this".
499bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge        pickSuggestionManually(0, WORD_TO_PICK);
50bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1);
51bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        assertEquals("pick typed word over auto-correction then backspace", WORD_TO_PICK,
52d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
53240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka        type(Constants.CODE_DELETE);
54bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        assertEquals("pick typed word over auto-correction then backspace", EXPECTED_RESULT,
55d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
56bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard    }
57bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard
589159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard    public void testPickTypedWordOverAutoCorrectionThenBackspace() {
599159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard        final String WORD_TO_TYPE = "tgis";
60f83a6821bbf3863415378ea39d3b705954318e41Jean Chalard        final String EXPECTED_RESULT = "tgi";
619159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard        type(WORD_TO_TYPE);
629159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard        // Choose the typed word, which should be in position 1 (because position 0 should
639159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard        // be occupied by the "this" auto-correction, as checked by testAutoCorrect())
649bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge        pickSuggestionManually(1, WORD_TO_TYPE);
659159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard        mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1);
66bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        assertEquals("pick typed word over auto-correction then backspace", WORD_TO_TYPE,
67d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
68240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka        type(Constants.CODE_DELETE);
699159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard        assertEquals("pick typed word over auto-correction then backspace", EXPECTED_RESULT,
70d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
7183c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard    }
7283c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard
73bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard    public void testPickDifferentSuggestionThenBackspace() {
74bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        final String WORD_TO_TYPE = "tgis";
75bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        final String WORD_TO_PICK = "thus";
76f83a6821bbf3863415378ea39d3b705954318e41Jean Chalard        final String EXPECTED_RESULT = "thu";
77bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        type(WORD_TO_TYPE);
78bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        // Choose the second suggestion, which should be in position 2 and should be "thus"
79bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        // when "tgis is typed.
809bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge        pickSuggestionManually(2, WORD_TO_PICK);
81bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1);
82bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        assertEquals("pick different suggestion then backspace", WORD_TO_PICK,
83d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
84240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka        type(Constants.CODE_DELETE);
85bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        assertEquals("pick different suggestion then backspace", EXPECTED_RESULT,
86d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
87bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard    }
88bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard
891e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard    public void testDeleteSelection() {
901e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        final String STRING_TO_TYPE = "some text delete me some text";
912752287c425b9be87800136bd616ee63940caaacJean Chalard        final int typedLength = STRING_TO_TYPE.length();
921e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        final int SELECTION_START = 10;
931e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        final int SELECTION_END = 19;
941e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        final String EXPECTED_RESULT = "some text  some text";
951e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        type(STRING_TO_TYPE);
961e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        // There is no IMF to call onUpdateSelection for us so we must do it by hand.
971e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        // Send once to simulate the cursor actually responding to the move caused by typing.
981e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        // This is necessary because LatinIME is bookkeeping to avoid confusing a real cursor
991e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        // move with a move triggered by LatinIME inputting stuff.
1002752287c425b9be87800136bd616ee63940caaacJean Chalard        mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1);
1011e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        mInputConnection.setSelection(SELECTION_START, SELECTION_END);
1021e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard        // And now we simulate the user actually selecting some text.
1032752287c425b9be87800136bd616ee63940caaacJean Chalard        mLatinIME.onUpdateSelection(typedLength, typedLength,
1042752287c425b9be87800136bd616ee63940caaacJean Chalard                SELECTION_START, SELECTION_END, -1, -1);
105240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka        type(Constants.CODE_DELETE);
106d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka        assertEquals("delete selection", EXPECTED_RESULT, mEditText.getText().toString());
107516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard    }
108516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard
109516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard    public void testDeleteSelectionTwice() {
110516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        final String STRING_TO_TYPE = "some text delete me some text";
111516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        final int typedLength = STRING_TO_TYPE.length();
112516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        final int SELECTION_START = 10;
113516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        final int SELECTION_END = 19;
114516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        final String EXPECTED_RESULT = "some text some text";
115516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        type(STRING_TO_TYPE);
116516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        // There is no IMF to call onUpdateSelection for us so we must do it by hand.
117516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        // Send once to simulate the cursor actually responding to the move caused by typing.
118516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        // This is necessary because LatinIME is bookkeeping to avoid confusing a real cursor
119516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        // move with a move triggered by LatinIME inputting stuff.
120516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1);
121516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        mInputConnection.setSelection(SELECTION_START, SELECTION_END);
122516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        // And now we simulate the user actually selecting some text.
123516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        mLatinIME.onUpdateSelection(typedLength, typedLength,
124516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard                SELECTION_START, SELECTION_END, -1, -1);
125516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        type(Constants.CODE_DELETE);
126516b63db2866f144a00ec7e1e6c29cb0865f5ff3Jean Chalard        type(Constants.CODE_DELETE);
127d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka        assertEquals("delete selection twice", EXPECTED_RESULT, mEditText.getText().toString());
1281e4684ad24914cde713980bb4174810bbf8bae10Jean Chalard    }
1290bfe359ee42af9c4487ce56acf42c74a2510980dJean Chalard
1300bfe359ee42af9c4487ce56acf42c74a2510980dJean Chalard    public void testAutoCorrect() {
1310bfe359ee42af9c4487ce56acf42c74a2510980dJean Chalard        final String STRING_TO_TYPE = "tgis ";
1320bfe359ee42af9c4487ce56acf42c74a2510980dJean Chalard        final String EXPECTED_RESULT = "this ";
1330bfe359ee42af9c4487ce56acf42c74a2510980dJean Chalard        type(STRING_TO_TYPE);
134d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka        assertEquals("simple auto-correct", EXPECTED_RESULT, mEditText.getText().toString());
135bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard    }
136bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard
137e8f717943f7063444cd1c777e8dd03dc738f3c4aJean Chalard    public void testAutoCorrectWithQuote() {
138e8f717943f7063444cd1c777e8dd03dc738f3c4aJean Chalard        final String STRING_TO_TYPE = "didn' ";
139e8f717943f7063444cd1c777e8dd03dc738f3c4aJean Chalard        final String EXPECTED_RESULT = "didn't ";
140e8f717943f7063444cd1c777e8dd03dc738f3c4aJean Chalard        type(STRING_TO_TYPE);
141e8f717943f7063444cd1c777e8dd03dc738f3c4aJean Chalard        assertEquals("auto-correct with quote", EXPECTED_RESULT, mEditText.getText().toString());
142e8f717943f7063444cd1c777e8dd03dc738f3c4aJean Chalard    }
143e8f717943f7063444cd1c777e8dd03dc738f3c4aJean Chalard
144bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard    public void testAutoCorrectWithPeriod() {
145bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        final String STRING_TO_TYPE = "tgis.";
146bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        final String EXPECTED_RESULT = "this.";
147bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        type(STRING_TO_TYPE);
148d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka        assertEquals("auto-correct with period", EXPECTED_RESULT, mEditText.getText().toString());
149bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard    }
150bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard
151bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard    public void testAutoCorrectWithPeriodThenRevert() {
152bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        final String STRING_TO_TYPE = "tgis.";
153bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        final String EXPECTED_RESULT = "tgis.";
154bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        type(STRING_TO_TYPE);
155bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
156240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka        type(Constants.CODE_DELETE);
157bb15f92d4f80677587fae87fa2dd7a29ec465b4cJean Chalard        assertEquals("auto-correct with period then revert", EXPECTED_RESULT,
158d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
1590bfe359ee42af9c4487ce56acf42c74a2510980dJean Chalard    }
16060e7718462a8c7b025ac8375b585c1da3db1e1feJean Chalard
1610e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard    public void testAutoCorrectWithSpaceThenRevert() {
1620e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard        final String STRING_TO_TYPE = "tgis ";
1630e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard        final String EXPECTED_RESULT = "tgis ";
1640e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard        type(STRING_TO_TYPE);
1650e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard        mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
166240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka        type(Constants.CODE_DELETE);
1670e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard        assertEquals("auto-correct with space then revert", EXPECTED_RESULT,
168d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
1690e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard    }
1700e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard
1710e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard    public void testAutoCorrectToSelfDoesNotRevert() {
1720e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard        final String STRING_TO_TYPE = "this ";
1730e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard        final String EXPECTED_RESULT = "this";
1740e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard        type(STRING_TO_TYPE);
1750e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard        mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
176240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka        type(Constants.CODE_DELETE);
1770e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard        assertEquals("auto-correct with space does not revert", EXPECTED_RESULT,
178d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
1790e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard    }
1800e9e7e337defe97d4ede8c59d0e925f5401f9292Jean Chalard
18160e7718462a8c7b025ac8375b585c1da3db1e1feJean Chalard    public void testDoubleSpace() {
1828142fd83a6ed8dd6741579f724ebda9e2b70dd01Jean Chalard        // U+1F607 is an emoji
1838142fd83a6ed8dd6741579f724ebda9e2b70dd01Jean Chalard        final String[] STRINGS_TO_TYPE =
1848142fd83a6ed8dd6741579f724ebda9e2b70dd01Jean Chalard                new String[] { "this   ", "a+  ", "\u1F607  ", "..  ", ")  ", "(  ", "%  " };
1858142fd83a6ed8dd6741579f724ebda9e2b70dd01Jean Chalard        final String[] EXPECTED_RESULTS =
186eacb2be8feffc49e97ae174607b69e210540111dKen Wakasa                new String[] { "this.  ", "a+. ", "\u1F607. ", "..  ", "). ", "(  ", "%. " };
1878142fd83a6ed8dd6741579f724ebda9e2b70dd01Jean Chalard        for (int i = 0; i < STRINGS_TO_TYPE.length; ++i) {
1888142fd83a6ed8dd6741579f724ebda9e2b70dd01Jean Chalard            mEditText.setText("");
1898142fd83a6ed8dd6741579f724ebda9e2b70dd01Jean Chalard            type(STRINGS_TO_TYPE[i]);
1908142fd83a6ed8dd6741579f724ebda9e2b70dd01Jean Chalard            assertEquals("double space processing", EXPECTED_RESULTS[i],
1918142fd83a6ed8dd6741579f724ebda9e2b70dd01Jean Chalard                    mEditText.getText().toString());
1928142fd83a6ed8dd6741579f724ebda9e2b70dd01Jean Chalard        }
19360e7718462a8c7b025ac8375b585c1da3db1e1feJean Chalard    }
19460e7718462a8c7b025ac8375b585c1da3db1e1feJean Chalard
19560e7718462a8c7b025ac8375b585c1da3db1e1feJean Chalard    public void testCancelDoubleSpace() {
196fb684cebe8f5dac1bdb6cfa7085a07ddc66acedeJean Chalard        final String STRING_TO_TYPE = "this  ";
1977b8b6e4b42710a04dbda19a16b57f44a0c3caca9Jean Chalard        final String EXPECTED_RESULT = "this ";
19860e7718462a8c7b025ac8375b585c1da3db1e1feJean Chalard        type(STRING_TO_TYPE);
199240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka        type(Constants.CODE_DELETE);
200d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka        assertEquals("double space make a period", EXPECTED_RESULT, mEditText.getText().toString());
201a02e703289d2704963f140c44d630dcc0a65e34aJean Chalard    }
20241df8a98fd0b89de87c7531903262c75dc7e505bJean Chalard
20341df8a98fd0b89de87c7531903262c75dc7e505bJean Chalard    public void testBackspaceAtStartAfterAutocorrect() {
20441df8a98fd0b89de87c7531903262c75dc7e505bJean Chalard        final String STRING_TO_TYPE = "tgis ";
2052752287c425b9be87800136bd616ee63940caaacJean Chalard        final int typedLength = STRING_TO_TYPE.length();
20641df8a98fd0b89de87c7531903262c75dc7e505bJean Chalard        final String EXPECTED_RESULT = "this ";
20741df8a98fd0b89de87c7531903262c75dc7e505bJean Chalard        final int NEW_CURSOR_POSITION = 0;
20841df8a98fd0b89de87c7531903262c75dc7e505bJean Chalard        type(STRING_TO_TYPE);
2092752287c425b9be87800136bd616ee63940caaacJean Chalard        mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1);
21041df8a98fd0b89de87c7531903262c75dc7e505bJean Chalard        mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION);
2112752287c425b9be87800136bd616ee63940caaacJean Chalard        mLatinIME.onUpdateSelection(typedLength, typedLength,
2122752287c425b9be87800136bd616ee63940caaacJean Chalard                NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1);
213240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka        type(Constants.CODE_DELETE);
214fb684cebe8f5dac1bdb6cfa7085a07ddc66acedeJean Chalard        assertEquals("auto correct then move cursor to start of line then backspace",
215d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                EXPECTED_RESULT, mEditText.getText().toString());
21660e7718462a8c7b025ac8375b585c1da3db1e1feJean Chalard    }
2179184d8b2352e11a25026ea9eed7f404836a7d476Jean Chalard
2189184d8b2352e11a25026ea9eed7f404836a7d476Jean Chalard    public void testAutoCorrectThenMoveCursorThenBackspace() {
2199184d8b2352e11a25026ea9eed7f404836a7d476Jean Chalard        final String STRING_TO_TYPE = "and tgis ";
2202752287c425b9be87800136bd616ee63940caaacJean Chalard        final int typedLength = STRING_TO_TYPE.length();
2219184d8b2352e11a25026ea9eed7f404836a7d476Jean Chalard        final String EXPECTED_RESULT = "andthis ";
2229184d8b2352e11a25026ea9eed7f404836a7d476Jean Chalard        final int NEW_CURSOR_POSITION = STRING_TO_TYPE.indexOf('t');
2239184d8b2352e11a25026ea9eed7f404836a7d476Jean Chalard        type(STRING_TO_TYPE);
2242752287c425b9be87800136bd616ee63940caaacJean Chalard        mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1);
2259184d8b2352e11a25026ea9eed7f404836a7d476Jean Chalard        mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION);
2262752287c425b9be87800136bd616ee63940caaacJean Chalard        mLatinIME.onUpdateSelection(typedLength, typedLength,
2272752287c425b9be87800136bd616ee63940caaacJean Chalard                NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1);
228240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka        type(Constants.CODE_DELETE);
229fb684cebe8f5dac1bdb6cfa7085a07ddc66acedeJean Chalard        assertEquals("auto correct then move cursor then backspace",
230d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                EXPECTED_RESULT, mEditText.getText().toString());
2319184d8b2352e11a25026ea9eed7f404836a7d476Jean Chalard    }
232cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard
233cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard    public void testNoSpaceAfterManualPick() {
234cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        final String WORD_TO_TYPE = "this";
235cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        final String EXPECTED_RESULT = WORD_TO_TYPE;
236cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        type(WORD_TO_TYPE);
2379bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge        pickSuggestionManually(0, WORD_TO_TYPE);
238cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        assertEquals("no space after manual pick", EXPECTED_RESULT,
239d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
240cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard    }
241cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard
242cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard    public void testManualPickThenType() {
243cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        final String WORD1_TO_TYPE = "this";
244cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        final String WORD2_TO_TYPE = "is";
245cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        final String EXPECTED_RESULT = "this is";
246cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        type(WORD1_TO_TYPE);
2479bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge        pickSuggestionManually(0, WORD1_TO_TYPE);
248cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        type(WORD2_TO_TYPE);
249d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka        assertEquals("manual pick then type", EXPECTED_RESULT, mEditText.getText().toString());
250cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard    }
251cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard
252cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard    public void testManualPickThenSeparator() {
253cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        final String WORD1_TO_TYPE = "this";
254cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        final String WORD2_TO_TYPE = "!";
255cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        final String EXPECTED_RESULT = "this!";
256cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        type(WORD1_TO_TYPE);
2579bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge        pickSuggestionManually(0, WORD1_TO_TYPE);
258cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        type(WORD2_TO_TYPE);
259d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka        assertEquals("manual pick then separator", EXPECTED_RESULT, mEditText.getText().toString());
260cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard    }
261cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard
262f68fe7a9c9262a3591eeba61f34a91855a34c930Jean Chalard    public void testManualPickThenStripperThenPick() {
263f68fe7a9c9262a3591eeba61f34a91855a34c930Jean Chalard        final String WORD_TO_TYPE = "this";
264f68fe7a9c9262a3591eeba61f34a91855a34c930Jean Chalard        final String STRIPPER = "\n";
265f68fe7a9c9262a3591eeba61f34a91855a34c930Jean Chalard        final String EXPECTED_RESULT = "this\nthis";
266f68fe7a9c9262a3591eeba61f34a91855a34c930Jean Chalard        type(WORD_TO_TYPE);
267f68fe7a9c9262a3591eeba61f34a91855a34c930Jean Chalard        pickSuggestionManually(0, WORD_TO_TYPE);
268f68fe7a9c9262a3591eeba61f34a91855a34c930Jean Chalard        type(STRIPPER);
269f68fe7a9c9262a3591eeba61f34a91855a34c930Jean Chalard        type(WORD_TO_TYPE);
270f68fe7a9c9262a3591eeba61f34a91855a34c930Jean Chalard        pickSuggestionManually(0, WORD_TO_TYPE);
271f68fe7a9c9262a3591eeba61f34a91855a34c930Jean Chalard        assertEquals("manual pick then \\n then manual pick", EXPECTED_RESULT,
272d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
273f68fe7a9c9262a3591eeba61f34a91855a34c930Jean Chalard    }
274f68fe7a9c9262a3591eeba61f34a91855a34c930Jean Chalard
275cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard    public void testManualPickThenSpaceThenType() {
276cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        final String WORD1_TO_TYPE = "this";
277cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        final String WORD2_TO_TYPE = " is";
278cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        final String EXPECTED_RESULT = "this is";
279cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        type(WORD1_TO_TYPE);
2809bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge        pickSuggestionManually(0, WORD1_TO_TYPE);
281cca2183f5a9174b94e39e68fab9bc749c86743efJean Chalard        type(WORD2_TO_TYPE);
282845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard        assertEquals("manual pick then space then type", EXPECTED_RESULT,
283d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
284845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard    }
285845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard
286845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard    public void testManualPickThenManualPick() {
287845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard        final String WORD1_TO_TYPE = "this";
288845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard        final String WORD2_TO_PICK = "is";
289845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard        final String EXPECTED_RESULT = "this is";
290845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard        type(WORD1_TO_TYPE);
2919bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge        pickSuggestionManually(0, WORD1_TO_TYPE);
292845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard        // Here we fake picking a word through bigram prediction. This test is taking
293845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard        // advantage of the fact that Latin IME blindly trusts the caller of #pickSuggestionManually
294845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard        // to actually pass the right string.
2959bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge        pickSuggestionManually(1, WORD2_TO_PICK);
296845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard        assertEquals("manual pick then manual pick", EXPECTED_RESULT,
297d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka                mEditText.getText().toString());
298845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard    }
299845b24d9d31072b98958c557366617ad1c34f1b7Jean Chalard
300825e2bbd910cce3055a4ca808d3744bc0b2ceddaJean Chalard    public void testDeleteWholeComposingWord() {
301825e2bbd910cce3055a4ca808d3744bc0b2ceddaJean Chalard        final String WORD_TO_TYPE = "this";
302825e2bbd910cce3055a4ca808d3744bc0b2ceddaJean Chalard        type(WORD_TO_TYPE);
303825e2bbd910cce3055a4ca808d3744bc0b2ceddaJean Chalard        for (int i = 0; i < WORD_TO_TYPE.length(); ++i) {
304240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka            type(Constants.CODE_DELETE);
305825e2bbd910cce3055a4ca808d3744bc0b2ceddaJean Chalard        }
306d5781eef628c2cd4ac38029040746daa4679d637Satoshi Kataoka        assertEquals("delete whole composing word", "", mEditText.getText().toString());
307825e2bbd910cce3055a4ca808d3744bc0b2ceddaJean Chalard    }
308c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard
309c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard    public void testResumeSuggestionOnBackspace() {
310c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard        final String WORD_TO_TYPE = "and this ";
311c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard        type(WORD_TO_TYPE);
312c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard        assertEquals("resume suggestion on backspace", -1,
313c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard                BaseInputConnection.getComposingSpanStart(mEditText.getText()));
314c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard        assertEquals("resume suggestion on backspace", -1,
315c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard                BaseInputConnection.getComposingSpanEnd(mEditText.getText()));
316c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard        type(Constants.CODE_DELETE);
317c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard        assertEquals("resume suggestion on backspace", 4,
318c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard                BaseInputConnection.getComposingSpanStart(mEditText.getText()));
319c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard        assertEquals("resume suggestion on backspace", 8,
320c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard                BaseInputConnection.getComposingSpanEnd(mEditText.getText()));
321c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard    }
322e38097dc2ae31774d49142d619f7d57708369785Jean Chalard
323e38097dc2ae31774d49142d619f7d57708369785Jean Chalard    private void helperTestComposing(final String wordToType, final boolean shouldBeComposing) {
324e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        mEditText.setText("");
325e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        type(wordToType);
326e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        assertEquals("start composing inside text", shouldBeComposing ? 0 : -1,
327e38097dc2ae31774d49142d619f7d57708369785Jean Chalard                BaseInputConnection.getComposingSpanStart(mEditText.getText()));
328e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        assertEquals("start composing inside text", shouldBeComposing ? wordToType.length() : -1,
329e38097dc2ae31774d49142d619f7d57708369785Jean Chalard                BaseInputConnection.getComposingSpanEnd(mEditText.getText()));
330e38097dc2ae31774d49142d619f7d57708369785Jean Chalard    }
331e38097dc2ae31774d49142d619f7d57708369785Jean Chalard
332e38097dc2ae31774d49142d619f7d57708369785Jean Chalard    public void testStartComposing() {
333e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        // Should start composing on a letter
334e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        helperTestComposing("a", true);
335e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        type("  "); // To reset the composing state
336e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        // Should not start composing on quote
337e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        helperTestComposing("'", false);
338e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        type("  ");
339e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        helperTestComposing("'-", false);
340e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        type("  ");
341e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        // Should not start composing on dash
342e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        helperTestComposing("-", false);
343e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        type("  ");
344e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        helperTestComposing("-'", false);
345e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        type("  ");
346e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        helperTestComposing("a-", true);
347e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        type("  ");
348e38097dc2ae31774d49142d619f7d57708369785Jean Chalard        helperTestComposing("a'", true);
349e38097dc2ae31774d49142d619f7d57708369785Jean Chalard    }
3509159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard    // TODO: Add some tests for non-BMP characters
35183c72d1dae7e91ba8ae50d79b11b1c0dd67451c2Jean Chalard}
352