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