Bug 1272549 - Part 10: Test. r=hiro
authorBoris Chiou <boris.chiou@gmail.com>
Thu, 06 Oct 2016 12:49:11 +0800
changeset 319302 8a0851bef5398617c915661793f48833af567502
parent 319301 89e37cf072fe2bfae86de8d985bfe8f9502a3d40
child 319303 77c515e8350a7d07d807fd9e8ac3bbe136043a4a
push id30869
push userphilringnalda@gmail.com
push dateWed, 26 Oct 2016 04:57:48 +0000
treeherdermozilla-central@9471b3c49b2c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershiro
bugs1272549
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1272549 - Part 10: Test. r=hiro MozReview-Commit-ID: DOiNI2DoS7c
dom/animation/test/mochitest.ini
dom/animation/test/mozilla/file_spacing_transform.html
dom/animation/test/mozilla/test_spacing_transform.html
--- a/dom/animation/test/mochitest.ini
+++ b/dom/animation/test/mochitest.ini
@@ -39,16 +39,17 @@ support-files =
   mozilla/file_cubic_bezier_limits.html
   mozilla/file_deferred_start.html
   mozilla/file_disabled_properties.html
   mozilla/file_disable_animations_api_core.html
   mozilla/file_document-timeline-origin-time-range.html
   mozilla/file_hide_and_show.html
   mozilla/file_partial_keyframes.html
   mozilla/file_spacing_property_order.html
+  mozilla/file_spacing_transform.html
   mozilla/file_transform_limits.html
   mozilla/file_underlying-discrete-value.html
   mozilla/file_set-easing.html
   style/file_animation-seeking-with-current-time.html
   style/file_animation-seeking-with-start-time.html
   style/file_animation-setting-effect.html
   style/file_animation-setting-spacing.html
   testcommon.js
@@ -95,14 +96,15 @@ skip-if = buildapp == 'mulet'
 skip-if = (toolkit == 'gonk' && debug)
 [mozilla/test_disable_animations_api_core.html]
 [mozilla/test_disabled_properties.html]
 [mozilla/test_document-timeline-origin-time-range.html]
 [mozilla/test_hide_and_show.html]
 [mozilla/test_partial_keyframes.html]
 [mozilla/test_set-easing.html]
 [mozilla/test_spacing_property_order.html]
