<!DOCTYPE html>
<meta charset=utf-8>
<title>Processing a keyframes argument (easing)</title>
<link rel="help" href="https://drafts.csswg.org/web-animations/#processing-a-keyframes-argument">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../testcommon.js"></script>
<script src="../../resources/easing-tests.js"></script>
<body>
<div id="log"></div>
<div id="target"></div>
<script>
'use strict';

test(() => {
  for (const [easing, expected] of gEasingParsingTests) {
    const effect = new KeyframeEffect(target, {
      left: ['10px', '20px'],
      easing: easing
    });
    assert_equals(effect.getKeyframes()[0].easing, expected,
                  `resulting easing for '${easing}'`);
  }
}, 'easing values are parsed correctly when set on a property-indexed'
   + ' keyframe');

test(() => {
  for (const [easing, expected] of gEasingParsingTests) {
    const effect = new KeyframeEffect(target, [
      { offset: 0, left: '10px', easing: easing },
      { offset: 1, left: '20px' }
    ]);
    assert_equals(effect.getKeyframes()[0].easing, expected,
                  `resulting easing for '${easing}'`);
  }
}, 'easing values are parsed correctly when using a keyframe sequence');

test(() => {
  for (const invalidEasing of gInvalidEasings) {
    assert_throws_js(TypeError, () => {
      new KeyframeEffect(target, { easing: invalidEasing });
    }, `TypeError is thrown for easing '${invalidEasing}'`);
  }
}, 'Invalid easing values are correctly rejected when set on a property-'
   + 'indexed keyframe');

test(() => {
  for (const invalidEasing of gInvalidEasings) {
    assert_throws_js(TypeError, () => {
      new KeyframeEffect(target, [{ easing: invalidEasing }]);
    }, `TypeError is thrown for easing '${invalidEasing}'`);
  }
}, 'Invalid easing values are correctly rejected when using a keyframe'
   + ' sequence');

test(() => {
  let propAccessCount = 0;
  const keyframe = {};
  const addProp = prop => {
    Object.defineProperty(keyframe, prop, {
      get: () => { propAccessCount++; },
      enumerable: true
    });
  }
  addProp('height');
  addProp('width');
  keyframe.easing = 'easy-peasy';

  assert_throws_js(TypeError, () => {
    new KeyframeEffect(target, keyframe);
  });
  assert_equals(propAccessCount, 2,
    'All properties were read before throwing the easing error');
}, 'Errors from invalid easings on a property-indexed keyframe are thrown after reading all properties');

test(() => {
  let propAccessCount = 0;

  const addProp = (keyframe, prop) => {
    Object.defineProperty(keyframe, prop, {
      get: () => { propAccessCount++; },
      enumerable: true
    });
  }

  const kf1 = {};
  addProp(kf1, 'height');
  addProp(kf1, 'width');
  kf1.easing = 'easy-peasy';

  const kf2 = {};
  addProp(kf2, 'height');
  addProp(kf2, 'width');

  assert_throws_js(TypeError, () => {
    new KeyframeEffect(target, [ kf1, kf2 ]);
  });
  assert_equals(propAccessCount, 4,
    'All properties were read before throwing the easing error');
}, 'Errors from invalid easings on a keyframe sequence are thrown after reading all properties');

</script>
