Home | History | Annotate | Download | only in animation
      1 /*
      2  * Copyright (c) 2013, 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 are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "platform/animation/TimingFunction.h"
     33 
     34 #include "wtf/text/WTFString.h"
     35 #include <gmock/gmock.h>
     36 #include <gtest/gtest.h>
     37 #include <sstream>
     38 #include <string>
     39 
     40 // Macro is only used to allow the use of streams.
     41 // Can be removed if a pretty failure message isn't needed.
     42 #define EXPECT_NE_WITH_MESSAGE(a, b) \
     43     EXPECT_NE(*a.second, *b.second) \
     44         << a.first \
     45         << " (" << a.second->toString().latin1().data() << ")" \
     46         << " ==  " \
     47         << b.first \
     48         << " (" << b.second->toString().latin1().data() << ")" \
     49         << "\n";
     50 
     51 namespace WebCore {
     52 
     53 namespace {
     54 
     55 using namespace WebCore;
     56 
     57 class TimingFunctionTest : public ::testing::Test {
     58 public:
     59     void notEqualHelperLoop(Vector<std::pair<std::string, RefPtr<TimingFunction> > >& v)
     60     {
     61         for (size_t i = 0; i < v.size(); ++i) {
     62             for (size_t j = 0; j < v.size(); ++j) {
     63                 if (i == j)
     64                     continue;
     65                 EXPECT_NE_WITH_MESSAGE(v[i], v[j]);
     66             }
     67         }
     68     }
     69 };
     70 
     71 TEST_F(TimingFunctionTest, LinearToString)
     72 {
     73     RefPtr<TimingFunction> linearTiming = LinearTimingFunction::shared();
     74     EXPECT_EQ(linearTiming->toString(), "linear");
     75 }
     76 
     77 TEST_F(TimingFunctionTest, CubicToString)
     78 {
     79     RefPtr<TimingFunction> cubicEaseTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
     80     EXPECT_EQ("ease", cubicEaseTiming->toString());
     81     RefPtr<TimingFunction> cubicEaseInTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
     82     EXPECT_EQ("ease-in", cubicEaseInTiming->toString());
     83     RefPtr<TimingFunction> cubicEaseOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
     84     EXPECT_EQ("ease-out", cubicEaseOutTiming->toString());
     85     RefPtr<TimingFunction> cubicEaseInOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
     86     EXPECT_EQ("ease-in-out", cubicEaseInOutTiming->toString());
     87 
     88     RefPtr<TimingFunction> cubicCustomTiming = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
     89     EXPECT_EQ("cubic-bezier(0.17, 0.67, 1, -1.73)", cubicCustomTiming->toString());
     90 }
     91 
     92 TEST_F(TimingFunctionTest, StepToString)
     93 {
     94     RefPtr<TimingFunction> stepTimingStart = StepsTimingFunction::preset(StepsTimingFunction::Start);
     95     EXPECT_EQ("step-start", stepTimingStart->toString());
     96 
     97     RefPtr<TimingFunction> stepTimingMiddle = StepsTimingFunction::preset(StepsTimingFunction::Middle);
     98     EXPECT_EQ("step-middle", stepTimingMiddle->toString());
     99 
    100     RefPtr<TimingFunction> stepTimingEnd = StepsTimingFunction::preset(StepsTimingFunction::End);
    101     EXPECT_EQ("step-end", stepTimingEnd->toString());
    102 
    103     RefPtr<TimingFunction> stepTimingCustomStart = StepsTimingFunction::create(3, StepsTimingFunction::StepAtStart);
    104     EXPECT_EQ("steps(3, start)", stepTimingCustomStart->toString());
    105 
    106     RefPtr<TimingFunction> stepTimingCustomMiddle = StepsTimingFunction::create(4, StepsTimingFunction::StepAtMiddle);
    107     EXPECT_EQ("steps(4, middle)", stepTimingCustomMiddle->toString());
    108 
    109     RefPtr<TimingFunction> stepTimingCustomEnd = StepsTimingFunction::create(5, StepsTimingFunction::StepAtEnd);
    110     EXPECT_EQ("steps(5, end)", stepTimingCustomEnd->toString());
    111 }
    112 
    113 TEST_F(TimingFunctionTest, BaseOperatorEq)
    114 {
    115     RefPtr<TimingFunction> linearTiming = LinearTimingFunction::shared();
    116     RefPtr<TimingFunction> cubicTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
    117     RefPtr<TimingFunction> cubicTiming2 = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
    118     RefPtr<TimingFunction> stepsTiming1 = StepsTimingFunction::preset(StepsTimingFunction::End);
    119     RefPtr<TimingFunction> stepsTiming2 = StepsTimingFunction::create(5, StepsTimingFunction::StepAtStart);
    120 
    121     Vector<std::pair<std::string, RefPtr<TimingFunction> > > v;
    122     v.append(std::make_pair("linearTiming", linearTiming));
    123     v.append(std::make_pair("cubicTiming1", cubicTiming1));
    124     v.append(std::make_pair("cubicTiming2", cubicTiming2));
    125     v.append(std::make_pair("stepsTiming1", stepsTiming1));
    126     v.append(std::make_pair("stepsTiming2", stepsTiming2));
    127     notEqualHelperLoop(v);
    128 }
    129 
    130 TEST_F(TimingFunctionTest, LinearOperatorEq)
    131 {
    132     RefPtr<TimingFunction> linearTiming1 = LinearTimingFunction::shared();
    133     RefPtr<TimingFunction> linearTiming2 = LinearTimingFunction::shared();
    134     EXPECT_EQ(*linearTiming1, *linearTiming1);
    135     EXPECT_EQ(*linearTiming1, *linearTiming2);
    136 }
    137 
    138 TEST_F(TimingFunctionTest, CubicOperatorEq)
    139 {
    140     RefPtr<TimingFunction> cubicEaseInTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
    141     RefPtr<TimingFunction> cubicEaseInTiming2 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
    142     EXPECT_EQ(*cubicEaseInTiming1, *cubicEaseInTiming1);
    143     EXPECT_EQ(*cubicEaseInTiming1, *cubicEaseInTiming2);
    144 
    145     RefPtr<TimingFunction> cubicEaseOutTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
    146     RefPtr<TimingFunction> cubicEaseOutTiming2 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
    147     EXPECT_EQ(*cubicEaseOutTiming1, *cubicEaseOutTiming1);
    148     EXPECT_EQ(*cubicEaseOutTiming1, *cubicEaseOutTiming2);
    149 
    150     RefPtr<TimingFunction> cubicEaseInOutTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
    151     RefPtr<TimingFunction> cubicEaseInOutTiming2 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
    152     EXPECT_EQ(*cubicEaseInOutTiming1, *cubicEaseInOutTiming1);
    153     EXPECT_EQ(*cubicEaseInOutTiming1, *cubicEaseInOutTiming2);
    154 
    155     RefPtr<TimingFunction> cubicCustomTiming1 = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
    156     RefPtr<TimingFunction> cubicCustomTiming2 = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
    157     EXPECT_EQ(*cubicCustomTiming1, *cubicCustomTiming1);
    158     EXPECT_EQ(*cubicCustomTiming1, *cubicCustomTiming2);
    159 
    160     Vector<std::pair<std::string, RefPtr<TimingFunction> > > v;
    161     v.append(std::make_pair("cubicEaseInTiming1", cubicEaseInTiming1));
    162     v.append(std::make_pair("cubicEaseOutTiming1", cubicEaseOutTiming1));
    163     v.append(std::make_pair("cubicEaseInOutTiming1", cubicEaseInOutTiming1));
    164     v.append(std::make_pair("cubicCustomTiming1", cubicCustomTiming1));
    165     notEqualHelperLoop(v);
    166 }
    167 
    168 TEST_F(TimingFunctionTest, CubicOperatorEqReflectivity)
    169 {
    170     RefPtr<TimingFunction> cubicA = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
    171     RefPtr<TimingFunction> cubicB = CubicBezierTimingFunction::create(0.42, 0.0, 1.0, 1.0);
    172     EXPECT_NE(*cubicA, *cubicB);
    173     EXPECT_NE(*cubicB, *cubicA);
    174 }
    175 
    176 TEST_F(TimingFunctionTest, StepsOperatorEq)
    177 {
    178     RefPtr<TimingFunction> stepsTimingStart1 = StepsTimingFunction::preset(StepsTimingFunction::Start);
    179     RefPtr<TimingFunction> stepsTimingStart2 = StepsTimingFunction::preset(StepsTimingFunction::Start);
    180     EXPECT_EQ(*stepsTimingStart1, *stepsTimingStart1);
    181     EXPECT_EQ(*stepsTimingStart1, *stepsTimingStart2);
    182 
    183     RefPtr<TimingFunction> stepsTimingEnd1 = StepsTimingFunction::preset(StepsTimingFunction::End);
    184     RefPtr<TimingFunction> stepsTimingEnd2 = StepsTimingFunction::preset(StepsTimingFunction::End);
    185     EXPECT_EQ(*stepsTimingEnd1, *stepsTimingEnd1);
    186     EXPECT_EQ(*stepsTimingEnd1, *stepsTimingEnd2);
    187 
    188     RefPtr<TimingFunction> stepsTimingCustom1 = StepsTimingFunction::create(5, StepsTimingFunction::StepAtStart);
    189     RefPtr<TimingFunction> stepsTimingCustom2 = StepsTimingFunction::create(5, StepsTimingFunction::StepAtEnd);
    190     RefPtr<TimingFunction> stepsTimingCustom3 = StepsTimingFunction::create(7, StepsTimingFunction::StepAtStart);
    191     RefPtr<TimingFunction> stepsTimingCustom4 = StepsTimingFunction::create(7, StepsTimingFunction::StepAtEnd);
    192 
    193     EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::StepAtStart), *stepsTimingCustom1);
    194     EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::StepAtEnd), *stepsTimingCustom2);
    195     EXPECT_EQ(*StepsTimingFunction::create(7, StepsTimingFunction::StepAtStart), *stepsTimingCustom3);
    196     EXPECT_EQ(*StepsTimingFunction::create(7, StepsTimingFunction::StepAtEnd), *stepsTimingCustom4);
    197 
    198     Vector<std::pair<std::string, RefPtr<TimingFunction> > > v;
    199     v.append(std::make_pair("stepsTimingStart1", stepsTimingStart1));
    200     v.append(std::make_pair("stepsTimingEnd1", stepsTimingEnd1));
    201     v.append(std::make_pair("stepsTimingCustom1", stepsTimingCustom1));
    202     v.append(std::make_pair("stepsTimingCustom2", stepsTimingCustom2));
    203     v.append(std::make_pair("stepsTimingCustom3", stepsTimingCustom3));
    204     v.append(std::make_pair("stepsTimingCustom4", stepsTimingCustom4));
    205     notEqualHelperLoop(v);
    206 }
    207 
    208 TEST_F(TimingFunctionTest, StepsOperatorEqReflectivity)
    209 {
    210     RefPtr<TimingFunction> stepsA = StepsTimingFunction::preset(StepsTimingFunction::Start);
    211     RefPtr<TimingFunction> stepsB = StepsTimingFunction::create(1, StepsTimingFunction::StepAtStart);
    212     EXPECT_NE(*stepsA, *stepsB);
    213     EXPECT_NE(*stepsB, *stepsA);
    214 }
    215 
    216 TEST_F(TimingFunctionTest, LinearEvaluate)
    217 {
    218     RefPtr<TimingFunction> linearTiming = LinearTimingFunction::shared();
    219     EXPECT_EQ(0.2, linearTiming->evaluate(0.2, 0));
    220     EXPECT_EQ(0.6, linearTiming->evaluate(0.6, 0));
    221     EXPECT_EQ(-0.2, linearTiming->evaluate(-0.2, 0));
    222     EXPECT_EQ(1.6, linearTiming->evaluate(1.6, 0));
    223 }
    224 
    225 TEST_F(TimingFunctionTest, CubicEvaluate)
    226 {
    227     double tolerance = 0.01;
    228     RefPtr<TimingFunction> cubicEaseTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
    229     EXPECT_NEAR(0.418, cubicEaseTiming->evaluate(0.25, tolerance), tolerance);
    230     EXPECT_NEAR(0.805, cubicEaseTiming->evaluate(0.50, tolerance), tolerance);
    231     EXPECT_NEAR(0.960, cubicEaseTiming->evaluate(0.75, tolerance), tolerance);
    232 
    233     RefPtr<TimingFunction> cubicEaseInTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
    234     EXPECT_NEAR(0.093, cubicEaseInTiming->evaluate(0.25, tolerance), tolerance);
    235     EXPECT_NEAR(0.305, cubicEaseInTiming->evaluate(0.50, tolerance), tolerance);
    236     EXPECT_NEAR(0.620, cubicEaseInTiming->evaluate(0.75, tolerance), tolerance);
    237 
    238     RefPtr<TimingFunction> cubicEaseOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
    239     EXPECT_NEAR(0.379, cubicEaseOutTiming->evaluate(0.25, tolerance), tolerance);
    240     EXPECT_NEAR(0.694, cubicEaseOutTiming->evaluate(0.50, tolerance), tolerance);
    241     EXPECT_NEAR(0.906, cubicEaseOutTiming->evaluate(0.75, tolerance), tolerance);
    242 
    243     RefPtr<TimingFunction> cubicEaseInOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
    244     EXPECT_NEAR(0.128, cubicEaseInOutTiming->evaluate(0.25, tolerance), tolerance);
    245     EXPECT_NEAR(0.500, cubicEaseInOutTiming->evaluate(0.50, tolerance), tolerance);
    246     EXPECT_NEAR(0.871, cubicEaseInOutTiming->evaluate(0.75, tolerance), tolerance);
    247 
    248     RefPtr<TimingFunction> cubicCustomTiming = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
    249     EXPECT_NEAR(0.034, cubicCustomTiming->evaluate(0.25, tolerance), tolerance);
    250     EXPECT_NEAR(-0.217, cubicCustomTiming->evaluate(0.50, tolerance), tolerance);
    251     EXPECT_NEAR(-0.335, cubicCustomTiming->evaluate(0.75, tolerance), tolerance);
    252 }
    253 
    254 TEST_F(TimingFunctionTest, StepsEvaluate)
    255 {
    256     RefPtr<TimingFunction> stepsTimingStart = StepsTimingFunction::preset(StepsTimingFunction::Start);
    257     EXPECT_EQ(0.00, stepsTimingStart->evaluate(-1.10, 0));
    258     EXPECT_EQ(0.00, stepsTimingStart->evaluate(-0.10, 0));
    259     EXPECT_EQ(1.00, stepsTimingStart->evaluate(0.00, 0));
    260     EXPECT_EQ(1.00, stepsTimingStart->evaluate(0.20, 0));
    261     EXPECT_EQ(1.00, stepsTimingStart->evaluate(0.60, 0));
    262     EXPECT_EQ(1.00, stepsTimingStart->evaluate(1.00, 0));
    263     EXPECT_EQ(1.00, stepsTimingStart->evaluate(2.00, 0));
    264 
    265     RefPtr<TimingFunction> stepsTimingMiddle = StepsTimingFunction::preset(StepsTimingFunction::Middle);
    266     EXPECT_EQ(0.00, stepsTimingMiddle->evaluate(-2.50, 0));
    267     EXPECT_EQ(0.00, stepsTimingMiddle->evaluate(0.00, 0));
    268     EXPECT_EQ(0.00, stepsTimingMiddle->evaluate(0.49, 0));
    269     EXPECT_EQ(1.00, stepsTimingMiddle->evaluate(0.50, 0));
    270     EXPECT_EQ(1.00, stepsTimingMiddle->evaluate(1.00, 0));
    271     EXPECT_EQ(1.00, stepsTimingMiddle->evaluate(2.50, 0));
    272 
    273     RefPtr<TimingFunction> stepsTimingEnd = StepsTimingFunction::preset(StepsTimingFunction::End);
    274     EXPECT_EQ(0.00, stepsTimingEnd->evaluate(-2.00, 0));
    275     EXPECT_EQ(0.00, stepsTimingEnd->evaluate(0.00, 0));
    276     EXPECT_EQ(0.00, stepsTimingEnd->evaluate(0.20, 0));
    277     EXPECT_EQ(0.00, stepsTimingEnd->evaluate(0.60, 0));
    278     EXPECT_EQ(1.00, stepsTimingEnd->evaluate(1.00, 0));
    279     EXPECT_EQ(1.00, stepsTimingEnd->evaluate(2.00, 0));
    280 
    281     RefPtr<TimingFunction> stepsTimingCustomStart = StepsTimingFunction::create(4, StepsTimingFunction::StepAtStart);
    282     EXPECT_EQ(0.00, stepsTimingCustomStart->evaluate(-0.50, 0));
    283     EXPECT_EQ(0.25, stepsTimingCustomStart->evaluate(0.00, 0));
    284     EXPECT_EQ(0.25, stepsTimingCustomStart->evaluate(0.24, 0));
    285     EXPECT_EQ(0.50, stepsTimingCustomStart->evaluate(0.25, 0));
    286     EXPECT_EQ(0.50, stepsTimingCustomStart->evaluate(0.49, 0));
    287     EXPECT_EQ(0.75, stepsTimingCustomStart->evaluate(0.50, 0));
    288     EXPECT_EQ(0.75, stepsTimingCustomStart->evaluate(0.74, 0));
    289     EXPECT_EQ(1.00, stepsTimingCustomStart->evaluate(0.75, 0));
    290     EXPECT_EQ(1.00, stepsTimingCustomStart->evaluate(1.00, 0));
    291     EXPECT_EQ(1.00, stepsTimingCustomStart->evaluate(1.50, 0));
    292 
    293     RefPtr<TimingFunction> stepsTimingCustomMiddle = StepsTimingFunction::create(4, StepsTimingFunction::StepAtMiddle);
    294     EXPECT_EQ(0.00, stepsTimingCustomMiddle->evaluate(-2.00, 0));
    295     EXPECT_EQ(0.00, stepsTimingCustomMiddle->evaluate(0.00, 0));
    296     EXPECT_EQ(0.00, stepsTimingCustomMiddle->evaluate(0.12, 0));
    297     EXPECT_EQ(0.25, stepsTimingCustomMiddle->evaluate(0.13, 0));
    298     EXPECT_EQ(0.25, stepsTimingCustomMiddle->evaluate(0.37, 0));
    299     EXPECT_EQ(0.50, stepsTimingCustomMiddle->evaluate(0.38, 0));
    300     EXPECT_EQ(0.50, stepsTimingCustomMiddle->evaluate(0.62, 0));
    301     EXPECT_EQ(0.75, stepsTimingCustomMiddle->evaluate(0.63, 0));
    302     EXPECT_EQ(0.75, stepsTimingCustomMiddle->evaluate(0.87, 0));
    303     EXPECT_EQ(1.00, stepsTimingCustomMiddle->evaluate(0.88, 0));
    304     EXPECT_EQ(1.00, stepsTimingCustomMiddle->evaluate(1.00, 0));
    305     EXPECT_EQ(1.00, stepsTimingCustomMiddle->evaluate(3.00, 0));
    306 
    307     RefPtr<TimingFunction> stepsTimingCustomEnd = StepsTimingFunction::create(4, StepsTimingFunction::StepAtEnd);
    308     EXPECT_EQ(0.00, stepsTimingCustomEnd->evaluate(-2.00, 0));
    309     EXPECT_EQ(0.00, stepsTimingCustomEnd->evaluate(0.00, 0));
    310     EXPECT_EQ(0.00, stepsTimingCustomEnd->evaluate(0.24, 0));
    311     EXPECT_EQ(0.25, stepsTimingCustomEnd->evaluate(0.25, 0));
    312     EXPECT_EQ(0.25, stepsTimingCustomEnd->evaluate(0.49, 0));
    313     EXPECT_EQ(0.50, stepsTimingCustomEnd->evaluate(0.50, 0));
    314     EXPECT_EQ(0.50, stepsTimingCustomEnd->evaluate(0.74, 0));
    315     EXPECT_EQ(0.75, stepsTimingCustomEnd->evaluate(0.75, 0));
    316     EXPECT_EQ(0.75, stepsTimingCustomEnd->evaluate(0.99, 0));
    317     EXPECT_EQ(1.00, stepsTimingCustomEnd->evaluate(1.00, 0));
    318     EXPECT_EQ(1.00, stepsTimingCustomEnd->evaluate(2.00, 0));
    319 }
    320 
    321 } // namespace
    322 
    323 } // namespace WebCore
    324