constructor.html (7482B)
1 <!DOCTYPE html> 2 <meta charset=utf-8> 3 <title>KeyframeEffect constructor</title> 4 <link rel="help" 5 href="https://drafts.csswg.org/web-animations/#dom-keyframeeffect-keyframeeffect"> 6 <link rel="help" 7 href="https://drafts.csswg.org/web-animations/#dom-keyframeeffectreadonly-keyframeeffectreadonly"> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 <script src="../../testcommon.js"></script> 11 <script src="../../resources/easing-tests.js"></script> 12 <script src="../../resources/keyframe-utils.js"></script> 13 <script src="../../resources/keyframe-tests.js"></script> 14 <body> 15 <div id="log"></div> 16 <div id="target"></div> 17 <script> 18 'use strict'; 19 20 const target = document.getElementById('target'); 21 22 test(t => { 23 for (const frames of gEmptyKeyframeListTests) { 24 assert_equals(new KeyframeEffect(target, frames).getKeyframes().length, 25 0, `number of frames for ${JSON.stringify(frames)}`); 26 } 27 }, 'A KeyframeEffect can be constructed with no frames'); 28 29 test(t => { 30 for (const subtest of gEasingParsingTests) { 31 const easing = subtest[0]; 32 const expected = subtest[1]; 33 const effect = new KeyframeEffect(target, { 34 left: ['10px', '20px'] 35 }, { easing: easing }); 36 assert_equals(effect.getTiming().easing, expected, 37 `resulting easing for '${easing}'`); 38 } 39 }, 'easing values are parsed correctly when passed to the ' + 40 'KeyframeEffect constructor in KeyframeEffectOptions'); 41 42 test(t => { 43 for (const invalidEasing of gInvalidEasings) { 44 assert_throws_js(TypeError, () => { 45 new KeyframeEffect(target, null, { easing: invalidEasing }); 46 }, `TypeError is thrown for easing '${invalidEasing}'`); 47 } 48 }, 'Invalid easing values are correctly rejected when passed to the ' + 49 'KeyframeEffect constructor in KeyframeEffectOptions'); 50 51 test(t => { 52 const getKeyframe = 53 composite => ({ left: [ '10px', '20px' ], composite: composite }); 54 for (const composite of gGoodKeyframeCompositeValueTests) { 55 const effect = new KeyframeEffect(target, getKeyframe(composite)); 56 assert_equals(effect.getKeyframes()[0].composite, composite, 57 `resulting composite for '${composite}'`); 58 } 59 for (const composite of gBadKeyframeCompositeValueTests) { 60 assert_throws_js(TypeError, () => { 61 new KeyframeEffect(target, getKeyframe(composite)); 62 }); 63 } 64 }, 'composite values are parsed correctly when passed to the ' + 65 'KeyframeEffect constructor in property-indexed keyframes'); 66 67 test(t => { 68 const getKeyframes = composite => 69 [ 70 { offset: 0, left: '10px', composite: composite }, 71 { offset: 1, left: '20px' } 72 ]; 73 for (const composite of gGoodKeyframeCompositeValueTests) { 74 const effect = new KeyframeEffect(target, getKeyframes(composite)); 75 assert_equals(effect.getKeyframes()[0].composite, composite, 76 `resulting composite for '${composite}'`); 77 } 78 for (const composite of gBadKeyframeCompositeValueTests) { 79 assert_throws_js(TypeError, () => { 80 new KeyframeEffect(target, getKeyframes(composite)); 81 }); 82 } 83 }, 'composite values are parsed correctly when passed to the ' + 84 'KeyframeEffect constructor in regular keyframes'); 85 86 test(t => { 87 for (const composite of gGoodOptionsCompositeValueTests) { 88 const effect = new KeyframeEffect(target, { 89 left: ['10px', '20px'] 90 }, { composite }); 91 assert_equals(effect.getKeyframes()[0].composite, 'auto', 92 `resulting composite for '${composite}'`); 93 } 94 for (const composite of gBadOptionsCompositeValueTests) { 95 assert_throws_js(TypeError, () => { 96 new KeyframeEffect(target, { 97 left: ['10px', '20px'] 98 }, { composite: composite }); 99 }); 100 } 101 }, 'composite value is auto if the composite operation specified on the ' + 102 'keyframe effect is being used'); 103 104 for (const subtest of gKeyframesTests) { 105 test(t => { 106 const effect = new KeyframeEffect(target, subtest.input); 107 assert_frame_lists_equal(effect.getKeyframes(), subtest.output); 108 }, `A KeyframeEffect can be constructed with ${subtest.desc}`); 109 110 test(t => { 111 const effect = new KeyframeEffect(target, subtest.input); 112 const secondEffect = new KeyframeEffect(target, effect.getKeyframes()); 113 assert_frame_lists_equal(secondEffect.getKeyframes(), 114 effect.getKeyframes()); 115 }, `A KeyframeEffect constructed with ${subtest.desc} roundtrips`); 116 } 117 118 for (const subtest of gInvalidKeyframesTests) { 119 test(t => { 120 assert_throws_js(TypeError, () => { 121 new KeyframeEffect(target, subtest.input); 122 }); 123 }, `KeyframeEffect constructor throws with ${subtest.desc}`); 124 } 125 126 test(t => { 127 const effect = new KeyframeEffect(target, { left: ['10px', '20px'] }); 128 129 const timing = effect.getTiming(); 130 assert_equals(timing.delay, 0, 'default delay'); 131 assert_equals(timing.endDelay, 0, 'default endDelay'); 132 assert_equals(timing.fill, 'auto', 'default fill'); 133 assert_equals(timing.iterations, 1.0, 'default iterations'); 134 assert_equals(timing.iterationStart, 0.0, 'default iterationStart'); 135 assert_equals(timing.duration, 'auto', 'default duration'); 136 assert_equals(timing.direction, 'normal', 'default direction'); 137 assert_equals(timing.easing, 'linear', 'default easing'); 138 139 assert_equals(effect.composite, 'replace', 'default composite'); 140 assert_equals(effect.iterationComposite, 'replace', 141 'default iterationComposite'); 142 }, 'A KeyframeEffect constructed without any KeyframeEffectOptions object'); 143 144 for (const subtest of gKeyframeEffectOptionTests) { 145 test(t => { 146 const effect = new KeyframeEffect(target, { left: ['10px', '20px'] }, 147 subtest.input); 148 149 // Helper function to provide default expected values when the test does 150 // not supply them. 151 const expected = (field, defaultValue) => { 152 return field in subtest.expected ? subtest.expected[field] : defaultValue; 153 }; 154 155 const timing = effect.getTiming(); 156 assert_equals(timing.delay, expected('delay', 0), 157 'timing delay'); 158 assert_equals(timing.fill, expected('fill', 'auto'), 159 'timing fill'); 160 assert_equals(timing.iterations, expected('iterations', 1), 161 'timing iterations'); 162 assert_equals(timing.duration, expected('duration', 'auto'), 163 'timing duration'); 164 assert_equals(timing.direction, expected('direction', 'normal'), 165 'timing direction'); 166 167 }, `A KeyframeEffect constructed by ${subtest.desc}`); 168 } 169 170 for (const subtest of gInvalidKeyframeEffectOptionTests) { 171 test(t => { 172 assert_throws_js(TypeError, () => { 173 new KeyframeEffect(target, { left: ['10px', '20px'] }, subtest.input); 174 }); 175 }, `Invalid KeyframeEffect option by ${subtest.desc}`); 176 } 177 178 test(t => { 179 const effect = new KeyframeEffect(null, { left: ['10px', '20px'] }, 180 { duration: 100 * MS_PER_SEC, 181 fill: 'forwards' }); 182 assert_equals(effect.target, null, 183 'Effect created with null target has correct target'); 184 }, 'A KeyframeEffect constructed with null target'); 185 186 test(t => { 187 const test_error = { name: 'test' }; 188 189 assert_throws_exactly(test_error, () => { 190 new KeyframeEffect(target, { get left() { throw test_error }}) 191 }); 192 }, 'KeyframeEffect constructor propagates exceptions generated by accessing' 193 + ' the options object'); 194 </script> 195 </body>