<!DOCTYPE html>
<html>
<!--
Copyright 2008 The Closure Library Authors. All Rights Reserved.

Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<!--
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.ui.SliderBase</title>
<script src="../base.js"></script>
<script type="text/javascript">
  goog.require('goog.dom');
  goog.require('goog.a11y.aria');
  goog.require('goog.a11y.aria.State');
  goog.require('goog.dom.classes');
  goog.require('goog.events');
  goog.require('goog.events.EventType');
  goog.require('goog.events.KeyCodes');
  goog.require('goog.fx.Animation');
  goog.require('goog.math.Coordinate');
  goog.require('goog.style');
  goog.require('goog.style.bidi');
  goog.require('goog.testing.MockClock');
  goog.require('goog.testing.MockControl');
  goog.require('goog.testing.events');
  goog.require('goog.testing.jsunit');
  goog.require('goog.testing.mockmatchers');
  goog.require('goog.testing.recordFunction');
  goog.require('goog.ui.Component');
  goog.require('goog.ui.SliderBase');
  goog.require('goog.userAgent');
</script>
<style type="text/css">

#oneThumbSlider {
  position: relative;
  width: 1000px;
  background: grey;
  height: 20px;
}

#oneThumbSlider.test-slider-vertical {
  height: 1000px;
  width: 20px;
}

#twoThumbSlider {
  position: relative;
  /* Extra 20px is so distance between thumb centers is 1000px */
  width: 1020px;
}

#valueThumb, #extentThumb {
  position: absolute;
  width: 20px;
}

#thumb {
  position: absolute;
  width: 20px;
  height: 20px;
  background: black;
  top: 5px;
}

.test-slider-vertical > #thumb {
  left: 5px;
  top: auto;
}

#rangeHighlight {
  position: absolute;
}

</style>
</head>
<body>

<div id="sandbox"></div>

<script type="text/javascript">
var oneThumbSlider;
var oneThumbSliderRtl;
var oneChangeEventCount;

var twoThumbSlider;
var twoThumbSliderRtl;
var twoChangeEventCount;

var mockClock;
var mockAnimation;

/**
 * A basic class to implement the abstract goog.ui.SliderBase for testing.
 * @constructor
 * @extends {goog.ui.SliderBase}
 */
function OneThumbSlider() {
  goog.ui.SliderBase.call(this);
}
goog.inherits(OneThumbSlider, goog.ui.SliderBase);


/** {@override} */
OneThumbSlider.prototype.createThumbs = function() {
  this.valueThumb = this.extentThumb = goog.dom.getElement('thumb');
};


/** {@override} */
OneThumbSlider.prototype.getCssClass = function(orientation) {
  return goog.getCssName('test-slider', orientation);
};


/**
 * A basic class to implement the abstract goog.ui.SliderBase for testing.
 * @constructor
 * @extends {goog.ui.SliderBase}
 */
function TwoThumbSlider() {
  goog.ui.SliderBase.call(this);
}
goog.inherits(TwoThumbSlider, goog.ui.SliderBase);


/** {@override} */
TwoThumbSlider.prototype.createThumbs = function() {
  this.valueThumb = goog.dom.getElement('valueThumb');
  this.extentThumb = goog.dom.getElement('extentThumb');
  this.rangeHighlight = goog.dom.getElement('rangeHighlight');
};


/** {@override} */
TwoThumbSlider.prototype.getCssClass = function(orientation) {
  return goog.getCssName('test-slider', orientation);
};


/**
 * Basic class that implements the AnimationFactory interface for testing.
 * @param {!goog.fx.Animation|!Array.<!goog.fx.Animation>} testAnimations The
 *     test animations to use.
 * @constructor
 * @implements {goog.ui.SliderBase.AnimationFactory}
 */
function AnimationFactory(testAnimations) {
  this.testAnimations = testAnimations;
}


/** @override */
AnimationFactory.prototype.createAnimations = function() {
  return this.testAnimations;
};


