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

Unified Diff: third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js

Issue 1410943004: Make SVG attribute interpolation test helper use testharness (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@_cleanUpSVGInterpolationTestHelper
Patch Set: Rebased Created 5 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/svg-amplitude-interpolation-expected.txt » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js b/third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js
index 2e094ebdfc648140e366d87a7abce110a7d5a3c6..8cdfa8287feedcd95fb17fc634a0d2a9594315e3 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js
@@ -1,68 +1,23 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
+/* Copyright 2015 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Exported function:
+ * - assertAttributeInterpolation({property, from, to}, [{at: fraction, is: value}])
+ * Constructs a test case for each fraction that asserts the expected value
+ * equals the value produced by interpolation between from and to using
+ * SMIL and Web Animations.
+*/
'use strict';
-(function() {
- var testCount = 0;
- var animationEventCount = 0;
-
- var durationSeconds = 0.001;
- var iterationCount = 0.5;
- var delaySeconds = 0;
- var fragment = document.createDocumentFragment();
- var fragmentAttachedListeners = [];
- var style = document.createElement('style');
- fragment.appendChild(style);
-
- var smilTestsDiv = document.createElement('div');
- smilTestsDiv.id = 'smil-tests';
- smilTestsDiv.textContent = 'SVG SMIL:';
- fragment.appendChild(smilTestsDiv);
-
- var waTestsDiv = document.createElement('div');
- waTestsDiv.id = 'web-animations-tests';
- waTestsDiv.textContent = 'Web Animations API:';
- fragment.appendChild(waTestsDiv);
-
- var updateScheduled = false;
- function maybeScheduleUpdate() {
- if (updateScheduled) {
- return;
- }
- updateScheduled = true;
- setTimeout(function() {
- updateScheduled = false;
- document.body.appendChild(fragment);
- requestAnimationFrame(function () {
- fragmentAttachedListeners.forEach(function(listener) {listener();});
- });
- }, 0);
- }
+(() => {
+ var interpolationTests = [];
- function smilResults() {
- var result = '\nSVG SMIL:\n';
- var targets = document.querySelectorAll('.target.smil');
- for (var i = 0; i < targets.length; i++) {
- result += targets[i].getResultString() + '\n';
+ function createElement(tagName, container) {
+ var element = document.createElement(tagName);
+ if (container) {
+ container.appendChild(element);
}
- return result;
- }
-
- function waResults() {
- var result = '\nWeb Animations API:\n';
- var targets = document.querySelectorAll('.target.web-animations');
- for (var i = 0; i < targets.length; i++) {
- result += targets[i].getResultString() + '\n';
- }
- return result;
- }
-
- function dumpResults() {
- var results = document.createElement('pre');
- results.id = 'results';
- results.textContent = smilResults() + waResults();
- document.body.appendChild(results);
+ return element;
}
// Constructs a timing function which produces 'y' at x = 0.5
@@ -83,53 +38,10 @@
return 'cubic-bezier(0, ' + b + ', 1, ' + b + ')';
}
- function createTestContainer(description, className) {
- var testContainer = document.createElement('div');
- testContainer.setAttribute('description', description);
- testContainer.classList.add('test');
- if (className) {
- testContainer.classList.add(className);
- }
- return testContainer;
- }
-
- function convertPropertyToCamelCase(property) {
- return property.replace(/^-/, '').replace(/-\w/g, function(m) {return m[1].toUpperCase();});
- }
-
- function describeSMILTest(params) {
- return '<animate /> ' + convertPropertyToCamelCase(params.property) + ': from [' + params.from + '] to [' + params.to + ']';
- }
-
- function describeWATest(params) {
- return 'element.animate() ' + convertPropertyToCamelCase(params.property) + ': from [' + params.from + '] to [' + params.to + ']';
- }
-
- var nextTestId = 0;
function assertAttributeInterpolation(params, expectations) {
- var testId = 'test-' + ++nextTestId;
- var nextCaseId = 0;
-
- var smilTestContainer = createTestContainer(describeSMILTest(params), testId);
- smilTestsDiv.appendChild(smilTestContainer);
- expectations.forEach(function(expectation) {
- if (expectation.at < 0 || expectation.at > 1)
- return;
- smilTestContainer.appendChild(makeInterpolationTest(
- 'smil', expectation.at, testId, 'case-' + ++nextCaseId, params, expectation.is));
- });
-
- var waTestContainer = createTestContainer(describeWATest(params), testId);
- waTestsDiv.appendChild(waTestContainer);
- expectations.forEach(function(expectation) {
- waTestContainer.appendChild(makeInterpolationTest(
- 'web-animations', expectation.at, testId, 'case-' + ++nextCaseId, params, expectation.is));
- });
-
- maybeScheduleUpdate();
+ interpolationTests.push({params, expectations});
}
-
function roundNumbers(value) {
return value.
// Round numbers to two decimal places.
@@ -150,8 +62,8 @@
replace(/\s+/g, ' ');
}
- function createTargetContainer(id) {
- var targetContainer = document.createElement('div');
+ function createTarget(container) {
+ var targetContainer = createElement('div');
var template = document.querySelector('#target-template');
if (template) {
targetContainer.appendChild(template.content.cloneNode(true));
@@ -165,21 +77,20 @@
// If the template contains just one element, use that rather than a wrapper div.
if (targetContainer.children.length == 1 && targetContainer.childNodes.length == 1) {
targetContainer = targetContainer.firstChild;
- targetContainer.remove();
}
+ container.appendChild(targetContainer);
}
var target = targetContainer.querySelector('.target') || targetContainer;
- target.classList.add('target');
- target.classList.add(id);
- return targetContainer;
+ target.container = targetContainer;
+ return target;
}
+ var anchor = createElement('a');
function sanitizeUrls(value) {
var matches = value.match(/url\([^\)]*\)/g);
if (matches !== null) {
for (var i = 0; i < matches.length; ++i) {
var url = /url\(([^\)]*)\)/g.exec(matches[i])[1];
- var anchor = document.createElement('a');
anchor.href = url;
anchor.pathname = '...' + anchor.pathname.substring(anchor.pathname.lastIndexOf('/'));
value = value.replace(matches[i], 'url(' + anchor.href + ')');
@@ -254,7 +165,7 @@
}
function getAttributeValue(element, attributeName) {
- if (animatedNumberOptionalNumberAttributes.indexOf(attributeName) !== -1)
+ if (animatedNumberOptionalNumberAttributes.includes(attributeName))
return getAttributeValue(element, attributeName + 'X') + ', ' + getAttributeValue(element, attributeName + 'Y');
// The attribute 'class' is exposed in IDL as 'className'
@@ -286,7 +197,7 @@
if (attributeName === 'preserveAlpha')
return 'false';
- console.log('Unknown attribute, cannot get ' + element.className.baseVal + ' ' + attributeName);
+ console.error('Unknown attribute, cannot get ' + attributeName);
return null;
}
@@ -306,7 +217,7 @@
result = serializeSVGTransformList(result);
if (typeof result !== 'string' && typeof result !== 'number' && typeof result !== 'boolean') {
- console.log('Attribute value has unexpected type: ' + result);
+ console.error('Attribute value has unexpected type: ' + result);
}
return String(result);
@@ -319,15 +230,10 @@
&& (attributeName !== 'in' || !element['in1'])
&& (attributeName !== 'orient' || !element['orientType'])
&& (animatedNumberOptionalNumberAttributes.indexOf(attributeName) === -1 || !element[attributeName + 'X'])) {
- console.log('Unknown attribute, cannot set ' + element.className.baseVal + ' ' + attributeName);
+ console.error('Unknown attribute, cannot set ' + attributeName);
return;
}
- if (attributeName === 'class') {
- // Preserve the existing classes as we use them to select elements.
- expectation = element['className'].baseVal + ' ' + expectation;
- }
-
if (attributeName.toLowerCase().indexOf('transform') === -1) {
var setElement = document.createElementNS(svgNamespace, 'set');
setElement.setAttribute('attributeName', namespacedAttributeName(attributeName));
@@ -339,196 +245,156 @@
}
}
- function makeKeyframes(target, attributeName, params) {
- // Replace 'transform' with 'svgTransform', etc. This avoids collisions with CSS properties or the Web Animations API (offset).
- attributeName = 'svg' + attributeName[0].toUpperCase() + attributeName.slice(1);
+ function createAnimateElement(attributeName, from, to)
+ {
+ var animateElement;
+ if (attributeName.toLowerCase().includes('transform')) {
+ from = from.split(')');
+ to = to.split(')');
+ // Discard empty string at end.
+ from.pop();
+ to.pop();
+
+ // SMIL requires separate animateTransform elements for each transform in the list.
+ if (from.length !== 1 || to.length !== 1) {
+ return null;
+ }
- var keyframes = [{}, {}];
- if (attributeName === 'svgClass') {
- // Preserve the existing classes as we use them to select elements.
- keyframes[0][attributeName] = target['className'].baseVal + ' ' + params.from;
- keyframes[1][attributeName] = target['className'].baseVal + ' ' + params.to;
- } else {
- keyframes[0][attributeName] = params.from;
- keyframes[1][attributeName] = params.to;
- }
- return keyframes;
- }
+ from = from[0].split('(');
+ to = to[0].split('(');
+ if (from[0].trim() !== to[0].trim()) {
+ return null;
+ }
- function appendAnimate(target, attributeName, from, to)
- {
- var animateElement = document.createElementNS(svgNamespace, 'animate');
- animateElement.setAttribute('attributeName', namespacedAttributeName(attributeName));
- animateElement.setAttribute('attributeType', 'XML');
- if (attributeName === 'class') {
- // Preserve the existing classes as we use them to select elements.
- animateElement.setAttribute('from', target['className'].baseVal + ' ' + from);
- animateElement.setAttribute('to', target['className'].baseVal + ' ' + to);
+ animateElement = document.createElementNS(svgNamespace, 'animateTransform');
+ animateElement.setAttribute('type', from[0].trim());
+ animateElement.setAttribute('from', from[1]);
+ animateElement.setAttribute('to', to[1]);
} else {
+ animateElement = document.createElementNS(svgNamespace, 'animate');
animateElement.setAttribute('from', from);
animateElement.setAttribute('to', to);
}
- animateElement.setAttribute('begin', '0');
- animateElement.setAttribute('dur', '1');
- animateElement.setAttribute('fill', 'freeze');
- target.appendChild(animateElement);
- }
- function appendAnimateTransform(target, attributeName, from, to)
- {
- var animateElement = document.createElementNS(svgNamespace, 'animate');
animateElement.setAttribute('attributeName', namespacedAttributeName(attributeName));
animateElement.setAttribute('attributeType', 'XML');
- if (attributeName === 'class') {
- // Preserve the existing classes as we use them to select elements.
- animateElement.setAttribute('from', target['className'].baseVal + ' ' + from);
- animateElement.setAttribute('to', target['className'].baseVal + ' ' + to);
- } else {
- animateElement.setAttribute('from', from);
- animateElement.setAttribute('to', to);
- }
animateElement.setAttribute('begin', '0');
animateElement.setAttribute('dur', '1');
animateElement.setAttribute('fill', 'freeze');
- target.appendChild(animateElement);
- }
+ return animateElement;
+ }
+
+ function createTestTarget(method, description, container, params, expectation) {
+ var target = createTarget(container);
+ var expected = createTarget(container);
+ setAttributeValue(expected, params.property, expectation.is);
+
+ target.interpolate = function() {
+ switch (method) {
+ case 'SMIL':
+ var animateElement = createAnimateElement(params.property, params.from, params.to);
+ if (animateElement) {
+ target.appendChild(animateElement);
+ target.container.pauseAnimations();
+ target.container.setCurrentTime(expectation.at);
+ } else {
+ console.warn(`Unable to test SMIL from ${params.from} to ${params.to}`);
+ target.container.remove();
+ target.measure = function() {};
+ }
+ break;
+ case 'Web Animations':
+ // Replace 'transform' with 'svgTransform', etc. This avoids collisions with CSS properties or the Web Animations API (offset).
+ var prefixedProperty = 'svg' + params.property[0].toUpperCase() + params.property.slice(1);
+ target.animate([
+ {[prefixedProperty]: params.from},
+ {[prefixedProperty]: params.to},
+ ], {
+ fill: 'forwards',
+ duration: 1,
+ easing: createEasing(expectation.at),
+ delay: -0.5,
+ iterations: 0.5,
+ });
+ break;
+ default:
+ console.error('Unknown test method: ' + method);
+ }
+ };
- // Append animateTransform elements to parents of target.
- function appendAnimateTransform(target, attributeName, from, to)
- {
- var currentElement = target;
- var parents = [];
- from = from.split(')');
- to = to.split(')');
- // Discard empty string at end.
- from.pop();
- to.pop();
-
- // SMIL requires separate animateTransform elements for each transform in the list.
- if (from.length !== 1 || to.length !== 1)
- return;
+ target.measure = function() {
+ test(function() {
+ assert_equals(
+ normalizeValue(getAttributeValue(target, params.property)),
+ normalizeValue(getAttributeValue(expected, params.property)));
+ }, `${method}: ${description} at (${expectation.at}) is [${expectation.is}]`);
+ };
- from = from[0].split('(');
- to = to[0].split('(');
- if (from[0].trim() !== to[0].trim())
- return;
-
- var animateTransformElement = document.createElementNS(svgNamespace, 'animateTransform');
- animateTransformElement.setAttribute('attributeName', namespacedAttributeName(attributeName));
- animateTransformElement.setAttribute('attributeType', 'XML');
- animateTransformElement.setAttribute('type', from[0].trim());
- animateTransformElement.setAttribute('from', from[1]);
- animateTransformElement.setAttribute('to', to[1]);
- animateTransformElement.setAttribute('begin', '0');
- animateTransformElement.setAttribute('dur', '1');
- animateTransformElement.setAttribute('fill', 'freeze');
- target.appendChild(animateTransformElement);
+ return target;
}
- function makeInterpolationTest(testType, fraction, testId, caseId, params, expectation) {
- var attributeName = convertPropertyToCamelCase(params.property);
+ function createTestTargets(interpolationTests, container) {
+ var targets = [];
+ for (var interpolationTest of interpolationTests) {
+ var params = interpolationTest.params;
+ var description = `Interpolate attribute <${params.property}> from [${params.from}] to [${params.to}]`;
+ var expectations = interpolationTest.expectations;
- var targetContainer = createTargetContainer(caseId);
- var target = targetContainer.querySelector('.target') || targetContainer;
- target.classList.add(testType);
- var replicaContainer, replica;
- {
- replicaContainer = createTargetContainer(caseId);
- replica = replicaContainer.querySelector('.target') || replicaContainer;
- replica.classList.add('replica');
- setAttributeValue(replica, params.property, expectation);
- }
- target.testType = testType;
- target.getResultString = function() {
- var value = getAttributeValue(this, params.property);
- var result = '';
- var reason = '';
- var property = convertPropertyToCamelCase(params.property);
- {
- var parsedExpectation = getAttributeValue(replica, params.property);
- if (attributeName === 'class') {
- parsedExpectation = parsedExpectation.replace('replica', testType);
+ for (var method of ['SMIL', 'Web Animations']) {
+ createElement('pre', container).textContent = `${method}: ${description}`;
+ var smilContainer = createElement('div', container);
+ for (var expectation of expectations) {
+ if (method === 'SMIL' && (expectation.at < 0 || expectation.at > 1)) {
+ continue;
+ }
+ targets.push(createTestTarget(method, description, smilContainer, params, expectation));
}
- // console.log('expected ' + parsedExpectation + ', actual ' + value);
- var pass = normalizeValue(value) === normalizeValue(parsedExpectation);
- result = pass ? 'PASS: ' : 'FAIL: ';
- reason = pass ? '' : ', expected [' + expectation + ']' +
- (expectation === parsedExpectation ? '' : ' (parsed as [' + sanitizeUrls(roundNumbers(parsedExpectation)) + '])');
- value = pass ? expectation : sanitizeUrls(value);
}
- return result + property + ' from [' + params.from + '] to ' +
- '[' + params.to + '] was [' + value + ']' +
- ' at ' + fraction + reason;
- };
- var easing = createEasing(fraction);
- testCount++;
- {
- fragmentAttachedListeners.push(function() {
- if (testType === 'smil') {
- if (attributeName.toLowerCase().indexOf('transform') === -1)
- appendAnimate(target, attributeName, params.from, params.to);
- else
- appendAnimateTransform(target, attributeName, params.from, params.to);
-
- targetContainer.pauseAnimations();
- targetContainer.setCurrentTime(fraction);
- } else if (testType === 'web-animations' && target.animate) {
- target.animate(makeKeyframes(target, attributeName, params), {
- fill: 'forwards',
- duration: 1,
- easing: easing,
- delay: -0.5,
- iterations: 0.5,
- });
- }
- animationEnded();
- });
}
- var testFragment = document.createDocumentFragment();
- testFragment.appendChild(targetContainer);
- testFragment.appendChild(replicaContainer);
- testFragment.appendChild(document.createTextNode('\n'));
- return testFragment;
+ return targets;
}
- var finished = false;
- function finishTest() {
- finished = true;
- dumpResults();
- if (window.testRunner) {
- var results = document.querySelector('#results');
- document.documentElement.textContent = '';
- document.documentElement.appendChild(results);
- testRunner.dumpAsText();
-
- testRunner.notifyDone();
- }
- }
+ function runTests() {
+ return new Promise((resolve) => {
+ var container = createElement('div', document.body);
+ var targets = createTestTargets(interpolationTests, container);
- if (window.testRunner) {
- testRunner.waitUntilDone();
- }
+ requestAnimationFrame(() => {
+ for (var target of targets) {
+ target.interpolate();
+ }
- function isLastAnimationEvent() {
- return !finished && animationEventCount === testCount;
- }
+ requestAnimationFrame(() => {
+ for (var target of targets) {
+ target.measure();
+ }
- function animationEnded() {
- animationEventCount++;
- if (!isLastAnimationEvent()) {
- return;
- }
- requestAnimationFrame(finishTest);
+ if (window.testRunner) {
+ container.style.display = 'none';
+ }
+
+ resolve();
+ });
+ });
+ });
}
- if (!window.testRunner) {
- setTimeout(function() {
- if (finished) {
- return;
- }
- finishTest();
- }, 5000);
+ function loadScript(url) {
+ return new Promise(function(resolve) {
+ var script = createElement('script', document.head);
+ script.src = url;
+ script.onload = resolve;
+ });
}
+ loadScript('../../resources/testharness.js').then(() => {
+ return loadScript('../../resources/testharnessreport.js');
+ }).then(() => {
+ var asyncHandle = async_test('This test uses interpolation-test.js.')
+ requestAnimationFrame(() => {
+ runTests().then(() => asyncHandle.done());
+ });
+ });
+
window.assertAttributeInterpolation = assertAttributeInterpolation;
})();
« no previous file with comments | « no previous file | third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/svg-amplitude-interpolation-expected.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698