123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699 |
- /*
- *************************
- Lock To Ticks Tests
- *************************
- Verify that the when lock_to_ticks is true, the selected values will be snapped to closest tick values
- */
- describe("Slider with lock_to_ticks: true tests", function() {
- var testSlider;
- it("Should set `options.lock_to_ticks` to false when `ticks[]` is not set", function() {
- testSlider = $('#testSlider1').slider({
- lock_to_ticks: true
- });
- var lockAttr = testSlider.slider('getAttribute', 'lock_to_ticks');
- expect(lockAttr).toBe(false);
- });
- it("Should set the slider value when `ticks[]` is not set", function() {
- testSlider = $('#testSlider1').slider({
- min: 0,
- max: 10,
- value: 1,
- lock_to_ticks: true
- });
- testSlider.slider('setValue', 5);
- var value = testSlider.slider('getValue');
- expect(value).toBe(5);
- });
- it("Should return a value (after calling `setAttribute()`)", function() {
- testSlider = $('#testSlider1').slider({
- min: 0,
- max: 10,
- value: 1,
- lock_to_ticks: true
- });
- // Try to lock to ticks when there are no ticks[]
- testSlider.slider('setAttribute', 'lock_to_ticks', true);
- testSlider.slider('setValue', 5);
- // Without proper checking, getValue() is going to return NaN in this case
- var value = testSlider.slider('getValue');
- expect(isNaN(value)).toBe(false);
- });
- it("Should snap to closest tick value (single)", function() {
- testSlider = $('#testSlider1').slider({
- value: 1,
- ticks: [1, 10, 50, 200, 500, 1000, 5000, 10000],
- lock_to_ticks: true
- });
- // Set a value that is not a tick
- testSlider.slider('setValue', 102);
- var value = testSlider.slider('getValue');
- expect(value).toBe(50);
- });
- it("Should snap to closest tick value (single, vertical)", function() {
- testSlider = $('#testSlider1').slider({
- value: 1,
- ticks: [1, 10, 50, 200, 500, 1000, 5000, 10000],
- lock_to_ticks: true,
- orientation: 'vertical'
- });
- //selecting values that are not inside tickes
- testSlider.slider('setValue', 102);
- //getting the actual values. They should be the closest values from ticks (which are 1 and 50 on this case)
- var value = testSlider.slider('getValue');
- expect(value).toBe(50);
- });
- it("Should snap to closest tick value (range)", function() {
- testSlider = $("#testSlider1").slider({
- value: [1, 10000],
- ticks: [1, 10, 50, 200, 500, 1000, 5000, 10000],
- lock_to_ticks: true
- });
- //selecting values that are not inside tickes
- testSlider.slider("setValue", [4, 102]);
- //getting the actual values. They should be the closest values from ticks (which are 1 and 50 on this case)
- var values = testSlider.slider("getValue");
- expect(values[0]).toBe(1);
- expect(values[1]).toBe(50);
- });
- it("Should snap to closest tick value (range, vertical)", function() {
- testSlider = $("#testSlider1").slider({
- value: [1, 10000],
- ticks: [1, 10, 50, 200, 500, 1000, 5000, 10000],
- lock_to_ticks: true,
- orientation: 'vertical'
- });
- //selecting values that are not inside tickes
- testSlider.slider("setValue", [4, 102]);
- //getting the actual values. They should be the closest values from ticks (which are 1 and 50 on this case)
- var values = testSlider.slider("getValue");
- expect(values[0]).toBe(1);
- expect(values[1]).toBe(50);
- });
- afterEach(function() {
- if(testSlider) {
- testSlider.slider('destroy');
- testSlider = null;
- }
- });
- });
- /**
- * The mouse navigation tests are based on the following slider properties:
- *
- * initial value: 3 or [3, 7]
- * ticks: [0, 3, 5, 7, 10]
- * step: 0.1
- *
- * When the values are in the range from 0 to 10 and the step is 0.1, every value
- * can be represented as 1% of the range. For example, 5.5 is 55% and 5.6 is 56%.
- * This makes it easier to test the behaviour of tick locking.
- *
- * The mouse clicks are based on a percentage that represents where the user clicked
- * on the slider (60% = 6.0). The percentage is then used to calculate the coordinates
- * for the mouse events (mousedown, mousemove, and mouseup).
- *
- * These tests are setup to test for all combinations of relevant slider configurations:
- * single/range, horizontal/vertical orientation, LTR/RTL, and ordered/reversed.
- * The tests also check that the handles have the correct positioning, which should
- * match the ticks that the handles lock to.
- *
- * The test data was carefully chosen based on following the test logic below.
- *
- * The test logic for sliders:
- * - Clicking to the left of the handle should not change its value
- * - Clicking to the left of the handle should change its value and lock to another tick
- * - Ditto for clicking to the right of the handle
- *
- * For range sliders, the same logic is applied except test both handle1 and handle2.
- */
- describe("`lock_to_ticks: true` mouse navigation test cases", function() {
- var initialValue = 3;
- var initialRangeValues = [3, 7];
- var tickValues = [0, 3, 5, 7, 10];
- // Quick lookup from value to index
- var tickIndexes = {0: 0, 3: 1, 5: 2, 7: 3, 10: 4};
- var stepValue = 0.1;
- var orientations = ['horizontal', 'vertical'];
- var reversed = [false, true];
- var sliderTypes = ['single', 'range'];
- var rtl = [false, true];
- var testCases = [];
- var mouseEventArguments;
- function calcMouseEventCoords(sliderElem, orientation, per) {
- var sliderBB = sliderElem.getBoundingClientRect();
- if (orientation === 'horizontal') {
- return {
- clientX: sliderBB.left + (sliderElem.offsetWidth * per / 100),
- clientY: sliderBB.top
- };
- }
- else if (orientation === 'vertical') {
- return {
- clientX: sliderBB.left,
- clientY: sliderBB.top + (sliderElem.offsetHeight * per / 100)
- };
- }
- }
- beforeEach(function() {
- // Set up default set of mouse event arguments
- mouseEventArguments = [
- 'mousemove', // type
- true, // canBubble
- true, // cancelable
- document, // view,
- 0, // detail
- 0, // screenX
- 0, // screenY
- undefined, // clientX
- undefined, // clientY,
- false, // ctrlKey
- false, // altKey
- false, // shiftKey
- false, // metaKey,
- 0, // button
- null // relatedTarget
- ];
- });
- function createMouseEvent(type, clientX, clientY) {
- var mouseEvent = document.createEvent('MouseEvent');
- mouseEventArguments[0] = type;
- mouseEventArguments[7] = clientX;
- mouseEventArguments[8] = clientY;
- mouseEvent.initMouseEvent.apply(mouseEvent, mouseEventArguments);
- return mouseEvent;
- }
- var mouseTestData = {
- single: {
- testData: [{
- willChange: false,
- expectedValue: initialValue,
- percent: 20
- }, {
- willChange: true,
- expectedValue: 0,
- percent: 10
- }, {
- willChange: false,
- expectedValue: initialValue,
- percent: 40
- }, {
- willChange: true,
- expectedValue: 5,
- percent: 45
- }],
- // Modify test data for RTL and reversed situations.
- altTestData: [{
- willChange: false,
- expectedValue: initialValue,
- percent: 80
- }, {
- willChange: true,
- expectedValue: 0,
- percent: 90
- }, {
- willChange: false,
- expectedValue: initialValue,
- percent: 60
- }, {
- willChange: true,
- expectedValue: 5,
- percent: 55
- }],
- },
- range: {
- testData: [{
- willChange: false,
- expectedValue: initialRangeValues,
- percent: 20
- }, {
- willChange: true,
- expectedValue: [0, 7],
- percent: 10
- }, {
- willChange: false,
- expectedValue: initialRangeValues,
- percent: 40
- }, {
- willChange: true,
- expectedValue: [5, 7],
- percent: 45
- },
- // More test data that will affect handle2
- {
- willChange: true,
- expectedValue: [3, 5],
- percent: 60
- }, {
- willChange: false,
- expectedValue: initialRangeValues,
- percent: 65
- }, {
- willChange: false,
- expectedValue: initialRangeValues,
- percent: 80
- }, {
- willChange: true,
- expectedValue: [3, 10],
- percent: 90
- }],
- // Modify test data for RTL and reversed situations.
- // Here, the order of the ticks matter when locking a handle to a tick
- // when there are two ticks that are equal in distance to lock to.
- altTestData: [{
- willChange: false,
- expectedValue: initialRangeValues,
- percent: 20
- }, {
- willChange: true,
- expectedValue: [3, 10],
- percent: 10
- }, {
- willChange: true,
- expectedValue: [3, 5],
- percent: 40
- }, {
- willChange: false,
- expectedValue: initialRangeValues,
- percent: 35
- },
- // More test data that will affect handle2
- {
- willChange: false,
- expectedValue: initialRangeValues,
- percent: 60
- }, {
- willChange: true,
- expectedValue: [5, 7],
- percent: 55
- }, {
- willChange: false,
- expectedValue: initialRangeValues,
- percent: 80
- }, {
- willChange: true,
- expectedValue: [0, 7],
- percent: 90
- }],
- }
- };
- sliderTypes.forEach(function(sliderType) {
- orientations.forEach(function(orientation) {
- rtl.forEach(function(isRTL) {
- reversed.forEach(function(isReversed) {
- var isHorizontal = orientation === 'horizontal';
- var isVertical = orientation === 'vertical';
- var isRange = sliderType === 'range';
- var whichData;
- var whichStyle;
- whichData = mouseTestData[sliderType].testData;
- if (isHorizontal) {
- // XOR
- // One or the other needs to be true
- if ((isRTL && !isReversed) || (isReversed && !isRTL)) {
- whichData = mouseTestData[sliderType].altTestData;
- }
- }
- else if (isVertical) {
- if (isReversed) {
- whichData = mouseTestData[sliderType].altTestData;
- }
- }
- if (isHorizontal) {
- if (isRTL) {
- whichStyle = 'right';
- }
- else {
- whichStyle = 'left';
- }
- }
- else if (isVertical) {
- whichStyle = 'top';
- }
- testCases.push({
- value: isRange ? initialRangeValues : initialValue,
- step: stepValue,
- range: isRange,
- orientation: orientation,
- reversed: isReversed,
- rtl: 'auto',
- isRTL: isRTL,
- inputId: isRTL ? 'rtlSlider' : 'testSlider1',
- testData: whichData,
- stylePos: whichStyle
- });
- });
- });
- });
- });
- testCases.forEach(function(testCase) {
- describe("range=" + testCase.range + ", orientation=" + testCase.orientation +
- ", rtl=" + testCase.isRTL + ", reversed=" + testCase.reversed, function() {
- var $testSlider;
- var $handle1;
- var $handle2;
- var sliderId;
- var sliderOptions;
- var $tick1;
- var $tick2;
- var $ticks;
- beforeEach(function() {
- sliderId = testCase.range ? 'myRangeSlider' : 'mySlider';
- sliderOptions = {
- id: sliderId,
- step: testCase.step,
- orientation: testCase.orientation,
- value: testCase.value,
- range: testCase.range,
- lock_to_ticks: true,
- reversed: testCase.reversed,
- rtl: 'auto',
- ticks: tickValues,
- };
- });
- afterEach(function() {
- if ($testSlider) {
- $testSlider.slider('destroy');
- $testSlider = null;
- }
- });
- testCase.testData.forEach(function(testData) {
- it("Should snap to closest tick (percent=" + testData.percent + ", changed=" + testData.willChange + ")", function(done) {
- $testSlider = $('#'+testCase.inputId).slider(sliderOptions);
- var sliderElem = $('#'+sliderId)[0];
- $ticks = $('#'+sliderId).find('.slider-tick');
- $handle1 = $('#'+sliderId).find('.slider-handle:first');
- $handle2 = $('#'+sliderId).find('.slider-handle:last');
- var coords = calcMouseEventCoords(sliderElem, testCase.orientation, testData.percent);
- var checkMouseMove = function() {
- var value = $testSlider.slider('getValue');
- expect(value).toEqual(testData.expectedValue);
- if (testCase.range) {
- $tick1 = $ticks.eq(tickIndexes[testData.expectedValue[0]]);
- $tick2 = $ticks.eq(tickIndexes[testData.expectedValue[1]]);
- expect($handle1.css(testCase.stylePos)).toBe($tick1.css(testCase.stylePos));
- expect($handle2.css(testCase.stylePos)).toBe($tick2.css(testCase.stylePos));
- }
- else {
- $tick1 = $ticks.eq(tickIndexes[testData.expectedValue]);
- expect($handle1.css(testCase.stylePos)).toBe($tick1.css(testCase.stylePos));
- }
- };
- var checkMouseUp = function() {
- var value = $testSlider.slider('getValue');
- expect(value).toEqual(testData.expectedValue);
- if (testCase.range) {
- $tick1 = $ticks.eq(tickIndexes[testData.expectedValue[0]]);
- $tick2 = $ticks.eq(tickIndexes[testData.expectedValue[1]]);
- expect($handle1.css(testCase.stylePos)).toBe($tick1.css(testCase.stylePos));
- expect($handle2.css(testCase.stylePos)).toBe($tick2.css(testCase.stylePos));
- }
- else {
- $tick1 = $ticks.eq(tickIndexes[testData.expectedValue]);
- expect($handle1.css(testCase.stylePos)).toBe($tick1.css(testCase.stylePos));
- }
- document.removeEventListener('mousemove', checkMouseMove, false);
- document.removeEventListener('mouseup', checkMouseUp, false);
- done();
- };
- sliderElem.addEventListener('mousedown', function() {
- var value = $testSlider.slider('getValue');
- expect(value).toEqual(testData.expectedValue);
- // Check position of handles
- if (testCase.range) {
- $tick1 = $ticks.eq(tickIndexes[testData.expectedValue[0]]);
- $tick2 = $ticks.eq(tickIndexes[testData.expectedValue[1]]);
- expect($handle1.css(testCase.stylePos)).toBe($tick1.css(testCase.stylePos));
- expect($handle2.css(testCase.stylePos)).toBe($tick2.css(testCase.stylePos));
- }
- else {
- $tick1 = $ticks.eq(tickIndexes[testData.expectedValue]);
- expect($handle1.css(testCase.stylePos)).toBe($tick1.css(testCase.stylePos));
- }
- document.addEventListener('mousemove', checkMouseMove, false);
- document.addEventListener('mouseup', checkMouseUp, false);
- });
- sliderElem.dispatchEvent(createMouseEvent('mousedown', coords.clientX, coords.clientY));
- document.dispatchEvent(createMouseEvent('mousemove', coords.clientX, coords.clientY));
- document.dispatchEvent(createMouseEvent('mouseup', coords.clientX, coords.clientY));
- });
- });
- });
- });
- });
- /**
- * The keyboard navigation tests are based on the following slider properties:
- *
- * initial value: 3 or [3, 7]
- * ticks: [0, 3, 5, 7, 10]
- * step: 0.1
- *
- * See description for mouse navigation tests for explanation for test setup values.
- *
- * These tests are setup to test for all combinations of relevant slider configurations:
- * single/range, horizontal/vertical orientation, LTR/RTL, natural keys navigation,
- * ordered/reversed, and all key presses (left, up, right, down).
- *
- * The test data is fairly straightforward and passes most configurations except for
- * special cases when using natural key navigation. For these cases, the test data
- * had to be 'inverted'. For example, the test data had to be inverted when the
- * slider has a horizontal orientation with either RTL or reversed option set (but not both).
- *
- * The test logic for sliders:
- * - Key to the left should change the value and lock to the tick to the left
- * - Key to the right should change the value and lock to the tick to the right
- *
- * For range sliders, the same logic is applied except test both handle1 and handle2.
- */
- describe("`lock_to_ticks: true` keyboard navigation test cases", function() {
- var initialValue = 3;
- var initialRangeValues = [3, 7];
- var tickValues = [0, 3, 5, 7, 10];
- var stepValue = 0.1;
- var keyData = {
- left: 37,
- up: 38,
- right: 39,
- down: 40
- };
- var keys = ['left', 'up', 'right', 'down'];
- var orientations = ['horizontal', 'vertical'];
- var reversed = [false, true];
- var naturalKeys = [false, true];
- var ranged = [false, true];
- var rtl = [false, true];
- var rangeHandles = ['handle1', 'handle2'];
- var testCases = [];
- orientations.forEach(function(orientation) {
- ranged.forEach(function(isRange) {
- rtl.forEach(function(isRTL) {
- naturalKeys.forEach(function(isNatural) {
- reversed.forEach(function(isReversed) {
- testCases.push({
- value: isRange ? initialRangeValues : initialValue,
- step: stepValue,
- range: isRange,
- orientation: orientation,
- reversed: isReversed,
- rtl: 'auto',
- natural_arrow_keys: isNatural,
- isRTL: isRTL,
- inputId: isRTL ? 'rtlSlider' : 'testSlider1',
- });
- });
- });
- });
- });
- });
- testCases.forEach(function(testCase) {
- var handles = testCase.range ? rangeHandles : ['handle1'];
- describe("orientation=" + testCase.orientation + ", range=" + testCase.range + ", rtl=" + testCase.isRTL +
- ", natural_arrow_keys=" + testCase.natural_arrow_keys +
- ", reversed=" + testCase.reversed, function() {
- var $testSlider;
- var $handle;
- var keyboardEvent;
- var sliderId;
- var sliderOptions;
- beforeEach(function() {
- sliderId = testCase.range ? 'myRangeSlider' : 'mySlider';
- sliderOptions = {
- id: sliderId,
- step: testCase.step,
- orientation: testCase.orientation,
- value: testCase.value,
- range: testCase.range,
- lock_to_ticks: true,
- reversed: testCase.reversed,
- rtl: 'auto',
- natural_arrow_keys: testCase.natural_arrow_keys,
- ticks: tickValues,
- };
- // Create keyboard event
- keyboardEvent = document.createEvent('Event');
- keyboardEvent.initEvent('keydown', true, true);
- });
- afterEach(function() {
- keyboardEvent = null;
- if ($testSlider) {
- $testSlider.slider('destroy');
- $testSlider = null;
- }
- });
- handles.forEach(function(handleKey) {
- keys.forEach(function(key) {
- var isHorizontal = testCase.orientation === 'horizontal';
- var isVertical = testCase.orientation === 'vertical';
- var isRange = testCase.range;
- var isRTL = testCase.isRTL;
- var isReversed = testCase.reversed;
- var isNatural = testCase.natural_arrow_keys;
- var testData = {
- keyCode: keyData[key],
- handle1: {
- expectedValue: null
- },
- handle2: {
- expectedValue: null
- }
- };
- if (isRange) {
- // If initial value is [3, 7] Then
- // These expected values will pass 96/128 tests (32 failures)
- if (key === 'left' || key === 'down') {
- testData.handle1.expectedValue = [0, 7];
- testData.handle2.expectedValue = [3, 5];
- }
- else if (key === 'right' || key === 'up') {
- testData.handle1.expectedValue = [5, 7];
- testData.handle2.expectedValue = [3, 10];
- }
- // Special cases when using natural keys
- if (isNatural) {
- if ((isHorizontal && isReversed && !isRTL) ||
- (isHorizontal && isRTL && !isReversed) ||
- (isVertical && !isReversed))
- {
- if (key === 'left' || key === 'down') {
- testData.handle1.expectedValue = [5, 7];
- testData.handle2.expectedValue = [3, 10];
- }
- else if (key === 'right' || key === 'up') {
- testData.handle1.expectedValue = [0, 7];
- testData.handle2.expectedValue = [3, 5];
- }
- }
- }
- }
- else {
- // If initial value is 3 Then
- // These expected values will pass 48/64 tests (16 failures)
- if (key === 'left' || key === 'down') {
- testData.handle1.expectedValue = 0;
- }
- else if (key === 'right' || key === 'up') {
- testData.handle1.expectedValue = 5;
- }
- // Special cases when using natural keys
- if (isNatural) {
- // XOR
- // One or the other needs to be true
- if ((isHorizontal && isReversed && !isRTL) ||
- (isHorizontal && isRTL && !isReversed) ||
- (isVertical && !isReversed))
- {
- if (key === 'left' || key === 'down') {
- testData.handle1.expectedValue = 5;
- }
- else if (key === 'right' || key === 'up') {
- testData.handle1.expectedValue = 0;
- }
- }
- }
- }
- it("Should lock to tick (" + handleKey + ", key=" + key + ")", function(done) {
- $testSlider = $('#'+testCase.inputId).slider(sliderOptions);
- $handle = $('#'+sliderId).find('.slider-handle:' + (handleKey === 'handle1' ? 'first' : 'last'));
- $handle.on('keydown', function() {
- var value = $testSlider.slider('getValue');
- expect(value).toEqual(testData[handleKey].expectedValue);
- done();
- });
- keyboardEvent.keyCode = keyboardEvent.which = testData.keyCode;
- $handle[0].dispatchEvent(keyboardEvent);
- });
- });
- });
- });
- });
- });
|