function setUp() {
  var sandBox = goog.dom.getElement('sandbox');
  mockClock = new goog.testing.MockClock(true);

  var oneThumbElem = goog.dom.createDom(
      'div', {'id': 'oneThumbSlider'},
      goog.dom.createDom('span', {'id': 'thumb'}));
  sandBox.appendChild(oneThumbElem);
  oneThumbSlider = new OneThumbSlider();
  oneThumbSlider.decorate(oneThumbElem);
  oneChangeEventCount = 0;
  goog.events.listen(oneThumbSlider, goog.ui.Component.EventType.CHANGE,
      function() {
        oneChangeEventCount++;
      });

 var twoThumbElem = goog.dom.createDom(
     'div', {'id': 'twoThumbSlider'},
     goog.dom.createDom('div', {'id': 'rangeHighlight'}),
     goog.dom.createDom('span', {'id': 'valueThumb'}),
     goog.dom.createDom('span', {'id': 'extentThumb'}));
  sandBox.appendChild(twoThumbElem);
  twoThumbSlider = new TwoThumbSlider();
  twoThumbSlider.decorate(twoThumbElem);
  twoChangeEventCount = 0;
  goog.events.listen(twoThumbSlider, goog.ui.Component.EventType.CHANGE,
      function() {
        twoChangeEventCount++;
      });

  var sandBoxRtl = goog.dom.createDom('div',
      {'dir': 'rtl', 'style': 'position:absolute;'});
  sandBox.appendChild(sandBoxRtl);

  var oneThumbElemRtl = goog.dom.createDom(
      'div', {'id': 'oneThumbSliderRtl'},
      goog.dom.createDom('span', {'id': 'thumbRtl'}));
  sandBoxRtl.appendChild(oneThumbElemRtl);
  oneThumbSliderRtl = new OneThumbSlider();
  oneThumbSliderRtl.enableFlipForRtl(true);
  oneThumbSliderRtl.decorate(oneThumbElemRtl);
  goog.events.listen(oneThumbSliderRtl, goog.ui.Component.EventType.CHANGE,
      function() {
        oneChangeEventCount++;
      });

 var twoThumbElemRtl = goog.dom.createDom(
     'div', {'id': 'twoThumbSliderRtl'},
     goog.dom.createDom('div', {'id': 'rangeHighlightRtl'}),
     goog.dom.createDom('span', {'id': 'valueThumbRtl'}),
     goog.dom.createDom('span', {'id': 'extentThumbRtl'}));
  sandBoxRtl.appendChild(twoThumbElemRtl);
  twoThumbSliderRtl = new TwoThumbSlider();
  twoThumbSliderRtl.enableFlipForRtl(true);
  twoThumbSliderRtl.decorate(twoThumbElemRtl);
  twoChangeEventCount = 0;
  goog.events.listen(twoThumbSliderRtl, goog.ui.Component.EventType.CHANGE,
      function() {
        twoChangeEventCount++;
      });
}

function tearDown() {
<<<<<<< HEAD
  goog.events.removeAll();
=======
  goog.events.removeAllNativeListeners();
>>>>>>> newgitrepo
  oneThumbSlider.dispose();
  twoThumbSlider.dispose();
  oneThumbSliderRtl.dispose();
  twoThumbSliderRtl.dispose();
  mockClock.dispose();
  goog.dom.getElement('sandbox').innerHTML = '';
}

function testGetAndSetValue() {
  oneThumbSlider.setValue(30);
  assertEquals(30, oneThumbSlider.getValue());
  assertEquals('Setting valid value must dispatch only a single change event.',
      1, oneChangeEventCount);

  oneThumbSlider.setValue(30);
  assertEquals(30, oneThumbSlider.getValue());
  assertEquals('Setting to same value must not dispatch change event.',
      1, oneChangeEventCount);

  oneThumbSlider.setValue(-30);
  assertEquals('Setting invalid value must not change value.',
      30, oneThumbSlider.getValue());
  assertEquals('Setting invalid value must not dispatch change event.',
      1, oneChangeEventCount);


  // Value thumb can't go past extent thumb, so we must move that first to
  // allow setting value.
  twoThumbSlider.setExtent(70);
  twoChangeEventCount = 0;
  twoThumbSlider.setValue(60);
  assertEquals(60, twoThumbSlider.getValue());
  assertEquals('Setting valid value must dispatch only a single change event.',
      1, twoChangeEventCount);

  twoThumbSlider.setValue(60);
  assertEquals(60, twoThumbSlider.getValue());
  assertEquals('Setting to same value must not dispatch change event.',
      1, twoChangeEventCount);

  twoThumbSlider.setValue(-60);
  assertEquals('Setting invalid value must not change value.',
      60, twoThumbSlider.getValue());
  assertEquals('Setting invalid value must not dispatch change event.',
      1, twoChangeEventCount);
}

