/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.text;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import android.os.Parcel;
import android.support.test.filters.LargeTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.test.MoreAsserts;
import android.text.style.StyleSpan;
import android.text.util.Rfc822Token;
import android.text.util.Rfc822Tokenizer;
import android.view.View;

import com.google.android.collect.Lists;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * TextUtilsTest tests {@link TextUtils}.
 */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class TextUtilsTest {

    @Test
    public void testBasic() {
        assertEquals("", TextUtils.concat());
        assertEquals("foo", TextUtils.concat("foo"));
        assertEquals("foobar", TextUtils.concat("foo", "bar"));
        assertEquals("foobarbaz", TextUtils.concat("foo", "bar", "baz"));

        SpannableString foo = new SpannableString("foo");
        foo.setSpan("foo", 1, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

        SpannableString bar = new SpannableString("bar");
        bar.setSpan("bar", 1, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

        SpannableString baz = new SpannableString("baz");
        baz.setSpan("baz", 1, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

        assertEquals("foo", TextUtils.concat(foo).toString());
        assertEquals("foobar", TextUtils.concat(foo, bar).toString());
        assertEquals("foobarbaz", TextUtils.concat(foo, bar, baz).toString());

        assertEquals(1, ((Spanned) TextUtils.concat(foo)).getSpanStart("foo"));

        assertEquals(1, ((Spanned) TextUtils.concat(foo, bar)).getSpanStart("foo"));
        assertEquals(4, ((Spanned) TextUtils.concat(foo, bar)).getSpanStart("bar"));

        assertEquals(1, ((Spanned) TextUtils.concat(foo, bar, baz)).getSpanStart("foo"));
        assertEquals(4, ((Spanned) TextUtils.concat(foo, bar, baz)).getSpanStart("bar"));
        assertEquals(7, ((Spanned) TextUtils.concat(foo, bar, baz)).getSpanStart("baz"));

        assertTrue(TextUtils.concat("foo", "bar") instanceof String);
        assertTrue(TextUtils.concat(foo, bar) instanceof SpannedString);
    }

    @Test
    public void testTemplateString() {
        CharSequence result;

        result = TextUtils.expandTemplate("This is a ^1 of the ^2 broadcast ^3.",
                                          "test", "emergency", "system");
        assertEquals("This is a test of the emergency broadcast system.",
                     result.toString());

        result = TextUtils.expandTemplate("^^^1^^^2^3^a^1^^b^^^c",
                                          "one", "two", "three");
        assertEquals("^one^twothree^aone^b^^c",
                     result.toString());

        result = TextUtils.expandTemplate("^");
        assertEquals("^", result.toString());

        result = TextUtils.expandTemplate("^^");
        assertEquals("^", result.toString());

        result = TextUtils.expandTemplate("^^^");
        assertEquals("^^", result.toString());

        result = TextUtils.expandTemplate("shorter ^1 values ^2.", "a", "");
        assertEquals("shorter a values .", result.toString());

        try {
            TextUtils.expandTemplate("Only ^1 value given, but ^2 used.", "foo");
            fail();
        } catch (IllegalArgumentException e) {
        }

        try {
            TextUtils.expandTemplate("^1 value given, and ^0 used.", "foo");
            fail();
        } catch (IllegalArgumentException e) {
        }

        result = TextUtils.expandTemplate("^1 value given, and ^9 used.",
                                          "one", "two", "three", "four", "five",
                                          "six", "seven", "eight", "nine");
        assertEquals("one value given, and nine used.", result.toString());

        try {
            TextUtils.expandTemplate("^1 value given, and ^10 used.",
                                     "one", "two", "three", "four", "five",
                                     "six", "seven", "eight", "nine", "ten");
            fail();
        } catch (IllegalArgumentException e) {
        }

        // putting carets in the values: expansion is not recursive.

        result = TextUtils.expandTemplate("^2", "foo", "^^");
        assertEquals("^^", result.toString());

        result = TextUtils.expandTemplate("^^2", "foo", "1");
        assertEquals("^2", result.toString());

        result = TextUtils.expandTemplate("^1", "value with ^2 in it", "foo");
        assertEquals("value with ^2 in it", result.toString());
    }

    /** Fail unless text+spans contains a span 'spanName' with the given start and end. */
    private void checkContains(Spanned text, String[] spans, String spanName,
                               int start, int end) {
        for (String i: spans) {
            if (i.equals(spanName)) {
                assertEquals(start, text.getSpanStart(i));
                assertEquals(end, text.getSpanEnd(i));
                return;
            }
        }
        fail();
    }

    @Test
    public void testTemplateSpan() {
        SpannableString template;
        Spanned result;
        String[] spans;

        // ordinary replacement

        template = new SpannableString("a^1b");
        template.setSpan("before", 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        template.setSpan("during", 1, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        template.setSpan("after", 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        template.setSpan("during+after", 1, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        result = (Spanned) TextUtils.expandTemplate(template, "foo");
        assertEquals(5, result.length());
        spans = result.getSpans(0, result.length(), String.class);

        // value is one character longer, so span endpoints should change.
        assertEquals(4, spans.length);
        checkContains(result, spans, "before", 0, 1);
        checkContains(result, spans, "during", 1, 4);
        checkContains(result, spans, "after", 4, 5);
        checkContains(result, spans, "during+after", 1, 5);


        // replacement with empty string

        result = (Spanned) TextUtils.expandTemplate(template, "");
        assertEquals(2, result.length());
        spans = result.getSpans(0, result.length(), String.class);

        // the "during" span should disappear.
        assertEquals(3, spans.length);
        checkContains(result, spans, "before", 0, 1);
        checkContains(result, spans, "after", 1, 2);
        checkContains(result, spans, "during+after", 1, 2);
    }

    @Test
    public void testStringSplitterSimple() {
        stringSplitterTestHelper("a,b,cde", new String[] {"a", "b", "cde"});
    }

    @Test
    public void testStringSplitterEmpty() {
        stringSplitterTestHelper("", new String[] {});
    }

    @Test
    public void testStringSplitterWithLeadingEmptyString() {
        stringSplitterTestHelper(",a,b,cde", new String[] {"", "a", "b", "cde"});
    }

    @Test
    public void testStringSplitterWithInternalEmptyString() {
        stringSplitterTestHelper("a,b,,cde", new String[] {"a", "b", "", "cde"});
    }

    @Test
    public void testStringSplitterWithTrailingEmptyString() {
        // A single trailing emtpy string should be ignored.
        stringSplitterTestHelper("a,b,cde,", new String[] {"a", "b", "cde"});
    }

    private void stringSplitterTestHelper(String string, String[] expectedStrings) {
        TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
        splitter.setString(string);
        List<String> strings = Lists.newArrayList();
        for (String s : splitter) {
            strings.add(s);
        }
        MoreAsserts.assertEquals(expectedStrings, strings.toArray(new String[]{}));
    }

    @Test
    public void testTrim() {
        String[] strings = { "abc", " abc", "  abc", "abc ", "abc  ",
                             " abc ", "  abc  ", "\nabc\n", "\nabc", "abc\n" };

        for (String s : strings) {
            assertEquals(s.trim().length(), TextUtils.getTrimmedLength(s));
        }
    }

    @Test
    public void testRfc822TokenizerFullAddress() {
        Rfc822Token[] tokens = Rfc822Tokenizer.tokenize("Foo Bar (something) <foo@google.com>");
        assertNotNull(tokens);
        assertEquals(1, tokens.length);
        assertEquals("foo@google.com", tokens[0].getAddress());
        assertEquals("Foo Bar", tokens[0].getName());
        assertEquals("something",tokens[0].getComment());
    }

    @Test
    public void testRfc822TokenizeItemWithError() {
        Rfc822Token[] tokens = Rfc822Tokenizer.tokenize("\"Foo Bar\\");
        assertNotNull(tokens);
        assertEquals(1, tokens.length);
        assertEquals("Foo Bar", tokens[0].getAddress());
    }

    @Test
    public void testRfc822FindToken() {
        Rfc822Tokenizer tokenizer = new Rfc822Tokenizer();
        //                0           1         2           3         4
        //                0 1234 56789012345678901234 5678 90123456789012345
        String address = "\"Foo\" <foo@google.com>, \"Bar\" <bar@google.com>";
        assertEquals(0, tokenizer.findTokenStart(address, 21));
        assertEquals(22, tokenizer.findTokenEnd(address, 21));
        assertEquals(24, tokenizer.findTokenStart(address, 25));
        assertEquals(46, tokenizer.findTokenEnd(address, 25));
    }

    @Test
    public void testRfc822FindTokenWithError() {
        assertEquals(9, new Rfc822Tokenizer().findTokenEnd("\"Foo Bar\\", 0));
    }

    @LargeTest
    @Test
    public void testEllipsize() {
        CharSequence s1 = "The quick brown fox jumps over \u00FEhe lazy dog.";
        CharSequence s2 = new Wrapper(s1);
        Spannable s3 = new SpannableString(s1);
        s3.setSpan(new StyleSpan(0), 5, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        TextPaint p = new TextPaint();
        p.setFlags(p.getFlags() & ~p.DEV_KERN_TEXT_FLAG);

        for (int i = 0; i < 100; i++) {
            for (int j = 0; j < 3; j++) {
                TextUtils.TruncateAt kind = null;

                switch (j) {
                case 0:
                    kind = TextUtils.TruncateAt.START;
                    break;

                case 1:
                    kind = TextUtils.TruncateAt.END;
                    break;

                case 2:
                    kind = TextUtils.TruncateAt.MIDDLE;
                    break;
                }

                String out1 = TextUtils.ellipsize(s1, p, i, kind).toString();
                String out2 = TextUtils.ellipsize(s2, p, i, kind).toString();
                String out3 = TextUtils.ellipsize(s3, p, i, kind).toString();

                String keep1 = TextUtils.ellipsize(s1, p, i, kind, true, null).toString();
                String keep2 = TextUtils.ellipsize(s2, p, i, kind, true, null).toString();
                String keep3 = TextUtils.ellipsize(s3, p, i, kind, true, null).toString();

                String trim1 = keep1.replace("\uFEFF", "");

                // Are all normal output strings identical?
                assertEquals("wid " + i + " pass " + j, out1, out2);
                assertEquals("wid " + i + " pass " + j, out2, out3);

                // Are preserved output strings identical?
                assertEquals("wid " + i + " pass " + j, keep1, keep2);
                assertEquals("wid " + i + " pass " + j, keep2, keep3);

                // Does trimming padding from preserved yield normal?
                assertEquals("wid " + i + " pass " + j, out1, trim1);

                // Did preserved output strings preserve length?
                assertEquals("wid " + i + " pass " + j, keep1.length(), s1.length());

                // Does the output string actually fit in the space?
                assertTrue("wid " + i + " pass " + j, p.measureText(out1) <= i);

                // Is the padded output the same width as trimmed output?
                assertTrue("wid " + i + " pass " + j, p.measureText(keep1) == p.measureText(out1));
            }
        }
    }

    @Test
    public void testEllipsize_multiCodepoint() {
        final TextPaint paint = new TextPaint();
        final float wordWidth = paint.measureText("MMMM");

        // Establish the ground rules first, for single-codepoint cases.
        final String ellipsis = "."; // one full stop character
        assertEquals(
                "MM.\uFEFF",
                TextUtils.ellipsize("MMMM", paint, 0.7f * wordWidth,
                        TextUtils.TruncateAt.END, true /* preserve length */,
                        null /* no callback */, TextDirectionHeuristics.LTR,
                        ellipsis));
        assertEquals(
                "MM.",
                TextUtils.ellipsize("MMMM", paint, 0.7f * wordWidth,
                        TextUtils.TruncateAt.END, false /* preserve length */,
                        null /* no callback */, TextDirectionHeuristics.LTR,
                        ellipsis));
        assertEquals(
                "M.",
                TextUtils.ellipsize("MM", paint, 0.45f * wordWidth,
                        TextUtils.TruncateAt.END, true /* preserve length */,
                        null /* no callback */, TextDirectionHeuristics.LTR,
                        ellipsis));
        assertEquals(
                "M.",
                TextUtils.ellipsize("MM", paint, 0.45f * wordWidth,
                        TextUtils.TruncateAt.END, false /* preserve length */,
                        null /* no callback */, TextDirectionHeuristics.LTR,
                        ellipsis));

        // Now check the differences for multi-codepoint ellipsis.
        final String longEllipsis = ".."; // two full stop characters
        assertEquals(
                "MM..",
                TextUtils.ellipsize("MMMM", paint, 0.7f * wordWidth,
                        TextUtils.TruncateAt.END, true /* preserve length */,
                        null /* no callback */, TextDirectionHeuristics.LTR,
                        longEllipsis));
        assertEquals(
                "MM..",
                TextUtils.ellipsize("MMMM", paint, 0.7f * wordWidth,
                        TextUtils.TruncateAt.END, false /* preserve length */,
                        null /* no callback */, TextDirectionHeuristics.LTR,
                        longEllipsis));
        assertEquals(
                "M\uFEFF",
                TextUtils.ellipsize("MM", paint, 0.45f * wordWidth,
                        TextUtils.TruncateAt.END, true /* preserve length */,
                        null /* no callback */, TextDirectionHeuristics.LTR,
                        longEllipsis));
        assertEquals(
                "M..",
                TextUtils.ellipsize("MM", paint, 0.45f * wordWidth,
                        TextUtils.TruncateAt.END, false /* preserve length */,
                        null /* no callback */, TextDirectionHeuristics.LTR,
                        longEllipsis));
    }

    @Test
    public void testDelimitedStringContains() {
        assertFalse(TextUtils.delimitedStringContains("", ',', null));
        assertFalse(TextUtils.delimitedStringContains(null, ',', ""));
        // Whole match
        assertTrue(TextUtils.delimitedStringContains("gps", ',', "gps"));
        // At beginning.
        assertTrue(TextUtils.delimitedStringContains("gps,gpsx,network,mock", ',', "gps"));
        assertTrue(TextUtils.delimitedStringContains("gps,network,mock", ',', "gps"));
        // In middle, both without, before & after a false match.
        assertTrue(TextUtils.delimitedStringContains("network,gps,mock", ',', "gps"));
        assertTrue(TextUtils.delimitedStringContains("network,gps,gpsx,mock", ',', "gps"));
        assertTrue(TextUtils.delimitedStringContains("network,gpsx,gps,mock", ',', "gps"));
        // At the end.
        assertTrue(TextUtils.delimitedStringContains("network,mock,gps", ',', "gps"));
        assertTrue(TextUtils.delimitedStringContains("network,mock,gpsx,gps", ',', "gps"));
        // Not present (but with a false match)
        assertFalse(TextUtils.delimitedStringContains("network,mock,gpsx", ',', "gps"));
    }

    @Test
    public void testCharSequenceCreator() {
        Parcel p = Parcel.obtain();
        CharSequence text;
        try {
            TextUtils.writeToParcel(null, p, 0);
            text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
            assertNull("null CharSequence should generate null from parcel", text);
        } finally {
            p.recycle();
        }
        p = Parcel.obtain();
        try {
            TextUtils.writeToParcel("test", p, 0);
            p.setDataPosition(0);
            text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
            assertEquals("conversion to/from parcel failed", "test", text);
        } finally {
            p.recycle();
        }
    }

    @Test
    public void testCharSequenceCreatorNull() {
        Parcel p;
        CharSequence text;
        p = Parcel.obtain();
        try {
            TextUtils.writeToParcel(null, p, 0);
            p.setDataPosition(0);
            text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
            assertNull("null CharSequence should generate null from parcel", text);
        } finally {
            p.recycle();
        }
    }

    @Test
    public void testCharSequenceCreatorSpannable() {
        Parcel p;
        CharSequence text;
        p = Parcel.obtain();
        try {
            TextUtils.writeToParcel(new SpannableString("test"), p, 0);
            p.setDataPosition(0);
            text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
            assertEquals("conversion to/from parcel failed", "test", text.toString());
        } finally {
            p.recycle();
        }
    }

    @Test
    public void testCharSequenceCreatorString() {
        Parcel p;
        CharSequence text;
        p = Parcel.obtain();
        try {
            TextUtils.writeToParcel("test", p, 0);
            p.setDataPosition(0);
            text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
            assertEquals("conversion to/from parcel failed", "test", text.toString());
        } finally {
            p.recycle();
        }
    }

    /**
     * CharSequence wrapper for testing the cases where text is copied into
     * a char array instead of working from a String or a Spanned.
     */
    private static class Wrapper implements CharSequence {
        private CharSequence mString;

        public Wrapper(CharSequence s) {
            mString = s;
        }

        @Override
        public int length() {
            return mString.length();
        }

        @Override
        public char charAt(int off) {
            return mString.charAt(off);
        }

        @Override
        public String toString() {
            return mString.toString();
        }

        @Override
        public CharSequence subSequence(int start, int end) {
            return new Wrapper(mString.subSequence(start, end));
        }
    }

    @Test
    public void testRemoveEmptySpans() {
        MockSpanned spanned = new MockSpanned();

        spanned.test();
        spanned.addSpan().test();
        spanned.addSpan().test();
        spanned.addSpan().test();
        spanned.addEmptySpan().test();
        spanned.addSpan().test();
        spanned.addEmptySpan().test();
        spanned.addEmptySpan().test();
        spanned.addSpan().test();

        spanned.clear();
        spanned.addEmptySpan().test();
        spanned.addEmptySpan().test();
        spanned.addEmptySpan().test();
        spanned.addSpan().test();
        spanned.addEmptySpan().test();
        spanned.addSpan().test();

        spanned.clear();
        spanned.addSpan().test();
        spanned.addEmptySpan().test();
        spanned.addSpan().test();
        spanned.addEmptySpan().test();
        spanned.addSpan().test();
        spanned.addSpan().test();
    }

    protected static class MockSpanned implements Spanned {

        private List<Object> allSpans = new ArrayList<Object>();
        private List<Object> nonEmptySpans = new ArrayList<Object>();

        public void clear() {
            allSpans.clear();
            nonEmptySpans.clear();
        }

        public MockSpanned addSpan() {
            Object o = new Object();
            allSpans.add(o);
            nonEmptySpans.add(o);
            return this;
        }

        public MockSpanned addEmptySpan() {
            Object o = new Object();
            allSpans.add(o);
            return this;
        }

        public void test() {
            Object[] nonEmpty = TextUtils.removeEmptySpans(allSpans.toArray(), this, Object.class);
            assertEquals("Mismatched array size", nonEmptySpans.size(), nonEmpty.length);
            for (int i=0; i<nonEmpty.length; i++) {
                assertEquals("Span differ", nonEmptySpans.get(i), nonEmpty[i]);
            }
        }

        @Override
        public char charAt(int arg0) {
            return 0;
        }

        @Override
        public int length() {
            return 0;
        }

        @Override
        public CharSequence subSequence(int arg0, int arg1) {
            return null;
        }

        @Override
        public <T> T[] getSpans(int start, int end, Class<T> type) {
            return null;
        }

        @Override
        public int getSpanStart(Object tag) {
            return 0;
        }

        @Override
        public int getSpanEnd(Object tag) {
            return nonEmptySpans.contains(tag) ? 1 : 0;
        }

        @Override
        public int getSpanFlags(Object tag) {
            return 0;
        }

        @Override
        public int nextSpanTransition(int start, int limit, Class type) {
            return 0;
        }
    }

    @Test
    public void testGetLayoutDirectionFromLocale() {
        assertEquals(View.LAYOUT_DIRECTION_LTR, TextUtils.getLayoutDirectionFromLocale(null));
        assertEquals(View.LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.ROOT));
        assertEquals(View.LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("en")));
        assertEquals(View.LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("en-US")));
        assertEquals(View.LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("az")));
        assertEquals(View.LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("az-AZ")));
        assertEquals(View.LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("az-Latn")));
        assertEquals(View.LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("en-EG")));
        assertEquals(View.LAYOUT_DIRECTION_LTR,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("ar-Latn")));

        assertEquals(View.LAYOUT_DIRECTION_RTL,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("ar")));
        assertEquals(View.LAYOUT_DIRECTION_RTL,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("fa")));
        assertEquals(View.LAYOUT_DIRECTION_RTL,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("he")));
        assertEquals(View.LAYOUT_DIRECTION_RTL,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("iw")));
        assertEquals(View.LAYOUT_DIRECTION_RTL,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("ur")));
        assertEquals(View.LAYOUT_DIRECTION_RTL,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("dv")));
        assertEquals(View.LAYOUT_DIRECTION_RTL,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("az-Arab")));
        assertEquals(View.LAYOUT_DIRECTION_RTL,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("az-IR")));
        assertEquals(View.LAYOUT_DIRECTION_RTL,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("fa-US")));
        assertEquals(View.LAYOUT_DIRECTION_RTL,
                TextUtils.getLayoutDirectionFromLocale(Locale.forLanguageTag("tr-Arab")));
    }

    @Test
    public void testToUpperCase() {
        {
            final CharSequence result = TextUtils.toUpperCase(null, "abc", false);
            assertEquals(StringBuilder.class, result.getClass());
            assertEquals("ABC", result.toString());
        }
        {
            final SpannableString str = new SpannableString("abc");
            Object span = new Object();
            str.setSpan(span, 1, 2, Spanned.SPAN_INCLUSIVE_INCLUSIVE);

            final CharSequence result = TextUtils.toUpperCase(null, str, true /* copySpans */);
            assertEquals(SpannableStringBuilder.class, result.getClass());
            assertEquals("ABC", result.toString());
            final Spanned spanned = (Spanned) result;
            final Object[] resultSpans = spanned.getSpans(0, result.length(), Object.class);
            assertEquals(1, resultSpans.length);
            assertSame(span, resultSpans[0]);
            assertEquals(1, spanned.getSpanStart(span));
            assertEquals(2, spanned.getSpanEnd(span));
            assertEquals(Spanned.SPAN_INCLUSIVE_INCLUSIVE, spanned.getSpanFlags(span));
        }
        {
            final Locale turkish = new Locale("tr", "TR");
            final CharSequence result = TextUtils.toUpperCase(turkish, "i", false);
            assertEquals(StringBuilder.class, result.getClass());
            assertEquals("İ", result.toString());
        }
        {
            final String str = "ABC";
            assertSame(str, TextUtils.toUpperCase(null, str, false));
        }
        {
            final SpannableString str = new SpannableString("ABC");
            str.setSpan(new Object(), 1, 2, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
            assertSame(str, TextUtils.toUpperCase(null, str, true /* copySpans */));
        }
    }

    // Copied from cts/tests/tests/widget/src/android/widget/cts/TextViewTest.java and modified
    // for the TextUtils.toUpperCase method.
    @Test
    public void testToUpperCase_SpansArePreserved() {
        final Locale greek = new Locale("el", "GR");
        final String lowerString = "ι\u0301ριδα";  // ίριδα with first letter decomposed
        final String upperString = "ΙΡΙΔΑ";  // uppercased
        // expected lowercase to uppercase index map
        final int[] indexMap = {0, 1, 1, 2, 3, 4, 5};
        final int flags = Spanned.SPAN_INCLUSIVE_INCLUSIVE;

        final Spannable source = new SpannableString(lowerString);
        source.setSpan(new Object(), 0, 1, flags);
        source.setSpan(new Object(), 1, 2, flags);
        source.setSpan(new Object(), 2, 3, flags);
        source.setSpan(new Object(), 3, 4, flags);
        source.setSpan(new Object(), 4, 5, flags);
        source.setSpan(new Object(), 5, 6, flags);
        source.setSpan(new Object(), 0, 2, flags);
        source.setSpan(new Object(), 1, 3, flags);
        source.setSpan(new Object(), 2, 4, flags);
        source.setSpan(new Object(), 0, 6, flags);
        final Object[] sourceSpans = source.getSpans(0, source.length(), Object.class);

        final CharSequence uppercase = TextUtils.toUpperCase(greek, source, true /* copySpans */);
        assertEquals(SpannableStringBuilder.class, uppercase.getClass());
        final Spanned result = (Spanned) uppercase;

        assertEquals(upperString, result.toString());
        final Object[] resultSpans = result.getSpans(0, result.length(), Object.class);
        assertEquals(sourceSpans.length, resultSpans.length);
        for (int i = 0; i < sourceSpans.length; i++) {
            assertSame(sourceSpans[i], resultSpans[i]);
            final Object span = sourceSpans[i];
            assertEquals(indexMap[source.getSpanStart(span)], result.getSpanStart(span));
            assertEquals(indexMap[source.getSpanEnd(span)], result.getSpanEnd(span));
            assertEquals(source.getSpanFlags(span), result.getSpanFlags(span));
        }
    }

    @Test
    public void testTrimToSize() {
        final String testString = "a\uD800\uDC00a";
        assertEquals("Should return text as it is if size is longer than length",
                testString, TextUtils.trimToSize(testString, 5));
        assertEquals("Should return text as it is if size is equal to length",
                testString, TextUtils.trimToSize(testString, 4));
        assertEquals("Should trim text",
                "a\uD800\uDC00", TextUtils.trimToSize(testString, 3));
        assertEquals("Should trim surrogate pairs if size is in the middle of a pair",
                "a", TextUtils.trimToSize(testString, 2));
        assertEquals("Should trim text",
                "a", TextUtils.trimToSize(testString, 1));
        assertEquals("Should handle null",
                null, TextUtils.trimToSize(null, 1));

        assertEquals("Should trim high surrogate if invalid surrogate",
                "a\uD800", TextUtils.trimToSize("a\uD800\uD800", 2));
        assertEquals("Should trim low surrogate if invalid surrogate",
                "a\uDC00", TextUtils.trimToSize("a\uDC00\uDC00", 2));
    }

    @Test(expected = IllegalArgumentException.class)
    public void testTrimToSizeThrowsExceptionForNegativeSize() {
        TextUtils.trimToSize("", -1);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testTrimToSizeThrowsExceptionForZeroSize() {
        TextUtils.trimToSize("abc", 0);
    }
}
