Fix InputPointersTests

InputPointers.getTime(int) has a validity check of time values. And
the check is enabled when LatinImeLogger.sDBG is on. Such situation
may occur while unit testing. This change ensure that time values are
monotonic while unit testing.

Change-Id: I9ff2cff2bcd253de0e8206dd3be964fe565170fa
main
Tadashi G. Takaoka 2014-01-07 17:43:44 +09:00
parent 385031557b
commit e7dc5302af
2 changed files with 167 additions and 99 deletions

View File

@ -16,14 +16,16 @@
package com.android.inputmethod.latin;
import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.utils.ResizableIntArray;
import android.util.Log;
// TODO: This class is not thread-safe.
public final class InputPointers {
private static final String TAG = InputPointers.class.getSimpleName();
private static final boolean DEBUG_TIME = false;
private final int mDefaultCapacity;
private final ResizableIntArray mXCoordinates;
private final ResizableIntArray mYCoordinates;
@ -38,10 +40,29 @@ public final class InputPointers {
mTimes = new ResizableIntArray(defaultCapacity);
}
private void fillWithLastTimeUntil(final int index) {
final int fromIndex = mTimes.getLength();
// Fill the gap with the latest time.
// See {@link #getTime(int)} and {@link #isValidTimeStamps()}.
if (fromIndex <= 0) {
return;
}
final int fillLength = index - fromIndex + 1;
if (fillLength <= 0) {
return;
}
final int lastTime = mTimes.get(fromIndex - 1);
mTimes.fill(lastTime, fromIndex, fillLength);
}
// TODO: Rename this method to addPointerAt
public void addPointer(int index, int x, int y, int pointerId, int time) {
mXCoordinates.add(index, x);
mYCoordinates.add(index, y);
mPointerIds.add(index, pointerId);
if (LatinImeLogger.sDBG || DEBUG_TIME) {
fillWithLastTimeUntil(index);
}
mTimes.add(index, time);
}
@ -67,23 +88,6 @@ public final class InputPointers {
mTimes.copy(ip.mTimes);
}
/**
* Append the pointers in the specified {@link InputPointers} to the end of this.
* @param src the source {@link InputPointers} to read the data from.
* @param startPos the starting index of the pointers in {@code src}.
* @param length the number of pointers to be appended.
*/
@UsedForTesting
void append(InputPointers src, int startPos, int length) {
if (length == 0) {
return;
}
mXCoordinates.append(src.mXCoordinates, startPos, length);
mYCoordinates.append(src.mYCoordinates, startPos, length);
mPointerIds.append(src.mPointerIds, startPos, length);
mTimes.append(src.mTimes, startPos, length);
}
/**
* Append the times, x-coordinates and y-coordinates in the specified {@link ResizableIntArray}
* to the end of this.
@ -141,7 +145,7 @@ public final class InputPointers {
}
public int[] getTimes() {
if (LatinImeLogger.sDBG) {
if (LatinImeLogger.sDBG || DEBUG_TIME) {
if (!isValidTimeStamps()) {
throw new RuntimeException("Time stamps are invalid.");
}
@ -157,10 +161,11 @@ public final class InputPointers {
private boolean isValidTimeStamps() {
final int[] times = mTimes.getPrimitiveArray();
for (int i = 1; i < getPointerSize(); ++i) {
final int size = getPointerSize();
for (int i = 1; i < size; ++i) {
if (times[i] < times[i - 1]) {
// dump
for (int j = 0; j < times.length; ++j) {
for (int j = 0; j < size; ++j) {
Log.d(TAG, "--- (" + j + ") " + times[j]);
}
return false;

View File

@ -55,14 +55,22 @@ public class InputPointersTests extends AndroidTestCase {
final InputPointers src = new InputPointers(DEFAULT_CAPACITY);
final int limit = src.getXCoordinates().length * 2 + 10;
for (int i = 0; i < limit; i++) {
src.addPointer(i, i * 2, i * 3, i * 4);
final int x = i;
final int y = i * 2;
final int pointerId = i * 3;
final int time = i * 4;
src.addPointer(x, y, pointerId, time);
assertEquals("size after add " + i, i + 1, src.getPointerSize());
}
for (int i = 0; i < limit; i++) {
assertEquals("xCoordinates at " + i, i, src.getXCoordinates()[i]);
assertEquals("yCoordinates at " + i, i * 2, src.getYCoordinates()[i]);
assertEquals("pointerIds at " + i, i * 3, src.getPointerIds()[i]);
assertEquals("times at " + i, i * 4, src.getTimes()[i]);
final int x = i;
final int y = i * 2;
final int pointerId = i * 3;
final int time = i * 4;
assertEquals("xCoordinates at " + i, x, src.getXCoordinates()[i]);
assertEquals("yCoordinates at " + i, y, src.getYCoordinates()[i]);
assertEquals("pointerIds at " + i, pointerId, src.getPointerIds()[i]);
assertEquals("times at " + i, time, src.getTimes()[i]);
}
}
@ -70,14 +78,22 @@ public class InputPointersTests extends AndroidTestCase {
final InputPointers src = new InputPointers(DEFAULT_CAPACITY);
final int limit = 1000, step = 100;
for (int i = 0; i < limit; i += step) {
src.addPointer(i, i, i * 2, i * 3, i * 4);
final int x = i;
final int y = i * 2;
final int pointerId = i * 3;
final int time = i * 4;
src.addPointer(i, x, y, pointerId, time);
assertEquals("size after add at " + i, i + 1, src.getPointerSize());
}
for (int i = 0; i < limit; i += step) {
assertEquals("xCoordinates at " + i, i, src.getXCoordinates()[i]);
assertEquals("yCoordinates at " + i, i * 2, src.getYCoordinates()[i]);
assertEquals("pointerIds at " + i, i * 3, src.getPointerIds()[i]);
assertEquals("times at " + i, i * 4, src.getTimes()[i]);
final int x = i;
final int y = i * 2;
final int pointerId = i * 3;
final int time = i * 4;
assertEquals("xCoordinates at " + i, x, src.getXCoordinates()[i]);
assertEquals("yCoordinates at " + i, y, src.getYCoordinates()[i]);
assertEquals("pointerIds at " + i, pointerId, src.getPointerIds()[i]);
assertEquals("times at " + i, time, src.getTimes()[i]);
}
}
@ -85,7 +101,11 @@ public class InputPointersTests extends AndroidTestCase {
final InputPointers src = new InputPointers(DEFAULT_CAPACITY);
final int limit = src.getXCoordinates().length * 2 + 10;
for (int i = 0; i < limit; i++) {
src.addPointer(i, i * 2, i * 3, i * 4);
final int x = i;
final int y = i * 2;
final int pointerId = i * 3;
final int time = i * 4;
src.addPointer(x, y, pointerId, time);
}
final InputPointers dst = new InputPointers(DEFAULT_CAPACITY);
dst.set(src);
@ -100,7 +120,11 @@ public class InputPointersTests extends AndroidTestCase {
final InputPointers src = new InputPointers(DEFAULT_CAPACITY);
final int limit = 100;
for (int i = 0; i < limit; i++) {
src.addPointer(i, i * 2, i * 3, i * 4);
final int x = i;
final int y = i * 2;
final int pointerId = i * 3;
final int time = i * 4;
src.addPointer(x, y, pointerId, time);
}
final InputPointers dst = new InputPointers(DEFAULT_CAPACITY);
dst.copy(src);
@ -121,106 +145,135 @@ public class InputPointersTests extends AndroidTestCase {
}
public void testAppend() {
final InputPointers src = new InputPointers(DEFAULT_CAPACITY);
final int srcLen = 100;
for (int i = 0; i < srcLen; i++) {
src.addPointer(i, i * 2, i * 3, i * 4);
}
final int dstLen = 50;
final int dstLength = 50;
final InputPointers dst = new InputPointers(DEFAULT_CAPACITY);
for (int i = 0; i < dstLen; i++) {
final int value = -i - 1;
dst.addPointer(value * 4, value * 3, value * 2, value);
for (int i = 0; i < dstLength; i++) {
final int x = i * 4;
final int y = i * 3;
final int pointerId = i * 2;
final int time = i;
dst.addPointer(x, y, pointerId, time);
}
final InputPointers dstCopy = new InputPointers(DEFAULT_CAPACITY);
dstCopy.copy(dst);
dst.append(src, 0, 0);
assertEquals("size after append zero", dstLen, dst.getPointerSize());
assertIntArrayEquals("xCoordinates after append zero",
dstCopy.getXCoordinates(), 0, dst.getXCoordinates(), 0, dstLen);
assertIntArrayEquals("yCoordinates after append zero",
dstCopy.getYCoordinates(), 0, dst.getYCoordinates(), 0, dstLen);
assertIntArrayEquals("pointerIds after append zero",
dstCopy.getPointerIds(), 0, dst.getPointerIds(), 0, dstLen);
assertIntArrayEquals("times after append zero",
dstCopy.getTimes(), 0, dst.getTimes(), 0, dstLen);
final ResizableIntArray srcXCoords = new ResizableIntArray(DEFAULT_CAPACITY);
final ResizableIntArray srcYCoords = new ResizableIntArray(DEFAULT_CAPACITY);
final ResizableIntArray srcPointerIds = new ResizableIntArray(DEFAULT_CAPACITY);
final ResizableIntArray srcTimes = new ResizableIntArray(DEFAULT_CAPACITY);
final int srcLength = 100;
final int srcPointerId = 10;
for (int i = 0; i < srcLength; i++) {
final int x = i;
final int y = i * 2;
// The time value must be larger than <code>dst</code>.
final int time = i * 4 + dstLength;
srcXCoords.add(x);
srcYCoords.add(y);
srcPointerIds.add(srcPointerId);
srcTimes.add(time);
}
dst.append(src, 0, srcLen);
assertEquals("size after append", dstLen + srcLen, dst.getPointerSize());
final int startPos = 0;
dst.append(srcPointerId, srcTimes, srcXCoords, srcYCoords,
startPos, 0 /* length */);
assertEquals("size after append zero", dstLength, dst.getPointerSize());
assertIntArrayEquals("xCoordinates after append zero",
dstCopy.getXCoordinates(), startPos, dst.getXCoordinates(), startPos, dstLength);
assertIntArrayEquals("yCoordinates after append zero",
dstCopy.getYCoordinates(), startPos, dst.getYCoordinates(), startPos, dstLength);
assertIntArrayEquals("pointerIds after append zero",
dstCopy.getPointerIds(), startPos, dst.getPointerIds(), startPos, dstLength);
assertIntArrayEquals("times after append zero",
dstCopy.getTimes(), startPos, dst.getTimes(), startPos, dstLength);
dst.append(srcPointerId, srcTimes, srcXCoords, srcYCoords,
startPos, srcLength);
assertEquals("size after append", dstLength + srcLength, dst.getPointerSize());
assertTrue("primitive length after append",
dst.getPointerIds().length >= dstLen + srcLen);
dst.getPointerIds().length >= dstLength + srcLength);
assertIntArrayEquals("original xCoordinates values after append",
dstCopy.getXCoordinates(), 0, dst.getXCoordinates(), 0, dstLen);
dstCopy.getXCoordinates(), startPos, dst.getXCoordinates(), startPos, dstLength);
assertIntArrayEquals("original yCoordinates values after append",
dstCopy.getYCoordinates(), 0, dst.getYCoordinates(), 0, dstLen);
dstCopy.getYCoordinates(), startPos, dst.getYCoordinates(), startPos, dstLength);
assertIntArrayEquals("original pointerIds values after append",
dstCopy.getPointerIds(), 0, dst.getPointerIds(), 0, dstLen);
dstCopy.getPointerIds(), startPos, dst.getPointerIds(), startPos, dstLength);
assertIntArrayEquals("original times values after append",
dstCopy.getTimes(), 0, dst.getTimes(), 0, dstLen);
dstCopy.getTimes(), startPos, dst.getTimes(), startPos, dstLength);
assertIntArrayEquals("appended xCoordinates values after append",
src.getXCoordinates(), 0, dst.getXCoordinates(), dstLen, srcLen);
srcXCoords.getPrimitiveArray(), startPos, dst.getXCoordinates(),
dstLength, srcLength);
assertIntArrayEquals("appended yCoordinates values after append",
src.getYCoordinates(), 0, dst.getYCoordinates(), dstLen, srcLen);
srcYCoords.getPrimitiveArray(), startPos, dst.getYCoordinates(),
dstLength, srcLength);
assertIntArrayEquals("appended pointerIds values after append",
src.getPointerIds(), 0, dst.getPointerIds(), dstLen, srcLen);
srcPointerIds.getPrimitiveArray(), startPos, dst.getPointerIds(),
dstLength, srcLength);
assertIntArrayEquals("appended times values after append",
src.getTimes(), 0, dst.getTimes(), dstLen, srcLen);
srcTimes.getPrimitiveArray(), startPos, dst.getTimes(), dstLength, srcLength);
}
public void testAppendResizableIntArray() {
final int srcLen = 100;
final int dstLength = 50;
final InputPointers dst = new InputPointers(DEFAULT_CAPACITY);
for (int i = 0; i < dstLength; i++) {
final int x = i * 4;
final int y = i * 3;
final int pointerId = i * 2;
final int time = i;
dst.addPointer(x, y, pointerId, time);
}
final InputPointers dstCopy = new InputPointers(DEFAULT_CAPACITY);
dstCopy.copy(dst);
final int srcLength = 100;
final int srcPointerId = 1;
final int[] srcPointerIds = new int[srcLen];
final int[] srcPointerIds = new int[srcLength];
Arrays.fill(srcPointerIds, srcPointerId);
final ResizableIntArray srcTimes = new ResizableIntArray(DEFAULT_CAPACITY);
final ResizableIntArray srcXCoords = new ResizableIntArray(DEFAULT_CAPACITY);
final ResizableIntArray srcYCoords= new ResizableIntArray(DEFAULT_CAPACITY);
for (int i = 0; i < srcLen; i++) {
srcTimes.add(i * 2);
srcXCoords.add(i * 3);
srcYCoords.add(i * 4);
for (int i = 0; i < srcLength; i++) {
// The time value must be larger than <code>dst</code>.
final int time = i * 2 + dstLength;
final int x = i * 3;
final int y = i * 4;
srcTimes.add(time);
srcXCoords.add(x);
srcYCoords.add(y);
}
final int dstLen = 50;
final InputPointers dst = new InputPointers(DEFAULT_CAPACITY);
for (int i = 0; i < dstLen; i++) {
final int value = -i - 1;
dst.addPointer(value * 4, value * 3, value * 2, value);
}
final InputPointers dstCopy = new InputPointers(DEFAULT_CAPACITY);
dstCopy.copy(dst);
dst.append(srcPointerId, srcTimes, srcXCoords, srcYCoords, 0, 0);
assertEquals("size after append zero", dstLen, dst.getPointerSize());
assertEquals("size after append zero", dstLength, dst.getPointerSize());
assertIntArrayEquals("xCoordinates after append zero",
dstCopy.getXCoordinates(), 0, dst.getXCoordinates(), 0, dstLen);
dstCopy.getXCoordinates(), 0, dst.getXCoordinates(), 0, dstLength);
assertIntArrayEquals("yCoordinates after append zero",
dstCopy.getYCoordinates(), 0, dst.getYCoordinates(), 0, dstLen);
dstCopy.getYCoordinates(), 0, dst.getYCoordinates(), 0, dstLength);
assertIntArrayEquals("pointerIds after append zero",
dstCopy.getPointerIds(), 0, dst.getPointerIds(), 0, dstLen);
dstCopy.getPointerIds(), 0, dst.getPointerIds(), 0, dstLength);
assertIntArrayEquals("times after append zero",
dstCopy.getTimes(), 0, dst.getTimes(), 0, dstLen);
dstCopy.getTimes(), 0, dst.getTimes(), 0, dstLength);
dst.append(srcPointerId, srcTimes, srcXCoords, srcYCoords, 0, srcLen);
assertEquals("size after append", dstLen + srcLen, dst.getPointerSize());
dst.append(srcPointerId, srcTimes, srcXCoords, srcYCoords, 0, srcLength);
assertEquals("size after append", dstLength + srcLength, dst.getPointerSize());
assertTrue("primitive length after append",
dst.getPointerIds().length >= dstLen + srcLen);
dst.getPointerIds().length >= dstLength + srcLength);
assertIntArrayEquals("original xCoordinates values after append",
dstCopy.getXCoordinates(), 0, dst.getXCoordinates(), 0, dstLen);
dstCopy.getXCoordinates(), 0, dst.getXCoordinates(), 0, dstLength);
assertIntArrayEquals("original yCoordinates values after append",
dstCopy.getYCoordinates(), 0, dst.getYCoordinates(), 0, dstLen);
dstCopy.getYCoordinates(), 0, dst.getYCoordinates(), 0, dstLength);
assertIntArrayEquals("original pointerIds values after append",
dstCopy.getPointerIds(), 0, dst.getPointerIds(), 0, dstLen);
dstCopy.getPointerIds(), 0, dst.getPointerIds(), 0, dstLength);
assertIntArrayEquals("original times values after append",
dstCopy.getTimes(), 0, dst.getTimes(), 0, dstLen);
dstCopy.getTimes(), 0, dst.getTimes(), 0, dstLength);
assertIntArrayEquals("appended xCoordinates values after append",
srcXCoords.getPrimitiveArray(), 0, dst.getXCoordinates(), dstLen, srcLen);
srcXCoords.getPrimitiveArray(), 0, dst.getXCoordinates(), dstLength, srcLength);
assertIntArrayEquals("appended yCoordinates values after append",
srcYCoords.getPrimitiveArray(), 0, dst.getYCoordinates(), dstLen, srcLen);
srcYCoords.getPrimitiveArray(), 0, dst.getYCoordinates(), dstLength, srcLength);
assertIntArrayEquals("appended pointerIds values after append",
srcPointerIds, 0, dst.getPointerIds(), dstLen, srcLen);
srcPointerIds, 0, dst.getPointerIds(), dstLength, srcLength);
assertIntArrayEquals("appended times values after append",
srcTimes.getPrimitiveArray(), 0, dst.getTimes(), dstLen, srcLen);
srcTimes.getPrimitiveArray(), 0, dst.getTimes(), dstLength, srcLength);
}
// TODO: Consolidate this method with
@ -250,14 +303,24 @@ public class InputPointersTests extends AndroidTestCase {
final int limit = 100;
final int shiftAmount = 20;
for (int i = 0; i < limit; i++) {
src.addPointer(i, i * 2, i * 3, i * 4);
final int x = i;
final int y = i * 2;
final int pointerId = i * 3;
final int time = i * 4;
src.addPointer(x, y, pointerId, time);
}
src.shift(shiftAmount);
assertEquals("length after shift", src.getPointerSize(), limit - shiftAmount);
for (int i = 0; i < limit - shiftAmount; ++i) {
assertEquals("xCoordinates at " + i, i + shiftAmount, src.getXCoordinates()[i]);
assertEquals("yCoordinates at " + i, (i + shiftAmount) * 2, src.getYCoordinates()[i]);
assertEquals("pointerIds at " + i, (i + shiftAmount) * 3, src.getPointerIds()[i]);
assertEquals("times at " + i, (i + shiftAmount) * 4, src.getTimes()[i]);
final int oldIndex = i + shiftAmount;
final int x = oldIndex;
final int y = oldIndex * 2;
final int pointerId = oldIndex * 3;
final int time = oldIndex * 4;
assertEquals("xCoordinates at " + i, x, src.getXCoordinates()[i]);
assertEquals("yCoordinates at " + i, y, src.getYCoordinates()[i]);
assertEquals("pointerIds at " + i, pointerId, src.getPointerIds()[i]);
assertEquals("times at " + i, time, src.getTimes()[i]);
}
}
}