1 /* 2 * Copyright (C) 2008 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 android.widget; 18 19 import android.app.Activity; 20 import android.content.Intent; 21 import android.graphics.Paint; 22 import android.platform.test.annotations.Presubmit; 23 import android.test.ActivityInstrumentationTestCase2; 24 import android.test.suitebuilder.annotation.SmallTest; 25 import android.text.GetChars; 26 import android.text.Layout; 27 import android.text.Selection; 28 import android.text.Spannable; 29 import android.util.Log; 30 import android.view.View; 31 import java.util.Locale; 32 33 /** 34 * TextViewTest tests {@link TextView}. 35 */ 36 public class TextViewTest extends ActivityInstrumentationTestCase2<TextViewActivity> { 37 private static final String TAG = "TextViewTest"; 38 private TextView mTextView; 39 40 public TextViewTest() { 41 super(TextViewActivity.class); 42 } 43 44 @SmallTest 45 @Presubmit 46 public void testArray() throws Exception { 47 getActivity().runOnUiThread(new Runnable() { 48 @Override 49 public void run() { 50 mTextView = new TextView(getActivity()); 51 } 52 }); 53 getInstrumentation().waitForIdleSync(); 54 55 char[] c = new char[] { 'H', 'e', 'l', 'l', 'o', ' ', 56 'W', 'o', 'r', 'l', 'd', '!' }; 57 58 mTextView.setText(c, 1, 4); 59 CharSequence oldText = mTextView.getText(); 60 61 mTextView.setText(c, 4, 5); 62 CharSequence newText = mTextView.getText(); 63 64 assertTrue(newText == oldText); 65 66 assertEquals(5, newText.length()); 67 assertEquals('o', newText.charAt(0)); 68 assertEquals("o Wor", newText.toString()); 69 70 assertEquals(" Wo", newText.subSequence(1, 4)); 71 72 char[] c2 = new char[7]; 73 ((GetChars) newText).getChars(1, 4, c2, 2); 74 assertEquals('\0', c2[1]); 75 assertEquals(' ', c2[2]); 76 assertEquals('W', c2[3]); 77 assertEquals('o', c2[4]); 78 assertEquals('\0', c2[5]); 79 } 80 81 @SmallTest 82 public void testProcessTextActivityResultNonEditable() { 83 getActivity().runOnUiThread(new Runnable() { 84 @Override 85 public void run() { 86 mTextView = new TextView(getActivity()); 87 } 88 }); 89 getInstrumentation().waitForIdleSync(); 90 CharSequence originalText = "This is some text."; 91 mTextView.setText(originalText, TextView.BufferType.SPANNABLE); 92 assertEquals(originalText, mTextView.getText().toString()); 93 mTextView.setTextIsSelectable(true); 94 Selection.setSelection((Spannable) mTextView.getText(), 0, mTextView.getText().length()); 95 96 // We need to run this in the UI thread, as it will create a Toast. 97 getActivity().runOnUiThread(new Runnable() { 98 @Override 99 public void run() { 100 CharSequence newText = "Text is replaced."; 101 Intent data = new Intent(); 102 data.putExtra(Intent.EXTRA_PROCESS_TEXT, newText); 103 mTextView.onActivityResult(TextView.PROCESS_TEXT_REQUEST_CODE, Activity.RESULT_OK, data); 104 } 105 }); 106 getInstrumentation().waitForIdleSync(); 107 108 // This is a TextView, which can't be modified. Hence no change should have been made. 109 assertEquals(originalText, mTextView.getText().toString()); 110 } 111 112 @SmallTest 113 public void testProcessTextActivityResultEditable() { 114 getActivity().runOnUiThread(new Runnable() { 115 @Override 116 public void run() { 117 mTextView = new EditText(getActivity()); 118 } 119 }); 120 getInstrumentation().waitForIdleSync(); 121 CharSequence originalText = "This is some text."; 122 mTextView.setText(originalText, TextView.BufferType.SPANNABLE); 123 assertEquals(originalText, mTextView.getText().toString()); 124 mTextView.setTextIsSelectable(true); 125 Selection.setSelection(((EditText) mTextView).getText(), 0, mTextView.getText().length()); 126 127 CharSequence newText = "Text is replaced."; 128 Intent data = new Intent(); 129 data.putExtra(Intent.EXTRA_PROCESS_TEXT, newText); 130 mTextView.onActivityResult(TextView.PROCESS_TEXT_REQUEST_CODE, Activity.RESULT_OK, data); 131 132 assertEquals(newText, mTextView.getText().toString()); 133 } 134 135 @SmallTest 136 public void testProcessTextActivityResultCancel() { 137 getActivity().runOnUiThread(new Runnable() { 138 @Override 139 public void run() { 140 mTextView = new EditText(getActivity()); 141 } 142 }); 143 getInstrumentation().waitForIdleSync(); 144 CharSequence originalText = "This is some text."; 145 mTextView.setText(originalText, TextView.BufferType.SPANNABLE); 146 assertEquals(originalText, mTextView.getText().toString()); 147 mTextView.setTextIsSelectable(true); 148 Selection.setSelection(((EditText) mTextView).getText(), 0, mTextView.getText().length()); 149 150 CharSequence newText = "Text is replaced."; 151 Intent data = new Intent(); 152 data.putExtra(Intent.EXTRA_PROCESS_TEXT, newText); 153 mTextView.onActivityResult(TextView.PROCESS_TEXT_REQUEST_CODE, Activity.RESULT_CANCELED, 154 data); 155 156 assertEquals(originalText, mTextView.getText().toString()); 157 } 158 159 @SmallTest 160 public void testProcessTextActivityNoData() { 161 getActivity().runOnUiThread(new Runnable() { 162 @Override 163 public void run() { 164 mTextView = new EditText(getActivity()); 165 } 166 }); 167 getInstrumentation().waitForIdleSync(); 168 CharSequence originalText = "This is some text."; 169 mTextView.setText(originalText, TextView.BufferType.SPANNABLE); 170 assertEquals(originalText, mTextView.getText().toString()); 171 mTextView.setTextIsSelectable(true); 172 Selection.setSelection(((EditText) mTextView).getText(), 0, mTextView.getText().length()); 173 174 mTextView.onActivityResult(TextView.PROCESS_TEXT_REQUEST_CODE, Activity.RESULT_OK, null); 175 176 assertEquals(originalText, mTextView.getText().toString()); 177 } 178 179 @SmallTest 180 public void testHyphenationWidth() { 181 TextView textView = new TextView(getActivity()); 182 textView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL); 183 textView.setTextLocale(Locale.US); 184 185 Paint paint = textView.getPaint(); 186 187 String word = "thisissuperlonglongword"; 188 float wordWidth = paint.measureText(word, 0, word.length()); 189 190 StringBuilder sb = new StringBuilder(); 191 for (int i = 0; i < 100; ++i) { 192 sb.append(word); 193 sb.append(" "); 194 } 195 textView.setText(sb.toString()); 196 197 int width = (int)(wordWidth * 0.7); 198 int height = 4096; // enough for all text. 199 200 textView.measure( 201 View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), 202 View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)); 203 textView.layout(0, 0, width, height); 204 205 Layout layout = textView.getLayout(); 206 assertNotNull(layout); 207 208 int lineCount = layout.getLineCount(); 209 boolean hyphenationHappend = false; 210 for (int i = 0; i < lineCount; ++i) { 211 if (layout.getHyphen(i) != 1) { 212 continue; // Hyphantion does not happen. 213 } 214 hyphenationHappend = true; 215 216 int start = layout.getLineStart(i); 217 int end = layout.getLineEnd(i); 218 219 float withoutHyphenLength = paint.measureText(sb, start, end); 220 float withHyphenLength = layout.getLineWidth(i); 221 222 assertTrue("LineWidth should take account of hyphen length.", 223 withHyphenLength > withoutHyphenLength); 224 } 225 assertTrue("Hyphenation must happen on TextView narrower than the word width", 226 hyphenationHappend); 227 } 228 } 229