@SmallTest public void testComputeScrollOffsetForFling() throws Exception { class TestData extends Parameter { final int velocity; final float decayRate; final int expectedScrollPosition; TestData(int velocity, float decayRate, int expectedScrollPosition) { this.velocity = velocity; this.decayRate = decayRate; this.expectedScrollPosition = expectedScrollPosition; } } int scrollPosition = 50; TestData[] testDataList = { new TestData(0, 0f, 50), // Decay rate is 0 so scroll animation happens only once. new TestData(+1000, 0f, 60), // Decay rate is 1 so scroll animation happens repeatedly until // reaching the maximum boundary. new TestData(+1000, 1f, 90), // Check boundary value. new TestData(Integer.MAX_VALUE, 1f, 90), }; SnapScroller.TimestampCalculator timestampCalculator = createMock(SnapScroller.TimestampCalculator.class); SnapScroller scroller = new SnapScroller(timestampCalculator); scroller.setContentSize(110); scroller.setPageSize(10); scroller.setViewSize(20); scroller.setMinimumVelocity(0); for (TestData testData : testDataList) { resetAll(); expect(timestampCalculator.getTimestamp()) .andStubAnswer( new IAnswer<Long>() { long counter = 0; @Override public Long answer() throws Throwable { return counter += 100; } }); replayAll(); scroller.setDecayRate(testData.decayRate); scroller.scrollTo(scrollPosition); scroller.fling(testData.velocity); while (scroller.isScrolling()) { scroller.computeScrollOffset(); } assertEquals(testData.toString(), testData.expectedScrollPosition, scroller.scrollPosition); } }