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