Bug 1452989 [wpt PR 10399] - Web Animations: Fix bugs in procedure to process a keyframes argument, a=testonly
authorStephen McGruer <smcgruer@chromium.org>
Sun, 22 Apr 2018 15:05:57 +0000
changeset 415272 60ed7d758b1b4f5afaa636416cf3b5568316ca5e
parent 415271 b5a7874d1f31011fc3ffc401ad16a05f546edb8d
child 415273 8469c16d69c5ac2b1e050428bfb571d7e53753d7
push id102533
push userwptsync@mozilla.com
push dateTue, 24 Apr 2018 12:30:46 +0000
treeherdermozilla-inbound@2342a0a0052f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1452989, 10399, 827573, 989261, 550641
milestone61.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 1452989 [wpt PR 10399] - Web Animations: Fix bugs in procedure to process a keyframes argument, a=testonly Automatic update from web-platform-testsWeb Animations: Fix bugs in procedure to process a keyframes argument There were three minor bugs left in the implementation: - We threw on lists-in-custom-iterators instead of just ignoring them. - We returned all properties on the keyframe rather than just those defined on the keyframe itself (e.g. we would include prototype properties, against spec). - We didn't access the properties in ascending unicode order. Bug: 827573 Change-Id: I213ae5b24e1f35d7f28d16625025122950a6ba88 Reviewed-on: https://chromium-review.googlesource.com/989261 Reviewed-by: Kentaro Hara <haraken@chromium.org> Reviewed-by: Yuki Shiino <yukishiino@chromium.org> Reviewed-by: Robert Flack <flackr@chromium.org> Commit-Queue: Stephen McGruer <smcgruer@chromium.org> Cr-Commit-Position: refs/heads/master@{#550641} -- wpt-commits: 2707869d65f3a4d5a1f2ab1d44920b19695a7cde wpt-pr: 10399
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -606288,17 +606288,17 @@
    "c65dd7fd3c76ac1e5d6f22dbd36544f7900cd992",
    "testharness"
   ],
   "web-animations/interfaces/KeyframeEffect/iterationComposite.html": [
    "c5ce17faeb355f1e9efae516d6272a88c46daa1f",
    "testharness"
   ],
   "web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html": [
-   "ca5efb8556aff617bef957be315ea2fd01e756d8",
+   "f68c116e1da5ae8783187af22f00758d02b7a0e9",
    "testharness"
   ],
   "web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-002.html": [
    "e9237e244034845f6f902f8149a0e66e5b6164f2",
    "testharness"
   ],
   "web-animations/interfaces/KeyframeEffect/setKeyframes.html": [
    "a346e0e004010a6f51e06ffd30d0b6eddd45421d",
--- a/testing/web-platform/tests/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html
+++ b/testing/web-platform/tests/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html
@@ -303,38 +303,120 @@ test(() => {
       left: '200px',
       composite: null,
     },
   ]);
 }, 'Keyframes are read from a custom iterator with where an offset is'
    + ' specified');
 
 test(() => {
+  const test_error = { name: 'test' };
+  const bad_keyframe = { get left() { throw test_error; } };
+  assert_throws(test_error, () => {
+    new KeyframeEffect(null, createIterable([
+      { done: false, value: { left: '100px' } },
+      { done: false, value: bad_keyframe },
+      { done: false, value: { left: '200px' } },
+      { done: true },
+    ]));
+  });
+}, 'If a keyframe throws for an animatable property, that exception should be'
+    + ' propagated');
+
+test(() => {
   assert_throws({ name: 'TypeError' }, () => {
     new KeyframeEffect(null, createIterable([
       { done: false, value: { left: '100px' } },
       { done: false, value: 1234 },
       { done: false, value: { left: '200px' } },
       { done: true },
     ]));
   });
 }, 'Reading from a custom iterator that returns a non-object keyframe'
    + ' should throw');
 
 test(() => {
   const effect = new KeyframeEffect(null, createIterable([
+    { done: false, value: { left: '100px' } },
+    { done: false },  // No value member; keyframe is undefined.
+    { done: false, value: { left: '200px' } },
+    { done: true },
+  ]));
+  assert_frame_lists_equal(effect.getKeyframes(), [
+    { left: '100px', offset: null, computedOffset: 0, easing: 'linear', composite: null },
+    { offset: null, computedOffset: 0.5, easing: 'linear', composite: null },
+    { left: '200px', offset: null, computedOffset: 1, easing: 'linear', composite: null },
+  ]);
+}, 'An undefined keyframe returned from a custom iterator should be treated as a'
+    + ' default keyframe');
+
+test(() => {
+  const effect = new KeyframeEffect(null, createIterable([
+    { done: false, value: { left: '100px' } },
+    { done: false, value: null },
+    { done: false, value: { left: '200px' } },
+    { done: true },
+  ]));
+  assert_frame_lists_equal(effect.getKeyframes(), [
+    { left: '100px', offset: null, computedOffset: 0, easing: 'linear', composite: null },
+    { offset: null, computedOffset: 0.5, easing: 'linear', composite: null },
+    { left: '200px', offset: null, computedOffset: 1, easing: 'linear', composite: null },
+  ]);
+}, 'A null keyframe returned from a custom iterator should be treated as a'
+    + ' default keyframe');
+
+test(() => {
+  const effect = new KeyframeEffect(null, createIterable([
     { done: false, value: { left: ['100px', '200px'] } },
     { done: true },
   ]));
   assert_frame_lists_equal(effect.getKeyframes(), [
     { offset: null, computedOffset: 1, easing: 'linear', composite: null }
   ]);
 }, 'A list of values returned from a custom iterator should be ignored');
 
 test(() => {
+  const test_error = { name: 'test' };
+  const keyframe_obj = {
+    [Symbol.iterator]() {
+      return { next() { throw test_error; } };
+    },
+  };
+  assert_throws(test_error, () => {
+    new KeyframeEffect(null, keyframe_obj);
+  });
+}, 'If a custom iterator throws from next(), the exception should be rethrown');
+
+// Test handling of invalid Symbol.iterator
+
+test(() => {
+  const test_error = { name: 'test' };
+  const keyframe_obj = {
+    [Symbol.iterator]() {
+      throw test_error;
+    },
+  };
+  assert_throws(test_error, () => {
+    new KeyframeEffect(null, keyframe_obj);
+  });
+}, 'Accessing a Symbol.iterator property that throws should rethrow');
+
+test(() => {
+  const keyframe_obj = {
+    [Symbol.iterator]() {
+      return 42;  // Not an object.
+    },
+  };
+  assert_throws({ name: 'TypeError' }, () => {
+    new KeyframeEffect(null, keyframe_obj);
+  });
+}, 'A non-object returned from the Symbol.iterator property should cause a'
+    + ' TypeError to be thrown');
+
+test(() => {
   const keyframe = {};
   Object.defineProperty(keyframe, 'width', { value: '200px' });
   Object.defineProperty(keyframe, 'height', {
     value: '100px',
     enumerable: true,
   });
   assert_equals(keyframe.width, '200px', 'width of keyframe is readable');
   assert_equals(keyframe.height, '100px', 'height of keyframe is readable');