@pie-lib/graphing 4.0.23 → 4.0.24-beta.1

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.
Files changed (66) hide show
  1. package/CHANGELOG.md +0 -92
  2. package/lib/mark-label.js +7 -197
  3. package/lib/mark-label.js.map +1 -1
  4. package/lib/tools/circle/component.js +3 -34
  5. package/lib/tools/circle/component.js.map +1 -1
  6. package/lib/tools/point/component.js +8 -29
  7. package/lib/tools/point/component.js.map +1 -1
  8. package/lib/tools/polygon/component.js +6 -31
  9. package/lib/tools/polygon/component.js.map +1 -1
  10. package/lib/tools/shared/line/index.js +3 -34
  11. package/lib/tools/shared/line/index.js.map +1 -1
  12. package/package.json +17 -17
  13. package/src/mark-label.jsx +8 -209
  14. package/src/tools/circle/component.jsx +3 -26
  15. package/src/tools/point/component.jsx +8 -21
  16. package/src/tools/polygon/component.jsx +6 -24
  17. package/src/tools/shared/line/index.jsx +3 -26
  18. package/LICENSE.md +0 -5
  19. package/src/__tests__/bg.test.jsx +0 -250
  20. package/src/__tests__/coordinates-label.test.jsx +0 -243
  21. package/src/__tests__/graph-with-controls.test.jsx +0 -198
  22. package/src/__tests__/graph.test.jsx +0 -796
  23. package/src/__tests__/grid-setup.test.jsx +0 -645
  24. package/src/__tests__/grid.test.jsx +0 -22
  25. package/src/__tests__/key-legend.test.jsx +0 -260
  26. package/src/__tests__/label-svg-icon.test.jsx +0 -278
  27. package/src/__tests__/labels.test.jsx +0 -55
  28. package/src/__tests__/mark-label.test.jsx +0 -437
  29. package/src/__tests__/toggle-bar.test.jsx +0 -146
  30. package/src/__tests__/tool-menu.test.jsx +0 -115
  31. package/src/__tests__/undo-redo.test.jsx +0 -24
  32. package/src/__tests__/use-debounce.test.js +0 -21
  33. package/src/__tests__/utils.js +0 -41
  34. package/src/__tests__/utils.test.js +0 -105
  35. package/src/axis/__tests__/arrow.test.jsx +0 -38
  36. package/src/axis/__tests__/axes.test.jsx +0 -216
  37. package/src/container/__tests__/actions.test.js +0 -105
  38. package/src/container/__tests__/index.test.jsx +0 -319
  39. package/src/container/__tests__/marks.test.js +0 -172
  40. package/src/container/__tests__/middleware.test.js +0 -235
  41. package/src/container/__tests__/reducer.test.js +0 -324
  42. package/src/tools/absolute/__tests__/component.test.jsx +0 -53
  43. package/src/tools/circle/__tests__/bg-circle.test.jsx +0 -26
  44. package/src/tools/circle/__tests__/component.test.jsx +0 -494
  45. package/src/tools/circle/__tests__/index.test.js +0 -480
  46. package/src/tools/exponential/__tests__/component.test.jsx +0 -53
  47. package/src/tools/exponential/__tests__/index.test.js +0 -729
  48. package/src/tools/line/__tests__/component.test.jsx +0 -37
  49. package/src/tools/parabola/__tests__/component.test.jsx +0 -48
  50. package/src/tools/parabola/__tests__/index.test.js +0 -470
  51. package/src/tools/point/__tests__/component.test.jsx +0 -475
  52. package/src/tools/point/__tests__/index.test.js +0 -241
  53. package/src/tools/polygon/__tests__/component.test.jsx +0 -471
  54. package/src/tools/polygon/__tests__/index.test.js +0 -294
  55. package/src/tools/polygon/__tests__/line.test.jsx +0 -35
  56. package/src/tools/polygon/__tests__/polygon.test.jsx +0 -61
  57. package/src/tools/ray/__tests__/component.test.jsx +0 -29
  58. package/src/tools/segment/__tests__/component.test.jsx +0 -28
  59. package/src/tools/shared/__tests__/arrow-head.test.jsx +0 -31
  60. package/src/tools/shared/line/__tests__/index.test.jsx +0 -109
  61. package/src/tools/shared/line/__tests__/line-path.test.jsx +0 -53
  62. package/src/tools/shared/line/__tests__/with-root-edge.test.jsx +0 -73
  63. package/src/tools/shared/point/__tests__/arrow-point.test.jsx +0 -91
  64. package/src/tools/shared/point/__tests__/base-point.test.jsx +0 -87
  65. package/src/tools/sine/__tests__/component.test.jsx +0 -51
  66. package/src/tools/vector/__tests__/component.test.jsx +0 -25
