ChipsTest.java revision d71925073f008dccd8c4b65d5d66534e6451e64d
1/* 2 * Copyright (C) 2011 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 17package com.android.ex.chips; 18 19import android.content.Context; 20import android.test.AndroidTestCase; 21import android.text.Editable; 22import android.text.SpannableStringBuilder; 23import android.text.style.ImageSpan; 24import android.text.util.Rfc822Tokenizer; 25import android.widget.TextView; 26 27import com.android.ex.chips.RecipientEditTextView; 28import com.android.ex.chips.RecipientEntry; 29 30 31public class ChipsTest extends AndroidTestCase { 32 private RecipientChip[] mMockRecips; 33 34 private RecipientEntry[] mMockEntries; 35 36 private Rfc822Tokenizer mTokenizer; 37 38 private Editable mEditable; 39 40 class MockRecipientEditTextView extends RecipientEditTextView { 41 42 public MockRecipientEditTextView(Context context) { 43 super(context, null); 44 mTokenizer = new Rfc822Tokenizer(); 45 setTokenizer(mTokenizer); 46 } 47 48 @Override 49 public RecipientChip[] getSortedRecipients() { 50 return mMockRecips; 51 } 52 53 @Override 54 public Editable getText() { 55 return mEditable; 56 } 57 58 @Override 59 public Editable getSpannable() { 60 return mEditable; 61 } 62 63 @Override 64 public int getLineHeight() { 65 return 48; 66 } 67 } 68 69 private MockRecipientEditTextView createViewForTesting() { 70 mEditable = new SpannableStringBuilder(); 71 MockRecipientEditTextView view = new MockRecipientEditTextView(getContext()); 72 return view; 73 } 74 75 public void testCreateDisplayText() { 76 RecipientEditTextView view = createViewForTesting(); 77 RecipientEntry entry = RecipientEntry.constructGeneratedEntry("User Name, Jr", 78 "user@username.com"); 79 String test = view.createDisplayText(entry); 80 assertEquals("Expected a properly formatted RFC email address", 81 "\"User Name, Jr\" <user@username.com>, ", test); 82 83 RecipientEntry alreadyFormatted = RecipientEntry.constructFakeEntry("user@username.com, "); 84 test = view.createDisplayText(alreadyFormatted); 85 assertEquals("Expected a properly formatted RFC email address", "<user@username.com>, ", 86 test); 87 88 RecipientEntry alreadyFormattedNoSpace = RecipientEntry 89 .constructFakeEntry("user@username.com,"); 90 test = view.createDisplayText(alreadyFormattedNoSpace); 91 assertEquals("Expected a properly formatted RFC email address", "<user@username.com>, ", 92 test); 93 94 RecipientEntry alreadyNamed = RecipientEntry.constructGeneratedEntry("User Name", 95 "\"User Name, Jr\" <user@username.com>"); 96 test = view.createDisplayText(alreadyNamed); 97 assertEquals( 98 "Expected address that used the name not the excess address name", 99 "User Name <user@username.com>, ", test); 100 } 101 102 public void testSanitizeBetween() { 103 populateMocks(2); 104 MockRecipientEditTextView view = createViewForTesting(); 105 String first = (String) mTokenizer.terminateToken("FIRST"); 106 String second = (String) mTokenizer.terminateToken("SECOND"); 107 String extra = "EXTRA"; 108 mEditable = new SpannableStringBuilder(); 109 mEditable.append(first + extra + second); 110 int firstStart = mEditable.toString().indexOf(first); 111 int firstEnd = firstStart + first.trim().length(); 112 int secondStart = mEditable.toString().indexOf(second); 113 int secondEnd = secondStart + second.trim().length(); 114 mEditable.setSpan(mMockRecips[mMockRecips.length - 2], firstStart, firstEnd, 0); 115 mEditable.setSpan(mMockRecips[mMockRecips.length - 1], secondStart, secondEnd, 0); 116 view.sanitizeBetween(); 117 String editableString = mEditable.toString(); 118 assertEquals(editableString.indexOf(extra), -1); 119 assertEquals(editableString.indexOf(first), firstStart); 120 assertEquals(editableString.indexOf(second), secondStart - extra.length()); 121 assertEquals(editableString, (first + second)); 122 123 mEditable = new SpannableStringBuilder(); 124 populateMocks(1); 125 mEditable.append(extra); 126 mEditable.append(first); 127 firstStart = mEditable.toString().indexOf(first); 128 firstEnd = firstStart + first.length(); 129 mEditable.setSpan(mMockRecips[mMockRecips.length - 1], firstStart, firstEnd, 0); 130 view.sanitizeBetween(); 131 assertEquals(mEditable.toString(), first); 132 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), firstStart 133 - extra.length()); 134 } 135 136 public void testMoreChip() { 137 populateMocks(3); 138 MockRecipientEditTextView view = createViewForTesting(); 139 view.setMoreItem(createTestMoreItem()); 140 String first = (String) mTokenizer.terminateToken("FIRST"); 141 String second = (String) mTokenizer.terminateToken("SECOND"); 142 String third = (String) mTokenizer.terminateToken("THIRD"); 143 mEditable = new SpannableStringBuilder(); 144 mEditable.append(first+second+third); 145 146 int firstStart = mEditable.toString().indexOf(first); 147 int firstEnd = firstStart + first.trim().length(); 148 int secondStart = mEditable.toString().indexOf(second); 149 int secondEnd = secondStart + second.trim().length(); 150 int thirdStart = mEditable.toString().indexOf(third); 151 int thirdEnd = thirdStart + third.trim().length(); 152 mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0); 153 mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0); 154 mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0); 155 156 view.createMoreChip(); 157 assertEquals(mEditable.toString(), first+second+third); 158 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart); 159 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart); 160 // Find the more chip. 161 ImageSpan moreChip = view.getMoreChip(); 162 assertEquals(mEditable.getSpanStart(moreChip), thirdStart); 163 assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd); 164 165 view.removeMoreChip(); 166 assertEquals(mEditable.toString(), first+second+third); 167 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart); 168 assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd); 169 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart); 170 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart); 171 assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd); 172 moreChip = view.getMoreChip(); 173 assertEquals(mEditable.getSpanStart(moreChip), -1); 174 175 // Rinse and repeat, just in case! 176 view.createMoreChip(); 177 assertEquals(mEditable.toString(), first+second+third); 178 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart); 179 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart); 180 // Find the more chip. 181 moreChip = view.getMoreChip(); 182 assertEquals(mEditable.getSpanStart(moreChip), thirdStart); 183 assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd); 184 185 view.removeMoreChip(); 186 assertEquals(mEditable.toString(), first+second+third); 187 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart); 188 assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd); 189 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart); 190 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart); 191 assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd); 192 moreChip = view.getMoreChip(); 193 assertEquals(mEditable.getSpanStart(moreChip), -1); 194 } 195 196 public void testMoreChipLotsOfUsers() { 197 populateMocks(10); 198 MockRecipientEditTextView view = createViewForTesting(); 199 view.setMoreItem(createTestMoreItem()); 200 String first = (String) mTokenizer.terminateToken("FIRST"); 201 String second = (String) mTokenizer.terminateToken("SECOND"); 202 String third = (String) mTokenizer.terminateToken("THIRD"); 203 String fourth = (String) mTokenizer.terminateToken("FOURTH"); 204 String fifth = (String) mTokenizer.terminateToken("FIFTH"); 205 String sixth = (String) mTokenizer.terminateToken("SIXTH"); 206 String seventh = (String) mTokenizer.terminateToken("SEVENTH"); 207 String eigth = (String) mTokenizer.terminateToken("EIGHTH"); 208 String ninth = (String) mTokenizer.terminateToken("NINTH"); 209 String tenth = (String) mTokenizer.terminateToken("TENTH"); 210 mEditable = new SpannableStringBuilder(); 211 mEditable.append(first+second+third+fourth+fifth+sixth+seventh+eigth+ninth+tenth); 212 213 int firstStart = mEditable.toString().indexOf(first); 214 int firstEnd = firstStart + first.trim().length(); 215 int secondStart = mEditable.toString().indexOf(second); 216 int secondEnd = secondStart + second.trim().length(); 217 int thirdStart = mEditable.toString().indexOf(third); 218 int thirdEnd = thirdStart + third.trim().length(); 219 int fourthStart = mEditable.toString().indexOf(fourth); 220 int fourthEnd = fourthStart + fourth.trim().length(); 221 int fifthStart = mEditable.toString().indexOf(fifth); 222 int fifthEnd = fifthStart + fifth.trim().length(); 223 int sixthStart = mEditable.toString().indexOf(sixth); 224 int sixthEnd = sixthStart + sixth.trim().length(); 225 int seventhStart = mEditable.toString().indexOf(seventh); 226 int seventhEnd = seventhStart + seventh.trim().length(); 227 int eighthStart = mEditable.toString().indexOf(eigth); 228 int eighthEnd = eighthStart + eigth.trim().length(); 229 int ninthStart = mEditable.toString().indexOf(ninth); 230 int ninthEnd = ninthStart + ninth.trim().length(); 231 int tenthStart = mEditable.toString().indexOf(tenth); 232 int tenthEnd = tenthStart + tenth.trim().length(); 233 mEditable.setSpan(mMockRecips[mMockRecips.length - 10], firstStart, firstEnd, 0); 234 mEditable.setSpan(mMockRecips[mMockRecips.length - 9], secondStart, secondEnd, 0); 235 mEditable.setSpan(mMockRecips[mMockRecips.length - 8], thirdStart, thirdEnd, 0); 236 mEditable.setSpan(mMockRecips[mMockRecips.length - 7], fourthStart, fourthEnd, 0); 237 mEditable.setSpan(mMockRecips[mMockRecips.length - 6], fifthStart, fifthEnd, 0); 238 mEditable.setSpan(mMockRecips[mMockRecips.length - 5], sixthStart, sixthEnd, 0); 239 mEditable.setSpan(mMockRecips[mMockRecips.length - 4], seventhStart, seventhEnd, 0); 240 mEditable.setSpan(mMockRecips[mMockRecips.length - 3], eighthStart, eighthEnd, 0); 241 mEditable.setSpan(mMockRecips[mMockRecips.length - 2], ninthStart, ninthEnd, 0); 242 mEditable.setSpan(mMockRecips[mMockRecips.length - 1], tenthStart, tenthEnd, 0); 243 244 view.createMoreChip(); 245 assertEquals(mEditable.toString(), first + second + third + fourth + fifth + sixth 246 + seventh + eigth + ninth + tenth); 247 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 10]), firstStart); 248 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 9]), secondStart); 249 // Find the more chip. 250 ImageSpan moreChip = view.getMoreChip(); 251 assertEquals(mEditable.getSpanStart(moreChip), thirdStart); 252 assertEquals(mEditable.getSpanEnd(moreChip), tenthEnd); 253 254 view.removeMoreChip(); 255 assertEquals(mEditable.toString(), first + second + third + fourth + fifth + sixth 256 + seventh + eigth + ninth + tenth); 257 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 10]), firstStart); 258 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 9]), secondStart); 259 260 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 8]), thirdStart); 261 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 7]), fourthStart); 262 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 6]), fifthStart); 263 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 5]), sixthStart); 264 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), seventhStart); 265 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), eighthStart); 266 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), ninthStart); 267 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), tenthStart); 268 moreChip = view.getMoreChip(); 269 assertEquals(mEditable.getSpanStart(moreChip), -1); 270 271 } 272 273 public void testMoreChipSpecialChars() { 274 populateMocks(3); 275 MockRecipientEditTextView view = createViewForTesting(); 276 view.setMoreItem(createTestMoreItem()); 277 String first = (String) mTokenizer.terminateToken("FI,RST"); 278 String second = (String) mTokenizer.terminateToken("SE,COND"); 279 String third = (String) mTokenizer.terminateToken("THI,RD"); 280 mEditable = new SpannableStringBuilder(); 281 mEditable.append(first+second+third); 282 283 int firstStart = mEditable.toString().indexOf(first); 284 int firstEnd = firstStart + first.trim().length(); 285 int secondStart = mEditable.toString().indexOf(second); 286 int secondEnd = secondStart + second.trim().length(); 287 int thirdStart = mEditable.toString().indexOf(third); 288 int thirdEnd = thirdStart + third.trim().length(); 289 mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0); 290 mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0); 291 mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0); 292 293 view.createMoreChip(); 294 assertEquals(mEditable.toString(), first+second+third); 295 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart); 296 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart); 297 // Find the more chip. 298 ImageSpan moreChip = view.getMoreChip(); 299 assertEquals(mEditable.getSpanStart(moreChip), thirdStart); 300 assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd); 301 302 view.removeMoreChip(); 303 assertEquals(mEditable.toString(), first+second+third); 304 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart); 305 assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd); 306 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart); 307 assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart); 308 assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd); 309 moreChip = view.getMoreChip(); 310 assertEquals(mEditable.getSpanStart(moreChip), -1); 311 } 312 313 private TextView createTestMoreItem() { 314 TextView view = new TextView(getContext()); 315 view.setText("<xliff:g id='count'>%1$s</xliff:g> more..."); 316 return view; 317 } 318 319 private void populateMocks(int size) { 320 mMockEntries = new RecipientEntry[size]; 321 for (int i = 0; i < size; i++) { 322 mMockEntries[i] = RecipientEntry.constructGeneratedEntry("user", 323 "user@username.com"); 324 } 325 mMockRecips = new RecipientChip[size]; 326 for (int i = 0; i < size; i++) { 327 mMockRecips[i] = new RecipientChip(null, mMockEntries[i], i); 328 } 329 } 330} 331