| OLD | NEW |
| 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"; | 1 "use strict"; |
| 19 | 2 |
| 20 var target = document.getElementById("target"); | 3 // Utility functions and common keyframe test data. |
| 21 | 4 |
| 22 function assert_frames_equal(a, b, name) { | 5 // ------------------------------ |
| 23 assert_equals(Object.keys(a).sort().toString(), | 6 // Helper functions |
| 24 Object.keys(b).sort().toString(), | 7 // ------------------------------ |
| 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 | 8 |
| 9 /** |
| 10 * Test equality between two lists of computed keyframes |
| 11 * @param {Array.<ComputedKeyframe>} a - actual computed keyframes |
| 12 * @param {Array.<ComputedKeyframe>} b - expected computed keyframes |
| 13 */ |
| 31 function assert_frame_lists_equal(a, b) { | 14 function assert_frame_lists_equal(a, b) { |
| 32 assert_equals(a.length, b.length, "number of frames"); | 15 assert_equals(a.length, b.length, "number of frames"); |
| 33 for (var i = 0; i < Math.min(a.length, b.length); i++) { | 16 for (var i = 0; i < Math.min(a.length, b.length); i++) { |
| 34 assert_frames_equal(a[i], b[i], "ComputedKeyframe #" + i); | 17 assert_frames_equal(a[i], b[i], "ComputedKeyframe #" + i); |
| 35 } | 18 } |
| 36 } | 19 } |
| 37 | 20 |
| 38 var gEmptyKeyframeListTests = [ | 21 /** Helper */ |
| 39 [], | 22 function assert_frames_equal(a, b, name) { |
| 40 null, | 23 assert_equals(Object.keys(a).sort().toString(), |
| 41 undefined, | 24 Object.keys(b).sort().toString(), |
| 42 ]; | 25 "properties on " + name); |
| 26 for (var p in a) { |
| 27 assert_equals(a[p], b[p], "value for '" + p + "' on " + name); |
| 28 } |
| 29 } |
| 43 | 30 |
| 44 test(function(t) { | 31 // ------------------------------ |
| 45 gEmptyKeyframeListTests.forEach(function(frames) { | 32 // Easing values |
| 46 assert_equals(new KeyframeEffectReadOnly(target, frames).getFrames().length, | 33 // ------------------------------ |
| 47 0, "number of frames for " + JSON.stringify(frames)); | |
| 48 }); | |
| 49 }, "a KeyframeEffectReadOnly can be constructed with no frames"); | |
| 50 | 34 |
| 51 // [specified easing value, expected easing value] | 35 // [specified easing value, expected easing value] |
| 52 var gEasingValueTests = [ | 36 var gEasingValueTests = [ |
| 53 ["linear", "linear"], | 37 ["linear", "linear"], |
| 54 ["ease-in-out", "ease-in-out"], | 38 ["ease-in-out", "ease-in-out"], |
| 55 ["Ease\\2d in-out", "ease-in-out"], | 39 ["Ease\\2d in-out", "ease-in-out"], |
| 56 ["ease /**/", "ease"], | 40 ["ease /**/", "ease"], |
| 57 ]; | 41 ]; |
| 58 | 42 |
| 59 test(function(t) { | 43 var gInvalidEasingInKeyframeSequenceTests = [ |
| 60 gEasingValueTests.forEach(function(subtest) { | 44 { desc: "a blank easing", |
| 61 var easing = subtest[0]; | 45 input: [{ easing: "" }] }, |
| 62 var expected = subtest[1]; | 46 { desc: "an unrecognized easing", |
| 63 var effect = new KeyframeEffectReadOnly(target, { | 47 input: [{ easing: "unrecognized" }] }, |
| 64 left: ["10px", "20px"], | 48 { desc: "an 'initial' easing", |
| 65 easing: easing | 49 input: [{ easing: "initial" }] }, |
| 66 }); | 50 { desc: "an 'inherit' easing", |
| 67 assert_equals(effect.getFrames()[0].easing, expected, | 51 input: [{ easing: "inherit" }] }, |
| 68 "resulting easing for '" + easing + "'"); | 52 { desc: "a variable easing", |
| 69 }); | 53 input: [{ easing: "var(--x)" }] }, |
| 70 }, "easing values are parsed correctly when passed to the " + | 54 { desc: "a multi-value easing", |
| 71 "KeyframeEffectReadOnly constructor in a property-indexed keyframe"); | 55 input: [{ easing: "ease-in-out, ease-out" }] } |
| 56 ]; |
| 72 | 57 |
| 73 test(function(t) { | 58 // ------------------------------ |
| 74 gEasingValueTests.forEach(function(subtest) { | 59 // Composite values |
| 75 var easing = subtest[0]; | 60 // ------------------------------ |
| 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 | 61 |
| 100 var gGoodKeyframeCompositeValueTests = [ | 62 var gGoodKeyframeCompositeValueTests = [ |
| 101 "replace", "add", "accumulate", undefined | 63 "replace", "add", "accumulate", undefined |
| 102 ]; | 64 ]; |
| 103 | 65 |
| 104 var gGoodOptionsCompositeValueTests = [ | 66 var gGoodOptionsCompositeValueTests = [ |
| 105 "replace", "add", "accumulate" | 67 "replace", "add", "accumulate" |
| 106 ]; | 68 ]; |
| 107 | 69 |
| 108 var gBadCompositeValueTests = [ | 70 var gBadCompositeValueTests = [ |
| 109 "unrecognised", "replace ", "Replace", null | 71 "unrecognised", "replace ", "Replace", null |
| 110 ]; | 72 ]; |
| 111 | 73 |
| 112 test(function(t) { | 74 // ------------------------------ |
| 113 var getFrame = function(composite) { | 75 // Keyframes |
| 114 return { left: [ "10px", "20px" ], composite: composite }; | 76 // ------------------------------ |
| 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 | 77 |
| 129 test(function(t) { | 78 var gEmptyKeyframeListTests = [ |
| 130 var getFrames = function(composite) { | 79 [], |
| 131 return [ | 80 null, |
| 132 { offset: 0, left: "10px", composite: composite }, | 81 undefined, |
| 133 { offset: 1, left: "20px" } | 82 ]; |
| 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 | 83 |
| 167 var gPropertyIndexedKeyframesTests = [ | 84 var gPropertyIndexedKeyframesTests = [ |
| 168 { desc: "a one property two value property-indexed keyframes specification", | 85 { desc: "a one property two value property-indexed keyframes specification", |
| 169 input: { left: ["10px", "20px"] }, | 86 input: { left: ["10px", "20px"] }, |
| 170 output: [{ offset: null, computedOffset: 0, easing: "linear", | 87 output: [{ offset: null, computedOffset: 0, easing: "linear", |
| 171 left: "10px" }, | 88 left: "10px" }, |
| 172 { offset: null, computedOffset: 1, easing: "linear", | 89 { offset: null, computedOffset: 1, easing: "linear", |
| 173 left: "20px" }] }, | 90 left: "20px" }] }, |
| 174 { desc: "a one shorthand property two value property-indexed keyframes" | 91 { desc: "a one shorthand property two value property-indexed keyframes" |
| 175 + " specification", | 92 + " specification", |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 { offset: 0.0, computedOffset: 0.0, easing: "ease", | 190 { offset: 0.0, computedOffset: 0.0, easing: "ease", |
| 274 left: "200px" }, | 191 left: "200px" }, |
| 275 { offset: 0.5, computedOffset: 0.5, easing: "linear", | 192 { offset: 0.5, computedOffset: 0.5, easing: "linear", |
| 276 left: "300px" }, | 193 left: "300px" }, |
| 277 { offset: 1.0, computedOffset: 1.0, easing: "ease-out", | 194 { offset: 1.0, computedOffset: 1.0, easing: "ease-out", |
| 278 left: "400px" }, | 195 left: "400px" }, |
| 279 { offset: 1.0, computedOffset: 1.0, easing: "step-end", | 196 { offset: 1.0, computedOffset: 1.0, easing: "step-end", |
| 280 left: "500px" }] }, | 197 left: "500px" }] }, |
| 281 ]; | 198 ]; |
| 282 | 199 |
| 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 = [ | 200 var gKeyframeSequenceTests = [ |
| 201 { desc: "a one property one keyframe sequence", |
| 202 input: [{ offset: 1, left: "10px" }], |
| 203 output: [{ offset: null, computedOffset: 1, easing: "linear", |
| 204 left: "10px" }] }, |
| 318 { desc: "a one property two keyframe sequence", | 205 { desc: "a one property two keyframe sequence", |
| 319 input: [{ offset: 0, left: "10px" }, | 206 input: [{ offset: 0, left: "10px" }, |
| 320 { offset: 1, left: "20px" }], | 207 { offset: 1, left: "20px" }], |
| 321 output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" }, | 208 output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" }, |
| 322 { offset: 1, computedOffset: 1, easing: "linear", left: "20px" }] | 209 { offset: 1, computedOffset: 1, easing: "linear", left: "20px" }] |
| 323 }, | 210 }, |
| 324 { desc: "a two property two keyframe sequence", | 211 { desc: "a two property two keyframe sequence", |
| 325 input: [{ offset: 0, left: "10px", top: "30px" }, | 212 input: [{ offset: 0, left: "10px", top: "30px" }, |
| 326 { offset: 1, left: "20px", top: "40px" }], | 213 { offset: 1, left: "20px", top: "40px" }], |
| 327 output: [{ offset: 0, computedOffset: 0, easing: "linear", | 214 output: [{ offset: 0, computedOffset: 0, easing: "linear", |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 { desc: "a two property four keyframe sequence", | 264 { desc: "a two property four keyframe sequence", |
| 378 input: [{ offset: 0, left: "10px" }, | 265 input: [{ offset: 0, left: "10px" }, |
| 379 { offset: 0, top: "20px" }, | 266 { offset: 0, top: "20px" }, |
| 380 { offset: 1, top: "30px" }, | 267 { offset: 1, top: "30px" }, |
| 381 { offset: 1, left: "40px" }], | 268 { offset: 1, left: "40px" }], |
| 382 output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" }, | 269 output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" }, |
| 383 { offset: 0, computedOffset: 0, easing: "linear", top: "20px" }, | 270 { offset: 0, computedOffset: 0, easing: "linear", top: "20px" }, |
| 384 { offset: 1, computedOffset: 1, easing: "linear", top: "30px" }, | 271 { offset: 1, computedOffset: 1, easing: "linear", top: "30px" }, |
| 385 { offset: 1, computedOffset: 1, easing: "linear", left: "40px" }] | 272 { offset: 1, computedOffset: 1, easing: "linear", left: "40px" }] |
| 386 }, | 273 }, |
| 274 { desc: "a single keyframe sequence with omitted offsets", |
| 275 input: [{ left: "10px" }], |
| 276 output: [{ offset: null, computedOffset: 1, easing: "linear", |
| 277 left: "10px" }] }, |
| 387 { desc: "a one property keyframe sequence with some omitted offsets", | 278 { desc: "a one property keyframe sequence with some omitted offsets", |
| 388 input: [{ offset: 0.00, left: "10px" }, | 279 input: [{ offset: 0.00, left: "10px" }, |
| 389 { offset: 0.25, left: "20px" }, | 280 { offset: 0.25, left: "20px" }, |
| 390 { left: "30px" }, | 281 { left: "30px" }, |
| 391 { left: "40px" }, | 282 { left: "40px" }, |
| 392 { offset: 1.00, left: "50px" }], | 283 { offset: 1.00, left: "50px" }], |
| 393 output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", | 284 output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", |
| 394 left: "10px" }, | 285 left: "10px" }, |
| 395 { offset: 0.25, computedOffset: 0.25, easing: "linear", | 286 { offset: 0.25, computedOffset: 0.25, easing: "linear", |
| 396 left: "20px" }, | 287 left: "20px" }, |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 border: "3px dashed rgb(7, 8, 9)" }] }, | 397 border: "3px dashed rgb(7, 8, 9)" }] }, |
| 507 { desc: "a keyframe sequence where greater shorthand precedes lesser" | 398 { desc: "a keyframe sequence where greater shorthand precedes lesser" |
| 508 + " shorthand", | 399 + " shorthand", |
| 509 input: [{ offset: 0, border: "2px dotted rgb(4, 5, 6)", | 400 input: [{ offset: 0, border: "2px dotted rgb(4, 5, 6)", |
| 510 borderLeft: "1px solid rgb(1, 2, 3)" }, | 401 borderLeft: "1px solid rgb(1, 2, 3)" }, |
| 511 { offset: 1, border: "3px dashed rgb(7, 8, 9)" }], | 402 { offset: 1, border: "3px dashed rgb(7, 8, 9)" }], |
| 512 output: [{ offset: 0, computedOffset: 0, easing: "linear", | 403 output: [{ offset: 0, computedOffset: 0, easing: "linear", |
| 513 border: "2px dotted rgb(4, 5, 6)", | 404 border: "2px dotted rgb(4, 5, 6)", |
| 514 borderLeft: "1px solid rgb(1, 2, 3)" }, | 405 borderLeft: "1px solid rgb(1, 2, 3)" }, |
| 515 { offset: 1, computedOffset: 1, easing: "linear", | 406 { offset: 1, computedOffset: 1, easing: "linear", |
| 516 border: "3px dashed rgb(7, 8, 9)" }] }, | 407 border: "3px dashed rgb(7, 8, 9)" }] } |
| 517 ]; | 408 ]; |
| 518 | 409 |
| 519 gKeyframeSequenceTests.forEach(function(subtest) { | 410 var gInvalidKeyframesTests = [ |
| 520 test(function(t) { | 411 { desc: "keyframes with an out-of-bounded positive offset", |
| 521 var effect = new KeyframeEffectReadOnly(target, subtest.input); | 412 input: [ { opacity: 0 }, |
| 522 assert_frame_lists_equal(effect.getFrames(), subtest.output); | 413 { opacity: 0.5, offset: 2 }, |
| 523 }, "a KeyframeEffectReadOnly can be constructed with " + subtest.desc); | 414 { opacity: 1 } ], |
| 524 | 415 expected: { name: "TypeError" } }, |
| 525 test(function(t) { | 416 { desc: "keyframes with an out-of-bounded negative offset", |
| 526 var effect = new KeyframeEffectReadOnly(target, subtest.input); | 417 input: [ { opacity: 0 }, |
| 527 var secondEffect = new KeyframeEffectReadOnly(target, effect.getFrames()); | 418 { opacity: 0.5, offset: -1 }, |
| 528 assert_frame_lists_equal(secondEffect.getFrames(), effect.getFrames()); | 419 { opacity: 1 } ], |
| 529 }, "a KeyframeEffectReadOnly constructed with " + subtest.desc + | 420 expected: { name: "TypeError" } }, |
| 530 " roundtrips"); | 421 { desc: "keyframes not loosely sorted by offset", |
| 531 }); | 422 input: [ { opacity: 0, offset: 1 }, |
| 532 | 423 { opacity: 1, offset: 0 } ], |
| 533 var gInvalidEasingInKeyframeSequenceTests = [ | 424 expected: { name: "TypeError" } }, |
| 534 { desc: "a blank easing", | 425 { desc: "property-indexed keyframes with an invalid easing value", |
| 535 input: [{ easing: "" }] }, | 426 input: { opacity: [ 0, 0.5, 1 ], |
| 536 { desc: "an unrecognized easing", | 427 easing: "inherit" }, |
| 537 input: [{ easing: "unrecognized" }] }, | 428 expected: { name: "TypeError" } }, |
| 538 { desc: "an 'initial' easing", | 429 { desc: "a keyframe sequence with an invalid easing value", |
| 539 input: [{ easing: "initial" }] }, | 430 input: [ { opacity: 0, easing: "jumpy" }, |
| 540 { desc: "an 'inherit' easing", | 431 { opacity: 1 } ], |
| 541 input: [{ easing: "inherit" }] }, | 432 expected: { name: "TypeError" } }, |
| 542 { desc: "a variable easing", | 433 { desc: "keyframes with an invalid composite value", |
| 543 input: [{ easing: "var(--x)" }] }, | 434 input: [ { opacity: 0, composite: "alternate" }, |
| 544 { desc: "a multi-value easing", | 435 { opacity: 1 } ], |
| 545 input: [{ easing: "ease-in-out, ease-out" }] } | 436 expected: { name: "TypeError" } } |
| 546 ]; | 437 ]; |
| 547 | 438 |
| 548 gInvalidEasingInKeyframeSequenceTests.forEach(function(subtest) { | 439 // ------------------------------ |
| 549 test(function(t) { | 440 // KeyframeEffectOptions |
| 550 assert_throws(new TypeError, function() { | 441 // ------------------------------ |
| 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 | 442 |
| 579 var gKeyframeEffectOptionTests = [ | 443 var gKeyframeEffectOptionTests = [ |
| 580 { desc: "an empty KeyframeEffectOptions object", | 444 { desc: "an empty KeyframeEffectOptions object", |
| 581 input: { }, | 445 input: { }, |
| 582 expected: { } }, | 446 expected: { } }, |
| 583 { desc: "a normal KeyframeEffectOptions object", | 447 { desc: "a normal KeyframeEffectOptions object", |
| 584 input: { delay: 1000, | 448 input: { delay: 1000, |
| 585 fill: "auto", | 449 fill: "auto", |
| 586 iterations: 5.5, | 450 iterations: 5.5, |
| 587 duration: "auto", | 451 duration: "auto", |
| (...skipping 19 matching lines...) Expand all Loading... |
| 607 input: { iterations: Infinity }, | 471 input: { iterations: Infinity }, |
| 608 expected: { iterations: Infinity } }, | 472 expected: { iterations: Infinity } }, |
| 609 { desc: "an auto fill", | 473 { desc: "an auto fill", |
| 610 input: { fill: "auto" }, | 474 input: { fill: "auto" }, |
| 611 expected: { fill: "auto" } }, | 475 expected: { fill: "auto" } }, |
| 612 { desc: "a forwards fill", | 476 { desc: "a forwards fill", |
| 613 input: { fill: "forwards" }, | 477 input: { fill: "forwards" }, |
| 614 expected: { fill: "forwards" } } | 478 expected: { fill: "forwards" } } |
| 615 ]; | 479 ]; |
| 616 | 480 |
| 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 = [ | 481 var gInvalidKeyframeEffectOptionTests = [ |
| 645 { desc: "-Infinity", | 482 { desc: "-Infinity", |
| 646 input: -Infinity, | 483 input: -Infinity, |
| 647 expected: { name: "TypeError" } }, | 484 expected: { name: "TypeError" } }, |
| 648 { desc: "NaN", | 485 { desc: "NaN", |
| 649 input: NaN, | 486 input: NaN, |
| 650 expected: { name: "TypeError" } }, | 487 expected: { name: "TypeError" } }, |
| 651 { desc: "a negative value", | 488 { desc: "a negative value", |
| 652 input: -1, | 489 input: -1, |
| 653 expected: { name: "TypeError" } }, | 490 expected: { name: "TypeError" } }, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 684 { desc: "an 'inherit' easing", | 521 { desc: "an 'inherit' easing", |
| 685 input: { easing: "inherit" }, | 522 input: { easing: "inherit" }, |
| 686 expected: { name: "TypeError" } }, | 523 expected: { name: "TypeError" } }, |
| 687 { desc: "a variable easing", | 524 { desc: "a variable easing", |
| 688 input: { easing: "var(--x)" }, | 525 input: { easing: "var(--x)" }, |
| 689 expected: { name: "TypeError" } }, | 526 expected: { name: "TypeError" } }, |
| 690 { desc: "a multi-value easing", | 527 { desc: "a multi-value easing", |
| 691 input: { easing: "ease-in-out, ease-out" }, | 528 input: { easing: "ease-in-out, ease-out" }, |
| 692 expected: { name: "TypeError" } } | 529 expected: { name: "TypeError" } } |
| 693 ]; | 530 ]; |
| 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> | |
| OLD | NEW |