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

Side by Side Diff: third_party/WebKit/LayoutTests/animations/responsive/resources/responsive-test.js

Issue 1450123003: Add SVG animation support to responsive-test.js (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@_responsiveNeutralValueFormat
Patch Set: Rebased Created 5 years, 1 month 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /* 5 /*
6 Exported function: 6 Exported functions:
7 assertResponsive 7 assertCSSResponsive
8 assertSVGResponsive
8 9
9 Call signature: 10 Options format: {
10 assertResponsive({ 11 ?targetTag: <Target element tag name>,
11 property: <CSS Property>, 12 property: <Property/Attribute name>,
12 ?from: <CSS Value>, 13 ?getter(target): <Reads animated value from target>,
13 ?to: <CSS Value>, 14 ?from: <Value>,
15 ?to: <Value>,
14 configurations: [{ 16 configurations: [{
15 state: { 17 state: {
16 ?underlying: <CSS Value>, 18 ?underlying: <Value>,
17 ?inherited: <CSS Value>, 19 ?inherited: <CSS Value>,
18 }, 20 },
19 expect: [ 21 expect: [
20 { at: <Float>, is: <CSS Value> } 22 { at: <Float>, is: <Value> },
21 ], 23 ],
22 }], 24 }],
23 }) 25 }
24 26
25 Description: 27 Description:
26 assertResponsive takes a property specific interpolation and a list of style 28 assertCSSResponsive() and assertSVGResponsive() take a property
27 configurations with interpolation expectations that apply to each 29 specific interpolation and a list of style configurations with interpolation
28 configuration. 30 expectations that apply to each configuration.
29 It starts the interpolation in every configuration, changes the 31 It starts the interpolation in every configuration, changes the
30 state to every other configuration (n * (n - 1) complexity) and asserts that 32 state to every other configuration (n * (n - 1) complexity) and asserts that
31 each destination configuration's expectations are met. 33 each destination configuration's expectations are met.
32 Each animation target can be assigned custom styles via the ".target" selector. 34 Each animation target can be assigned custom styles via the ".target" selector.
33 This test is designed to catch stale interpolation caches. 35 This test is designed to catch stale interpolation caches.
34 */ 36 */
35 37
36 (function() { 38 (function() {
37 'use strict'; 39 'use strict';
38 var pendingResponsiveTests = []; 40 var pendingResponsiveTests = [];
41 var htmlNamespace = 'http://www.w3.org/1999/xhtml';
42 var svgNamespace = 'http://www.w3.org/2000/svg';
39 43
40 function assertResponsive(options) { 44 function assertCSSResponsive(options) {
41 pendingResponsiveTests.push(options); 45 pendingResponsiveTests.push({
46 options,
47 bindings: {
48 prefixProperty(property) {
49 return property;
50 },
51 createTargetContainer(container) {
52 return createElement('div', container);
53 },
54 createTarget(container) {
55 return createElement('div', container, 'target');
56 },
57 setValue(target, property, value) {
58 target.style[property] = value;
59 },
60 getAnimatedValue(target, property) {
61 return getComputedStyle(target)[property];
62 },
63 },
64 });
65 }
66
67 function assertSVGResponsive(options) {
68 pendingResponsiveTests.push({
69 options,
dstockwell 2015/11/17 22:13:02 might help to validate that everything necessary i
alancutter (OOO until 2018) 2015/11/17 22:35:09 Added assert.
70 bindings: {
71 prefixProperty(property) {
72 return 'svg' + property[0].toUpperCase() + property.slice(1);
73 },
74 createTargetContainer(container) {
75 var svgRoot = createElement('svg', container, 'svg-root', svgNamespace);
76 svgRoot.setAttribute('width', 0);
77 svgRoot.setAttribute('height', 0);
78 return svgRoot;
79 },
80 createTarget(targetContainer) {
81 return createElement(options.targetTag, targetContainer, 'target', svgNa mespace);
82 },
83 setValue(target, property, value) {
84 target.setAttribute(property, value);
85 },
86 getAnimatedValue(target, property) {
87 return options.getter ? options.getter(target) : target[property].animVa l;
88 },
89 },
90 });
42 } 91 }
43 92
44 function createStateTransitions(configurations) { 93 function createStateTransitions(configurations) {
45 var stateTransitions = []; 94 var stateTransitions = [];
46 for (var i = 0; i < configurations.length; i++) { 95 for (var i = 0; i < configurations.length; i++) {
47 var beforeConfiguration = configurations[i]; 96 var beforeConfiguration = configurations[i];
48 for (var j = 0; j < configurations.length; j++) { 97 for (var j = 0; j < configurations.length; j++) {
49 var afterConfiguration = configurations[j]; 98 var afterConfiguration = configurations[j];
50 if (j != i) { 99 if (j != i) {
51 stateTransitions.push({ 100 stateTransitions.push({
52 before: beforeConfiguration, 101 before: beforeConfiguration,
53 after: afterConfiguration, 102 after: afterConfiguration,
54 }); 103 });
55 } 104 }
56 } 105 }
57 } 106 }
58 return stateTransitions; 107 return stateTransitions;
59 } 108 }
60 109
61 function createElement(tag, container, className) { 110 function createElement(tag, container, className, namespace) {
62 var element = document.createElement(tag); 111 var element = document.createElementNS(namespace || htmlNamespace, tag);
63 if (container) { 112 if (container) {
64 container.appendChild(element); 113 container.appendChild(element);
65 } 114 }
66 if (className) { 115 if (className) {
67 element.classList.add(className); 116 element.classList.add(className);
68 } 117 }
69 return element; 118 return element;
70 } 119 }
71 120
72 function createTargets(n, container) { 121 function createTargets(bindings, n, container) {
73 var targets = []; 122 var targets = [];
74 for (var i = 0; i < n; i++) { 123 for (var i = 0; i < n; i++) {
75 targets.push(createElement('div', container, 'target')); 124 targets.push(bindings.createTarget(container));
76 } 125 }
77 return targets; 126 return targets;
78 } 127 }
79 128
80 function setState(targets, property, state) { 129 function setState(bindings, targets, property, state) {
81 if (state.inherited) { 130 if (state.inherited) {
82 var parent = targets[0].parentElement; 131 var parent = targets[0].parentElement;
83 console.assert(targets.every(function(target) { return target.parentElement === parent; })); 132 console.assert(targets.every(function(target) { return target.parentElement === parent; }));
84 parent.style[property] = state.inherited; 133 bindings.setValue(parent, property, state.inherited);
85 } 134 }
86 if (state.underlying) { 135 if (state.underlying) {
87 for (var target of targets) { 136 for (var target of targets) {
88 target.style[property] = state.underlying; 137 bindings.setValue(target, property, state.underlying);
89 } 138 }
90 } 139 }
91 } 140 }
92 141
93 function keyframeText(options, keyframeName) { 142 function keyframeText(options, keyframeName) {
94 return (keyframeName in options) ? `[${options[keyframeName]}]` : 'neutral'; 143 return (keyframeName in options) ? `[${options[keyframeName]}]` : 'neutral';
95 } 144 }
96 145
97 function createKeyframes(options) { 146 function createKeyframes(prefixedProperty, options) {
98 var keyframes = []; 147 var keyframes = [];
99 if ('from' in options) { 148 if ('from' in options) {
100 keyframes.push({ 149 keyframes.push({
101 offset: 0, 150 offset: 0,
102 [options.property]: options.from, 151 [prefixedProperty]: options.from,
103 }); 152 });
104 } 153 }
105 if ('to' in options) { 154 if ('to' in options) {
106 keyframes.push({ 155 keyframes.push({
107 offset: 1, 156 offset: 1,
108 [options.property]: options.to, 157 [prefixedProperty]: options.to,
109 }); 158 });
110 } 159 }
111 return keyframes; 160 return keyframes;
112 } 161 }
113 162
114 function startPausedAnimations(targets, keyframes, fractions) { 163 function startPausedAnimations(targets, keyframes, fractions) {
115 console.assert(targets.length == fractions.length); 164 console.assert(targets.length == fractions.length);
116 for (var i = 0; i < targets.length; i++) { 165 for (var i = 0; i < targets.length; i++) {
117 var target = targets[i]; 166 var target = targets[i];
118 var fraction = fractions[i]; 167 var fraction = fractions[i];
119 console.assert(fraction >= 0 && fraction < 1); 168 console.assert(fraction >= 0 && fraction < 1);
120 var animation = target.animate(keyframes, 1); 169 var animation = target.animate(keyframes, 1);
121 animation.currentTime = fraction; 170 animation.currentTime = fraction;
122 animation.pause(); 171 animation.pause();
123 } 172 }
124 } 173 }
125 174
126 function runPendingResponsiveTests() { 175 function runPendingResponsiveTests() {
127 var stateTransitionTests = []; 176 return new Promise(function(resolve) {
128 pendingResponsiveTests.forEach(function(options) { 177 var stateTransitionTests = [];
129 var property = options.property; 178 pendingResponsiveTests.forEach(function(responsiveTest) {
130 var from = options.from; 179 var options = responsiveTest.options;
131 var to = options.to; 180 var bindings = responsiveTest.bindings;
132 var keyframes = createKeyframes(options); 181 var property = options.property;
133 var fromText = keyframeText(options, 'from'); 182 var prefixedProperty = bindings.prefixProperty(property);
134 var toText = keyframeText(options, 'to'); 183 var from = options.from;
184 var to = options.to;
185 var keyframes = createKeyframes(prefixedProperty, options);
186 var fromText = keyframeText(options, 'from');
187 var toText = keyframeText(options, 'to');
135 188
136 var stateTransitions = createStateTransitions(options.configurations); 189 var stateTransitions = createStateTransitions(options.configurations);
137 stateTransitions.forEach(function(stateTransition) { 190 stateTransitions.forEach(function(stateTransition) {
138 var before = stateTransition.before; 191 var before = stateTransition.before;
139 var after = stateTransition.after; 192 var after = stateTransition.after;
140 var container = createElement('div', document.body); 193 var container = bindings.createTargetContainer(document.body);
141 var targets = createTargets(after.expect.length, container); 194 var targets = createTargets(bindings, after.expect.length, container);
142 195
143 setState(targets, property, before.state); 196 setState(bindings, targets, property, before.state);
144 startPausedAnimations(targets, keyframes, after.expect.map(function(expect ation) { return expectation.at; })); 197 startPausedAnimations(targets, keyframes, after.expect.map(function(expe ctation) { return expectation.at; }));
145 stateTransitionTests.push({ 198 stateTransitionTests.push({
146 applyStateTransition() { 199 applyStateTransition() {
147 setState(targets, property, after.state); 200 setState(bindings, targets, property, after.state);
148 }, 201 },
149 assert() { 202 assert() {
150 for (var i = 0; i < targets.length; i++) { 203 for (var i = 0; i < targets.length; i++) {
151 var target = targets[i]; 204 var target = targets[i];
152 var expectation = after.expect[i]; 205 var expectation = after.expect[i];
153 var actual = getComputedStyle(target)[property]; 206 var actual = bindings.getAnimatedValue(target, property);
154 test(function() { 207 test(function() {
155 assert_equals(actual, expectation.is); 208 assert_equals(actual, expectation.is);
156 }, `Animation on property <${property}> from ${fromText} to ${toText } with ${JSON.stringify(before.state)} changed to ${JSON.stringify(after.state)} at (${expectation.at}) is [${expectation.is}]`); 209 }, `Animation on property <${prefixedProperty}> from ${fromText} t o ${toText} with ${JSON.stringify(before.state)} changed to ${JSON.stringify(aft er.state)} at (${expectation.at}) is [${expectation.is}]`);
157 } 210 }
158 }, 211 },
212 });
159 }); 213 });
160 }); 214 });
215
216 for (var stateTransitionTest of stateTransitionTests) {
217 stateTransitionTest.applyStateTransition();
218 }
219
220 requestAnimationFrame(function() {
221 for (var stateTransitionTest of stateTransitionTests) {
222 stateTransitionTest.assert();
223 }
224 resolve();
225 });
161 }); 226 });
162
163 // Separate style modification from measurement as different phases to avoid a style recalc storm.
164 for (var stateTransitionTest of stateTransitionTests) {
165 stateTransitionTest.applyStateTransition();
166 }
167 for (var stateTransitionTest of stateTransitionTests) {
168 stateTransitionTest.assert();
169 }
170 } 227 }
171 228
172 function loadScript(url) { 229 function loadScript(url) {
173 return new Promise(function(resolve) { 230 return new Promise(function(resolve) {
174 var script = document.createElement('script'); 231 var script = document.createElement('script');
175 script.src = url; 232 script.src = url;
176 script.onload = resolve; 233 script.onload = resolve;
177 document.head.appendChild(script); 234 document.head.appendChild(script);
178 }); 235 });
179 } 236 }
180 237
181 loadScript('../../resources/testharness.js').then(function() { 238 loadScript('../../resources/testharness.js').then(function() {
182 return loadScript('../../resources/testharnessreport.js'); 239 return loadScript('../../resources/testharnessreport.js');
183 }).then(function() { 240 }).then(function() {
184 var asyncHandle = async_test('This test uses responsive-test.js.') 241 var asyncHandle = async_test('This test uses responsive-test.js.')
185 requestAnimationFrame(function() { 242 runPendingResponsiveTests().then(function() {
186 runPendingResponsiveTests(); 243 asyncHandle.done();
187 asyncHandle.done()
188 }); 244 });
189 }); 245 });
190 246
191 247
192 window.assertResponsive = assertResponsive; 248 window.assertCSSResponsive = assertCSSResponsive;
249 window.assertSVGResponsive = assertSVGResponsive;
193 250
194 })(); 251 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698