123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035 |
- // Copyright 2008 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- goog.provide('goog.ui.SliderBaseTest');
- goog.setTestOnly('goog.ui.SliderBaseTest');
- goog.require('goog.a11y.aria');
- goog.require('goog.a11y.aria.State');
- goog.require('goog.dom');
- goog.require('goog.dom.TagName');
- goog.require('goog.dom.classlist');
- 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');
- 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, undefined /* domHelper */, function(value) {
- return value > 5 ? 'A big value.' : 'A small value.';
- });
- }
- 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(
- goog.dom.TagName.DIV, {'id': 'oneThumbSlider'},
- goog.dom.createDom(goog.dom.TagName.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(
- goog.dom.TagName.DIV, {'id': 'twoThumbSlider'},
- goog.dom.createDom(goog.dom.TagName.DIV, {'id': 'rangeHighlight'}),
- goog.dom.createDom(goog.dom.TagName.SPAN, {'id': 'valueThumb'}),
- goog.dom.createDom(goog.dom.TagName.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(
- goog.dom.TagName.DIV, {'dir': 'rtl', 'style': 'position:absolute;'});
- sandBox.appendChild(sandBoxRtl);
- var oneThumbElemRtl = goog.dom.createDom(
- goog.dom.TagName.DIV, {'id': 'oneThumbSliderRtl'},
- goog.dom.createDom(goog.dom.TagName.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(
- goog.dom.TagName.DIV, {'id': 'twoThumbSliderRtl'},
- goog.dom.createDom(goog.dom.TagName.DIV, {'id': 'rangeHighlightRtl'}),
- goog.dom.createDom(goog.dom.TagName.SPAN, {'id': 'valueThumbRtl'}),
- goog.dom.createDom(goog.dom.TagName.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() {
- oneThumbSlider.dispose();
- twoThumbSlider.dispose();
- oneThumbSliderRtl.dispose();
- twoThumbSliderRtl.dispose();
- mockClock.dispose();
- goog.dom.removeChildren(goog.dom.getElement('sandbox'));
- }
- 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 testValueText() {
- oneThumbSlider.setValue(10);
- assertEquals(
- 'Setting value results in correct aria-valuetext', 'A big value.',
- goog.a11y.aria.getState(
- oneThumbSlider.getElement(), goog.a11y.aria.State.VALUETEXT));
- oneThumbSlider.setValue(2);
- assertEquals(
- 'Updating value results in updated aria-valuetext', 'A small value.',
- goog.a11y.aria.getState(
- oneThumbSlider.getElement(), goog.a11y.aria.State.VALUETEXT));
- }
- function testGetValueText() {
- oneThumbSlider.setValue(10);
- assertEquals(
- 'Getting the text value gets the correct description', 'A big value.',
- oneThumbSlider.getTextValue());
- oneThumbSlider.setValue(2);
- assertEquals(
- 'Getting the updated text value gets the correct updated description',
- 'A small value.', oneThumbSlider.getTextValue());
- }
- 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 testKeyHandlingLargeStepSize() {
- twoThumbSlider.setValue(0);
- twoThumbSlider.setExtent(100);
- twoThumbSlider.setStep(5);
- assertEquals(0, twoThumbSlider.getValue());
- assertEquals(100, twoThumbSlider.getExtent());
- goog.testing.events.fireKeySequence(
- twoThumbSlider.getElement(), goog.events.KeyCodes.RIGHT);
- assertEquals(5, twoThumbSlider.getValue());
- assertEquals(95, twoThumbSlider.getExtent());
- goog.testing.events.fireKeySequence(
- twoThumbSlider.getElement(), goog.events.KeyCodes.RIGHT);
- assertEquals(10, twoThumbSlider.getValue());
- assertEquals(90, twoThumbSlider.getExtent());
- goog.testing.events.fireKeySequence(
- twoThumbSlider.getElement(), goog.events.KeyCodes.LEFT);
- assertEquals(5, twoThumbSlider.getValue());
- assertEquals(90, twoThumbSlider.getExtent());
- goog.testing.events.fireKeySequence(
- twoThumbSlider.getElement(), goog.events.KeyCodes.LEFT);
- assertEquals(0, twoThumbSlider.getValue());
- assertEquals(90, 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(
- goog.dom.TagName.DIV, {}, goog.dom.createDom(goog.dom.TagName.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.classlist.contains(
- 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.classlist.contains(
- 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);
- }
- 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);
- }
- function testSingleThumbSliderHasZeroExtent() {
- var stepSize = 0.02;
- oneThumbSlider.setStep(stepSize);
- oneThumbSlider.setMinimum(-1);
- oneThumbSlider.setMaximum(1);
- oneThumbSlider.setValue(0.7);
- assertEquals(0, oneThumbSlider.getExtent());
- oneThumbSlider.setValue(0.3);
- assertEquals(0, oneThumbSlider.getExtent());
- }
- /**
- * 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);
- assertRoughlyEquals(
- value, Math.round(oneThumbSlider.getValueFromMousePosition(e)), 1);
- // Verify this works regardless of current position.
- oneThumbSlider.setValue(value / 2);
- assertRoughlyEquals(
- value, Math.round(oneThumbSlider.getValueFromMousePosition(e)), 1);
- }
- /**
- * Tests ignoring click event after mousedown event.
- */
- function testClickAfterMousedown() {
- // Get the center of the thumb at value zero.
- oneThumbSlider.setValue(0);
- 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 sliderElement = oneThumbSlider.getElement();
- var width = sliderElement.clientWidth - size.width;
- var range = oneThumbSlider.getMaximum() - oneThumbSlider.getMinimum();
- var offsetXAtZero = offset.x;
- // Temporarily control time.
- var theTime = goog.now();
- var saveGoogNow = goog.now;
- goog.now = function() { return theTime; };
- // set coordinate for a particular value.
- var valueOne = 10;
- offset.x = offsetXAtZero + Math.round(valueOne / range * width);
- goog.testing.events.fireMouseDownEvent(sliderElement, null, offset);
- assertEquals(valueOne, oneThumbSlider.getValue());
- // Verify a click event with another value that follows quickly is ignored.
- theTime += oneThumbSlider.MOUSE_DOWN_DELAY_ / 2;
- var valueTwo = 20;
- offset.x = offsetXAtZero + Math.round(valueTwo / range * width);
- goog.testing.events.fireClickEvent(sliderElement, null, offset);
- assertEquals(valueOne, oneThumbSlider.getValue());
- // Verify a click later in time does move the thumb.
- theTime += oneThumbSlider.MOUSE_DOWN_DELAY_;
- goog.testing.events.fireClickEvent(sliderElement, null, offset);
- assertEquals(valueTwo, oneThumbSlider.getValue());
- goog.now = saveGoogNow;
- }
- /**
- * 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
- // across 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);
- }
- /**
- * Tests animationend event after click.
- */
- function testAnimationEndEventAfterClick() {
- 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);
- };
- 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;
- }
- oneThumbSlider.setMoveToPointEnabled(true);
- goog.events.listen(
- oneThumbSlider, goog.ui.SliderBase.EventType.ANIMATION_END, handler);
- function isAnimationEndType(type) {
- return type == goog.ui.SliderBase.EventType.ANIMATION_END;
- }
- offset.x += 100;
- goog.testing.events.fireClickSequence(
- oneThumbSlider.getElement(), /* opt_button */ undefined, offset);
- mockClock.tick(animationDelay);
- assertEquals(1, event_types.length);
- assertTrue(isAnimationEndType(event_types[0]));
- goog.events.removeAll(oneThumbSlider);
- }
|