Bug 1394284 - add wpt test for fallback discrete type of transform animation. draft
authorJeremy Chen <jeremychen@mozilla.com>
Tue, 12 Sep 2017 13:29:04 +0800
changeset 668177 1f07882c634b4972a4469e2d68c521a8c098354b
parent 668176 4495d60f82cdbae0d08f2bc2f8f914faa91c0a8d
child 732613 32c6d8354ea76fd224de87aab403f7722e8d5830
push id80952
push userbmo:jeremychen@mozilla.com
push dateThu, 21 Sep 2017 07:49:09 +0000
bugs1394284
milestone57.0a1
Bug 1394284 - add wpt test for fallback discrete type of transform animation. According to the spec, if one of the matrices for transform interpolation is non-invertible, the used animation function must fall-back to a discrete animation. Add wpt tests so we can ensure the web compability for this behavior. Note that we don't add 'discrete' type for transform property in property-list.js. Because the 'discrete' type also tests discrete addition and accumulation, however, the fallback behavior is just for interpolation and accumulation, not for addition. So, we add tests in each part of transformListType in property-types.js. One test is failing in Gecko, so annotate it for Gecko. MozReview-Commit-ID: 3JGvgqbBqZp
testing/web-platform/meta/MANIFEST.json
testing/web-platform/meta/web-animations/animation-model/animation-types/interpolation-per-property.html.ini
testing/web-platform/tests/web-animations/animation-model/animation-types/property-types.js
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -627702,17 +627702,17 @@
    "55100f7d505bc8cbc966ced0d1337ed78534a553",
    "testharness"
   ],
   "web-animations/animation-model/animation-types/property-list.js": [
    "6a1aafd6077aa656cfba4bba48f7ceca8344b810",
    "support"
   ],
   "web-animations/animation-model/animation-types/property-types.js": [
-   "98c3bbc4e0403d289a053711ebba7a0029345282",
+   "4b9e06fc9014110a711c590f866a149d31a9a6fa",
    "support"
   ],
   "web-animations/animation-model/combining-effects/effect-composition.html": [
    "8ac06085132d822e908d48de4c1109b66323f19f",
    "testharness"
   ],
   "web-animations/animation-model/keyframe-effects/effect-value-context.html": [
    "10d9ee521240475a1729c2facfcea8b50342614e",
--- a/testing/web-platform/meta/web-animations/animation-model/animation-types/interpolation-per-property.html.ini
+++ b/testing/web-platform/meta/web-animations/animation-model/animation-types/interpolation-per-property.html.ini
@@ -10,8 +10,13 @@ prefs: [layout.css.font-variations.enabl
       if stylo: PASS
       FAIL
 
   [font-variation-settings supports animation as float with multiple duplicate tags]
     expected:
       if stylo: PASS
       FAIL
 
+  [transform: non-invertible matrices in matched transform lists]
+    expected:
+      if stylo: PASS
+      FAIL
+    bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1400167
--- a/testing/web-platform/tests/web-animations/animation-model/animation-types/property-types.js
+++ b/testing/web-platform/tests/web-animations/animation-model/animation-types/property-types.js
@@ -908,16 +908,66 @@ const transformListType = {
       var target = createTestElement(t, setup);
       var animation =
         target.animate({ [idlName]: ['rotateY(60deg)', 'none' ] }, 1000);
 
       testAnimationSampleMatrices(animation, idlName,
                    // rotateY(30deg) == rotate3D(0, 1, 0, 30deg)
         [{ time: 500, expected: rotate3dToMatrix(0, 1, 0, Math.PI / 6) }]);
     }, property + ': rotateY');
+
+    // Following tests aim for test the fallback discrete interpolation behavior
+    // for non-invertible matrices. The non-invertible matrix that we use is the
+    // singuler matrix, matrix(1, 1, 0, 0, 0, 100).
+    test(function(t) {
+      var idlName = propertyToIDL(property);
+      var target = createTestElement(t, setup);
+      var animation =
+        target.animate({ [idlName]: ['matrix(-1, 0, 0, -1, 200, 0)',
+                                     'matrix( 1, 1, 0,  0, 0, 100)'] },
+                       { duration: 1000, fill: 'both' });
+
+      testAnimationSampleMatrices(animation, idlName,
+        [ { time: 0,    expected: [ -1, 0, 0, -1, 200,   0 ] },
+          { time: 499,  expected: [ -1, 0, 0, -1, 200,   0 ] },
+          { time: 500,  expected: [  1, 1, 0,  0,   0, 100 ] },
+          { time: 1000, expected: [  1, 1, 0,  0,   0, 100 ] }]);
+    }, property + ': non-invertible matrices');
+
+    test(function(t) {
+      var idlName = propertyToIDL(property);
+      var target = createTestElement(t, setup);
+      var animation =                // matrix(0, -1, 1, 0, 250, 0)
+        target.animate({ [idlName]: ['translate(50px)  matrix(-1, 0, 0, -1, 200, 0) rotate(90deg)',
+                                     // matrix(-1, -1, 0, 0, 100, 100)
+                                     'translate(100px) matrix( 1, 1, 0,  0, 0, 100) rotate(180deg)'] },
+                       { duration: 1000, fill: 'both' });
+
+      testAnimationSampleMatrices(animation, idlName,
+        [ { time: 0,    expected: [  0, -1, 1, 0, 250,   0 ] },
+          { time: 499,  expected: [  0, -1, 1, 0, 250,   0 ] },
+          { time: 500,  expected: [ -1, -1, 0, 0, 100, 100 ] },
+          { time: 1000, expected: [ -1, -1, 0, 0, 100, 100 ] }]);
+    }, property + ': non-invertible matrices in matched transform lists');
+
+    test(function(t) {
+      var idlName = propertyToIDL(property);
+      var target = createTestElement(t, setup);
+      var animation =                // matrix(-2, 0, 0, -2, 250, 0)
+        target.animate({ [idlName]: ['translate(50px)  matrix(-1, 0, 0, -1, 200, 0) scale(2)',
+                                     // matrix(1, 1, 1, 1, 100, 100)
+                                     'translate(100px) matrix( 1, 1, 0,  0, 0, 100) skew(45deg)'] },
+                       { duration: 1000, fill: 'both' });
+
+      testAnimationSampleMatrices(animation, idlName,
+        [ { time: 0,    expected: [ -2, 0, 0, -2, 250,   0 ] },
+          { time: 499,  expected: [ -2, 0, 0, -2, 250,   0 ] },
+          { time: 500,  expected: [  1, 1, 1,  1, 100, 100 ] },
+          { time: 1000, expected: [  1, 1, 1,  1, 100, 100 ] }]);
+    }, property + ': non-invertible matrices in mismatched transform lists');
   },
 
   testAddition: function(property, setup) {
     test(function(t) {
       var idlName = propertyToIDL(property);
       var target = createTestElement(t, setup);
       target.style[idlName] = 'translateX(100px)';
       var animation = target.animate({ [idlName]: ['translateX(-200px)',
@@ -1073,16 +1123,65 @@ const transformListType = {
       var animation =
         target.animate({ [idlName]: [ from, to ] },
                        { duration: 1000, fill: 'both', composite: 'add' });
 
       testAnimationSampleMatrices(animation, idlName,
         [{ time: 0,    expected: rotate3dToMatrix(1, 1, 0,    -Math.PI / 4) },
          { time: 1000, expected: rotate3dToMatrix(1, 1, 0, 3 * Math.PI / 4) }]);
     }, property + ': matrix3d');
+
+    // Following tests aim for test the addition behavior for non-invertible
+    // matrices. Note that the addition for non-invertible matrices should be
+    // the same, just like addition for invertible matrices. With these tests,
+    // we can assure that addition never behaves as discrete. The non-invertible
+    // matrix that we use is the singuler matrix, matrix(1, 1, 0, 0, 0, 100).
+    test(function(t) {
+      var idlName = propertyToIDL(property);
+      var target = createTestElement(t, setup);
+      target.style[idlName] = 'translateX(50px)';
+      var animation =
+        target.animate({ [idlName]: ['matrix(-1, 0, 0, -1, 200, 0)',
+                                     'matrix( 1, 1, 0,  0, 0, 100)'] },
+                       { duration: 1000, fill: 'both', composite: 'add' });
+
+      testAnimationSampleMatrices(animation, idlName,
+        [ { time: 0,    expected: [ -1, 0, 0, -1, 250,   0 ] },
+          { time: 1000, expected: [  1, 1, 0,  0,  50, 100 ] }]);
+    }, property + ': non-invertible matrices');
+
+    test(function(t) {
+      var idlName = propertyToIDL(property);
+      var target = createTestElement(t, setup);
+      target.style[idlName] = 'translateX(50px)';
+      var animation =                // matrix(0, -1, 1, 0, 200, 0)
+        target.animate({ [idlName]: ['matrix(-1, 0, 0, -1, 200, 0) rotate(90deg)',
+                                     // matrix(-1, -1, 0, 0, 0, 100)
+                                     'matrix( 1, 1, 0,  0, 0, 100) rotate(180deg)'] },
+                       { duration: 1000, fill: 'both', composite: 'add' });
+
+      testAnimationSampleMatrices(animation, idlName,
+        [ { time: 0,    expected: [  0, -1, 1, 0, 250,   0 ] },
+          { time: 1000, expected: [ -1, -1, 0, 0,  50, 100 ] }]);
+    }, property + ': non-invertible matrices in matched transform lists');
+
+    test(function(t) {
+      var idlName = propertyToIDL(property);
+      var target = createTestElement(t, setup);
+      target.style[idlName] = 'translateX(50px)';
+      var animation =                // matrix(-2, 0, 0, -2, 200, 0)
+        target.animate({ [idlName]: ['matrix(-1, 0, 0, -1, 200, 0) scale(2)',
+                                     // matrix(1, 1, 1, 1, 0, 100)
+                                     'matrix( 1, 1, 0,  0, 0, 100) skew(45deg)'] },
+                       { duration: 1000, fill: 'both', composite: 'add' });
+
+      testAnimationSampleMatrices(animation, idlName,
+        [ { time: 0,    expected: [ -2, 0, 0, -2, 250,   0 ] },
+          { time: 1000, expected: [  1, 1, 1,  1,  50, 100 ] }]);
+    }, property + ': non-invertible matrices in mismatched transform lists');
   },
 
   testAccumulation: function(property, setup) {
     test(function(t) {
       var idlName = propertyToIDL(property);
       var target = createTestElement(t, setup);
       target.style[idlName] = 'translateX(100px)';
       var animation = target.animate({ [idlName]: ['translateX(-200px)',
@@ -1240,16 +1339,101 @@ const transformListType = {
       var animation =
         target.animate({ [idlName]: [ 'none', 'none' ] },
                        { duration: 1000, fill: 'both', composite: 'accumulate' });
 
       testAnimationSampleMatrices(animation, idlName,
         [{ time: 0,    expected: matrixArray },
          { time: 1000, expected: matrixArray }]);
     }, property + ': none');
+
+    // Following tests aim for test the fallback discrete accumulation behavior
+    // for non-invertible matrices. The non-invertible matrix that we use is the
+    // singuler matrix, matrix(1, 1, 0, 0, 0, 100).
+    test(function(t) {
+      var idlName = propertyToIDL(property);
+      var target = createTestElement(t, setup);
+      target.animate({ [idlName]: ['matrix(-1, 0, 0, -1, 200, 0)',
+                                   'matrix(-1, 0, 0, -1, 200, 0)'] }, 1000);
+      var animation = target.animate({ [idlName]: ['matrix( 1, 1, 0, 0, 0, 100)',
+                                                   'matrix( 1, 1, 0, 0, 0, 100)'] },
+                                     { duration: 1000, composite: 'accumulate' });
+      testAnimationSampleMatrices(animation, idlName,
+                                  [{ time: 0, expected: [ 1, 1, 0, 0, 0, 100 ] }]);
+    }, property + ': non-invertible matrices (non-invertible onto invertible)');
+
+    test(function(t) {
+      var idlName = propertyToIDL(property);
+      var target = createTestElement(t, setup);
+      target.animate({ [idlName]: ['matrix( 1, 1, 0, 0, 0, 100)',
+                                   'matrix( 1, 1, 0, 0, 0, 100)'] }, 1000);
+      var animation = target.animate({ [idlName]: ['matrix(-1, 0, 0, -1, 200, 0)',
+                                                   'matrix(-1, 0, 0, -1, 200, 0)'] },
+                                     { duration: 1000, composite: 'accumulate' });
+      testAnimationSampleMatrices(animation, idlName,
+                                  [{ time: 0, expected: [ -1, 0, 0, -1, 200, 0 ] }]);
+    }, property + ': non-invertible matrices (invertible onto non-invertible)');
+
+    test(function(t) {
+      var idlName = propertyToIDL(property);
+      var target = createTestElement(t, setup);
+                                   // matrix(0, -1, 1, 0, 250, 0)
+      target.animate({ [idlName]: ['translate(50px)  matrix(-1, 0, 0, -1, 200, 0) rotate(90deg)',
+                                   'translate(50px)  matrix(-1, 0, 0, -1, 200, 0) rotate(90deg)'] }, 1000);
+      var animation =                // matrix(-1, -1, 0, 0, 100, 100)
+        target.animate({ [idlName]: ['translate(100px) matrix( 1, 1, 0, 0, 0, 100) rotate(180deg)',
+                                     'translate(100px) matrix( 1, 1, 0, 0, 0, 100) rotate(180deg)'] },
+                       { duration: 1000, composite: 'accumulate' });
+      testAnimationSampleMatrices(animation, idlName,
+                                  [{ time: 0, expected: [ -1, -1, 0, 0, 100, 100 ] }]);
+    }, property + ': non-invertible matrices in matched transform lists (non-invertible onto invertible)');
+
+    test(function(t) {
+      var idlName = propertyToIDL(property);
+      var target = createTestElement(t, setup);
+                                   // matrix(-1, -1, 0, 0, 100, 100)
+      target.animate({ [idlName]: ['translate(100px) matrix(1, 1, 0, 0, 0, 100) rotate(180deg)',
+                                   'translate(100px) matrix(1, 1, 0, 0, 0, 100) rotate(180deg)'] }, 1000);
+      var animation =                // matrix(0, -1, 1, 0, 250, 0)
+        target.animate({ [idlName]: ['translate(50px)  matrix(-1, 0, 0, -1, 200, 0) rotate(90deg)',
+                                     'translate(50px)  matrix(-1, 0, 0, -1, 200, 0) rotate(90deg)'] },
+                       { duration: 1000, composite: 'accumulate' });
+      testAnimationSampleMatrices(animation, idlName,
+                                  [{ time: 0, expected: [ 0, -1, 1, 0, 250, 0 ] }]);
+    }, property + ': non-invertible matrices in matched transform lists (invertible onto non-invertible)');
+
+    test(function(t) {
+      var idlName = propertyToIDL(property);
+      var target = createTestElement(t, setup);
+                                   // matrix(-2, 0, 0, -2, 250, 0)
+      target.animate({ [idlName]: ['translate(50px)  matrix(-1, 0, 0, -1, 200, 0) scale(2)',
+                                   'translate(50px)  matrix(-1, 0, 0, -1, 200, 0) scale(2)'] }, 1000);
+      var animation =                // matrix(1, 1, 1, 1, 100, 100)
+        target.animate({ [idlName]: ['translate(100px) matrix(1, 1, 0, 0, 0, 100) skew(45deg)',
+                                     'translate(100px) matrix(1, 1, 0, 0, 0, 100) skew(45deg)'] },
+                       { duration: 1000, composite: 'accumulate' });
+      testAnimationSampleMatrices(animation, idlName,
+                                  [{ time: 0, expected: [ 1, 1, 1, 1, 100, 100 ] }]);
+    }, property + ': non-invertible matrices in mismatched transform lists' +
+                  ' (non-invertible onto invertible)');
+
+    test(function(t) {
+      var idlName = propertyToIDL(property);
+      var target = createTestElement(t, setup);
+                                   // matrix(1, 1, 1, 1, 100, 100)
+      target.animate({ [idlName]: ['translate(100px) matrix(1, 1, 0, 0, 0, 100) skew(45deg)',
+                                   'translate(100px) matrix(1, 1, 0, 0, 0, 100) skew(45deg)'] }, 1000);
+      var animation =                // matrix(-2, 0, 0, -2, 250, 0)
+        target.animate({ [idlName]: ['translate(50px)  matrix(-1, 0, 0, -1, 200, 0) scale(2)',
+                                     'translate(50px)  matrix(-1, 0, 0, -1, 200, 0) scale(2)'] },
+                       { duration: 1000, composite: 'accumulate' });
+      testAnimationSampleMatrices(animation, idlName,
+                                  [{ time: 0, expected: [ -2, 0, 0, -2, 250, 0 ] }]);
+    }, property + ': non-invertible matrices in mismatched transform lists' +
+                  ' (invertible onto non-invertible)');
   },
 };
 
 const filterListType = {
   testInterpolation: function(property, setup) {
     test(function(t) {
       var idlName = propertyToIDL(property);
       var target = createTestElement(t, setup);