114 lines
3.7 KiB
JavaScript
114 lines
3.7 KiB
JavaScript
|
// eslint-disable-next-line no-restricted-imports
|
||
|
import Mousetrap from 'mousetrap';
|
||
|
|
||
|
const originalMethodReturnValue = {};
|
||
|
// Create a mock stopCallback method before ~/lib/utils/mousetrap overwrites
|
||
|
// it. This allows us to spy on calls to it.
|
||
|
const mockOriginalStopCallbackMethod = jest.fn().mockReturnValue(originalMethodReturnValue);
|
||
|
Mousetrap.prototype.stopCallback = mockOriginalStopCallbackMethod;
|
||
|
|
||
|
describe('mousetrap utils', () => {
|
||
|
describe('addStopCallback', () => {
|
||
|
let addStopCallback;
|
||
|
let clearStopCallbacksForTests;
|
||
|
const mockMousetrapInstance = { isMockMousetrap: true };
|
||
|
const mockKeyboardEvent = { type: 'keydown', key: 'Enter' };
|
||
|
const mockCombo = 'enter';
|
||
|
|
||
|
const mockKeydown = ({
|
||
|
instance = mockMousetrapInstance,
|
||
|
event = mockKeyboardEvent,
|
||
|
element = document,
|
||
|
combo = mockCombo,
|
||
|
} = {}) => Mousetrap.prototype.stopCallback.call(instance, event, element, combo);
|
||
|
|
||
|
beforeEach(async () => {
|
||
|
// Import async since it mutates the Mousetrap instance, by design.
|
||
|
({ addStopCallback, clearStopCallbacksForTests } = await import('~/lib/mousetrap'));
|
||
|
clearStopCallbacksForTests();
|
||
|
});
|
||
|
|
||
|
it('delegates to the original stopCallback method when no additional callbacks added', () => {
|
||
|
const returnValue = mockKeydown();
|
||
|
|
||
|
expect(mockOriginalStopCallbackMethod).toHaveBeenCalledTimes(1);
|
||
|
|
||
|
const [thisArg] = mockOriginalStopCallbackMethod.mock.contexts;
|
||
|
const [eventArg, element, combo] = mockOriginalStopCallbackMethod.mock.calls[0];
|
||
|
|
||
|
expect(thisArg).toBe(mockMousetrapInstance);
|
||
|
expect(eventArg).toBe(mockKeyboardEvent);
|
||
|
expect(element).toBe(document);
|
||
|
expect(combo).toBe(mockCombo);
|
||
|
|
||
|
expect(returnValue).toBe(originalMethodReturnValue);
|
||
|
});
|
||
|
|
||
|
it('passes the expected arguments to the given stop callback', () => {
|
||
|
const callback = jest.fn();
|
||
|
|
||
|
addStopCallback(callback);
|
||
|
|
||
|
mockKeydown();
|
||
|
|
||
|
expect(callback).toHaveBeenCalledTimes(1);
|
||
|
|
||
|
const [thisArg] = callback.mock.contexts;
|
||
|
const [eventArg, element, combo] = callback.mock.calls[0];
|
||
|
|
||
|
expect(thisArg).toBe(mockMousetrapInstance);
|
||
|
expect(eventArg).toBe(mockKeyboardEvent);
|
||
|
expect(element).toBe(document);
|
||
|
expect(combo).toBe(mockCombo);
|
||
|
});
|
||
|
|
||
|
describe.each([true, false])('when a stop handler returns %p', (stopCallbackReturnValue) => {
|
||
|
let methodReturnValue;
|
||
|
const stopCallback = jest.fn().mockReturnValue(stopCallbackReturnValue);
|
||
|
|
||
|
beforeEach(() => {
|
||
|
addStopCallback(stopCallback);
|
||
|
|
||
|
methodReturnValue = mockKeydown();
|
||
|
});
|
||
|
|
||
|
it(`returns ${stopCallbackReturnValue}`, () => {
|
||
|
expect(methodReturnValue).toBe(stopCallbackReturnValue);
|
||
|
});
|
||
|
|
||
|
it('calls stop callback', () => {
|
||
|
expect(stopCallback).toHaveBeenCalledTimes(1);
|
||
|
});
|
||
|
|
||
|
it('does not call mockOriginalStopCallbackMethod', () => {
|
||
|
expect(mockOriginalStopCallbackMethod).not.toHaveBeenCalled();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('when a stop handler returns undefined', () => {
|
||
|
let methodReturnValue;
|
||
|
const stopCallback = jest.fn().mockReturnValue(undefined);
|
||
|
|
||
|
beforeEach(() => {
|
||
|
addStopCallback(stopCallback);
|
||
|
|
||
|
methodReturnValue = mockKeydown();
|
||
|
});
|
||
|
|
||
|
it('returns originalMethodReturnValue', () => {
|
||
|
expect(methodReturnValue).toBe(originalMethodReturnValue);
|
||
|
});
|
||
|
|
||
|
it('calls stop callback', () => {
|
||
|
expect(stopCallback).toHaveBeenCalledTimes(1);
|
||
|
});
|
||
|
|
||
|
// Because this is the only registered stop callback, the next callback
|
||
|
// is the original method.
|
||
|
it('does call original stopCallback method', () => {
|
||
|
expect(mockOriginalStopCallbackMethod).toHaveBeenCalledTimes(1);
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|