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