+[mozilla/test_spacing_transform.html]
 [mozilla/test_transform_limits.html]
 [mozilla/test_underlying-discrete-value.html]
 [style/test_animation-seeking-with-current-time.html]
 [style/test_animation-seeking-with-start-time.html]
 [style/test_animation-setting-effect.html]
 [style/test_animation-setting-spacing.html]
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/mozilla/file_spacing_transform.html
@@ -0,0 +1,240 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../testcommon.js"></script>
+<body>
+<script>
+'use strict';
+
+const pi  = Math.PI;
+const cos = Math.cos;
+const sin = Math.sin;
+const tan = Math.tan;
+const sqrt = Math.sqrt;
+
+// Help function for testing the computed offsets by the distance array.
+function assert_animation_offsets(anim, dist) {
+  const epsilon = 0.00000001;
+  const frames = anim.effect.getKeyframes();
+  const cumDist = dist.reduce( (prev, curr) => {
+    prev.push(prev.length == 0 ? curr : curr + prev[prev.length - 1]);
+    return prev;
+  }, []);
+
+  const total = cumDist[cumDist.length - 1];
+  for (var i = 0; i < frames.length; ++i) {
+    assert_approx_equals(frames[i].computedOffset, cumDist[i] / total,
+                         epsilon, 'computedOffset of frame ' + i);
+  }
+}
+
+function getAngleDist(rotate1, rotate2) {
+  function quaternion(axis, angle) {
+    var x = axis[0] * sin(angle/2.0);
+    var y = axis[1] * sin(angle/2.0);
+    var z = axis[2] * sin(angle/2.0);
+    var w = cos(angle/2.0);
+    return { 'x': x, 'y': y, 'z': z, 'w': w };
+  }
+  var q1 = quaternion(rotate1.axis, rotate1.angle);
+  var q2 = quaternion(rotate2.axis, rotate2.angle);
+  var dotProduct = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w;
+  return 2.0 * Math.acos(dotProduct);
+}
+
+function createMatrix(elements, Is3D) {
+  return (Is3D ? "matrix3d" : "matrix") + "(" + elements.join() + ")";
+}
+
+test(function(t) {
+  var anim = addDiv(t).animate([ { transform: "none" },
+                                 { transform: "translate(-20px)" },
+                                 { transform: "translate(100px)" },
+                                 { transform: "translate(50px)"} ],
+                               { spacing: "paced(transform)" });
+  assert_animation_offsets(anim, [ 0, 20, 120, 50 ]);
+}, 'Test spacing on translate' );
+
+test(function(t) {
+  var anim =
+    addDiv(t).animate([ { transform: "none" },
+                        { transform: "translate3d(-20px, 10px, 100px)" },
+                        { transform: "translate3d(100px, 200px, 50px)" },
+                        { transform: "translate(50px, -10px)"} ],
+                      { spacing: "paced(transform)" });
+  var dist = [ 0,
+               Math.sqrt(20 * 20 + 10 * 10 + 100 * 100),
+               Math.sqrt(120 * 120 + 190 * 190 + 50 * 50),
+               Math.sqrt(50 * 50 + 210 * 210 + 50 * 50) ];
+  assert_animation_offsets(anim, dist);
+}, 'Test spacing on translate3d' );
+
+test(function(t) {
+  var anim = addDiv(t).animate([ { transform: "scale(0.5)" },
+                                 { transform: "scale(4.5)" },
+                                 { transform: "scale(2.5)" },
+                                 { transform: "none"} ],
+                               { spacing: "paced(transform)" });
+  assert_animation_offsets(anim, [ 0, 4.0, 2.0, 1.5 ]);
+}, 'Test spacing on scale' );
+
+test(function(t) {
+  var anim = addDiv(t).animate([ { transform: "scale(0.5, 0.5)" },
+                                 { transform: "scale3d(4.5, 5.0, 2.5)" },
+                                 { transform: "scale3d(2.5, 1.0, 2.0)" },
+                                 { transform: "scale3d(1, 0.5, 1.0)"} ],
+                               { spacing:"paced(transform)" });
+  var dist = [ 0,
+               Math.sqrt(4.0 * 4.0 + 4.5 * 4.5 + 1.5 * 1.5),
+               Math.sqrt(2.0 * 2.0 + 4.0 * 4.0 + 0.5 * 0.5),
+               Math.sqrt(1.5 * 1.5 + 0.5 * 0.5 + 1.0 * 1.0) ];
+  assert_animation_offsets(anim, dist);
+}, 'Test spacing on scale3d' );
+
+test(function(t) {
+  var anim = addDiv(t).animate([ { transform: "rotate(60deg)" },
+                                 { transform: "none" },
+                                 { transform: "rotate(720deg)" },
+                                 { transform: "rotate(-360deg)"} ],
+                               { spacing: "paced(transform)" });
+  assert_animation_offsets(anim, [ 0, 60, 720, 1080 ]);
+}, 'Test spacing on rotate' );
+
+test(function(t) {
+  var anim = addDiv(t).animate([ { transform: "rotate3d(1,0,0,60deg)" },
+                                 { transform: "rotate3d(1,0,0,70deg)" },
+                                 { transform: "rotate3d(0,0,1,-110deg)" },
+                                 { transform: "rotate3d(1,0,0,219deg)"} ],
+                               { spacing: "paced(transform)" });
+  var dist = [ 0,
+               getAngleDist({ axis: [1,0,0], angle: 60 * pi / 180 },
+                            { axis: [1,0,0], angle: 70 * pi / 180 }),
+               getAngleDist({ axis: [0,1,0], angle: 70 * pi / 180 },
+                            { axis: [0,0,1], angle: -110 * pi / 180 }),
+               getAngleDist({ axis: [0,0,1], angle: -110 * pi / 180 },
+                            { axis: [1,0,0], angle: 219 * pi / 180 }) ];
+  assert_animation_offsets(anim, dist);
+}, 'Test spacing on rotate3d' );
+
+test(function(t) {
+  var anim = addDiv(t).animate([ { transform: "skew(60deg)" },
+                                 { transform: "none" },
+                                 { transform: "skew(-90deg)" },
+                                 { transform: "skew(90deg)"} ],
+                               { spacing: "paced(transform)" });
+  assert_animation_offsets(anim, [ 0, 60, 90, 180 ]);
+}, 'Test spacing on skew' );
+
+test(function(t) {
+  var anim = addDiv(t).animate([ { transform: "skew(60deg, 30deg)" },
+                                 { transform: "none" },
+                                 { transform: "skew(-90deg, 60deg)" },
+                                 { transform: "skew(90deg, 60deg)"} ],
+                               { spacing: "paced(transform)" });
+  var dist = [ 0,
+               sqrt(60 * 60 + 30 * 30),
+               sqrt(90 * 90 + 60 * 60),
+               sqrt(180 * 180 + 0) ];
+  assert_animation_offsets(anim, dist);
+}, 'Test spacing on skew along both X and Y' );
+
+test(function(t) {
+  // We calculate the distance of two perspective functions by converting them
+  // into two matrix3ds, and then do matrix decomposition to get two
+  // perspective vectors, so the equivalent perspective vectors are:
+  // perspective 1: (0, 0, -1/128, 1);
+  // perspective 2: (0, 0, -1/infinity = 0, 1);
+  // perspective 3: (0, 0, -1/1024, 1);
+  // perspective 4: (0, 0, -1/32, 1);
+  var anim = addDiv(t).animate([ { transform: "perspective(128px)" },
+                                 { transform: "none" },
+                                 { transform: "perspective(1024px)" },
+                                 { transform: "perspective(32px)"} ],
+                               { spacing: "paced(transform)" });
+  assert_animation_offsets(anim,
+                           [ 0, 1/128, 1/1024, 1/32 - 1/1024 ]);
+}, 'Test spacing on perspective' );
+
+test(function(t) {
+  var anim =
+    addDiv(t).animate([ { transform: "none" },
+                        { transform: "rotate(180deg) translate(0px)" },
+                        { transform: "rotate(180deg) translate(1000px)" },
+                        { transform: "rotate(360deg) translate(1000px)"} ],
+                      { spacing: "paced(transform)" });
+  var dist = [ 0,
+               sqrt(pi * pi + 0),
+               sqrt(1000 * 1000),
+               sqrt(pi * pi + 0) ];
+  assert_animation_offsets(anim, dist);
+}, 'Test spacing on matched transform lists' );
+
+test(function(t) {
+  // matrix1 => translate(100px, 50px), skewX(60deg).
+  // matrix2 => translate(1000px), rotate(180deg).
+  // matrix3 => translate(1000px), scale(1.5, 0.7).
+  const matrix1 = createMatrix([ 1, 0, tan(pi/4.0), 1, 100, 50 ]);
+  const matrix2 = createMatrix([ cos(pi), sin(pi),
+                                -sin(pi), cos(pi),
+                                 1000, 0 ]);
+  const matrix3 = createMatrix([ 1.5, 0, 0, 0.7, 1000, 0 ]);
+  var anim = addDiv(t).animate([ { transform: "none" },
+                                 { transform: matrix1 },
+                                 { transform: matrix2 },
+                                 { transform: matrix3 } ],
+                               { spacing: "paced(transform)" });
+  var dist = [ 0,
+               sqrt(100 * 100 + 50 * 50 + pi/4 * pi/4),
+               sqrt(900 * 900 + 50 * 50 + pi * pi + pi/4 * pi/4),
+               sqrt(pi * pi + 0.5 * 0.5 + 0.3 * 0.3) ];
+  assert_animation_offsets(anim, dist);
+}, 'Test spacing on matrix' );
+
+test(function(t) {
+  // matrix1 => translate3d(100px, 50px, -10px), skew(60deg).
+  // matrix2 => translate3d(1000px, 0, 0), rotate3d(1, 0, 0, 180deg).
+  // matrix3 => translate3d(1000px, 0, 0), scale3d(1.5, 0.7, 2.2).
+  const matrix1 = createMatrix([ 1, 0, 0, 0,
+                                 tan(pi/4.0), 1, 0, 0,
+                                 0, 0, 1, 0,
+                                 100, 50, -10, 1 ], true);
+  const matrix2 = createMatrix([ 1, 0, 0, 0,
+                                 0, cos(pi), sin(pi), 0,
+                                 0, -sin(pi), cos(pi), 0,
+                                 1000, 0, 0, 1 ], true);
+  const matrix3 = createMatrix([ 1.5, 0, 0, 0,
+                                 0, 0.7, 0, 0,
+                                 0, 0, 2.2, 0,
+                                 1000, 0, 0, 1 ], true);
+  var anim = addDiv(t).animate([ { transform: "none" },
+                                 { transform: matrix1 },
+                                 { transform: matrix2 },
+                                 { transform: matrix3 } ],
+                               { spacing: "paced(transform)" });
+  var dist = [ 0,
+               sqrt(100 * 100 + 50 * 50 + 10 * 10 + pi/4 * pi/4),
+               sqrt(900 * 900 + 50 * 50 + 10 * 10 + pi/4 * pi/4 + pi * pi),
+               sqrt(0.5 * 0.5 + 0.3 * 0.3 + 1.2 * 1.2 + pi * pi) ];
+  assert_animation_offsets(anim, dist);
+}, 'Test spacing on matrix3d' );
+
+test(function(t) {
+  var anim =
+    addDiv(t).animate([ { transform: "none" },
+                        { transform: "translate(100px, 50px) skew(45deg)" },
+                        { transform: "translate(1000px) " +
+                                     "rotate3d(1, 0, 0, 180deg)" },
+                        { transform: "translate(1000px) " +
+                                     "scale3d(2.5, 0.5, 0.7)" } ],
+                      { spacing: "paced(transform)" });
+
+  var dist = [ 0,
+               sqrt(100 * 100 + 50 * 50 + pi/4 * pi/4),
+               sqrt(900 * 900 + 50 * 50 + pi/4 * pi/4 + pi * pi),
+               sqrt(1.5 * 1.5 + 0.5 * 0.5 + 0.3 * 0.3 + pi * pi) ];
+  assert_animation_offsets(anim, dist);
+}, 'Test spacing on mismatched transform list' );
+
+done();
+
+</script>
+</body>
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/mozilla/test_spacing_transform.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+'use strict';
+setup({explicit_done: true});
+SpecialPowers.pushPrefEnv(
+  { "set": [["dom.animations-api.core.enabled", true]]},
+  function() {
+    window.open("file_spacing_transform.html");
+  });
+</script>