blob: 8636e0beee5b00f1b244b5b2d4602f9adb26628b [file] [log] [blame]
/*
* Copyright (C) 2022 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.view.inputmethod.cts;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.os.Parcel;
import android.platform.test.annotations.AppModeSdkSandbox;
import android.text.SegmentFinder;
import android.view.inputmethod.TextBoundsInfo;
import android.view.inputmethod.TextBoundsInfoResult;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.compatibility.common.util.ApiTest;
import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
@RunWith(AndroidJUnit4.class)
@AppModeSdkSandbox(reason = "Allow test in the SDK sandbox (does not prevent other modes).")
public class TextBoundsInfoTest {
private static final float[] CHARACTER_BOUNDS1 = new float[] {
0.0f, 0.0f, 10.0f, 20.0f,
10.0f, 0.0f, 20.0f, 20.0f,
20.0f, 0.0f, 30.0f, 20.0f,
10.0f, 20.0f, 20.0f, 40.0f,
0.0f, 20.0f, 10.0f, 40.0f};
private static final float[] CHARACTER_BOUNDS2 = new float[] {
20.0f, 0.0f, 30.0f, 20.0f,
10.0f, 0.0f, 20.0f, 20.0f,
0.0f, 0.0f, 10.0f, 20.0f,
0.0f, 20.0f, 10.0f, 40.0f,
10.0f, 20.0f, 20.0f, 40.0f};
private static final int LTR_BIDI_LEVEL = 0;
private static final int RTL_BIDI_LEVEL = 1;
private static final int MAX_BIDI_LEVEL = 125;
private static final int[] CHARACTER_BIDI_LEVEL1 = new int[] {LTR_BIDI_LEVEL, LTR_BIDI_LEVEL,
LTR_BIDI_LEVEL, RTL_BIDI_LEVEL, MAX_BIDI_LEVEL};
private static final int[] CHARACTER_BIDI_LEVEL2 = new int[] {MAX_BIDI_LEVEL, RTL_BIDI_LEVEL,
LTR_BIDI_LEVEL, LTR_BIDI_LEVEL, LTR_BIDI_LEVEL};
private static final int[] CHARACTER_FLAGS1 = new int[] {
TextBoundsInfo.FLAG_CHARACTER_WHITESPACE,
TextBoundsInfo.FLAG_CHARACTER_PUNCTUATION,
TextBoundsInfo.FLAG_CHARACTER_LINEFEED,
TextBoundsInfo.FLAG_LINE_IS_RTL,
TextBoundsInfo.FLAG_LINE_IS_RTL
};
private static final int[] CHARACTER_FLAGS2 = new int[] {TextBoundsInfo.FLAG_LINE_IS_RTL,
TextBoundsInfo.FLAG_LINE_IS_RTL, TextBoundsInfo.FLAG_CHARACTER_WHITESPACE, 0, 0};
private static final SegmentFinder GRAPHEME_SEGMENT_FINDER1 =
new SegmentFinder.PrescribedSegmentFinder(
new int[] { 0, 1, 1, 2, 2, 4, 4, 5, 5, 7, 7, 8, 8, 9, 9, 10, 10, 11 });
private static final SegmentFinder GRAPHEME_SEGMENT_FINDER2 =
new SegmentFinder.PrescribedSegmentFinder(
new int[] { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10 });
private static final SegmentFinder WORD_SEGMENT_FINDER1 =
new SegmentFinder.PrescribedSegmentFinder(new int[] { 0, 3, 4, 5, 5, 10 });
private static final SegmentFinder WORD_SEGMENT_FINDER2 =
new SegmentFinder.PrescribedSegmentFinder(new int[] { 0, 4, 5, 8, 9, 11 });
private static final SegmentFinder LINE_SEGMENT_FINDER1 =
new SegmentFinder.PrescribedSegmentFinder(new int[] { 0, 5, 5, 8, 8, 10, 10, 15 });
private static final SegmentFinder LINE_SEGMENT_FINDER2 =
new SegmentFinder.PrescribedSegmentFinder(new int[] { 0, 5, 5, 7, 7, 10, 10, 15 });
@Test
@ApiTest(
apis = {
"android.view.inputmethod.TextBoundsInfo#getStart",
"android.view.inputmethod.TextBoundsInfo#getEnd",
"android.view.inputmethod.TextBoundsInfo#getMatrix",
"android.view.inputmethod.TextBoundsInfo#getCharacterBounds",
"android.view.inputmethod.TextBoundsInfo#getCharacterFlags",
"android.view.inputmethod.TextBoundsInfo#getCharacterBidiLevel",
"android.view.inputmethod.TextBoundsInfo#getGraphemeSegmentFinder",
"android.view.inputmethod.TextBoundsInfo#getWordSegmentFinder",
"android.view.inputmethod.TextBoundsInfo#getLineSegmentFinder",
"android.view.inputmethod.TextBoundsInfo.Builder#setStart",
"android.view.inputmethod.TextBoundsInfo.Builder#setEnd",
"android.view.inputmethod.TextBoundsInfo.Builder#setMatrix",
"android.view.inputmethod.TextBoundsInfo.Builder#setCharacterBounds",
"android.view.inputmethod.TextBoundsInfo.Builder#setCharacterFlags",
"android.view.inputmethod.TextBoundsInfo.Builder#setCharacterBidiLevel",
"android.view.inputmethod.TextBoundsInfo.Builder#setGraphemeSegmentFinder",
"android.view.inputmethod.TextBoundsInfo.Builder#setWordSegmentFinder",
"android.view.inputmethod.TextBoundsInfo.Builder#setLineSegmentFinder",
"android.view.inputmethod.TextBoundsInfo.Builder#build",
}
)
public void testBuilder() {
final int start1 = 5;
final int end1 = 10;
final Matrix matrix1 = new Matrix();
matrix1.setRotate(10f);
TextBoundsInfo.Builder builder = new TextBoundsInfo.Builder(start1, end1);
TextBoundsInfo textBoundsInfo1 = builder.setMatrix(matrix1)
.setCharacterBounds(CHARACTER_BOUNDS1)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setCharacterFlags(CHARACTER_FLAGS1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER1)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
assertEquals(start1, textBoundsInfo1.getStartIndex());
assertEquals(end1, textBoundsInfo1.getEndIndex());
final Matrix actualMatrix = new Matrix();
textBoundsInfo1.getMatrix(actualMatrix);
assertEquals(matrix1, actualMatrix);
assertCharacterBounds(CHARACTER_BOUNDS1, textBoundsInfo1);
assertCharacterBidiLevel(CHARACTER_BIDI_LEVEL1, textBoundsInfo1);
assertCharacterFlags(CHARACTER_FLAGS1, textBoundsInfo1);
assertEquals(GRAPHEME_SEGMENT_FINDER1, textBoundsInfo1.getGraphemeSegmentFinder());
assertEquals(WORD_SEGMENT_FINDER1, textBoundsInfo1.getWordSegmentFinder());
assertEquals(LINE_SEGMENT_FINDER1, textBoundsInfo1.getLineSegmentFinder());
// Build another TextBoundsInfo, making sure the Builder creates an identical object.
TextBoundsInfo textBoundsInfo2 = builder.build();
assertEquals(start1, textBoundsInfo2.getStartIndex());
assertEquals(end1, textBoundsInfo2.getEndIndex());
textBoundsInfo2.getMatrix(actualMatrix);
assertEquals(matrix1, actualMatrix);
assertCharacterBounds(CHARACTER_BOUNDS1, textBoundsInfo2);
assertCharacterBidiLevel(CHARACTER_BIDI_LEVEL1, textBoundsInfo2);
assertCharacterFlags(CHARACTER_FLAGS1, textBoundsInfo2);
assertEquals(GRAPHEME_SEGMENT_FINDER1, textBoundsInfo2.getGraphemeSegmentFinder());
assertEquals(WORD_SEGMENT_FINDER1, textBoundsInfo2.getWordSegmentFinder());
assertEquals(LINE_SEGMENT_FINDER1, textBoundsInfo2.getLineSegmentFinder());
final int start2 = 8;
final int end2 = 13;
final Matrix matrix2 = new Matrix();
matrix2.setTranslate(20f, 30f);
// Clear the existing parameters and build a different object.
TextBoundsInfo textBoundsInfo3 = builder.clear()
.setStartAndEnd(start2, end2)
.setMatrix(matrix2)
.setCharacterBounds(CHARACTER_BOUNDS2)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL2)
.setCharacterFlags(CHARACTER_FLAGS2)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER2)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.setLineSegmentFinder(LINE_SEGMENT_FINDER2)
.build();
assertEquals(start2, textBoundsInfo3.getStartIndex());
assertEquals(end2, textBoundsInfo3.getEndIndex());
textBoundsInfo3.getMatrix(actualMatrix);
assertEquals(matrix2, actualMatrix);
assertCharacterBounds(CHARACTER_BOUNDS2, textBoundsInfo3);
assertCharacterBidiLevel(CHARACTER_BIDI_LEVEL2, textBoundsInfo3);
assertCharacterFlags(CHARACTER_FLAGS2, textBoundsInfo3);
assertEquals(GRAPHEME_SEGMENT_FINDER2, textBoundsInfo3.getGraphemeSegmentFinder());
assertEquals(WORD_SEGMENT_FINDER2, textBoundsInfo3.getWordSegmentFinder());
assertEquals(LINE_SEGMENT_FINDER2, textBoundsInfo3.getLineSegmentFinder());
}
@Test
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo#writeToParcel" })
public void testTextBoundsInfo_writeToParcel() {
final Matrix matrix = new Matrix();
matrix.setRotate(15f);
TextBoundsInfo textBoundsInfo1 = new TextBoundsInfo.Builder(5, 10)
.setMatrix(matrix)
.setCharacterBounds(CHARACTER_BOUNDS1)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setCharacterFlags(CHARACTER_FLAGS1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER1)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
// Gut check, making sure the first TextBoundsInfo is built correctly.
assertEquals(5, textBoundsInfo1.getStartIndex());
assertEquals(10, textBoundsInfo1.getEndIndex());
final Matrix actualMatrix = new Matrix();
textBoundsInfo1.getMatrix(actualMatrix);
assertEquals(matrix, actualMatrix);
assertCharacterBounds(CHARACTER_BOUNDS1, textBoundsInfo1);
assertCharacterFlags(CHARACTER_FLAGS1, textBoundsInfo1);
assertCharacterBidiLevel(CHARACTER_BIDI_LEVEL1, textBoundsInfo1);
assertEquals(GRAPHEME_SEGMENT_FINDER1, textBoundsInfo1.getGraphemeSegmentFinder());
assertEquals(WORD_SEGMENT_FINDER1, textBoundsInfo1.getWordSegmentFinder());
assertEquals(LINE_SEGMENT_FINDER1, textBoundsInfo1.getLineSegmentFinder());
Parcel parcel = Parcel.obtain();
final int dataPosition = parcel.dataPosition();
parcel.writeParcelable(textBoundsInfo1, 0);
parcel.setDataPosition(dataPosition);
TextBoundsInfo textBoundsInfo2 =
parcel.readParcelable(TextBoundsInfo.class.getClassLoader(), TextBoundsInfo.class);
assertEquals(5, textBoundsInfo2.getStartIndex());
assertEquals(10, textBoundsInfo2.getEndIndex());
textBoundsInfo2.getMatrix(actualMatrix);
assertEquals(matrix, actualMatrix);
assertCharacterBounds(CHARACTER_BOUNDS1, textBoundsInfo2);
assertCharacterFlags(CHARACTER_FLAGS1, textBoundsInfo1);
assertCharacterBidiLevel(CHARACTER_BIDI_LEVEL1, textBoundsInfo1);
// Only check the iterator in the given range.
assertSegmentFinderEqualsInRange(GRAPHEME_SEGMENT_FINDER1,
textBoundsInfo2.getGraphemeSegmentFinder(), 5, 10);
assertSegmentFinderEqualsInRange(WORD_SEGMENT_FINDER1,
textBoundsInfo2.getWordSegmentFinder(), 5, 10);
assertSegmentFinderEqualsInRange(LINE_SEGMENT_FINDER1,
textBoundsInfo2.getLineSegmentFinder(), 5, 10);
}
@Test(expected = IllegalStateException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#build" })
public void testBuilder_matrix_isRequired() {
new TextBoundsInfo.Builder(5, 10)
.setCharacterBounds(CHARACTER_BOUNDS1)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setCharacterFlags(CHARACTER_FLAGS1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
}
@Test(expected = IllegalStateException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#build" })
public void testBuilder_startAndEnd_isRequired() {
final TextBoundsInfo.Builder builder = new TextBoundsInfo.Builder(5, 10);
builder.clear();
builder.setMatrix(Matrix.IDENTITY_MATRIX)
.setCharacterBounds(CHARACTER_BOUNDS1)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setCharacterFlags(CHARACTER_FLAGS1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
}
@Test(expected = IllegalArgumentException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#setStart" })
public void testBuilder_start_isNegative() {
new TextBoundsInfo.Builder(-1 , 5);
}
@Test(expected = IllegalArgumentException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#setEnd" })
public void testBuilder_end_isNegative() {
new TextBoundsInfo.Builder(0, -1);
}
@Test(expected = IllegalArgumentException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#build" })
public void testBuilder_startGreaterThanEnd() {
new TextBoundsInfo.Builder(1, 0);
}
@Test(expected = IllegalStateException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#build" })
public void testBuilder_characterBounds_isRequired() {
new TextBoundsInfo.Builder(5, 10)
.setMatrix(Matrix.IDENTITY_MATRIX)
.setCharacterFlags(CHARACTER_FLAGS1)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
}
@Test(expected = NullPointerException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#setCharacterBounds" })
public void testBuilder_characterBounds_isNull() {
new TextBoundsInfo.Builder(0, 5).setCharacterBounds(null);
}
@Test(expected = IllegalStateException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#build" })
public void testBuilder_characterBounds_wrongLength() {
// Expected characterBounds.length == 20 to match the given range [0, 5).
new TextBoundsInfo.Builder(5, 10)
.setMatrix(Matrix.IDENTITY_MATRIX)
.setCharacterBounds(new float[16])
.setCharacterFlags(CHARACTER_FLAGS1)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
}
@Test(expected = IllegalStateException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#build" })
public void testBuilder_characterFlags_isRequired() {
new TextBoundsInfo.Builder(5, 10)
.setMatrix(Matrix.IDENTITY_MATRIX)
.setCharacterBounds(CHARACTER_BOUNDS1)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
}
@Test(expected = NullPointerException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#setCharacterFlags" })
public void testBuilder_characterFlags_isNull() {
new TextBoundsInfo.Builder(5, 10).setCharacterFlags(null);
}
@Test(expected = IllegalStateException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#build" })
public void testBuilder_characterFlags_wrongLength() {
// Expected characterFlags.length == 5 to match the given range [0, 5).
new TextBoundsInfo.Builder(5, 10)
.setMatrix(Matrix.IDENTITY_MATRIX)
.setCharacterFlags(new int[6])
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setCharacterBounds(CHARACTER_BOUNDS1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
}
@Test(expected = IllegalStateException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#build" })
public void testBuilder_characterBidiLevel_isRequired() {
new TextBoundsInfo.Builder(5, 10)
.setMatrix(Matrix.IDENTITY_MATRIX)
.setCharacterBounds(CHARACTER_BOUNDS1)
.setCharacterFlags(CHARACTER_FLAGS1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
}
@Test(expected = NullPointerException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#setCharacterBidiLevel" })
public void testBuilder_characterBidiLevel_isNull() {
new TextBoundsInfo.Builder(5, 10).setCharacterBidiLevel(null);
}
@Test(expected = IllegalStateException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#build" })
public void testBuilder_characterBidiLevel_wrongLength() {
// Expected characterBidiLevel.length == 5 to match the given range [0, 5).
new TextBoundsInfo.Builder(5, 10)
.setMatrix(Matrix.IDENTITY_MATRIX)
.setCharacterFlags(CHARACTER_FLAGS1)
.setCharacterBidiLevel(new int[6])
.setCharacterBounds(CHARACTER_BOUNDS1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
}
@Test
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#setCharacterBidiLevel" })
public void testBuilder_characterBidiLevel_invalidBidiLevel() {
// Bidi level must be in the range of [0, 125].
try {
new TextBoundsInfo.Builder(0, 1).setCharacterBidiLevel(new int[] { 126 });
fail();
} catch (IllegalArgumentException ignored) { }
try {
new TextBoundsInfo.Builder(0 , 1).setCharacterBidiLevel(new int[] { -1 });
fail();
} catch (IllegalArgumentException ignored) { }
}
@Test
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#setCharacterBidiLevel" })
public void testBuilder_characterBidiLevel_isCleared() {
final var builder = new TextBoundsInfo.Builder(5, 10)
.setMatrix(Matrix.IDENTITY_MATRIX)
.setCharacterFlags(CHARACTER_FLAGS1)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setCharacterBounds(CHARACTER_BOUNDS1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1);
builder.build();
builder.clear();
builder.setMatrix(Matrix.IDENTITY_MATRIX)
.setStartAndEnd(5, 10)
.setCharacterFlags(CHARACTER_FLAGS1)
// omit setting characterBidiLevel.
.setCharacterBounds(CHARACTER_BOUNDS1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1);
assertThrows(IllegalStateException.class, builder::build);
}
@Test(expected = IllegalArgumentException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#setCharacterFlags" })
public void testBuilder_characterFlags_invalidFlag() {
TextBoundsInfo.Builder builder = new TextBoundsInfo.Builder(0, 5);
// 1 << 20 is an unknown flags
int[] characterFlags = new int[] { 0, 1 << 20, 0, 0, 0};
builder.setCharacterFlags(characterFlags);
}
@Test(expected = IllegalStateException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#build" })
public void testBuilder_graphemeSegmentFinder_isRequired() {
new TextBoundsInfo.Builder(5, 10)
.setMatrix(Matrix.IDENTITY_MATRIX)
.setCharacterBounds(CHARACTER_BOUNDS1)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setCharacterFlags(CHARACTER_FLAGS1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
}
@Test(expected = NullPointerException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#setGraphemeSegmentFinder" })
public void testBuilder_graphemeSegmentFinder_isNull() {
new TextBoundsInfo.Builder(5, 10).setGraphemeSegmentFinder(null);
}
@Test(expected = IllegalStateException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#build" })
public void testBuilder_wordSegmentFinder_isRequired() {
new TextBoundsInfo.Builder(5, 10)
.setMatrix(Matrix.IDENTITY_MATRIX)
.setCharacterBounds(CHARACTER_BOUNDS1)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setCharacterFlags(CHARACTER_FLAGS1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
}
@Test(expected = NullPointerException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#setWordSegmentFinder" })
public void testBuilder_wordSegmentFinder_isNull() {
new TextBoundsInfo.Builder(5, 10).setWordSegmentFinder(null);
}
@Test(expected = IllegalStateException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#build" })
public void testBuilder_lineSegmentFinder_isRequired() {
new TextBoundsInfo.Builder(5, 10)
.setMatrix(Matrix.IDENTITY_MATRIX)
.setCharacterBounds(CHARACTER_BOUNDS1)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setCharacterFlags(CHARACTER_FLAGS1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER2)
.build();
}
@Test(expected = NullPointerException.class)
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfo.Builder#setLineSegmentFinder" })
public void testBuilder_lineSegmentFinder_isNull() {
new TextBoundsInfo.Builder(5, 10).setLineSegmentFinder(null);
}
@Test
@ApiTest(apis = { "android.view.inputmethod.TextBoundsInfoResult#getResultCode",
"android.view.inputmethod.TextBoundsInfoResult#getTextBoundsInfo"})
public void testTextBoundsInfoResult_constructor() {
TextBoundsInfoResult result =
new TextBoundsInfoResult(TextBoundsInfoResult.CODE_UNSUPPORTED);
assertEquals(result.getResultCode(), TextBoundsInfoResult.CODE_UNSUPPORTED);
result = new TextBoundsInfoResult(TextBoundsInfoResult.CODE_FAILED);
assertEquals(result.getResultCode(), TextBoundsInfoResult.CODE_FAILED);
result = new TextBoundsInfoResult(TextBoundsInfoResult.CODE_CANCELLED);
assertEquals(result.getResultCode(), TextBoundsInfoResult.CODE_CANCELLED);
final TextBoundsInfo textBoundsInfo = new TextBoundsInfo.Builder(5, 10)
.setCharacterBounds(CHARACTER_BOUNDS1)
.setCharacterBidiLevel(CHARACTER_BIDI_LEVEL1)
.setMatrix(Matrix.IDENTITY_MATRIX)
.setCharacterFlags(CHARACTER_FLAGS1)
.setGraphemeSegmentFinder(GRAPHEME_SEGMENT_FINDER1)
.setWordSegmentFinder(WORD_SEGMENT_FINDER1)
.setLineSegmentFinder(LINE_SEGMENT_FINDER1)
.build();
result = new TextBoundsInfoResult(TextBoundsInfoResult.CODE_SUCCESS,
textBoundsInfo);
assertEquals(result.getResultCode(), TextBoundsInfoResult.CODE_SUCCESS);
assertEquals(result.getTextBoundsInfo(), textBoundsInfo);
}
@Test
public void testTextBoundsInfoResult_resultCodeIsSuccess_textBoundsInfoIsRequired() {
try {
new TextBoundsInfoResult(TextBoundsInfoResult.CODE_SUCCESS);
fail();
} catch (IllegalStateException ignored) { }
try {
new TextBoundsInfoResult(TextBoundsInfoResult.CODE_SUCCESS, null);
fail();
} catch (IllegalStateException ignored) { }
}
private static void assertCharacterBounds(float[] characterBounds,
TextBoundsInfo textBoundsInfo) {
final int start = textBoundsInfo.getStartIndex();
final int end = textBoundsInfo.getEndIndex();
for (int offset = 0; offset < end - start; ++offset) {
final RectF expectedRect = new RectF(
characterBounds[4 * offset],
characterBounds[4 * offset + 1],
characterBounds[4 * offset + 2],
characterBounds[4 * offset + 3]);
final RectF actualRectF = new RectF();
textBoundsInfo.getCharacterBounds(offset + start, actualRectF);
assertEquals(expectedRect, actualRectF);
}
}
private static void assertCharacterFlags(int[] characterFlags,
TextBoundsInfo textBoundsInfo) {
final int start = textBoundsInfo.getStartIndex();
final int end = textBoundsInfo.getEndIndex();
for (int offset = 0; offset < end - start; ++offset) {
assertEquals(characterFlags[offset],
textBoundsInfo.getCharacterFlags(offset + start));
}
}
private static void assertCharacterBidiLevel(int[] characterBidiLevels,
TextBoundsInfo textBoundsInfo) {
final int start = textBoundsInfo.getStartIndex();
final int end = textBoundsInfo.getEndIndex();
for (int offset = 0; offset < end - start; ++offset) {
assertEquals(characterBidiLevels[offset],
textBoundsInfo.getCharacterBidiLevel(offset + start));
}
}
/**
* Helper method to assert that the given {@link SegmentFinder}s are the same in the given
* range.
*/
private static void assertSegmentFinderEqualsInRange(SegmentFinder expect,
SegmentFinder actual, int start, int end) {
int expectSegmentEnd = expect.nextEndBoundary(start);
int expectSegmentStart = expect.previousStartBoundary(expectSegmentEnd);
int actualSegmentEnd = actual.nextEndBoundary(start);
int actualSegmentStart = actual.previousStartBoundary(actualSegmentEnd);
while (expectSegmentStart != SegmentFinder.DONE && expectSegmentEnd <= end) {
assertEquals(expectSegmentStart, actualSegmentStart);
assertEquals(expectSegmentEnd, actualSegmentEnd);
expectSegmentStart = expect.nextStartBoundary(expectSegmentStart);
actualSegmentStart = actual.nextStartBoundary(actualSegmentStart);
expectSegmentEnd = expect.nextEndBoundary(expectSegmentEnd);
actualSegmentEnd = actual.nextEndBoundary(actualSegmentEnd);
}
// The actual SegmentFinder doesn't have more segments within the range.
assertTrue(actualSegmentEnd > end || actualSegmentEnd == SegmentFinder.DONE);
}
}