Home | History | Annotate | Download | only in latin
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.inputmethod.latin;
     18 
     19 import android.inputmethodservice.InputMethodService;
     20 import android.test.AndroidTestCase;
     21 import android.test.suitebuilder.annotation.SmallTest;
     22 import android.text.TextUtils;
     23 import android.view.inputmethod.ExtractedText;
     24 import android.view.inputmethod.ExtractedTextRequest;
     25 import android.view.inputmethod.InputConnection;
     26 import android.view.inputmethod.InputConnectionWrapper;
     27 
     28 import com.android.inputmethod.latin.RichInputConnection.Range;
     29 
     30 @SmallTest
     31 public class RichInputConnectionTests extends AndroidTestCase {
     32 
     33     // The following is meant to be a reasonable default for
     34     // the "word_separators" resource.
     35     private static final String sSeparators = ".,:;!?-";
     36 
     37     @Override
     38     protected void setUp() throws Exception {
     39         super.setUp();
     40     }
     41 
     42     private class MockConnection extends InputConnectionWrapper {
     43         final String mTextBefore;
     44         final String mTextAfter;
     45         final ExtractedText mExtractedText;
     46 
     47         public MockConnection(String textBefore, String textAfter, ExtractedText extractedText) {
     48             super(null, false);
     49             mTextBefore = textBefore;
     50             mTextAfter = textAfter;
     51             mExtractedText = extractedText;
     52         }
     53 
     54         /* (non-Javadoc)
     55          * @see android.view.inputmethod.InputConnectionWrapper#getTextBeforeCursor(int, int)
     56          */
     57         @Override
     58         public CharSequence getTextBeforeCursor(int n, int flags) {
     59             return mTextBefore;
     60         }
     61 
     62         /* (non-Javadoc)
     63          * @see android.view.inputmethod.InputConnectionWrapper#getTextAfterCursor(int, int)
     64          */
     65         @Override
     66         public CharSequence getTextAfterCursor(int n, int flags) {
     67             return mTextAfter;
     68         }
     69 
     70         /* (non-Javadoc)
     71          * @see android.view.inputmethod.InputConnectionWrapper#getExtractedText(
     72          *         ExtractedTextRequest, int)
     73          */
     74         @Override
     75         public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
     76             return mExtractedText;
     77         }
     78 
     79         @Override
     80         public boolean beginBatchEdit() {
     81             return true;
     82         }
     83 
     84         @Override
     85         public boolean endBatchEdit() {
     86             return true;
     87         }
     88 
     89         @Override
     90         public boolean finishComposingText() {
     91             return true;
     92         }
     93     }
     94 
     95     private class MockInputMethodService extends InputMethodService {
     96         InputConnection mInputConnection;
     97         public void setInputConnection(final InputConnection inputConnection) {
     98             mInputConnection = inputConnection;
     99         }
    100         @Override
    101         public InputConnection getCurrentInputConnection() {
    102             return mInputConnection;
    103         }
    104     }
    105 
    106     /************************** Tests ************************/
    107 
    108     /**
    109      * Test for getting previous word (for bigram suggestions)
    110      */
    111     public void testGetPreviousWord() {
    112         // If one of the following cases breaks, the bigram suggestions won't work.
    113         assertEquals(RichInputConnection.getNthPreviousWord("abc def", sSeparators, 2), "abc");
    114         assertNull(RichInputConnection.getNthPreviousWord("abc", sSeparators, 2));
    115         assertNull(RichInputConnection.getNthPreviousWord("abc. def", sSeparators, 2));
    116 
    117         // The following tests reflect the current behavior of the function
    118         // RichInputConnection#getNthPreviousWord.
    119         // TODO: However at this time, the code does never go
    120         // into such a path, so it should be safe to change the behavior of
    121         // this function if needed - especially since it does not seem very
    122         // logical. These tests are just there to catch any unintentional
    123         // changes in the behavior of the RichInputConnection#getPreviousWord method.
    124         assertEquals(RichInputConnection.getNthPreviousWord("abc def ", sSeparators, 2), "abc");
    125         assertEquals(RichInputConnection.getNthPreviousWord("abc def.", sSeparators, 2), "abc");
    126         assertEquals(RichInputConnection.getNthPreviousWord("abc def .", sSeparators, 2), "def");
    127         assertNull(RichInputConnection.getNthPreviousWord("abc ", sSeparators, 2));
    128 
    129         assertEquals(RichInputConnection.getNthPreviousWord("abc def", sSeparators, 1), "def");
    130         assertEquals(RichInputConnection.getNthPreviousWord("abc def ", sSeparators, 1), "def");
    131         assertNull(RichInputConnection.getNthPreviousWord("abc def.", sSeparators, 1));
    132         assertNull(RichInputConnection.getNthPreviousWord("abc def .", sSeparators, 1));
    133     }
    134 
    135     /**
    136      * Test logic in getting the word range at the cursor.
    137      */
    138     public void testGetWordRangeAtCursor() {
    139         ExtractedText et = new ExtractedText();
    140         final MockInputMethodService mockInputMethodService = new MockInputMethodService();
    141         final RichInputConnection ic = new RichInputConnection(mockInputMethodService);
    142         mockInputMethodService.setInputConnection(new MockConnection("word wo", "rd", et));
    143         et.startOffset = 0;
    144         et.selectionStart = 7;
    145         Range r;
    146 
    147         ic.beginBatchEdit();
    148         // basic case
    149         r = ic.getWordRangeAtCursor(" ", 0);
    150         assertTrue(TextUtils.equals("word", r.mWord));
    151 
    152         // more than one word
    153         r = ic.getWordRangeAtCursor(" ", 1);
    154         assertTrue(TextUtils.equals("word word", r.mWord));
    155         ic.endBatchEdit();
    156 
    157         // tab character instead of space
    158         mockInputMethodService.setInputConnection(new MockConnection("one\tword\two", "rd", et));
    159         ic.beginBatchEdit();
    160         r = ic.getWordRangeAtCursor("\t", 1);
    161         ic.endBatchEdit();
    162         assertTrue(TextUtils.equals("word\tword", r.mWord));
    163 
    164         // only one word doesn't go too far
    165         mockInputMethodService.setInputConnection(new MockConnection("one\tword\two", "rd", et));
    166         ic.beginBatchEdit();
    167         r = ic.getWordRangeAtCursor("\t", 1);
    168         ic.endBatchEdit();
    169         assertTrue(TextUtils.equals("word\tword", r.mWord));
    170 
    171         // tab or space
    172         mockInputMethodService.setInputConnection(new MockConnection("one word\two", "rd", et));
    173         ic.beginBatchEdit();
    174         r = ic.getWordRangeAtCursor(" \t", 1);
    175         ic.endBatchEdit();
    176         assertTrue(TextUtils.equals("word\tword", r.mWord));
    177 
    178         // tab or space multiword
    179         mockInputMethodService.setInputConnection(new MockConnection("one word\two", "rd", et));
    180         ic.beginBatchEdit();
    181         r = ic.getWordRangeAtCursor(" \t", 2);
    182         ic.endBatchEdit();
    183         assertTrue(TextUtils.equals("one word\tword", r.mWord));
    184 
    185         // splitting on supplementary character
    186         final String supplementaryChar = "\uD840\uDC8A";
    187         mockInputMethodService.setInputConnection(
    188                 new MockConnection("one word" + supplementaryChar + "wo", "rd", et));
    189         ic.beginBatchEdit();
    190         r = ic.getWordRangeAtCursor(supplementaryChar, 0);
    191         ic.endBatchEdit();
    192         assertTrue(TextUtils.equals("word", r.mWord));
    193     }
    194 }
    195