/* * Copyright 2018 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 androidx.core.text; import static android.text.TextDirectionHeuristics.LTR; import static android.text.TextDirectionHeuristics.RTL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.graphics.Color; import android.support.test.filters.SdkSuppress; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.text.Layout; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextDirectionHeuristics; import android.text.TextPaint; import android.text.style.BackgroundColorSpan; import android.text.style.TypefaceSpan; import androidx.core.text.PrecomputedTextCompat.Params; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class PrecomputedTextCompatTest { private static final CharSequence NULL_CHAR_SEQUENCE = null; private static final String STRING = "Hello, World!"; private static final String MULTIPARA_STRING = "Hello,\nWorld!"; private static final int SPAN_START = 3; private static final int SPAN_END = 7; private static final TypefaceSpan SPAN = new TypefaceSpan("serif"); private static final Spanned SPANNED; static { final SpannableStringBuilder ssb = new SpannableStringBuilder(STRING); ssb.setSpan(SPAN, SPAN_START, SPAN_END, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); SPANNED = ssb; } private static final TextPaint PAINT = new TextPaint(); @Test public void testParams_create() { assertNotNull(new Params.Builder(PAINT).build()); assertNotNull(new Params.Builder(PAINT) .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE).build()); assertNotNull(new Params.Builder(PAINT) .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL).build()); assertNotNull(new Params.Builder(PAINT) .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setTextDirection(LTR).build()); } @Test public void testParams_SetGet() { assertEquals(Layout.BREAK_STRATEGY_SIMPLE, new Params.Builder(PAINT) .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE).build().getBreakStrategy()); assertEquals(Layout.HYPHENATION_FREQUENCY_NONE, new Params.Builder(PAINT) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE).build() .getHyphenationFrequency()); assertEquals(RTL, new Params.Builder(PAINT).setTextDirection(RTL).build() .getTextDirection()); } @Test @SdkSuppress(minSdkVersion = 23) public void testParams_GetDefaultValues() { assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, new Params.Builder(PAINT).build().getBreakStrategy()); assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, new Params.Builder(PAINT).build().getHyphenationFrequency()); } @Test @SdkSuppress(minSdkVersion = 18) public void testParams_GetDefaultValues2() { assertEquals(TextDirectionHeuristics.FIRSTSTRONG_LTR, new Params.Builder(PAINT).build().getTextDirection()); } @Test @SdkSuppress(minSdkVersion = 23) public void testParams_equals() { final Params base = new Params.Builder(PAINT) .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setTextDirection(LTR).build(); assertFalse(base.equals(null)); assertTrue(base.equals(base)); assertFalse(base.equals(new Object())); Params other = new Params.Builder(PAINT) .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setTextDirection(LTR).build(); assertTrue(base.equals(other)); assertTrue(other.equals(base)); assertEquals(base.hashCode(), other.hashCode()); other = new Params.Builder(PAINT) .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setTextDirection(LTR).build(); assertFalse(base.equals(other)); assertFalse(other.equals(base)); other = new Params.Builder(PAINT) .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE) .setTextDirection(LTR).build(); assertFalse(base.equals(other)); assertFalse(other.equals(base)); other = new Params.Builder(PAINT) .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setTextDirection(RTL).build(); assertFalse(base.equals(other)); assertFalse(other.equals(base)); TextPaint anotherPaint = new TextPaint(PAINT); anotherPaint.setTextSize(PAINT.getTextSize() * 2.0f); other = new Params.Builder(anotherPaint) .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY) .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) .setTextDirection(LTR).build(); assertFalse(base.equals(other)); assertFalse(other.equals(base)); } @Test public void testParams_equals2() { final Params base = new Params.Builder(PAINT).build(); assertFalse(base.equals(null)); assertTrue(base.equals(base)); assertFalse(base.equals(new Object())); Params other = new Params.Builder(PAINT).build(); assertTrue(base.equals(other)); assertTrue(other.equals(base)); assertEquals(base.hashCode(), other.hashCode()); TextPaint paint = new TextPaint(PAINT); paint.setTextSize(paint.getTextSize() * 2.0f + 1.0f); other = new Params.Builder(paint).build(); assertFalse(base.equals(other)); assertFalse(other.equals(base)); } @Test public void testCreate_withNull() { final Params param = new Params.Builder(PAINT).build(); try { PrecomputedTextCompat.create(NULL_CHAR_SEQUENCE, param); fail(); } catch (NullPointerException e) { // pass } try { PrecomputedTextCompat.create(STRING, null); fail(); } catch (NullPointerException e) { // pass } } @Test public void testCharSequenceInteface() { final Params param = new Params.Builder(PAINT).build(); final CharSequence s = PrecomputedTextCompat.create(STRING, param); assertEquals(STRING.length(), s.length()); assertEquals('H', s.charAt(0)); assertEquals('e', s.charAt(1)); assertEquals('l', s.charAt(2)); assertEquals('l', s.charAt(3)); assertEquals('o', s.charAt(4)); assertEquals(',', s.charAt(5)); assertEquals("Hello, World!", s.toString()); final CharSequence s3 = s.subSequence(0, 3); assertEquals(3, s3.length()); assertEquals('H', s3.charAt(0)); assertEquals('e', s3.charAt(1)); assertEquals('l', s3.charAt(2)); } @Test public void testSpannedInterface_Spanned() { final Params param = new Params.Builder(PAINT).build(); final Spanned s = PrecomputedTextCompat.create(SPANNED, param); final TypefaceSpan[] spans = s.getSpans(0, s.length(), TypefaceSpan.class); assertNotNull(spans); assertEquals(1, spans.length); assertEquals(SPAN, spans[0]); assertEquals(SPAN_START, s.getSpanStart(SPAN)); assertEquals(SPAN_END, s.getSpanEnd(SPAN)); assertTrue((s.getSpanFlags(SPAN) & Spanned.SPAN_INCLUSIVE_EXCLUSIVE) != 0); assertEquals(SPAN_START, s.nextSpanTransition(0, s.length(), TypefaceSpan.class)); assertEquals(SPAN_END, s.nextSpanTransition(SPAN_START, s.length(), TypefaceSpan.class)); } @Test public void testSpannedInterface_Spannable() { final BackgroundColorSpan span = new BackgroundColorSpan(Color.RED); final Params param = new Params.Builder(PAINT).build(); final Spannable s = PrecomputedTextCompat.create(STRING, param); assertEquals(0, s.getSpans(0, s.length(), BackgroundColorSpan.class).length); s.setSpan(span, SPAN_START, SPAN_END, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); final BackgroundColorSpan[] spans = s.getSpans(0, s.length(), BackgroundColorSpan.class); assertEquals(SPAN_START, s.getSpanStart(span)); assertEquals(SPAN_END, s.getSpanEnd(span)); assertTrue((s.getSpanFlags(span) & Spanned.SPAN_INCLUSIVE_EXCLUSIVE) != 0); assertEquals(SPAN_START, s.nextSpanTransition(0, s.length(), BackgroundColorSpan.class)); assertEquals(SPAN_END, s.nextSpanTransition(SPAN_START, s.length(), BackgroundColorSpan.class)); s.removeSpan(span); assertEquals(0, s.getSpans(0, s.length(), BackgroundColorSpan.class).length); } @Test(expected = IllegalArgumentException.class) public void testSpannedInterface_Spannable_setSpan_MetricsAffectingSpan() { final Params param = new Params.Builder(PAINT).build(); final Spannable s = PrecomputedTextCompat.create(SPANNED, param); s.setSpan(SPAN, SPAN_START, SPAN_END, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); } @Test(expected = IllegalArgumentException.class) public void testSpannedInterface_Spannable_removeSpan_MetricsAffectingSpan() { final Params param = new Params.Builder(PAINT).build(); final Spannable s = PrecomputedTextCompat.create(SPANNED, param); s.removeSpan(SPAN); } @Test public void testSpannedInterface_String() { final Params param = new Params.Builder(PAINT).build(); final Spanned s = PrecomputedTextCompat.create(STRING, param); TypefaceSpan[] spans = s.getSpans(0, s.length(), TypefaceSpan.class); assertNotNull(spans); assertEquals(0, spans.length); assertEquals(-1, s.getSpanStart(SPAN)); assertEquals(-1, s.getSpanEnd(SPAN)); assertEquals(0, s.getSpanFlags(SPAN)); assertEquals(s.length(), s.nextSpanTransition(0, s.length(), TypefaceSpan.class)); } @Test public void testGetParagraphCount() { final Params param = new Params.Builder(PAINT).build(); final PrecomputedTextCompat pm = PrecomputedTextCompat.create(STRING, param); assertEquals(1, pm.getParagraphCount()); assertEquals(0, pm.getParagraphStart(0)); assertEquals(STRING.length(), pm.getParagraphEnd(0)); final PrecomputedTextCompat pm1 = PrecomputedTextCompat.create(MULTIPARA_STRING, param); assertEquals(2, pm1.getParagraphCount()); assertEquals(0, pm1.getParagraphStart(0)); assertEquals(7, pm1.getParagraphEnd(0)); assertEquals(7, pm1.getParagraphStart(1)); assertEquals(pm1.length(), pm1.getParagraphEnd(1)); } }