2 * Copyright (c) 2013, Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
32 #include "platform/animation/TimingFunction.h"
34 #include "wtf/text/WTFString.h"
35 #include <gmock/gmock.h>
36 #include <gtest/gtest.h>
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) \
45 << " (" << a.second->toString().latin1().data() << ")" \
48 << " (" << b.second->toString().latin1().data() << ")" \
55 class TimingFunctionTest
: public ::testing::Test
{
57 void notEqualHelperLoop(Vector
<std::pair
<std::string
, RefPtr
<TimingFunction
>>>& v
)
59 for (size_t i
= 0; i
< v
.size(); ++i
) {
60 for (size_t j
= 0; j
< v
.size(); ++j
) {
63 EXPECT_NE_WITH_MESSAGE(v
[i
], v
[j
]);
69 TEST_F(TimingFunctionTest
, LinearToString
)
71 RefPtr
<TimingFunction
> linearTiming
= LinearTimingFunction::shared();
72 EXPECT_EQ(linearTiming
->toString(), "linear");
75 TEST_F(TimingFunctionTest
, CubicToString
)
77 RefPtr
<TimingFunction
> cubicEaseTiming
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease
);
78 EXPECT_EQ("ease", cubicEaseTiming
->toString());
79 RefPtr
<TimingFunction
> cubicEaseInTiming
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn
);
80 EXPECT_EQ("ease-in", cubicEaseInTiming
->toString());
81 RefPtr
<TimingFunction
> cubicEaseOutTiming
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut
);
82 EXPECT_EQ("ease-out", cubicEaseOutTiming
->toString());
83 RefPtr
<TimingFunction
> cubicEaseInOutTiming
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut
);
84 EXPECT_EQ("ease-in-out", cubicEaseInOutTiming
->toString());
86 RefPtr
<TimingFunction
> cubicCustomTiming
= CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
87 EXPECT_EQ("cubic-bezier(0.17, 0.67, 1, -1.73)", cubicCustomTiming
->toString());
90 TEST_F(TimingFunctionTest
, StepToString
)
92 RefPtr
<TimingFunction
> stepTimingStart
= StepsTimingFunction::preset(StepsTimingFunction::Start
);
93 EXPECT_EQ("step-start", stepTimingStart
->toString());
95 RefPtr
<TimingFunction
> stepTimingMiddle
= StepsTimingFunction::preset(StepsTimingFunction::Middle
);
96 EXPECT_EQ("step-middle", stepTimingMiddle
->toString());
98 RefPtr
<TimingFunction
> stepTimingEnd
= StepsTimingFunction::preset(StepsTimingFunction::End
);
99 EXPECT_EQ("step-end", stepTimingEnd
->toString());
101 RefPtr
<TimingFunction
> stepTimingCustomStart
= StepsTimingFunction::create(3, StepsTimingFunction::Start
);
102 EXPECT_EQ("steps(3, start)", stepTimingCustomStart
->toString());
104 RefPtr
<TimingFunction
> stepTimingCustomMiddle
= StepsTimingFunction::create(4, StepsTimingFunction::Middle
);
105 EXPECT_EQ("steps(4, middle)", stepTimingCustomMiddle
->toString());
107 RefPtr
<TimingFunction
> stepTimingCustomEnd
= StepsTimingFunction::create(5, StepsTimingFunction::End
);
108 EXPECT_EQ("steps(5, end)", stepTimingCustomEnd
->toString());
111 TEST_F(TimingFunctionTest
, BaseOperatorEq
)
113 RefPtr
<TimingFunction
> linearTiming
= LinearTimingFunction::shared();
114 RefPtr
<TimingFunction
> cubicTiming1
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn
);
115 RefPtr
<TimingFunction
> cubicTiming2
= CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
116 RefPtr
<TimingFunction
> stepsTiming1
= StepsTimingFunction::preset(StepsTimingFunction::End
);
117 RefPtr
<TimingFunction
> stepsTiming2
= StepsTimingFunction::create(5, StepsTimingFunction::Start
);
119 Vector
<std::pair
<std::string
, RefPtr
<TimingFunction
>>> v
;
120 v
.append(std::make_pair("linearTiming", linearTiming
));
121 v
.append(std::make_pair("cubicTiming1", cubicTiming1
));
122 v
.append(std::make_pair("cubicTiming2", cubicTiming2
));
123 v
.append(std::make_pair("stepsTiming1", stepsTiming1
));
124 v
.append(std::make_pair("stepsTiming2", stepsTiming2
));
125 notEqualHelperLoop(v
);
128 TEST_F(TimingFunctionTest
, LinearOperatorEq
)
130 RefPtr
<TimingFunction
> linearTiming1
= LinearTimingFunction::shared();
131 RefPtr
<TimingFunction
> linearTiming2
= LinearTimingFunction::shared();
132 EXPECT_EQ(*linearTiming1
, *linearTiming1
);
133 EXPECT_EQ(*linearTiming1
, *linearTiming2
);
136 TEST_F(TimingFunctionTest
, CubicOperatorEq
)
138 RefPtr
<TimingFunction
> cubicEaseInTiming1
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn
);
139 RefPtr
<TimingFunction
> cubicEaseInTiming2
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn
);
140 EXPECT_EQ(*cubicEaseInTiming1
, *cubicEaseInTiming1
);
141 EXPECT_EQ(*cubicEaseInTiming1
, *cubicEaseInTiming2
);
143 RefPtr
<TimingFunction
> cubicEaseOutTiming1
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut
);
144 RefPtr
<TimingFunction
> cubicEaseOutTiming2
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut
);
145 EXPECT_EQ(*cubicEaseOutTiming1
, *cubicEaseOutTiming1
);
146 EXPECT_EQ(*cubicEaseOutTiming1
, *cubicEaseOutTiming2
);
148 RefPtr
<TimingFunction
> cubicEaseInOutTiming1
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut
);
149 RefPtr
<TimingFunction
> cubicEaseInOutTiming2
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut
);
150 EXPECT_EQ(*cubicEaseInOutTiming1
, *cubicEaseInOutTiming1
);
151 EXPECT_EQ(*cubicEaseInOutTiming1
, *cubicEaseInOutTiming2
);
153 RefPtr
<TimingFunction
> cubicCustomTiming1
= CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
154 RefPtr
<TimingFunction
> cubicCustomTiming2
= CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
155 EXPECT_EQ(*cubicCustomTiming1
, *cubicCustomTiming1
);
156 EXPECT_EQ(*cubicCustomTiming1
, *cubicCustomTiming2
);
158 Vector
<std::pair
<std::string
, RefPtr
<TimingFunction
>>> v
;
159 v
.append(std::make_pair("cubicEaseInTiming1", cubicEaseInTiming1
));
160 v
.append(std::make_pair("cubicEaseOutTiming1", cubicEaseOutTiming1
));
161 v
.append(std::make_pair("cubicEaseInOutTiming1", cubicEaseInOutTiming1
));
162 v
.append(std::make_pair("cubicCustomTiming1", cubicCustomTiming1
));
163 notEqualHelperLoop(v
);
166 TEST_F(TimingFunctionTest
, CubicOperatorEqReflectivity
)
168 RefPtr
<TimingFunction
> cubicA
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn
);
169 RefPtr
<TimingFunction
> cubicB
= CubicBezierTimingFunction::create(0.42, 0.0, 1.0, 1.0);
170 EXPECT_NE(*cubicA
, *cubicB
);
171 EXPECT_NE(*cubicB
, *cubicA
);
174 TEST_F(TimingFunctionTest
, StepsOperatorEq
)
176 RefPtr
<TimingFunction
> stepsTimingStart1
= StepsTimingFunction::preset(StepsTimingFunction::Start
);
177 RefPtr
<TimingFunction
> stepsTimingStart2
= StepsTimingFunction::preset(StepsTimingFunction::Start
);
178 EXPECT_EQ(*stepsTimingStart1
, *stepsTimingStart1
);
179 EXPECT_EQ(*stepsTimingStart1
, *stepsTimingStart2
);
181 RefPtr
<TimingFunction
> stepsTimingEnd1
= StepsTimingFunction::preset(StepsTimingFunction::End
);
182 RefPtr
<TimingFunction
> stepsTimingEnd2
= StepsTimingFunction::preset(StepsTimingFunction::End
);
183 EXPECT_EQ(*stepsTimingEnd1
, *stepsTimingEnd1
);
184 EXPECT_EQ(*stepsTimingEnd1
, *stepsTimingEnd2
);
186 RefPtr
<TimingFunction
> stepsTimingCustom1
= StepsTimingFunction::create(5, StepsTimingFunction::Start
);
187 RefPtr
<TimingFunction
> stepsTimingCustom2
= StepsTimingFunction::create(5, StepsTimingFunction::End
);
188 RefPtr
<TimingFunction
> stepsTimingCustom3
= StepsTimingFunction::create(7, StepsTimingFunction::Start
);
189 RefPtr
<TimingFunction
> stepsTimingCustom4
= StepsTimingFunction::create(7, StepsTimingFunction::End
);
191 EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::Start
), *stepsTimingCustom1
);
192 EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::End
), *stepsTimingCustom2
);
193 EXPECT_EQ(*StepsTimingFunction::create(7, StepsTimingFunction::Start
), *stepsTimingCustom3
);
194 EXPECT_EQ(*StepsTimingFunction::create(7, StepsTimingFunction::End
), *stepsTimingCustom4
);
196 Vector
<std::pair
<std::string
, RefPtr
<TimingFunction
>>> v
;
197 v
.append(std::make_pair("stepsTimingStart1", stepsTimingStart1
));
198 v
.append(std::make_pair("stepsTimingEnd1", stepsTimingEnd1
));
199 v
.append(std::make_pair("stepsTimingCustom1", stepsTimingCustom1
));
200 v
.append(std::make_pair("stepsTimingCustom2", stepsTimingCustom2
));
201 v
.append(std::make_pair("stepsTimingCustom3", stepsTimingCustom3
));
202 v
.append(std::make_pair("stepsTimingCustom4", stepsTimingCustom4
));
203 notEqualHelperLoop(v
);
206 TEST_F(TimingFunctionTest
, StepsOperatorEqPreset
)
208 RefPtr
<TimingFunction
> stepsA
= StepsTimingFunction::preset(StepsTimingFunction::Start
);
209 RefPtr
<TimingFunction
> stepsB
= StepsTimingFunction::create(1, StepsTimingFunction::Start
);
210 EXPECT_EQ(*stepsA
, *stepsB
);
211 EXPECT_EQ(*stepsB
, *stepsA
);
214 TEST_F(TimingFunctionTest
, LinearEvaluate
)
216 RefPtr
<TimingFunction
> linearTiming
= LinearTimingFunction::shared();
217 EXPECT_EQ(0.2, linearTiming
->evaluate(0.2, 0));
218 EXPECT_EQ(0.6, linearTiming
->evaluate(0.6, 0));
219 EXPECT_EQ(-0.2, linearTiming
->evaluate(-0.2, 0));
220 EXPECT_EQ(1.6, linearTiming
->evaluate(1.6, 0));
223 TEST_F(TimingFunctionTest
, LinearRange
)
227 RefPtr
<TimingFunction
> linearTiming
= LinearTimingFunction::shared();
228 linearTiming
->range(&start
, &end
);
229 EXPECT_NEAR(0, start
, 0.01);
230 EXPECT_NEAR(1, end
, 0.01);
233 linearTiming
->range(&start
, &end
);
234 EXPECT_NEAR(-1, start
, 0.01);
235 EXPECT_NEAR(10, end
, 0.01);
238 TEST_F(TimingFunctionTest
, StepRange
)
242 RefPtr
<TimingFunction
> steps
= StepsTimingFunction::preset(StepsTimingFunction::Start
);
243 steps
->range(&start
, &end
);
244 EXPECT_NEAR(0, start
, 0.01);
245 EXPECT_NEAR(1, end
, 0.01);
249 steps
->range(&start
, &end
);
250 EXPECT_NEAR(0, start
, 0.01);
251 EXPECT_NEAR(1, end
, 0.01);
254 TEST_F(TimingFunctionTest
, CubicRange
)
259 RefPtr
<TimingFunction
> cubicEaseTiming
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease
);
262 cubicEaseTiming
->range(&start
, &end
);
263 EXPECT_NEAR(0, start
, 0.01);
264 EXPECT_NEAR(1, end
, 0.01);
267 cubicEaseTiming
->range(&start
, &end
);
268 EXPECT_NEAR(-0.4, start
, 0.01);
269 EXPECT_NEAR(1, end
, 0.01);
271 RefPtr
<TimingFunction
> cubicEaseInTiming
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn
);
274 cubicEaseInTiming
->range(&start
, &end
);
275 EXPECT_NEAR(0, start
, 0.01);
276 EXPECT_NEAR(1, end
, 0.01);
279 cubicEaseInTiming
->range(&start
, &end
);
280 EXPECT_NEAR(0.0, start
, 0.01);
281 EXPECT_NEAR(16.51, end
, 0.01);
283 RefPtr
<TimingFunction
> cubicEaseOutTiming
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut
);
286 cubicEaseOutTiming
->range(&start
, &end
);
287 EXPECT_NEAR(0, start
, 0.01);
288 EXPECT_NEAR(1, end
, 0.01);
291 cubicEaseOutTiming
->range(&start
, &end
);
292 EXPECT_NEAR(-1.72, start
, 0.01);
293 EXPECT_NEAR(1.0, end
, 0.01);
295 RefPtr
<TimingFunction
> cubicEaseInOutTiming
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut
);
298 cubicEaseInOutTiming
->range(&start
, &end
);
299 EXPECT_NEAR(0, start
, 0.01);
300 EXPECT_NEAR(1, end
, 0.01);
303 cubicEaseInOutTiming
->range(&start
, &end
);
304 EXPECT_NEAR(0.0, start
, 0.01);
305 EXPECT_NEAR(1.0, end
, 0.01);
307 RefPtr
<TimingFunction
> cubicCustomTiming
= CubicBezierTimingFunction::create(0.17, 0.67, 1.0, -1.73);
310 cubicCustomTiming
->range(&start
, &end
);
311 EXPECT_NEAR(-0.33, start
, 0.01);
312 EXPECT_NEAR(1.0, end
, 0.01);
316 cubicCustomTiming
->range(&start
, &end
);
317 EXPECT_NEAR(-3.94, start
, 0.01);
318 EXPECT_NEAR(4.578, end
, 0.01);
321 TEST_F(TimingFunctionTest
, CubicEvaluate
)
323 double tolerance
= 0.01;
324 RefPtr
<TimingFunction
> cubicEaseTiming
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease
);
325 EXPECT_NEAR(0.418, cubicEaseTiming
->evaluate(0.25, tolerance
), tolerance
);
326 EXPECT_NEAR(0.805, cubicEaseTiming
->evaluate(0.50, tolerance
), tolerance
);
327 EXPECT_NEAR(0.960, cubicEaseTiming
->evaluate(0.75, tolerance
), tolerance
);
329 RefPtr
<TimingFunction
> cubicEaseInTiming
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn
);
330 EXPECT_NEAR(0.093, cubicEaseInTiming
->evaluate(0.25, tolerance
), tolerance
);
331 EXPECT_NEAR(0.305, cubicEaseInTiming
->evaluate(0.50, tolerance
), tolerance
);
332 EXPECT_NEAR(0.620, cubicEaseInTiming
->evaluate(0.75, tolerance
), tolerance
);
334 RefPtr
<TimingFunction
> cubicEaseOutTiming
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut
);
335 EXPECT_NEAR(0.379, cubicEaseOutTiming
->evaluate(0.25, tolerance
), tolerance
);
336 EXPECT_NEAR(0.694, cubicEaseOutTiming
->evaluate(0.50, tolerance
), tolerance
);
337 EXPECT_NEAR(0.906, cubicEaseOutTiming
->evaluate(0.75, tolerance
), tolerance
);
339 RefPtr
<TimingFunction
> cubicEaseInOutTiming
= CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut
);
340 EXPECT_NEAR(0.128, cubicEaseInOutTiming
->evaluate(0.25, tolerance
), tolerance
);
341 EXPECT_NEAR(0.500, cubicEaseInOutTiming
->evaluate(0.50, tolerance
), tolerance
);
342 EXPECT_NEAR(0.871, cubicEaseInOutTiming
->evaluate(0.75, tolerance
), tolerance
);
344 RefPtr
<TimingFunction
> cubicCustomTiming
= CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
345 EXPECT_NEAR(0.034, cubicCustomTiming
->evaluate(0.25, tolerance
), tolerance
);
346 EXPECT_NEAR(-0.217, cubicCustomTiming
->evaluate(0.50, tolerance
), tolerance
);
347 EXPECT_NEAR(-0.335, cubicCustomTiming
->evaluate(0.75, tolerance
), tolerance
);
350 TEST_F(TimingFunctionTest
, StepsEvaluate
)
352 RefPtr
<TimingFunction
> stepsTimingStart
= StepsTimingFunction::preset(StepsTimingFunction::Start
);
353 EXPECT_EQ(0.00, stepsTimingStart
->evaluate(-1.10, 0));
354 EXPECT_EQ(0.00, stepsTimingStart
->evaluate(-0.10, 0));
355 EXPECT_EQ(1.00, stepsTimingStart
->evaluate(0.00, 0));
356 EXPECT_EQ(1.00, stepsTimingStart
->evaluate(0.20, 0));
357 EXPECT_EQ(1.00, stepsTimingStart
->evaluate(0.60, 0));
358 EXPECT_EQ(1.00, stepsTimingStart
->evaluate(1.00, 0));
359 EXPECT_EQ(1.00, stepsTimingStart
->evaluate(2.00, 0));
361 RefPtr
<TimingFunction
> stepsTimingMiddle
= StepsTimingFunction::preset(StepsTimingFunction::Middle
);
362 EXPECT_EQ(0.00, stepsTimingMiddle
->evaluate(-2.50, 0));
363 EXPECT_EQ(0.00, stepsTimingMiddle
->evaluate(0.00, 0));
364 EXPECT_EQ(0.00, stepsTimingMiddle
->evaluate(0.49, 0));
365 EXPECT_EQ(1.00, stepsTimingMiddle
->evaluate(0.50, 0));
366 EXPECT_EQ(1.00, stepsTimingMiddle
->evaluate(1.00, 0));
367 EXPECT_EQ(1.00, stepsTimingMiddle
->evaluate(2.50, 0));
369 RefPtr
<TimingFunction
> stepsTimingEnd
= StepsTimingFunction::preset(StepsTimingFunction::End
);
370 EXPECT_EQ(0.00, stepsTimingEnd
->evaluate(-2.00, 0));
371 EXPECT_EQ(0.00, stepsTimingEnd
->evaluate(0.00, 0));
372 EXPECT_EQ(0.00, stepsTimingEnd
->evaluate(0.20, 0));
373 EXPECT_EQ(0.00, stepsTimingEnd
->evaluate(0.60, 0));
374 EXPECT_EQ(1.00, stepsTimingEnd
->evaluate(1.00, 0));
375 EXPECT_EQ(1.00, stepsTimingEnd
->evaluate(2.00, 0));
377 RefPtr
<TimingFunction
> stepsTimingCustomStart
= StepsTimingFunction::create(4, StepsTimingFunction::Start
);
378 EXPECT_EQ(0.00, stepsTimingCustomStart
->evaluate(-0.50, 0));
379 EXPECT_EQ(0.25, stepsTimingCustomStart
->evaluate(0.00, 0));
380 EXPECT_EQ(0.25, stepsTimingCustomStart
->evaluate(0.24, 0));
381 EXPECT_EQ(0.50, stepsTimingCustomStart
->evaluate(0.25, 0));
382 EXPECT_EQ(0.50, stepsTimingCustomStart
->evaluate(0.49, 0));
383 EXPECT_EQ(0.75, stepsTimingCustomStart
->evaluate(0.50, 0));
384 EXPECT_EQ(0.75, stepsTimingCustomStart
->evaluate(0.74, 0));
385 EXPECT_EQ(1.00, stepsTimingCustomStart
->evaluate(0.75, 0));
386 EXPECT_EQ(1.00, stepsTimingCustomStart
->evaluate(1.00, 0));
387 EXPECT_EQ(1.00, stepsTimingCustomStart
->evaluate(1.50, 0));
389 RefPtr
<TimingFunction
> stepsTimingCustomMiddle
= StepsTimingFunction::create(4, StepsTimingFunction::Middle
);
390 EXPECT_EQ(0.00, stepsTimingCustomMiddle
->evaluate(-2.00, 0));
391 EXPECT_EQ(0.00, stepsTimingCustomMiddle
->evaluate(0.00, 0));
392 EXPECT_EQ(0.00, stepsTimingCustomMiddle
->evaluate(0.12, 0));
393 EXPECT_EQ(0.25, stepsTimingCustomMiddle
->evaluate(0.13, 0));
394 EXPECT_EQ(0.25, stepsTimingCustomMiddle
->evaluate(0.37, 0));
395 EXPECT_EQ(0.50, stepsTimingCustomMiddle
->evaluate(0.38, 0));
396 EXPECT_EQ(0.50, stepsTimingCustomMiddle
->evaluate(0.62, 0));
397 EXPECT_EQ(0.75, stepsTimingCustomMiddle
->evaluate(0.63, 0));
398 EXPECT_EQ(0.75, stepsTimingCustomMiddle
->evaluate(0.87, 0));
399 EXPECT_EQ(1.00, stepsTimingCustomMiddle
->evaluate(0.88, 0));
400 EXPECT_EQ(1.00, stepsTimingCustomMiddle
->evaluate(1.00, 0));
401 EXPECT_EQ(1.00, stepsTimingCustomMiddle
->evaluate(3.00, 0));
403 RefPtr
<TimingFunction
> stepsTimingCustomEnd
= StepsTimingFunction::create(4, StepsTimingFunction::End
);
404 EXPECT_EQ(0.00, stepsTimingCustomEnd
->evaluate(-2.00, 0));
405 EXPECT_EQ(0.00, stepsTimingCustomEnd
->evaluate(0.00, 0));
406 EXPECT_EQ(0.00, stepsTimingCustomEnd
->evaluate(0.24, 0));
407 EXPECT_EQ(0.25, stepsTimingCustomEnd
->evaluate(0.25, 0));
408 EXPECT_EQ(0.25, stepsTimingCustomEnd
->evaluate(0.49, 0));
409 EXPECT_EQ(0.50, stepsTimingCustomEnd
->evaluate(0.50, 0));
410 EXPECT_EQ(0.50, stepsTimingCustomEnd
->evaluate(0.74, 0));
411 EXPECT_EQ(0.75, stepsTimingCustomEnd
->evaluate(0.75, 0));
412 EXPECT_EQ(0.75, stepsTimingCustomEnd
->evaluate(0.99, 0));
413 EXPECT_EQ(1.00, stepsTimingCustomEnd
->evaluate(1.00, 0));
414 EXPECT_EQ(1.00, stepsTimingCustomEnd
->evaluate(2.00, 0));
417 static void checkSteps(int steps
, StepsTimingFunction::StepAtPosition position
, double expectedSplit
)
419 Vector
<TimingFunction::PartitionRegion
> regions
= Vector
<TimingFunction::PartitionRegion
>();
420 RefPtr
<TimingFunction
> stepsFunction
= StepsTimingFunction::create(steps
, position
);
421 stepsFunction
->partition(regions
);
423 EXPECT_EQ(regions
.size(), 2ul);
424 EXPECT_EQ(regions
.at(0).half
, TimingFunction::RangeHalf::Lower
);
425 EXPECT_EQ(regions
.at(1).half
, TimingFunction::RangeHalf::Upper
);
427 EXPECT_EQ(0, regions
.at(0).start
);
428 EXPECT_EQ(regions
.at(0).end
, regions
.at(1).start
);
429 EXPECT_EQ(1, regions
.at(1).end
);
431 double split
= regions
.at(0).end
;
432 EXPECT_FLOAT_EQ(split
, expectedSplit
);
435 EXPECT_TRUE(stepsFunction
->evaluate(split
- dt
, 0) < 0.5);
436 EXPECT_TRUE(stepsFunction
->evaluate(split
, 0) >= 0.5);
437 EXPECT_TRUE(stepsFunction
->evaluate(split
+ dt
, 0) >= 0.5);
440 static void checkCubicRegions2(double x1
, double y1
, double x2
, double y2
)
442 Vector
<TimingFunction::PartitionRegion
> regions
= Vector
<TimingFunction::PartitionRegion
>();
443 RefPtr
<TimingFunction
> cubic
= CubicBezierTimingFunction::create(x1
, y1
, x2
, y2
);
444 cubic
->partition(regions
);
446 EXPECT_EQ(regions
.size(), 2ul);
447 EXPECT_EQ(regions
.at(0).half
, TimingFunction::RangeHalf::Lower
);
448 EXPECT_EQ(regions
.at(1).half
, TimingFunction::RangeHalf::Upper
);
450 EXPECT_EQ(0, regions
.at(0).start
);
451 EXPECT_EQ(regions
.at(0).end
, regions
.at(1).start
);
452 EXPECT_EQ(1, regions
.at(1).end
);
454 UnitBezier bezier
= UnitBezier(x1
, y1
, x2
, y2
);
455 EXPECT_FLOAT_EQ(0.5, bezier
.solve(regions
.at(0).end
, std::numeric_limits
<double>::epsilon()));
458 static void checkCubicRegions4(double x1
, double y1
, double x2
, double y2
)
460 Vector
<TimingFunction::PartitionRegion
> regions
= Vector
<TimingFunction::PartitionRegion
>();
461 RefPtr
<TimingFunction
> cubic
= CubicBezierTimingFunction::create(x1
, y1
, x2
, y2
);
462 cubic
->partition(regions
);
464 EXPECT_EQ(regions
.size(), 4ul);
465 EXPECT_EQ(regions
.at(0).half
, TimingFunction::RangeHalf::Lower
);
466 EXPECT_EQ(regions
.at(1).half
, TimingFunction::RangeHalf::Upper
);
467 EXPECT_EQ(regions
.at(2).half
, TimingFunction::RangeHalf::Lower
);
468 EXPECT_EQ(regions
.at(3).half
, TimingFunction::RangeHalf::Upper
);
470 EXPECT_EQ(0, regions
.at(0).start
);
471 EXPECT_EQ(regions
.at(0).end
, regions
.at(1).start
);
472 EXPECT_EQ(regions
.at(1).end
, regions
.at(2).start
);
473 EXPECT_EQ(regions
.at(2).end
, regions
.at(3).start
);
474 EXPECT_EQ(1, regions
.at(3).end
);
476 UnitBezier bezier
= UnitBezier(x1
, y1
, x2
, y2
);
477 EXPECT_FLOAT_EQ(0.5, bezier
.solve(regions
.at(0).end
, std::numeric_limits
<double>::epsilon()));
478 EXPECT_FLOAT_EQ(0.5, bezier
.solve(regions
.at(1).end
, std::numeric_limits
<double>::epsilon()));
481 TEST_F(TimingFunctionTest
, StepsPartitioning
)
483 checkSteps(1, StepsTimingFunction::StepAtPosition::Start
, 0.0);
484 checkSteps(1, StepsTimingFunction::StepAtPosition::Middle
, 0.5);
485 checkSteps(1, StepsTimingFunction::StepAtPosition::End
, 1.0);
487 checkSteps(2, StepsTimingFunction::StepAtPosition::Start
, 0.0);
488 checkSteps(2, StepsTimingFunction::StepAtPosition::Middle
, 0.25);
489 checkSteps(2, StepsTimingFunction::StepAtPosition::End
, 0.5);
491 checkSteps(3, StepsTimingFunction::StepAtPosition::Start
, 1.0 / 3.0);
492 checkSteps(3, StepsTimingFunction::StepAtPosition::Middle
, 0.5);
493 checkSteps(3, StepsTimingFunction::StepAtPosition::End
, 2.0 / 3.0);
495 checkSteps(4, StepsTimingFunction::StepAtPosition::Start
, 0.25);
496 checkSteps(4, StepsTimingFunction::StepAtPosition::Middle
, 0.375);
497 checkSteps(4, StepsTimingFunction::StepAtPosition::End
, 0.5);
499 checkSteps(5, StepsTimingFunction::StepAtPosition::Start
, 0.4);
500 checkSteps(5, StepsTimingFunction::StepAtPosition::Middle
, 0.5);
501 checkSteps(5, StepsTimingFunction::StepAtPosition::End
, 0.6);
503 checkSteps(8, StepsTimingFunction::StepAtPosition::Start
, 0.375);
504 checkSteps(8, StepsTimingFunction::StepAtPosition::Middle
, 0.4375);
505 checkSteps(8, StepsTimingFunction::StepAtPosition::End
, 0.5);
508 TEST_F(TimingFunctionTest
, CubicPartitioning
)
510 // Preset timing functions
511 checkCubicRegions2(0.25, 0.1, 0.25, 1.0);
512 checkCubicRegions2(0.42, 0.0, 1.0, 1.0);
513 checkCubicRegions2(0.0, 0.0, 0.58, 1.0);
514 checkCubicRegions2(0.42, 0.0, 0.58, 1.0);
517 checkCubicRegions2(0.0, 0.0, 1.0, 1.0);
519 // Curves with horizontal point of inflexion
520 checkCubicRegions2(0.0, 1.0, 1.0, 0.0);
521 checkCubicRegions2(0.0, 1.0, 1.0, -2e-16);
522 checkCubicRegions2(0.0, 4.0 / 7.0, 1.0, -2.0 / 7.0);
524 // Curves with no stationary points in (0,1)
525 checkCubicRegions2(1.0, 0.0, 0.0, 1.0);
526 checkCubicRegions2(0.3, 0.8, 0.2, 1.0);
528 // Curves with 2 stationary points, 1 intersection
529 checkCubicRegions2(0.5, 1.0, 1.0, -1.0);
530 checkCubicRegions2(1.0, 2.0, 0.0, -3.0);
532 // Curves with 2 stationary points, 3 intersections
533 checkCubicRegions4(1.0, 2.0, 0.0, -1.0);
534 checkCubicRegions4(0.7, 1.5, 1.0, -0.5);
536 // Curves with derivative discriminant < 0
537 checkCubicRegions2(0.5, 1.0, 0.0, 0.8);
538 checkCubicRegions2(0.4, 1.3, 0.1, 0.8);
540 // Curves with extremely close points of intersection
541 checkCubicRegions4(0.0, 1.65, 0.0, -1.5);
542 checkCubicRegions2(0.0, 1.64, 0.0, -1.5);
544 // Curves with turning points touching y = 0.5
545 checkCubicRegions2(0.0, 41.0 / 27.0, 1.0, -10.0 / 9.0);
546 checkCubicRegions2(0.0, 19.0 / 9.0, 1.0, -14.0 / 27.0);