ChipsTest.java revision f6519d2aabaac51fd62dc819c109db86748d79e8
17cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira/*
27cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira * Copyright (C) 2011 The Android Open Source Project
37cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira *
47cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira * Licensed under the Apache License, Version 2.0 (the "License");
57cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira * you may not use this file except in compliance with the License.
67cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira * You may obtain a copy of the License at
77cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira *
87cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira *      http://www.apache.org/licenses/LICENSE-2.0
97cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira *
107cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira * Unless required by applicable law or agreed to in writing, software
117cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS,
127cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira * See the License for the specific language governing permissions and
147cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira * limitations under the License.
157cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira */
167cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira
177cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereirapackage com.android.ex.chips;
187cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira
1901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereiraimport android.content.Context;
2097cb25912dab282cf732757f68b0405ed005f00bMindy Pereiraimport android.graphics.Bitmap;
2197cb25912dab282cf732757f68b0405ed005f00bMindy Pereiraimport android.graphics.drawable.BitmapDrawable;
2297cb25912dab282cf732757f68b0405ed005f00bMindy Pereiraimport android.graphics.drawable.Drawable;
237cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereiraimport android.test.AndroidTestCase;
24fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereiraimport android.test.suitebuilder.annotation.SmallTest;
2501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereiraimport android.text.Editable;
2601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereiraimport android.text.SpannableStringBuilder;
27d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereiraimport android.text.style.ImageSpan;
2801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereiraimport android.text.util.Rfc822Tokenizer;
29d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereiraimport android.widget.TextView;
3001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
3101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereiraimport com.android.ex.chips.RecipientEditTextView;
3201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereiraimport com.android.ex.chips.RecipientEntry;
3301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
34fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira@SmallTest
357cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereirapublic class ChipsTest extends AndroidTestCase {
368eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira    private RecipientChip[] mMockRecips;
3701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
388eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira    private RecipientEntry[] mMockEntries;
3901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
4001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    private Rfc822Tokenizer mTokenizer;
4101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
4201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    private Editable mEditable;
4301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
44f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    class BaseMockRecipientEditTextView extends RecipientEditTextView {
4501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
46f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        public BaseMockRecipientEditTextView(Context context) {
4701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira            super(context, null);
4801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira            mTokenizer = new Rfc822Tokenizer();
4901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira            setTokenizer(mTokenizer);
5001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        }
5101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
5201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        @Override
5301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        public RecipientChip[] getSortedRecipients() {
5401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira            return mMockRecips;
5501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        }
5601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
5701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        @Override
58f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        public int getLineHeight() {
59f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            return 48;
60f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
61f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
62f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        @Override
63f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        Drawable getChipBackground(RecipientEntry contact) {
64f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            return createChipBackground();
65f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
66f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
67f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        @Override
68f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        public int getViewWidth() {
69f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            return 100;
70f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
71f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    }
72f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
73f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    class MockRecipientEditTextView extends BaseMockRecipientEditTextView {
74f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
75f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        public MockRecipientEditTextView(Context context) {
76f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            super(context);
77f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            mTokenizer = new Rfc822Tokenizer();
78f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            setTokenizer(mTokenizer);
79f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
80f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
81f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        @Override
82f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        public RecipientChip[] getSortedRecipients() {
83f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            return mMockRecips;
84f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
85f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
86f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        @Override
8701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        public Editable getText() {
8801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira            return mEditable;
8901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        }
9001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
9101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        @Override
9201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        public Editable getSpannable() {
9301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira            return mEditable;
9401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        }
95d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
96d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        @Override
97d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        public int getLineHeight() {
98d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira            return 48;
99d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        }
10097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
10120c9d620e79ae28994856541761a951074551518Mindy Pereira        @Override
102aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        Drawable getChipBackground(RecipientEntry contact) {
10397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira            return createChipBackground();
10497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        }
10520c9d620e79ae28994856541761a951074551518Mindy Pereira
10620c9d620e79ae28994856541761a951074551518Mindy Pereira        @Override
10720c9d620e79ae28994856541761a951074551518Mindy Pereira        public int length() {
10820c9d620e79ae28994856541761a951074551518Mindy Pereira            return mEditable != null ? mEditable.length() : 0;
10920c9d620e79ae28994856541761a951074551518Mindy Pereira        }
11020c9d620e79ae28994856541761a951074551518Mindy Pereira
11120c9d620e79ae28994856541761a951074551518Mindy Pereira        @Override
11220c9d620e79ae28994856541761a951074551518Mindy Pereira        public String toString() {
11320c9d620e79ae28994856541761a951074551518Mindy Pereira            return mEditable != null ? mEditable.toString() : "";
11420c9d620e79ae28994856541761a951074551518Mindy Pereira        }
115f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
116f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        @Override
117f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        public int getViewWidth() {
118f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            return 100;
119f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
12001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    }
12101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
12201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    private MockRecipientEditTextView createViewForTesting() {
12301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable = new SpannableStringBuilder();
12401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        MockRecipientEditTextView view = new MockRecipientEditTextView(getContext());
12501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        return view;
12601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    }
12701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
12801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    public void testCreateDisplayText() {
12901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEditTextView view = createViewForTesting();
13001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEntry entry = RecipientEntry.constructGeneratedEntry("User Name, Jr",
13101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira                "user@username.com");
132aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String testAddress = view.createAddressText(entry);
133aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String testDisplay = view.createChipDisplayText(entry);
13401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals("Expected a properly formatted RFC email address",
135aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira                "\"User Name, Jr\" <user@username.com>, ", testAddress);
136aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals("Expected a displayable name", "User Name, Jr", testDisplay);
137aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira
13801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
13901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEntry alreadyFormatted = RecipientEntry.constructFakeEntry("user@username.com, ");
140aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testAddress = view.createAddressText(alreadyFormatted);
141aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testDisplay = view.createChipDisplayText(alreadyFormatted);
14201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals("Expected a properly formatted RFC email address", "<user@username.com>, ",
143aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira                testAddress);
144aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals("Expected a displayable name", "user@username.com", testDisplay);
14501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
14601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEntry alreadyFormattedNoSpace = RecipientEntry
14701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira                .constructFakeEntry("user@username.com,");
148aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testAddress = view.createAddressText(alreadyFormattedNoSpace);
14901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals("Expected a properly formatted RFC email address", "<user@username.com>, ",
150aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira                testAddress);
15101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
15201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEntry alreadyNamed = RecipientEntry.constructGeneratedEntry("User Name",
15301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira                "\"User Name, Jr\" <user@username.com>");
154aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testAddress = view.createAddressText(alreadyNamed);
155aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testDisplay = view.createChipDisplayText(alreadyNamed);
15601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(
15701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira                "Expected address that used the name not the excess address name",
158aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira                "User Name <user@username.com>, ", testAddress);
159aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals("Expected a displayable name", "User Name", testDisplay);
16001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    }
1617cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira
16201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    public void testSanitizeBetween() {
163fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // First, add 2 chips and then make sure we remove
164fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // the extra content between them correctly.
1658eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        populateMocks(2);
16601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
16701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
16801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
16901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        String extra = "EXTRA";
170d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable = new SpannableStringBuilder();
17101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.append(first + extra + second);
17201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
17362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
17401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
17562397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
17601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], firstStart, firstEnd, 0);
17701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], secondStart, secondEnd, 0);
17801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        view.sanitizeBetween();
17901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        String editableString = mEditable.toString();
18001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(editableString.indexOf(extra), -1);
18101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(editableString.indexOf(first), firstStart);
18201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(editableString.indexOf(second), secondStart - extra.length());
18301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(editableString, (first + second));
184399bda87ad1a4d003609d6d27afc50c8359846b9Mindy Pereira
185fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Add 1 chip and make sure that we remove the extra stuff before it correctly.
18601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable = new SpannableStringBuilder();
1878eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        populateMocks(1);
1888eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        mEditable.append(extra);
18901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.append(first);
19001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        firstStart = mEditable.toString().indexOf(first);
19101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        firstEnd = firstStart + first.length();
19201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], firstStart, firstEnd, 0);
19301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        view.sanitizeBetween();
19401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(mEditable.toString(), first);
1958eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), firstStart
1968eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira                - extra.length());
1978eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira    }
1988eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira
199aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira    public void testSanitizeEnd() {
200aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        // First, add 2 chips and then make sure we remove
201aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        // the extra content between them correctly.
202aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        populateMocks(2);
203aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
204aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
205aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
206aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String extra = "EXTRA";
207aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable = new SpannableStringBuilder();
208aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.append(first + second);
209aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
210aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int firstEnd = firstStart + first.trim().length();
211aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
212aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int secondEnd = secondStart + second.trim().length();
213aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], firstStart, firstEnd, 0);
214aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], secondStart, secondEnd, 0);
215aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.sanitizeEnd();
216aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String editableString = mEditable.toString();
217aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(editableString.indexOf(extra), -1);
218aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(editableString.indexOf(first), firstStart);
219aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(editableString.indexOf(second), secondStart);
220aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(editableString, (first + second));
221aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.append(extra);
222aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        editableString = mEditable.toString();
223aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(mEditable.toString(), (first + second + extra));
224aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.sanitizeEnd();
225aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(mEditable.toString(), (first + second));
226aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira    }
227aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira
228f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    public void testMoreChipPlainText() {
229f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
230f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.setMoreItem(createTestMoreItem());
231f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
232f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
233f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
234f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        mEditable = new SpannableStringBuilder();
235f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        mEditable.append(first+second+third);
236f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
237f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        int thirdEnd = thirdStart + third.trim().length();
238f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.createMoreChipPlainText();
239f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        ImageSpan moreChip = view.getMoreChip();
240f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
241f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
242f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    }
243f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
244f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    public void testCountTokens() {
245f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
246f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.setMoreItem(createTestMoreItem());
247f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
248f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
249f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
250f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String fourth = (String) ("FOURTH,");
251f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String fifth = (String) ("FIFTH,");
252f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        mEditable = new SpannableStringBuilder();
253f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        mEditable.append(first+second+third+fourth+fifth);
254f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.countTokens(mEditable), 5);
255f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    }
256f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
257f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    public void testTooManyRecips() {
258f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        BaseMockRecipientEditTextView view = new BaseMockRecipientEditTextView(getContext());
259f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.setMoreItem(createTestMoreItem());
260f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        for (int i = 0; i < 100; i++) {
261f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            view.append(mTokenizer.terminateToken(i + ""));
262f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
263f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.countTokens(view.getText()), 100);
264f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.handlePendingChips();
265f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.createMoreChip();
266f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        ImageSpan moreChip = view.getMoreChip();
267f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        // We show 2 chips then place a more chip.
268f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        int secondStart = view.getText().toString().indexOf(
269f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira                (String) mTokenizer.terminateToken(RecipientEditTextView.CHIP_LIMIT + ""));
270f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.getText().getSpanStart(moreChip), secondStart);
271f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.getText().getSpanEnd(moreChip), view.length());
272f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.getSortedRecipients(), null);
273f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    }
274f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
275d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    public void testMoreChip() {
276fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Add 3 chips: this is the trigger point at which the more chip will be created.
277fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test that adding the chips and then creating and removing the more chip, as if
278fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // the user were focusing/ removing focus from the chips field.
279d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        populateMocks(3);
280d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
281d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.setMoreItem(createTestMoreItem());
282d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
283d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
284d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
285d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable = new SpannableStringBuilder();
286d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.append(first+second+third);
287d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
288d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
28962397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
290d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
29162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
292d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
29362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
294d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
295d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
296d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
297d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
298d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.createMoreChip();
299d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
300d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
301d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
302d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Find the more chip.
303d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        ImageSpan moreChip = view.getMoreChip();
304d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
305f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
306d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
307d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.removeMoreChip();
308d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
309d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
310d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
311d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
312d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
313d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
314d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
315d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
316d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
317d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Rinse and repeat, just in case!
318d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.createMoreChip();
319d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
320d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
321d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
322d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Find the more chip.
323d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
324d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
325f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
326d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
327d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.removeMoreChip();
328d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
329d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
330d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
331d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
332d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
333d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
334d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
335d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
336d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    }
337d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
338d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    public void testMoreChipLotsOfUsers() {
339fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test adding and removing the more chip in the case where we have a lot of users.
340d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        populateMocks(10);
341d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
342d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.setMoreItem(createTestMoreItem());
343d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
344d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
345d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
346d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String fourth = (String) mTokenizer.terminateToken("FOURTH");
347d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String fifth = (String) mTokenizer.terminateToken("FIFTH");
348d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String sixth = (String) mTokenizer.terminateToken("SIXTH");
349d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String seventh = (String) mTokenizer.terminateToken("SEVENTH");
350d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String eigth = (String) mTokenizer.terminateToken("EIGHTH");
351d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String ninth = (String) mTokenizer.terminateToken("NINTH");
352d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String tenth = (String) mTokenizer.terminateToken("TENTH");
353d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable = new SpannableStringBuilder();
354d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.append(first+second+third+fourth+fifth+sixth+seventh+eigth+ninth+tenth);
355d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
356d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
35762397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
358d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
35962397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
360d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
36162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
362d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int fourthStart = mEditable.toString().indexOf(fourth);
36362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int fourthEnd = fourthStart + fourth.trim().length();
364d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int fifthStart = mEditable.toString().indexOf(fifth);
36562397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int fifthEnd = fifthStart + fifth.trim().length();
366d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int sixthStart = mEditable.toString().indexOf(sixth);
36762397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int sixthEnd = sixthStart + sixth.trim().length();
368d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int seventhStart = mEditable.toString().indexOf(seventh);
36962397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int seventhEnd = seventhStart + seventh.trim().length();
370d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int eighthStart = mEditable.toString().indexOf(eigth);
37162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int eighthEnd = eighthStart + eigth.trim().length();
372d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int ninthStart = mEditable.toString().indexOf(ninth);
37362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int ninthEnd = ninthStart + ninth.trim().length();
374d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int tenthStart = mEditable.toString().indexOf(tenth);
37562397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int tenthEnd = tenthStart + tenth.trim().length();
376d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 10], firstStart, firstEnd, 0);
377d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 9], secondStart, secondEnd, 0);
378d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 8], thirdStart, thirdEnd, 0);
379d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 7], fourthStart, fourthEnd, 0);
380d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 6], fifthStart, fifthEnd, 0);
381d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 5], sixthStart, sixthEnd, 0);
382d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 4], seventhStart, seventhEnd, 0);
383d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], eighthStart, eighthEnd, 0);
384d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], ninthStart, ninthEnd, 0);
385d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], tenthStart, tenthEnd, 0);
386d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
387d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.createMoreChip();
388d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first + second + third + fourth + fifth + sixth
389d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira                + seventh + eigth + ninth + tenth);
390d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 10]), firstStart);
391d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 9]), secondStart);
392d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Find the more chip.
393d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        ImageSpan moreChip = view.getMoreChip();
394d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
395f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), tenthEnd + 1);
396d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
397d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.removeMoreChip();
398d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first + second + third + fourth + fifth + sixth
399d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira                + seventh + eigth + ninth + tenth);
400d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 10]), firstStart);
401d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 9]), secondStart);
402d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
403d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 8]), thirdStart);
404d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 7]), fourthStart);
405d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 6]), fifthStart);
406d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 5]), sixthStart);
407d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), seventhStart);
408d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), eighthStart);
409d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), ninthStart);
410d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), tenthStart);
411d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
412d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
413d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
414d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    }
415d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
416d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    public void testMoreChipSpecialChars() {
417fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Make sure the more chip correctly handles extra tokenizer characters in the middle
418fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // of chip text.
419d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        populateMocks(3);
420d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
421d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.setMoreItem(createTestMoreItem());
422d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String first = (String) mTokenizer.terminateToken("FI,RST");
423d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String second = (String) mTokenizer.terminateToken("SE,COND");
424d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String third = (String) mTokenizer.terminateToken("THI,RD");
425d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable = new SpannableStringBuilder();
426d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.append(first+second+third);
427d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
428d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
42962397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
430d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
43162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
432d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
43362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
434d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
435d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
436d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
437d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
438d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.createMoreChip();
439d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
440d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
441d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
442d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Find the more chip.
443d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        ImageSpan moreChip = view.getMoreChip();
444d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
445f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
446d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
447d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.removeMoreChip();
448d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
449d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
450d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
451d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
452d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
453d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
454d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
455d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
456d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    }
457d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
458dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira    public void testMoreChipDupes() {
459fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Make sure the more chip is correctly added and removed when we have duplicate chips.
460dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        populateMocks(4);
461dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
462dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        view.setMoreItem(createTestMoreItem());
463dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
464dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
465dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
466dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable = new SpannableStringBuilder();
467dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.append(first+second+third+third);
468dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira
469dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
47062397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
471dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
47262397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
473dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
47462397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
475dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        int thirdNextStart = mEditable.toString().indexOf(third, thirdEnd);
47662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdNextEnd = thirdNextStart + third.trim().length();
477dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 4], firstStart, firstEnd, 0);
478dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], secondStart, secondEnd, 0);
479dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], thirdStart, thirdEnd, 0);
480dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdNextStart, thirdNextEnd, 0);
481dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira
482dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        view.createMoreChip();
483dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.toString(), first+second+third+third);
484dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), firstStart);
485dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), secondStart);
486dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        // Find the more chip.
487dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        ImageSpan moreChip = view.getMoreChip();
488dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
489f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdNextEnd + 1);
490dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira
491dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        view.removeMoreChip();
492dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.toString(), first+second+third+third);
493dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), firstStart);
494dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 4]), firstEnd);
495dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), secondStart);
496dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), thirdStart);
497dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), thirdEnd);
498dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdNextStart);
499dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdNextEnd);
500dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        moreChip = view.getMoreChip();
501dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
502dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira    }
503dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira
50497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    public void testRemoveChip() {
505fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Create 3 chips to start and test removing chips in various postions.
50697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        populateMocks(3);
50797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
50897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setMoreItem(createTestMoreItem());
50997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
51097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
51197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
51297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable = new SpannableStringBuilder();
51397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.append(first + second + third);
51497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
51597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
51697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int firstEnd = firstStart + first.length();
51797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
51897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int secondEnd = secondStart + second.length();
51997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
52097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int thirdEnd = thirdStart + third.length();
52197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
52297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
52397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
52497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second + third);
525fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test removing the middle chip.
52697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.removeChip(mMockRecips[mMockRecips.length - 2]);
52797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + third);
52897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
52997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
53097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), -1);
53197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), -1);
53297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int newThirdStart = mEditable.toString().indexOf(third);
53397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), newThirdStart);
53497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), newThirdStart
53597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                + third.length());
53697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
537fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test removing the first chip.
53897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        populateMocks(3);
53997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view = createViewForTesting();
54097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setMoreItem(createTestMoreItem());
54197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable = new SpannableStringBuilder();
54297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.append(first + second + third);
54397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
54497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        firstStart = mEditable.toString().indexOf(first);
54597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        firstEnd = firstStart + first.length();
54697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        secondStart = mEditable.toString().indexOf(second);
54797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        secondEnd = secondStart + second.length();
54897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        thirdStart = mEditable.toString().indexOf(third);
54997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        thirdEnd = thirdStart + third.length();
55097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
55197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
55297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
55397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second + third);
55497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.removeChip(mMockRecips[mMockRecips.length - 3]);
55597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), second + third);
55697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), -1);
55797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), -1);
55897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), 0);
55997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), second.length());
56097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        newThirdStart = mEditable.toString().indexOf(third);
56197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), newThirdStart);
56297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), newThirdStart
56397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                + third.length());
56497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
565fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test removing the last chip.
56697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        populateMocks(3);
56797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view = createViewForTesting();
56897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setMoreItem(createTestMoreItem());
56997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable = new SpannableStringBuilder();
57097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.append(first + second + third);
57197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
57297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        firstStart = mEditable.toString().indexOf(first);
57397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        firstEnd = firstStart + first.length();
57497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        secondStart = mEditable.toString().indexOf(second);
57597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        secondEnd = secondStart + second.length();
57697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        thirdStart = mEditable.toString().indexOf(third);
57797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        thirdEnd = thirdStart + third.length();
57897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
57997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
58097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
58197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second + third);
58297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.removeChip(mMockRecips[mMockRecips.length - 1]);
58397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second);
58497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
58597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
58697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
58797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), secondEnd);
58897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), -1);
58997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), -1);
59097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    }
59197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
59297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    public void testReplaceChip() {
59397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        populateMocks(3);
59497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
59597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setMoreItem(createTestMoreItem());
59697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setChipBackground(createChipBackground());
59797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setChipHeight(48);
59897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
59997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
60097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
60197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable = new SpannableStringBuilder();
60297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.append(first + second + third);
60397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
604fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test replacing the first chip with a new chip.
60597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
60662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
60797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
60862397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
60997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
61062397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
61197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
61297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
61397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
61497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second + third);
61597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.replaceChip(mMockRecips[mMockRecips.length - 3], RecipientEntry
61697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .constructGeneratedEntry("replacement", "replacement@replacement.com"));
61797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), mTokenizer
61897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .terminateToken("replacement <replacement@replacement.com>")
61997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                + second + third);
62097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), -1);
62197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), -1);
62297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), mEditable
62397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .toString().indexOf(second));
62497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), mEditable
62597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .toString().indexOf(second)
62662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                + second.trim().length());
62797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), mEditable
62897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .toString().indexOf(third));
62997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), mEditable
63097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .toString().indexOf(third)
63162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                + third.trim().length());
63297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        RecipientChip[] spans = mEditable.getSpans(0, mEditable.length(), RecipientChip.class);
63397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(spans.length, 3);
63497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        spans = mEditable
63597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .getSpans(0, mEditable.toString().indexOf(second) - 1, RecipientChip.class);
63697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals((String) spans[0].getDisplay(), "replacement");
637fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira
638fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira
639fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test replacing the middle chip with a new chip.
640fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable = new SpannableStringBuilder();
641fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.append(first + second + third);
642fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        firstStart = mEditable.toString().indexOf(first);
64362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        firstEnd = firstStart + first.trim().length();
644fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        secondStart = mEditable.toString().indexOf(second);
64562397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        secondEnd = secondStart + second.trim().length();
646fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        thirdStart = mEditable.toString().indexOf(third);
64762397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        thirdEnd = thirdStart + third.trim().length();
648fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
649fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
650fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
651fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.toString(), first + second + third);
652fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        view.replaceChip(mMockRecips[mMockRecips.length - 2], RecipientEntry
653fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira                .constructGeneratedEntry("replacement", "replacement@replacement.com"));
65462397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        assertEquals(mEditable.toString(), first + mTokenizer
65562397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                .terminateToken("replacement <replacement@replacement.com>") + third);
656fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
657fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
658fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), -1);
659fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), -1);
660fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), mEditable
661fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira                .toString().indexOf(third));
662fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), mEditable
663fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira                .toString().indexOf(third)
66462397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                + third.trim().length());
665fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        spans = mEditable.getSpans(0, mEditable.length(), RecipientChip.class);
666fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(spans.length, 3);
667fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        spans = mEditable
668fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira                .getSpans(firstEnd, mEditable.toString().indexOf(third) - 1, RecipientChip.class);
669fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals((String) spans[0].getDisplay(), "replacement");
670fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira
671fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira
672fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test replacing the last chip with a new chip.
673fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable = new SpannableStringBuilder();
674fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.append(first + second + third);
675fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        firstStart = mEditable.toString().indexOf(first);
67662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        firstEnd = firstStart + first.trim().length();
677fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        secondStart = mEditable.toString().indexOf(second);
67862397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        secondEnd = secondStart + second.trim().length();
679fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        thirdStart = mEditable.toString().indexOf(third);
68062397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        thirdEnd = thirdStart + third.trim().length();
681fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
682fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
683fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
684fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.toString(), first + second + third);
685fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        view.replaceChip(mMockRecips[mMockRecips.length - 1], RecipientEntry
686fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira                .constructGeneratedEntry("replacement", "replacement@replacement.com"));
68762397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        assertEquals(mEditable.toString(), first + second + mTokenizer
68862397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                .terminateToken("replacement <replacement@replacement.com>"));
689fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
690fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
691fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
692fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), secondEnd);
693fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), -1);
694fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), -1);
695fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        spans = mEditable.getSpans(0, mEditable.length(), RecipientChip.class);
696fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(spans.length, 3);
697fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        spans = mEditable
698fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira                .getSpans(secondEnd, mEditable.length(), RecipientChip.class);
699fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals((String) spans[0].getDisplay(), "replacement");
70097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    }
70197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
70220c9d620e79ae28994856541761a951074551518Mindy Pereira    public void testHandlePaste() {
70320c9d620e79ae28994856541761a951074551518Mindy Pereira        // Start with an empty edit field.
70420c9d620e79ae28994856541761a951074551518Mindy Pereira        // Add an address; the text should be left as is.
70520c9d620e79ae28994856541761a951074551518Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
70620c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setMoreItem(createTestMoreItem());
70720c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipBackground(createChipBackground());
70820c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipHeight(48);
70920c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
71020c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user@user.com");
71120c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
71220c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
71320c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 0);
71420c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), "user@user.com");
71520c9d620e79ae28994856541761a951074551518Mindy Pereira
71620c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test adding a single address to an empty chips field with a space at
71720c9d620e79ae28994856541761a951074551518Mindy Pereira        // the end of it. The address should stay as text.
71820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
71920c9d620e79ae28994856541761a951074551518Mindy Pereira        String tokenizedUser = "user@user.com" + " ";
72020c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(tokenizedUser);
72120c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
72220c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
72320c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 0);
72420c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), tokenizedUser);
72520c9d620e79ae28994856541761a951074551518Mindy Pereira
72620c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test adding a single address to an empty chips field with a semicolon at
72720c9d620e79ae28994856541761a951074551518Mindy Pereira        // the end of it. The address should become a chip
72820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
72920c9d620e79ae28994856541761a951074551518Mindy Pereira        tokenizedUser = "user@user.com;";
73020c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(tokenizedUser);
73120c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
73220c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
73320c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 1);
73420c9d620e79ae28994856541761a951074551518Mindy Pereira
73520c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test adding 2 address to an empty chips field. The second to last
73620c9d620e79ae28994856541761a951074551518Mindy Pereira        // address should become a chip and the last address should stay as
73720c9d620e79ae28994856541761a951074551518Mindy Pereira        // text.
73820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
73920c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user1,user2@user.com");
74020c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
74120c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
74220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 1);
74320c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.toString().indexOf("user2@user.com"),
74420c9d620e79ae28994856541761a951074551518Mindy Pereira                RecipientChip.class).length, 1);
74520c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), "<user1>, user2@user.com");
74620c9d620e79ae28994856541761a951074551518Mindy Pereira
74720c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test adding a single address to the end of existing chips. The existing
74820c9d620e79ae28994856541761a951074551518Mindy Pereira        // chips should remain, and the last address should stay as text.
74920c9d620e79ae28994856541761a951074551518Mindy Pereira        populateMocks(3);
75020c9d620e79ae28994856541761a951074551518Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
75120c9d620e79ae28994856541761a951074551518Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
75220c9d620e79ae28994856541761a951074551518Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
75320c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
75420c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(first + second + third);
75520c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
75620c9d620e79ae28994856541761a951074551518Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
75720c9d620e79ae28994856541761a951074551518Mindy Pereira        int firstEnd = firstStart + first.trim().length();
75820c9d620e79ae28994856541761a951074551518Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
75920c9d620e79ae28994856541761a951074551518Mindy Pereira        int secondEnd = secondStart + second.trim().length();
76020c9d620e79ae28994856541761a951074551518Mindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
76120c9d620e79ae28994856541761a951074551518Mindy Pereira        int thirdEnd = thirdStart + third.trim().length();
76220c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
76320c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
76420c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
76520c9d620e79ae28994856541761a951074551518Mindy Pereira
76620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user@user.com");
76720c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
76820c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
76920c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length,
77020c9d620e79ae28994856541761a951074551518Mindy Pereira                mMockRecips.length);
77120c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), first + second + third + "user@user.com");
77220c9d620e79ae28994856541761a951074551518Mindy Pereira
77320c9d620e79ae28994856541761a951074551518Mindy Pereira        // Paste 2 addresses after existing chips. We expect the first address to be turned into
77420c9d620e79ae28994856541761a951074551518Mindy Pereira        // a chip and the second to be left as text.
77520c9d620e79ae28994856541761a951074551518Mindy Pereira        populateMocks(3);
77620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
77720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(first + second + third);
77820c9d620e79ae28994856541761a951074551518Mindy Pereira
77920c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
78020c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
78120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
78220c9d620e79ae28994856541761a951074551518Mindy Pereira
78320c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user1, user2@user.com");
78420c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
78520c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
78620c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length,
78720c9d620e79ae28994856541761a951074551518Mindy Pereira                mMockRecips.length + 1);
78820c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
78920c9d620e79ae28994856541761a951074551518Mindy Pereira                .toString().indexOf("user2@user.com") - 1, RecipientChip.class).length, 1);
79020c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
79120c9d620e79ae28994856541761a951074551518Mindy Pereira                .length(), RecipientChip.class).length, 0);
79220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), first + second + third + "<user1>, user2@user.com");
79320c9d620e79ae28994856541761a951074551518Mindy Pereira
79420c9d620e79ae28994856541761a951074551518Mindy Pereira        // Paste 2 addresses after existing chips. We expect the first address to be turned into
79520c9d620e79ae28994856541761a951074551518Mindy Pereira        // a chip and the second to be left as text. This removes the space seperator char between
79620c9d620e79ae28994856541761a951074551518Mindy Pereira        // addresses.
79720c9d620e79ae28994856541761a951074551518Mindy Pereira        populateMocks(3);
79820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
79920c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(first + second + third);
80020c9d620e79ae28994856541761a951074551518Mindy Pereira
80120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
80220c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
80320c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
80420c9d620e79ae28994856541761a951074551518Mindy Pereira
80520c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user1,user2@user.com");
80620c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
80720c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
80820c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length,
80920c9d620e79ae28994856541761a951074551518Mindy Pereira                mMockRecips.length + 1);
81020c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
81120c9d620e79ae28994856541761a951074551518Mindy Pereira                .toString().indexOf("user2@user.com") - 1, RecipientChip.class).length, 1);
81220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
81320c9d620e79ae28994856541761a951074551518Mindy Pereira                .length(), RecipientChip.class).length, 0);
81420c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), first + second + third + "<user1>, user2@user.com");
81520c9d620e79ae28994856541761a951074551518Mindy Pereira
81620c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test a complete token pasted in at the end. It should be turned into a chip.
81720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
81820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user1, user2@user.com,");
81920c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
82020c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
82120c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 2);
82220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
82320c9d620e79ae28994856541761a951074551518Mindy Pereira                .toString().indexOf("user2@user.com") - 1, RecipientChip.class).length, 1);
82420c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
82520c9d620e79ae28994856541761a951074551518Mindy Pereira                .length(), RecipientChip.class).length, 1);
82620c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), "<user1>, <user2@user.com>, ");
82720c9d620e79ae28994856541761a951074551518Mindy Pereira    }
82820c9d620e79ae28994856541761a951074551518Mindy Pereira
82920c9d620e79ae28994856541761a951074551518Mindy Pereira    public void testGetPastTerminators() {
83020c9d620e79ae28994856541761a951074551518Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
83120c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setMoreItem(createTestMoreItem());
83220c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipBackground(createChipBackground());
83320c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipHeight(48);
83420c9d620e79ae28994856541761a951074551518Mindy Pereira        String test = "test";
83520c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
83620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
83720c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
83820c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
83920c9d620e79ae28994856541761a951074551518Mindy Pereira
84020c9d620e79ae28994856541761a951074551518Mindy Pereira        test = "test,";
84120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
84220c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
84320c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
84420c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
84520c9d620e79ae28994856541761a951074551518Mindy Pereira
84620c9d620e79ae28994856541761a951074551518Mindy Pereira        test = "test, ";
84720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
84820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
84920c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
85020c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
85120c9d620e79ae28994856541761a951074551518Mindy Pereira
85220c9d620e79ae28994856541761a951074551518Mindy Pereira        test = "test;";
85320c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
85420c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
85520c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
85620c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
85720c9d620e79ae28994856541761a951074551518Mindy Pereira
85820c9d620e79ae28994856541761a951074551518Mindy Pereira        test = "test; ";
85920c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
86020c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
86120c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
86220c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
86320c9d620e79ae28994856541761a951074551518Mindy Pereira    }
86420c9d620e79ae28994856541761a951074551518Mindy Pereira
86520c9d620e79ae28994856541761a951074551518Mindy Pereira    public void testIsCompletedToken() {
86620c9d620e79ae28994856541761a951074551518Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
86720c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setMoreItem(createTestMoreItem());
86820c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipBackground(createChipBackground());
86920c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipHeight(48);
87020c9d620e79ae28994856541761a951074551518Mindy Pereira        assertTrue(view.isCompletedToken("test;"));
87120c9d620e79ae28994856541761a951074551518Mindy Pereira        assertTrue(view.isCompletedToken("test,"));
87220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertFalse(view.isCompletedToken("test"));
87320c9d620e79ae28994856541761a951074551518Mindy Pereira        assertFalse(view.isCompletedToken("test "));
87420c9d620e79ae28994856541761a951074551518Mindy Pereira    }
87520c9d620e79ae28994856541761a951074551518Mindy Pereira
876aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira    public void testGetLastChip() {
877aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        populateMocks(3);
878aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
879aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.setMoreItem(createTestMoreItem());
880aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.setChipBackground(createChipBackground());
881aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.setChipHeight(48);
882aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
883aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
884aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
885aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable = new SpannableStringBuilder();
886aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.append(first + second + third);
887aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira
888aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        // Test replacing the first chip with a new chip.
889aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
890aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int firstEnd = firstStart + first.trim().length();
891aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
892aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int secondEnd = secondStart + second.trim().length();
893aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
894aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int thirdEnd = thirdStart + third.trim().length();
895aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
896aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
897aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
898aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(view.getLastChip(), mMockRecips[mMockRecips.length - 1]);
899aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.append("extra");
900aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(view.getLastChip(), mMockRecips[mMockRecips.length - 1]);
901aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira    }
902aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira
90397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    private Drawable createChipBackground() {
90497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        Bitmap drawable = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
90597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        return new BitmapDrawable(getContext().getResources(), drawable);
90697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    }
90797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
908d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    private TextView createTestMoreItem() {
909d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        TextView view = new TextView(getContext());
910d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.setText("<xliff:g id='count'>%1$s</xliff:g> more...");
911d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        return view;
912d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    }
913d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
9148eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira    private void populateMocks(int size) {
9158eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        mMockEntries = new RecipientEntry[size];
9168eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        for (int i = 0; i < size; i++) {
9178eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira            mMockEntries[i] = RecipientEntry.constructGeneratedEntry("user",
9188eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira                    "user@username.com");
9198eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        }
9208eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        mMockRecips = new RecipientChip[size];
9218eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        for (int i = 0; i < size; i++) {
9228eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira            mMockRecips[i] = new RecipientChip(null, mMockEntries[i], i);
9238eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        }
9247cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira    }
9257cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira}
926