function testGetAndSetValueRtl() {
  var thumbElement = goog.dom.getElement('thumbRtl');
  assertEquals(0, goog.style.bidi.getOffsetStart(thumbElement));
  assertEquals('', thumbElement.style.left);
  assertTrue(thumbElement.style.right >= 0);

  oneThumbSliderRtl.setValue(30);
  assertEquals(30, oneThumbSliderRtl.getValue());
  assertEquals('Setting valid value must dispatch only a single change event.',
      1, oneChangeEventCount);

  assertEquals('', thumbElement.style.left);
  assertTrue(thumbElement.style.right >= 0);

  oneThumbSliderRtl.setValue(30);
  assertEquals(30, oneThumbSliderRtl.getValue());
  assertEquals('Setting to same value must not dispatch change event.',
      1, oneChangeEventCount);

  oneThumbSliderRtl.setValue(-30);
  assertEquals('Setting invalid value must not change value.',
      30, oneThumbSliderRtl.getValue());
  assertEquals('Setting invalid value must not dispatch change event.',
      1, oneChangeEventCount);


  // Value thumb can't go past extent thumb, so we must move that first to
  // allow setting value.
  var valueThumbElement = goog.dom.getElement('valueThumbRtl');
  var extentThumbElement = goog.dom.getElement('extentThumbRtl');
  assertEquals(0, goog.style.bidi.getOffsetStart(valueThumbElement));
  assertEquals(0, goog.style.bidi.getOffsetStart(extentThumbElement));
  assertEquals('', valueThumbElement.style.left);
  assertTrue(valueThumbElement.style.right >= 0);
  assertEquals('', extentThumbElement.style.left);
  assertTrue(extentThumbElement.style.right >= 0);

  twoThumbSliderRtl.setExtent(70);
  twoChangeEventCount = 0;
  twoThumbSliderRtl.setValue(60);
  assertEquals(60, twoThumbSliderRtl.getValue());
  assertEquals('Setting valid value must dispatch only a single change event.',
      1, twoChangeEventCount);

  twoThumbSliderRtl.setValue(60);
  assertEquals(60, twoThumbSliderRtl.getValue());
  assertEquals('Setting to same value must not dispatch change event.',
      1, twoChangeEventCount);

  assertEquals('', valueThumbElement.style.left);
  assertTrue(valueThumbElement.style.right >= 0);
  assertEquals('', extentThumbElement.style.left);
  assertTrue(extentThumbElement.style.right >= 0);

  twoThumbSliderRtl.setValue(-60);
  assertEquals('Setting invalid value must not change value.',
      60, twoThumbSliderRtl.getValue());
  assertEquals('Setting invalid value must not dispatch change event.',
      1, twoChangeEventCount);
}

function testGetAndSetExtent() {
  // Note(user): With a one thumb slider the API only really makes sense if you
  // always use setValue since there is no extent.

  twoThumbSlider.setExtent(7);
  assertEquals(7, twoThumbSlider.getExtent());
  assertEquals('Setting valid value must dispatch only a single change event.',
      1, twoChangeEventCount);

  twoThumbSlider.setExtent(7);
  assertEquals(7, twoThumbSlider.getExtent());
  assertEquals('Setting to same value must not dispatch change event.',
      1, twoChangeEventCount);

  twoThumbSlider.setExtent(-7);
  assertEquals('Setting invalid value must not change value.',
      7, twoThumbSlider.getExtent());
  assertEquals('Setting invalid value must not dispatch change event.',
      1, twoChangeEventCount);
}

function testUpdateValueExtent() {
  twoThumbSlider.setValueAndExtent(30, 50);

  assertNotNull(twoThumbSlider.getElement());
  assertEquals('Setting value results in updating aria-valuenow',
      '30',
      goog.a11y.aria.getState(twoThumbSlider.getElement(),
          goog.a11y.aria.State.VALUENOW));
  assertEquals(30, twoThumbSlider.getValue());
  assertEquals(50, twoThumbSlider.getExtent());
}

function testRangeListener() {
  var slider = new goog.ui.SliderBase;
  slider.updateUi_ = slider.updateAriaStates = function() {};
  slider.rangeModel.setValue(0);

  var f = goog.testing.recordFunction();
  goog.events.listen(slider, goog.ui.Component.EventType.CHANGE, f);

  slider.rangeModel.setValue(50);
  assertEquals(1, f.getCallCount());

  slider.exitDocument();
  slider.rangeModel.setValue(0);
  assertEquals('The range model listener should not have been removed so we ' +
               'should have gotten a second event dispatch',
               2, f.getCallCount());
}

