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
19219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décampsimport android.annotation.TargetApi;
20219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décampsimport android.content.ClipData;
2101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereiraimport android.content.Context;
2297cb25912dab282cf732757f68b0405ed005f00bMindy Pereiraimport android.graphics.Bitmap;
2397cb25912dab282cf732757f68b0405ed005f00bMindy Pereiraimport android.graphics.drawable.BitmapDrawable;
2497cb25912dab282cf732757f68b0405ed005f00bMindy Pereiraimport android.graphics.drawable.Drawable;
25219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décampsimport android.net.Uri;
267cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereiraimport android.test.AndroidTestCase;
27fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereiraimport android.test.suitebuilder.annotation.SmallTest;
2801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereiraimport android.text.Editable;
2901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereiraimport android.text.SpannableStringBuilder;
3001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereiraimport android.text.util.Rfc822Tokenizer;
31d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereiraimport android.widget.TextView;
3201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
33194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedyimport com.android.ex.chips.recipientchip.DrawableRecipientChip;
346c2a016fb00482339dc66b93822042f9f9e2424fJin Caoimport com.android.ex.chips.recipientchip.ReplacementDrawableSpan;
35858e094f1c695aefdf6a23f522c0f16d81bd79f7Scott Kennedyimport com.android.ex.chips.recipientchip.VisibleRecipientChip;
3601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
37983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedyimport java.util.regex.Pattern;
38983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy
39fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira@SmallTest
407cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereirapublic class ChipsTest extends AndroidTestCase {
41194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy    private DrawableRecipientChip[] mMockRecips;
4201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
438eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira    private RecipientEntry[] mMockEntries;
4401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
4501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    private Rfc822Tokenizer mTokenizer;
4601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
4701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    private Editable mEditable;
4801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
49f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    class BaseMockRecipientEditTextView extends RecipientEditTextView {
5001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
51f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        public BaseMockRecipientEditTextView(Context context) {
5201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira            super(context, null);
5301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira            mTokenizer = new Rfc822Tokenizer();
5401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira            setTokenizer(mTokenizer);
5501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        }
5601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
5701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        @Override
58194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        public DrawableRecipientChip[] getSortedRecipients() {
5901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira            return mMockRecips;
6001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        }
6101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
6201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        @Override
63f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        public int getLineHeight() {
64f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            return 48;
65f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
66f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
67f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        @Override
68f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        Drawable getChipBackground(RecipientEntry contact) {
69f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            return createChipBackground();
70f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
71f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
72f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        @Override
73f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        public int getViewWidth() {
74f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            return 100;
75f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
76f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    }
77f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
78f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    class MockRecipientEditTextView extends BaseMockRecipientEditTextView {
79f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
80f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        public MockRecipientEditTextView(Context context) {
81f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            super(context);
82f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            mTokenizer = new Rfc822Tokenizer();
83f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            setTokenizer(mTokenizer);
84f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
85f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
86f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        @Override
87194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        public DrawableRecipientChip[] getSortedRecipients() {
88f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            return mMockRecips;
89f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
90f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
91f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        @Override
9201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        public Editable getText() {
9301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira            return mEditable;
9401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        }
9501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
9601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        @Override
9701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        public Editable getSpannable() {
9801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira            return mEditable;
9901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        }
100d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
101d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        @Override
102d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        public int getLineHeight() {
103d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira            return 48;
104d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        }
10597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
10620c9d620e79ae28994856541761a951074551518Mindy Pereira        @Override
107aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        Drawable getChipBackground(RecipientEntry contact) {
10897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira            return createChipBackground();
10997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        }
11020c9d620e79ae28994856541761a951074551518Mindy Pereira
11120c9d620e79ae28994856541761a951074551518Mindy Pereira        @Override
11220c9d620e79ae28994856541761a951074551518Mindy Pereira        public int length() {
11320c9d620e79ae28994856541761a951074551518Mindy Pereira            return mEditable != null ? mEditable.length() : 0;
11420c9d620e79ae28994856541761a951074551518Mindy Pereira        }
11520c9d620e79ae28994856541761a951074551518Mindy Pereira
11620c9d620e79ae28994856541761a951074551518Mindy Pereira        @Override
11720c9d620e79ae28994856541761a951074551518Mindy Pereira        public String toString() {
11820c9d620e79ae28994856541761a951074551518Mindy Pereira            return mEditable != null ? mEditable.toString() : "";
11920c9d620e79ae28994856541761a951074551518Mindy Pereira        }
120f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
121f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        @Override
122f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        public int getViewWidth() {
123f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            return 100;
124f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
12501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    }
12601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
127bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira    private class TestBaseRecipientAdapter extends BaseRecipientAdapter {
128983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        public TestBaseRecipientAdapter(final Context context) {
129bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira            super(context);
130bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira        }
131983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy
132983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        public TestBaseRecipientAdapter(final Context context, final int preferredMaxResultCount,
133983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy                final int queryMode) {
134983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy            super(context, preferredMaxResultCount, queryMode);
135983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        }
136bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira    }
137bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira
13801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    private MockRecipientEditTextView createViewForTesting() {
13901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable = new SpannableStringBuilder();
14001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        MockRecipientEditTextView view = new MockRecipientEditTextView(getContext());
141bdf58b6b2b95396b080f13727ddcb459fa0fa16aMindy Pereira        view.setAdapter(new TestBaseRecipientAdapter(getContext()));
14201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        return view;
14301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    }
14401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
14501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    public void testCreateDisplayText() {
14601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEditTextView view = createViewForTesting();
14701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEntry entry = RecipientEntry.constructGeneratedEntry("User Name, Jr",
148b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                "user@username.com", true);
149aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String testAddress = view.createAddressText(entry);
150aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String testDisplay = view.createChipDisplayText(entry);
15101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals("Expected a properly formatted RFC email address",
152aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira                "\"User Name, Jr\" <user@username.com>, ", testAddress);
153aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals("Expected a displayable name", "User Name, Jr", testDisplay);
154aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira
155b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy        RecipientEntry alreadyFormatted =
156b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                RecipientEntry.constructFakeEntry("user@username.com, ", true);
157aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testAddress = view.createAddressText(alreadyFormatted);
158aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testDisplay = view.createChipDisplayText(alreadyFormatted);
15901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals("Expected a properly formatted RFC email address", "<user@username.com>, ",
160aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira                testAddress);
161aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals("Expected a displayable name", "user@username.com", testDisplay);
16201162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
16301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEntry alreadyFormattedNoSpace = RecipientEntry
164b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                .constructFakeEntry("user@username.com,", true);
165aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testAddress = view.createAddressText(alreadyFormattedNoSpace);
16601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals("Expected a properly formatted RFC email address", "<user@username.com>, ",
167aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira                testAddress);
16801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira
16901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        RecipientEntry alreadyNamed = RecipientEntry.constructGeneratedEntry("User Name",
170b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                "\"User Name, Jr\" <user@username.com>", true);
171aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testAddress = view.createAddressText(alreadyNamed);
172aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        testDisplay = view.createChipDisplayText(alreadyNamed);
17301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(
17401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira                "Expected address that used the name not the excess address name",
175aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira                "User Name <user@username.com>, ", testAddress);
176aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals("Expected a displayable name", "User Name", testDisplay);
17701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    }
1787cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira
17901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira    public void testSanitizeBetween() {
180fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // First, add 2 chips and then make sure we remove
181fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // the extra content between them correctly.
1828eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        populateMocks(2);
18301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
18401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
18501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
18601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        String extra = "EXTRA";
187d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable = new SpannableStringBuilder();
18801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.append(first + extra + second);
18901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
19062397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
19101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
19262397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
19301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], firstStart, firstEnd, 0);
19401162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], secondStart, secondEnd, 0);
19501162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        view.sanitizeBetween();
19601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        String editableString = mEditable.toString();
19701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(editableString.indexOf(extra), -1);
19801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(editableString.indexOf(first), firstStart);
19901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(editableString.indexOf(second), secondStart - extra.length());
20001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(editableString, (first + second));
201399bda87ad1a4d003609d6d27afc50c8359846b9Mindy Pereira
202fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Add 1 chip and make sure that we remove the extra stuff before it correctly.
20301162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable = new SpannableStringBuilder();
2048eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        populateMocks(1);
2058eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        mEditable.append(extra);
20601162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.append(first);
20701162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        firstStart = mEditable.toString().indexOf(first);
20801162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        firstEnd = firstStart + first.length();
20901162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], firstStart, firstEnd, 0);
21001162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        view.sanitizeBetween();
21101162ce6739af1c9d9870f8e7e489f805c7e6794Mindy Pereira        assertEquals(mEditable.toString(), first);
2128eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), firstStart
2138eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira                - extra.length());
2148eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira    }
2158eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira
216aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira    public void testSanitizeEnd() {
217aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        // First, add 2 chips and then make sure we remove
218aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        // the extra content between them correctly.
219aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        populateMocks(2);
220aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
221aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
222aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
223aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String extra = "EXTRA";
224aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable = new SpannableStringBuilder();
225aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.append(first + second);
226aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
227aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int firstEnd = firstStart + first.trim().length();
228aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
229aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int secondEnd = secondStart + second.trim().length();
230aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], firstStart, firstEnd, 0);
231aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], secondStart, secondEnd, 0);
232aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.sanitizeEnd();
233aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String editableString = mEditable.toString();
234aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(editableString.indexOf(extra), -1);
235aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(editableString.indexOf(first), firstStart);
236aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(editableString.indexOf(second), secondStart);
237aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(editableString, (first + second));
238aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.append(extra);
239aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        editableString = mEditable.toString();
240aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(mEditable.toString(), (first + second + extra));
241aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.sanitizeEnd();
242aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(mEditable.toString(), (first + second));
243aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira    }
244aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira
245f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    public void testMoreChipPlainText() {
246f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
247f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.setMoreItem(createTestMoreItem());
248f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
249f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
250f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
251f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        mEditable = new SpannableStringBuilder();
252f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        mEditable.append(first+second+third);
253f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
254f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        int thirdEnd = thirdStart + third.trim().length();
255f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.createMoreChipPlainText();
2566c2a016fb00482339dc66b93822042f9f9e2424fJin Cao        ReplacementDrawableSpan moreChip = view.getMoreChip();
257f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
258f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
259f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    }
260f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
261f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    public void testCountTokens() {
262f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
263f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.setMoreItem(createTestMoreItem());
264f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
265f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
266f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
267f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy        String fourth = "FOURTH,";
268f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy        String fifth = "FIFTH,";
269f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        mEditable = new SpannableStringBuilder();
270f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        mEditable.append(first+second+third+fourth+fifth);
271f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.countTokens(mEditable), 5);
272f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    }
273f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
274f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    public void testTooManyRecips() {
275f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        BaseMockRecipientEditTextView view = new BaseMockRecipientEditTextView(getContext());
276f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.setMoreItem(createTestMoreItem());
277f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        for (int i = 0; i < 100; i++) {
278f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira            view.append(mTokenizer.terminateToken(i + ""));
279f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        }
280f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.countTokens(view.getText()), 100);
281f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.handlePendingChips();
282f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        view.createMoreChip();
2836c2a016fb00482339dc66b93822042f9f9e2424fJin Cao        ReplacementDrawableSpan moreChip = view.getMoreChip();
284f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        // We show 2 chips then place a more chip.
285f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        int secondStart = view.getText().toString().indexOf(
286f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira                (String) mTokenizer.terminateToken(RecipientEditTextView.CHIP_LIMIT + ""));
287f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.getText().getSpanStart(moreChip), secondStart);
288f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.getText().getSpanEnd(moreChip), view.length());
289f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(view.getSortedRecipients(), null);
290f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira    }
291f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira
292d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    public void testMoreChip() {
293fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Add 3 chips: this is the trigger point at which the more chip will be created.
294fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test that adding the chips and then creating and removing the more chip, as if
295fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // the user were focusing/ removing focus from the chips field.
296d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        populateMocks(3);
297d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
298d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.setMoreItem(createTestMoreItem());
299d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
300d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
301d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
302d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable = new SpannableStringBuilder();
303d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.append(first+second+third);
304d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
305d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
30662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
307d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
30862397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
309d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
31062397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
311d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
312d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
313d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
314d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
315d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.createMoreChip();
316d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
317d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
318d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
319d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Find the more chip.
3206c2a016fb00482339dc66b93822042f9f9e2424fJin Cao        ReplacementDrawableSpan moreChip = view.getMoreChip();
321d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
322f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
323d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
324d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.removeMoreChip();
325d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
326d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
327d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
328d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
329d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
330d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
331d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
332d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
333d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
334d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Rinse and repeat, just in case!
335d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.createMoreChip();
336d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
337d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
338d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
339d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Find the more chip.
340d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
341d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
342f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
343d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
344d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.removeMoreChip();
345d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
346d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
347d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
348d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
349d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
350d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
351d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
352d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
353d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    }
354d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
355d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    public void testMoreChipLotsOfUsers() {
356fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test adding and removing the more chip in the case where we have a lot of users.
357d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        populateMocks(10);
358d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
359d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.setMoreItem(createTestMoreItem());
360d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
361d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
362d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
363d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String fourth = (String) mTokenizer.terminateToken("FOURTH");
364d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String fifth = (String) mTokenizer.terminateToken("FIFTH");
365d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String sixth = (String) mTokenizer.terminateToken("SIXTH");
366d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String seventh = (String) mTokenizer.terminateToken("SEVENTH");
367d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String eigth = (String) mTokenizer.terminateToken("EIGHTH");
368d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String ninth = (String) mTokenizer.terminateToken("NINTH");
369d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String tenth = (String) mTokenizer.terminateToken("TENTH");
370d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable = new SpannableStringBuilder();
371d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.append(first+second+third+fourth+fifth+sixth+seventh+eigth+ninth+tenth);
372d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
373d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
37462397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
375d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
37662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
377d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
37862397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
379d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int fourthStart = mEditable.toString().indexOf(fourth);
38062397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int fourthEnd = fourthStart + fourth.trim().length();
381d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int fifthStart = mEditable.toString().indexOf(fifth);
38262397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int fifthEnd = fifthStart + fifth.trim().length();
383d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int sixthStart = mEditable.toString().indexOf(sixth);
38462397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int sixthEnd = sixthStart + sixth.trim().length();
385d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int seventhStart = mEditable.toString().indexOf(seventh);
38662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int seventhEnd = seventhStart + seventh.trim().length();
387d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int eighthStart = mEditable.toString().indexOf(eigth);
38862397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int eighthEnd = eighthStart + eigth.trim().length();
389d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int ninthStart = mEditable.toString().indexOf(ninth);
39062397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int ninthEnd = ninthStart + ninth.trim().length();
391d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int tenthStart = mEditable.toString().indexOf(tenth);
39262397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int tenthEnd = tenthStart + tenth.trim().length();
393d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 10], firstStart, firstEnd, 0);
394d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 9], secondStart, secondEnd, 0);
395d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 8], thirdStart, thirdEnd, 0);
396d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 7], fourthStart, fourthEnd, 0);
397d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 6], fifthStart, fifthEnd, 0);
398d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 5], sixthStart, sixthEnd, 0);
399d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 4], seventhStart, seventhEnd, 0);
400d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], eighthStart, eighthEnd, 0);
401d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], ninthStart, ninthEnd, 0);
402d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], tenthStart, tenthEnd, 0);
403d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
404d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.createMoreChip();
405d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first + second + third + fourth + fifth + sixth
406d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira                + seventh + eigth + ninth + tenth);
407d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 10]), firstStart);
408d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 9]), secondStart);
409d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Find the more chip.
4106c2a016fb00482339dc66b93822042f9f9e2424fJin Cao        ReplacementDrawableSpan moreChip = view.getMoreChip();
411d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
412f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), tenthEnd + 1);
413d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
414d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.removeMoreChip();
415d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first + second + third + fourth + fifth + sixth
416d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira                + seventh + eigth + ninth + tenth);
417d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 10]), firstStart);
418d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 9]), secondStart);
419d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
420d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 8]), thirdStart);
421d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 7]), fourthStart);
422d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 6]), fifthStart);
423d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 5]), sixthStart);
424d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), seventhStart);
425d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), eighthStart);
426d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), ninthStart);
427d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), tenthStart);
428d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
429d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
430d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
431d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    }
432d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
433d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    public void testMoreChipSpecialChars() {
434fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Make sure the more chip correctly handles extra tokenizer characters in the middle
435fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // of chip text.
436d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        populateMocks(3);
437d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
438d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.setMoreItem(createTestMoreItem());
439d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String first = (String) mTokenizer.terminateToken("FI,RST");
440d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String second = (String) mTokenizer.terminateToken("SE,COND");
441d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        String third = (String) mTokenizer.terminateToken("THI,RD");
442d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable = new SpannableStringBuilder();
443d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.append(first+second+third);
444d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
445d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
44662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
447d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
44862397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
449d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
45062397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
451d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
452d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
453d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
454d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
455d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.createMoreChip();
456d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
457d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
458d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
459d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        // Find the more chip.
4606c2a016fb00482339dc66b93822042f9f9e2424fJin Cao        ReplacementDrawableSpan moreChip = view.getMoreChip();
461d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
462f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdEnd + 1);
463d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
464d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.removeMoreChip();
465d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.toString(), first+second+third);
466d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
467d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
468d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
469d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdStart);
470d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdEnd);
471d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        moreChip = view.getMoreChip();
472d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
473d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    }
474d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
475dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira    public void testMoreChipDupes() {
476fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Make sure the more chip is correctly added and removed when we have duplicate chips.
477dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        populateMocks(4);
478dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
479dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        view.setMoreItem(createTestMoreItem());
480dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
481dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
482dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
483dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable = new SpannableStringBuilder();
484dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.append(first+second+third+third);
485dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira
486dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
48762397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
488dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
48962397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
490dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
49162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
492dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        int thirdNextStart = mEditable.toString().indexOf(third, thirdEnd);
49362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdNextEnd = thirdNextStart + third.trim().length();
494dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 4], firstStart, firstEnd, 0);
495dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], secondStart, secondEnd, 0);
496dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], thirdStart, thirdEnd, 0);
497dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdNextStart, thirdNextEnd, 0);
498dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira
499dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        view.createMoreChip();
500dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.toString(), first+second+third+third);
501dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), firstStart);
502dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), secondStart);
503dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        // Find the more chip.
5046c2a016fb00482339dc66b93822042f9f9e2424fJin Cao        ReplacementDrawableSpan moreChip = view.getMoreChip();
505dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), thirdStart);
506f6519d2aabaac51fd62dc819c109db86748d79e8Mindy Pereira        assertEquals(mEditable.getSpanEnd(moreChip), thirdNextEnd + 1);
507dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira
508dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        view.removeMoreChip();
509dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.toString(), first+second+third+third);
510dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 4]), firstStart);
511dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 4]), firstEnd);
512dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), secondStart);
513dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), thirdStart);
514dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), thirdEnd);
515dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), thirdNextStart);
516dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), thirdNextEnd);
517dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        moreChip = view.getMoreChip();
518dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira        assertEquals(mEditable.getSpanStart(moreChip), -1);
519dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira    }
520dfeb97f6b18cdeff9872f8d32cd7a33baa1f8825Mindy Pereira
52197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    public void testRemoveChip() {
522fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Create 3 chips to start and test removing chips in various postions.
52397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        populateMocks(3);
52497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
52597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setMoreItem(createTestMoreItem());
52697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
52797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
52897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
52997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable = new SpannableStringBuilder();
53097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.append(first + second + third);
53197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
53297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
53397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int firstEnd = firstStart + first.length();
53497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
53597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int secondEnd = secondStart + second.length();
53697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
53797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int thirdEnd = thirdStart + third.length();
53897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
53997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
54097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
54197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second + third);
542fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test removing the middle chip.
54397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.removeChip(mMockRecips[mMockRecips.length - 2]);
54497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + third);
54597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
54697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
54797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), -1);
54897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), -1);
54997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int newThirdStart = mEditable.toString().indexOf(third);
55097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), newThirdStart);
55197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), newThirdStart
55297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                + third.length());
55397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
554fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test removing the first chip.
55597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        populateMocks(3);
55697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view = createViewForTesting();
55797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setMoreItem(createTestMoreItem());
55897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable = new SpannableStringBuilder();
55997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.append(first + second + third);
56097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
56197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        firstStart = mEditable.toString().indexOf(first);
56297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        firstEnd = firstStart + first.length();
56397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        secondStart = mEditable.toString().indexOf(second);
56497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        secondEnd = secondStart + second.length();
56597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        thirdStart = mEditable.toString().indexOf(third);
56697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        thirdEnd = thirdStart + third.length();
56797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
56897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
56997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
57097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second + third);
57197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.removeChip(mMockRecips[mMockRecips.length - 3]);
57297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), second + third);
57397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), -1);
57497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), -1);
57597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), 0);
57697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), second.length());
57797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        newThirdStart = mEditable.toString().indexOf(third);
57897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), newThirdStart);
57997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), newThirdStart
58097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                + third.length());
58197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
582fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test removing the last chip.
58397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        populateMocks(3);
58497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view = createViewForTesting();
58597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setMoreItem(createTestMoreItem());
58697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable = new SpannableStringBuilder();
58797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.append(first + second + third);
58897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
58997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        firstStart = mEditable.toString().indexOf(first);
59097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        firstEnd = firstStart + first.length();
59197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        secondStart = mEditable.toString().indexOf(second);
59297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        secondEnd = secondStart + second.length();
59397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        thirdStart = mEditable.toString().indexOf(third);
59497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        thirdEnd = thirdStart + third.length();
59597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
59697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
59797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
59897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second + third);
59997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.removeChip(mMockRecips[mMockRecips.length - 1]);
60097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second);
60197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
60297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
60397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
60497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), secondEnd);
60597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), -1);
60697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), -1);
60797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    }
60897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
60997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    public void testReplaceChip() {
61097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        populateMocks(3);
61197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        MockRecipientEditTextView view = createViewForTesting();
61297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setMoreItem(createTestMoreItem());
61397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setChipBackground(createChipBackground());
61497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.setChipHeight(48);
61597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
61697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
61797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
61897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable = new SpannableStringBuilder();
61997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.append(first + second + third);
62097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
621fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test replacing the first chip with a new chip.
62297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int firstStart = mEditable.toString().indexOf(first);
62362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int firstEnd = firstStart + first.trim().length();
62497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int secondStart = mEditable.toString().indexOf(second);
62562397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int secondEnd = secondStart + second.trim().length();
62697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
62762397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        int thirdEnd = thirdStart + third.trim().length();
62897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
62997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
63097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
63197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), first + second + third);
63297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        view.replaceChip(mMockRecips[mMockRecips.length - 3], RecipientEntry
633b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                .constructGeneratedEntry("replacement", "replacement@replacement.com", true));
63497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.toString(), mTokenizer
63597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .terminateToken("replacement <replacement@replacement.com>")
63697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                + second + third);
63797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), -1);
63897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), -1);
63997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), mEditable
64097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .toString().indexOf(second));
64197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), mEditable
64297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .toString().indexOf(second)
64362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                + second.trim().length());
64497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), mEditable
64597cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .toString().indexOf(third));
64697cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), mEditable
64797cb25912dab282cf732757f68b0405ed005f00bMindy Pereira                .toString().indexOf(third)
64862397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                + third.trim().length());
649194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        DrawableRecipientChip[] spans =
650194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy                mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class);
65197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals(spans.length, 3);
65297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        spans = mEditable
653194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy                .getSpans(0, mEditable.toString().indexOf(second) - 1, DrawableRecipientChip.class);
65497cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        assertEquals((String) spans[0].getDisplay(), "replacement");
655fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira
656fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira
657fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test replacing the middle chip with a new chip.
658fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable = new SpannableStringBuilder();
659fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.append(first + second + third);
660fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        firstStart = mEditable.toString().indexOf(first);
66162397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        firstEnd = firstStart + first.trim().length();
662fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        secondStart = mEditable.toString().indexOf(second);
66362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        secondEnd = secondStart + second.trim().length();
664fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        thirdStart = mEditable.toString().indexOf(third);
66562397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        thirdEnd = thirdStart + third.trim().length();
666fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
667fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
668fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
669fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.toString(), first + second + third);
670fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        view.replaceChip(mMockRecips[mMockRecips.length - 2], RecipientEntry
671b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                .constructGeneratedEntry("replacement", "replacement@replacement.com", true));
67262397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        assertEquals(mEditable.toString(), first + mTokenizer
67362397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                .terminateToken("replacement <replacement@replacement.com>") + third);
674fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
675fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
676fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), -1);
677fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), -1);
678fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), mEditable
679fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira                .toString().indexOf(third));
680fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), mEditable
681fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira                .toString().indexOf(third)
68262397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                + third.trim().length());
683194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        spans = mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class);
684fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(spans.length, 3);
685194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        spans = mEditable.getSpans(firstEnd, mEditable.toString().indexOf(third) - 1,
686194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy                DrawableRecipientChip.class);
687fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals((String) spans[0].getDisplay(), "replacement");
688fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira
689fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira
690fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        // Test replacing the last chip with a new chip.
691fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable = new SpannableStringBuilder();
692fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.append(first + second + third);
693fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        firstStart = mEditable.toString().indexOf(first);
69462397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        firstEnd = firstStart + first.trim().length();
695fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        secondStart = mEditable.toString().indexOf(second);
69662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        secondEnd = secondStart + second.trim().length();
697fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        thirdStart = mEditable.toString().indexOf(third);
69862397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        thirdEnd = thirdStart + third.trim().length();
699fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
700fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
701fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
702fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.toString(), first + second + third);
703fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        view.replaceChip(mMockRecips[mMockRecips.length - 1], RecipientEntry
704b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                .constructGeneratedEntry("replacement", "replacement@replacement.com", true));
70562397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira        assertEquals(mEditable.toString(), first + second + mTokenizer
70662397a5ac6b2df89ec4c2f8f23680add5850c17aMindy Pereira                .terminateToken("replacement <replacement@replacement.com>"));
707fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 3]), firstStart);
708fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 3]), firstEnd);
709fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 2]), secondStart);
710fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 2]), secondEnd);
711fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanStart(mMockRecips[mMockRecips.length - 1]), -1);
712fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(mEditable.getSpanEnd(mMockRecips[mMockRecips.length - 1]), -1);
713194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        spans = mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class);
714fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals(spans.length, 3);
715fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        spans = mEditable
716194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy                .getSpans(secondEnd, mEditable.length(), DrawableRecipientChip.class);
717fecc6f882abd4287cdffafa947457e06b1db5112Mindy Pereira        assertEquals((String) spans[0].getDisplay(), "replacement");
71897cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    }
71997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
72020c9d620e79ae28994856541761a951074551518Mindy Pereira    public void testHandlePaste() {
72120c9d620e79ae28994856541761a951074551518Mindy Pereira        // Start with an empty edit field.
72220c9d620e79ae28994856541761a951074551518Mindy Pereira        // Add an address; the text should be left as is.
72320c9d620e79ae28994856541761a951074551518Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
72420c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setMoreItem(createTestMoreItem());
72520c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipBackground(createChipBackground());
72620c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipHeight(48);
72720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
72820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user@user.com");
72920c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
73020c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
731194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length, 0);
73220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), "user@user.com");
73320c9d620e79ae28994856541761a951074551518Mindy Pereira
73420c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test adding a single address to an empty chips field with a space at
73520c9d620e79ae28994856541761a951074551518Mindy Pereira        // the end of it. The address should stay as text.
73620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
73720c9d620e79ae28994856541761a951074551518Mindy Pereira        String tokenizedUser = "user@user.com" + " ";
73820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(tokenizedUser);
73920c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
74020c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
741194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length, 0);
74220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), tokenizedUser);
74320c9d620e79ae28994856541761a951074551518Mindy Pereira
74420c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test adding a single address to an empty chips field with a semicolon at
74520c9d620e79ae28994856541761a951074551518Mindy Pereira        // the end of it. The address should become a chip
74620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
74720c9d620e79ae28994856541761a951074551518Mindy Pereira        tokenizedUser = "user@user.com;";
74820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(tokenizedUser);
74920c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
75020c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
751194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length, 1);
75220c9d620e79ae28994856541761a951074551518Mindy Pereira
75320c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test adding 2 address to an empty chips field. The second to last
75420c9d620e79ae28994856541761a951074551518Mindy Pereira        // address should become a chip and the last address should stay as
75520c9d620e79ae28994856541761a951074551518Mindy Pereira        // text.
75620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
75720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user1,user2@user.com");
75820c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
75920c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
760194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length, 1);
76120c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(0, mEditable.toString().indexOf("user2@user.com"),
762194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy                DrawableRecipientChip.class).length, 1);
76320c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), "<user1>, user2@user.com");
76420c9d620e79ae28994856541761a951074551518Mindy Pereira
76520c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test adding a single address to the end of existing chips. The existing
76620c9d620e79ae28994856541761a951074551518Mindy Pereira        // chips should remain, and the last address should stay as text.
76720c9d620e79ae28994856541761a951074551518Mindy Pereira        populateMocks(3);
76820c9d620e79ae28994856541761a951074551518Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
76920c9d620e79ae28994856541761a951074551518Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
77020c9d620e79ae28994856541761a951074551518Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
77120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
77220c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(first + second + third);
77320c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
77420c9d620e79ae28994856541761a951074551518Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
77520c9d620e79ae28994856541761a951074551518Mindy Pereira        int firstEnd = firstStart + first.trim().length();
77620c9d620e79ae28994856541761a951074551518Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
77720c9d620e79ae28994856541761a951074551518Mindy Pereira        int secondEnd = secondStart + second.trim().length();
77820c9d620e79ae28994856541761a951074551518Mindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
77920c9d620e79ae28994856541761a951074551518Mindy Pereira        int thirdEnd = thirdStart + third.trim().length();
78020c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
78120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
78220c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
78320c9d620e79ae28994856541761a951074551518Mindy Pereira
78420c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user@user.com");
78520c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
78620c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
787194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length,
78820c9d620e79ae28994856541761a951074551518Mindy Pereira                mMockRecips.length);
78920c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), first + second + third + "user@user.com");
79020c9d620e79ae28994856541761a951074551518Mindy Pereira
79120c9d620e79ae28994856541761a951074551518Mindy Pereira        // Paste 2 addresses after existing chips. We expect the first address to be turned into
79220c9d620e79ae28994856541761a951074551518Mindy Pereira        // a chip and the second to be left as text.
79320c9d620e79ae28994856541761a951074551518Mindy Pereira        populateMocks(3);
79420c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
79520c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(first + second + third);
79620c9d620e79ae28994856541761a951074551518Mindy Pereira
79720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
79820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
79920c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
80020c9d620e79ae28994856541761a951074551518Mindy Pereira
80120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user1, user2@user.com");
80220c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
80320c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
804194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length,
80520c9d620e79ae28994856541761a951074551518Mindy Pereira                mMockRecips.length + 1);
80620c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
807194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy                .toString().indexOf("user2@user.com") - 1, DrawableRecipientChip.class).length, 1);
80820c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
809194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy                .length(), DrawableRecipientChip.class).length, 0);
81020c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), first + second + third + "<user1>, user2@user.com");
81120c9d620e79ae28994856541761a951074551518Mindy Pereira
81220c9d620e79ae28994856541761a951074551518Mindy Pereira        // Paste 2 addresses after existing chips. We expect the first address to be turned into
81320c9d620e79ae28994856541761a951074551518Mindy Pereira        // a chip and the second to be left as text. This removes the space seperator char between
81420c9d620e79ae28994856541761a951074551518Mindy Pereira        // addresses.
81520c9d620e79ae28994856541761a951074551518Mindy Pereira        populateMocks(3);
81620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
81720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(first + second + third);
81820c9d620e79ae28994856541761a951074551518Mindy Pereira
81920c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
82020c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
82120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
82220c9d620e79ae28994856541761a951074551518Mindy Pereira
82320c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user1,user2@user.com");
82420c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
82520c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
826194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length,
82720c9d620e79ae28994856541761a951074551518Mindy Pereira                mMockRecips.length + 1);
82820c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
829194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy                .toString().indexOf("user2@user.com") - 1, DrawableRecipientChip.class).length, 1);
83020c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
831194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy                .length(), DrawableRecipientChip.class).length, 0);
83220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), first + second + third + "<user1>, user2@user.com");
83320c9d620e79ae28994856541761a951074551518Mindy Pereira
83420c9d620e79ae28994856541761a951074551518Mindy Pereira        // Test a complete token pasted in at the end. It should be turned into a chip.
83520c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
83620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append("user1, user2@user.com,");
83720c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setSelection(mEditable.length());
83820c9d620e79ae28994856541761a951074551518Mindy Pereira        view.handlePaste();
839194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        assertEquals(mEditable.getSpans(0, mEditable.length(), DrawableRecipientChip.class).length, 2);
84020c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("<user1>"), mEditable
841194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy                .toString().indexOf("user2@user.com") - 1, DrawableRecipientChip.class).length, 1);
84220c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.getSpans(mEditable.toString().indexOf("user2@user.com"), mEditable
843194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy                .length(), DrawableRecipientChip.class).length, 1);
84420c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(mEditable.toString(), "<user1>, <user2@user.com>, ");
84520c9d620e79ae28994856541761a951074551518Mindy Pereira    }
84620c9d620e79ae28994856541761a951074551518Mindy Pereira
847219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps    @TargetApi(16)
848219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps    public void testHandlePasteClip() {
849219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        MockRecipientEditTextView view = createViewForTesting();
850219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps
851219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        ClipData clipData = null;
852219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        mEditable = new SpannableStringBuilder();
853219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        view.handlePasteClip(clipData);
854219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        assertEquals("", view.getText().toString());
855219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps
856219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        clipData = ClipData.newPlainText("user label", "<foo@example.com>");
857219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        mEditable = new SpannableStringBuilder();
858219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        view.handlePasteClip(clipData);
859219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        assertEquals("<foo@example.com>", view.getText().toString());
860219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps
861219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        clipData = ClipData.newHtmlText("user label",
862219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps                "<bar@example.com>", "<a href=\"mailto:bar@example.com\">email</a>");
863219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        mEditable = new SpannableStringBuilder();
864219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        view.handlePasteClip(clipData);
865219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        assertEquals("<bar@example.com>", view.getText().toString());
866219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps
867219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        ClipData.Item clipImageData = new ClipData.Item(Uri.parse("content://my/image"));
868219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        clipData = new ClipData("user label", new String[]{"image/jpeg"}, clipImageData);
869219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        mEditable = new SpannableStringBuilder();
870219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        view.handlePasteClip(clipData);
871219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        assertEquals("", view.getText().toString()
872219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps        );
873219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps    }
874219cbfbd7806b17ce10ba2cfb3f0cd45d167d46cRégis Décamps
87520c9d620e79ae28994856541761a951074551518Mindy Pereira    public void testGetPastTerminators() {
87620c9d620e79ae28994856541761a951074551518Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
87720c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setMoreItem(createTestMoreItem());
87820c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipBackground(createChipBackground());
87920c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipHeight(48);
88020c9d620e79ae28994856541761a951074551518Mindy Pereira        String test = "test";
88120c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
88220c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
88320c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
88420c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
88520c9d620e79ae28994856541761a951074551518Mindy Pereira
88620c9d620e79ae28994856541761a951074551518Mindy Pereira        test = "test,";
88720c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
88820c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
88920c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
89020c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
89120c9d620e79ae28994856541761a951074551518Mindy Pereira
89220c9d620e79ae28994856541761a951074551518Mindy Pereira        test = "test, ";
89320c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
89420c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
89520c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
89620c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
89720c9d620e79ae28994856541761a951074551518Mindy Pereira
89820c9d620e79ae28994856541761a951074551518Mindy Pereira        test = "test;";
89920c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
90020c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
90120c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
90220c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
90320c9d620e79ae28994856541761a951074551518Mindy Pereira
90420c9d620e79ae28994856541761a951074551518Mindy Pereira        test = "test; ";
90520c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable = new SpannableStringBuilder();
90620c9d620e79ae28994856541761a951074551518Mindy Pereira        mEditable.append(test);
90720c9d620e79ae28994856541761a951074551518Mindy Pereira        assertEquals(view.movePastTerminators(mTokenizer.findTokenEnd(mEditable.toString(), 0)),
90820c9d620e79ae28994856541761a951074551518Mindy Pereira                test.length());
90920c9d620e79ae28994856541761a951074551518Mindy Pereira    }
91020c9d620e79ae28994856541761a951074551518Mindy Pereira
91120c9d620e79ae28994856541761a951074551518Mindy Pereira    public void testIsCompletedToken() {
91220c9d620e79ae28994856541761a951074551518Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
91320c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setMoreItem(createTestMoreItem());
91420c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipBackground(createChipBackground());
91520c9d620e79ae28994856541761a951074551518Mindy Pereira        view.setChipHeight(48);
91620c9d620e79ae28994856541761a951074551518Mindy Pereira        assertTrue(view.isCompletedToken("test;"));
91720c9d620e79ae28994856541761a951074551518Mindy Pereira        assertTrue(view.isCompletedToken("test,"));
91820c9d620e79ae28994856541761a951074551518Mindy Pereira        assertFalse(view.isCompletedToken("test"));
91920c9d620e79ae28994856541761a951074551518Mindy Pereira        assertFalse(view.isCompletedToken("test "));
92020c9d620e79ae28994856541761a951074551518Mindy Pereira    }
92120c9d620e79ae28994856541761a951074551518Mindy Pereira
922aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira    public void testGetLastChip() {
923aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        populateMocks(3);
924aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        MockRecipientEditTextView view = createViewForTesting();
925aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.setMoreItem(createTestMoreItem());
926aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.setChipBackground(createChipBackground());
927aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        view.setChipHeight(48);
928aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String first = (String) mTokenizer.terminateToken("FIRST");
929aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String second = (String) mTokenizer.terminateToken("SECOND");
930aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        String third = (String) mTokenizer.terminateToken("THIRD");
931aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable = new SpannableStringBuilder();
932aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.append(first + second + third);
933aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira
934aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        // Test replacing the first chip with a new chip.
935aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int firstStart = mEditable.toString().indexOf(first);
936aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int firstEnd = firstStart + first.trim().length();
937aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int secondStart = mEditable.toString().indexOf(second);
938aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int secondEnd = secondStart + second.trim().length();
939aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int thirdStart = mEditable.toString().indexOf(third);
940aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        int thirdEnd = thirdStart + third.trim().length();
941aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 3], firstStart, firstEnd, 0);
942aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 2], secondStart, secondEnd, 0);
943aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.setSpan(mMockRecips[mMockRecips.length - 1], thirdStart, thirdEnd, 0);
944aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(view.getLastChip(), mMockRecips[mMockRecips.length - 1]);
945aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        mEditable.append("extra");
946aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira        assertEquals(view.getLastChip(), mMockRecips[mMockRecips.length - 1]);
947aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira    }
948aca23c4de8d85b04e6044c9a8f047c337cf427c9Mindy Pereira
94997cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    private Drawable createChipBackground() {
95097cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        Bitmap drawable = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
95197cb25912dab282cf732757f68b0405ed005f00bMindy Pereira        return new BitmapDrawable(getContext().getResources(), drawable);
95297cb25912dab282cf732757f68b0405ed005f00bMindy Pereira    }
95397cb25912dab282cf732757f68b0405ed005f00bMindy Pereira
954d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    private TextView createTestMoreItem() {
955d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        TextView view = new TextView(getContext());
956d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        view.setText("<xliff:g id='count'>%1$s</xliff:g> more...");
957d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira        return view;
958d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira    }
959d71925073f008dccd8c4b65d5d66534e6451e64dMindy Pereira
9608eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira    private void populateMocks(int size) {
9618eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        mMockEntries = new RecipientEntry[size];
9628eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        for (int i = 0; i < size; i++) {
9638eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira            mMockEntries[i] = RecipientEntry.constructGeneratedEntry("user",
964b1cddbb70524197b68d99a6805a97d50eef4e353Scott Kennedy                    "user@username.com", true);
9658eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        }
966194d427ebcfc2133bda410e0e4c399250d9a6066Scott Kennedy        mMockRecips = new DrawableRecipientChip[size];
9678eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        for (int i = 0; i < size; i++) {
968f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy            mMockRecips[i] = new VisibleRecipientChip(null, mMockEntries[i]);
9698eb031e6de46e477412d92ab0c5ef20b431f1804Mindy Pereira        }
9707cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira    }
97120c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy
97220c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy    /**
97320c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * <p>
97420c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * Ensure the original text is always accurate, regardless of the type of email. The original
97520c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * text is used to determine where to display the chip span. If this test fails, it means some
97620c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * text that should be turned into one whole chip may behave unexpectedly.
97720c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * </p>
97820c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * <p>
97920c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * For example, a bug was seen where
98020c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     *
98120c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * <pre>
98220c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * "Android User" <android@example.com>
98320c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * </pre>
98420c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     *
98520c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * was converted to
98620c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     *
98720c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * <pre>
98820c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * Android User [android@example.com]
98920c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * </pre>
99020c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     *
99120c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * where text inside [] is a chip.
99220c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     * </p>
99320c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy     */
99420c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy    public void testCreateReplacementChipOriginalText() {
99520c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        // Name in quotes + email address
99620c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        testCreateReplacementChipOriginalText("\"Android User\" <android@example.com>,");
99720c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        // Name in quotes + email address without brackets
99820c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        testCreateReplacementChipOriginalText("\"Android User\" android@example.com,");
99920c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        // Name in quotes
100020c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        testCreateReplacementChipOriginalText("\"Android User\",");
100120c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        // Name without quotes + email address
100220c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        testCreateReplacementChipOriginalText("Android User <android@example.com>,");
100320c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        // Name without quotes
100420c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        testCreateReplacementChipOriginalText("Android User,");
100520c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        // Email address
100620c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        testCreateReplacementChipOriginalText("<android@example.com>,");
100720c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        // Email address without brackets
100820c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        testCreateReplacementChipOriginalText("android@example.com,");
100920c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy    }
101020c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy
101120c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy    private void testCreateReplacementChipOriginalText(final String email) {
101220c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        // No trailing space
101320c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        attemptCreateReplacementChipOriginalText(email.trim());
101420c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        // Trailing space
101520c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        attemptCreateReplacementChipOriginalText(email.trim() + " ");
101620c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy    }
101720c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy
101820c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy    private void attemptCreateReplacementChipOriginalText(final String email) {
101920c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        final RecipientEditTextView view = new RecipientEditTextView(getContext(), null);
102020c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy
102120c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        view.setText(email);
102220c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        view.mPendingChips.add(email);
102320c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy
102420c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        view.createReplacementChip(0, email.length(), view.getText(), true);
102520c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        // The "original text" should be the email without the comma or space(s)
102620c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy        assertEquals(email.replaceAll(",\\s*$", ""),
102720c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy                view.mTemporaryRecipients.get(0).getOriginalText().toString().trim());
102820c8aa75e7213ee82089b9aea9f407ca62302167Scott Kennedy    }
1029983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy
1030983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy    public void testCreateTokenizedEntryForPhone() {
1031983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        final String phonePattern = "[^\\d]*888[^\\d]*555[^\\d]*1234[^\\d]*";
1032983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        final String phone1 = "8885551234";
1033983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        final String phone2 = "888-555-1234";
1034983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        final String phone3 = "(888) 555-1234";
1035983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy
1036983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        final RecipientEditTextView view = new RecipientEditTextView(getContext(), null);
1037983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        final BaseRecipientAdapter adapter = new TestBaseRecipientAdapter(getContext(), 10,
1038983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy                BaseRecipientAdapter.QUERY_TYPE_PHONE);
1039983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        view.setAdapter(adapter);
1040983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy
1041983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        final RecipientEntry entry1 = view.createTokenizedEntry(phone1);
1042983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        final String destination1 = entry1.getDestination();
1043983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        assertTrue(phone1 + " failed with " + destination1,
1044983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy                Pattern.matches(phonePattern, destination1));
1045983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy
1046983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        final RecipientEntry entry2 = view.createTokenizedEntry(phone2);
1047983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        final String destination2 = entry2.getDestination();
1048983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        assertTrue(phone2 + " failed with " + destination2,
1049983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy                Pattern.matches(phonePattern, destination2));
1050983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy
1051983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        final RecipientEntry entry3 = view.createTokenizedEntry(phone3);
1052983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        final String destination3 = entry3.getDestination();
1053983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy        assertTrue(phone3 + " failed with " + destination3,
1054983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy                Pattern.matches(phonePattern, destination3));
1055983c99b9e00913e8d2a5642cd05ccb9a81570be7Scott Kennedy    }
10567cb970b6d9b60b9b9828d40fea8cff395a40ecd9Mindy Pereira}
1057