ChipsTest.java revision f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4
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
122bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira    private class TestBaseRecipientAdapter extends BaseRecipientAdapter {
123bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira        public TestBaseRecipientAdapter(Context context) {
124bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira            super(context);
125bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira        }
126bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira    }
127bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira
12801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    private MockRecipientEditTextView createViewForTesting() {
12901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable = new SpannableStringBuilder();
13001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        MockRecipientEditTextView view = new MockRecipientEditTextView(getContext());
131bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira        view.setAdapter(new TestBaseRecipientAdapter(getContext()));
13201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        return view;
13301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    }
13401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
13501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    public void testCreateDisplayText() {
13601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEditTextView view = createViewForTesting();
13701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEntry entry = RecipientEntry.constructGeneratedEntry("User Name, Jr",
138b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                "user@username.com", true);
139aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String testAddress = view.createAddressText(entry);
140aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String testDisplay = view.createChipDisplayText(entry);
14101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals("Expected a properly formatted RFC email address",
142aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira                "\"User Name, Jr\" <user@username.com>, ", testAddress);
143aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals("Expected a displayable name", "User Name, Jr", testDisplay);
144aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira
14501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
146b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy        RecipientEntry alreadyFormatted =
147b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                RecipientEntry.constructFakeEntry("user@username.com, ", true);
148aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testAddress = view.createAddressText(alreadyFormatted);
149aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testDisplay = view.createChipDisplayText(alreadyFormatted);
15001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals("Expected a properly formatted RFC email address", "<user@username.com>, ",
151aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira                testAddress);
152aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals("Expected a displayable name", "user@username.com", testDisplay);
15301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
15401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEntry alreadyFormattedNoSpace = RecipientEntry
155b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                .constructFakeEntry("user@username.com,", true);
156aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testAddress = view.createAddressText(alreadyFormattedNoSpace);
15701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals("Expected a properly formatted RFC email address", "<user@username.com>, ",
158aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira                testAddress);
15901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
16001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEntry alreadyNamed = RecipientEntry.constructGeneratedEntry("User Name",
161b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                "\"User Name, Jr\" <user@username.com>", true);
162aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testAddress = view.createAddressText(alreadyNamed);
163aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testDisplay = view.createChipDisplayText(alreadyNamed);
16401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(
16501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira                "Expected address that used the name not the excess address name",
166aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira                "User Name <user@username.com>, ", testAddress);
167aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals("Expected a displayable name", "User Name", testDisplay);
16801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    }
1697cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira
17001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    public void testSanitizeBetween() {
171fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // First, add 2 chips and then make sure we remove
172fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // the extra content between them correctly.
1738eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        populateMocks(2);
17401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
17501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
17601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
17701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        String extra = "EXTRA";
178d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable = new SpannableStringBuilder();
17901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.append(first + extra + second);
18001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
18162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
18201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
18362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
18401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], firstStart, firstEnd, 0);
18501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], secondStart, secondEnd, 0);
18601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        view.sanitizeBetween();
18701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        String editableString = mEditable.toString();
18801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(editableString.indexOf(extra), -1);
18901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(editableString.indexOf(first), firstStart);
19001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(editableString.indexOf(second), secondStart - extra.length());
19101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(editableString, (first + second));
192399bda87ad1a4d003609d6d27afc50c8359846b9Mindy Pereira
193fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Add 1 chip and make sure that we remove the extra stuff before it correctly.
19401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable = new SpannableStringBuilder();
1958eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        populateMocks(1);
1968eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        mEditable.append(extra);
19701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.append(first);
19801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        firstStart = mEditable.toString().indexOf(first);
19901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        firstEnd = firstStart + first.length();
20001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], firstStart, firstEnd, 0);
20101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        view.sanitizeBetween();
20201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(mEditable.toString(), first);
2038eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), firstStart
2048eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira                - extra.length());
2058eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira    }
2068eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira
207aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira    public void testSanitizeEnd() {
208aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        // First, add 2 chips and then make sure we remove
209aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        // the extra content between them correctly.
210aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        populateMocks(2);
211aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
212aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
213aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
214aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String extra = "EXTRA";
215aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable = new SpannableStringBuilder();
216aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.append(first + second);
217aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
218aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int firstEnd = firstStart + first.trim().length();
219aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
220aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int secondEnd = secondStart + second.trim().length();
221aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], firstStart, firstEnd, 0);
222aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], secondStart, secondEnd, 0);
223aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.sanitizeEnd();
224aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String editableString = mEditable.toString();
225aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(editableString.indexOf(extra), -1);
226aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(editableString.indexOf(first), firstStart);
227aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(editableString.indexOf(second), secondStart);
228aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(editableString, (first + second));
229aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.append(extra);
230aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        editableString = mEditable.toString();
231aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(mEditable.toString(), (first + second + extra));
232aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.sanitizeEnd();
233aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(mEditable.toString(), (first + second));
234aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira    }
235aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira
236f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    public void testMoreChipPlainText() {
237f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
238f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.setMoreItem(createTestMoreItem());
239f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
240f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
241f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
242f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        mEditable = new SpannableStringBuilder();
243f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        mEditable.append(first+second+third);
244f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
245f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        int thirdEnd = thirdStart + third.trim().length();
246f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.createMoreChipPlainText();
247f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        ImageSpan moreChip = view.getMoreChip();
248f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
249f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
250f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    }
251f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
252f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    public void testCountTokens() {
253f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
254f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.setMoreItem(createTestMoreItem());
255f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
256f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
257f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
258f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy        String fourth = "FOURTH,";
259f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy        String fifth = "FIFTH,";
260f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        mEditable = new SpannableStringBuilder();
261f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        mEditable.append(first+second+third+fourth+fifth);
262f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.countTokens(mEditable), 5);
263f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    }
264f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
265f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    public void testTooManyRecips() {
266f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        BaseMockRecipientEditTextView view = new BaseMockRecipientEditTextView(getContext());
267f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.setMoreItem(createTestMoreItem());
268f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        for (int i = 0; i < 100; i++) {
269f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            view.append(mTokenizer.terminateToken(i + ""));
270f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
271f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.countTokens(view.getText()), 100);
272f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.handlePendingChips();
273f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.createMoreChip();
274f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        ImageSpan moreChip = view.getMoreChip();
275f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        // We show 2 chips then place a more chip.
276f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        int secondStart = view.getText().toString().indexOf(
277f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira                (String) mTokenizer.terminateToken(RecipientEditTextView.CHIP_LIMIT + ""));
278f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.getText().getSpanStart(moreChip), secondStart);
279f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.getText().getSpanEnd(moreChip), view.length());
280f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.getSortedRecipients(), null);
281f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    }
282f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
283d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    public void testMoreChip() {
284fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Add 3 chips: this is the trigger point at which the more chip will be created.
285fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test that adding the chips and then creating and removing the more chip, as if
286fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // the user were focusing/ removing focus from the chips field.
287d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        populateMocks(3);
288d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
289d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.setMoreItem(createTestMoreItem());
290d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
291d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
292d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
293d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable = new SpannableStringBuilder();
294d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.append(first+second+third);
295d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
296d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
29762397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
298d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
29962397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
300d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
30162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
302d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
303d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
304d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
305d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
306d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.createMoreChip();
307d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
308d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
309d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
310d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Find the more chip.
311d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        ImageSpan moreChip = view.getMoreChip();
312d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
313f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
314d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
315d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.removeMoreChip();
316d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
317d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
318d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
319d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
320d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
321d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
322d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
323d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
324d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
325d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Rinse and repeat, just in case!
326d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.createMoreChip();
327d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
328d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
329d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
330d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Find the more chip.
331d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
332d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
333f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
334d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
335d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.removeMoreChip();
336d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
337d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
338d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
339d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
340d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
341d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
342d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
343d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
344d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    }
345d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
346d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    public void testMoreChipLotsOfUsers() {
347fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test adding and removing the more chip in the case where we have a lot of users.
348d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        populateMocks(10);
349d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
350d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.setMoreItem(createTestMoreItem());
351d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
352d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
353d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
354d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String fourth = (String) mTokenizer.terminateToken("FOURTH");
355d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String fifth = (String) mTokenizer.terminateToken("FIFTH");
356d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String sixth = (String) mTokenizer.terminateToken("SIXTH");
357d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String seventh = (String) mTokenizer.terminateToken("SEVENTH");
358d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String eigth = (String) mTokenizer.terminateToken("EIGHTH");
359d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String ninth = (String) mTokenizer.terminateToken("NINTH");
360d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String tenth = (String) mTokenizer.terminateToken("TENTH");
361d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable = new SpannableStringBuilder();
362d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.append(first+second+third+fourth+fifth+sixth+seventh+eigth+ninth+tenth);
363d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
364d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
36562397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
366d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
36762397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
368d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
36962397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
370d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int fourthStart = mEditable.toString().indexOf(fourth);
37162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int fourthEnd = fourthStart + fourth.trim().length();
372d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int fifthStart = mEditable.toString().indexOf(fifth);
37362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int fifthEnd = fifthStart + fifth.trim().length();
374d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int sixthStart = mEditable.toString().indexOf(sixth);
37562397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int sixthEnd = sixthStart + sixth.trim().length();
376d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int seventhStart = mEditable.toString().indexOf(seventh);
37762397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int seventhEnd = seventhStart + seventh.trim().length();
378d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int eighthStart = mEditable.toString().indexOf(eigth);
37962397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int eighthEnd = eighthStart + eigth.trim().length();
380d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int ninthStart = mEditable.toString().indexOf(ninth);
38162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int ninthEnd = ninthStart + ninth.trim().length();
382d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int tenthStart = mEditable.toString().indexOf(tenth);
38362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int tenthEnd = tenthStart + tenth.trim().length();
384d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 10], firstStart, firstEnd, 0);
385d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 9], secondStart, secondEnd, 0);
386d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 8], thirdStart, thirdEnd, 0);
387d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 7], fourthStart, fourthEnd, 0);
388d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 6], fifthStart, fifthEnd, 0);
389d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 5], sixthStart, sixthEnd, 0);
390d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 4], seventhStart, seventhEnd, 0);
391d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], eighthStart, eighthEnd, 0);
392d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], ninthStart, ninthEnd, 0);
393d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], tenthStart, tenthEnd, 0);
394d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
395d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.createMoreChip();
396d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first + second + third + fourth + fifth + sixth
397d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira                + seventh + eigth + ninth + tenth);
398d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 10]), firstStart);
399d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 9]), secondStart);
400d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Find the more chip.
401d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        ImageSpan moreChip = view.getMoreChip();
402d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
403f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), tenthEnd + 1);
404d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
405d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.removeMoreChip();
406d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first + second + third + fourth + fifth + sixth
407d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira                + seventh + eigth + ninth + tenth);
408d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 10]), firstStart);
409d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 9]), secondStart);
410d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
411d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 8]), thirdStart);
412d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 7]), fourthStart);
413d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 6]), fifthStart);
414d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 5]), sixthStart);
415d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), seventhStart);
416d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), eighthStart);
417d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), ninthStart);
418d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), tenthStart);
419d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
420d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
421d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
422d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    }
423d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
424d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    public void testMoreChipSpecialChars() {
425fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Make sure the more chip correctly handles extra tokenizer characters in the middle
426fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // of chip text.
427d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        populateMocks(3);
428d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
429d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.setMoreItem(createTestMoreItem());
430d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String first = (String) mTokenizer.terminateToken("FI,RST");
431d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String second = (String) mTokenizer.terminateToken("SE,COND");
432d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String third = (String) mTokenizer.terminateToken("THI,RD");
433d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable = new SpannableStringBuilder();
434d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.append(first+second+third);
435d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
436d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
43762397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
438d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
43962397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
440d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
44162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
442d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
443d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
444d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
445d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
446d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.createMoreChip();
447d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
448d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
449d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
450d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Find the more chip.
451d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        ImageSpan moreChip = view.getMoreChip();
452d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
453f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
454d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
455d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.removeMoreChip();
456d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
457d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
458d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
459d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
460d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
461d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
462d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
463d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
464d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    }
465d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
466dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira    public void testMoreChipDupes() {
467fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Make sure the more chip is correctly added and removed when we have duplicate chips.
468dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        populateMocks(4);
469dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
470dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        view.setMoreItem(createTestMoreItem());
471dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
472dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
473dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
474dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable = new SpannableStringBuilder();
475dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.append(first+second+third+third);
476dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira
477dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
47862397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
479dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
48062397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
481dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
48262397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
483dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        int thirdNextStart = mEditable.toString().indexOf(third, thirdEnd);
48462397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdNextEnd = thirdNextStart + third.trim().length();
485dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 4], firstStart, firstEnd, 0);
486dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], secondStart, secondEnd, 0);
487dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], thirdStart, thirdEnd, 0);
488dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdNextStart, thirdNextEnd, 0);
489dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira
490dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        view.createMoreChip();
491dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.toString(), first+second+third+third);
492dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), firstStart);
493dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), secondStart);
494dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        // Find the more chip.
495dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        ImageSpan moreChip = view.getMoreChip();
496dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
497f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdNextEnd + 1);
498dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira
499dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        view.removeMoreChip();
500dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.toString(), first+second+third+third);
501dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), firstStart);
502dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 4]), firstEnd);
503dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), secondStart);
504dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), thirdStart);
505dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), thirdEnd);
506dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdNextStart);
507dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdNextEnd);
508dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        moreChip = view.getMoreChip();
509dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
510dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira    }
511dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira
51297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    public void testRemoveChip() {
513fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Create 3 chips to start and test removing chips in various postions.
51497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        populateMocks(3);
51597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
51697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setMoreItem(createTestMoreItem());
51797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
51897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
51997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
52097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable = new SpannableStringBuilder();
52197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.append(first + second + third);
52297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
52397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
52497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int firstEnd = firstStart + first.length();
52597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
52697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int secondEnd = secondStart + second.length();
52797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
52897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int thirdEnd = thirdStart + third.length();
52997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
53097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
53197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
53297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second + third);
533fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test removing the middle chip.
53497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.removeChip(mMockRecips[mMockRecips.length - 2]);
53597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + third);
53697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
53797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
53897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), -1);
53997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), -1);
54097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int newThirdStart = mEditable.toString().indexOf(third);
54197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), newThirdStart);
54297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), newThirdStart
54397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                + third.length());
54497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
545fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test removing the first chip.
54697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        populateMocks(3);
54797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view = createViewForTesting();
54897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setMoreItem(createTestMoreItem());
54997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable = new SpannableStringBuilder();
55097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.append(first + second + third);
55197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
55297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        firstStart = mEditable.toString().indexOf(first);
55397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        firstEnd = firstStart + first.length();
55497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        secondStart = mEditable.toString().indexOf(second);
55597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        secondEnd = secondStart + second.length();
55697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        thirdStart = mEditable.toString().indexOf(third);
55797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        thirdEnd = thirdStart + third.length();
55897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
55997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
56097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
56197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second + third);
56297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.removeChip(mMockRecips[mMockRecips.length - 3]);
56397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), second + third);
56497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), -1);
56597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), -1);
56697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), 0);
56797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), second.length());
56897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        newThirdStart = mEditable.toString().indexOf(third);
56997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), newThirdStart);
57097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), newThirdStart
57197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                + third.length());
57297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
573fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test removing the last chip.
57497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        populateMocks(3);
57597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view = createViewForTesting();
57697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setMoreItem(createTestMoreItem());
57797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable = new SpannableStringBuilder();
57897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.append(first + second + third);
57997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
58097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        firstStart = mEditable.toString().indexOf(first);
58197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        firstEnd = firstStart + first.length();
58297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        secondStart = mEditable.toString().indexOf(second);
58397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        secondEnd = secondStart + second.length();
58497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        thirdStart = mEditable.toString().indexOf(third);
58597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        thirdEnd = thirdStart + third.length();
58697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
58797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
58897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
58997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second + third);
59097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.removeChip(mMockRecips[mMockRecips.length - 1]);
59197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second);
59297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
59397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
59497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
59597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), secondEnd);
59697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), -1);
59797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), -1);
59897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    }
59997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
60097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    public void testReplaceChip() {
60197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        populateMocks(3);
60297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
60397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setMoreItem(createTestMoreItem());
60497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setChipBackground(createChipBackground());
60597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setChipHeight(48);
60697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
60797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
60897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
60997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable = new SpannableStringBuilder();
61097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.append(first + second + third);
61197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
612fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test replacing the first chip with a new chip.
61397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
61462397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
61597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
61662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
61797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
61862397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
61997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
62097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
62197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
62297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second + third);
62397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.replaceChip(mMockRecips[mMockRecips.length - 3], RecipientEntry
624b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                .constructGeneratedEntry("replacement", "replacement@replacement.com", true));
62597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), mTokenizer
62697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .terminateToken("replacement <replacement@replacement.com>")
62797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                + second + third);
62897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), -1);
62997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), -1);
63097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), mEditable
63197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .toString().indexOf(second));
63297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), mEditable
63397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .toString().indexOf(second)
63462397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                + second.trim().length());
63597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), mEditable
63697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .toString().indexOf(third));
63797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), mEditable
63897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .toString().indexOf(third)
63962397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                + third.trim().length());
64097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        RecipientChip[] spans = mEditable.getSpans(0, mEditable.length(), RecipientChip.class);
64197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(spans.length, 3);
64297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        spans = mEditable
64397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .getSpans(0, mEditable.toString().indexOf(second) - 1, RecipientChip.class);
64497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals((String) spans[0].getDisplay(), "replacement");
645fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira
646fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira
647fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test replacing the middle chip with a new chip.
648fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable = new SpannableStringBuilder();
649fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.append(first + second + third);
650fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        firstStart = mEditable.toString().indexOf(first);
65162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        firstEnd = firstStart + first.trim().length();
652fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        secondStart = mEditable.toString().indexOf(second);
65362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        secondEnd = secondStart + second.trim().length();
654fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        thirdStart = mEditable.toString().indexOf(third);
65562397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        thirdEnd = thirdStart + third.trim().length();
656fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
657fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
658fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
659fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.toString(), first + second + third);
660fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        view.replaceChip(mMockRecips[mMockRecips.length - 2], RecipientEntry
661b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                .constructGeneratedEntry("replacement", "replacement@replacement.com", true));
66262397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        assertEquals(mEditable.toString(), first + mTokenizer
66362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                .terminateToken("replacement <replacement@replacement.com>") + third);
664fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
665fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
666fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), -1);
667fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), -1);
668fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), mEditable
669fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira                .toString().indexOf(third));
670fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), mEditable
671fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira                .toString().indexOf(third)
67262397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                + third.trim().length());
673fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        spans = mEditable.getSpans(0, mEditable.length(), RecipientChip.class);
674fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(spans.length, 3);
675fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        spans = mEditable
676fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira                .getSpans(firstEnd, mEditable.toString().indexOf(third) - 1, RecipientChip.class);
677fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals((String) spans[0].getDisplay(), "replacement");
678fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira
679fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira
680fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test replacing the last chip with a new chip.
681fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable = new SpannableStringBuilder();
682fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.append(first + second + third);
683fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        firstStart = mEditable.toString().indexOf(first);
68462397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        firstEnd = firstStart + first.trim().length();
685fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        secondStart = mEditable.toString().indexOf(second);
68662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        secondEnd = secondStart + second.trim().length();
687fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        thirdStart = mEditable.toString().indexOf(third);
68862397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        thirdEnd = thirdStart + third.trim().length();
689fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
690fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
691fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
692fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.toString(), first + second + third);
693fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        view.replaceChip(mMockRecips[mMockRecips.length - 1], RecipientEntry
694b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                .constructGeneratedEntry("replacement", "replacement@replacement.com", true));
69562397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        assertEquals(mEditable.toString(), first + second + mTokenizer
69662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                .terminateToken("replacement <replacement@replacement.com>"));
697fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
698fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
699fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
700fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), secondEnd);
701fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), -1);
702fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), -1);
703fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        spans = mEditable.getSpans(0, mEditable.length(), RecipientChip.class);
704fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(spans.length, 3);
705fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        spans = mEditable
706fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira                .getSpans(secondEnd, mEditable.length(), RecipientChip.class);
707fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals((String) spans[0].getDisplay(), "replacement");
70897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    }
70997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
71020c9d620e79ae28994856541761a951074551518Mindy Pereira    public void testHandlePaste() {
71120c9d620e79ae28994856541761a951074551518Mindy Pereira        // Start with an empty edit field.
71220c9d620e79ae28994856541761a951074551518Mindy Pereira        // Add an address; the text should be left as is.
71320c9d620e79ae28994856541761a951074551518Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
71420c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setMoreItem(createTestMoreItem());
71520c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipBackground(createChipBackground());
71620c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipHeight(48);
71720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
71820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user@user.com");
71920c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
72020c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
72120c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 0);
72220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), "user@user.com");
72320c9d620e79ae28994856541761a951074551518Mindy Pereira
72420c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test adding a single address to an empty chips field with a space at
72520c9d620e79ae28994856541761a951074551518Mindy Pereira        // the end of it. The address should stay as text.
72620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
72720c9d620e79ae28994856541761a951074551518Mindy Pereira        String tokenizedUser = "user@user.com" + " ";
72820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(tokenizedUser);
72920c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
73020c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
73120c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 0);
73220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), tokenizedUser);
73320c9d620e79ae28994856541761a951074551518Mindy Pereira
73420c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test adding a single address to an empty chips field with a semicolon at
73520c9d620e79ae28994856541761a951074551518Mindy Pereira        // the end of it. The address should become a chip
73620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
73720c9d620e79ae28994856541761a951074551518Mindy Pereira        tokenizedUser = "user@user.com;";
73820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(tokenizedUser);
73920c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
74020c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
74120c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 1);
74220c9d620e79ae28994856541761a951074551518Mindy Pereira
74320c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test adding 2 address to an empty chips field. The second to last
74420c9d620e79ae28994856541761a951074551518Mindy Pereira        // address should become a chip and the last address should stay as
74520c9d620e79ae28994856541761a951074551518Mindy Pereira        // text.
74620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
74720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user1,user2@user.com");
74820c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
74920c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
75020c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 1);
75120c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.toString().indexOf("user2@user.com"),
75220c9d620e79ae28994856541761a951074551518Mindy Pereira                RecipientChip.class).length, 1);
75320c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), "<user1>, user2@user.com");
75420c9d620e79ae28994856541761a951074551518Mindy Pereira
75520c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test adding a single address to the end of existing chips. The existing
75620c9d620e79ae28994856541761a951074551518Mindy Pereira        // chips should remain, and the last address should stay as text.
75720c9d620e79ae28994856541761a951074551518Mindy Pereira        populateMocks(3);
75820c9d620e79ae28994856541761a951074551518Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
75920c9d620e79ae28994856541761a951074551518Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
76020c9d620e79ae28994856541761a951074551518Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
76120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
76220c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(first + second + third);
76320c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
76420c9d620e79ae28994856541761a951074551518Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
76520c9d620e79ae28994856541761a951074551518Mindy Pereira        int firstEnd = firstStart + first.trim().length();
76620c9d620e79ae28994856541761a951074551518Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
76720c9d620e79ae28994856541761a951074551518Mindy Pereira        int secondEnd = secondStart + second.trim().length();
76820c9d620e79ae28994856541761a951074551518Mindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
76920c9d620e79ae28994856541761a951074551518Mindy Pereira        int thirdEnd = thirdStart + third.trim().length();
77020c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
77120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
77220c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
77320c9d620e79ae28994856541761a951074551518Mindy Pereira
77420c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user@user.com");
77520c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
77620c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
77720c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length,
77820c9d620e79ae28994856541761a951074551518Mindy Pereira                mMockRecips.length);
77920c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), first + second + third + "user@user.com");
78020c9d620e79ae28994856541761a951074551518Mindy Pereira
78120c9d620e79ae28994856541761a951074551518Mindy Pereira        // Paste 2 addresses after existing chips. We expect the first address to be turned into
78220c9d620e79ae28994856541761a951074551518Mindy Pereira        // a chip and the second to be left as text.
78320c9d620e79ae28994856541761a951074551518Mindy Pereira        populateMocks(3);
78420c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
78520c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(first + second + third);
78620c9d620e79ae28994856541761a951074551518Mindy Pereira
78720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
78820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
78920c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
79020c9d620e79ae28994856541761a951074551518Mindy Pereira
79120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user1, user2@user.com");
79220c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
79320c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
79420c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length,
79520c9d620e79ae28994856541761a951074551518Mindy Pereira                mMockRecips.length + 1);
79620c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
79720c9d620e79ae28994856541761a951074551518Mindy Pereira                .toString().indexOf("user2@user.com") - 1, RecipientChip.class).length, 1);
79820c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
79920c9d620e79ae28994856541761a951074551518Mindy Pereira                .length(), RecipientChip.class).length, 0);
80020c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), first + second + third + "<user1>, user2@user.com");
80120c9d620e79ae28994856541761a951074551518Mindy Pereira
80220c9d620e79ae28994856541761a951074551518Mindy Pereira        // Paste 2 addresses after existing chips. We expect the first address to be turned into
80320c9d620e79ae28994856541761a951074551518Mindy Pereira        // a chip and the second to be left as text. This removes the space seperator char between
80420c9d620e79ae28994856541761a951074551518Mindy Pereira        // addresses.
80520c9d620e79ae28994856541761a951074551518Mindy Pereira        populateMocks(3);
80620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
80720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(first + second + third);
80820c9d620e79ae28994856541761a951074551518Mindy Pereira
80920c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
81020c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
81120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
81220c9d620e79ae28994856541761a951074551518Mindy Pereira
81320c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user1,user2@user.com");
81420c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
81520c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
81620c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length,
81720c9d620e79ae28994856541761a951074551518Mindy Pereira                mMockRecips.length + 1);
81820c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
81920c9d620e79ae28994856541761a951074551518Mindy Pereira                .toString().indexOf("user2@user.com") - 1, RecipientChip.class).length, 1);
82020c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
82120c9d620e79ae28994856541761a951074551518Mindy Pereira                .length(), RecipientChip.class).length, 0);
82220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), first + second + third + "<user1>, user2@user.com");
82320c9d620e79ae28994856541761a951074551518Mindy Pereira
82420c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test a complete token pasted in at the end. It should be turned into a chip.
82520c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
82620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user1, user2@user.com,");
82720c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
82820c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
82920c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.length(), RecipientChip.class).length, 2);
83020c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
83120c9d620e79ae28994856541761a951074551518Mindy Pereira                .toString().indexOf("user2@user.com") - 1, RecipientChip.class).length, 1);
83220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
83320c9d620e79ae28994856541761a951074551518Mindy Pereira                .length(), RecipientChip.class).length, 1);
83420c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), "<user1>, <user2@user.com>, ");
83520c9d620e79ae28994856541761a951074551518Mindy Pereira    }
83620c9d620e79ae28994856541761a951074551518Mindy Pereira
83720c9d620e79ae28994856541761a951074551518Mindy Pereira    public void testGetPastTerminators() {
83820c9d620e79ae28994856541761a951074551518Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
83920c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setMoreItem(createTestMoreItem());
84020c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipBackground(createChipBackground());
84120c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipHeight(48);
84220c9d620e79ae28994856541761a951074551518Mindy Pereira        String test = "test";
84320c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
84420c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
84520c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
84620c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
84720c9d620e79ae28994856541761a951074551518Mindy Pereira
84820c9d620e79ae28994856541761a951074551518Mindy Pereira        test = "test,";
84920c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
85020c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
85120c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
85220c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
85320c9d620e79ae28994856541761a951074551518Mindy Pereira
85420c9d620e79ae28994856541761a951074551518Mindy Pereira        test = "test, ";
85520c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
85620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
85720c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
85820c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
85920c9d620e79ae28994856541761a951074551518Mindy Pereira
86020c9d620e79ae28994856541761a951074551518Mindy Pereira        test = "test;";
86120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
86220c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
86320c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
86420c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
86520c9d620e79ae28994856541761a951074551518Mindy Pereira
86620c9d620e79ae28994856541761a951074551518Mindy Pereira        test = "test; ";
86720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
86820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
86920c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
87020c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
87120c9d620e79ae28994856541761a951074551518Mindy Pereira    }
87220c9d620e79ae28994856541761a951074551518Mindy Pereira
87320c9d620e79ae28994856541761a951074551518Mindy Pereira    public void testIsCompletedToken() {
87420c9d620e79ae28994856541761a951074551518Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
87520c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setMoreItem(createTestMoreItem());
87620c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipBackground(createChipBackground());
87720c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipHeight(48);
87820c9d620e79ae28994856541761a951074551518Mindy Pereira        assertTrue(view.isCompletedToken("test;"));
87920c9d620e79ae28994856541761a951074551518Mindy Pereira        assertTrue(view.isCompletedToken("test,"));
88020c9d620e79ae28994856541761a951074551518Mindy Pereira        assertFalse(view.isCompletedToken("test"));
88120c9d620e79ae28994856541761a951074551518Mindy Pereira        assertFalse(view.isCompletedToken("test "));
88220c9d620e79ae28994856541761a951074551518Mindy Pereira    }
88320c9d620e79ae28994856541761a951074551518Mindy Pereira
884aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira    public void testGetLastChip() {
885aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        populateMocks(3);
886aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
887aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.setMoreItem(createTestMoreItem());
888aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.setChipBackground(createChipBackground());
889aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.setChipHeight(48);
890aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
891aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
892aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
893aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable = new SpannableStringBuilder();
894aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.append(first + second + third);
895aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira
896aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        // Test replacing the first chip with a new chip.
897aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
898aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int firstEnd = firstStart + first.trim().length();
899aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
900aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int secondEnd = secondStart + second.trim().length();
901aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
902aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int thirdEnd = thirdStart + third.trim().length();
903aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
904aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
905aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
906aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(view.getLastChip(), mMockRecips[mMockRecips.length - 1]);
907aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.append("extra");
908aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(view.getLastChip(), mMockRecips[mMockRecips.length - 1]);
909aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira    }
910aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira
91197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    private Drawable createChipBackground() {
91297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        Bitmap drawable = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
91397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        return new BitmapDrawable(getContext().getResources(), drawable);
91497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    }
91597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
916d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    private TextView createTestMoreItem() {
917d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        TextView view = new TextView(getContext());
918d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.setText("<xliff:g id='count'>%1$s</xliff:g> more...");
919d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        return view;
920d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    }
921d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
9228eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira    private void populateMocks(int size) {
9238eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        mMockEntries = new RecipientEntry[size];
9248eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        for (int i = 0; i < size; i++) {
9258eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira            mMockEntries[i] = RecipientEntry.constructGeneratedEntry("user",
926b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                    "user@username.com", true);
9278eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        }
9288eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        mMockRecips = new RecipientChip[size];
9298eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        for (int i = 0; i < size; i++) {
930f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy            mMockRecips[i] = new VisibleRecipientChip(null, mMockEntries[i]);
9318eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        }
9327cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira    }
9337cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira}
934