mirror of
https://github.com/grafana/grafana.git
synced 2025-09-18 12:03:52 +08:00

* Fix lint error in types.ts * Bump eslint and its deps to latest * Add eslintignore and remove not needed eslintrcs * Change webpack configs eslint config * Update package.jsons and removed unused eslintrc files * Chore yarn lint --fix 💅 * Add devenv to eslintignore * Remove eslint disable comments for rules that are not used * Remaining eslint fixes 💅 * Bump grafana/eslint-config 💥 * Modify package.json No need for duplicate checks. * Modify eslintignore to ignore data and dist folders * Revert removing .eslintrc to make sure not to use certain packages * Modify package.json to remove not needed command * Use gitignore for ignoring paths
300 lines
10 KiB
JavaScript
300 lines
10 KiB
JavaScript
// Copyright (c) 2017 Uber Technologies, Inc.
|
|
//
|
|
// 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.
|
|
|
|
import DraggableManager from './DraggableManager';
|
|
import EUpdateTypes from './EUpdateTypes';
|
|
|
|
describe('DraggableManager', () => {
|
|
const baseClientX = 100;
|
|
// left button mouse events have `.button === 0`
|
|
const baseMouseEvt = { button: 0, clientX: baseClientX };
|
|
const tag = 'some-tag';
|
|
let bounds;
|
|
let getBounds;
|
|
let ctorOpts;
|
|
let instance;
|
|
|
|
function startDragging(dragManager) {
|
|
dragManager.handleMouseDown({ ...baseMouseEvt, type: 'mousedown' });
|
|
expect(dragManager.isDragging()).toBe(true);
|
|
}
|
|
|
|
beforeEach(() => {
|
|
bounds = {
|
|
clientXLeft: 50,
|
|
maxValue: 0.9,
|
|
minValue: 0.1,
|
|
width: 100,
|
|
};
|
|
getBounds = jest.fn(() => bounds);
|
|
ctorOpts = {
|
|
getBounds,
|
|
tag,
|
|
onMouseEnter: jest.fn(),
|
|
onMouseLeave: jest.fn(),
|
|
onMouseMove: jest.fn(),
|
|
onDragStart: jest.fn(),
|
|
onDragMove: jest.fn(),
|
|
onDragEnd: jest.fn(),
|
|
resetBoundsOnResize: false,
|
|
};
|
|
instance = new DraggableManager(ctorOpts);
|
|
});
|
|
|
|
describe('_getPosition()', () => {
|
|
it('invokes the getBounds ctor argument', () => {
|
|
instance._getPosition(0);
|
|
expect(ctorOpts.getBounds.mock.calls).toEqual([[tag]]);
|
|
});
|
|
|
|
it('converts clientX to x and [0, 1] value', () => {
|
|
const left = 100;
|
|
const pos = instance._getPosition(left);
|
|
expect(pos).toEqual({
|
|
x: left - bounds.clientXLeft,
|
|
value: (left - bounds.clientXLeft) / bounds.width,
|
|
});
|
|
});
|
|
|
|
it('clamps x and [0, 1] value based on getBounds().minValue', () => {
|
|
const left = 0;
|
|
const pos = instance._getPosition(left);
|
|
expect(pos).toEqual({
|
|
x: bounds.minValue * bounds.width,
|
|
value: bounds.minValue,
|
|
});
|
|
});
|
|
|
|
it('clamps x and [0, 1] value based on getBounds().maxValue', () => {
|
|
const left = 10000;
|
|
const pos = instance._getPosition(left);
|
|
expect(pos).toEqual({
|
|
x: bounds.maxValue * bounds.width,
|
|
value: bounds.maxValue,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('window resize event listener', () => {
|
|
it('is added in the ctor iff `resetBoundsOnResize` param is truthy', () => {
|
|
const oldFn = window.addEventListener;
|
|
window.addEventListener = jest.fn();
|
|
|
|
ctorOpts.resetBoundsOnResize = false;
|
|
instance = new DraggableManager(ctorOpts);
|
|
expect(window.addEventListener.mock.calls).toEqual([]);
|
|
ctorOpts.resetBoundsOnResize = true;
|
|
instance = new DraggableManager(ctorOpts);
|
|
expect(window.addEventListener.mock.calls).toEqual([['resize', expect.any(Function)]]);
|
|
|
|
window.addEventListener = oldFn;
|
|
});
|
|
|
|
it('is removed in `.dispose()` iff `resetBoundsOnResize` param is truthy', () => {
|
|
const oldFn = window.removeEventListener;
|
|
window.removeEventListener = jest.fn();
|
|
|
|
ctorOpts.resetBoundsOnResize = false;
|
|
instance = new DraggableManager(ctorOpts);
|
|
instance.dispose();
|
|
expect(window.removeEventListener.mock.calls).toEqual([]);
|
|
ctorOpts.resetBoundsOnResize = true;
|
|
instance = new DraggableManager(ctorOpts);
|
|
instance.dispose();
|
|
expect(window.removeEventListener.mock.calls).toEqual([['resize', expect.any(Function)]]);
|
|
|
|
window.removeEventListener = oldFn;
|
|
});
|
|
});
|
|
|
|
describe('minor mouse events', () => {
|
|
it('throws an error for invalid event types', () => {
|
|
const type = 'invalid-event-type';
|
|
const throwers = [
|
|
() => instance.handleMouseEnter({ ...baseMouseEvt, type }),
|
|
() => instance.handleMouseMove({ ...baseMouseEvt, type }),
|
|
() => instance.handleMouseLeave({ ...baseMouseEvt, type }),
|
|
];
|
|
throwers.forEach(thrower => expect(thrower).toThrow());
|
|
});
|
|
|
|
it('does nothing if already dragging', () => {
|
|
startDragging(instance);
|
|
expect(getBounds.mock.calls.length).toBe(1);
|
|
|
|
instance.handleMouseEnter({ ...baseMouseEvt, type: 'mouseenter' });
|
|
instance.handleMouseMove({ ...baseMouseEvt, type: 'mousemove' });
|
|
instance.handleMouseLeave({ ...baseMouseEvt, type: 'mouseleave' });
|
|
expect(ctorOpts.onMouseEnter).not.toHaveBeenCalled();
|
|
expect(ctorOpts.onMouseMove).not.toHaveBeenCalled();
|
|
expect(ctorOpts.onMouseLeave).not.toHaveBeenCalled();
|
|
|
|
const evt = { ...baseMouseEvt, type: 'invalid-type' };
|
|
expect(() => instance.handleMouseEnter(evt)).not.toThrow();
|
|
|
|
expect(getBounds.mock.calls.length).toBe(1);
|
|
});
|
|
|
|
it('passes data based on the mouse event type to callbacks', () => {
|
|
const x = baseClientX - bounds.clientXLeft;
|
|
const value = (baseClientX - bounds.clientXLeft) / bounds.width;
|
|
const cases = [
|
|
{
|
|
type: 'mouseenter',
|
|
handler: instance.handleMouseEnter,
|
|
callback: ctorOpts.onMouseEnter,
|
|
updateType: EUpdateTypes.MouseEnter,
|
|
},
|
|
{
|
|
type: 'mousemove',
|
|
handler: instance.handleMouseMove,
|
|
callback: ctorOpts.onMouseMove,
|
|
updateType: EUpdateTypes.MouseMove,
|
|
},
|
|
{
|
|
type: 'mouseleave',
|
|
handler: instance.handleMouseLeave,
|
|
callback: ctorOpts.onMouseLeave,
|
|
updateType: EUpdateTypes.MouseLeave,
|
|
},
|
|
];
|
|
|
|
cases.forEach(testCase => {
|
|
const { type, handler, callback, updateType } = testCase;
|
|
const event = { ...baseMouseEvt, type };
|
|
handler(event);
|
|
expect(callback.mock.calls).toEqual([[{ event, tag, value, x, manager: instance, type: updateType }]]);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('drag events', () => {
|
|
let realWindowAddEvent;
|
|
let realWindowRmEvent;
|
|
|
|
beforeEach(() => {
|
|
realWindowAddEvent = window.addEventListener;
|
|
realWindowRmEvent = window.removeEventListener;
|
|
window.addEventListener = jest.fn();
|
|
window.removeEventListener = jest.fn();
|
|
});
|
|
|
|
afterEach(() => {
|
|
window.addEventListener = realWindowAddEvent;
|
|
window.removeEventListener = realWindowRmEvent;
|
|
});
|
|
|
|
it('throws an error for invalid event types', () => {
|
|
expect(() => instance.handleMouseDown({ ...baseMouseEvt, type: 'invalid-event-type' })).toThrow();
|
|
});
|
|
|
|
describe('mousedown', () => {
|
|
it('is ignored if already dragging', () => {
|
|
startDragging(instance);
|
|
window.addEventListener.mockReset();
|
|
ctorOpts.onDragStart.mockReset();
|
|
|
|
expect(getBounds.mock.calls.length).toBe(1);
|
|
instance.handleMouseDown({ ...baseMouseEvt, type: 'mousedown' });
|
|
expect(getBounds.mock.calls.length).toBe(1);
|
|
|
|
expect(window.addEventListener).not.toHaveBeenCalled();
|
|
expect(ctorOpts.onDragStart).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('sets `isDragging()` to true', () => {
|
|
instance.handleMouseDown({ ...baseMouseEvt, type: 'mousedown' });
|
|
expect(instance.isDragging()).toBe(true);
|
|
});
|
|
|
|
it('adds the window mouse listener events', () => {
|
|
instance.handleMouseDown({ ...baseMouseEvt, type: 'mousedown' });
|
|
expect(window.addEventListener.mock.calls).toEqual([
|
|
['mousemove', expect.any(Function)],
|
|
['mouseup', expect.any(Function)],
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('mousemove', () => {
|
|
it('is ignored if not already dragging', () => {
|
|
instance._handleDragEvent({ ...baseMouseEvt, type: 'mousemove' });
|
|
expect(ctorOpts.onDragMove).not.toHaveBeenCalled();
|
|
startDragging(instance);
|
|
instance._handleDragEvent({ ...baseMouseEvt, type: 'mousemove' });
|
|
expect(ctorOpts.onDragMove).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('mouseup', () => {
|
|
it('is ignored if not already dragging', () => {
|
|
instance._handleDragEvent({ ...baseMouseEvt, type: 'mouseup' });
|
|
expect(ctorOpts.onDragEnd).not.toHaveBeenCalled();
|
|
startDragging(instance);
|
|
instance._handleDragEvent({ ...baseMouseEvt, type: 'mouseup' });
|
|
expect(ctorOpts.onDragEnd).toHaveBeenCalled();
|
|
});
|
|
|
|
it('sets `isDragging()` to false', () => {
|
|
startDragging(instance);
|
|
expect(instance.isDragging()).toBe(true);
|
|
instance._handleDragEvent({ ...baseMouseEvt, type: 'mouseup' });
|
|
expect(instance.isDragging()).toBe(false);
|
|
});
|
|
|
|
it('removes the window mouse listener events', () => {
|
|
startDragging(instance);
|
|
expect(window.removeEventListener).not.toHaveBeenCalled();
|
|
instance._handleDragEvent({ ...baseMouseEvt, type: 'mouseup' });
|
|
expect(window.removeEventListener.mock.calls).toEqual([
|
|
['mousemove', expect.any(Function)],
|
|
['mouseup', expect.any(Function)],
|
|
]);
|
|
});
|
|
});
|
|
|
|
it('passes drag event data to the callbacks', () => {
|
|
const x = baseClientX - bounds.clientXLeft;
|
|
const value = (baseClientX - bounds.clientXLeft) / bounds.width;
|
|
const cases = [
|
|
{
|
|
type: 'mousedown',
|
|
handler: instance.handleMouseDown,
|
|
callback: ctorOpts.onDragStart,
|
|
updateType: EUpdateTypes.DragStart,
|
|
},
|
|
{
|
|
type: 'mousemove',
|
|
handler: instance._handleDragEvent,
|
|
callback: ctorOpts.onDragMove,
|
|
updateType: EUpdateTypes.DragMove,
|
|
},
|
|
{
|
|
type: 'mouseup',
|
|
handler: instance._handleDragEvent,
|
|
callback: ctorOpts.onDragEnd,
|
|
updateType: EUpdateTypes.DragEnd,
|
|
},
|
|
];
|
|
|
|
cases.forEach(testCase => {
|
|
const { type, handler, callback, updateType } = testCase;
|
|
const event = { ...baseMouseEvt, type };
|
|
handler(event);
|
|
expect(callback.mock.calls).toEqual([[{ event, tag, value, x, manager: instance, type: updateType }]]);
|
|
});
|
|
});
|
|
});
|
|
});
|