@shopgate/engage
Version:
Shopgate's ENGAGE library.
193 lines (187 loc) • 6.6 kB
JavaScript
/* eslint-disable function-call-argument-newline */
import React from 'react';
import { shallow, mount } from 'enzyme';
import RangeSlider from "./index";
import RangeSliderHandle from "./components/Handle";
import { generateLinearEasingCallback, generateExponentialEasingCallback, getAbsoluteValue, getRelativeValue } from "./helper";
/**
* Creates a (fake) touch event.
* @param {number} pageX the x page offset of the simulated touch event
* @returns {Object} the new fake event containing only the properties required for testing.
*/
import { jsx as _jsx } from "react/jsx-runtime";
const createTouchEvent = pageX => {
// Simulate a handle of 16px width.
const simulatedHandleWidth = 16;
const simulatedHandleHalfWidth = simulatedHandleWidth / 2;
const touchEvent = {
target: {
offsetWidth: simulatedHandleWidth,
getBoundingClientRect: () => ({
// Simulate a touch on the center of the handle.
left: pageX - simulatedHandleHalfWidth
})
},
touches: [{
pageX
}]
};
return touchEvent;
};
/**
* Simulates a series of touch events.
* This function will automatically validate the from/to values of the range slider.
* An extra testCallback may be provided to perform additional checks.
*
* @param {number} pxWidth The simulated width of the DOM element (in px).
* @param {number} pxOffset The simulated left offset of the DOM element (in px).
* @param {number} min The absolute minimum value of the slider.
* @param {number} max The absolute maximum value of the slider.
* @param {Array} value The initial value(s) of the slider.
* @param {string} easing The name of the easing function.
* @param {number} resolutionOrFactor The resolution or factor for the easing function.
* @param {Array} simulateSteps A set of relative horizontal pixel movements to simulate.
* @param {Function} testCallback An optional callback for the onChange event of the slider.
*/
const simulateInputTest = (pxWidth, pxOffset, min, max, value, easing, resolutionOrFactor, simulateSteps, testCallback) => {
const config = {
totalPixelWidth: pxWidth,
leftPixelOffset: pxOffset,
min,
max,
easing,
resolution: resolutionOrFactor,
factor: resolutionOrFactor,
initialValue: value,
valuePixelSize: pxWidth / (max - min),
currentTouchDeltaX: 0
};
config.currentTouchDeltaX = config.valuePixelSize * value[1];
const ease = {
linear: generateLinearEasingCallback(config.resolution),
exponential: generateExponentialEasingCallback(config.factor)
}[config.easing];
// eslint-disable-next-line require-jsdoc
const callback = ([from, to]) => {
const {
currentTouchDeltaX,
valuePixelSize
} = config;
const relativeValue = getRelativeValue(currentTouchDeltaX / valuePixelSize, min, max);
const expected = getAbsoluteValue(ease(relativeValue), config.min, config.max, true);
expect(expected === from || expected === to).toBe(true);
if (testCallback) {
testCallback(config, from, to);
}
};
const wrapper = mount(/*#__PURE__*/_jsx(RangeSlider, {
min: config.min,
max: config.max,
value: config.initialValue,
easing: easing,
resolution: config.resolution,
factor: config.factor,
onChange: callback
}));
expect(wrapper).toMatchSnapshot();
// Create a simulated touch event.
const pageX = config.leftPixelOffset + config.currentTouchDeltaX;
const touchEvent = createTouchEvent(pageX);
const inst = wrapper.instance();
inst.handleTouchStart(touchEvent, 1);
simulateSteps.forEach(deltaX => {
config.currentTouchDeltaX += deltaX;
touchEvent.touches[0].pageX = config.leftPixelOffset + config.currentTouchDeltaX;
Object.defineProperty(inst.domElement, 'offsetLeft', {
get: () => config.leftPixelOffset,
configurable: true
});
Object.defineProperty(inst.domElement, 'offsetWidth', {
get: () => config.totalPixelWidth,
configurable: true
});
inst.handleTouchMove(touchEvent);
});
inst.handleTouchEnd();
};
describe.skip('<RangeSlider />', () => {
/**
* Simple attribute tests
*/
it('renders with boundaries', () => {
const wrapper = shallow(/*#__PURE__*/_jsx(RangeSlider, {
min: 0,
max: 100
}));
expect(wrapper).toMatchSnapshot();
expect(wrapper.find(RangeSliderHandle).length).toBe(2);
});
it('renders without boundaries', () => {
const wrapper = shallow(/*#__PURE__*/_jsx(RangeSlider, {}));
expect(wrapper).toMatchSnapshot();
expect(wrapper.find(RangeSliderHandle).length).toBe(2);
});
it('renders without a value pair', () => {
const wrapper = shallow(/*#__PURE__*/_jsx(RangeSlider, {
value: [10, 50]
}));
expect(wrapper).toMatchSnapshot();
expect(wrapper.find(RangeSliderHandle).length).toBe(2);
});
/**
* Callback tests
*/
it('emits onChange if handle was touched (linear)', () => {
simulateInputTest(100, 73,
// Range slider pixel width and offset.
0, 100,
// Range slider minimum and maximum value.
[50, 75],
// Initial value.
'linear',
// Which wasing should be used.
0.01,
// Resolution.
[
// A series of pixel offsets to move the slider handle.
+0, +3, -15, +17, -80, +75]);
});
it('emits onChange if handle was touched (exponential)', () => {
simulateInputTest(78, 12,
// Range slider pixel width and offset.
0, 1000,
// Range slider minimum maximum value.
[10, 450],
// Initial value.
'exponential',
// Which wasing should be used.
0.01,
// Resolution.
[
// A series of pixel offsets to move the slider handle.
+10, +10, +10, +10, +10, +10, +10, +10, -10, -10, -10, -10, -10, -10, -10, -10, +3, -15, +17, -80, +104, -23, -12, +67]);
});
it('emits onChange if the outer range was touched', () => {
// eslint-disable-next-line require-jsdoc
const callback = value => expect(value).toEqual([-80, 0]);
const wrapper = mount(/*#__PURE__*/_jsx(RangeSlider, {
min: -100,
max: 100,
value: [0, 0],
onChange: callback
}));
// Create a simulated touch event at a page x offset of 20px.
const touchEvent = createTouchEvent(20);
const inst = wrapper.instance();
Object.defineProperty(inst.domElement, 'offsetLeft', {
get: () => 0,
configurable: true
});
Object.defineProperty(inst.domElement, 'offsetWidth', {
get: () => 200,
configurable: true
});
inst.handleRangeTouch(touchEvent);
});
});
/* eslint-enable function-call-argument-newline */