<!doctype html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../testcommon.js"></script>
<body>
<style>
@keyframes anim {
  to { margin-left: 100px; }
}

.transition-div {
  margin-left: 100px;
}
</style>
<div id="log"></div>
<script>
'use strict';

// We clamp +infinity or -inifinity value in floating point to
// maximum floating point value or -maxinum floating point value.
const max_float = '3.40282e38';

test(function(t) {
  var div = addDiv(t);
  var anim = div.animate({ }, 100 * MS_PER_SEC);

  anim.effect.updateTiming({ easing: 'cubic-bezier(0, 1e+39, 0, 0)' });
  assert_equals(anim.effect.getComputedTiming().easing,
    'cubic-bezier(0, ' + max_float + ', 0, 0)',
    'y1 control point for effect easing is out of upper boundary');

  anim.effect.updateTiming({ easing: 'cubic-bezier(0, 0, 0, 1e+39)' });
  assert_equals(anim.effect.getComputedTiming().easing,
    'cubic-bezier(0, 0, 0, ' + max_float + ')',
    'y2 control point for effect easing is out of upper boundary');

  anim.effect.updateTiming({ easing: 'cubic-bezier(0, -1e+39, 0, 0)' });
  assert_equals(anim.effect.getComputedTiming().easing,
    'cubic-bezier(0, ' + '-' + max_float + ', 0, 0)',
    'y1 control point for effect easing is out of lower boundary');

  anim.effect.updateTiming({ easing: 'cubic-bezier(0, 0, 0, -1e+39)' });
  assert_equals(anim.effect.getComputedTiming().easing,
    'cubic-bezier(0, 0, 0, ' + '-' + max_float + ')',
    'y2 control point for effect easing is out of lower boundary');

}, 'Clamp y1 and y2 control point out of boundaries for effect easing' );

test(function(t) {
  var div = addDiv(t);
  var anim = div.animate({ }, 100 * MS_PER_SEC);

  anim.effect.setKeyframes([ { easing: 'cubic-bezier(0, 1e+39, 0, 0)' }]);
  assert_equals(anim.effect.getKeyframes()[0].easing,
    'cubic-bezier(0, ' + max_float + ', 0, 0)',
    'y1 control point for keyframe easing is out of upper boundary');

  anim.effect.setKeyframes([ { easing: 'cubic-bezier(0, 0, 0, 1e+39)' }]);
  assert_equals(anim.effect.getKeyframes()[0].easing,
    'cubic-bezier(0, 0, 0, ' + max_float + ')',
    'y2 control point for keyframe easing is out of upper boundary');

  anim.effect.setKeyframes([ { easing: 'cubic-bezier(0, -1e+39, 0, 0)' }]);
  assert_equals(anim.effect.getKeyframes()[0].easing,
    'cubic-bezier(0, ' + '-' + max_float + ', 0, 0)',
    'y1 control point for keyframe easing is out of lower boundary');

  anim.effect.setKeyframes([ { easing: 'cubic-bezier(0, 0, 0, -1e+39)' }]);
  assert_equals(anim.effect.getKeyframes()[0].easing,
    'cubic-bezier(0, 0, 0, ' + '-' + max_float + ')',
    'y2 control point for keyframe easing is out of lower boundary');

}, 'Clamp y1 and y2 control point out of boundaries for keyframe easing' );

