1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
// 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);
});
});
});
});
|