1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.text; 18 19 import static org.junit.Assert.assertEquals; 20 21 import android.graphics.Typeface; 22 import android.os.Parcel; 23 import android.support.test.filters.SmallTest; 24 import android.support.test.runner.AndroidJUnit4; 25 import android.text.style.CharacterStyle; 26 import android.text.style.StyleSpan; 27 import android.text.style.TextAppearanceSpan; 28 import android.text.style.TypefaceSpan; 29 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 33 /** 34 * SpannedTest tests some features of Spanned 35 */ 36 @SmallTest 37 @RunWith(AndroidJUnit4.class) 38 public class SpannedTest { 39 private int mExpect; 40 41 @Test 42 public void testSpannableString() { 43 checkPriority(new SpannableString("the quick brown fox")); 44 } 45 46 @Test 47 public void testSpannableStringBuilder() { 48 checkPriority2(new SpannableStringBuilder("the quick brown fox")); 49 } 50 51 @Test 52 public void testAppend() { 53 Object o = new Object(); 54 SpannableString ss = new SpannableString("Test"); 55 ss.setSpan(o, 0, ss.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 56 57 SpannableStringBuilder ssb = new SpannableStringBuilder(); 58 ssb.append(ss); 59 assertEquals(0, ssb.getSpanStart(o)); 60 assertEquals(4, ssb.getSpanEnd(o)); 61 assertEquals(1, ssb.getSpans(0, 4, Object.class).length); 62 63 ssb.insert(0, ss); 64 assertEquals(4, ssb.getSpanStart(o)); 65 assertEquals(8, ssb.getSpanEnd(o)); 66 assertEquals(0, ssb.getSpans(0, 4, Object.class).length); 67 assertEquals(1, ssb.getSpans(4, 8, Object.class).length); 68 } 69 70 @Test 71 public void testWrapParcel() { 72 SpannableString s = new SpannableString("Hello there world"); 73 CharacterStyle mark = new StyleSpan(Typeface.BOLD); 74 s.setSpan(mark, 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 75 s.setSpan(CharacterStyle.wrap(mark), 3, 7, 76 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 77 s.setSpan(new TextAppearanceSpan("mono", 0, -1, null, null), 7, 8, 78 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 79 s.setSpan(CharacterStyle.wrap(new TypefaceSpan("mono")), 8, 9, 80 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 81 82 Parcel p = Parcel.obtain(); 83 TextUtils.writeToParcel(s, p, 0); 84 p.setDataPosition(0); 85 86 Spanned s2 = (Spanned) TextUtils.CHAR_SEQUENCE_CREATOR. 87 createFromParcel(p); 88 StyleSpan[] style; 89 90 style = s2.getSpans(1, 2, StyleSpan.class); 91 assertEquals(1, style.length); 92 assertEquals(1, s2.getSpanStart(style[0])); 93 assertEquals(2, s2.getSpanEnd(style[0])); 94 95 style = s2.getSpans(3, 7, StyleSpan.class); 96 assertEquals(1, style.length); 97 assertEquals(3, s2.getSpanStart(style[0])); 98 assertEquals(7, s2.getSpanEnd(style[0])); 99 100 TextAppearanceSpan[] appearance = s2.getSpans(7, 8, 101 TextAppearanceSpan.class); 102 assertEquals(1, appearance.length); 103 assertEquals(7, s2.getSpanStart(appearance[0])); 104 assertEquals(8, s2.getSpanEnd(appearance[0])); 105 106 TypefaceSpan[] tf = s2.getSpans(8, 9, TypefaceSpan.class); 107 assertEquals(1, tf.length); 108 assertEquals(8, s2.getSpanStart(tf[0])); 109 assertEquals(9, s2.getSpanEnd(tf[0])); 110 } 111 112 private void checkPriority(Spannable s) { 113 s.setSpan(new Object(), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE | 114 (5 << Spannable.SPAN_PRIORITY_SHIFT)); 115 s.setSpan(new Object(), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE | 116 (10 << Spannable.SPAN_PRIORITY_SHIFT)); 117 s.setSpan(new Object(), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE | 118 (0 << Spannable.SPAN_PRIORITY_SHIFT)); 119 s.setSpan(new Object(), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE | 120 (15 << Spannable.SPAN_PRIORITY_SHIFT)); 121 s.setSpan(new Object(), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE | 122 (3 << Spannable.SPAN_PRIORITY_SHIFT)); 123 s.setSpan(new Object(), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE | 124 (6 << Spannable.SPAN_PRIORITY_SHIFT)); 125 s.setSpan(new Object(), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE | 126 (0 << Spannable.SPAN_PRIORITY_SHIFT)); 127 128 Object[] spans = s.getSpans(0, s.length(), Object.class); 129 130 for (int i = 0; i < spans.length - 1; i++) { 131 assertEquals((s.getSpanFlags(spans[i]) & Spanned.SPAN_PRIORITY) >= 132 (s.getSpanFlags(spans[i + 1]) & Spanned.SPAN_PRIORITY), 133 true); 134 } 135 136 mExpect = 0; 137 138 s.setSpan(new Watcher(2), 0, s.length(), 139 Spannable.SPAN_INCLUSIVE_INCLUSIVE | 140 (2 << Spannable.SPAN_PRIORITY_SHIFT)); 141 s.setSpan(new Watcher(4), 0, s.length(), 142 Spannable.SPAN_INCLUSIVE_INCLUSIVE | 143 (4 << Spannable.SPAN_PRIORITY_SHIFT)); 144 s.setSpan(new Watcher(1), 0, s.length(), 145 Spannable.SPAN_INCLUSIVE_INCLUSIVE | 146 (1 << Spannable.SPAN_PRIORITY_SHIFT)); 147 s.setSpan(new Watcher(3), 0, s.length(), 148 Spannable.SPAN_INCLUSIVE_INCLUSIVE | 149 (3 << Spannable.SPAN_PRIORITY_SHIFT)); 150 151 mExpect = 4; 152 s.setSpan(new Object(), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 153 assertEquals(mExpect, 0); 154 } 155 156 private void checkPriority2(SpannableStringBuilder ssb) { 157 checkPriority(ssb); 158 159 mExpect = 4; 160 ssb.insert(3, "something"); 161 assertEquals(mExpect, 0); 162 } 163 164 private class Watcher implements SpanWatcher, TextWatcher { 165 private int mSequence; 166 167 public Watcher(int sequence) { 168 mSequence = sequence; 169 } 170 171 @Override 172 public void onSpanChanged(Spannable b, Object o, int s, int e, int st, int en) { } 173 174 @Override 175 public void onSpanRemoved(Spannable b, Object o, int s, int e) { } 176 177 @Override 178 public void onSpanAdded(Spannable b, Object o, int s, int e) { 179 if (mExpect != 0) { 180 assertEquals(mSequence, mExpect); 181 mExpect = mSequence - 1; 182 } 183 } 184 185 @Override 186 public void beforeTextChanged(CharSequence s, int start, int count, int after) { } 187 188 @Override 189 public void onTextChanged(CharSequence s, int start, int before, int count) { 190 if (mExpect != 0) { 191 assertEquals(mSequence, mExpect); 192 mExpect = mSequence - 1; 193 } 194 } 195 196 @Override 197 public void afterTextChanged(Editable s) { } 198 } 199 } 200