test(function(t) {
  var div = addDiv(t);

  div.style.animation = 'anim 100s cubic-bezier(0, 1e+39, 0, 0)';

  assert_equals(div.getAnimations()[0].effect.getKeyframes()[0].easing,
    'cubic-bezier(0, ' + max_float + ', 0, 0)',
    'y1 control point for CSS animation is out of upper boundary');

  div.style.animation = 'anim 100s cubic-bezier(0, 0, 0, 1e+39)';
  assert_equals(div.getAnimations()[0].effect.getKeyframes()[0].easing,
    'cubic-bezier(0, 0, 0, ' + max_float + ')',
    'y2 control point for CSS animation is out of upper boundary');

  div.style.animation = 'anim 100s cubic-bezier(0, -1e+39, 0, 0)';
  assert_equals(div.getAnimations()[0].effect.getKeyframes()[0].easing,
    'cubic-bezier(0, ' + '-' + max_float + ', 0, 0)',
    'y1 control point for CSS animation is out of lower boundary');

  div.style.animation = 'anim 100s cubic-bezier(0, 0, 0, -1e+39)';
  assert_equals(div.getAnimations()[0].effect.getKeyframes()[0].easing,
    'cubic-bezier(0, 0, 0, ' + '-' + max_float + ')',
    'y2 control point for CSS animation is out of lower boundary');

}, 'Clamp y1 and y2 control point out of boundaries for CSS animation' );

test(function(t) {
  var div = addDiv(t, {'class': 'transition-div'});

  div.style.transition = 'margin-left 100s cubic-bezier(0, 1e+39, 0, 0)';
  flushComputedStyle(div);
  div.style.marginLeft = '0px';
  assert_equals(div.getAnimations()[0].effect.getTiming().easing,
    'cubic-bezier(0, ' + max_float + ', 0, 0)',
    'y1 control point for CSS transition on upper boundary');
  div.style.transition = '';
  div.style.marginLeft = '';

  div.style.transition = 'margin-left 100s cubic-bezier(0, 0, 0, 1e+39)';
  flushComputedStyle(div);
  div.style.marginLeft = '0px';
  assert_equals(div.getAnimations()[0].effect.getTiming().easing,
    'cubic-bezier(0, 0, 0, ' + max_float + ')',
    'y2 control point for CSS transition on upper boundary');
  div.style.transition = '';
  div.style.marginLeft = '';

  div.style.transition = 'margin-left 100s cubic-bezier(0, -1e+39, 0, 0)';
  flushComputedStyle(div);
  div.style.marginLeft = '0px';
  assert_equals(div.getAnimations()[0].effect.getTiming().easing,
    'cubic-bezier(0, ' + '-' + max_float + ', 0, 0)',
    'y1 control point for CSS transition on lower boundary');
  div.style.transition = '';
  div.style.marginLeft = '';

  div.style.transition = 'margin-left 100s cubic-bezier(0, 0, 0, -1e+39)';
  flushComputedStyle(div);
  div.style.marginLeft = '0px';
  assert_equals(div.getAnimations()[0].effect.getTiming().easing,
    'cubic-bezier(0, 0, 0, ' + '-' + max_float + ')',
    'y2 control point for CSS transition on lower boundary');

}, 'Clamp y1 and y2 control point out of boundaries for CSS transition' );

test(function(t) {
  var div = addDiv(t);
  var anim = div.animate({ }, { duration: 100 * MS_PER_SEC, fill: 'forwards' });

  anim.pause();
  // The positive steepest function on both edges.
  anim.effect.updateTiming({ easing: 'cubic-bezier(0, 1e+39, 0, 1e+39)' });
  assert_equals(anim.effect.getComputedTiming().progress, 0.0,
    'progress on lower edge for the highest value of y1 and y2 control points');

  anim.finish();
  assert_equals(anim.effect.getComputedTiming().progress, 1.0,
    'progress on upper edge for the highest value of y1 and y2 control points');

  // The negative steepest function on both edges.
  anim.effect.updateTiming({ easing: 'cubic-bezier(0, -1e+39, 0, -1e+39)' });
  anim.currentTime = 0;
  assert_equals(anim.effect.getComputedTiming().progress, 0.0,
    'progress on lower edge for the lowest value of y1 and y2 control points');

  anim.finish();
  assert_equals(anim.effect.getComputedTiming().progress, 1.0,
    'progress on lower edge for the lowest value of y1 and y2 control points');

}, 'Calculated values on both edges');

</script>
</body>
