ChipsTest.java revision 3ff3589ef691918ae7b3e96412c6064c6daccbf5
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.graphics.Bitmap;
21import android.graphics.drawable.BitmapDrawable;
22import android.graphics.drawable.Drawable;
23import android.test.AndroidTestCase;
24import android.test.suitebuilder.annotation.SmallTest;
25import android.text.Editable;
26import android.text.SpannableStringBuilder;
27import android.text.style.ImageSpan;
28import android.text.util.Rfc822Tokenizer;
29import android.widget.TextView;
30
31import com.android.ex.chips.RecipientEditTextView;
32import com.android.ex.chips.RecipientEntry;
33
34@SmallTest
35public class ChipsTest extends AndroidTestCase {
36    private RecipientChip[] mMockRecips;
37
38    private RecipientEntry[] mMockEntries;
39
40    private Rfc822Tokenizer mTokenizer;
41
42    private Editable mEditable;
43
44    class BaseMockRecipientEditTextView extends RecipientEditTextView {
45
46        public BaseMockRecipientEditTextView(Context context) {
47            super(context, null);
48            mTokenizer = new Rfc822Tokenizer();
49            setTokenizer(mTokenizer);
50        }
51
52        @Override
53        public RecipientChip[] getSortedRecipients() {
54            return mMockRecips;
55        }
56
57        @Override
58        public int getLineHeight() {
59            return 48;
60        }
61
62        @Override
63        Drawable getChipBackground(RecipientEntry contact) {
64            return createChipBackground();
65        }
66
67        @Override
68        public int getViewWidth() {
69            return 100;
70        }
71    }
72
73    class MockRecipientEditTextView extends BaseMockRecipientEditTextView {
74
75        public MockRecipientEditTextView(Context context) {
76            super(context);
77            mTokenizer = new Rfc822Tokenizer();
78            setTokenizer(mTokenizer);
79        }
80
81        @Override
82        public RecipientChip[] getSortedRecipients() {
83            return mMockRecips;
84        }
85
86        @Override
87        public Editable getText() {
88            return mEditable;
89        }
90
91        @Override
92        public Editable getSpannable() {
93            return mEditable;
94        }
95
96        @Override
97        public int getLineHeight() {
98            return 48;
99        }
100
101        @Override
102        Drawable getChipBackground(RecipientEntry contact) {
103            return createChipBackground();
104        }
105
106        @Override
107        public int length() {
108            return mEditable != null ? mEditable.length() : 0;
109        }
110
111        @Override
112        public String toString() {
113            return mEditable != null ? mEditable.toString() : "";
114        }
115
116        @Override
117        public int getViewWidth() {
118            return 100;
119        }
120    }
121
122    private class TestBaseRecipientAdapter extends BaseRecipientAdapter {
123        public TestBaseRecipientAdapter(Context context) {
124            super(context);
125        }
126    }
127
128    private MockRecipientEditTextView createViewForTesting() {
129        mEditable = new SpannableStringBuilder();
130        MockRecipientEditTextView view = new MockRecipientEditTextView(getContext());
131        view.setAdapter(new TestBaseRecipientAdapter(getContext()));
132        return view;
133    }
134
135    public void testCreateDisplayText() {
136        RecipientEditTextView view = createViewForTesting();
137        RecipientEntry entry = RecipientEntry.constructGeneratedEntry("User Name, Jr",
138                "user@username.com", true);
139        String testAddress = view.createAddressText(entry);
140        String testDisplay = view.createChipDisplayText(entry);
141        assertEquals("Expected a properly formatted RFC email address",
142                "\"User Name, Jr\" <user@username.com>, ", testAddress);
143        assertEquals("Expected a displayable name", "User Name, Jr", testDisplay);
144
145
146        RecipientEntry alreadyFormatted =
147                RecipientEntry.constructFakeEntry("user@username.com, ", true);
148        testAddress = view.createAddressText(alreadyFormatted);
149        testDisplay = view.createChipDisplayText(alreadyFormatted);
150        assertEquals("Expected a properly formatted RFC email address", "<user@username.com>, ",
151                testAddress);
152        assertEquals("Expected a displayable name", "user@username.com", testDisplay);
153
154        RecipientEntry alreadyFormattedNoSpace = RecipientEntry
155                .constructFakeEntry("user@username.com,", true);
156        testAddress = view.createAddressText(alreadyFormattedNoSpace);
157        assertEquals("Expected a properly formatted RFC email address", "<user@username.com>, ",
158                testAddress);
159
160        RecipientEntry alreadyNamed = RecipientEntry.constructGeneratedEntry("User Name",
161                "\"User Name, Jr\" <user@username.com>", true);
162        testAddress = view.createAddressText(alreadyNamed);
163        testDisplay = view.createChipDisplayText(alreadyNamed);
164        assertEquals(
165                "Expected address that used the name not the excess address name",
166                "User Name <user@username.com>, ", testAddress);
167        assertEquals("Expected a displayable name", "User Name", testDisplay);
168    }
169
170    public void testSanitizeBetween() {
171        // First, add 2 chips and then make sure we remove
172        // the extra content between them correctly.
173        populateMocks(2);
174        MockRecipientEditTextView view = createViewForTesting();
175        String first = (String) mTokenizer.terminateToken("FIRST");
176        String second = (String) mTokenizer.terminateToken("SECOND");
177        String extra = "EXTRA";
178        mEditable = new SpannableStringBuilder();
179        mEditable.append(first + extra + second);
180        int firstStart = mEditable.toString().indexOf(first);
181        int firstEnd = firstStart + first.trim().length();
182        int secondStart = mEditable.toString().indexOf(second);
183        int secondEnd = secondStart + second.trim().length();
184        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], firstStart, firstEnd, 0);
185        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], secondStart, secondEnd, 0);
186        view.sanitizeBetween();
187        String editableString = mEditable.toString();
188        assertEquals(editableString.indexOf(extra), -1);
189        assertEquals(editableString.indexOf(first), firstStart);
190        assertEquals(editableString.indexOf(second), secondStart - extra.length());
191        assertEquals(editableString, (first + second));
192
193        // Add 1 chip and make sure that we remove the extra stuff before it correctly.
194        mEditable = new SpannableStringBuilder();
195        populateMocks(1);
196        mEditable.append(extra);
197        mEditable.append(first);
198        firstStart = mEditable.toString().indexOf(first);
199        firstEnd = firstStart + first.length();
200        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], firstStart, firstEnd, 0);
201        view.sanitizeBetween();
202        assertEquals(mEditable.toString(), first);
203        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), firstStart
204                - extra.length());
205    }
206
207    public void testSanitizeEnd() {
208        // First, add 2 chips and then make sure we remove
209        // the extra content between them correctly.
210        populateMocks(2);
211        MockRecipientEditTextView view = createViewForTesting();
212        String first = (String) mTokenizer.terminateToken("FIRST");
213        String second = (String) mTokenizer.terminateToken("SECOND");
214        String extra = "EXTRA";
215        mEditable = new SpannableStringBuilder();
216        mEditable.append(first + second);
217        int firstStart = mEditable.toString().indexOf(first);
218        int firstEnd = firstStart + first.trim().length();
219        int secondStart = mEditable.toString().indexOf(second);
220        int secondEnd = secondStart + second.trim().length();
221        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], firstStart, firstEnd, 0);
222        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], secondStart, secondEnd, 0);
223        view.sanitizeEnd();
224        String editableString = mEditable.toString();
225        assertEquals(editableString.indexOf(extra), -1);
226        assertEquals(editableString.indexOf(first), firstStart);
227        assertEquals(editableString.indexOf(second), secondStart);
228        assertEquals(editableString, (first + second));
229        mEditable.append(extra);
230        editableString = mEditable.toString();
231        assertEquals(mEditable.toString(), (first + second + extra));
232        view.sanitizeEnd();
233        assertEquals(mEditable.toString(), (first + second));
234    }
235
236    public void testMoreChipPlainText() {
237        MockRecipientEditTextView view = createViewForTesting();
238        view.setMoreItem(createTestMoreItem());
239        String first = (String) mTokenizer.terminateToken("FIRST");
240        String second = (String) mTokenizer.terminateToken("SECOND");
241        String third = (String) mTokenizer.terminateToken("THIRD");
242        mEditable = new SpannableStringBuilder();
243        mEditable.append(first+second+third);
244        int thirdStart = mEditable.toString().indexOf(third);
245        int thirdEnd = thirdStart + third.trim().length();
246        view.createMoreChipPlainText();
247        ImageSpan moreChip = view.getMoreChip();
248        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
249        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
250    }
251
252    public void testCountTokens() {
253        MockRecipientEditTextView view = createViewForTesting();
254        view.setMoreItem(createTestMoreItem());
255        String first = (String) mTokenizer.terminateToken("FIRST");
256        String second = (String) mTokenizer.terminateToken("SECOND");
257        String third = (String) mTokenizer.terminateToken("THIRD");
258        String fourth = (String) ("FOURTH,");
259        String fifth = (String) ("FIFTH,");
260        mEditable = new SpannableStringBuilder();
261        mEditable.append(first+second+third+fourth+fifth);
262        assertEquals(view.countTokens(mEditable), 5);
263    }
264
265    public void testTooManyRecips() {
266        BaseMockRecipientEditTextView view = new BaseMockRecipientEditTextView(getContext());
267        view.setMoreItem(createTestMoreItem());
268        for (int i = 0; i < 100; i++) {
269            view.append(mTokenizer.terminateToken(i + ""));
270        }
271        assertEquals(view.countTokens(view.getText()), 100);
272        view.handlePendingChips();
273        view.createMoreChip();
274        ImageSpan moreChip = view.getMoreChip();
275        // We show 2 chips then place a more chip.
276        int secondStart = view.getText().toString().indexOf(
277                (String) mTokenizer.terminateToken(RecipientEditTextView.CHIP_LIMIT + ""));
278        assertEquals(view.getText().getSpanStart(moreChip), secondStart);
279        assertEquals(view.getText().getSpanEnd(moreChip), view.length());
280        assertEquals(view.getSortedRecipients(), null);
281    }
282
283    public void testMoreChip() {
284        // Add 3 chips: this is the trigger point at which the more chip will be created.
285        // Test that adding the chips and then creating and removing the more chip, as if
286        // the user were focusing/ removing focus from the chips field.
287        populateMocks(3);
288        MockRecipientEditTextView view = createViewForTesting();
289        view.setMoreItem(createTestMoreItem());
290        String first = (String) mTokenizer.terminateToken("FIRST");
291        String second = (String) mTokenizer.terminateToken("SECOND");
292        String third = (String) mTokenizer.terminateToken("THIRD");
293        mEditable = new SpannableStringBuilder();
294        mEditable.append(first+second+third);
295
296        int firstStart = mEditable.toString().indexOf(first);
297        int firstEnd = firstStart + first.trim().length();
298        int secondStart = mEditable.toString().indexOf(second);
299        int secondEnd = secondStart + second.trim().length();
300        int thirdStart = mEditable.toString().indexOf(third);
301        int thirdEnd = thirdStart + third.trim().length();
302        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
303        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
304        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
305
306        view.createMoreChip();
307        assertEquals(mEditable.toString(), first+second+third);
308        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
309        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
310        // Find the more chip.
311        ImageSpan moreChip = view.getMoreChip();
312        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
313        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
314
315        view.removeMoreChip();
316        assertEquals(mEditable.toString(), first+second+third);
317        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
318        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
319        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
320        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
321        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
322        moreChip = view.getMoreChip();
323        assertEquals(mEditable.getSpanStart(moreChip), -1);
324
325        // Rinse and repeat, just in case!
326        view.createMoreChip();
327        assertEquals(mEditable.toString(), first+second+third);
328        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
329        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
330        // Find the more chip.
331        moreChip = view.getMoreChip();
332        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
333        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
334
335        view.removeMoreChip();
336        assertEquals(mEditable.toString(), first+second+third);
337        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
338        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
339        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
340        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
341        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
342        moreChip = view.getMoreChip();
343        assertEquals(mEditable.getSpanStart(moreChip), -1);
344    }
345
346    public void testMoreChipLotsOfUsers() {
347        // Test adding and removing the more chip in the case where we have a lot of users.
348        populateMocks(10);
349        MockRecipientEditTextView view = createViewForTesting();
350        view.setMoreItem(createTestMoreItem());
351        String first = (String) mTokenizer.terminateToken("FIRST");
352        String second = (String) mTokenizer.terminateToken("SECOND");
353        String third = (String) mTokenizer.terminateToken("THIRD");
354        String fourth = (String) mTokenizer.terminateToken("FOURTH");
355        String fifth = (String) mTokenizer.terminateToken("FIFTH");
356        String sixth = (String) mTokenizer.terminateToken("SIXTH");
357        String seventh = (String) mTokenizer.terminateToken("SEVENTH");
358        String eigth = (String) mTokenizer.terminateToken("EIGHTH");
359        String ninth = (String) mTokenizer.terminateToken("NINTH");
360        String tenth = (String) mTokenizer.terminateToken("TENTH");
361        mEditable = new SpannableStringBuilder();
362        mEditable.append(first+second+third+fourth+fifth+sixth+seventh+eigth+ninth+tenth);
363
364        int firstStart = mEditable.toString().indexOf(first);
365        int firstEnd = firstStart + first.trim().length();
366        int secondStart = mEditable.toString().indexOf(second);
367        int secondEnd = secondStart + second.trim().length();
368        int thirdStart = mEditable.toString().indexOf(third);
369        int thirdEnd = thirdStart + third.trim().length();
370        int fourthStart = mEditable.toString().indexOf(fourth);
371        int fourthEnd = fourthStart + fourth.trim().length();
372        int fifthStart = mEditable.toString().indexOf(fifth);
373        int fifthEnd = fifthStart + fifth.trim().length();
374        int sixthStart = mEditable.toString().indexOf(sixth);
375        int sixthEnd = sixthStart + sixth.trim().length();
376        int seventhStart = mEditable.toString().indexOf(seventh);
377        int seventhEnd = seventhStart + seventh.trim().length();
378        int eighthStart = mEditable.toString().indexOf(eigth);
379        int eighthEnd = eighthStart + eigth.trim().length();
380        int ninthStart = mEditable.toString().indexOf(ninth);
381        int ninthEnd = ninthStart + ninth.trim().length();
382        int tenthStart = mEditable.toString().indexOf(tenth);
383        int tenthEnd = tenthStart + tenth.trim().length();
384        mEditable.setSpan(mMockRecips[mMockRecips.length - 10], firstStart, firstEnd, 0);
385        mEditable.setSpan(mMockRecips[mMockRecips.length - 9], secondStart, secondEnd, 0);
386        mEditable.setSpan(mMockRecips[mMockRecips.length - 8], thirdStart, thirdEnd, 0);
387        mEditable.setSpan(mMockRecips[mMockRecips.length - 7], fourthStart, fourthEnd, 0);
388        mEditable.setSpan(mMockRecips[mMockRecips.length - 6], fifthStart, fifthEnd, 0);
389        mEditable.setSpan(mMockRecips[mMockRecips.length - 5], sixthStart, sixthEnd, 0);
390        mEditable.setSpan(mMockRecips[mMockRecips.length - 4], seventhStart, seventhEnd, 0);
391        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], eighthStart, eighthEnd, 0);
392        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], ninthStart, ninthEnd, 0);
393        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], tenthStart, tenthEnd, 0);
394
395        view.createMoreChip();
396        assertEquals(mEditable.toString(), first + second + third + fourth + fifth + sixth
397                + seventh + eigth + ninth + tenth);
398        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 10]), firstStart);
399        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 9]), secondStart);
400        // Find the more chip.
401        ImageSpan moreChip = view.getMoreChip();
402        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
403        assertEquals(mEditable.getSpanEnd(moreChip), tenthEnd + 1);
404
405        view.removeMoreChip();
406        assertEquals(mEditable.toString(), first + second + third + fourth + fifth + sixth
407                + seventh + eigth + ninth + tenth);
408        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 10]), firstStart);
409        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 9]), secondStart);
410
411        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 8]), thirdStart);
412        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 7]), fourthStart);
413        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 6]), fifthStart);
414        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 5]), sixthStart);
415        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), seventhStart);
416        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), eighthStart);
417        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), ninthStart);
418        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), tenthStart);
419        moreChip = view.getMoreChip();
420        assertEquals(mEditable.getSpanStart(moreChip), -1);
421
422    }
423
424    public void testMoreChipSpecialChars() {
425        // Make sure the more chip correctly handles extra tokenizer characters in the middle
426        // of chip text.
427        populateMocks(3);
428        MockRecipientEditTextView view = createViewForTesting();
429        view.setMoreItem(createTestMoreItem());
430        String first = (String) mTokenizer.terminateToken("FI,RST");
431        String second = (String) mTokenizer.terminateToken("SE,COND");
432        String third = (String) mTokenizer.terminateToken("THI,RD");
433        mEditable = new SpannableStringBuilder();
434        mEditable.append(first+second+third);
435
436        int firstStart = mEditable.toString().indexOf(first);
437        int firstEnd = firstStart + first.trim().length();
438        int secondStart = mEditable.toString().indexOf(second);
439        int secondEnd = secondStart + second.trim().length();
440        int thirdStart = mEditable.toString().indexOf(third);
441        int thirdEnd = thirdStart + third.trim().length();
442        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
443        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
444        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
445
446        view.createMoreChip();
447        assertEquals(mEditable.toString(), first+second+third);
448        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
449        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
450        // Find the more chip.
451        ImageSpan moreChip = view.getMoreChip();
452        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
453        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
454
455        view.removeMoreChip();
456        assertEquals(mEditable.toString(), first+second+third);
457        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
458        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
459        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
460        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
461        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
462        moreChip = view.getMoreChip();
463        assertEquals(mEditable.getSpanStart(moreChip), -1);
464    }
465
466    public void testMoreChipDupes() {
467        // Make sure the more chip is correctly added and removed when we have duplicate chips.
468        populateMocks(4);
469        MockRecipientEditTextView view = createViewForTesting();
470        view.setMoreItem(createTestMoreItem());
471        String first = (String) mTokenizer.terminateToken("FIRST");
472        String second = (String) mTokenizer.terminateToken("SECOND");
473        String third = (String) mTokenizer.terminateToken("THIRD");
474        mEditable = new SpannableStringBuilder();
475        mEditable.append(first+second+third+third);
476
477        int firstStart = mEditable.toString().indexOf(first);
478        int firstEnd = firstStart + first.trim().length();
479        int secondStart = mEditable.toString().indexOf(second);
480        int secondEnd = secondStart + second.trim().length();
481        int thirdStart = mEditable.toString().indexOf(third);
482        int thirdEnd = thirdStart + third.trim().length();
483        int thirdNextStart = mEditable.toString().indexOf(third, thirdEnd);
484        int thirdNextEnd = thirdNextStart + third.trim().length();
485        mEditable.setSpan(mMockRecips[mMockRecips.length - 4], firstStart, firstEnd, 0);
486        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], secondStart, secondEnd, 0);
487        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], thirdStart, thirdEnd, 0);
488        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdNextStart, thirdNextEnd, 0);
489
490        view.createMoreChip();
491        assertEquals(mEditable.toString(), first+second+third+third);
492        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), firstStart);
493        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), secondStart);
494        // Find the more chip.
495        ImageSpan moreChip = view.getMoreChip();
496        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
497        assertEquals(mEditable.getSpanEnd(moreChip), thirdNextEnd + 1);
498
499        view.removeMoreChip();
500        assertEquals(mEditable.toString(), first+second+third+third);
501        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), firstStart);
502        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 4]), firstEnd);
503        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), secondStart);
504        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), thirdStart);
505        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), thirdEnd);
506        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdNextStart);
507        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdNextEnd);
508        moreChip = view.getMoreChip();
509        assertEquals(mEditable.getSpanStart(moreChip), -1);
510    }
511
512    public void testRemoveChip() {
513        // Create 3 chips to start and test removing chips in various postions.
514        populateMocks(3);
515        MockRecipientEditTextView view = createViewForTesting();
516        view.setMoreItem(createTestMoreItem());
517        String first = (String) mTokenizer.terminateToken("FIRST");
518        String second = (String) mTokenizer.terminateToken("SECOND");
519        String third = (String) mTokenizer.terminateToken("THIRD");
520        mEditable = new SpannableStringBuilder();
521        mEditable.append(first + second + third);
522
523        int firstStart = mEditable.toString().indexOf(first);
524        int firstEnd = firstStart + first.length();
525        int secondStart = mEditable.toString().indexOf(second);
526        int secondEnd = secondStart + second.length();
527        int thirdStart = mEditable.toString().indexOf(third);
528        int thirdEnd = thirdStart + third.length();
529        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
530        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
531        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
532        assertEquals(mEditable.toString(), first + second + third);
533        // Test removing the middle chip.
534        view.removeChip(mMockRecips[mMockRecips.length - 2]);
535        assertEquals(mEditable.toString(), first + third);
536        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
537        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
538        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), -1);
539        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), -1);
540        int newThirdStart = mEditable.toString().indexOf(third);
541        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), newThirdStart);
542        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), newThirdStart
543                + third.length());
544
545        // Test removing the first chip.
546        populateMocks(3);
547        view = createViewForTesting();
548        view.setMoreItem(createTestMoreItem());
549        mEditable = new SpannableStringBuilder();
550        mEditable.append(first + second + third);
551
552        firstStart = mEditable.toString().indexOf(first);
553        firstEnd = firstStart + first.length();
554        secondStart = mEditable.toString().indexOf(second);
555        secondEnd = secondStart + second.length();
556        thirdStart = mEditable.toString().indexOf(third);
557        thirdEnd = thirdStart + third.length();
558        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
559        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
560        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
561        assertEquals(mEditable.toString(), first + second + third);
562        view.removeChip(mMockRecips[mMockRecips.length - 3]);
563        assertEquals(mEditable.toString(), second + third);
564        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), -1);
565        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), -1);
566        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), 0);
567        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), second.length());
568        newThirdStart = mEditable.toString().indexOf(third);
569        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), newThirdStart);
570        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), newThirdStart
571                + third.length());
572
573        // Test removing the last chip.
574        populateMocks(3);
575        view = createViewForTesting();
576        view.setMoreItem(createTestMoreItem());
577        mEditable = new SpannableStringBuilder();
578        mEditable.append(first + second + third);
579
580        firstStart = mEditable.toString().indexOf(first);
581        firstEnd = firstStart + first.length();
582        secondStart = mEditable.toString().indexOf(second);
583        secondEnd = secondStart + second.length();
584        thirdStart = mEditable.toString().indexOf(third);
585        thirdEnd = thirdStart + third.length();
586        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
587        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
588        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
589        assertEquals(mEditable.toString(), first + second + third);
590        view.removeChip(mMockRecips[mMockRecips.length - 1]);
591        assertEquals(mEditable.toString(), first + second);
592        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
593        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
594        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
595        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), secondEnd);
596        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), -1);
597        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), -1);
598    }
599
600    public void testReplaceChip() {
601        populateMocks(3);
602        MockRecipientEditTextView view = createViewForTesting();
603        view.setMoreItem(createTestMoreItem());
604        view.setChipBackground(createChipBackground());
605        view.setChipHeight(48);
606        String first = (String) mTokenizer.terminateToken("FIRST");
607        String second = (String) mTokenizer.terminateToken("SECOND");
608        String third = (String) mTokenizer.terminateToken("THIRD");
609        mEditable = new SpannableStringBuilder();
610        mEditable.append(first + second + third);
611
612        // Test replacing the first chip with a new chip.
613        int firstStart = mEditable.toString().indexOf(first);
614        int firstEnd = firstStart + first.trim().length();
615        int secondStart = mEditable.toString().indexOf(second);
616        int secondEnd = secondStart + second.trim().length();
617        int thirdStart = mEditable.toString().indexOf(third);
618        int thirdEnd = thirdStart + third.trim().length();
619        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
620        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
621        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
622        assertEquals(mEditable.toString(), first + second + third);
623        view.replaceChip(mMockRecips[mMockRecips.length - 3], RecipientEntry
624                .constructGeneratedEntry("replacement", "replacement@replacement.com", true));
625        assertEquals(mEditable.toString(), mTokenizer
626                .terminateToken("replacement <replacement@replacement.com>")
627                + second + third);
628        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), -1);
629        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), -1);
630        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), mEditable
631                .toString().indexOf(second));
632        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), mEditable
633                .toString().indexOf(second)
634                + second.trim().length());
635        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), mEditable
636                .toString().indexOf(third));
637        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), mEditable
638                .toString().indexOf(third)
639                + third.trim().length());
640        RecipientChip[] spans = mEditable.getSpans(0, mEditable.length(), RecipientChip.class);
641        assertEquals(spans.length, 3);
642        spans = mEditable
643                .getSpans(0, mEditable.toString().indexOf(second) - 1, RecipientChip.class);
644        assertEquals((String) spans[0].getDisplay(), "replacement");
645
646
647        // Test replacing the middle chip with a new chip.
648        mEditable = new SpannableStringBuilder();
649        mEditable.append(first + second + third);
650        firstStart = mEditable.toString().indexOf(first);
651        firstEnd = firstStart + first.trim().length();
652        secondStart = mEditable.toString().indexOf(second);
653        secondEnd = secondStart + second.trim().length();
654        thirdStart = mEditable.toString().indexOf(third);
655        thirdEnd = thirdStart + third.trim().length();
656        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
657        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
658        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
659        assertEquals(mEditable.toString(), first + second + third);
660        view.replaceChip(mMockRecips[mMockRecips.length - 2], RecipientEntry
661                .constructGeneratedEntry("replacement", "replacement@replacement.com", true));
662        assertEquals(mEditable.toString(), first + mTokenizer
663                .terminateToken("replacement <replacement@replacement.com>") + third);
664        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
665        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
666        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), -1);
667        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), -1);
668        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), mEditable
669                .toString().indexOf(third));
670        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), mEditable
671                .toString().indexOf(third)
672                + third.trim().length());
673        spans = mEditable.getSpans(0, mEditable.length(), RecipientChip.class);
674        assertEquals(spans.length, 3);
675        spans = mEditable
676                .getSpans(firstEnd, mEditable.toString().indexOf(third) - 1, RecipientChip.class);
677        assertEquals((String) spans[0].getDisplay(), "replacement");
678
679
680        // Test replacing the last chip with a new chip.
681        mEditable = new SpannableStringBuilder();
682        mEditable.append(first + second + third);
683        firstStart = mEditable.toString().indexOf(first);
684        firstEnd = firstStart + first.trim().length();
685        secondStart = mEditable.toString().indexOf(second);
686        secondEnd = secondStart + second.trim().length();
687        thirdStart = mEditable.toString().indexOf(third);
688        thirdEnd = thirdStart + third.trim().length();
689        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
690        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
691        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
692        assertEquals(mEditable.toString(), first + second + third);
693        view.replaceChip(mMockRecips[mMockRecips.length - 1], RecipientEntry
694                .constructGeneratedEntry("replacement", "replacement@replacement.com", true));
695        assertEquals(mEditable.toString(), first + second + mTokenizer
696                .terminateToken("replacement <replacement@replacement.com>"));
697        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
698        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
699        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
700        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), secondEnd);
701        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), -1);
702        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), -1);
703        spans = mEditable.getSpans(0, mEditable.length(), RecipientChip.class);
704        assertEquals(spans.length, 3);
705        spans = mEditable
706                .getSpans(secondEnd, mEditable.length(), RecipientChip.class);
707        assertEquals((String) spans[0].getDisplay(), "replacement");
708    }
709
710    public void testHandlePaste() {
711        // Start with an empty edit field.
712        // Add an address; the text should be left as is.
713        MockRecipientEditTextView view = createViewForTesting();
714        view.setMoreItem(createTestMoreItem());
715        view.setChipBackground(createChipBackground());
716        view.setChipHeight(48);
717        mEditable = new SpannableStringBuilder();
718        mEditable.append("user@user.com");
719        view.setSelection(mEditable.length());
720        view.handlePaste();
721        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 0);
722        assertEquals(mEditable.toString(), "user@user.com");
723
724        // Test adding a single address to an empty chips field with a space at
725        // the end of it. The address should stay as text.
726        mEditable = new SpannableStringBuilder();
727        String tokenizedUser = "user@user.com" + " ";
728        mEditable.append(tokenizedUser);
729        view.setSelection(mEditable.length());
730        view.handlePaste();
731        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 0);
732        assertEquals(mEditable.toString(), tokenizedUser);
733
734        // Test adding a single address to an empty chips field with a semicolon at
735        // the end of it. The address should become a chip
736        mEditable = new SpannableStringBuilder();
737        tokenizedUser = "user@user.com;";
738        mEditable.append(tokenizedUser);
739        view.setSelection(mEditable.length());
740        view.handlePaste();
741        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 1);
742
743        // Test adding 2 address to an empty chips field. The second to last
744        // address should become a chip and the last address should stay as
745        // text.
746        mEditable = new SpannableStringBuilder();
747        mEditable.append("user1,user2@user.com");
748        view.setSelection(mEditable.length());
749        view.handlePaste();
750        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 1);
751        assertEquals(mEditable.getSpans(0, mEditable.toString().indexOf("user2@user.com"),
752                RecipientChip.class).length, 1);
753        assertEquals(mEditable.toString(), "<user1>, user2@user.com");
754
755        // Test adding a single address to the end of existing chips. The existing
756        // chips should remain, and the last address should stay as text.
757        populateMocks(3);
758        String first = (String) mTokenizer.terminateToken("FIRST");
759        String second = (String) mTokenizer.terminateToken("SECOND");
760        String third = (String) mTokenizer.terminateToken("THIRD");
761        mEditable = new SpannableStringBuilder();
762        mEditable.append(first + second + third);
763        view.setSelection(mEditable.length());
764        int firstStart = mEditable.toString().indexOf(first);
765        int firstEnd = firstStart + first.trim().length();
766        int secondStart = mEditable.toString().indexOf(second);
767        int secondEnd = secondStart + second.trim().length();
768        int thirdStart = mEditable.toString().indexOf(third);
769        int thirdEnd = thirdStart + third.trim().length();
770        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
771        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
772        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
773
774        mEditable.append("user@user.com");
775        view.setSelection(mEditable.length());
776        view.handlePaste();
777        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length,
778                mMockRecips.length);
779        assertEquals(mEditable.toString(), first + second + third + "user@user.com");
780
781        // Paste 2 addresses after existing chips. We expect the first address to be turned into
782        // a chip and the second to be left as text.
783        populateMocks(3);
784        mEditable = new SpannableStringBuilder();
785        mEditable.append(first + second + third);
786
787        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
788        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
789        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
790
791        mEditable.append("user1, user2@user.com");
792        view.setSelection(mEditable.length());
793        view.handlePaste();
794        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length,
795                mMockRecips.length + 1);
796        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
797                .toString().indexOf("user2@user.com") - 1, RecipientChip.class).length, 1);
798        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
799                .length(), RecipientChip.class).length, 0);
800        assertEquals(mEditable.toString(), first + second + third + "<user1>, user2@user.com");
801
802        // Paste 2 addresses after existing chips. We expect the first address to be turned into
803        // a chip and the second to be left as text. This removes the space seperator char between
804        // addresses.
805        populateMocks(3);
806        mEditable = new SpannableStringBuilder();
807        mEditable.append(first + second + third);
808
809        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
810        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
811        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
812
813        mEditable.append("user1,user2@user.com");
814        view.setSelection(mEditable.length());
815        view.handlePaste();
816        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length,
817                mMockRecips.length + 1);
818        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
819                .toString().indexOf("user2@user.com") - 1, RecipientChip.class).length, 1);
820        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
821                .length(), RecipientChip.class).length, 0);
822        assertEquals(mEditable.toString(), first + second + third + "<user1>, user2@user.com");
823
824        // Test a complete token pasted in at the end. It should be turned into a chip.
825        mEditable = new SpannableStringBuilder();
826        mEditable.append("user1, user2@user.com,");
827        view.setSelection(mEditable.length());
828        view.handlePaste();
829        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 2);
830        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
831                .toString().indexOf("user2@user.com") - 1, RecipientChip.class).length, 1);
832        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
833                .length(), RecipientChip.class).length, 1);
834        assertEquals(mEditable.toString(), "<user1>, <user2@user.com>, ");
835    }
836
837    public void testGetPastTerminators() {
838        MockRecipientEditTextView view = createViewForTesting();
839        view.setMoreItem(createTestMoreItem());
840        view.setChipBackground(createChipBackground());
841        view.setChipHeight(48);
842        String test = "test";
843        mEditable = new SpannableStringBuilder();
844        mEditable.append(test);
845        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
846                test.length());
847
848        test = "test,";
849        mEditable = new SpannableStringBuilder();
850        mEditable.append(test);
851        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
852                test.length());
853
854        test = "test, ";
855        mEditable = new SpannableStringBuilder();
856        mEditable.append(test);
857        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
858                test.length());
859
860        test = "test;";
861        mEditable = new SpannableStringBuilder();
862        mEditable.append(test);
863        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
864                test.length());
865
866        test = "test; ";
867        mEditable = new SpannableStringBuilder();
868        mEditable.append(test);
869        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
870                test.length());
871    }
872
873    public void testIsCompletedToken() {
874        MockRecipientEditTextView view = createViewForTesting();
875        view.setMoreItem(createTestMoreItem());
876        view.setChipBackground(createChipBackground());
877        view.setChipHeight(48);
878        assertTrue(view.isCompletedToken("test;"));
879        assertTrue(view.isCompletedToken("test,"));
880        assertFalse(view.isCompletedToken("test"));
881        assertFalse(view.isCompletedToken("test "));
882    }
883
884    public void testGetLastChip() {
885        populateMocks(3);
886        MockRecipientEditTextView view = createViewForTesting();
887        view.setMoreItem(createTestMoreItem());
888        view.setChipBackground(createChipBackground());
889        view.setChipHeight(48);
890        String first = (String) mTokenizer.terminateToken("FIRST");
891        String second = (String) mTokenizer.terminateToken("SECOND");
892        String third = (String) mTokenizer.terminateToken("THIRD");
893        mEditable = new SpannableStringBuilder();
894        mEditable.append(first + second + third);
895
896        // Test replacing the first chip with a new chip.
897        int firstStart = mEditable.toString().indexOf(first);
898        int firstEnd = firstStart + first.trim().length();
899        int secondStart = mEditable.toString().indexOf(second);
900        int secondEnd = secondStart + second.trim().length();
901        int thirdStart = mEditable.toString().indexOf(third);
902        int thirdEnd = thirdStart + third.trim().length();
903        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
904        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
905        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
906        assertEquals(view.getLastChip(), mMockRecips[mMockRecips.length - 1]);
907        mEditable.append("extra");
908        assertEquals(view.getLastChip(), mMockRecips[mMockRecips.length - 1]);
909    }
910
911    private Drawable createChipBackground() {
912        Bitmap drawable = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
913        return new BitmapDrawable(getContext().getResources(), drawable);
914    }
915
916    private TextView createTestMoreItem() {
917        TextView view = new TextView(getContext());
918        view.setText("<xliff:g id='count'>%1$s</xliff:g> more...");
919        return view;
920    }
921
922    private void populateMocks(int size) {
923        mMockEntries = new RecipientEntry[size];
924        for (int i = 0; i < size; i++) {
925            mMockEntries[i] = RecipientEntry.constructGeneratedEntry("user",
926                    "user@username.com", true);
927        }
928        mMockRecips = new RecipientChip[size];
929        for (int i = 0; i < size; i++) {
930            mMockRecips[i] = new VisibleRecipientChip(null, mMockEntries[i], i);
931        }
932    }
933}
934