1d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam/* 2d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * Copyright (C) 2016 The Android Open Source Project 3d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * 4d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * Licensed under the Apache License, Version 2.0 (the "License"); 5d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * you may not use this file except in compliance with the License. 6d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * You may obtain a copy of the License at 7d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * 8d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * http://www.apache.org/licenses/LICENSE-2.0 9d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * 10d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * Unless required by applicable law or agreed to in writing, software 11d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * distributed under the License is distributed on an "AS IS" BASIS, 12d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * See the License for the specific language governing permissions and 14d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * limitations under the License. 15d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam */ 16d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 17618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lampackage com.android.setupwizardlib.view; 18d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 19e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lamimport static com.google.common.truth.Truth.assertThat; 20e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam 212614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport static org.junit.Assert.assertEquals; 222614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport static org.junit.Assert.assertFalse; 2351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport static org.junit.Assert.assertSame; 242614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport static org.junit.Assert.assertTrue; 2551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport static org.mockito.Matchers.eq; 26e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lamimport static org.mockito.Mockito.doReturn; 2751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport static org.mockito.Mockito.mock; 2851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport static org.mockito.Mockito.spy; 2951f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport static org.mockito.Mockito.verify; 30618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lamimport static org.robolectric.RuntimeEnvironment.application; 312614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam 3263cdc5ccb7f1f61d0e752e38d7e57c690658a0acMaurice Lamimport android.annotation.SuppressLint; 3351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport android.content.Context; 3451f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport android.content.ContextWrapper; 35618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lamimport android.os.Build.VERSION; 36618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lamimport android.os.Build.VERSION_CODES; 37d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.text.Annotation; 38d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.text.SpannableStringBuilder; 39d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.text.Spanned; 40d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.text.style.TextAppearanceSpan; 41e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lamimport android.view.MotionEvent; 42d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 43618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lamimport com.android.setupwizardlib.robolectric.SuwLibRobolectricTestRunner; 44d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport com.android.setupwizardlib.span.LinkSpan; 4551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport com.android.setupwizardlib.span.LinkSpan.OnLinkClickListener; 46e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lamimport com.android.setupwizardlib.view.TouchableMovementMethod.TouchableLinkMovementMethod; 47d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 482614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport org.junit.Test; 492614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport org.junit.runner.RunWith; 50618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lamimport org.robolectric.annotation.Config; 512614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam 52d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport java.util.Arrays; 53d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 54618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam@RunWith(SuwLibRobolectricTestRunner.class) 55618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam@Config(sdk = { Config.OLDEST_SDK, Config.NEWEST_SDK }) 562614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lampublic class RichTextViewTest { 57d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 582614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 59d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public void testLinkAnnotation() { 60d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam Annotation link = new Annotation("link", "foobar"); 61d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world"); 62d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam ssb.setSpan(link, 1, 2, 0 /* flags */); 63d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 64618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam RichTextView textView = new RichTextView(application); 65d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam textView.setText(ssb); 66d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 67d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam final CharSequence text = textView.getText(); 68d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertTrue("Text should be spanned", text instanceof Spanned); 69d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 70e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam assertThat(textView.getMovementMethod()).isInstanceOf(TouchableLinkMovementMethod.class); 71e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam 72d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam Object[] spans = ((Spanned) text).getSpans(0, text.length(), Annotation.class); 73d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertEquals("Annotation should be removed " + Arrays.toString(spans), 0, spans.length); 74d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 75d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam spans = ((Spanned) text).getSpans(0, text.length(), LinkSpan.class); 76d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertEquals("There should be one span " + Arrays.toString(spans), 1, spans.length); 77d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertTrue("The span should be a LinkSpan", spans[0] instanceof LinkSpan); 78d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertEquals("The LinkSpan should have id \"foobar\"", 79d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam "foobar", ((LinkSpan) spans[0]).getId()); 80d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 81d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 822614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 8351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam public void testOnLinkClickListener() { 8451f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam Annotation link = new Annotation("link", "foobar"); 8551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world"); 8651f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam ssb.setSpan(link, 1, 2, 0 /* flags */); 8751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 88618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam RichTextView textView = new RichTextView(application); 8951f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam textView.setText(ssb); 9051f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 9151f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam OnLinkClickListener listener = mock(OnLinkClickListener.class); 9251f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam textView.setOnLinkClickListener(listener); 9351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 9451f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam assertSame(listener, textView.getOnLinkClickListener()); 9551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 9651f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam CharSequence text = textView.getText(); 9751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam LinkSpan[] spans = ((Spanned) text).getSpans(0, text.length(), LinkSpan.class); 9851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam spans[0].onClick(textView); 9951f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 10051f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam verify(listener).onLinkClick(eq(spans[0])); 10151f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam } 10251f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 10351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam @Test 10451f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam public void testLegacyContextOnClickListener() { 10551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam // Click listener implemented by context should still be invoked for compatibility. 10651f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam Annotation link = new Annotation("link", "foobar"); 10751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world"); 10851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam ssb.setSpan(link, 1, 2, 0 /* flags */); 10951f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 110618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam TestContext context = spy(new TestContext(application)); 11151f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam RichTextView textView = new RichTextView(context); 11251f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam textView.setText(ssb); 11351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 11451f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam CharSequence text = textView.getText(); 11551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam LinkSpan[] spans = ((Spanned) text).getSpans(0, text.length(), LinkSpan.class); 11651f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam spans[0].onClick(textView); 11751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 11851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam verify(context).onClick(eq(spans[0])); 11951f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam } 12051f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 12151f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam @Test 122e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam public void onTouchEvent_clickOnLinks_shouldReturnTrue() { 123e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam Annotation link = new Annotation("link", "foobar"); 124e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world"); 125e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam ssb.setSpan(link, 0, 2, 0 /* flags */); 126e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam 127e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam RichTextView textView = new RichTextView(application); 128e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam textView.setText(ssb); 129e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam 130e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam TouchableLinkMovementMethod mockMovementMethod = mock(TouchableLinkMovementMethod.class); 131e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam textView.setMovementMethod(mockMovementMethod); 132e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam 133e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam MotionEvent motionEvent = 134e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam MotionEvent.obtain(123, 22, MotionEvent.ACTION_DOWN, 0, 0, 0); 135e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam doReturn(motionEvent).when(mockMovementMethod).getLastTouchEvent(); 136e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam doReturn(true).when(mockMovementMethod).isLastTouchEventHandled(); 137e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam assertThat(textView.onTouchEvent(motionEvent)).isTrue(); 138e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam } 139e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam 140e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam @Test 141e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam public void onTouchEvent_clickOutsideLinks_shouldReturnFalse() { 142e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam Annotation link = new Annotation("link", "foobar"); 143e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world"); 144e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam ssb.setSpan(link, 0, 2, 0 /* flags */); 145e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam 146e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam RichTextView textView = new RichTextView(application); 147e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam textView.setText(ssb); 148e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam 149e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam TouchableLinkMovementMethod mockMovementMethod = mock(TouchableLinkMovementMethod.class); 150e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam textView.setMovementMethod(mockMovementMethod); 151e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam 152e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam MotionEvent motionEvent = 153e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam MotionEvent.obtain(123, 22, MotionEvent.ACTION_DOWN, 0, 0, 0); 154e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam doReturn(motionEvent).when(mockMovementMethod).getLastTouchEvent(); 155e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam doReturn(false).when(mockMovementMethod).isLastTouchEventHandled(); 156e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam assertThat(textView.onTouchEvent(motionEvent)).isFalse(); 157e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam } 158e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam 159e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam @Test 160d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam public void testTextStyle() { 161d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam Annotation link = new Annotation("textAppearance", "foobar"); 162d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world"); 163d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam ssb.setSpan(link, 1, 2, 0 /* flags */); 164d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 165618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam RichTextView textView = new RichTextView(application); 166d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam textView.setText(ssb); 167d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 168d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam final CharSequence text = textView.getText(); 169d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertTrue("Text should be spanned", text instanceof Spanned); 170d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 171d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam Object[] spans = ((Spanned) text).getSpans(0, text.length(), Annotation.class); 172d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertEquals("Annotation should be removed " + Arrays.toString(spans), 0, spans.length); 173d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 174d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam spans = ((Spanned) text).getSpans(0, text.length(), TextAppearanceSpan.class); 175d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertEquals("There should be one span " + Arrays.toString(spans), 1, spans.length); 176d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam assertTrue("The span should be a TextAppearanceSpan", 177d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam spans[0] instanceof TextAppearanceSpan); 178d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 1799a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur 1802614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 18151f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam public void testTextContainingLinksAreFocusable() { 1829a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur Annotation testLink = new Annotation("link", "value"); 1839a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder("Linked"); 1849a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur spannableStringBuilder.setSpan(testLink, 0, 3, 0); 1859a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur 186618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam RichTextView view = new RichTextView(application); 1879a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur view.setText(spannableStringBuilder); 1889a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur 1899a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur assertTrue("TextView should be focusable since it contains spans", view.isFocusable()); 1909a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur } 1919a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur 1929a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur 19363cdc5ccb7f1f61d0e752e38d7e57c690658a0acMaurice Lam @SuppressLint("SetTextI18n") // It's OK. This is just a test. 1942614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 1959a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur public void testTextContainingNoLinksAreNotFocusable() { 196618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam RichTextView textView = new RichTextView(application); 1979a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur textView.setText("Thou shall not be focusable!"); 1989a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur 1999a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur assertFalse("TextView should not be focusable since it does not contain any span", 2009a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur textView.isFocusable()); 2019a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur } 2029a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur 2039a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur 2049a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur // Based on the text contents of the text view, the "focusable" property of the element 2059a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur // should also be automatically changed. 20663cdc5ccb7f1f61d0e752e38d7e57c690658a0acMaurice Lam @SuppressLint("SetTextI18n") // It's OK. This is just a test. 2072614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam @Test 20851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam public void testRichTextViewFocusChangesWithTextChange() { 209618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam RichTextView textView = new RichTextView(application); 2109a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur textView.setText("Thou shall not be focusable!"); 2119a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur 2129a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur assertFalse(textView.isFocusable()); 213618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam assertFalse(textView.isFocusableInTouchMode()); 2149a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur 2159a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur SpannableStringBuilder spannableStringBuilder = 2169a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur new SpannableStringBuilder("I am focusable"); 2179a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur spannableStringBuilder.setSpan(new Annotation("link", "focus:on_me"), 0, 1, 0); 2189a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur textView.setText(spannableStringBuilder); 2199a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur assertTrue(textView.isFocusable()); 220618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam if (VERSION.SDK_INT >= VERSION_CODES.N_MR1) { 221618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam assertTrue(textView.isFocusableInTouchMode()); 222618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam assertFalse(textView.getRevealOnFocusHint()); 223618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam } else { 224618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam assertFalse(textView.isFocusableInTouchMode()); 225618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam } 2269a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur } 22751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 22851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam public static class TestContext extends ContextWrapper implements LinkSpan.OnClickListener { 22951f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 23051f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam public TestContext(Context base) { 23151f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam super(base); 23251f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam } 23351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam 23451f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam @Override 23551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam public void onClick(LinkSpan span) { 23651f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam // Ignore. Can be verified using Mockito 23751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam } 23851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam } 239d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam} 240