@pie-lib/plot 2.27.2 → 2.27.3-next.155

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,20 @@
1
- import { shallow } from 'enzyme';
1
+ import { render } from '@testing-library/react';
2
2
  import React from 'react';
3
3
  import { gridDraggable } from '../grid-draggable';
4
4
  import { getDelta } from '../utils';
5
-
6
5
  import { clientPoint } from 'd3-selection';
7
6
 
8
7
  jest.mock('d3-selection', () => ({
9
8
  clientPoint: jest.fn().mockReturnValue([0, 0]),
10
9
  }));
11
10
 
11
+ let mockDraggableCoreProps;
12
12
  jest.mock('../draggable', () => ({
13
- DraggableCore: jest.fn((type, props, children) => children),
13
+ DraggableCore: (props) => {
14
+ // Store the props so tests can call the handlers
15
+ mockDraggableCoreProps = props;
16
+ return props.children;
17
+ },
14
18
  }));
15
19
 
16
20
  jest.mock('../utils', () => ({
@@ -22,6 +26,7 @@ const xyFn = () => {
22
26
  out.invert = jest.fn((n) => n);
23
27
  return out;
24
28
  };
29
+
25
30
  const getGraphProps = () => ({
26
31
  scale: {
27
32
  x: xyFn(),
@@ -45,282 +50,430 @@ const getGraphProps = () => ({
45
50
  width: 500,
46
51
  height: 500,
47
52
  },
48
- getRootNode: () => ({}),
53
+ getRootNode: () => ({
54
+ ownerSVGElement: null,
55
+ getBoundingClientRect: () => ({
56
+ left: 0,
57
+ top: 0,
58
+ right: 100,
59
+ bottom: 100,
60
+ }),
61
+ }),
49
62
  });
50
63
 
51
64
  describe('gridDraggable', () => {
52
- const wrapper = (opts, extras) => {
53
- const defaults = {
54
- graphProps: getGraphProps(),
55
- };
56
-
57
- defaults.graphProps.scale.x.invert = jest.fn((x) => x);
58
- defaults.graphProps.scale.y.invert = jest.fn((x) => x);
65
+ let defaultOptions;
66
+ let defaultProps;
59
67
 
60
- const props = { ...defaults, ...extras };
61
-
62
- opts = {
68
+ beforeEach(() => {
69
+ mockDraggableCoreProps = null;
70
+ defaultOptions = {
63
71
  anchorPoint: jest.fn().mockReturnValue({ x: 0, y: 0 }),
64
72
  bounds: jest.fn().mockReturnValue({ left: 0, top: 0, bottom: 0, right: 0 }),
65
73
  fromDelta: jest.fn(),
66
- ...opts,
67
74
  };
68
75
 
69
- const Comp = gridDraggable(opts)(() => <div />);
70
- return shallow(<Comp {...props} />);
71
- };
76
+ defaultProps = {
77
+ graphProps: getGraphProps(),
78
+ };
79
+ });
72
80
 
73
- describe('snapshot', () => {
74
- it('reqular', () => {
75
- const w = wrapper();
76
- expect(w).toMatchSnapshot();
77
- });
81
+ it('renders regular component', () => {
82
+ const Comp = gridDraggable(defaultOptions)(() => <div>Test</div>);
83
+ const { container } = render(<Comp {...defaultProps} />);
84
+ expect(container.firstChild).toBeInTheDocument();
85
+ });
78
86
 
79
- it('render with decimals', () => {
80
- const w = wrapper(
81
- {},
82
- {
83
- domain: {
84
- min: -1.5,
85
- max: 1.6,
86
- step: 0.3,
87
- },
88
- range: {
89
- min: -2,
90
- max: 3,
91
- step: 0.2,
92
- },
87
+ it('renders with decimal domain and range', () => {
88
+ const props = {
89
+ ...defaultProps,
90
+ graphProps: {
91
+ ...getGraphProps(),
92
+ domain: {
93
+ min: -1.5,
94
+ max: 1.6,
95
+ step: 0.3,
93
96
  },
94
- );
95
- expect(w).toMatchSnapshot();
96
- });
97
+ range: {
98
+ min: -2,
99
+ max: 3,
100
+ step: 0.2,
101
+ },
102
+ },
103
+ };
104
+ const Comp = gridDraggable(defaultOptions)(() => <div>Test</div>);
105
+ const { container } = render(<Comp {...props} />);
106
+ expect(container.firstChild).toBeInTheDocument();
97
107
  });
98
108
 
99
109
  describe('logic', () => {
100
- describe('grid', () => {
101
- it('returns the grid', () => {
102
- const w = wrapper();
103
- const g = w.instance().grid();
104
- expect(g).toEqual({ x: 1, y: 1 });
105
- });
106
- });
110
+ describe('grid calculation', () => {
111
+ it('passes correct grid to DraggableCore based on domain and range step', () => {
112
+ const Comp = gridDraggable(defaultOptions)(() => <div>Test</div>);
113
+ render(<Comp {...defaultProps} />);
107
114
 
108
- describe('onStart', () => {
109
- it('sets the drag state', () => {
110
- const w = wrapper();
111
- w.instance().onStart({ clientX: 100, clientY: 100 });
112
- expect(w.state().startX).toEqual(100);
113
- expect(w.state().startY).toEqual(100);
115
+ // Grid is calculated as: scale.x(domain.step) - scale.x(0)
116
+ // With our mock xyFn that returns n, this is: step - 0 = step
117
+ expect(mockDraggableCoreProps.grid).toEqual([1, 1]);
114
118
  });
115
119
 
116
- it('calls the handler', () => {
117
- const onDragStart = jest.fn();
118
- const w = wrapper(
119
- {},
120
- {
121
- onDragStart,
120
+ it('calculates grid with decimal steps', () => {
121
+ const props = {
122
+ ...defaultProps,
123
+ graphProps: {
124
+ ...getGraphProps(),
125
+ domain: { min: -1.5, max: 1.6, step: 0.3 },
126
+ range: { min: -2, max: 3, step: 0.2 },
122
127
  },
123
- );
124
- w.instance().onStart({ clientX: 100, clientY: 100 });
125
- expect(onDragStart).toHaveBeenCalled();
128
+ };
129
+ const Comp = gridDraggable(defaultOptions)(() => <div>Test</div>);
130
+ render(<Comp {...props} />);
131
+
132
+ expect(mockDraggableCoreProps.grid).toEqual([0.3, 0.2]);
126
133
  });
127
134
  });
128
135
 
129
- describe('position', () => {
130
- it('returns position object', () => {
131
- const w = wrapper();
132
- const pos = w.instance().position();
136
+ describe('onStart', () => {
137
+ it('calls onDragStart handler when drag starts', () => {
138
+ const onDragStart = jest.fn();
139
+ const props = { ...defaultProps, onDragStart };
140
+ const Comp = gridDraggable(defaultOptions)(() => <div>Test</div>);
141
+ render(<Comp {...props} />);
133
142
 
134
- const anchorPoint = {
135
- x: 0,
136
- y: 0,
137
- };
138
- expect(pos).toEqual({
139
- anchorPoint,
140
- x: expect.any(Function),
141
- y: expect.any(Function),
142
- });
143
- });
144
- });
143
+ // Simulate drag start
144
+ mockDraggableCoreProps.onStart({ clientX: 100, clientY: 100 });
145
145
 
146
- describe('tiny', () => {
147
- it('returns true for 10 ', () => {
148
- const w = wrapper();
149
- w.setState({ startX: 0 });
150
- const result = w.instance().tiny('x', { clientX: 10 });
151
- expect(result).toBe(false);
152
- });
153
- it('returns true for 0.01', () => {
154
- const w = wrapper();
155
- w.setState({ startX: 0 });
156
- const result = w.instance().tiny('x', { clientX: 0.01 });
157
- expect(result).toBe(true);
146
+ expect(onDragStart).toHaveBeenCalled();
158
147
  });
159
148
  });
160
149
 
161
150
  describe('onDrag', () => {
162
- let onDrag, w;
163
-
164
- beforeEach(() => {
165
- onDrag = jest.fn();
166
- w = wrapper({}, { onDrag });
167
- w.instance().applyDelta = jest.fn().mockReturnValue(0);
168
- w.instance().props.graphProps.getRootNode = jest.fn().mockReturnValue({
169
- ownerSVGElement: null,
170
- getBoundingClientRect: jest.fn(() => ({
171
- left: 0,
172
- top: 0,
173
- right: 100,
174
- bottom: 100,
175
- })),
176
- });
177
- w.instance().getClientPoint = jest.fn().mockReturnValue([50, 50]); // Mocking getClientPoint
178
- w.instance().onDrag({}, { x: 1, y: 1 });
179
- });
151
+ it('calls onDrag callback with result from fromDelta', () => {
152
+ const onDrag = jest.fn();
153
+ const fromDelta = jest.fn().mockReturnValue('delta-result');
154
+ const bounds = jest.fn().mockReturnValue({ left: -100, top: -100, bottom: 100, right: 100 });
155
+ const options = { ...defaultOptions, fromDelta, bounds };
156
+ const props = { ...defaultProps, onDrag };
157
+
158
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
159
+ render(<Comp {...props} />);
180
160
 
181
- it('calls applyDelta', () => {
182
- expect(w.instance().applyDelta).toHaveBeenCalled();
161
+ // Set up drag start state
162
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
163
+
164
+ // Simulate drag
165
+ mockDraggableCoreProps.onDrag({}, { deltaX: 10, deltaY: 10 });
166
+
167
+ expect(fromDelta).toHaveBeenCalled();
168
+ expect(onDrag).toHaveBeenCalledWith('delta-result');
183
169
  });
184
170
 
185
- it('calls callback', () => {
186
- expect(onDrag).toHaveBeenCalledWith(0);
171
+ it('does not call onDrag when no onDrag handler is provided', () => {
172
+ const fromDelta = jest.fn();
173
+ const options = { ...defaultOptions, fromDelta };
174
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
175
+ render(<Comp {...defaultProps} />);
176
+
177
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
178
+ mockDraggableCoreProps.onDrag({}, { deltaX: 10, deltaY: 10 });
179
+
180
+ expect(fromDelta).not.toHaveBeenCalled();
187
181
  });
188
182
 
189
- const bounds = (left, right, top, bottom) => ({ left, right, top, bottom });
190
- describe('bounds', () => {
191
- const assertEarlyExit = (bounds, dd) => {
192
- it(`${JSON.stringify(bounds)}, ${dd.deltaX}, ${dd.deltaY} `, () => {
193
- w = wrapper({}, { onDrag });
194
- w.instance().getScaledBounds = jest.fn().mockReturnValue(bounds);
195
- w.instance().getClientPoint = jest.fn().mockReturnValue([50, 50]);
196
- w.instance().onDrag({}, dd);
197
- expect(w.instance().getClientPoint).not.toHaveBeenCalled();
198
- });
199
- };
200
- assertEarlyExit(bounds(0, 0, 0, 0), { deltaX: -10 });
201
- assertEarlyExit(bounds(0, 0, 0, 0), { deltaX: 10 });
202
- assertEarlyExit(bounds(-100, 100, 0, 0), { deltaY: -10 });
203
- assertEarlyExit(bounds(-100, 100, -100, 0), { deltaY: 10 });
204
- it('calls client point if it doesnt exit early bounds', () => {
205
- w = wrapper({}, { onDrag });
206
- w.instance().getScaledBounds = jest.fn().mockReturnValue(bounds(100, 100, 100, 100));
207
- w.instance().getClientPoint = jest.fn().mockReturnValue([50, 50]);
208
- w.instance().onDrag({}, { deltaX: 10 });
209
- expect(w.instance().getClientPoint).toHaveBeenCalled(); // Asserting that getClientPoint is called
183
+ describe('bounds checking', () => {
184
+ it('does not call onDrag when dragging left beyond left bound', () => {
185
+ const onDrag = jest.fn();
186
+ const bounds = jest.fn().mockReturnValue({ left: 0, top: 0, bottom: 0, right: 0 });
187
+ const fromDelta = jest.fn().mockReturnValue('result');
188
+ const options = { ...defaultOptions, bounds, fromDelta };
189
+ const props = { ...defaultProps, onDrag };
190
+
191
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
192
+ render(<Comp {...props} />);
193
+
194
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
195
+ // deltaX < 0 and deltaX < scaled bounds.left (0), so -10 < 0 triggers early return
196
+ mockDraggableCoreProps.onDrag({}, { deltaX: -10, deltaY: 0 });
197
+
198
+ expect(onDrag).not.toHaveBeenCalled();
199
+ });
200
+
201
+ it('does not call onDrag when dragging right beyond right bound', () => {
202
+ const onDrag = jest.fn();
203
+ const bounds = jest.fn().mockReturnValue({ left: 0, top: 0, bottom: 0, right: 0 });
204
+ const fromDelta = jest.fn().mockReturnValue('result');
205
+ const options = { ...defaultOptions, bounds, fromDelta };
206
+ const props = { ...defaultProps, onDrag };
207
+
208
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
209
+ render(<Comp {...props} />);
210
+
211
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
212
+ // deltaX > 0 and deltaX > scaled bounds.right (0), so 10 > 0 triggers early return
213
+ mockDraggableCoreProps.onDrag({}, { deltaX: 10, deltaY: 0 });
214
+
215
+ expect(onDrag).not.toHaveBeenCalled();
216
+ });
217
+
218
+ it('does not call onDrag when dragging up beyond top bound', () => {
219
+ const onDrag = jest.fn();
220
+ const bounds = jest.fn().mockReturnValue({ left: -100, top: 0, bottom: 0, right: 100 });
221
+ const fromDelta = jest.fn().mockReturnValue('result');
222
+ const options = { ...defaultOptions, bounds, fromDelta };
223
+ const props = { ...defaultProps, onDrag };
224
+
225
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
226
+ render(<Comp {...props} />);
227
+
228
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
229
+ // deltaY < 0 and deltaY < scaled bounds.top (0), so -10 < 0 triggers early return
230
+ mockDraggableCoreProps.onDrag({}, { deltaX: 0, deltaY: -10 });
231
+
232
+ expect(onDrag).not.toHaveBeenCalled();
233
+ });
234
+
235
+ it('does not call onDrag when dragging down beyond bottom bound', () => {
236
+ const onDrag = jest.fn();
237
+ const bounds = jest.fn().mockReturnValue({ left: -100, top: -100, bottom: 0, right: 100 });
238
+ const fromDelta = jest.fn().mockReturnValue('result');
239
+ const options = { ...defaultOptions, bounds, fromDelta };
240
+ const props = { ...defaultProps, onDrag };
241
+
242
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
243
+ render(<Comp {...props} />);
244
+
245
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
246
+ // deltaY > 0 and deltaY > scaled bounds.bottom (0), so 10 > 0 triggers early return
247
+ mockDraggableCoreProps.onDrag({}, { deltaX: 0, deltaY: 10 });
248
+
249
+ expect(onDrag).not.toHaveBeenCalled();
250
+ });
251
+
252
+ it('calls onDrag when dragging within bounds', () => {
253
+ const onDrag = jest.fn();
254
+ const bounds = jest.fn().mockReturnValue({ left: -100, top: -100, bottom: 100, right: 100 });
255
+ const fromDelta = jest.fn().mockReturnValue('result');
256
+ const options = { ...defaultOptions, bounds, fromDelta };
257
+ const props = { ...defaultProps, onDrag };
258
+
259
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
260
+ render(<Comp {...props} />);
261
+
262
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
263
+ // All bound checks pass: deltaX (-10) is NOT < bounds.left (-100) and NOT > bounds.right (100)
264
+ // Similarly for deltaY
265
+ mockDraggableCoreProps.onDrag({}, { deltaX: -10, deltaY: 10 });
266
+
267
+ expect(onDrag).toHaveBeenCalled();
210
268
  });
211
269
  });
212
- });
213
270
 
214
- describe('skipDragOutsideOfBounds', () => {
215
- let w;
216
- const assertSkipDrag = (dd, rawXFn, rawYFn, expected) => {
217
- rawXFn = rawXFn || ((x) => x);
218
- rawYFn = rawYFn || ((y) => y);
219
-
220
- it(`${dd.deltaX}, ${dd.deltaY}, ${expected}`, () => {
221
- w = wrapper({});
222
- const gp = getGraphProps();
223
-
224
- const mockGetBoundingClientRect = jest.fn(() => ({
225
- left: 0,
226
- top: 0,
227
- right: 100,
228
- bottom: 100,
229
- }));
230
-
231
- w.instance().getClientPoint = jest.fn(() => [
232
- rawXFn(gp.domain.min, gp.domain.max),
233
- rawYFn(gp.range.min, gp.range.max),
234
- ]);
235
-
236
- const rootNode = {
237
- ownerSVGElement: null,
238
- getBoundingClientRect: mockGetBoundingClientRect,
271
+ describe('skipDragOutsideOfBounds', () => {
272
+ it('skips drag when moving left and x is below domain.min', () => {
273
+ const onDrag = jest.fn();
274
+ const graphProps = {
275
+ ...getGraphProps(),
276
+ domain: { min: -5, max: 5, step: 1 },
277
+ range: { min: -5, max: 5, step: 1 },
239
278
  };
279
+ graphProps.scale.x.invert = jest.fn().mockReturnValue(-6); // Below min
240
280
 
241
- const result = w.instance().skipDragOutsideOfBounds(dd, {}, { ...gp, getRootNode: () => rootNode });
242
- expect(result).toEqual(expected);
281
+ const props = { ...defaultProps, graphProps, onDrag };
282
+ const bounds = jest.fn().mockReturnValue({ left: 100, top: 100, bottom: 100, right: 100 });
283
+ const options = { ...defaultOptions, bounds };
284
+
285
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
286
+ render(<Comp {...props} />);
287
+
288
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
289
+ mockDraggableCoreProps.onDrag({}, { deltaX: 1, deltaY: 0 });
290
+
291
+ expect(onDrag).not.toHaveBeenCalled();
243
292
  });
244
- };
245
- assertSkipDrag(
246
- { deltaX: 1 },
247
- (min, max) => min - 1,
248
- (min, max) => min,
249
- true,
250
- );
251
- assertSkipDrag(
252
- { deltaX: -1 },
253
- (min, max) => max + 1,
254
- (min, max) => min,
255
- true,
256
- );
257
- assertSkipDrag(
258
- { deltaY: 1 },
259
- (min, max) => max,
260
- (min, max) => max + 1,
261
- true,
262
- );
263
- assertSkipDrag(
264
- { deltaY: -1 },
265
- (min, max) => max,
266
- (min, max) => min - 1,
267
- true,
268
- );
269
- assertSkipDrag(
270
- { deltaY: 1 },
271
- (min, max) => max,
272
- (min, max) => max,
273
- false,
274
- );
275
- assertSkipDrag(
276
- { deltaY: -1 },
277
- (min, max) => max,
278
- (min, max) => min,
279
- false,
280
- );
281
- });
282
293
 
283
- describe('getDelta', () => {
284
- it('calls utils.getDelta', () => {
285
- const w = wrapper();
286
- w.instance().position = jest.fn().mockReturnValue({
287
- anchorPoint: {
288
- x: 0,
289
- y: 0,
290
- },
291
- x: jest.fn((x) => x),
292
- y: jest.fn((y) => y),
294
+ it('skips drag when moving right and x is above domain.max', () => {
295
+ const onDrag = jest.fn();
296
+ const graphProps = {
297
+ ...getGraphProps(),
298
+ domain: { min: -5, max: 5, step: 1 },
299
+ range: { min: -5, max: 5, step: 1 },
300
+ };
301
+ graphProps.scale.x.invert = jest.fn().mockReturnValue(6); // Above max
302
+
303
+ const props = { ...defaultProps, graphProps, onDrag };
304
+ const bounds = jest.fn().mockReturnValue({ left: 100, top: 100, bottom: 100, right: 100 });
305
+ const options = { ...defaultOptions, bounds };
306
+
307
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
308
+ render(<Comp {...props} />);
309
+
310
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
311
+ mockDraggableCoreProps.onDrag({}, { deltaX: -1, deltaY: 0 });
312
+
313
+ expect(onDrag).not.toHaveBeenCalled();
314
+ });
315
+
316
+ it('skips drag when moving up and y is above range.max', () => {
317
+ const onDrag = jest.fn();
318
+ const graphProps = {
319
+ ...getGraphProps(),
320
+ domain: { min: -5, max: 5, step: 1 },
321
+ range: { min: -5, max: 5, step: 1 },
322
+ };
323
+ graphProps.scale.y.invert = jest.fn().mockReturnValue(6); // Above max
324
+
325
+ const props = { ...defaultProps, graphProps, onDrag };
326
+ const bounds = jest.fn().mockReturnValue({ left: 100, top: 100, bottom: 100, right: 100 });
327
+ const options = { ...defaultOptions, bounds };
328
+
329
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
330
+ render(<Comp {...props} />);
331
+
332
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
333
+ mockDraggableCoreProps.onDrag({}, { deltaX: 0, deltaY: 1 });
334
+
335
+ expect(onDrag).not.toHaveBeenCalled();
336
+ });
337
+
338
+ it('skips drag when moving down and y is below range.min', () => {
339
+ const onDrag = jest.fn();
340
+ const graphProps = {
341
+ ...getGraphProps(),
342
+ domain: { min: -5, max: 5, step: 1 },
343
+ range: { min: -5, max: 5, step: 1 },
344
+ };
345
+ graphProps.scale.y.invert = jest.fn().mockReturnValue(-6); // Below min
346
+
347
+ const props = { ...defaultProps, graphProps, onDrag };
348
+ const bounds = jest.fn().mockReturnValue({ left: 100, top: 100, bottom: 100, right: 100 });
349
+ const options = { ...defaultOptions, bounds };
350
+
351
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
352
+ render(<Comp {...props} />);
353
+
354
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
355
+ mockDraggableCoreProps.onDrag({}, { deltaX: 0, deltaY: -1 });
356
+
357
+ expect(onDrag).not.toHaveBeenCalled();
358
+ });
359
+
360
+ it('allows drag when within domain and range', () => {
361
+ const onDrag = jest.fn();
362
+ const graphProps = {
363
+ ...getGraphProps(),
364
+ domain: { min: -5, max: 5, step: 1 },
365
+ range: { min: -5, max: 5, step: 1 },
366
+ };
367
+ graphProps.scale.x.invert = jest.fn().mockReturnValue(3); // Within bounds
368
+ graphProps.scale.y.invert = jest.fn().mockReturnValue(2); // Within bounds
369
+
370
+ const props = { ...defaultProps, graphProps, onDrag };
371
+ const bounds = jest.fn().mockReturnValue({ left: -100, top: -100, bottom: 100, right: 100 });
372
+ const options = { ...defaultOptions, bounds };
373
+
374
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
375
+ render(<Comp {...props} />);
376
+
377
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
378
+ mockDraggableCoreProps.onDrag({}, { deltaX: 1, deltaY: -1 });
379
+
380
+ expect(onDrag).toHaveBeenCalled();
293
381
  });
294
- w.instance().getDelta({ x: 1, y: 1 });
295
- expect(getDelta).toHaveBeenCalledWith({ x: 0, y: 0 }, { x: 1, y: 1 });
296
382
  });
297
383
  });
298
- describe('applyDelta', () => {
299
- it('calls fromDelta', () => {
384
+
385
+ describe('getDelta and applyDelta', () => {
386
+ it('calls utils.getDelta when processing drag', () => {
387
+ getDelta.mockClear();
388
+ const onDrag = jest.fn();
389
+ const props = { ...defaultProps, onDrag };
390
+ const bounds = jest.fn().mockReturnValue({ left: -100, top: -100, bottom: 100, right: 100 });
391
+ const options = { ...defaultOptions, bounds };
392
+
393
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
394
+ render(<Comp {...props} />);
395
+
396
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
397
+ mockDraggableCoreProps.onDrag({}, { deltaX: 10, deltaY: 10 });
398
+
399
+ expect(getDelta).toHaveBeenCalled();
400
+ });
401
+
402
+ it('calls fromDelta with result from getDelta', () => {
300
403
  const fromDelta = jest.fn();
301
- const w = wrapper({ fromDelta });
302
- w.instance().getDelta = jest.fn();
303
- w.instance().applyDelta({ x: 1, y: 1 });
304
- expect(fromDelta).toHaveBeenCalledWith(expect.anything(), undefined);
404
+ getDelta.mockReturnValue({ x: 5, y: 5 });
405
+ const bounds = jest.fn().mockReturnValue({ left: -100, top: -100, bottom: 100, right: 100 });
406
+ const options = { ...defaultOptions, fromDelta, bounds };
407
+ const props = { ...defaultProps, onDrag: jest.fn() };
408
+
409
+ const Comp = gridDraggable(options)(() => <div>Test</div>);
410
+ render(<Comp {...props} />);
411
+
412
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
413
+ mockDraggableCoreProps.onDrag({}, { deltaX: 10, deltaY: 10 });
414
+
415
+ expect(fromDelta).toHaveBeenCalled();
305
416
  });
306
417
  });
418
+
307
419
  describe('onStop', () => {
308
- it('calls onDragStop', () => {
420
+ it('calls onDragStop when drag stops', () => {
309
421
  const onDragStop = jest.fn();
310
- const w = wrapper({}, { onDragStop });
311
- w.setState({ startX: 0, startY: 0 });
312
- w.instance().onStop({}, {});
422
+ const props = { ...defaultProps, onDragStop };
423
+
424
+ const Comp = gridDraggable(defaultOptions)(() => <div>Test</div>);
425
+ render(<Comp {...props} />);
426
+
427
+ // Start to set up state
428
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
429
+
430
+ // Stop with large movement (not tiny)
431
+ mockDraggableCoreProps.onStop({ clientX: 100, clientY: 100 }, {});
432
+
313
433
  expect(onDragStop).toHaveBeenCalled();
314
434
  });
315
435
 
316
- it('calls onClick if tiny', () => {
436
+ it('calls onClick instead of onDragStop when movement is tiny', () => {
317
437
  const onClick = jest.fn();
318
- const w = wrapper({}, { onClick });
319
- w.instance().tiny = jest.fn().mockReturnValue(true);
438
+ const onDragStop = jest.fn();
439
+ const props = { ...defaultProps, onClick, onDragStop };
440
+
320
441
  clientPoint.mockReturnValue([0, 0]);
321
- w.instance().onStop({}, {});
442
+
443
+ const Comp = gridDraggable(defaultOptions)(() => <div>Test</div>);
444
+ render(<Comp {...props} />);
445
+
446
+ // Start and stop at almost the same position (tiny movement)
447
+ // Grid is 1x1, tiny threshold is grid/10 = 0.1
448
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
449
+ mockDraggableCoreProps.onStop({ clientX: 0.05, clientY: 0.05, target: {} }, {});
450
+
322
451
  expect(onClick).toHaveBeenCalledWith({ x: 0, y: 0 });
323
452
  });
453
+
454
+ it('calls onClick with snapped coordinates', () => {
455
+ const onClick = jest.fn();
456
+ const props = { ...defaultProps, onClick };
457
+ const graphProps = getGraphProps();
458
+ graphProps.scale.x.invert = jest.fn().mockReturnValue(1.7);
459
+ graphProps.scale.y.invert = jest.fn().mockReturnValue(2.3);
460
+ graphProps.snap.x = jest.fn().mockReturnValue(2);
461
+ graphProps.snap.y = jest.fn().mockReturnValue(2);
462
+
463
+ clientPoint.mockReturnValue([1.7, 2.3]);
464
+
465
+ const propsWithGraphProps = { ...props, graphProps };
466
+ const Comp = gridDraggable(defaultOptions)(() => <div>Test</div>);
467
+ render(<Comp {...propsWithGraphProps} />);
468
+
469
+ // Start and stop at almost the same position (tiny movement)
470
+ mockDraggableCoreProps.onStart({ clientX: 0, clientY: 0 });
471
+ mockDraggableCoreProps.onStop({ clientX: 0.05, clientY: 0.05, target: {} }, {});
472
+
473
+ expect(graphProps.snap.x).toHaveBeenCalledWith(1.7);
474
+ expect(graphProps.snap.y).toHaveBeenCalledWith(2.3);
475
+ expect(onClick).toHaveBeenCalledWith({ x: 2, y: 2 });
476
+ });
324
477
  });
325
478
  });
326
479
  });