Bug 1244590 - Part 10: Test for creating animations with a specific spacing mode. draft
authorBoris Chiou <boris.chiou@gmail.com>
Wed, 11 May 2016 18:36:15 +0800
changeset 369285 5c6435df39f7b14f82c2bd623de20be9d65012bb
parent 369284 02417a19d3948e0454b5a4b881e968b3ad50f9c4
child 369286 e4ddd129d7ad7258c411918fee59d375e5f70698
push id18826
push userbmo:boris.chiou@gmail.com
push dateSat, 21 May 2016 11:25:24 +0000
bugs1244590
milestone49.0a1
Bug 1244590 - Part 10: Test for creating animations with a specific spacing mode. MozReview-Commit-ID: J0xNLunv9A7
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/web-animations/animation-model/keyframe-effects/spacing-keyframes.html
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -36010,16 +36010,22 @@
           }
         ],
         "web-animations/animation-model/keyframe-effects/effect-value-context.html": [
           {
             "path": "web-animations/animation-model/keyframe-effects/effect-value-context.html",
             "url": "/web-animations/animation-model/keyframe-effects/effect-value-context.html"
           }
         ],
+        "web-animations/animation-model/keyframe-effects/spacing-keyframes.html": [
+          {
+            "path": "web-animations/animation-model/keyframe-effects/spacing-keyframes.html",
+            "url": "/web-animations/animation-model/keyframe-effects/spacing-keyframes.html"
+          }
+        ],
         "web-animations/animation-model/keyframe-effects/the-effect-value-of-a-keyframe-effect.html": [
           {
             "path": "web-animations/animation-model/keyframe-effects/the-effect-value-of-a-keyframe-effect.html",
             "url": "/web-animations/animation-model/keyframe-effects/the-effect-value-of-a-keyframe-effect.html"
           }
         ],
         "web-animations/interfaces/Animatable/animate.html": [
           {
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/web-animations/animation-model/keyframe-effects/spacing-keyframes.html
@@ -0,0 +1,308 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Keyframe spacing tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#spacing-keyframes">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+test(function(t) {
+  assert_throws(new TypeError, function() {
+    var anim = createDiv(t).animate([ { marginLeft: '0px' },
+                                      { marginLeft: '-20px' },
+                                      { marginLeft: '100px' },
+                                      { marginLeft: '50px' } ],
+                                    { duration: 100 * MS_PER_SEC,
+                                      spacing: 'dist' });
+  });
+}, 'Test throwing TypeError if not using the correct keyword');
+
+test(function(t) {
+  assert_throws(new TypeError, function() {
+    var anim = createDiv(t).animate([ { marginLeft: '0px' },
+                                      { marginLeft: '-20px' },
+                                      { marginLeft: '100px' },
+                                      { marginLeft: '50px' } ],
+                                    { duration: 100 * MS_PER_SEC,
+                                      spacing: 'pace(margin-left)' });
+  });
+}, 'Test throwing TypeError if there is any typo');
+
+test(function(t) {
+  assert_throws(new TypeError, function() {
+    var anim = createDiv(t).animate([ { marginLeft: '0px' },
+                                      { marginLeft: '-20px' },
+                                      { marginLeft: '100px' },
+                                      { marginLeft: '50px' } ],
+                                    { duration: 100 * MS_PER_SEC,
+                                      spacing: 'paced(cabbage)' });
+  });
+}, 'Test throwing TypeError if using a non-existed property');
+
+test(function(t) {
+  assert_throws(new TypeError, function() {
+    var anim = createDiv(t).animate([ { marginLeft: '0px' },
+                                      { marginLeft: '-20px' },
+                                      { marginLeft: '100px' },
+                                      { marginLeft: '50px' } ],
+                                    { duration: 100 * MS_PER_SEC,
+                                      spacing: 'paced(margin-left )' });
+  });
+}, 'Test throwing TypeError if adding some extra spaces');
+
+test(function(t) {
+  assert_throws(new TypeError, function() {
+    var anim = createDiv(t).animate([ { marginLeft: '0px' },
+                                      { marginLeft: '-20px' },
+                                      { marginLeft: '100px' },
+                                      { marginLeft: '50px' } ],
+                                    { duration: 100 * MS_PER_SEC,
+                                      spacing: 'paced()' });
+  });
+}, 'Test throwing TypeError if there is no paced property');
+
+test(function(t) {
+  var anim = createDiv(t).animate([ { marginLeft: '0px' },
+                                    { marginLeft: '-20px' },
+                                    { marginLeft: '100px' },
+                                    { marginLeft: '50px' } ],
+                                  { duration: 100 * MS_PER_SEC,
+                                    spacing: 'distribute' });
+
+  assert_equals(anim.effect.spacing, 'distribute', 'spacing mode');
+
+  var frames = anim.effect.getKeyframes();
+  var slots = frames.length - 1;
+  assert_equals(frames[0].computedOffset, 0.0, '1st frame offset');
+  assert_equals(frames[1].computedOffset, 1.0 / slots, '2nd frame offset');
+  assert_equals(frames[2].computedOffset, 2.0 / slots, '3rd frame offset');
+  assert_equals(frames[3].computedOffset, 1.0, 'last frame offset');
+}, 'Test distribute spacing without specific offsets');
+
+test(function(t) {
+  var anim = createDiv(t).animate([ { marginLeft: '0px' },
+                                    { marginLeft: '-20px' },
+                                    { marginLeft: '100px', offset: 0.5 },
+                                    { marginLeft: '50px' } ],
+                                  { duration: 100 * MS_PER_SEC,
+                                    spacing: 'distribute' });
+
+  var frames = anim.effect.getKeyframes();
+  assert_equals(frames[0].computedOffset, 0.0, '1st frame offset');
+  assert_equals(frames[1].computedOffset, 0.5 * 1 / 2, '2nd frame offset');
+  assert_equals(frames[2].computedOffset, 0.5, '3rd frame offset');
+  assert_equals(frames[3].computedOffset, 1.0, 'last frame offset');
+}, 'Test distribute spacing with specific offsets');
+
+test(function(t) {
+  var anim = createDiv(t).animate([ { marginLeft: '0px' },
+                                    { marginLeft: '-20px' },
+                                    { marginLeft: '100px' },
+                                    { marginLeft: '50px' } ],
+                                  { duration: 100 * MS_PER_SEC,
+                                    spacing: 'paced(margin-left)' });
+
+  assert_equals(anim.effect.spacing, 'paced(margin-left)', 'spacing mode');
+
+  var frames = anim.effect.getKeyframes();
+  var cumDist = [0, 20, 140, 190];
+  assert_equals(frames[0].computedOffset, 0.0,
+                '1st frame offset');
+  assert_equals(frames[1].computedOffset, cumDist[1] / cumDist[3],
+                '2nd frame offset');
+  assert_equals(frames[2].computedOffset, cumDist[2] / cumDist[3],
+                '3rd frame offset');
+  assert_equals(frames[3].computedOffset, 1.0,
+                'last frame offset');
+}, 'Test paced spacing without specific offsets');
+
+test(function(t) {
+  var anim = createDiv(t).animate([ { marginLeft: '0px' },
+                                    { marginLeft: '-20px' },
+                                    { marginLeft: '100px', offset: 0.5 },
+                                    { marginLeft: '120px' },
+                                    { marginLeft: '50px' } ],
+                                  { duration: 100 * MS_PER_SEC,
+                                    spacing: 'paced(margin-left)' });
+
+  var frames = anim.effect.getKeyframes();
+  var cumDist1 = [ 0, 20, 140 ];
+  var cumDist2 = [ 0, 20, 90 ];
+  assert_equals(frames[1].computedOffset, 0.5 * cumDist1[1] / cumDist1[2],
+                '2nd frame offset');
+  assert_equals(frames[2].computedOffset, 0.5,
+                '3rd frame offset');
+  assert_equals(frames[3].computedOffset, 0.5 + 0.5 * cumDist2[1] / cumDist2[2],
+                '4th frame offset');
+}, 'Test paced spacing with specific offsets');
+
+test(function(t) {
+  var anim = createDiv(t).animate([ { marginLeft: '0px' },
+                                    { marginLeft: '0px' },
+                                    { marginLeft: '100px' },
+                                    { marginLeft: '50px' } ],
+                                  { duration: 100 * MS_PER_SEC,
+                                    spacing: 'paced(margin-left)' });
+
+  var frames = anim.effect.getKeyframes();
+  var cumDist = [0, 0, 100, 150];
+  assert_equals(frames[1].computedOffset, cumDist[1] / cumDist[3],
+                '2nd frame offset');
+  assert_equals(frames[2].computedOffset, cumDist[2] / cumDist[3],
+                '3rd frame offset');
+}, 'Test paced spacing if some paced property value are not changed');
+
+test(function(t) {
+  var anim = createDiv(t).animate([ { marginLeft: '0px' },
+                                    { marginLeft: '0px' },
+                                    { marginLeft: '0px' },
+                                    { marginLeft: '0px' } ],
+                                  { duration: 100 * MS_PER_SEC,
+                                    spacing: 'paced(margin-left)' });
+
+  var frames = anim.effect.getKeyframes();
+  var slots = frames.length - 1;
+  assert_equals(frames[1].computedOffset, 1.0 / slots, '2nd frame offset');
+  assert_equals(frames[2].computedOffset, 2.0 / slots, '3rd frame offset');
+}, 'Test falling back to distribute spacing if all paced property value ' +
+   'are not changed');
+
+// TODO: Add test case for mixing % values and pixel values
+
+test(function(t) {
+  var anim = createDiv(t).animate([ { margin: '0px' },
+                                    { marginTop: '-20px' },
+                                    { marginLeft: '100px' },
+                                    { margin: '50px' } ],
+                                  { duration: 100 * MS_PER_SEC,
+                                    spacing: 'paced(margin-left)' });
+
+  var frames = anim.effect.getKeyframes();
+  assert_equals(frames[1].computedOffset, frames[2].computedOffset * 1 / 2,
+                '2nd frame offset using distribute spacing');
+  assert_equals(frames[2].computedOffset, 100 / 150,
+                '3rd frame offset using paced spacing');
+}, 'Test paced spacing if a paced property that appears on only some ' +
+   'keyframes');
+
+test(function(t) {
+  var anim = createDiv(t).animate([ { margin: '0px' },
+                                    { marginTop: '-20px', offset: 0.5 },
+                                    { marginLeft: '40px' },
+                                    { marginLeft: '100px' },
+                                    { margin: '50px' } ],
+                                  { duration: 100 * MS_PER_SEC,
+                                    spacing: 'paced(margin-left)' });
+
+  var frames = anim.effect.getKeyframes();
+  assert_equals(frames[2].computedOffset, 0.5 + 0.5 * 1 / 3,
+                '3rd frame offset using distribute spacing because it is the ' +
+                'first paceable keyframe');
+  assert_equals(frames[3].computedOffset,
+                frames[2].computedOffset +
+                (1.0 - frames[2].computedOffset) * 60 / 110,
+                '4th frame offset using paced spacing');
+}, 'Test paced spacing if a paced property that appears on only some ' +
+   'keyframes with a specific offset');
+
+test(function(t) {
+  var anim = createDiv(t).animate([ { margin: '0px' },
+                                    { margin: '-20px' },
+                                    { margin: '100px' },
+                                    { margin: '50px' } ],
+                                  { duration: 100 * MS_PER_SEC,
+                                    spacing: 'paced(margin)' });
+
+  var frames = anim.effect.getKeyframes();
+  var cumDist = [0, 20, 140, 190];
+  assert_equals(frames[1].computedOffset, cumDist[1] / cumDist[3],
+                '2nd frame offset');
+  assert_equals(frames[2].computedOffset, cumDist[2] / cumDist[3],
+                '3rd frame offset');
+}, 'Test paced spacing for using shorthand property');
+
+test(function(t) {
+  var anim =
+    createDiv(t).animate([ { marginLeft: '0px',   marginRight:  '0px',
+                             marginTop:  '10px',  marginBottom: '10px' },
+                           { marginLeft: '-20px', marginRight:  '-20px',
+                             marginTop:  '0px',   marginBottom: '0px' },
+                           { marginLeft: '100px', marginRight:  '100px',
+                             marginTop:  '-50px', marginBottom: '-50px' },
+                           { marginLeft: '50px',  marginRight:  '50px',
+                             marginTop:  '80px',  marginBottom: '80px' } ],
+                         { duration: 100 * MS_PER_SEC,
+                           spacing: 'paced(margin)' });
+
+  var frames = anim.effect.getKeyframes();
+  var dist = [ 0,
+               Math.sqrt(20 * 20 * 2 + 10 * 10 * 2),
+               Math.sqrt(120 * 120 * 2 + 50 * 50 * 2),
+               Math.sqrt(50 * 50 * 2 + 130 * 130 * 2) ];
+  var cumDist = [];
+  dist.reduce(function(prev, curr, i) { return cumDist[i] = prev + curr; }, 0);
+  assert_approx_equals(frames[1].computedOffset, cumDist[1] / cumDist[3],
+                       0.0001, '2nd frame offset');
+  assert_approx_equals(frames[2].computedOffset, cumDist[2] / cumDist[3],
+                       0.0001, '3rd frame offset');
+}, 'Test paced spacing for using shorthand property');
+
+test(function(t) {
+  var anim = createDiv(t).animate([ { marginLeft: '0px', marginTop: '0px' },
+                                    { marginLeft: '-20px', marginTop: '-20px' },
+                                    { marginLeft: '100px', marginTop: '100px' },
+                                    { marginLeft: '50px', marginTop: '50px' } ],
+                                  { duration: 100 * MS_PER_SEC,
+                                    spacing: 'paced(margin)' });
+
+  var frames = anim.effect.getKeyframes();
+  var slots = frames.length - 1;
+  assert_equals(frames[1].computedOffset, 1 / slots, '2nd frame offset');
+  assert_equals(frames[2].computedOffset, 2 / slots, '3rd frame offset');
+}, 'Test falling back to distribute spacing if all keyframe miss some ' +
+   'components');
+
+test(function(t) {
+  var anim = createDiv(t).animate([ { margin: '0px' },
+                                    { marginLeft: '-20px' },
+                                    { marginTop: '40px' },
+                                    { margin: '100px' },
+                                    { margin: '50px' } ],
+                                  { duration: 100 * MS_PER_SEC,
+                                    spacing: 'paced(margin)' });
+
+  var frames = anim.effect.getKeyframes();
+  assert_equals(frames[1].computedOffset, frames[3].computedOffset * 1 / 3,
+                '2nd frame offset using distribute spacing');
+  assert_equals(frames[2].computedOffset, frames[3].computedOffset * 2 / 3,
+                '3rd frame offset using distribute spacing');
+  assert_equals(frames[3].computedOffset, 100 / 150,
+                '4th frame offset using paced spacing');
+}, 'Test paced spacing only for keyframes specifying all some components, ' +
+   'and falling back to distribute spacing for the reset');
+
+test(function(t) {
+  var anim = createDiv(t).animate([ { margin: '0px' },
+                                    { marginLeft: '-20px' },
+                                    { marginTop: '40px', offset: 0.5 },
+                                    { margin: '100px' },
+                                    { margin: '50px' } ],
+                                  { duration: 100 * MS_PER_SEC,
+                                    spacing: 'paced(margin)' });
+
+  var frames = anim.effect.getKeyframes();
+  assert_equals(frames[1].computedOffset, 0.5 * 1 / 2,
+                '2nd frame offset using distribute spacing');
+  assert_equals(frames[3].computedOffset, 0.5 + 0.5 * 1 / 2,
+                '4th frame offset using distribute spacing because it is the ' +
+                'first paceable keyframe from a non-null offset keyframe');
+}, 'Test paced spacing only for keyframes specifying all some components, ' +
+   'and falling back to distribute spacing for the reset with some specific ' +
+   'offsets');
+
+</script>
+</body>