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

Side by Side Diff: LayoutTests/animations/interpolation/resources/interpolation-test.js

Issue 1326443003: Web Animations: Enable additive animations in experimental (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Update missed tests Created 5 years, 3 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2015 Google Inc. All rights reserved. 2 * Copyright (C) 2015 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 24 matching lines...) Expand all
35 * The following functions are exported: 35 * The following functions are exported:
36 * - assertInterpolation({property, from, to, [method]}, [{at: fraction, is: va lue}]) 36 * - assertInterpolation({property, from, to, [method]}, [{at: fraction, is: va lue}])
37 * Constructs a test case for each fraction that asserts the expected val ue 37 * Constructs a test case for each fraction that asserts the expected val ue
38 * equals the value produced by interpolation between from and to using 38 * equals the value produced by interpolation between from and to using
39 * CSS Animations, CSS Transitions and Web Animations. If the method opti on is 39 * CSS Animations, CSS Transitions and Web Animations. If the method opti on is
40 * specified then only that interpolation method will be used. 40 * specified then only that interpolation method will be used.
41 * - assertNoInterpolation({property, from, to, [method]}) 41 * - assertNoInterpolation({property, from, to, [method]})
42 * This works in the same way as assertInterpolation with expectations au to 42 * This works in the same way as assertInterpolation with expectations au to
43 * generated according to each interpolation method's handling of values 43 * generated according to each interpolation method's handling of values
44 * that don't interpolate. 44 * that don't interpolate.
45 * - assertComposition({property, underlying, [addFrom], [addTo], [replaceFrom] , [replaceTo]}, [{at: fraction, is: value}])
46 * Similar to assertInterpolation() instead using only the Web Animations API
47 * to animate composite specified keyframes (add or replace) on top of
48 * an underlying value.
49 * Exactly one of (addFrom, replaceFrom) must be specified.
50 * Exactly one of (addTo, replaceTo) must be specified.
45 * - afterTest(callback) 51 * - afterTest(callback)
46 * Calls callback after all the tests have executed. 52 * Calls callback after all the tests have executed.
47 */ 53 */
48 'use strict'; 54 'use strict';
49 (function() { 55 (function() {
50 var interpolationTests = []; 56 var interpolationTests = [];
57 var compositionTests = [];
51 var cssAnimationsData = { 58 var cssAnimationsData = {
52 sharedStyle: null, 59 sharedStyle: null,
53 nextID: 0, 60 nextID: 0,
54 }; 61 };
55 var webAnimationsEnabled = typeof Element.prototype.animate === 'function'; 62 var webAnimationsEnabled = typeof Element.prototype.animate === 'function';
56 var expectNoInterpolation = {}; 63 var expectNoInterpolation = {};
57 var afterTestHook = function() {}; 64 var afterTestHook = function() {};
58 65
59 var cssAnimationsInterpolation = { 66 var cssAnimationsInterpolation = {
60 name: 'CSS Animations', 67 name: 'CSS Animations',
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 111
105 var webAnimationsInterpolation = { 112 var webAnimationsInterpolation = {
106 name: 'Web Animations', 113 name: 'Web Animations',
107 supportsProperty: function(property) {return property.indexOf('-webkit-') != = 0;}, 114 supportsProperty: function(property) {return property.indexOf('-webkit-') != = 0;},
108 supportsValue: function(value) {return value !== '';}, 115 supportsValue: function(value) {return value !== '';},
109 setup: function() {}, 116 setup: function() {},
110 nonInterpolationExpectations: function(from, to) { 117 nonInterpolationExpectations: function(from, to) {
111 return expectFlip(from, to, 0.5); 118 return expectFlip(from, to, 0.5);
112 }, 119 },
113 interpolate: function(property, from, to, at, target) { 120 interpolate: function(property, from, to, at, target) {
114 var keyframes = [{}, {}]; 121 this.interpolateKeyframes([
115 keyframes[0][property] = from; 122 {offset: 0, [property]: from},
116 keyframes[1][property] = to; 123 {offset: 1, [property]: to},
117 var player = target.animate(keyframes, { 124 ], at, target);
125 },
126 interpolateKeyframes: function(keyframes, at, target) {
127 target.animate(keyframes, {
118 fill: 'forwards', 128 fill: 'forwards',
119 duration: 1, 129 duration: 1,
120 easing: createEasing(at), 130 easing: createEasing(at),
121 delay: -0.5, 131 delay: -0.5,
122 iterations: 0.5, 132 iterations: 0.5,
123 }); 133 });
124 }, 134 },
125 rebaseline: false, 135 rebaseline: false,
126 }; 136 };
127 137
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 171
162 function loadScript(url) { 172 function loadScript(url) {
163 return new Promise(function(resolve) { 173 return new Promise(function(resolve) {
164 var script = document.createElement('script'); 174 var script = document.createElement('script');
165 script.src = url; 175 script.src = url;
166 script.onload = resolve; 176 script.onload = resolve;
167 document.head.appendChild(script); 177 document.head.appendChild(script);
168 }); 178 });
169 } 179 }
170 180
171 function createTargetContainer(parent) { 181 function createTargetContainer(parent, className) {
172 var targetContainer = createElement(parent); 182 var targetContainer = createElement(parent);
173 targetContainer.classList.add('container'); 183 targetContainer.classList.add('container');
174 var template = document.querySelector('#target-template'); 184 var template = document.querySelector('#target-template');
175 if (template) { 185 if (template) {
176 targetContainer.appendChild(template.content.cloneNode(true)); 186 targetContainer.appendChild(template.content.cloneNode(true));
177 } 187 }
178 var target = targetContainer.querySelector('.target') || targetContainer; 188 var target = targetContainer.querySelector('.target') || targetContainer;
179 target.classList.add('target'); 189 target.classList.add('target', className);
180 target.parentElement.classList.add('parent'); 190 target.parentElement.classList.add('parent');
181 targetContainer.target = target; 191 targetContainer.target = target;
182 return targetContainer; 192 return targetContainer;
183 } 193 }
184 194
185 function roundNumbers(value) { 195 function roundNumbers(value) {
186 return value. 196 return value.
187 // Round numbers to two decimal places. 197 // Round numbers to two decimal places.
188 replace(/-?\d*\.\d+(e-?\d+)?/g, function(n) { 198 replace(/-?\d*\.\d+(e-?\d+)?/g, function(n) {
189 return (parseFloat(n).toFixed(2)). 199 return (parseFloat(n).toFixed(2)).
(...skipping 30 matching lines...) Expand all
220 assertInterpolation(options, expectNoInterpolation); 230 assertInterpolation(options, expectNoInterpolation);
221 } 231 }
222 232
223 function assertInterpolation(options, expectations) { 233 function assertInterpolation(options, expectations) {
224 if (options.from) { 234 if (options.from) {
225 console.assert(CSS.supports(options.property, options.from)); 235 console.assert(CSS.supports(options.property, options.from));
226 } 236 }
227 if (options.to) { 237 if (options.to) {
228 console.assert(CSS.supports(options.property, options.to)); 238 console.assert(CSS.supports(options.property, options.to));
229 } 239 }
230 interpolationTests.push({ 240 interpolationTests.push({options, expectations});
231 options: options,
232 expectations: expectations,
233 });
234 } 241 }
235 242
236 function createTestTargets(interpolationMethods, interpolationTests, container , rebaselineContainer) { 243 function assertComposition(options, expectations) {
237 var targets = []; 244 compositionTests.push({options, expectations});
238 interpolationMethods.forEach(function(interpolationMethod, interpolationMeth odIndex) { 245 }
239 var methodContainer = createElement(container); 246
240 interpolationTests.forEach(function(interpolationTest) { 247 function createInterpolationTestTargets(interpolationMethod, interpolationMeth odContainer, interpolationTest, rebaselineContainer) {
241 var property = interpolationTest.options.property; 248 var property = interpolationTest.options.property;
242 var from = interpolationTest.options.from; 249 var from = interpolationTest.options.from;
243 var to = interpolationTest.options.to; 250 var to = interpolationTest.options.to;
244 if ((interpolationTest.options.method && interpolationTest.options.metho d != interpolationMethod.name) 251 if ((interpolationTest.options.method && interpolationTest.options.method != interpolationMethod.name)
245 || !interpolationMethod.supportsProperty(property) 252 || !interpolationMethod.supportsProperty(property)
246 || !interpolationMethod.supportsValue(from) 253 || !interpolationMethod.supportsValue(from)
247 || !interpolationMethod.supportsValue(to)) { 254 || !interpolationMethod.supportsValue(to)) {
248 return; 255 return;
249 } 256 }
250 if (interpolationMethod.rebaseline) { 257 if (interpolationMethod.rebaseline) {
251 var rebaseline = createElement(rebaselineContainer, 'pre'); 258 var rebaseline = createElement(rebaselineContainer, 'pre');
252 rebaseline.appendChild(document.createTextNode(`\ 259 rebaseline.appendChild(document.createTextNode(`\
253 assertInterpolation({ 260 assertInterpolation({
254 property: '${property}', 261 property: '${property}',
255 from: '${from}', 262 from: '${from}',
256 to: '${to}', 263 to: '${to}',
257 }, [\n`)); 264 }, [\n`));
258 var rebaselineExpectation; 265 var rebaselineExpectation;
259 rebaseline.appendChild(rebaselineExpectation = document.createTextNode ('')); 266 rebaseline.appendChild(rebaselineExpectation = document.createTextNode('') );
260 rebaseline.appendChild(document.createTextNode(']);\n\n')); 267 rebaseline.appendChild(document.createTextNode(']);\n\n'));
268 }
269 var testText = `${interpolationMethod.name}: property <${property}> from [${ from}] to [${to}]`;
270 var testContainer = createElement(interpolationMethodContainer, 'div', testT ext);
271 createElement(testContainer, 'br');
272 var expectations = interpolationTest.expectations;
273 if (expectations === expectNoInterpolation) {
274 expectations = interpolationMethod.nonInterpolationExpectations(from, to);
275 }
276 return expectations.map(function(expectation) {
277 var actualTargetContainer = createTargetContainer(testContainer, 'actual') ;
278 var expectedTargetContainer = createTargetContainer(testContainer, 'expect ed');
279 expectedTargetContainer.target.style[property] = expectation.is;
280 var target = actualTargetContainer.target;
281 interpolationMethod.setup(property, from, target);
282 target.interpolate = function() {
283 interpolationMethod.interpolate(property, from, to, expectation.at, targ et);
284 };
285 target.measure = function() {
286 var actualValue = getComputedStyle(target)[property];
287 test(function() {
288 assert_equals(
289 normalizeValue(actualValue),
290 normalizeValue(getComputedStyle(expectedTargetContainer.target)[prop erty]));
291 }, `${testText} at (${expectation.at}) is [${sanitizeUrls(actualValue)}] `);
292 if (rebaselineExpectation) {
293 rebaselineExpectation.textContent += ` {at: ${expectation.at}, is: '$ {actualValue}'},\n`;
261 } 294 }
262 var testText = interpolationMethod.name + ': property <' + property + '> from [' + from + '] to [' + to + ']'; 295 };
263 var testContainer = createElement(methodContainer, 'div', testText); 296 return target;
264 createElement(testContainer, 'br'); 297 });
265 var expectations = interpolationTest.expectations; 298 }
266 if (expectations === expectNoInterpolation) { 299
267 expectations = interpolationMethod.nonInterpolationExpectations(from, to); 300 function createCompositionTestTargets(compositionContainer, compositionTest, r ebaselineContainer) {
301 var options = compositionTest.options;
302 console.assert('addFrom' in options !== 'replaceFrom' in options);
303 console.assert('addTo' in options !== 'replaceTo' in options);
304 var property = options.property;
305 var underlying = options.underlying;
306 var from = options.addFrom || options.replaceFrom;
307 var to = options.addTo || options.replaceTo;
308 var fromComposite = 'addFrom' in options ? 'add' : 'replace';
309 var toComposite = 'addTo' in options ? 'add' : 'replace';
310 if (webAnimationsInterpolation.rebaseline) {
311 var rebaseline = createElement(rebaselineContainer, 'pre');
312 rebaseline.appendChild(document.createTextNode(`\
313 assertComposition({
314 property: '${property}',
315 underlying: '${underlying}',
316 ${fromComposite}From: '${from}',
317 ${toComposite}To: '${to}',
318 }, [\n`));
319 var rebaselineExpectation;
320 rebaseline.appendChild(rebaselineExpectation = document.createTextNode('') );
321 rebaseline.appendChild(document.createTextNode(']);\n\n'));
322 }
323 var testText = `Compositing: property <${property}> underlying [${underlying }] from ${fromComposite} [${from}] to ${toComposite} [${to}]`;
324 var testContainer = createElement(compositionContainer, 'div', testText);
325 createElement(testContainer, 'br');
326 return compositionTest.expectations.map(function(expectation) {
327 var actualTargetContainer = createTargetContainer(testContainer, 'actual') ;
328 var expectedTargetContainer = createTargetContainer(testContainer, 'expect ed');
329 expectedTargetContainer.target.style[property] = expectation.is;
330 var target = actualTargetContainer.target;
331 target.style[property] = underlying;
332 target.interpolate = function() {
333 webAnimationsInterpolation.interpolateKeyframes([{
334 offset: 0,
335 composite: fromComposite,
336 [property]: from,
337 }, {
338 offset: 1,
339 composite: toComposite,
340 [property]: to,
341 }], expectation.at, target);
342 };
343 target.measure = function() {
344 var actualValue = getComputedStyle(target)[property];
345 test(function() {
346 assert_equals(
347 normalizeValue(actualValue),
348 normalizeValue(getComputedStyle(expectedTargetContainer.target)[prop erty]));
349 }, `${testText} at (${expectation.at}) is [${sanitizeUrls(actualValue)}] `);
350 if (rebaselineExpectation) {
351 rebaselineExpectation.textContent += ` {at: ${expectation.at}, is: '$ {actualValue}'},\n`;
268 } 352 }
269 expectations.forEach(function(expectation) { 353 };
270 var actualTargetContainer = createTargetContainer(testContainer); 354 return target;
271 var expectedTargetContainer = createTargetContainer(testContainer);
272 expectedTargetContainer.target.classList.add('expected');
273 expectedTargetContainer.target.style[property] = expectation.is;
274 var target = actualTargetContainer.target;
275 target.classList.add('actual');
276 interpolationMethod.setup(property, from, target);
277 target.interpolate = function() {
278 interpolationMethod.interpolate(property, from, to, expectation.at, target);
279 };
280 target.measure = function() {
281 var actualValue = getComputedStyle(target)[property];
282 test(function() {
283 assert_equals(
284 normalizeValue(actualValue),
285 normalizeValue(getComputedStyle(expectedTargetContainer.target)[ property]));
286 }, testText + ' at (' + expectation.at + ') is [' + sanitizeUrls(act ualValue) + ']');
287 if (interpolationMethod.rebaseline) {
288 rebaselineExpectation.textContent += ` {at: ${expectation.at}, is : '${actualValue}'},\n`;
289 }
290 };
291 targets.push(target);
292 });
293 });
294 }); 355 });
356 }
357
358 function createTestTargets(interpolationMethods, interpolationTests, compositi onTests, container, rebaselineContainer) {
359 var targets = [];
360 for (var interpolationMethod of interpolationMethods) {
361 var interpolationMethodContainer = createElement(container);
362 for (var interpolationTest of interpolationTests) {
363 [].push.apply(targets, createInterpolationTestTargets(interpolationMetho d, interpolationMethodContainer, interpolationTest, rebaselineContainer));
364 }
365 }
366 var compositionContainer = createElement(container);
367 for (var compositionTest of compositionTests) {
368 [].push.apply(targets, createCompositionTestTargets(compositionContainer, compositionTest, rebaselineContainer));
369 }
295 return targets; 370 return targets;
296 } 371 }
297 372
298 function runInterpolationTests() { 373 function runTests() {
299 var interpolationMethods = [ 374 var interpolationMethods = [
300 cssTransitionsInterpolation, 375 cssTransitionsInterpolation,
301 cssAnimationsInterpolation, 376 cssAnimationsInterpolation,
302 ]; 377 ];
303 if (webAnimationsEnabled) { 378 if (webAnimationsEnabled) {
304 interpolationMethods.push(webAnimationsInterpolation); 379 interpolationMethods.push(webAnimationsInterpolation);
305 } 380 }
306 var rebaselineContainer = createElement(document.body); 381 var rebaselineContainer = createElement(document.body);
307 var container = createElement(document.body); 382 var container = createElement(document.body);
308 var targets = createTestTargets(interpolationMethods, interpolationTests, co ntainer, rebaselineContainer); 383 var targets = createTestTargets(interpolationMethods, interpolationTests, co mpositionTests, container, rebaselineContainer);
309 getComputedStyle(document.documentElement).left; // Force a style recalc for transitions. 384 getComputedStyle(document.documentElement).left; // Force a style recalc for transitions.
310 // Separate interpolation and measurement into different phases to avoid O(n ^2) of the number of targets. 385 // Separate interpolation and measurement into different phases to avoid O(n ^2) of the number of targets.
311 for (var target of targets) { 386 for (var target of targets) {
312 target.interpolate(); 387 target.interpolate();
313 } 388 }
314 for (var target of targets) { 389 for (var target of targets) {
315 target.measure(); 390 target.measure();
316 } 391 }
317 if (window.testRunner) { 392 if (window.testRunner) {
318 container.remove(); 393 container.remove();
319 } 394 }
320 afterTestHook(); 395 afterTestHook();
321 } 396 }
322 397
323 function afterTest(f) { 398 function afterTest(f) {
324 afterTestHook = f; 399 afterTestHook = f;
325 } 400 }
326 401
327 window.assertInterpolation = assertInterpolation; 402 window.assertInterpolation = assertInterpolation;
328 window.assertNoInterpolation = assertNoInterpolation; 403 window.assertNoInterpolation = assertNoInterpolation;
404 window.assertComposition = assertComposition;
329 window.afterTest = afterTest; 405 window.afterTest = afterTest;
330 406
331 loadScript('../../resources/testharness.js').then(function() { 407 loadScript('../../resources/testharness.js').then(function() {
332 return loadScript('../../resources/testharnessreport.js'); 408 return loadScript('../../resources/testharnessreport.js');
333 }).then(function() { 409 }).then(function() {
334 var asyncHandle = async_test('This test uses interpolation-test.js.') 410 var asyncHandle = async_test('This test uses interpolation-test.js.')
335 requestAnimationFrame(function() { 411 requestAnimationFrame(function() {
336 runInterpolationTests(); 412 runTests();
337 asyncHandle.done() 413 asyncHandle.done()
338 }); 414 });
339 }); 415 });
340 })(); 416 })();
OLDNEW
« no previous file with comments | « LayoutTests/animations/composition/left-composition.html ('k') | LayoutTests/fast/inline/inline-marquee-crash-expected.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698