blob: 9e0e917121e52fc4cd1cb8a7c8476e3feb7da691 [file] [log] [blame]
package org.robolectric.integrationtests.nativegraphics;
import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import android.graphics.Interpolator;
import android.graphics.Interpolator.Result;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(minSdk = O)
public class ShadowNativeInterpolatorTest {
private static final int DEFAULT_KEYFRAME_COUNT = 2;
private static final float TOLERANCE = 0.1f;
@Test
public void testConstructor() {
Interpolator interpolator = new Interpolator(10);
assertEquals(10, interpolator.getValueCount());
assertEquals(DEFAULT_KEYFRAME_COUNT, interpolator.getKeyFrameCount());
interpolator = new Interpolator(15, 20);
assertEquals(15, interpolator.getValueCount());
assertEquals(20, interpolator.getKeyFrameCount());
}
@Test
public void testReset1() {
final int expected = 100;
Interpolator interpolator = new Interpolator(10);
assertEquals(DEFAULT_KEYFRAME_COUNT, interpolator.getKeyFrameCount());
interpolator.reset(expected);
assertEquals(expected, interpolator.getValueCount());
assertEquals(DEFAULT_KEYFRAME_COUNT, interpolator.getKeyFrameCount());
}
@Test
public void testReset2() {
int expected1 = 100;
int expected2 = 200;
// new the Interpolator instance
Interpolator interpolator = new Interpolator(10);
interpolator.reset(expected1, expected2);
assertEquals(expected1, interpolator.getValueCount());
assertEquals(expected2, interpolator.getKeyFrameCount());
}
@Test
public void testTimeToValues2() {
Interpolator interpolator = new Interpolator(1);
interpolator.setKeyFrame(0, 2000, new float[] {1.0f});
interpolator.setKeyFrame(1, 4000, new float[] {2.0f});
verifyValue(1000, 1.0f, Result.FREEZE_START, interpolator);
verifyValue(3000, 1.5f, Result.NORMAL, interpolator);
verifyValue(6000, 2.0f, Result.FREEZE_END, interpolator);
// known bug: time argument is unsigned 32bit in graphics library
verifyValue(-1000, 2.0f, Result.FREEZE_END, interpolator);
interpolator.reset(1, 3);
interpolator.setKeyFrame(0, 2000, new float[] {1.0f});
interpolator.setKeyFrame(1, 4000, new float[] {2.0f});
interpolator.setKeyFrame(2, 6000, new float[] {4.0f});
verifyValue(0, 1.0f, Result.FREEZE_START, interpolator);
verifyValue(3000, 1.5f, Result.NORMAL, interpolator);
verifyValue(5000, 3.0f, Result.NORMAL, interpolator);
verifyValue(8000, 4.0f, Result.FREEZE_END, interpolator);
final int valueCount = 2;
final int validTime = 0;
interpolator.reset(valueCount);
assertEquals(valueCount, interpolator.getValueCount());
try {
// value array too short
interpolator.timeToValues(validTime, new float[valueCount - 1]);
fail("should throw out ArrayStoreException");
} catch (ArrayStoreException e) {
// expected
}
interpolator.reset(2, 2);
interpolator.setKeyFrame(0, 4000, new float[] {1.0f, 1.0f});
interpolator.setKeyFrame(1, 6000, new float[] {2.0f, 4.0f});
verifyValues(2000, new float[] {1.0f, 1.0f}, Result.FREEZE_START, interpolator);
verifyValues(5000, new float[] {1.5f, 2.5f}, Result.NORMAL, interpolator);
verifyValues(8000, new float[] {2.0f, 4.0f}, Result.FREEZE_END, interpolator);
}
@Test
public void testSetRepeatMirror() {
Interpolator interpolator = new Interpolator(1, 3);
interpolator.setKeyFrame(0, 2000, new float[] {1.0f});
interpolator.setKeyFrame(1, 4000, new float[] {2.0f});
interpolator.setKeyFrame(2, 6000, new float[] {4.0f});
verifyValue(1000, 1.0f, Result.FREEZE_START, interpolator);
verifyValue(3000, 1.5f, Result.NORMAL, interpolator);
verifyValue(5000, 3.0f, Result.NORMAL, interpolator);
verifyValue(7000, 4.0f, Result.FREEZE_END, interpolator);
// repeat once, no mirror
interpolator.setRepeatMirror(2, false);
verifyValue(1000, 4.0f, Result.FREEZE_END, interpolator); // known bug
verifyValue(3000, 1.5f, Result.NORMAL, interpolator);
verifyValue(5000, 3.0f, Result.NORMAL, interpolator);
verifyValue(7000, 1.5f, Result.NORMAL, interpolator);
verifyValue(9000, 3.0f, Result.NORMAL, interpolator);
verifyValue(11000, 4.0f, Result.FREEZE_END, interpolator);
// repeat once, mirror
interpolator.setRepeatMirror(2, true);
verifyValue(1000, 4.0f, Result.FREEZE_END, interpolator); // known bug
verifyValue(3000, 1.5f, Result.NORMAL, interpolator);
verifyValue(5000, 3.0f, Result.NORMAL, interpolator);
verifyValue(7000, 3.0f, Result.NORMAL, interpolator);
verifyValue(9000, 1.5f, Result.NORMAL, interpolator);
verifyValue(11000, 4.0f, Result.FREEZE_END, interpolator);
}
@Test
public void testSetKeyFrame() {
final float[] aZero = new float[] {0.0f};
final float[] aOne = new float[] {1.0f};
Interpolator interpolator = new Interpolator(1);
interpolator.setKeyFrame(0, 2000, aZero);
interpolator.setKeyFrame(1, 4000, aOne);
verifyValue(1000, 0.0f, Result.FREEZE_START, interpolator);
verifyValue(3000, 0.5f, Result.NORMAL, interpolator);
verifyValue(5000, 1.0f, Result.FREEZE_END, interpolator);
final float[] linearBlend = new float[] {0.0f, 0.0f, 1.0f, 1.0f};
final float[] accelerateBlend =
new float[] {
// approximate circle at PI/6 and PI/3
0.5f, 1.0f - 0.866f, 0.866f, 0.5f
};
final float[] decelerateBlend =
new float[] {
// approximate circle at PI/6 and PI/3
1.0f - 0.866f, 0.5f, 0.5f, 0.866f
};
// explicit linear blend should yield the same values
interpolator.setKeyFrame(0, 2000, aZero, linearBlend);
interpolator.setKeyFrame(1, 4000, aOne, linearBlend);
verifyValue(1000, 0.0f, Result.FREEZE_START, interpolator);
verifyValue(3000, 0.5f, Result.NORMAL, interpolator);
verifyValue(5000, 1.0f, Result.FREEZE_END, interpolator);
// blend of end key frame is not used
interpolator.setKeyFrame(0, 2000, aZero);
interpolator.setKeyFrame(1, 4000, aOne, accelerateBlend);
verifyValue(1000, 0.0f, Result.FREEZE_START, interpolator);
verifyValue(3000, 0.5f, Result.NORMAL, interpolator);
verifyValue(5000, 1.0f, Result.FREEZE_END, interpolator);
final float[] result = new float[1];
interpolator.setKeyFrame(0, 2000, aZero, accelerateBlend);
interpolator.setKeyFrame(1, 4000, aOne);
verifyValue(1000, 0.0f, Result.FREEZE_START, interpolator);
assertEquals(Result.NORMAL, interpolator.timeToValues(3000, result));
assertThat(result[0]).isLessThan(0.5f); // exact blend algorithm not known
verifyValue(5000, 1.0f, Result.FREEZE_END, interpolator);
interpolator.setKeyFrame(0, 2000, aZero, decelerateBlend);
interpolator.setKeyFrame(1, 4000, aOne);
verifyValue(1000, 0.0f, Result.FREEZE_START, interpolator);
assertEquals(Result.NORMAL, interpolator.timeToValues(3000, result));
assertThat(result[0]).isGreaterThan(0.5f); // exact blend algorithm not known
verifyValue(5000, 1.0f, Result.FREEZE_END, interpolator);
final int validTime = 0;
final int valueCount = 2;
interpolator.reset(valueCount);
assertEquals(valueCount, interpolator.getValueCount());
try {
// value array too short
interpolator.setKeyFrame(0, validTime, new float[valueCount - 1]);
fail("should throw ArrayStoreException");
} catch (ArrayStoreException e) {
// expected
}
try {
// index too small
interpolator.setKeyFrame(-1, validTime, new float[valueCount]);
fail("should throw IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
// index too large
interpolator.setKeyFrame(2, validTime, new float[valueCount]);
fail("should throw IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
// blend array too short
interpolator.setKeyFrame(0, validTime, new float[valueCount], new float[3]);
fail("should throw ArrayStoreException");
} catch (ArrayStoreException e) {
// expected
}
}
private void verifyValue(
int time, float expected, Result expectedResult, Interpolator interpolator) {
float[] values = new float[1];
assertEquals(expectedResult, interpolator.timeToValues(time, values));
assertEquals(expected, values[0], TOLERANCE);
}
private void verifyValues(
int time, float[] expected, Result expectedResult, Interpolator interpolator) {
float[] values = new float[expected.length];
assertEquals(expectedResult, interpolator.timeToValues(time, values));
assertArrayEquals(expected, values, TOLERANCE);
}
}