Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(275)

Side by Side Diff: third_party/WebKit/LayoutTests/imported/wpt/web-animations/keyframe-effect/constructor.html

Issue 2015623004: Import wpt@ed94c51f3dfaa5ff4c9c311add1a560408059c51 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <!DOCTYPE html>
2 <meta charset=utf-8>
3 <title>KeyframeEffectReadOnly constructor tests</title>
4 <link rel="help" href="http://w3c.github.io/web-animations/#the-keyframeeffect-i nterfaces">
5 <link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
6 <script src="../../../../resources/testharness.js"></script>
7 <script src="../../../../resources/testharnessreport.js"></script>
8 <script src="../testcommon.js"></script>
9 <body>
10 <div id="log"></div>
11 <div id="target"></div>
12 <style>
13 #target {
14 border-style: solid; /* so border-*-width values don't compute to 0 */
15 }
16 </style>
17 <script>
18 "use strict";
19
20 var target = document.getElementById("target");
21
22 function assert_frames_equal(a, b, name) {
23 assert_equals(Object.keys(a).sort().toString(),
24 Object.keys(b).sort().toString(),
25 "properties on " + name);
26 for (var p in a) {
27 assert_equals(a[p], b[p], "value for '" + p + "' on " + name);
28 }
29 }
30
31 function assert_frame_lists_equal(a, b) {
32 assert_equals(a.length, b.length, "number of frames");
33 for (var i = 0; i < Math.min(a.length, b.length); i++) {
34 assert_frames_equal(a[i], b[i], "ComputedKeyframe #" + i);
35 }
36 }
37
38 var gEmptyKeyframeListTests = [
39 [],
40 null,
41 undefined,
42 ];
43
44 test(function(t) {
45 gEmptyKeyframeListTests.forEach(function(frames) {
46 assert_equals(new KeyframeEffectReadOnly(target, frames).getFrames().length,
47 0, "number of frames for " + JSON.stringify(frames));
48 });
49 }, "a KeyframeEffectReadOnly can be constructed with no frames");
50
51 // [specified easing value, expected easing value]
52 var gEasingValueTests = [
53 ["linear", "linear"],
54 ["ease-in-out", "ease-in-out"],
55 ["Ease\\2d in-out", "ease-in-out"],
56 ["ease /**/", "ease"],
57 ];
58
59 test(function(t) {
60 gEasingValueTests.forEach(function(subtest) {
61 var easing = subtest[0];
62 var expected = subtest[1];
63 var effect = new KeyframeEffectReadOnly(target, {
64 left: ["10px", "20px"],
65 easing: easing
66 });
67 assert_equals(effect.getFrames()[0].easing, expected,
68 "resulting easing for '" + easing + "'");
69 });
70 }, "easing values are parsed correctly when passed to the " +
71 "KeyframeEffectReadOnly constructor in a property-indexed keyframe");
72
73 test(function(t) {
74 gEasingValueTests.forEach(function(subtest) {
75 var easing = subtest[0];
76 var expected = subtest[1];
77 var effect = new KeyframeEffectReadOnly(target, [
78 { offset: 0, left: "10px", easing: easing },
79 { offset: 1, left: "20px" }
80 ]);
81 assert_equals(effect.getFrames()[0].easing, expected,
82 "resulting easing for '" + easing + "'");
83 });
84 }, "easing values are parsed correctly when passed to the " +
85 "KeyframeEffectReadOnly constructor in regular keyframes");
86
87 test(function(t) {
88 gEasingValueTests.forEach(function(subtest) {
89 var easing = subtest[0];
90 var expected = subtest[1];
91 var effect = new KeyframeEffectReadOnly(target, {
92 left: ["10px", "20px"]
93 }, { easing: easing });
94 assert_equals(effect.timing.easing, expected,
95 "resulting easing for '" + easing + "'");
96 });
97 }, "easing values are parsed correctly when passed to the " +
98 "KeyframeEffectReadOnly constructor in KeyframeTimingOptions");
99
100 var gGoodKeyframeCompositeValueTests = [
101 "replace", "add", "accumulate", undefined
102 ];
103
104 var gGoodOptionsCompositeValueTests = [
105 "replace", "add", "accumulate"
106 ];
107
108 var gBadCompositeValueTests = [
109 "unrecognised", "replace ", "Replace", null
110 ];
111
112 test(function(t) {
113 var getFrame = function(composite) {
114 return { left: [ "10px", "20px" ], composite: composite };
115 };
116 gGoodKeyframeCompositeValueTests.forEach(function(composite) {
117 var effect = new KeyframeEffectReadOnly(target, getFrame(composite));
118 assert_equals(effect.getFrames()[0].composite, composite,
119 "resulting composite for '" + composite + "'");
120 });
121 gBadCompositeValueTests.forEach(function(composite) {
122 assert_throws(new TypeError, function() {
123 new KeyframeEffectReadOnly(target, getFrame(composite));
124 });
125 });
126 }, "composite values are parsed correctly when passed to the " +
127 "KeyframeEffectReadOnly constructor in property-indexed keyframes");
128
129 test(function(t) {
130 var getFrames = function(composite) {
131 return [
132 { offset: 0, left: "10px", composite: composite },
133 { offset: 1, left: "20px" }
134 ];
135 };
136 gGoodKeyframeCompositeValueTests.forEach(function(composite) {
137 var effect = new KeyframeEffectReadOnly(target, getFrames(composite));
138 assert_equals(effect.getFrames()[0].composite, composite,
139 "resulting composite for '" + composite + "'");
140 });
141 gBadCompositeValueTests.forEach(function(composite) {
142 assert_throws(new TypeError, function() {
143 new KeyframeEffectReadOnly(target, getFrames(composite));
144 });
145 });
146 }, "composite values are parsed correctly when passed to the " +
147 "KeyframeEffectReadOnly constructor in regular keyframes");
148
149 test(function(t) {
150 gGoodOptionsCompositeValueTests.forEach(function(composite) {
151 var effect = new KeyframeEffectReadOnly(target, {
152 left: ["10px", "20px"]
153 }, { composite: composite });
154 assert_equals(effect.getFrames()[0].composite, composite,
155 "resulting composite for '" + composite + "'");
156 });
157 gBadCompositeValueTests.forEach(function(composite) {
158 assert_throws(new TypeError, function() {
159 new KeyframeEffectReadOnly(target, {
160 left: ["10px", "20px"]
161 }, { composite: composite });
162 });
163 });
164 }, "composite values are parsed correctly when passed to the " +
165 "KeyframeEffectReadOnly constructor in KeyframeTimingOptions");
166
167 var gPropertyIndexedKeyframesTests = [
168 { desc: "a one property two value property-indexed keyframes specification",
169 input: { left: ["10px", "20px"] },
170 output: [{ offset: null, computedOffset: 0, easing: "linear",
171 left: "10px" },
172 { offset: null, computedOffset: 1, easing: "linear",
173 left: "20px" }] },
174 { desc: "a one shorthand property two value property-indexed keyframes"
175 + " specification",
176 input: { margin: ["10px", "10px 20px 30px 40px"] },
177 output: [{ offset: null, computedOffset: 0, easing: "linear",
178 margin: "10px" },
179 { offset: null, computedOffset: 1, easing: "linear",
180 margin: "10px 20px 30px 40px" }] },
181 { desc: "a two property (one shorthand and one of its longhand components)"
182 + " two value property-indexed keyframes specification",
183 input: { marginTop: ["50px", "60px"],
184 margin: ["10px", "10px 20px 30px 40px"] },
185 output: [{ offset: null, computedOffset: 0, easing: "linear",
186 marginTop: "50px", margin: "10px" },
187 { offset: null, computedOffset: 1, easing: "linear",
188 marginTop: "60px", margin: "10px 20px 30px 40px" }] },
189 { desc: "a two property two value property-indexed keyframes specification",
190 input: { left: ["10px", "20px"],
191 top: ["30px", "40px"] },
192 output: [{ offset: null, computedOffset: 0, easing: "linear",
193 left: "10px", top: "30px" },
194 { offset: null, computedOffset: 1, easing: "linear",
195 left: "20px", top: "40px" }] },
196 { desc: "a two property property-indexed keyframes specification with"
197 + " different numbers of values",
198 input: { left: ["10px", "20px", "30px"],
199 top: ["40px", "50px"] },
200 output: [{ offset: null, computedOffset: 0.0, easing: "linear",
201 left: "10px", top: "40px" },
202 { offset: null, computedOffset: 0.5, easing: "linear",
203 left: "20px" },
204 { offset: null, computedOffset: 1.0, easing: "linear",
205 left: "30px", top: "50px" }] },
206 { desc: "a property-indexed keyframes specification with an invalid value",
207 input: { left: ["10px", "20px", "30px", "40px", "50px"],
208 top: ["15px", "25px", "invalid", "45px", "55px"] },
209 output: [{ offset: null, computedOffset: 0.00, easing: "linear",
210 left: "10px", top: "15px" },
211 { offset: null, computedOffset: 0.25, easing: "linear",
212 left: "20px", top: "25px" },
213 { offset: null, computedOffset: 0.50, easing: "linear",
214 left: "30px", top: "invalid" },
215 { offset: null, computedOffset: 0.75, easing: "linear",
216 left: "40px", top: "45px" },
217 { offset: null, computedOffset: 1.00, easing: "linear",
218 left: "50px", top: "55px" }] },
219 { desc: "a one property two value property-indexed keyframes specification"
220 + " that needs to stringify its values",
221 input: { opacity: [0, 1] },
222 output: [{ offset: null, computedOffset: 0, easing: "linear",
223 opacity: "0" },
224 { offset: null, computedOffset: 1, easing: "linear",
225 opacity: "1" }] },
226 { desc: "a one property one value property-indexed keyframes specification",
227 input: { left: ["10px"] },
228 output: [{ offset: null, computedOffset: 1, easing: "linear",
229 left: "10px" }] },
230 { desc: "a one property one non-array value property-indexed keyframes"
231 + " specification",
232 input: { left: "10px" },
233 output: [{ offset: null, computedOffset: 1, easing: "linear",
234 left: "10px" }] },
235 { desc: "a one property two value property-indexed keyframes specification"
236 + " where the first value is invalid",
237 input: { left: ["invalid", "10px"] },
238 output: [{ offset: null, computedOffset: 0, easing: "linear",
239 left: "invalid" },
240 { offset: null, computedOffset: 1, easing: "linear",
241 left: "10px" }] },
242 { desc: "a one property two value property-indexed keyframes specification"
243 + " where the second value is invalid",
244 input: { left: ["10px", "invalid"] },
245 output: [{ offset: null, computedOffset: 0, easing: "linear",
246 left: "10px" },
247 { offset: null, computedOffset: 1, easing: "linear",
248 left: "invalid" }] },
249 { desc: "a two property property-indexed keyframes specification where one"
250 + " property is missing from the first keyframe",
251 input: [{ offset: 0, left: "10px" },
252 { offset: 1, left: "20px", top: "30px" }],
253 output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
254 { offset: 1, computedOffset: 1, easing: "linear",
255 left: "20px", top: "30px" }] },
256 { desc: "a two property property-indexed keyframes specification where one"
257 + " property is missing from the last keyframe",
258 input: [{ offset: 0, left: "10px", top: "20px" },
259 { offset: 1, left: "30px" }],
260 output: [{ offset: 0, computedOffset: 0, easing: "linear",
261 left: "10px" , top: "20px" },
262 { offset: 1, computedOffset: 1, easing: "linear",
263 left: "30px" }] },
264 { desc: "a property-indexed keyframes specification with repeated values"
265 + " at offset 0 with different easings",
266 input: [{ offset: 0.0, left: "100px", easing: "ease" },
267 { offset: 0.0, left: "200px", easing: "ease" },
268 { offset: 0.5, left: "300px", easing: "linear" },
269 { offset: 1.0, left: "400px", easing: "ease-out" },
270 { offset: 1.0, left: "500px", easing: "step-end" }],
271 output: [{ offset: 0.0, computedOffset: 0.0, easing: "ease",
272 left: "100px" },
273 { offset: 0.0, computedOffset: 0.0, easing: "ease",
274 left: "200px" },
275 { offset: 0.5, computedOffset: 0.5, easing: "linear",
276 left: "300px" },
277 { offset: 1.0, computedOffset: 1.0, easing: "ease-out",
278 left: "400px" },
279 { offset: 1.0, computedOffset: 1.0, easing: "step-end",
280 left: "500px" }] },
281 ];
282
283 gPropertyIndexedKeyframesTests.forEach(function(subtest) {
284 test(function(t) {
285 var effect = new KeyframeEffectReadOnly(target, subtest.input);
286 assert_frame_lists_equal(effect.getFrames(), subtest.output);
287 }, "a KeyframeEffectReadOnly can be constructed with " + subtest.desc);
288
289 test(function(t) {
290 var effect = new KeyframeEffectReadOnly(target, subtest.input);
291 var secondEffect = new KeyframeEffectReadOnly(target, effect.getFrames());
292 assert_frame_lists_equal(secondEffect.getFrames(), effect.getFrames());
293 }, "a KeyframeEffectReadOnly constructed with " + subtest.desc +
294 " roundtrips");
295 });
296
297 test(function(t) {
298 var expectedOrder = ["composite", "easing", "offset", "left", "marginLeft"];
299 var actualOrder = [];
300 var kf1 = {};
301 var kf2 = { marginLeft: "10px", left: "20px", offset: 1 };
302 [{ p: "marginLeft", v: "10px" },
303 { p: "left", v: "20px" },
304 { p: "offset", v: "0" },
305 { p: "easing", v: "linear" },
306 { p: "composite", v: "replace" }].forEach(function(e) {
307 Object.defineProperty(kf1, e.p, {
308 enumerable: true,
309 get: function() { actualOrder.push(e.p); return e.v; }
310 });
311 });
312 new KeyframeEffectReadOnly(target, [kf1, kf2]);
313 assert_array_equals(actualOrder, expectedOrder, "property access order");
314 }, "the KeyframeEffectReadOnly constructor reads keyframe properties in the " +
315 "expected order");
316
317 var gKeyframeSequenceTests = [
318 { desc: "a one property two keyframe sequence",
319 input: [{ offset: 0, left: "10px" },
320 { offset: 1, left: "20px" }],
321 output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
322 { offset: 1, computedOffset: 1, easing: "linear", left: "20px" }]
323 },
324 { desc: "a two property two keyframe sequence",
325 input: [{ offset: 0, left: "10px", top: "30px" },
326 { offset: 1, left: "20px", top: "40px" }],
327 output: [{ offset: 0, computedOffset: 0, easing: "linear",
328 left: "10px", top: "30px" },
329 { offset: 1, computedOffset: 1, easing: "linear",
330 left: "20px", top: "40px" }] },
331 { desc: "a one shorthand property two keyframe sequence",
332 input: [{ offset: 0, margin: "10px" },
333 { offset: 1, margin: "20px 30px 40px 50px" }],
334 output: [{ offset: 0, computedOffset: 0, easing: "linear",
335 margin: "10px" },
336 { offset: 1, computedOffset: 1, easing: "linear",
337 margin: "20px 30px 40px 50px" }] },
338 { desc: "a two property (a shorthand and one of its component longhands)"
339 + " two keyframe sequence",
340 input: [{ offset: 0, margin: "10px", marginTop: "20px" },
341 { offset: 1, marginTop: "70px", margin: "30px 40px 50px 60px" }],
342 output: [{ offset: 0, computedOffset: 0, easing: "linear",
343 margin: "10px", marginTop: "20px" },
344 { offset: 1, computedOffset: 1, easing: "linear",
345 marginTop: "70px", margin: "30px 40px 50px 60px" }] },
346 { desc: "a keyframe sequence with duplicate values for a given interior"
347 + " offset",
348 input: [{ offset: 0.0, left: "10px" },
349 { offset: 0.5, left: "20px" },
350 { offset: 0.5, left: "30px" },
351 { offset: 0.5, left: "40px" },
352 { offset: 1.0, left: "50px" }],
353 output: [{ offset: 0.0, computedOffset: 0.0, easing: "linear",
354 left: "10px" },
355 { offset: 0.5, computedOffset: 0.5, easing: "linear",
356 left: "20px" },
357 { offset: 0.5, computedOffset: 0.5, easing: "linear",
358 left: "30px" },
359 { offset: 0.5, computedOffset: 0.5, easing: "linear",
360 left: "40px" },
361 { offset: 1.0, computedOffset: 1.0, easing: "linear",
362 left: "50px" }] },
363 { desc: "a keyframe sequence with duplicate values for offsets 0 and 1",
364 input: [{ offset: 0, left: "10px" },
365 { offset: 0, left: "20px" },
366 { offset: 0, left: "30px" },
367 { offset: 1, left: "40px" },
368 { offset: 1, left: "50px" },
369 { offset: 1, left: "60px" }],
370 output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
371 { offset: 0, computedOffset: 0, easing: "linear", left: "20px" },
372 { offset: 0, computedOffset: 0, easing: "linear", left: "30px" },
373 { offset: 1, computedOffset: 1, easing: "linear", left: "40px" },
374 { offset: 1, computedOffset: 1, easing: "linear", left: "50px" },
375 { offset: 1, computedOffset: 1, easing: "linear", left: "60px" }]
376 },
377 { desc: "a two property four keyframe sequence",
378 input: [{ offset: 0, left: "10px" },
379 { offset: 0, top: "20px" },
380 { offset: 1, top: "30px" },
381 { offset: 1, left: "40px" }],
382 output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
383 { offset: 0, computedOffset: 0, easing: "linear", top: "20px" },
384 { offset: 1, computedOffset: 1, easing: "linear", top: "30px" },
385 { offset: 1, computedOffset: 1, easing: "linear", left: "40px" }]
386 },
387 { desc: "a one property keyframe sequence with some omitted offsets",
388 input: [{ offset: 0.00, left: "10px" },
389 { offset: 0.25, left: "20px" },
390 { left: "30px" },
391 { left: "40px" },
392 { offset: 1.00, left: "50px" }],
393 output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear",
394 left: "10px" },
395 { offset: 0.25, computedOffset: 0.25, easing: "linear",
396 left: "20px" },
397 { offset: null, computedOffset: 0.50, easing: "linear",
398 left: "30px" },
399 { offset: null, computedOffset: 0.75, easing: "linear",
400 left: "40px" },
401 { offset: 1.00, computedOffset: 1.00, easing: "linear",
402 left: "50px" }] },
403 { desc: "a two property keyframe sequence with some omitted offsets",
404 input: [{ offset: 0.00, left: "10px", top: "20px" },
405 { offset: 0.25, left: "30px" },
406 { left: "40px" },
407 { left: "50px", top: "60px" },
408 { offset: 1.00, left: "70px", top: "80px" }],
409 output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear",
410 left: "10px", top: "20px" },
411 { offset: 0.25, computedOffset: 0.25, easing: "linear",
412 left: "30px" },
413 { offset: null, computedOffset: 0.50, easing: "linear",
414 left: "40px" },
415 { offset: null, computedOffset: 0.75, easing: "linear",
416 left: "50px", top: "60px" },
417 { offset: 1.00, computedOffset: 1.00, easing: "linear",
418 left: "70px", top: "80px" }] },
419 { desc: "a one property keyframe sequence with all omitted offsets",
420 input: [{ left: "10px" },
421 { left: "20px" },
422 { left: "30px" },
423 { left: "40px" },
424 { left: "50px" }],
425 output: [{ offset: null, computedOffset: 0.00, easing: "linear",
426 left: "10px" },
427 { offset: null, computedOffset: 0.25, easing: "linear",
428 left: "20px" },
429 { offset: null, computedOffset: 0.50, easing: "linear",
430 left: "30px" },
431 { offset: null, computedOffset: 0.75, easing: "linear",
432 left: "40px" },
433 { offset: null, computedOffset: 1.00, easing: "linear",
434 left: "50px" }] },
435 { desc: "a keyframe sequence with different easing values, but the same"
436 + " easing value for a given offset",
437 input: [{ offset: 0.0, easing: "ease", left: "10px"},
438 { offset: 0.0, easing: "ease", top: "20px"},
439 { offset: 0.5, easing: "linear", left: "30px" },
440 { offset: 0.5, easing: "linear", top: "40px" },
441 { offset: 1.0, easing: "step-end", left: "50px" },
442 { offset: 1.0, easing: "step-end", top: "60px" }],
443 output: [{ offset: 0.0, computedOffset: 0.0, easing: "ease",
444 left: "10px" },
445 { offset: 0.0, computedOffset: 0.0, easing: "ease",
446 top: "20px" },
447 { offset: 0.5, computedOffset: 0.5, easing: "linear",
448 left: "30px" },
449 { offset: 0.5, computedOffset: 0.5, easing: "linear",
450 top: "40px" },
451 { offset: 1.0, computedOffset: 1.0, easing: "step-end",
452 left: "50px" },
453 { offset: 1.0, computedOffset: 1.0, easing: "step-end",
454 top: "60px" }] },
455 { desc: "a keyframe sequence with different composite values, but the"
456 + " same composite value for a given offset",
457 input: [{ offset: 0.0, composite: "replace", left: "10px" },
458 { offset: 0.0, composite: "replace", top: "20px" },
459 { offset: 0.5, composite: "add", left: "30px" },
460 { offset: 0.5, composite: "add", top: "40px" },
461 { offset: 1.0, composite: "replace", left: "50px" },
462 { offset: 1.0, composite: "replace", top: "60px" }],
463 output: [{ offset: 0.0, computedOffset: 0.0, easing: "linear",
464 composite: "replace", left: "10px" },
465 { offset: 0.0, computedOffset: 0.0, easing: "linear",
466 composite: "replace", top: "20px" },
467 { offset: 0.5, computedOffset: 0.0, easing: "linear",
468 composite: "add", left: "30px" },
469 { offset: 0.5, computedOffset: 0.0, easing: "linear",
470 composite: "add", top: "40px" },
471 { offset: 1.0, computedOffset: 1.0, easing: "linear",
472 composite: "replace", left: "50px" },
473 { offset: 1.0, computedOffset: 1.0, easing: "linear",
474 composite: "replace", top: "60px" }] },
475 { desc: "a one property two keyframe sequence that needs to stringify"
476 + " its values",
477 input: [{ offset: 0, opacity: 0 },
478 { offset: 1, opacity: 1 }],
479 output: [{ offset: 0, computedOffset: 0, easing: "linear", opacity: "0" },
480 { offset: 1, computedOffset: 1, easing: "linear", opacity: "1" }]
481 },
482 { desc: "a keyframe sequence where shorthand precedes longhand",
483 input: [{ offset: 0, margin: "10px", marginRight: "20px" },
484 { offset: 1, margin: "30px" }],
485 output: [{ offset: 0, computedOffset: 0, easing: "linear",
486 margin: "10px", marginRight: "20px" },
487 { offset: 1, computedOffset: 1, easing: "linear",
488 margin: "30px" }] },
489 { desc: "a keyframe sequence where longhand precedes shorthand",
490 input: [{ offset: 0, marginRight: "20px", margin: "10px" },
491 { offset: 1, margin: "30px" }],
492 output: [{ offset: 0, computedOffset: 0, easing: "linear",
493 marginRight: "20px", margin: "10px" },
494 { offset: 1, computedOffset: 1, easing: "linear",
495 margin: "30px" }] },
496 { desc: "a keyframe sequence where lesser shorthand precedes greater"
497 + " shorthand",
498 input: [{ offset: 0,
499 borderLeft: "1px solid rgb(1, 2, 3)",
500 border: "2px dotted rgb(4, 5, 6)" },
501 { offset: 1, border: "3px dashed rgb(7, 8, 9)" }],
502 output: [{ offset: 0, computedOffset: 0, easing: "linear",
503 borderLeft: "1px solid rgb(1, 2, 3)",
504 border: "2px dotted rgb(4, 5, 6)" },
505 { offset: 1, computedOffset: 1, easing: "linear",
506 border: "3px dashed rgb(7, 8, 9)" }] },
507 { desc: "a keyframe sequence where greater shorthand precedes lesser"
508 + " shorthand",
509 input: [{ offset: 0, border: "2px dotted rgb(4, 5, 6)",
510 borderLeft: "1px solid rgb(1, 2, 3)" },
511 { offset: 1, border: "3px dashed rgb(7, 8, 9)" }],
512 output: [{ offset: 0, computedOffset: 0, easing: "linear",
513 border: "2px dotted rgb(4, 5, 6)",
514 borderLeft: "1px solid rgb(1, 2, 3)" },
515 { offset: 1, computedOffset: 1, easing: "linear",
516 border: "3px dashed rgb(7, 8, 9)" }] },
517 ];
518
519 gKeyframeSequenceTests.forEach(function(subtest) {
520 test(function(t) {
521 var effect = new KeyframeEffectReadOnly(target, subtest.input);
522 assert_frame_lists_equal(effect.getFrames(), subtest.output);
523 }, "a KeyframeEffectReadOnly can be constructed with " + subtest.desc);
524
525 test(function(t) {
526 var effect = new KeyframeEffectReadOnly(target, subtest.input);
527 var secondEffect = new KeyframeEffectReadOnly(target, effect.getFrames());
528 assert_frame_lists_equal(secondEffect.getFrames(), effect.getFrames());
529 }, "a KeyframeEffectReadOnly constructed with " + subtest.desc +
530 " roundtrips");
531 });
532
533 var gInvalidEasingInKeyframeSequenceTests = [
534 { desc: "a blank easing",
535 input: [{ easing: "" }] },
536 { desc: "an unrecognized easing",
537 input: [{ easing: "unrecognized" }] },
538 { desc: "an 'initial' easing",
539 input: [{ easing: "initial" }] },
540 { desc: "an 'inherit' easing",
541 input: [{ easing: "inherit" }] },
542 { desc: "a variable easing",
543 input: [{ easing: "var(--x)" }] },
544 { desc: "a multi-value easing",
545 input: [{ easing: "ease-in-out, ease-out" }] }
546 ];
547
548 gInvalidEasingInKeyframeSequenceTests.forEach(function(subtest) {
549 test(function(t) {
550 assert_throws(new TypeError, function() {
551 new KeyframeEffectReadOnly(target, subtest.input);
552 });
553 }, "Invalid easing [" + subtest.desc + "] in keyframe sequence " +
554 "should be thrown");
555 });
556
557 test(function(t) {
558 var effect = new KeyframeEffectReadOnly(target,
559 {left: ["10px", "20px"]});
560
561 var timing = effect.timing;
562 assert_equals(timing.delay, 0, "default delay");
563 assert_equals(timing.endDelay, 0, "default endDelay");
564 assert_equals(timing.fill, "auto", "default fill");
565 assert_equals(timing.iterations, 1.0, "default iterations");
566 assert_equals(timing.iterationStart, 0.0, "default iterationStart");
567 assert_equals(timing.duration, "auto", "default duration");
568 assert_equals(timing.direction, "normal", "default direction");
569 assert_equals(timing.easing, "linear", "default easing");
570
571 assert_equals(effect.composite, "replace", "default composite");
572 assert_equals(effect.iterationComposite, "replace",
573 "default iterationComposite");
574 assert_equals(effect.spacing, "distribute",
575 "default spacing");
576 }, "a KeyframeEffectReadOnly constructed without any " +
577 "KeyframeEffectOptions object");
578
579 var gKeyframeEffectOptionTests = [
580 { desc: "an empty KeyframeEffectOptions object",
581 input: { },
582 expected: { } },
583 { desc: "a normal KeyframeEffectOptions object",
584 input: { delay: 1000,
585 fill: "auto",
586 iterations: 5.5,
587 duration: "auto",
588 direction: "alternate" },
589 expected: { delay: 1000,
590 fill: "auto",
591 iterations: 5.5,
592 duration: "auto",
593 direction: "alternate" } },
594 { desc: "a double value",
595 input: 3000,
596 expected: { duration: 3000 } },
597 { desc: "+Infinity",
598 input: Infinity,
599 expected: { duration: Infinity } },
600 { desc: "an Infinity duration",
601 input: { duration: Infinity },
602 expected: { duration: Infinity } },
603 { desc: "an auto duration",
604 input: { duration: "auto" },
605 expected: { duration: "auto" } },
606 { desc: "an Infinity iterations",
607 input: { iterations: Infinity },
608 expected: { iterations: Infinity } },
609 { desc: "an auto fill",
610 input: { fill: "auto" },
611 expected: { fill: "auto" } },
612 { desc: "a forwards fill",
613 input: { fill: "forwards" },
614 expected: { fill: "forwards" } }
615 ];
616
617 gKeyframeEffectOptionTests.forEach(function(stest) {
618 test(function(t) {
619 var effect = new KeyframeEffectReadOnly(target,
620 {left: ["10px", "20px"]},
621 stest.input);
622
623 // Helper function to provide default expected values when the test does
624 // not supply them.
625 var expected = function(field, defaultValue) {
626 return field in stest.expected ? stest.expected[field] : defaultValue;
627 };
628
629 var timing = effect.timing;
630 assert_equals(timing.delay, expected("delay", 0),
631 "timing delay");
632 assert_equals(timing.fill, expected("fill", "auto"),
633 "timing fill");
634 assert_equals(timing.iterations, expected("iterations", 1),
635 "timing iterations");
636 assert_equals(timing.duration, expected("duration", "auto"),
637 "timing duration");
638 assert_equals(timing.direction, expected("direction", "normal"),
639 "timing direction");
640
641 }, "a KeyframeEffectReadOnly constructed by " + stest.desc);
642 });
643
644 var gInvalidKeyframeEffectOptionTests = [
645 { desc: "-Infinity",
646 input: -Infinity,
647 expected: { name: "TypeError" } },
648 { desc: "NaN",
649 input: NaN,
650 expected: { name: "TypeError" } },
651 { desc: "a negative value",
652 input: -1,
653 expected: { name: "TypeError" } },
654 { desc: "a negative Infinity duration",
655 input: { duration: -Infinity },
656 expected: { name: "TypeError" } },
657 { desc: "a NaN duration",
658 input: { duration: NaN },
659 expected: { name: "TypeError" } },
660 { desc: "a negative duration",
661 input: { duration: -1 },
662 expected: { name: "TypeError" } },
663 { desc: "a string duration",
664 input: { duration: "merrychristmas" },
665 expected: { name: "TypeError" } },
666 { desc: "a negative Infinity iterations",
667 input: { iterations: -Infinity},
668 expected: { name: "TypeError" } },
669 { desc: "a NaN iterations",
670 input: { iterations: NaN },
671 expected: { name: "TypeError" } },
672 { desc: "a negative iterations",
673 input: { iterations: -1 },
674 expected: { name: "TypeError" } },
675 { desc: "a blank easing",
676 input: { easing: "" },
677 expected: { name: "TypeError" } },
678 { desc: "an unrecognized easing",
679 input: { easing: "unrecognised" },
680 expected: { name: "TypeError" } },
681 { desc: "an 'initial' easing",
682 input: { easing: "initial" },
683 expected: { name: "TypeError" } },
684 { desc: "an 'inherit' easing",
685 input: { easing: "inherit" },
686 expected: { name: "TypeError" } },
687 { desc: "a variable easing",
688 input: { easing: "var(--x)" },
689 expected: { name: "TypeError" } },
690 { desc: "a multi-value easing",
691 input: { easing: "ease-in-out, ease-out" },
692 expected: { name: "TypeError" } }
693 ];
694
695 gInvalidKeyframeEffectOptionTests.forEach(function(stest) {
696 test(function(t) {
697 assert_throws(stest.expected, function() {
698 new KeyframeEffectReadOnly(target,
699 { left: ["10px", "20px"] },
700 stest.input);
701 });
702 }, "Invalid KeyframeEffectReadOnly option by " + stest.desc);
703 });
704
705 test(function(t) {
706 var effect = new KeyframeEffect(target,
707 { left: ["10px", "20px"] });
708
709 assert_class_string(effect, "KeyframeEffect");
710 assert_class_string(effect.timing, "AnimationEffectTiming");
711 }, "KeyframeEffect constructor creates an AnimationEffectTiming timing object");
712
713 test(function(t) {
714 var test_error = { name: "test" };
715
716 assert_throws(test_error, function() {
717 new KeyframeEffect(target, { get left() { throw test_error }})
718 });
719 }, "KeyframeEffect constructor propagates exceptions generated by accessing"
720 + " the options object");
721
722 done();
723 </script>
724 </body>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698