1/*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1.  Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26// Tests for the ScrollAnimatorNone class.
27
28#include "config.h"
29
30#include "platform/scroll/ScrollAnimatorNone.h"
31
32#include "platform/Logging.h"
33#include "platform/geometry/FloatPoint.h"
34#include "platform/geometry/IntRect.h"
35#include "platform/scroll/ScrollAnimator.h"
36#include "platform/scroll/ScrollableArea.h"
37#include <gmock/gmock.h>
38#include <gtest/gtest.h>
39
40using namespace blink;
41
42using testing::AtLeast;
43using testing::Return;
44using testing::_;
45
46class MockScrollableArea : public ScrollableArea {
47public:
48    MockScrollableArea(bool scrollAnimatorEnabled)
49        : m_scrollAnimatorEnabled(scrollAnimatorEnabled) { }
50
51    MOCK_CONST_METHOD0(isActive, bool());
52    MOCK_CONST_METHOD1(scrollSize, int(ScrollbarOrientation));
53    MOCK_METHOD2(invalidateScrollbar, void(Scrollbar*, const IntRect&));
54    MOCK_CONST_METHOD0(isScrollCornerVisible, bool());
55    MOCK_CONST_METHOD0(scrollCornerRect, IntRect());
56    MOCK_METHOD1(setScrollOffset, void(const IntPoint&));
57    MOCK_METHOD2(invalidateScrollbarRect, void(Scrollbar*, const IntRect&));
58    MOCK_METHOD1(invalidateScrollCornerRect, void(const IntRect&));
59    MOCK_METHOD1(setScrollOffsetFromAnimation, void(const IntPoint&));
60    MOCK_CONST_METHOD0(enclosingScrollableArea, ScrollableArea*());
61    MOCK_CONST_METHOD0(minimumScrollPosition, IntPoint());
62    MOCK_CONST_METHOD0(maximumScrollPosition, IntPoint());
63    MOCK_CONST_METHOD1(visibleContentRect, IntRect(IncludeScrollbarsInRect));
64    MOCK_CONST_METHOD0(contentsSize, IntSize());
65    MOCK_CONST_METHOD0(overhangAmount, IntSize());
66    MOCK_CONST_METHOD0(scrollbarsCanBeActive, bool());
67    MOCK_CONST_METHOD0(scrollableAreaBoundingBox, IntRect());
68
69    virtual bool userInputScrollable(ScrollbarOrientation) const OVERRIDE { return true; }
70    virtual bool shouldPlaceVerticalScrollbarOnLeft() const OVERRIDE { return false; }
71    virtual IntPoint scrollPosition() const OVERRIDE { return IntPoint(); }
72    virtual int visibleHeight() const OVERRIDE { return 768; }
73    virtual int visibleWidth() const OVERRIDE { return 1024; }
74    virtual bool scrollAnimatorEnabled() const OVERRIDE { return m_scrollAnimatorEnabled; }
75    virtual int pageStep(ScrollbarOrientation) const OVERRIDE { return 0; }
76
77private:
78    bool m_scrollAnimatorEnabled;
79};
80
81class MockScrollAnimatorNone : public ScrollAnimatorNone {
82public:
83    MockScrollAnimatorNone(ScrollableArea* scrollableArea)
84        : ScrollAnimatorNone(scrollableArea) { }
85
86    float currentX() { return m_currentPosX; }
87    float currentY() { return m_currentPosY; }
88
89    FloatPoint m_fp;
90    int m_count;
91
92    void reset()
93    {
94        stopAnimationTimerIfNeeded();
95        m_currentPosX = 0;
96        m_currentPosY = 0;
97        m_horizontalData.reset();
98        m_verticalData.reset();
99        m_fp = FloatPoint::zero();
100        m_count = 0;
101    }
102
103    virtual void fireUpAnAnimation(FloatPoint fp)
104    {
105        m_fp = fp;
106        m_count++;
107    }
108
109    MOCK_METHOD1(scrollToOffsetWithoutAnimation, void(const FloatPoint&));
110};
111
112TEST(ScrollAnimatorEnabled, Enabled)
113{
114    MockScrollableArea scrollableArea(true);
115    MockScrollAnimatorNone scrollAnimatorNone(&scrollableArea);
116
117    EXPECT_CALL(scrollableArea, scrollSize(_)).Times(AtLeast(1)).WillRepeatedly(Return(1000));
118    EXPECT_CALL(scrollableArea, minimumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint()));
119    EXPECT_CALL(scrollableArea, maximumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint(1000, 1000)));
120    EXPECT_CALL(scrollableArea, setScrollOffset(_)).Times(4);
121
122    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByLine, 100, 1);
123    EXPECT_NE(100, scrollAnimatorNone.currentX());
124    EXPECT_NE(0, scrollAnimatorNone.currentX());
125    EXPECT_EQ(0, scrollAnimatorNone.currentY());
126    scrollAnimatorNone.reset();
127
128    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPage, 100, 1);
129    EXPECT_NE(100, scrollAnimatorNone.currentX());
130    EXPECT_NE(0, scrollAnimatorNone.currentX());
131    EXPECT_EQ(0, scrollAnimatorNone.currentY());
132    scrollAnimatorNone.reset();
133
134    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPixel, 4, 25);
135    EXPECT_NE(100, scrollAnimatorNone.currentX());
136    EXPECT_NE(0, scrollAnimatorNone.currentX());
137    EXPECT_EQ(0, scrollAnimatorNone.currentY());
138    scrollAnimatorNone.reset();
139
140    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPrecisePixel, 4, 25);
141    EXPECT_EQ(100, scrollAnimatorNone.currentX());
142    EXPECT_NE(0, scrollAnimatorNone.currentX());
143    EXPECT_EQ(0, scrollAnimatorNone.currentY());
144    scrollAnimatorNone.reset();
145}
146
147TEST(ScrollAnimatorEnabled, Disabled)
148{
149    MockScrollableArea scrollableArea(false);
150    MockScrollAnimatorNone scrollAnimatorNone(&scrollableArea);
151
152    EXPECT_CALL(scrollableArea, minimumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint()));
153    EXPECT_CALL(scrollableArea, maximumScrollPosition()).Times(AtLeast(1)).WillRepeatedly(Return(IntPoint(1000, 1000)));
154    EXPECT_CALL(scrollableArea, setScrollOffset(_)).Times(4);
155
156    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByLine, 100, 1);
157    EXPECT_EQ(100, scrollAnimatorNone.currentX());
158    EXPECT_EQ(0, scrollAnimatorNone.currentY());
159    scrollAnimatorNone.reset();
160
161    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPage, 100, 1);
162    EXPECT_EQ(100, scrollAnimatorNone.currentX());
163    EXPECT_EQ(0, scrollAnimatorNone.currentY());
164    scrollAnimatorNone.reset();
165
166    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByDocument, 100, 1);
167    EXPECT_EQ(100, scrollAnimatorNone.currentX());
168    EXPECT_EQ(0, scrollAnimatorNone.currentY());
169    scrollAnimatorNone.reset();
170
171    scrollAnimatorNone.scroll(HorizontalScrollbar, ScrollByPixel, 100, 1);
172    EXPECT_EQ(100, scrollAnimatorNone.currentX());
173    EXPECT_EQ(0, scrollAnimatorNone.currentY());
174    scrollAnimatorNone.reset();
175}
176
177class ScrollAnimatorNoneTest : public testing::Test {
178public:
179    struct SavePerAxisData : public ScrollAnimatorNone::PerAxisData {
180        SavePerAxisData(const ScrollAnimatorNone::PerAxisData& data)
181            : ScrollAnimatorNone::PerAxisData(&m_mockScrollAnimatorNone, 0, 768)
182            , m_mockScrollableArea(true)
183            , m_mockScrollAnimatorNone(&m_mockScrollableArea)
184        {
185            this->m_currentVelocity = data.m_currentVelocity;
186            this->m_desiredPosition = data.m_desiredPosition;
187            this->m_desiredVelocity = data.m_desiredVelocity;
188            this->m_startPosition = data.m_startPosition;
189            this->m_startTime = data.m_startTime;
190            this->m_startVelocity = data.m_startVelocity;
191            this->m_animationTime = data.m_animationTime;
192            this->m_lastAnimationTime = data.m_lastAnimationTime;
193            this->m_attackPosition = data.m_attackPosition;
194            this->m_attackTime = data.m_attackTime;
195            this->m_attackCurve = data.m_attackCurve;
196            this->m_releasePosition = data.m_releasePosition;
197            this->m_releaseTime = data.m_releaseTime;
198            this->m_releaseCurve = data.m_releaseCurve;
199        }
200
201        bool operator==(const SavePerAxisData& other) const
202        {
203            return m_currentVelocity == other.m_currentVelocity && m_desiredPosition == other.m_desiredPosition && m_desiredVelocity == other.m_desiredVelocity && m_startPosition == other.m_startPosition && m_startTime == other.m_startTime && m_startVelocity == other.m_startVelocity && m_animationTime == other.m_animationTime && m_lastAnimationTime == other.m_lastAnimationTime && m_attackPosition == other.m_attackPosition && m_attackTime == other.m_attackTime && m_attackCurve == other.m_attackCurve && m_releasePosition == other.m_releasePosition && m_releaseTime == other.m_releaseTime && m_releaseCurve == other.m_releaseCurve;
204        }
205        MockScrollableArea m_mockScrollableArea;
206        MockScrollAnimatorNone m_mockScrollAnimatorNone;
207    };
208
209    ScrollAnimatorNoneTest()
210        : m_mockScrollableArea(true)
211        , m_mockScrollAnimatorNone(&m_mockScrollableArea)
212    {
213    }
214
215    virtual void SetUp()
216    {
217        m_currentPosition = 100;
218        m_data = new ScrollAnimatorNone::PerAxisData(&m_mockScrollAnimatorNone, &m_currentPosition, 768);
219    }
220    virtual void TearDown()
221    {
222        delete m_data;
223    }
224
225    void reset();
226    bool updateDataFromParameters(float step, float multiplier, float scrollableSize, double currentTime, ScrollAnimatorNone::Parameters*);
227    bool animateScroll(double currentTime);
228
229    double attackArea(ScrollAnimatorNone::Curve, double startT, double endT);
230    double releaseArea(ScrollAnimatorNone::Curve, double startT, double endT);
231    double attackCurve(ScrollAnimatorNone::Curve, double deltaT, double curveT, double startPosition, double attackPosition);
232    double releaseCurve(ScrollAnimatorNone::Curve, double deltaT, double curveT, double releasePosition, double desiredPosition);
233    double coastCurve(ScrollAnimatorNone::Curve, double factor);
234
235    void curveTestInner(ScrollAnimatorNone::Curve, double step, double time);
236    void curveTest(ScrollAnimatorNone::Curve);
237
238    void checkDesiredPosition(float expectedPosition);
239    void checkSoftLanding(float expectedPosition);
240
241    static double kTickTime;
242    static double kAnimationTime;
243    static double kStartTime;
244    static double kEndTime;
245    float m_currentPosition;
246    MockScrollableArea m_mockScrollableArea;
247    MockScrollAnimatorNone m_mockScrollAnimatorNone;
248    bool m_scrollingDown;
249    ScrollAnimatorNone::PerAxisData* m_data;
250};
251
252double ScrollAnimatorNoneTest::kTickTime = 1 / 60.0;
253double ScrollAnimatorNoneTest::kAnimationTime = 0.01;
254double ScrollAnimatorNoneTest::kStartTime = 10.0;
255double ScrollAnimatorNoneTest::kEndTime = 20.0;
256
257void ScrollAnimatorNoneTest::reset()
258{
259    m_data->reset();
260    m_scrollingDown = true;
261}
262
263bool ScrollAnimatorNoneTest::updateDataFromParameters(float step, float multiplier, float scrollableSize, double currentTime, ScrollAnimatorNone::Parameters* parameters)
264{
265    if (step * multiplier)
266        m_scrollingDown = (step * multiplier > 0);
267
268    double oldVelocity = m_data->m_currentVelocity;
269    double oldDesiredVelocity = m_data->m_desiredVelocity;
270    double oldTimeLeft = m_data->m_animationTime - (m_data->m_lastAnimationTime - m_data->m_startTime);
271    bool result = m_data->updateDataFromParameters(step, multiplier, scrollableSize, currentTime, parameters);
272    if (m_scrollingDown)
273        EXPECT_LE(oldVelocity, m_data->m_currentVelocity);
274    else
275        EXPECT_GE(oldVelocity, m_data->m_currentVelocity);
276
277    double deltaTime = m_data->m_lastAnimationTime - m_data->m_startTime;
278    double timeLeft = m_data->m_animationTime - deltaTime;
279    double releaseTimeLeft = std::min(timeLeft, m_data->m_releaseTime);
280    double attackTimeLeft = std::max(0., m_data->m_attackTime - deltaTime);
281    double sustainTimeLeft = std::max(0., timeLeft - releaseTimeLeft - attackTimeLeft);
282
283    // If we're getting near the finish, the desired velocity can decrease since the time left gets increased.
284    if (step * multiplier) {
285        double allowedVelocityDecreaseFactor = 0.99 * oldTimeLeft / timeLeft;
286        allowedVelocityDecreaseFactor *= allowedVelocityDecreaseFactor;
287        if (m_scrollingDown)
288            EXPECT_LE(oldDesiredVelocity * allowedVelocityDecreaseFactor, m_data->m_desiredVelocity);
289        else
290            EXPECT_GE(oldDesiredVelocity * allowedVelocityDecreaseFactor, m_data->m_desiredVelocity);
291
292        double startPosition = attackTimeLeft ? m_data->m_attackPosition : m_currentPosition;
293        double expectedReleasePosition = startPosition + sustainTimeLeft * m_data->m_desiredVelocity;
294        EXPECT_NEAR(expectedReleasePosition, m_data->m_releasePosition, result ? .0001 : 1);
295    }
296
297    return result;
298}
299
300bool ScrollAnimatorNoneTest::animateScroll(double currentTime)
301{
302    double oldPosition = *m_data->m_currentPosition;
303    bool testEstimatedMaxVelocity = m_data->m_startTime + m_data->m_animationTime - m_data->m_lastAnimationTime > m_data->m_releaseTime;
304
305    bool result = m_data->animateScroll(currentTime);
306
307    double deltaTime = m_data->m_lastAnimationTime - m_data->m_startTime;
308    double timeLeft = m_data->m_animationTime - deltaTime;
309    double releaseTimeLeft = std::min(timeLeft, m_data->m_releaseTime);
310    double attackTimeLeft = std::max(0., m_data->m_attackTime - deltaTime);
311    double sustainTimeLeft = std::max(0., timeLeft - releaseTimeLeft - attackTimeLeft);
312    double distanceLeft = m_data->m_desiredPosition - *m_data->m_currentPosition;
313
314    if (m_scrollingDown) {
315        EXPECT_LE(0, m_data->m_currentVelocity);
316        EXPECT_LE(oldPosition, *m_data->m_currentPosition);
317    } else {
318        EXPECT_GE(0, m_data->m_currentVelocity);
319        EXPECT_GE(oldPosition, *m_data->m_currentPosition);
320    }
321    EXPECT_GE(fabs(m_data->m_desiredVelocity) * 2, fabs(m_data->m_currentVelocity));
322    if (testEstimatedMaxVelocity)
323        EXPECT_GE(fabs(distanceLeft / sustainTimeLeft) * 1.2, fabs(m_data->m_currentVelocity));
324
325    return result;
326}
327
328double ScrollAnimatorNoneTest::attackArea(ScrollAnimatorNone::Curve curve, double startT, double endT)
329{
330    return ScrollAnimatorNone::PerAxisData::attackArea(curve, startT, endT);
331}
332
333double ScrollAnimatorNoneTest::releaseArea(ScrollAnimatorNone::Curve curve, double startT, double endT)
334{
335    return ScrollAnimatorNone::PerAxisData::releaseArea(curve, startT, endT);
336}
337
338double ScrollAnimatorNoneTest::attackCurve(ScrollAnimatorNone::Curve curve, double deltaT, double curveT, double startPosition, double attackPosition)
339{
340    return ScrollAnimatorNone::PerAxisData::attackCurve(curve, deltaT, curveT, startPosition, attackPosition);
341}
342
343double ScrollAnimatorNoneTest::releaseCurve(ScrollAnimatorNone::Curve curve, double deltaT, double curveT, double releasePosition, double desiredPosition)
344{
345    return ScrollAnimatorNone::PerAxisData::releaseCurve(curve, deltaT, curveT, releasePosition, desiredPosition);
346}
347
348double ScrollAnimatorNoneTest::coastCurve(ScrollAnimatorNone::Curve curve, double factor)
349{
350    return ScrollAnimatorNone::PerAxisData::coastCurve(curve, factor);
351}
352
353void ScrollAnimatorNoneTest::curveTestInner(ScrollAnimatorNone::Curve curve, double step, double time)
354{
355    const double kPosition = 1000;
356
357    double oldPos = 0;
358    double oldVelocity = 0;
359    double accumulate = 0;
360
361    for (double t = step ; t <= time ; t += step) {
362        double newPos = attackCurve(curve, t, time, 0, kPosition);
363        double delta = newPos - oldPos;
364        double velocity = delta / step;
365        double velocityDelta = velocity - oldVelocity;
366
367        accumulate += (oldPos + newPos) / 2 * (step / time);
368        oldPos = newPos;
369        oldVelocity = velocity;
370        if (curve != ScrollAnimatorNone::Bounce) {
371            EXPECT_LE(-.0001, velocityDelta);
372            EXPECT_LT(0, delta);
373        }
374
375        double area = attackArea(curve, 0, t / time) * kPosition;
376        EXPECT_LE(0, area);
377        EXPECT_NEAR(accumulate, area, 1.0);
378    }
379
380    oldPos = 0;
381    oldVelocity *= 2;
382    accumulate = releaseArea(curve, 0, 1) * kPosition;
383    for (double t = step ; t <= time ; t += step) {
384        double newPos = releaseCurve(curve, t, time, 0, kPosition);
385        double delta = newPos - oldPos;
386        double velocity = delta / step;
387        double velocityDelta = velocity - oldVelocity;
388
389        accumulate -= (kPosition - (oldPos + newPos) / 2) * (step / time);
390        oldPos = newPos;
391        oldVelocity = velocity;
392        if (curve != ScrollAnimatorNone::Bounce) {
393            EXPECT_GE(0.01, velocityDelta);
394            EXPECT_LT(0, delta);
395        }
396
397        double area = releaseArea(curve, t / time, 1) * kPosition;
398        EXPECT_LE(0, area);
399        EXPECT_NEAR(accumulate, area, 1.0);
400    }
401}
402
403void ScrollAnimatorNoneTest::curveTest(ScrollAnimatorNone::Curve curve)
404{
405    curveTestInner(curve, 0.01, 0.25);
406    curveTestInner(curve, 0.2, 10);
407    curveTestInner(curve, 0.025, 10);
408    curveTestInner(curve, 0.01, 1);
409    curveTestInner(curve, 0.25, 40);
410}
411
412void ScrollAnimatorNoneTest::checkDesiredPosition(float expectedPosition)
413{
414    EXPECT_EQ(expectedPosition, m_data->m_desiredPosition);
415}
416
417void ScrollAnimatorNoneTest::checkSoftLanding(float expectedPosition)
418{
419    EXPECT_EQ(expectedPosition, m_currentPosition);
420    EXPECT_LE(m_data->m_desiredVelocity / 2, m_data->m_currentVelocity);
421}
422
423TEST_F(ScrollAnimatorNoneTest, CurveMathLinear)
424{
425    curveTest(ScrollAnimatorNone::Linear);
426}
427
428TEST_F(ScrollAnimatorNoneTest, CurveMathQuadratic)
429{
430    curveTest(ScrollAnimatorNone::Quadratic);
431}
432
433TEST_F(ScrollAnimatorNoneTest, CurveMathCubic)
434{
435    curveTest(ScrollAnimatorNone::Cubic);
436}
437
438TEST_F(ScrollAnimatorNoneTest, CurveMathQuartic)
439{
440    curveTest(ScrollAnimatorNone::Quartic);
441}
442
443TEST_F(ScrollAnimatorNoneTest, CurveMathBounce)
444{
445    curveTest(ScrollAnimatorNone::Bounce);
446}
447
448TEST_F(ScrollAnimatorNoneTest, CurveMathCoast)
449{
450    for (double t = .25; t < 1; t += .25) {
451        EXPECT_EQ(t, coastCurve(ScrollAnimatorNone::Linear, t));
452        EXPECT_LT(t, coastCurve(ScrollAnimatorNone::Quadratic, t));
453        EXPECT_LT(t, coastCurve(ScrollAnimatorNone::Cubic, t));
454        EXPECT_LT(coastCurve(ScrollAnimatorNone::Quadratic, t), coastCurve(ScrollAnimatorNone::Cubic, t));
455        EXPECT_LT(t, coastCurve(ScrollAnimatorNone::Quartic, t));
456        EXPECT_LT(coastCurve(ScrollAnimatorNone::Cubic, t), coastCurve(ScrollAnimatorNone::Quartic, t));
457    }
458}
459
460TEST_F(ScrollAnimatorNoneTest, ScrollOnceLinear)
461{
462    ScrollAnimatorNone::Parameters parameters(true, 7 * kTickTime, 0, ScrollAnimatorNone::Linear, 3 * kTickTime, ScrollAnimatorNone::Linear, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
463
464    EXPECT_TRUE(updateDataFromParameters(1, 40, 1000, kStartTime, &parameters));
465    bool result = true;
466    for (double t = kStartTime; result && t < kEndTime; t += kAnimationTime)
467        result = animateScroll(t);
468}
469
470TEST_F(ScrollAnimatorNoneTest, ScrollOnceQuadratic)
471{
472    ScrollAnimatorNone::Parameters parameters(true, 7 * kTickTime, 0, ScrollAnimatorNone::Quadratic, 3 * kTickTime, ScrollAnimatorNone::Quadratic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
473
474    EXPECT_TRUE(updateDataFromParameters(1, 40, 1000, kStartTime, &parameters));
475    bool result = true;
476    for (double t = kStartTime; result && t < kEndTime; t += kAnimationTime)
477        result = animateScroll(t);
478}
479
480TEST_F(ScrollAnimatorNoneTest, ScrollLongQuadratic)
481{
482    ScrollAnimatorNone::Parameters parameters(true, 20 * kTickTime, 0, ScrollAnimatorNone::Quadratic, 3 * kTickTime, ScrollAnimatorNone::Quadratic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
483
484    EXPECT_TRUE(updateDataFromParameters(1, 40, 1000, kStartTime, &parameters));
485    bool result = true;
486    for (double t = kStartTime; result && t < kEndTime; t += kAnimationTime)
487        result = animateScroll(t);
488}
489
490TEST_F(ScrollAnimatorNoneTest, ScrollQuadraticNoSustain)
491{
492    ScrollAnimatorNone::Parameters parameters(true, 8 * kTickTime, 0, ScrollAnimatorNone::Quadratic, 4 * kTickTime, ScrollAnimatorNone::Quadratic, 4 * kTickTime, ScrollAnimatorNone::Linear, 0);
493
494    EXPECT_TRUE(updateDataFromParameters(1, 40, 1000, kStartTime, &parameters));
495    bool result = true;
496    for (double t = kStartTime; result && t < kEndTime; t += kAnimationTime)
497        result = animateScroll(t);
498}
499
500TEST_F(ScrollAnimatorNoneTest, ScrollQuadraticSmoothed)
501{
502    ScrollAnimatorNone::Parameters parameters(true, 8 * kTickTime, 8 * kTickTime, ScrollAnimatorNone::Quadratic, 4 * kTickTime, ScrollAnimatorNone::Quadratic, 4 * kTickTime, ScrollAnimatorNone::Linear, 0);
503
504    EXPECT_TRUE(updateDataFromParameters(1, 40, 1000, kStartTime, &parameters));
505    bool result = true;
506    for (double t = kStartTime; result && t < kEndTime; t += kAnimationTime)
507        result = animateScroll(t);
508}
509
510TEST_F(ScrollAnimatorNoneTest, ScrollOnceCubic)
511{
512    ScrollAnimatorNone::Parameters parameters(true, 7 * kTickTime, 0, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
513
514    EXPECT_TRUE(updateDataFromParameters(1, 40, 1000, kStartTime, &parameters));
515    bool result = true;
516    for (double t = kStartTime; result && t < kEndTime; t += kAnimationTime)
517        result = animateScroll(t);
518}
519
520TEST_F(ScrollAnimatorNoneTest, ScrollOnceQuartic)
521{
522    ScrollAnimatorNone::Parameters parameters(true, 7 * kTickTime, 0, ScrollAnimatorNone::Quartic, 3 * kTickTime, ScrollAnimatorNone::Quartic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
523
524    EXPECT_TRUE(updateDataFromParameters(1, 40, 1000, kStartTime, &parameters));
525    bool result = true;
526    for (double t = kStartTime; result && t < kEndTime; t += kAnimationTime)
527        result = animateScroll(t);
528}
529
530TEST_F(ScrollAnimatorNoneTest, ScrollOnceShort)
531{
532    ScrollAnimatorNone::Parameters parameters(true, 7 * kTickTime, 0, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
533
534    EXPECT_TRUE(updateDataFromParameters(1, 40, 1000, kStartTime, &parameters));
535    bool result = true;
536    for (double t = kStartTime; result && t < kEndTime; t += kTickTime)
537        result = animateScroll(t);
538}
539
540TEST_F(ScrollAnimatorNoneTest, ScrollTwiceQuadratic)
541{
542    ScrollAnimatorNone::Parameters parameters(true, 7 * kTickTime, 0, ScrollAnimatorNone::Quadratic, 3 * kTickTime, ScrollAnimatorNone::Quadratic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
543
544    EXPECT_TRUE(updateDataFromParameters(1, 40, 1000, kStartTime, &parameters));
545    bool result = true;
546    double t;
547    for (t = kStartTime; result && t < kStartTime + 1.5 * kTickTime; t += kAnimationTime)
548        result = animateScroll(t);
549
550    result = result && animateScroll(t);
551    double before = m_currentPosition;
552    result = result && updateDataFromParameters(1, 40, 1000, t, &parameters);
553    result = result && animateScroll(t);
554    double after = m_currentPosition;
555    EXPECT_NEAR(before, after, 10);
556
557    t += kAnimationTime;
558
559    result = result && animateScroll(t);
560    before = m_currentPosition;
561    result = result && updateDataFromParameters(1, 40, 1000, t, &parameters);
562    result = result && animateScroll(t);
563    after = m_currentPosition;
564    EXPECT_NEAR(before, after, 10);
565
566    t += kAnimationTime;
567    for (; result && t < kEndTime; t += kAnimationTime)
568        result = animateScroll(t);
569}
570
571TEST_F(ScrollAnimatorNoneTest, ScrollLotsQuadratic)
572{
573    ScrollAnimatorNone::Parameters parameters(true, 7 * kTickTime, 0, ScrollAnimatorNone::Quadratic, 3 * kTickTime, ScrollAnimatorNone::Quadratic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
574
575    EXPECT_TRUE(updateDataFromParameters(1, 40, 10000, kStartTime, &parameters));
576    bool result = true;
577    double t;
578    for (t = kStartTime; result && t < kStartTime + 1.5 * kTickTime; t += kAnimationTime)
579        result = animateScroll(t);
580
581    for (int i = 0; i < 20; ++i) {
582        t += kAnimationTime;
583        result = result && animateScroll(t);
584        result = result && updateDataFromParameters(3, 40, 10000, t, &parameters);
585    }
586
587    t += kAnimationTime;
588    for (; result && t < kEndTime; t += kAnimationTime)
589        result = result && animateScroll(t);
590}
591
592TEST_F(ScrollAnimatorNoneTest, ScrollLotsQuadraticSmoothed)
593{
594    ScrollAnimatorNone::Parameters parameters(true, 10 * kTickTime, 6 * kTickTime, ScrollAnimatorNone::Quadratic, 3 * kTickTime, ScrollAnimatorNone::Quadratic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
595
596    EXPECT_TRUE(updateDataFromParameters(1, 40, 10000, kStartTime, &parameters));
597    bool result = true;
598    double t;
599    for (t = kStartTime; result && t < kStartTime + 1.5 * kTickTime; t += kAnimationTime)
600        result = animateScroll(t);
601
602    for (int i = 0; i < 20; ++i) {
603        t += kAnimationTime;
604        result = result && animateScroll(t);
605        result = result && updateDataFromParameters(3, 40, 10000, t, &parameters);
606    }
607
608    t += kAnimationTime;
609    for (; result && t < kEndTime; t += kAnimationTime)
610        result = result && animateScroll(t);
611}
612
613TEST_F(ScrollAnimatorNoneTest, ScrollTwiceCubic)
614{
615    ScrollAnimatorNone::Parameters parameters(true, 7 * kTickTime, 0, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
616
617    EXPECT_TRUE(updateDataFromParameters(1, 40, 1000, kStartTime, &parameters));
618    bool result = true;
619    double t;
620    for (t = kStartTime; result && t < kStartTime + 1.5 * kTickTime; t += kAnimationTime)
621        result = animateScroll(t);
622
623    result = result && animateScroll(t);
624    double before = m_currentPosition;
625    result = result && updateDataFromParameters(1, 40, 1000, t, &parameters);
626    result = result && animateScroll(t);
627    double after = m_currentPosition;
628    EXPECT_NEAR(before, after, 10);
629
630    t += kAnimationTime;
631
632    result = result && animateScroll(t);
633    before = m_currentPosition;
634    result = result && updateDataFromParameters(1, 40, 1000, t, &parameters);
635    result = result && animateScroll(t);
636    after = m_currentPosition;
637    EXPECT_NEAR(before, after, 10);
638
639    t += kAnimationTime;
640    for (; result && t < kEndTime; t += kAnimationTime)
641        result = animateScroll(t);
642}
643
644TEST_F(ScrollAnimatorNoneTest, ScrollLotsCubic)
645{
646    ScrollAnimatorNone::Parameters parameters(true, 7 * kTickTime, 0, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
647
648    EXPECT_TRUE(updateDataFromParameters(1, 40, 10000, kStartTime, &parameters));
649    bool result = true;
650    double t;
651    for (t = kStartTime; result && t < kStartTime + 1.5 * kTickTime; t += kAnimationTime)
652        result = animateScroll(t);
653
654    for (int i = 0; i < 20; ++i) {
655        t += kAnimationTime;
656        result = result && animateScroll(t);
657        result = result && updateDataFromParameters(3, 40, 10000, t, &parameters);
658    }
659
660    t += kAnimationTime;
661    for (; result && t < kEndTime; t += kAnimationTime)
662        result = result && animateScroll(t);
663}
664
665TEST_F(ScrollAnimatorNoneTest, ScrollLotsCubicSmoothed)
666{
667    ScrollAnimatorNone::Parameters parameters(true, 10 * kTickTime, 6 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
668
669    EXPECT_TRUE(updateDataFromParameters(1, 40, 10000, kStartTime, &parameters));
670    bool result = true;
671    double t;
672    for (t = kStartTime; result && t < kStartTime + 1.5 * kTickTime; t += kAnimationTime)
673        result = animateScroll(t);
674
675    for (int i = 0; i < 20; ++i) {
676        t += kAnimationTime;
677        result = result && animateScroll(t);
678        result = result && updateDataFromParameters(3, 40, 10000, t, &parameters);
679    }
680
681    t += kAnimationTime;
682    for (; result && t < kEndTime; t += kAnimationTime)
683        result = result && animateScroll(t);
684}
685
686TEST_F(ScrollAnimatorNoneTest, ScrollWheelTrace)
687{
688    ScrollAnimatorNone::Parameters parameters(true, 11 * kTickTime, 0, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
689
690    // Constructed from an actual scroll wheel trace that exhibited a glitch.
691    bool result = updateDataFromParameters(1, 53.33f, 1000, 100.5781f, &parameters);
692    result = animateScroll(100.5933);
693    result = result && animateScroll(100.6085);
694    result = result && updateDataFromParameters(1, 53.33f, 1000, 100.6485f, &parameters);
695    result = result && animateScroll(100.6515);
696    result = result && animateScroll(100.6853);
697    result = result && updateDataFromParameters(1, 53.33f, 1000, 100.6863f, &parameters);
698    result = result && animateScroll(100.7005);
699    result = result && animateScroll(100.7157);
700    result = result && animateScroll(100.7312);
701    result = result && updateDataFromParameters(1, 53.33f, 1000, 100.7379f, &parameters);
702    result = result && animateScroll(100.7464);
703    result = result && animateScroll(100.7617);
704    result = result && animateScroll(100.7775);
705    result = result && updateDataFromParameters(1, 53.33f, 1000, 100.7779f, &parameters);
706    for (double t = 100.7928; result && t < 200; t += 0.015)
707        result = result && animateScroll(t);
708}
709
710TEST_F(ScrollAnimatorNoneTest, ScrollWheelTraceSmoothed)
711{
712    ScrollAnimatorNone::Parameters parameters(true, 11 * kTickTime, 7 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
713
714    // Constructed from an actual scroll wheel trace that exhibited a glitch.
715    bool result = updateDataFromParameters(1, 53.33f, 1000, 100.5781f, &parameters);
716    result = animateScroll(100.5933);
717    result = result && animateScroll(100.6085);
718    result = result && updateDataFromParameters(1, 53.33f, 1000, 100.6485f, &parameters);
719    result = result && animateScroll(100.6515);
720    result = result && animateScroll(100.6853);
721    result = result && updateDataFromParameters(1, 53.33f, 1000, 100.6863f, &parameters);
722    result = result && animateScroll(100.7005);
723    result = result && animateScroll(100.7157);
724    result = result && animateScroll(100.7312);
725    result = result && updateDataFromParameters(1, 53.33f, 1000, 100.7379f, &parameters);
726    result = result && animateScroll(100.7464);
727    result = result && animateScroll(100.7617);
728    result = result && animateScroll(100.7775);
729    result = result && updateDataFromParameters(1, 53.33f, 1000, 100.7779f, &parameters);
730    for (double t = 100.7928; result && t < 200; t += 0.015)
731        result = result && animateScroll(t);
732}
733
734TEST_F(ScrollAnimatorNoneTest, LinuxTrackPadTrace)
735{
736    ScrollAnimatorNone::Parameters parameters(true, 11 * kTickTime, 0, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
737
738    bool result = updateDataFromParameters(1.00, 60.00, 1000, 100.6863, &parameters);
739    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.6897, &parameters);
740    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.7001, &parameters);
741    result = result && animateScroll(100.7015);
742    result = result && animateScroll(100.7169);
743    result = result && updateDataFromParameters(1.00, 40.00, 1000, 100.7179, &parameters);
744    result = result && animateScroll(100.7322);
745    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.7332, &parameters);
746    result = result && animateScroll(100.7491);
747    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.7519, &parameters);
748    result = result && animateScroll(100.7676);
749    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.7698, &parameters);
750    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.7830, &parameters);
751    result = result && animateScroll(100.7834);
752    result = result && animateScroll(100.7997);
753    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.8019, &parameters);
754    result = result && animateScroll(100.8154);
755    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.8241, &parameters);
756    result = result && animateScroll(100.8335);
757    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.8465, &parameters);
758    result = result && animateScroll(100.8513);
759    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.8623, &parameters);
760    for (double t = 100.8674; result && t < 200; t += 0.015)
761        result = result && animateScroll(t);
762}
763
764TEST_F(ScrollAnimatorNoneTest, LinuxTrackPadTraceSmoothed)
765{
766    ScrollAnimatorNone::Parameters parameters(true, 11 * kTickTime, 7 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
767
768    bool result = updateDataFromParameters(1.00, 60.00, 1000, 100.6863, &parameters);
769    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.6897, &parameters);
770    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.7001, &parameters);
771    result = result && animateScroll(100.7015);
772    result = result && animateScroll(100.7169);
773    result = result && updateDataFromParameters(1.00, 40.00, 1000, 100.7179, &parameters);
774    result = result && animateScroll(100.7322);
775    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.7332, &parameters);
776    result = result && animateScroll(100.7491);
777    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.7519, &parameters);
778    result = result && animateScroll(100.7676);
779    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.7698, &parameters);
780    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.7830, &parameters);
781    result = result && animateScroll(100.7834);
782    result = result && animateScroll(100.7997);
783    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.8019, &parameters);
784    result = result && animateScroll(100.8154);
785    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.8241, &parameters);
786    result = result && animateScroll(100.8335);
787    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.8465, &parameters);
788    result = result && animateScroll(100.8513);
789    result = result && updateDataFromParameters(1.00, 20.00, 1000, 100.8623, &parameters);
790    for (double t = 100.8674; result && t < 200; t += 0.015)
791        result = result && animateScroll(t);
792}
793
794TEST_F(ScrollAnimatorNoneTest, ScrollDownToBumper)
795{
796    ScrollAnimatorNone::Parameters parameters(true, 10 * kTickTime, 7 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
797
798    EXPECT_TRUE(updateDataFromParameters(1, 20, 200, kStartTime, &parameters));
799    bool result = true;
800    double t = kStartTime;
801    for (int i = 0; i < 10; ++i) {
802        t += kAnimationTime;
803        result = result && animateScroll(t);
804        updateDataFromParameters(1, 20, 200, t, &parameters);
805    }
806    checkDesiredPosition(200);
807
808    t += kAnimationTime;
809    for (; result && t < kEndTime; t += kAnimationTime)
810        result = result && animateScroll(t);
811    checkSoftLanding(200);
812}
813
814TEST_F(ScrollAnimatorNoneTest, ScrollUpToBumper)
815{
816    ScrollAnimatorNone::Parameters parameters(true, 10 * kTickTime, 7 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
817
818    EXPECT_TRUE(updateDataFromParameters(1, -20, 200, kStartTime, &parameters));
819    bool result = true;
820    double t = kStartTime;
821    for (int i = 0; i < 10; ++i) {
822        t += kAnimationTime;
823        result = result && animateScroll(t);
824        updateDataFromParameters(1, -20, 200, t, &parameters);
825    }
826    checkDesiredPosition(0);
827
828    t += kAnimationTime;
829    for (; result && t < kEndTime; t += kAnimationTime)
830        result = result && animateScroll(t);
831    checkSoftLanding(0);
832}
833
834TEST_F(ScrollAnimatorNoneTest, ScrollUpToBumperCoast)
835{
836    ScrollAnimatorNone::Parameters parameters(true, 11 * kTickTime, 2 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 1);
837
838    m_currentPosition = 40000;
839    EXPECT_TRUE(updateDataFromParameters(1, -10000, 50000, kStartTime, &parameters));
840    bool result = true;
841    double t = kStartTime;
842    for (int i = 0; i < 10; ++i) {
843        t += kAnimationTime;
844        result = result && animateScroll(t);
845        updateDataFromParameters(1, -10000, 50000, t, &parameters);
846    }
847    checkDesiredPosition(0);
848
849    t += kAnimationTime;
850    for (; result && t < kEndTime; t += kAnimationTime)
851        result = result && animateScroll(t);
852    checkSoftLanding(0);
853}
854
855TEST_F(ScrollAnimatorNoneTest, ScrollDownToBumperCoast)
856{
857    ScrollAnimatorNone::Parameters parameters(true, 11 * kTickTime, 2 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 1);
858
859    m_currentPosition = 10000;
860    EXPECT_TRUE(updateDataFromParameters(1, 10000, 50000, kStartTime, &parameters));
861    bool result = true;
862    double t = kStartTime;
863    for (int i = 0; i < 10; ++i) {
864        t += kAnimationTime;
865        result = result && animateScroll(t);
866        updateDataFromParameters(1, 10000, 50000, t, &parameters);
867    }
868    checkDesiredPosition(50000);
869
870    t += kAnimationTime;
871    for (; result && t < kEndTime; t += kAnimationTime)
872        result = result && animateScroll(t);
873    checkSoftLanding(50000);
874}
875
876TEST_F(ScrollAnimatorNoneTest, VaryingInputsEquivalency)
877{
878    ScrollAnimatorNone::Parameters parameters(true, 15 * kTickTime, 10 * kTickTime, ScrollAnimatorNone::Cubic, 5 * kTickTime, ScrollAnimatorNone::Cubic, 5 * kTickTime, ScrollAnimatorNone::Linear, 0);
879
880    reset();
881    EXPECT_TRUE(updateDataFromParameters(1, 300, 50000, kStartTime, &parameters));
882    SavePerAxisData dataSingle(*m_data);
883
884    reset();
885    EXPECT_TRUE(updateDataFromParameters(1, 150, 50000, kStartTime, &parameters));
886    EXPECT_TRUE(updateDataFromParameters(1, 150, 50000, kStartTime, &parameters));
887    SavePerAxisData dataDouble(*m_data);
888
889    reset();
890    EXPECT_TRUE(updateDataFromParameters(1, 100, 50000, kStartTime, &parameters));
891    EXPECT_TRUE(updateDataFromParameters(1, 100, 50000, kStartTime, &parameters));
892    EXPECT_TRUE(updateDataFromParameters(1, 100, 50000, kStartTime, &parameters));
893    SavePerAxisData dataTriple(*m_data);
894
895    reset();
896    EXPECT_TRUE(updateDataFromParameters(1, 50, 50000, kStartTime, &parameters));
897    EXPECT_TRUE(updateDataFromParameters(1, 50, 50000, kStartTime, &parameters));
898    EXPECT_TRUE(updateDataFromParameters(1, 50, 50000, kStartTime, &parameters));
899    EXPECT_TRUE(updateDataFromParameters(1, 50, 50000, kStartTime, &parameters));
900    EXPECT_TRUE(updateDataFromParameters(1, 50, 50000, kStartTime, &parameters));
901    EXPECT_TRUE(updateDataFromParameters(1, 50, 50000, kStartTime, &parameters));
902    SavePerAxisData dataMany(*m_data);
903
904    EXPECT_EQ(dataSingle, dataDouble);
905    EXPECT_EQ(dataSingle, dataTriple);
906    EXPECT_EQ(dataSingle, dataMany);
907}
908
909TEST_F(ScrollAnimatorNoneTest, VaryingInputsEquivalencyCoast)
910{
911    ScrollAnimatorNone::Parameters parameters(true, 15 * kTickTime, 10 * kTickTime, ScrollAnimatorNone::Cubic, 5 * kTickTime, ScrollAnimatorNone::Cubic, 5 * kTickTime, ScrollAnimatorNone::Linear, 1);
912
913    reset();
914    updateDataFromParameters(1, 300, 50000, kStartTime, &parameters);
915    SavePerAxisData dataSingle(*m_data);
916
917    reset();
918    updateDataFromParameters(1, 150, 50000, kStartTime, &parameters);
919    updateDataFromParameters(1, 150, 50000, kStartTime, &parameters);
920    SavePerAxisData dataDouble(*m_data);
921
922    reset();
923    updateDataFromParameters(1, 100, 50000, kStartTime, &parameters);
924    updateDataFromParameters(1, 100, 50000, kStartTime, &parameters);
925    updateDataFromParameters(1, 100, 50000, kStartTime, &parameters);
926    SavePerAxisData dataTriple(*m_data);
927
928    reset();
929    updateDataFromParameters(1, 50, 50000, kStartTime, &parameters);
930    updateDataFromParameters(1, 50, 50000, kStartTime, &parameters);
931    updateDataFromParameters(1, 50, 50000, kStartTime, &parameters);
932    updateDataFromParameters(1, 50, 50000, kStartTime, &parameters);
933    updateDataFromParameters(1, 50, 50000, kStartTime, &parameters);
934    updateDataFromParameters(1, 50, 50000, kStartTime, &parameters);
935    SavePerAxisData dataMany(*m_data);
936
937    EXPECT_EQ(dataSingle, dataDouble);
938    EXPECT_EQ(dataSingle, dataTriple);
939    EXPECT_EQ(dataSingle, dataMany);
940}
941
942TEST_F(ScrollAnimatorNoneTest, VaryingInputsEquivalencyCoastLarge)
943{
944    ScrollAnimatorNone::Parameters parameters(true, 15 * kTickTime, 10 * kTickTime, ScrollAnimatorNone::Cubic, 5 * kTickTime, ScrollAnimatorNone::Cubic, 5 * kTickTime, ScrollAnimatorNone::Linear, 1);
945
946    reset();
947    EXPECT_TRUE(updateDataFromParameters(1, 30000, 50000, kStartTime, &parameters));
948    SavePerAxisData dataSingle(*m_data);
949
950    reset();
951    EXPECT_TRUE(updateDataFromParameters(1, 15000, 50000, kStartTime, &parameters));
952    EXPECT_TRUE(updateDataFromParameters(1, 15000, 50000, kStartTime, &parameters));
953    SavePerAxisData dataDouble(*m_data);
954
955    reset();
956    EXPECT_TRUE(updateDataFromParameters(1, 10000, 50000, kStartTime, &parameters));
957    EXPECT_TRUE(updateDataFromParameters(1, 10000, 50000, kStartTime, &parameters));
958    EXPECT_TRUE(updateDataFromParameters(1, 10000, 50000, kStartTime, &parameters));
959    SavePerAxisData dataTriple(*m_data);
960
961    reset();
962    EXPECT_TRUE(updateDataFromParameters(1, 5000, 50000, kStartTime, &parameters));
963    EXPECT_TRUE(updateDataFromParameters(1, 5000, 50000, kStartTime, &parameters));
964    EXPECT_TRUE(updateDataFromParameters(1, 5000, 50000, kStartTime, &parameters));
965    EXPECT_TRUE(updateDataFromParameters(1, 5000, 50000, kStartTime, &parameters));
966    EXPECT_TRUE(updateDataFromParameters(1, 5000, 50000, kStartTime, &parameters));
967    EXPECT_TRUE(updateDataFromParameters(1, 5000, 50000, kStartTime, &parameters));
968    SavePerAxisData dataMany(*m_data);
969
970    EXPECT_EQ(dataSingle, dataDouble);
971    EXPECT_EQ(dataSingle, dataTriple);
972    EXPECT_EQ(dataSingle, dataMany);
973}
974
975TEST_F(ScrollAnimatorNoneTest, VaryingInputsEquivalencyCoastSteep)
976{
977    ScrollAnimatorNone::Parameters parameters(true, 15 * kTickTime, 10 * kTickTime, ScrollAnimatorNone::Cubic, 5 * kTickTime, ScrollAnimatorNone::Cubic, 5 * kTickTime, ScrollAnimatorNone::Quadratic, 1);
978
979    reset();
980    EXPECT_TRUE(updateDataFromParameters(1, 30000, 50000, kStartTime, &parameters));
981    SavePerAxisData dataSingle(*m_data);
982
983    reset();
984    EXPECT_TRUE(updateDataFromParameters(1, 15000, 50000, kStartTime, &parameters));
985    EXPECT_TRUE(updateDataFromParameters(1, 15000, 50000, kStartTime, &parameters));
986    SavePerAxisData dataDouble(*m_data);
987
988    reset();
989    EXPECT_TRUE(updateDataFromParameters(1, 10000, 50000, kStartTime, &parameters));
990    EXPECT_TRUE(updateDataFromParameters(1, 10000, 50000, kStartTime, &parameters));
991    EXPECT_TRUE(updateDataFromParameters(1, 10000, 50000, kStartTime, &parameters));
992    SavePerAxisData dataTriple(*m_data);
993
994    reset();
995    EXPECT_TRUE(updateDataFromParameters(1, 5000, 50000, kStartTime, &parameters));
996    EXPECT_TRUE(updateDataFromParameters(1, 5000, 50000, kStartTime, &parameters));
997    EXPECT_TRUE(updateDataFromParameters(1, 5000, 50000, kStartTime, &parameters));
998    EXPECT_TRUE(updateDataFromParameters(1, 5000, 50000, kStartTime, &parameters));
999    EXPECT_TRUE(updateDataFromParameters(1, 5000, 50000, kStartTime, &parameters));
1000    EXPECT_TRUE(updateDataFromParameters(1, 5000, 50000, kStartTime, &parameters));
1001    SavePerAxisData dataMany(*m_data);
1002
1003    EXPECT_EQ(dataSingle, dataDouble);
1004    EXPECT_EQ(dataSingle, dataTriple);
1005    EXPECT_EQ(dataSingle, dataMany);
1006}
1007
1008TEST_F(ScrollAnimatorNoneTest, ScrollStopInMiddle)
1009{
1010    ScrollAnimatorNone::Parameters parameters(true, 7 * kTickTime, 0, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
1011
1012    EXPECT_TRUE(updateDataFromParameters(1, 40, 1000, kStartTime, &parameters));
1013    bool result = true;
1014    double t;
1015    for (t = kStartTime; result && t < kStartTime + 1.5 * kTickTime; t += kAnimationTime)
1016        result = animateScroll(t);
1017
1018    result = result && animateScroll(t);
1019    EXPECT_TRUE(result);
1020    double before = m_currentPosition;
1021    result = result && updateDataFromParameters(0, 0, 1000, t, &parameters);
1022    EXPECT_FALSE(result);
1023    result = result && animateScroll(t);
1024    double after = m_currentPosition;
1025    EXPECT_EQ(before, after);
1026    checkDesiredPosition(after);
1027}
1028
1029TEST_F(ScrollAnimatorNoneTest, ReverseInMiddle)
1030{
1031    ScrollAnimatorNone::Parameters parameters(true, 7 * kTickTime, 0, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Cubic, 3 * kTickTime, ScrollAnimatorNone::Linear, 0);
1032
1033    EXPECT_TRUE(updateDataFromParameters(1, 40, 1000, kStartTime, &parameters));
1034    bool result = true;
1035    double t;
1036    for (t = kStartTime; result && t < kStartTime + 1.5 * kTickTime; t += kAnimationTime)
1037        result = animateScroll(t);
1038
1039    result = result && animateScroll(t);
1040    EXPECT_TRUE(result);
1041    double before = m_currentPosition;
1042    result = result && updateDataFromParameters(1, -10, 1000, t, &parameters);
1043    EXPECT_TRUE(result);
1044    result = result && animateScroll(t);
1045    double after = m_currentPosition;
1046    EXPECT_GE(before, after);
1047
1048    t += kAnimationTime;
1049    for (; result && t < kEndTime; t += kAnimationTime)
1050        result = result && animateScroll(t);
1051    EXPECT_GE(before, m_currentPosition);
1052}
1053