/**
 * Verifies that rangeHighlight position and size are correct for the given
 * startValue and endValue. Assumes slider has default min/max values [0, 100],
 * width of 1020px, and thumb widths of 20px, with rangeHighlight drawn from
 * the centers of the thumbs.
 * @param {number} rangeHighlight The range highlight.
 * @param {number} startValue The start value.
 * @param {number} endValue The end value.
 */
function assertHighlightedRange(rangeHighlight, startValue, endValue) {
  var rangeStr = '[' + startValue + ', ' + endValue + ']';
  var rangeStart = 10 + 10 * startValue;
  assertEquals('Range highlight for ' + rangeStr + ' should start at ' +
      rangeStart + 'px.', rangeStart, rangeHighlight.offsetLeft);
  var rangeSize = 10 * (endValue - startValue);
  assertEquals('Range highlight for ' + rangeStr + ' should have size ' +
      rangeSize + 'px.', rangeSize, rangeHighlight.offsetWidth);
}

function testKeyHandlingTests() {
  twoThumbSlider.setValue(0);
  twoThumbSlider.setExtent(100);
  assertEquals(0, twoThumbSlider.getValue());
  assertEquals(100, twoThumbSlider.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSlider.getElement(), goog.events.KeyCodes.RIGHT);
  assertEquals(1, twoThumbSlider.getValue());
  assertEquals(99, twoThumbSlider.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSlider.getElement(), goog.events.KeyCodes.RIGHT);
  assertEquals(2, twoThumbSlider.getValue());
  assertEquals(98, twoThumbSlider.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSlider.getElement(), goog.events.KeyCodes.LEFT);
  assertEquals(1, twoThumbSlider.getValue());
  assertEquals(98, twoThumbSlider.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSlider.getElement(), goog.events.KeyCodes.LEFT);
  assertEquals(0, twoThumbSlider.getValue());
  assertEquals(98, twoThumbSlider.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSlider.getElement(), goog.events.KeyCodes.RIGHT,
      { shiftKey: true });
  assertEquals(10, twoThumbSlider.getValue());
  assertEquals(90, twoThumbSlider.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSlider.getElement(), goog.events.KeyCodes.RIGHT,
      { shiftKey: true });
  assertEquals(20, twoThumbSlider.getValue());
  assertEquals(80, twoThumbSlider.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSlider.getElement(), goog.events.KeyCodes.LEFT,
       { shiftKey: true });
  assertEquals(10, twoThumbSlider.getValue());
  assertEquals(80, twoThumbSlider.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSlider.getElement(), goog.events.KeyCodes.LEFT,
      { shiftKey: true });
  assertEquals(0, twoThumbSlider.getValue());
  assertEquals(80, twoThumbSlider.getExtent());
}

function testKeyHandlingRtl() {
  twoThumbSliderRtl.setValue(0);
  twoThumbSliderRtl.setExtent(100);
  assertEquals(0, twoThumbSliderRtl.getValue());
  assertEquals(100, twoThumbSliderRtl.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSliderRtl.getElement(), goog.events.KeyCodes.RIGHT);
  assertEquals(0, twoThumbSliderRtl.getValue());
  assertEquals(99, twoThumbSliderRtl.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSliderRtl.getElement(), goog.events.KeyCodes.RIGHT);
  assertEquals(0, twoThumbSliderRtl.getValue());
  assertEquals(98, twoThumbSliderRtl.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSliderRtl.getElement(), goog.events.KeyCodes.LEFT);
  assertEquals(1, twoThumbSliderRtl.getValue());
  assertEquals(98, twoThumbSliderRtl.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSliderRtl.getElement(), goog.events.KeyCodes.LEFT);
  assertEquals(2, twoThumbSliderRtl.getValue());
  assertEquals(98, twoThumbSliderRtl.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSliderRtl.getElement(), goog.events.KeyCodes.RIGHT,
      { shiftKey: true });
  assertEquals(0, twoThumbSliderRtl.getValue());
  assertEquals(90, twoThumbSliderRtl.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSliderRtl.getElement(), goog.events.KeyCodes.RIGHT,
      { shiftKey: true });
  assertEquals(0, twoThumbSliderRtl.getValue());
  assertEquals(80, twoThumbSliderRtl.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSliderRtl.getElement(), goog.events.KeyCodes.LEFT,
       { shiftKey: true });
  assertEquals(10, twoThumbSliderRtl.getValue());
  assertEquals(80, twoThumbSliderRtl.getExtent());

  goog.testing.events.fireKeySequence(
      twoThumbSliderRtl.getElement(), goog.events.KeyCodes.LEFT,
      { shiftKey: true });
  assertEquals(20, twoThumbSliderRtl.getValue());
  assertEquals(80, twoThumbSliderRtl.getExtent());
}