@@ -1,471 +0,0 @@
1
- import { render } from '@pie-lib/test-utils';
2
- import React from 'react';
3
- import { graphProps, xy } from '../../../__tests__/utils';
4
-
5
- import { buildLines, RawBaseComponent, swap } from '../component';
6
-
7
- const xyLabel = (x, y, index, label) => ({
8
- ...xy(x, y, index),
9
- label,
10
- });
11
-
12
- describe('buildLines', () => {
13
- const defaultPoints = [xy(0, 0), xy(1, 1), xy(1, 0)];
14
-
15
- const assertBuildLines = (points, closed, expected) => {
16
- it(`builds points and lines for ${points} = ${expected}`, () => {
17
- const result = buildLines(points);
18
- expect(result).toMatchObject([
19
- { from: xy(0, 0, 0), to: xy(1, 1, 1) },
20
- { from: xy(1, 1, 1), to: xy(1, 0, 2) },
21
- ]);
22
- });
23
- };
24
-
25
- assertBuildLines(defaultPoints, true, []);
26
- });
27
-
28
- describe('swap', () => {
29
- it('swaps pairs', () => {
30
- const result = swap([xy(0, 0, 0), xy(1, 1, 1), xy(2, 2, 2)], xy(0, 0, 0), xy(3, 3, 0));
31
- expect(result).toEqual([xy(3, 3, 0), xy(1, 1, 1), xy(2, 2, 2)]);
32
- });
33
- });
34
-
35
- describe('RawBaseComponent', () => {
36
- let onChange = jest.fn();
37
- let onChangeProps = jest.fn();
38
- const renderComponent = (extras) => {
39
- const defaults = {
40
- classes: {},
41
- className: 'className',
42
- onChange,
43
- onChangeProps,
44
- onClosePolygon: jest.fn(),
45
- graphProps: graphProps(),
46
- points: [],
47
- };
48
- const props = { ...defaults, ...extras };
49
-
50
- return render(<RawBaseComponent {...props} />);
51
- };
52
-
53
- // used to test items that have labels attached to points
54
- const labelNode = document.createElement('foreignObject');
55
- const points = [xyLabel(0, 0, 0, 'A'), xyLabel(2, 2, 1, 'B'), xyLabel(0, 2, 2, 'C')];
56
- const renderWithLabels = (extras) =>
57
- renderComponent({
58
- labelNode: labelNode,
59
- points: points,
60
- ...extras,
61
- });
62
-
63
- describe('rendering', () => {
64
- it('renders without crashing', () => {
65
- const { container } = renderComponent();
66
- expect(container.firstChild).toBeInTheDocument();
67
- });
68
-
69
- it('renders with labels', () => {
70
- const { container } = renderWithLabels();
71
- expect(container.firstChild).toBeInTheDocument();
72
- });
73
-
74
- it('renders with multiple points', () => {
75
- const { container } = renderComponent({
76
- points: [xy(0, 0, 0), xy(1, 1, 1), xy(2, 0, 2)],
77
- });
78
- expect(container.firstChild).toBeInTheDocument();
79
- });
80
-
81
- it('renders with closed polygon', () => {
82
- const { container } = renderComponent({
83
- points: [xy(0, 0, 0), xy(1, 1, 1), xy(2, 0, 2)],
84
- closed: true,
85
- });
86
- expect(container.firstChild).toBeInTheDocument();
87
- });
88
-
89
- it('renders with single point', () => {
90
- const { container } = renderComponent({
91
- points: [xy(0, 0, 0)],
92
- });
93
- expect(container.firstChild).toBeInTheDocument();
94
- });
95
-
96
- it('renders with two points', () => {
97
- const { container } = renderComponent({
98
- points: [xy(0, 0, 0), xy(1, 1, 1)],
99
- });
100
- expect(container.firstChild).toBeInTheDocument();
101
- });
102
-
103
- it('renders with many points', () => {
104
- const manyPoints = Array.from({ length: 10 }, (_, i) => xy(i, i, i));
105
- const { container } = renderComponent({
106
- points: manyPoints,
107
- });
108
- expect(container.firstChild).toBeInTheDocument();
109
- });
110
-
111
- it('renders with negative coordinates', () => {
112
- const { container } = renderComponent({
113
- points: [xy(-5, -5, 0), xy(-1, -1, 1), xy(-3, -2, 2)],
114
- });
115
- expect(container.firstChild).toBeInTheDocument();
116
- });
117
-
118
- it('renders with decimal coordinates', () => {
119
- const { container } = renderComponent({
120
- points: [xy(0.5, 0.5, 0), xy(1.5, 1.5, 1), xy(2.5, 0.5, 2)],
121
- });
122
- expect(container.firstChild).toBeInTheDocument();
123
- });
124
-
125
- it('renders with zero coordinates', () => {
126
- const { container } = renderComponent({
127
- points: [xy(0, 0, 0), xy(0, 0, 1), xy(0, 0, 2)],
128
- });
129
- expect(container.firstChild).toBeInTheDocument();
130
- });
131
- });
132
-
133
- describe('states', () => {
134
- it('renders in disabled state', () => {
135
- const { container } = renderComponent({
136
- points: [xy(0, 0, 0), xy(1, 1, 1), xy(2, 0, 2)],
137
- disabled: true,
138
- });
139
- expect(container.firstChild).toBeInTheDocument();
140
- });
141
-
142
- it('renders in enabled state', () => {
143
- const { container } = renderComponent({
144
- points: [xy(0, 0, 0), xy(1, 1, 1), xy(2, 0, 2)],
145
- disabled: false,
146
- });
147
- expect(container.firstChild).toBeInTheDocument();
148
- });
149
-
150
- it('renders with correctness correct', () => {
151
- const { container } = renderComponent({
152
- points: [xy(0, 0, 0), xy(1, 1, 1), xy(2, 0, 2)],
153
- correctness: 'correct',
154
- });
155
- expect(container.firstChild).toBeInTheDocument();
156
- });
157
-
158
- it('renders with correctness incorrect', () => {
159
- const { container } = renderComponent({
160
- points: [xy(0, 0, 0), xy(1, 1, 1), xy(2, 0, 2)],
161
- correctness: 'incorrect',
162
- });
163
- expect(container.firstChild).toBeInTheDocument();
164
- });
165
-
166
- it('renders with correctness partial', () => {
167
- const { container } = renderComponent({
168
- points: [xy(0, 0, 0), xy(1, 1, 1), xy(2, 0, 2)],
169
- correctness: 'partial',
170
- });
171
- expect(container.firstChild).toBeInTheDocument();
172
- });
173
-
174
- it('renders with building state', () => {
175
- const { container } = renderComponent({
176
- points: [xy(0, 0, 0), xy(1, 1, 1)],
177
- building: true,
178
- });
179
- expect(container.firstChild).toBeInTheDocument();
180
- });
181
- });
182
-
183
- describe('labels', () => {
184
- it('renders with all points labeled', () => {
185
- const { container } = renderWithLabels();
186
- expect(container.firstChild).toBeInTheDocument();
187
- });
188
-
189
- it('renders with some points labeled', () => {
190
- const partialLabels = [xyLabel(0, 0, 0, 'A'), xy(2, 2, 1), xyLabel(0, 2, 2, 'C')];
191
- const { container } = renderComponent({
192
- labelNode,
193
- points: partialLabels,
194
- });
195
- expect(container.firstChild).toBeInTheDocument();
196
- });
197
-
198
- it('renders with empty labels', () => {
199
- const emptyLabels = [xyLabel(0, 0, 0, ''), xyLabel(2, 2, 1, ''), xyLabel(0, 2, 2, '')];
200
- const { container } = renderComponent({
201
- labelNode,
202
- points: emptyLabels,
203
- });
204
- expect(container.firstChild).toBeInTheDocument();
205
- });
206
-
207
- it('renders with long labels', () => {
208
- const longLabels = [
209
- xyLabel(0, 0, 0, 'Very Long Label A'),
210
- xyLabel(2, 2, 1, 'Very Long Label B'),
211
- xyLabel(0, 2, 2, 'Very Long Label C'),
212
- ];
213
- const { container } = renderComponent({
214
- labelNode,
215
- points: longLabels,
216
- });
217
- expect(container.firstChild).toBeInTheDocument();
218
- });
219
-
220
- it('renders without labelNode', () => {
221
- const { container } = renderComponent({
222
- points: [xyLabel(0, 0, 0, 'A'), xyLabel(2, 2, 1, 'B')],
223
- });
224
- expect(container.firstChild).toBeInTheDocument();
225
- });
226
-
227
- it('renders with labelModeEnabled', () => {
228
- const { container } = renderWithLabels({ labelModeEnabled: true });
229
- expect(container.firstChild).toBeInTheDocument();
230
- });
231
-
232
- it('renders with labelModeEnabled disabled', () => {
233
- const { container } = renderWithLabels({ labelModeEnabled: false });
234
- expect(container.firstChild).toBeInTheDocument();
235
- });
236
- });
237
-
238
- describe('props', () => {
239
- it('passes onChange callback', () => {
240
- const customOnChange = jest.fn();
241
- const { container } = renderComponent({
242
- onChange: customOnChange,
243
- points: [xy(0, 0, 0), xy(1, 1, 1)],
244
- });
245
- expect(container.firstChild).toBeInTheDocument();
246
- });
247
-
248
- it('passes onChangeProps callback', () => {
249
- const customOnChangeProps = jest.fn();
250
- const { container } = renderComponent({
251
- onChangeProps: customOnChangeProps,
252
- points: [xy(0, 0, 0), xy(1, 1, 1)],
253
- });
254
- expect(container.firstChild).toBeInTheDocument();
255
- });
256
-
257
- it('passes onClick callback', () => {
258
- const onClick = jest.fn();
259
- const { container } = renderComponent({
260
- onClick,
261
- points: [xy(0, 0, 0), xy(1, 1, 1)],
262
- });
263
- expect(container.firstChild).toBeInTheDocument();
264
- });
265
-
266
- it('passes onClosePolygon callback', () => {
267
- const onClosePolygon = jest.fn();
268
- const { container } = renderComponent({
269
- onClosePolygon,
270
- points: [xy(0, 0, 0), xy(1, 1, 1), xy(2, 0, 2)],
271
- });
272
- expect(container.firstChild).toBeInTheDocument();
273
- });
274
-
275
- it('passes onDragStart callback', () => {
276
- const onDragStart = jest.fn();
277
- const { container } = renderComponent({
278
- onDragStart,
279
- points: [xy(0, 0, 0), xy(1, 1, 1)],
280
- });
281
- expect(container.firstChild).toBeInTheDocument();
282
- });
283
-
284
- it('passes onDragStop callback', () => {
285
- const onDragStop = jest.fn();
286
- const { container } = renderComponent({
287
- onDragStop,
288
- points: [xy(0, 0, 0), xy(1, 1, 1)],
289
- });
290
- expect(container.firstChild).toBeInTheDocument();
291
- });
292
-
293
- it('passes coordinatesOnHover', () => {
294
- const { container } = renderComponent({
295
- coordinatesOnHover: true,
296
- points: [xy(0, 0, 0), xy(1, 1, 1)],
297
- });
298
- expect(container.firstChild).toBeInTheDocument();
299
- });
300
-
301
- it('passes graphProps', () => {
302
- const customGraphProps = graphProps(0, 10, 0, 10);
303
- const { container } = renderComponent({
304
- graphProps: customGraphProps,
305
- points: [xy(5, 5, 0), xy(7, 7, 1)],
306
- });
307
- expect(container.firstChild).toBeInTheDocument();
308
- });
309
- });
310
-
311
- describe('polygon shapes', () => {
312
- it('renders triangle', () => {
313
- const { container } = renderComponent({
314
- points: [xy(0, 0, 0), xy(2, 0, 1), xy(1, 2, 2)],
315
- closed: true,
316
- });
317
- expect(container.firstChild).toBeInTheDocument();
318
- });
319
-
320
- it('renders square', () => {
321
- const { container } = renderComponent({
322
- points: [xy(0, 0, 0), xy(2, 0, 1), xy(2, 2, 2), xy(0, 2, 3)],
323
- closed: true,
324
- });
325
- expect(container.firstChild).toBeInTheDocument();
326
- });
327
-
328
- it('renders pentagon', () => {
329
- const { container } = renderComponent({
330
- points: [xy(1, 0, 0), xy(2, 1, 1), xy(1.5, 2.5, 2), xy(0.5, 2.5, 3), xy(0, 1, 4)],
331
- closed: true,
332
- });
333
- expect(container.firstChild).toBeInTheDocument();
334
- });
335
-
336
- it('renders hexagon', () => {
337
- const { container } = renderComponent({
338
- points: [xy(1, 0, 0), xy(2, 0.5, 1), xy(2, 1.5, 2), xy(1, 2, 3), xy(0, 1.5, 4), xy(0, 0.5, 5)],
339
- closed: true,
340
- });
341
- expect(container.firstChild).toBeInTheDocument();
342
- });
343
-
344
- it('renders irregular polygon', () => {
345
- const { container } = renderComponent({
346
- points: [xy(0, 0, 0), xy(3, 1, 1), xy(2, 4, 2), xy(-1, 3, 3)],
347
- closed: true,
348
- });
349
- expect(container.firstChild).toBeInTheDocument();
350
- });
351
-
352
- it('renders concave polygon', () => {
353
- const { container } = renderComponent({
354
- points: [xy(0, 0, 0), xy(2, 0, 1), xy(2, 2, 2), xy(1, 1, 3), xy(0, 2, 4)],
355
- closed: true,
356
- });
357
- expect(container.firstChild).toBeInTheDocument();
358
- });
359
- });
360
-
361
- describe('edge cases', () => {
362
- it('handles empty points array', () => {
363
- const { container } = renderComponent({ points: [] });
364
- expect(container.firstChild).toBeInTheDocument();
365
- });
366
-
367
- it('handles points with same coordinates', () => {
368
- const { container } = renderComponent({
369
- points: [xy(1, 1, 0), xy(1, 1, 1), xy(1, 1, 2)],
370
- });
371
- expect(container.firstChild).toBeInTheDocument();
372
- });
373
-
374
- it('handles collinear points', () => {
375
- const { container } = renderComponent({
376
- points: [xy(0, 0, 0), xy(1, 1, 1), xy(2, 2, 2)],
377
- });
378
- expect(container.firstChild).toBeInTheDocument();
379
- });
380
-
381
- it('handles very close points', () => {
382
- const { container } = renderComponent({
383
- points: [xy(1, 1, 0), xy(1.001, 1.001, 1), xy(1.002, 1.002, 2)],
384
- });
385
- expect(container.firstChild).toBeInTheDocument();
386
- });
387
-
388
- it('handles large coordinate values', () => {
389
- const { container } = renderComponent({
390
- points: [xy(1000, 1000, 0), xy(2000, 1000, 1), xy(1500, 2000, 2)],
391
- });
392
- expect(container.firstChild).toBeInTheDocument();
393
- });
394
-
395
- it('handles mixed positive and negative coordinates', () => {
396
- const { container } = renderComponent({
397
- points: [xy(-5, 5, 0), xy(5, 5, 1), xy(5, -5, 2), xy(-5, -5, 3)],
398
- closed: true,
399
- });
400
- expect(container.firstChild).toBeInTheDocument();
401
- });
402
-
403
- it('handles points without index', () => {
404
- const { container } = renderComponent({
405
- points: [
406
- { x: 0, y: 0 },
407
- { x: 1, y: 1 },
408
- { x: 2, y: 0 },
409
- ],
410
- });
411
- expect(container.firstChild).toBeInTheDocument();
412
- });
413
- });
414
-
415
- describe('integration', () => {
416
- it('renders complete closed polygon with all features', () => {
417
- const { container } = renderComponent({
418
- points: points,
419
- closed: true,
420
- labelNode,
421
- labelModeEnabled: true,
422
- coordinatesOnHover: true,
423
- correctness: 'correct',
424
- disabled: false,
425
- onChange: jest.fn(),
426
- onChangeProps: jest.fn(),
427
- onClosePolygon: jest.fn(),
428
- onClick: jest.fn(),
429
- onDragStart: jest.fn(),
430
- onDragStop: jest.fn(),
431
- });
432
- expect(container.firstChild).toBeInTheDocument();
433
- });
434
-
435
- it('renders building polygon', () => {
436
- const { container } = renderComponent({
437
- points: [xy(0, 0, 0), xy(1, 1, 1)],
438
- building: true,
439
- closed: false,
440
- });
441
- expect(container.firstChild).toBeInTheDocument();
442
- });
443
-
444
- it('renders disabled polygon with labels', () => {
445
- const { container } = renderComponent({
446
- points: points,
447
- labelNode,
448
- disabled: true,
449
- closed: true,
450
- });
451
- expect(container.firstChild).toBeInTheDocument();
452
- });
453
-
454
- it('renders polygon with incorrect correctness', () => {
455
- const { container } = renderComponent({
456
- points: points,
457
- closed: true,
458
- correctness: 'incorrect',
459
- });
460
- expect(container.firstChild).toBeInTheDocument();
461
- });
462
- });
463
-
464
- // Note: Instance method tests (dragPoint, dragLine, dragPoly, labelChange, clickPoint)
465
- // have been removed as they test internal implementation details.
466
- // These behaviors should be tested through:
467
- // 1. User interaction tests (drag-and-drop, clicks) - requires complex setup with @dnd-kit
468
- // 2. Integration/E2E tests
469
- // 3. Testing the pure logic functions (buildLines, swap) which are already tested above
470
- // The component's public API (onChange, onChangeProps callbacks) is what matters for RTL testing.
471
- });