function testRangeHighlight() {
  var rangeHighlight = goog.dom.getElement('rangeHighlight');

  // Test [0, 100]
  twoThumbSlider.setValue(0);
  twoThumbSlider.setExtent(100);
  assertHighlightedRange(rangeHighlight, 0, 100);

  // Test [25, 75]
  twoThumbSlider.setValue(25);
  twoThumbSlider.setExtent(50);
  assertHighlightedRange(rangeHighlight, 25, 75);

  // Test [50, 50]
  twoThumbSlider.setValue(50);
  twoThumbSlider.setExtent(0);
  assertHighlightedRange(rangeHighlight, 50, 50);
}

function testRangeHighlightAnimation() {
  var animationDelay = 160; // Delay in ms, is a bit higher than actual delay.
  if (goog.userAgent.IE) {
    // For some reason, (probably due to how timing works), IE7 and IE8 will not
    // stop if we don't wait for it.
    animationDelay = 250;
  }

  var rangeHighlight = goog.dom.getElement('rangeHighlight');
  twoThumbSlider.setValue(0);
  twoThumbSlider.setExtent(100);

  // Animate right thumb, final range is [0, 75]
  twoThumbSlider.animatedSetValue(75);
  assertHighlightedRange(rangeHighlight, 0, 100);
  mockClock.tick(animationDelay);
  assertHighlightedRange(rangeHighlight, 0, 75);

  // Animate left thumb, final range is [25, 75]
  twoThumbSlider.animatedSetValue(25);
  assertHighlightedRange(rangeHighlight, 0, 75);
  mockClock.tick(animationDelay);
  assertHighlightedRange(rangeHighlight, 25, 75);
}

/**
 * Verifies that no error occurs and that the range highlight is sized correctly
 * for a zero-size slider (i.e. doesn't attempt to set a negative size). The
 * test tries to resize the slider from its original size to 0, then checks
 * that the range highlight's size is correctly set to 0.
 *
 * The size verification is needed because Webkit/Gecko outright ignore calls
 * to set negative sizes on an element, leaving it at its former size. IE
 * throws an error in the same situation.
 */
function testRangeHighlightForZeroSizeSlider() {
  // Make sure range highlight spans whole slider before zeroing width.
  twoThumbSlider.setExtent(100);
  twoThumbSlider.getElement().style.width = 0;

  // The setVisible call is used to force a UI update.
  twoThumbSlider.setVisible(true);
  assertEquals('Range highlight size should be 0 when slider size is 0',
      0, goog.dom.getElement('rangeHighlight').offsetWidth);
}

function testAnimatedSetValueAnimatesFactoryCreatedAnimations() {
  // Create and set the factory.
  var ignore = goog.testing.mockmatchers.ignoreArgument;
  var mockControl = new goog.testing.MockControl();
  var mockAnimation1 = mockControl.createLooseMock(goog.fx.Animation);
  var mockAnimation2 = mockControl.createLooseMock(goog.fx.Animation);
  var testAnimations = [mockAnimation1, mockAnimation2];
  oneThumbSlider.setAdditionalAnimations(new AnimationFactory(testAnimations));

  // Expect the animations to be played.
  mockAnimation1.play(false);
  mockAnimation2.play(false);
  mockAnimation1.addEventListener(ignore, ignore, ignore);
  mockAnimation2.addEventListener(ignore, ignore, ignore);

  // Animate and verify.
  mockControl.$replayAll();
  oneThumbSlider.animatedSetValue(50);
  mockControl.$verifyAll();
  mockControl.$resetAll();
  mockControl.$tearDown();
}

function testMouseWheelEventHandlerEnable() {
  // Mouse wheel handling should be enabled by default.
  assertTrue(oneThumbSlider.isHandleMouseWheel());

  // Test disabling the mouse wheel handler
  oneThumbSlider.setHandleMouseWheel(false);
  assertFalse(oneThumbSlider.isHandleMouseWheel());

  // Test that enabling again works fine.
  oneThumbSlider.setHandleMouseWheel(true);
  assertTrue(oneThumbSlider.isHandleMouseWheel());

  // Test that mouse wheel handling can be disabled before rendering a slider.
  var wheelDisabledElem = goog.dom.createDom(
      'div', {}, goog.dom.createDom('span'));
  var wheelDisabledSlider = new OneThumbSlider();
  wheelDisabledSlider.setHandleMouseWheel(false);
  wheelDisabledSlider.decorate(wheelDisabledElem);
  assertFalse(wheelDisabledSlider.isHandleMouseWheel());
}

function testDisabledAndEnabledSlider() {
  // Check that a slider is enabled by default
  assertTrue(oneThumbSlider.isEnabled());

  var listenerCount = oneThumbSlider.getHandler().getListenerCount();
  // Disable the slider and check its state
  oneThumbSlider.setEnabled(false);
  assertFalse(oneThumbSlider.isEnabled());
  assertTrue(goog.dom.classes.has(
      oneThumbSlider.getElement(), 'goog-slider-disabled'));
  assertEquals(0, oneThumbSlider.getHandler().getListenerCount());

  // setValue should work unaffected even when the slider is disabled.
  oneThumbSlider.setValue(30);
  assertEquals(30, oneThumbSlider.getValue());
  assertEquals('Setting valid value must dispatch a change event ' +
      'even when slider is disabled.', 1, oneChangeEventCount);

  // Test the transition from disabled to enabled
  oneThumbSlider.setEnabled(true);
  assertTrue(oneThumbSlider.isEnabled());
  assertFalse(goog.dom.classes.has(
      oneThumbSlider.getElement(), 'goog-slider-disabled'));
  assertTrue(listenerCount == oneThumbSlider.getHandler().getListenerCount());
}

function testBlockIncrementingWithEnableAndDisabled() {
  var doc = goog.dom.getOwnerDocument(oneThumbSlider.getElement());
  // Case when slider is not disabled between the mouse down and up events.
  goog.testing.events.fireMouseDownEvent(oneThumbSlider.getElement());
  assertEquals(1, goog.events.getListeners(
      oneThumbSlider.getElement(),
      goog.events.EventType.MOUSEMOVE, false).length);
  assertEquals(1, goog.events.getListeners(
      doc, goog.events.EventType.MOUSEUP, true).length);

  goog.testing.events.fireMouseUpEvent(oneThumbSlider.getElement());

  assertEquals(0, goog.events.getListeners(
      oneThumbSlider.getElement(),
      goog.events.EventType.MOUSEMOVE, false).length);
  assertEquals(0, goog.events.getListeners(
      doc, goog.events.EventType.MOUSEUP, true).length);

  // Case when the slider is disabled between the mouse down and up events.
  goog.testing.events.fireMouseDownEvent(oneThumbSlider.getElement());
  assertEquals(1, goog.events.getListeners(
      oneThumbSlider.getElement(),
      goog.events.EventType.MOUSEMOVE, false).length);
  assertEquals(1,
      goog.events.getListeners(doc,
      goog.events.EventType.MOUSEUP, true).length);

  oneThumbSlider.setEnabled(false);

  assertEquals(0, goog.events.getListeners(
      oneThumbSlider.getElement(),
      goog.events.EventType.MOUSEMOVE, false).length);
  assertEquals(0, goog.events.getListeners(
      doc, goog.events.EventType.MOUSEUP, true).length);
  assertEquals(1, oneThumbSlider.getHandler().getListenerCount());

  goog.testing.events.fireMouseUpEvent(oneThumbSlider.getElement());
  assertEquals(0, goog.events.getListeners(
      oneThumbSlider.getElement(),
      goog.events.EventType.MOUSEMOVE, false).length);
  assertEquals(0, goog.events.getListeners(
      doc, goog.events.EventType.MOUSEUP, true).length);
}

function testMouseClickWithMoveToPointEnabled() {
  var stepSize = 20;
  oneThumbSlider.setStep(stepSize);
  oneThumbSlider.setMoveToPointEnabled(true);
  var initialValue = oneThumbSlider.getValue();

  // Figure out the number of pixels per step.
  var numSteps = Math.round(
      (oneThumbSlider.getMaximum() - oneThumbSlider.getMinimum()) / stepSize);
  var size = goog.style.getSize(oneThumbSlider.getElement());
  var pixelsPerStep = Math.round(size.width / numSteps);

  var coords = goog.style.getClientPosition(oneThumbSlider.getElement());
  coords.x += pixelsPerStep / 2;

  // Case when value is increased
  goog.testing.events.fireClickSequence(oneThumbSlider.getElement(),
      /* opt_button */ undefined, coords);
  assertEquals(oneThumbSlider.getValue(), initialValue + stepSize);

  // Case when value is decreased
  goog.testing.events.fireClickSequence(oneThumbSlider.getElement(),
      /* opt_button */ undefined, coords);
  assertEquals(oneThumbSlider.getValue(), initialValue);

  // Case when thumb is clicked
  goog.testing.events.fireClickSequence(oneThumbSlider.getElement());
  assertEquals(oneThumbSlider.getValue(), initialValue);
}

<<<<<<< HEAD
=======
function testNonIntegerStepSize() {
  var stepSize = 0.02;
  oneThumbSlider.setStep(stepSize);
  oneThumbSlider.setMinimum(-1);
  oneThumbSlider.setMaximum(1);
  oneThumbSlider.setValue(0.7);
  assertRoughlyEquals(0.7, oneThumbSlider.getValue(), 0.000001);
  oneThumbSlider.setValue(0.3);
  assertRoughlyEquals(0.3, oneThumbSlider.getValue(), 0.000001);
}

>>>>>>> newgitrepo
/**
 * Tests getThumbCoordinateForValue method.
 */
function testThumbCoordinateForValueWithHorizontalSlider() {
  // Make sure the y-coordinate stays the same for the horizontal slider.
  var originalY = goog.style.getPosition(oneThumbSlider.valueThumb).y;
  var width = oneThumbSlider.getElement().clientWidth -
      oneThumbSlider.valueThumb.offsetWidth;
  var range = oneThumbSlider.getMaximum() - oneThumbSlider.getMinimum();

  // Verify coordinate for a particular value.
  var value = 20;
  var expectedX = Math.round(value / range * width);
  var expectedCoord = new goog.math.Coordinate(expectedX, originalY);
  var coord = oneThumbSlider.getThumbCoordinateForValue(value);
  assertObjectEquals(expectedCoord, coord);

  // Verify this works regardless of current position.
  oneThumbSlider.setValue(value / 2);
  coord = oneThumbSlider.getThumbCoordinateForValue(value);
  assertObjectEquals(expectedCoord, coord);
}

function testThumbCoordinateForValueWithVerticalSlider() {
  // Make sure the x-coordinate stays the same for the vertical slider.
  oneThumbSlider.setOrientation(goog.ui.SliderBase.Orientation.VERTICAL);
  var originalX = goog.style.getPosition(oneThumbSlider.valueThumb).x;
  var height = oneThumbSlider.getElement().clientHeight -
      oneThumbSlider.valueThumb.offsetHeight;
  var range = oneThumbSlider.getMaximum() - oneThumbSlider.getMinimum();

  // Verify coordinate for a particular value.
  var value = 20;
  var expectedY = height - Math.round(value / range * height);
  var expectedCoord = new goog.math.Coordinate(originalX, expectedY);
  var coord = oneThumbSlider.getThumbCoordinateForValue(value);
  assertObjectEquals(expectedCoord, coord);

  // Verify this works regardless of current position.
  oneThumbSlider.setValue(value / 2);
  coord = oneThumbSlider.getThumbCoordinateForValue(value);
  assertObjectEquals(expectedCoord, coord);
}

/**
 * Tests getValueFromMousePosition method.
 */
function testValueFromMousePosition() {
  var value = 30;
  oneThumbSlider.setValue(value);
  var offset = goog.style.getPageOffset(oneThumbSlider.valueThumb);
  var size = goog.style.getSize(oneThumbSlider.valueThumb);
  offset.x += size.width / 2;
  offset.y += size.height / 2;
  var e = null;
  goog.events.listen(oneThumbSlider, goog.events.EventType.MOUSEMOVE,
      function(evt) {
        e = evt;
      });
  goog.testing.events.fireMouseMoveEvent(oneThumbSlider, offset);
  assertNotEquals(e, null);
  assertEquals(
      value, Math.round(oneThumbSlider.getValueFromMousePosition(e)));
  // Verify this works regardless of current position.
  oneThumbSlider.setValue(value / 2);
  assertEquals(
      value, Math.round(oneThumbSlider.getValueFromMousePosition(e)));
}

/**
 * Tests dragging events.
 */
function testDragEvents() {
  var offset = goog.style.getPageOffset(oneThumbSlider.valueThumb);
  var size = goog.style.getSize(oneThumbSlider.valueThumb);
  offset.x += size.width / 2;
  offset.y += size.height / 2;
  var event_types = [];
  var handler = function(evt) {
    event_types.push(evt.type);
  };

  goog.events.listen(oneThumbSlider,
      [goog.ui.SliderBase.EventType.DRAG_START,
      goog.ui.SliderBase.EventType.DRAG_END,
      goog.ui.SliderBase.EventType.DRAG_VALUE_START,
      goog.ui.SliderBase.EventType.DRAG_VALUE_END,
      goog.ui.SliderBase.EventType.DRAG_EXTENT_START,
      goog.ui.SliderBase.EventType.DRAG_EXTENT_END,
      goog.ui.Component.EventType.CHANGE],
      handler);

  // Since the order of the events between value and extent is not guaranteed
  // accross browsers, we need to allow for both here and once we have
  // them all, make sure that they were different.
  function isValueOrExtentDragStart(type) {
    return type == goog.ui.SliderBase.EventType.DRAG_VALUE_START ||
        type == goog.ui.SliderBase.EventType.DRAG_EXTENT_START;
  };
  function isValueOrExtentDragEnd(type) {
    return type == goog.ui.SliderBase.EventType.DRAG_VALUE_END ||
        type == goog.ui.SliderBase.EventType.DRAG_EXTENT_END;
  };

  // Test that dragging the thumb calls all the correct events.
  goog.testing.events.fireMouseDownEvent(oneThumbSlider.valueThumb);
  offset.x += 100;
  goog.testing.events.fireMouseMoveEvent(oneThumbSlider.valueThumb, offset);
  goog.testing.events.fireMouseUpEvent(oneThumbSlider.valueThumb);

  assertEquals(9, event_types.length);

  assertEquals(goog.ui.SliderBase.EventType.DRAG_START, event_types[0]);
  assertTrue(isValueOrExtentDragStart(event_types[1]));

  assertEquals(goog.ui.SliderBase.EventType.DRAG_START, event_types[2]);
  assertTrue(isValueOrExtentDragStart(event_types[3]));

  assertEquals(goog.ui.Component.EventType.CHANGE, event_types[4]);

  assertEquals(goog.ui.SliderBase.EventType.DRAG_END, event_types[5]);
  assertTrue(isValueOrExtentDragEnd(event_types[6]));

  assertEquals(goog.ui.SliderBase.EventType.DRAG_END, event_types[7]);
  assertTrue(isValueOrExtentDragEnd(event_types[8]));

  assertFalse(event_types[1] == event_types[3]);
  assertFalse(event_types[6] == event_types[8]);

  // Test that clicking the thumb without moving the mouse does not cause a
  // CHANGE event between DRAG_START/DRAG_END.
  event_types = [];
  goog.testing.events.fireMouseDownEvent(oneThumbSlider.valueThumb);
  goog.testing.events.fireMouseUpEvent(oneThumbSlider.valueThumb);

  assertEquals(8, event_types.length);

  assertEquals(goog.ui.SliderBase.EventType.DRAG_START, event_types[0]);
  assertTrue(isValueOrExtentDragStart(event_types[1]));

  assertEquals(goog.ui.SliderBase.EventType.DRAG_START, event_types[2]);
  assertTrue(isValueOrExtentDragStart(event_types[3]));

  assertEquals(goog.ui.SliderBase.EventType.DRAG_END, event_types[4]);
  assertTrue(isValueOrExtentDragEnd(event_types[5]));

  assertEquals(goog.ui.SliderBase.EventType.DRAG_END, event_types[6]);
  assertTrue(isValueOrExtentDragEnd(event_types[7]));

  assertFalse(event_types[1] == event_types[3]);
  assertFalse(event_types[5] == event_types[7]);

  // Early listener removal, do not wait for tearDown, to avoid building up
  // arrays of events unnecessarilly in further tests.
  goog.events.removeAll(oneThumbSlider);
}

</script>
</body>
</html>
