@pie-lib/graphing 3.1.1-next.0 → 3.2.0-next.0
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.
- package/lib/axis/arrow.js +0 -3
- package/lib/axis/arrow.js.map +1 -1
- package/lib/axis/axes.js +0 -16
- package/lib/axis/axes.js.map +1 -1
- package/lib/axis/index.js +0 -7
- package/lib/axis/index.js.map +1 -1
- package/lib/bg.js +0 -6
- package/lib/bg.js.map +1 -1
- package/lib/container/actions.js +0 -1
- package/lib/container/actions.js.map +1 -1
- package/lib/container/index.js +4 -8
- package/lib/container/index.js.map +1 -1
- package/lib/container/marks.js +0 -2
- package/lib/container/marks.js.map +1 -1
- package/lib/container/middleware.js +0 -1
- package/lib/container/middleware.js.map +1 -1
- package/lib/container/reducer.js +0 -1
- package/lib/container/reducer.js.map +1 -1
- package/lib/coordinates-label.js +0 -11
- package/lib/coordinates-label.js.map +1 -1
- package/lib/graph-with-controls.js +3 -21
- package/lib/graph-with-controls.js.map +1 -1
- package/lib/graph.js +8 -27
- package/lib/graph.js.map +1 -1
- package/lib/grid-setup.js +0 -11
- package/lib/grid-setup.js.map +1 -1
- package/lib/grid.js +0 -22
- package/lib/grid.js.map +1 -1
- package/lib/index.js +0 -7
- package/lib/index.js.map +1 -1
- package/lib/key-legend.js +1 -2
- package/lib/key-legend.js.map +1 -1
- package/lib/label-svg-icon.js +0 -1
- package/lib/label-svg-icon.js.map +1 -1
- package/lib/labels.js +0 -13
- package/lib/labels.js.map +1 -1
- package/lib/mark-label.js +0 -15
- package/lib/mark-label.js.map +1 -1
- package/lib/toggle-bar.js +0 -17
- package/lib/toggle-bar.js.map +1 -1
- package/lib/tool-menu.js +0 -3
- package/lib/tool-menu.js.map +1 -1
- package/lib/tools/absolute/component.js +0 -1
- package/lib/tools/absolute/component.js.map +1 -1
- package/lib/tools/absolute/index.js +0 -10
- package/lib/tools/absolute/index.js.map +1 -1
- package/lib/tools/circle/bg-circle.js +0 -15
- package/lib/tools/circle/bg-circle.js.map +1 -1
- package/lib/tools/circle/component.js +2 -15
- package/lib/tools/circle/component.js.map +1 -1
- package/lib/tools/circle/index.js +0 -10
- package/lib/tools/circle/index.js.map +1 -1
- package/lib/tools/exponential/component.js +0 -1
- package/lib/tools/exponential/component.js.map +1 -1
- package/lib/tools/exponential/index.js +0 -10
- package/lib/tools/exponential/index.js.map +1 -1
- package/lib/tools/index.js +0 -1
- package/lib/tools/index.js.map +1 -1
- package/lib/tools/line/component.js +0 -2
- package/lib/tools/line/component.js.map +1 -1
- package/lib/tools/line/index.js +0 -1
- package/lib/tools/line/index.js.map +1 -1
- package/lib/tools/parabola/component.js +0 -1
- package/lib/tools/parabola/component.js.map +1 -1
- package/lib/tools/parabola/index.js +0 -10
- package/lib/tools/parabola/index.js.map +1 -1
- package/lib/tools/point/component.js +3 -15
- package/lib/tools/point/component.js.map +1 -1
- package/lib/tools/point/index.js +0 -10
- package/lib/tools/point/index.js.map +1 -1
- package/lib/tools/polygon/component.js +5 -29
- package/lib/tools/polygon/component.js.map +1 -1
- package/lib/tools/polygon/index.js +0 -12
- package/lib/tools/polygon/index.js.map +1 -1
- package/lib/tools/polygon/line.js +0 -15
- package/lib/tools/polygon/line.js.map +1 -1
- package/lib/tools/polygon/polygon.js +0 -18
- package/lib/tools/polygon/polygon.js.map +1 -1
- package/lib/tools/ray/component.js +0 -11
- package/lib/tools/ray/component.js.map +1 -1
- package/lib/tools/ray/index.js +0 -1
- package/lib/tools/ray/index.js.map +1 -1
- package/lib/tools/segment/component.js +0 -10
- package/lib/tools/segment/component.js.map +1 -1
- package/lib/tools/segment/index.js +0 -1
- package/lib/tools/segment/index.js.map +1 -1
- package/lib/tools/shared/arrow-head.js +0 -14
- package/lib/tools/shared/arrow-head.js.map +1 -1
- package/lib/tools/shared/icons/CorrectSVG.js +0 -1
- package/lib/tools/shared/icons/CorrectSVG.js.map +1 -1
- package/lib/tools/shared/icons/IncorrectSVG.js +0 -1
- package/lib/tools/shared/icons/IncorrectSVG.js.map +1 -1
- package/lib/tools/shared/icons/MissingSVG.js +0 -1
- package/lib/tools/shared/icons/MissingSVG.js.map +1 -1
- package/lib/tools/shared/line/index.js +7 -21
- package/lib/tools/shared/line/index.js.map +1 -1
- package/lib/tools/shared/line/line-path.js +0 -15
- package/lib/tools/shared/line/line-path.js.map +1 -1
- package/lib/tools/shared/line/with-root-edge.js +0 -11
- package/lib/tools/shared/line/with-root-edge.js.map +1 -1
- package/lib/tools/shared/point/arrow-point.js +0 -3
- package/lib/tools/shared/point/arrow-point.js.map +1 -1
- package/lib/tools/shared/point/arrow.js +0 -3
- package/lib/tools/shared/point/arrow.js.map +1 -1
- package/lib/tools/shared/point/base-point.js +0 -16
- package/lib/tools/shared/point/base-point.js.map +1 -1
- package/lib/tools/shared/point/index.js +0 -7
- package/lib/tools/shared/point/index.js.map +1 -1
- package/lib/tools/shared/styles.js +0 -1
- package/lib/tools/shared/styles.js.map +1 -1
- package/lib/tools/shared/types.js +0 -1
- package/lib/tools/shared/types.js.map +1 -1
- package/lib/tools/sine/component.js +0 -10
- package/lib/tools/sine/component.js.map +1 -1
- package/lib/tools/sine/index.js +0 -10
- package/lib/tools/sine/index.js.map +1 -1
- package/lib/tools/vector/component.js +0 -10
- package/lib/tools/vector/component.js.map +1 -1
- package/lib/tools/vector/index.js +0 -1
- package/lib/tools/vector/index.js.map +1 -1
- package/lib/undo-redo.js +0 -2
- package/lib/undo-redo.js.map +1 -1
- package/lib/use-debounce.js +0 -2
- package/lib/use-debounce.js.map +1 -1
- package/lib/utils.js +9 -26
- package/lib/utils.js.map +1 -1
- package/package.json +13 -10
- package/src/__tests__/bg.test.jsx +250 -0
- package/src/__tests__/coordinates-label.test.jsx +243 -0
- package/src/__tests__/graph-with-controls.test.jsx +9 -16
- package/src/__tests__/graph.test.jsx +560 -5
- package/src/__tests__/grid-setup.test.jsx +645 -0
- package/src/__tests__/grid.test.jsx +1 -1
- package/src/__tests__/key-legend.test.jsx +260 -0
- package/src/__tests__/label-svg-icon.test.jsx +278 -0
- package/src/__tests__/mark-label.test.jsx +1 -1
- package/src/__tests__/toggle-bar.test.jsx +0 -6
- package/src/__tests__/tool-menu.test.jsx +0 -4
- package/src/__tests__/use-debounce.test.js +1 -1
- package/src/__tests__/utils.test.js +15 -61
- package/src/axis/__tests__/axes.test.jsx +1 -1
- package/src/axis/axes.jsx +7 -21
- package/src/axis/index.js +1 -0
- package/src/bg.jsx +1 -1
- package/src/container/__tests__/actions.test.js +105 -0
- package/src/container/__tests__/index.test.jsx +319 -0
- package/src/container/__tests__/marks.test.js +172 -0
- package/src/container/__tests__/middleware.test.js +235 -0
- package/src/container/__tests__/reducer.test.js +324 -0
- package/src/container/index.jsx +2 -3
- package/src/coordinates-label.jsx +1 -7
- package/src/graph-with-controls.jsx +8 -6
- package/src/graph.jsx +2 -3
- package/src/grid-setup.jsx +1 -1
- package/src/key-legend.jsx +2 -1
- package/src/mark-label.jsx +7 -24
- package/src/toggle-bar.jsx +8 -1
- package/src/tools/absolute/__tests__/component.test.jsx +1 -2
- package/src/tools/absolute/component.jsx +2 -2
- package/src/tools/circle/__tests__/component.test.jsx +438 -0
- package/src/tools/circle/__tests__/index.test.js +480 -0
- package/src/tools/circle/bg-circle.jsx +2 -2
- package/src/tools/circle/component.jsx +10 -12
- package/src/tools/exponential/__tests__/component.test.jsx +0 -1
- package/src/tools/exponential/__tests__/index.test.js +729 -0
- package/src/tools/exponential/component.jsx +1 -1
- package/src/tools/line/__tests__/component.test.jsx +1 -0
- package/src/tools/line/component.jsx +4 -11
- package/src/tools/parabola/__tests__/component.test.jsx +0 -1
- package/src/tools/parabola/__tests__/index.test.js +470 -0
- package/src/tools/parabola/component.jsx +1 -1
- package/src/tools/point/__tests__/component.test.jsx +310 -2
- package/src/tools/point/__tests__/index.test.js +241 -0
- package/src/tools/point/component.jsx +1 -2
- package/src/tools/polygon/__tests__/component.test.jsx +391 -2
- package/src/tools/polygon/__tests__/index.test.js +237 -8
- package/src/tools/polygon/__tests__/line.test.jsx +13 -0
- package/src/tools/polygon/__tests__/polygon.test.jsx +19 -1
- package/src/tools/polygon/component.jsx +4 -14
- package/src/tools/polygon/line.jsx +1 -1
- package/src/tools/polygon/polygon.jsx +1 -1
- package/src/tools/ray/__tests__/component.test.jsx +1 -0
- package/src/tools/ray/component.jsx +3 -5
- package/src/tools/segment/__tests__/component.test.jsx +1 -0
- package/src/tools/segment/component.jsx +1 -1
- package/src/tools/shared/arrow-head.jsx +11 -6
- package/src/tools/shared/line/__tests__/index.test.jsx +1 -1
- package/src/tools/shared/line/__tests__/line-path.test.jsx +3 -3
- package/src/tools/shared/line/__tests__/with-root-edge.test.jsx +2 -2
- package/src/tools/shared/line/index.jsx +4 -6
- package/src/tools/shared/line/line-path.jsx +2 -8
- package/src/tools/shared/point/arrow-point.jsx +2 -5
- package/src/tools/sine/component.jsx +2 -2
- package/src/tools/vector/component.jsx +1 -1
- package/src/undo-redo.jsx +3 -9
- package/src/use-debounce.js +1 -1
- package/src/utils.js +1 -5
- package/NEXT.CHANGELOG.json +0 -16
|
@@ -2,7 +2,7 @@ import { render } from '@pie-lib/test-utils';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { graphProps, xy } from '../../../__tests__/utils';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { buildLines, RawBaseComponent, swap } from '../component';
|
|
6
6
|
|
|
7
7
|
const xyLabel = (x, y, index, label) => ({
|
|
8
8
|
...xy(x, y, index),
|
|
@@ -67,7 +67,396 @@ describe('RawBaseComponent', () => {
|
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
it('renders with labels', () => {
|
|
70
|
-
const { container} = renderWithLabels();
|
|
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
|
+
});
|
|
71
460
|
expect(container.firstChild).toBeInTheDocument();
|
|
72
461
|
});
|
|
73
462
|
});
|
|
@@ -1,46 +1,163 @@
|
|
|
1
1
|
import { addPointToArray, tool } from '../index';
|
|
2
|
+
import Polygon from '../component';
|
|
2
3
|
|
|
3
4
|
const xy = (x, y) => ({ x, y });
|
|
4
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Test suite for polygon tool
|
|
8
|
+
*
|
|
9
|
+
* Note: equalPoints() uses roundNumber() which rounds to 4 decimal places.
|
|
10
|
+
* - Values like 1.0001 and 1.0002 are considered DIFFERENT (round to 1.0001 and 1.0002)
|
|
11
|
+
* - Values like 1.00001 and 1.00002 are considered EQUAL (both round to 1.0000)
|
|
12
|
+
*/
|
|
13
|
+
|
|
5
14
|
describe('polygon', () => {
|
|
6
15
|
describe('addPointToArray', () => {
|
|
7
16
|
const assertAddPoint = (point, arr, expected) => {
|
|
8
|
-
it(`returns
|
|
17
|
+
it(`returns expected result when adding point to array`, () => {
|
|
9
18
|
const result = addPointToArray(point, arr);
|
|
10
19
|
expect(result).toEqual(expected);
|
|
11
20
|
});
|
|
12
21
|
};
|
|
22
|
+
|
|
13
23
|
assertAddPoint(xy(0, 0), [], { closed: false, points: [xy(0, 0)] });
|
|
14
24
|
assertAddPoint(xy(0, 0), [xy(0, 0)], { closed: false, points: [xy(0, 0)] });
|
|
15
25
|
assertAddPoint(xy(1, 1), [xy(0, 0)], {
|
|
16
26
|
closed: false,
|
|
17
27
|
points: [xy(0, 0), xy(1, 1)],
|
|
18
28
|
});
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
29
|
+
|
|
30
|
+
it('handles undefined array', () => {
|
|
31
|
+
const result = addPointToArray(xy(1, 2), undefined);
|
|
32
|
+
expect(result).toEqual({ points: [xy(1, 2)], closed: false });
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('handles null array', () => {
|
|
36
|
+
const result = addPointToArray(xy(1, 2), null);
|
|
37
|
+
expect(result).toEqual({ points: [xy(1, 2)], closed: false });
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('closes polygon when clicking first point', () => {
|
|
41
|
+
const firstPoint = xy(1, 2);
|
|
42
|
+
const points = [firstPoint, xy(3, 4), xy(5, 6)];
|
|
43
|
+
const result = addPointToArray(firstPoint, points);
|
|
44
|
+
|
|
45
|
+
expect(result).toEqual({ points, closed: true });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('does not add duplicate point in middle', () => {
|
|
49
|
+
const points = [xy(1, 2), xy(3, 4), xy(5, 6)];
|
|
50
|
+
const result = addPointToArray(points[1], points);
|
|
51
|
+
|
|
52
|
+
expect(result).toEqual({ points, closed: false });
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('adds new point to array with 2+ points', () => {
|
|
56
|
+
const points = [xy(0, 0), xy(1, 1)];
|
|
57
|
+
const newPoint = xy(2, 2);
|
|
58
|
+
const result = addPointToArray(newPoint, points);
|
|
59
|
+
|
|
60
|
+
expect(result).toEqual({
|
|
61
|
+
points: [...points, newPoint],
|
|
62
|
+
closed: false,
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('handles points within rounding tolerance', () => {
|
|
67
|
+
// roundNumber rounds to 4 decimal places
|
|
68
|
+
// 1.0001 and 1.0002 round to different values after toFixed(4)
|
|
69
|
+
const firstPoint = xy(1.0001, 2.0001);
|
|
70
|
+
const closePoint = xy(1.0002, 2.0002);
|
|
71
|
+
const result = addPointToArray(closePoint, [firstPoint]);
|
|
72
|
+
|
|
73
|
+
// Since they round to different values, both points are added
|
|
74
|
+
expect(result).toEqual({ points: [firstPoint, closePoint], closed: false });
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('handles points that round to exactly the same value', () => {
|
|
78
|
+
// Points that round to exactly the same value after toFixed(4)
|
|
79
|
+
const firstPoint = xy(1.0001, 2.0001);
|
|
80
|
+
const samePoint = xy(1.0001, 2.0001);
|
|
81
|
+
const result = addPointToArray(samePoint, [firstPoint]);
|
|
82
|
+
|
|
83
|
+
// Since they round to the same value, point is not added
|
|
84
|
+
expect(result).toEqual({ points: [firstPoint], closed: false });
|
|
22
85
|
});
|
|
23
86
|
});
|
|
24
87
|
});
|
|
25
88
|
|
|
26
89
|
describe('tool', () => {
|
|
27
90
|
let t;
|
|
91
|
+
|
|
28
92
|
beforeEach(() => {
|
|
29
93
|
t = tool();
|
|
30
94
|
});
|
|
31
95
|
|
|
32
|
-
|
|
33
|
-
|
|
96
|
+
describe('tool structure', () => {
|
|
97
|
+
it('creates polygon type', () => {
|
|
98
|
+
expect(t.type).toEqual('polygon');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('has Component property', () => {
|
|
102
|
+
expect(t.Component).toBe(Polygon);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('has complete method', () => {
|
|
106
|
+
expect(typeof t.complete).toBe('function');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('has addPoint method', () => {
|
|
110
|
+
expect(typeof t.addPoint).toBe('function');
|
|
111
|
+
});
|
|
34
112
|
});
|
|
35
113
|
|
|
36
114
|
describe('complete', () => {
|
|
37
115
|
it('closes polygon', () => {
|
|
38
116
|
expect(t.complete()).toEqual({ building: false, closed: true });
|
|
39
117
|
});
|
|
118
|
+
|
|
119
|
+
it('marks polygon as not building', () => {
|
|
120
|
+
const mark = {
|
|
121
|
+
type: 'polygon',
|
|
122
|
+
points: [xy(1, 2), xy(3, 4)],
|
|
123
|
+
closed: false,
|
|
124
|
+
building: true,
|
|
125
|
+
};
|
|
126
|
+
const result = t.complete(null, mark);
|
|
127
|
+
|
|
128
|
+
expect(result.building).toBe(false);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('marks polygon as closed', () => {
|
|
132
|
+
const mark = {
|
|
133
|
+
type: 'polygon',
|
|
134
|
+
points: [xy(1, 2), xy(3, 4)],
|
|
135
|
+
closed: false,
|
|
136
|
+
building: true,
|
|
137
|
+
};
|
|
138
|
+
const result = t.complete(null, mark);
|
|
139
|
+
|
|
140
|
+
expect(result.closed).toBe(true);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('preserves other mark properties', () => {
|
|
144
|
+
const mark = {
|
|
145
|
+
type: 'polygon',
|
|
146
|
+
points: [xy(1, 2)],
|
|
147
|
+
closed: false,
|
|
148
|
+
building: true,
|
|
149
|
+
label: 'Test',
|
|
150
|
+
color: 'red',
|
|
151
|
+
};
|
|
152
|
+
const result = t.complete(null, mark);
|
|
153
|
+
|
|
154
|
+
expect(result.label).toBe('Test');
|
|
155
|
+
expect(result.color).toBe('red');
|
|
156
|
+
});
|
|
40
157
|
});
|
|
41
158
|
|
|
42
159
|
describe('addPoint', () => {
|
|
43
|
-
it('creates new point', () => {
|
|
160
|
+
it('creates new polygon with first point', () => {
|
|
44
161
|
const mark = t.addPoint({ x: 0, y: 0 });
|
|
45
162
|
expect(mark).toEqual({
|
|
46
163
|
type: 'polygon',
|
|
@@ -50,7 +167,7 @@ describe('tool', () => {
|
|
|
50
167
|
});
|
|
51
168
|
});
|
|
52
169
|
|
|
53
|
-
it('adds
|
|
170
|
+
it('adds second point to existing mark', () => {
|
|
54
171
|
const mark = t.addPoint({ x: 0, y: 0 }, { points: [{ x: 1, y: 1 }] });
|
|
55
172
|
expect(mark).toEqual({
|
|
56
173
|
building: true,
|
|
@@ -61,5 +178,117 @@ describe('tool', () => {
|
|
|
61
178
|
],
|
|
62
179
|
});
|
|
63
180
|
});
|
|
181
|
+
|
|
182
|
+
it('creates mark with building flag true', () => {
|
|
183
|
+
const mark = t.addPoint(xy(1, 2));
|
|
184
|
+
expect(mark.building).toBe(true);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('creates mark with closed flag false', () => {
|
|
188
|
+
const mark = t.addPoint(xy(1, 2));
|
|
189
|
+
expect(mark.closed).toBe(false);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('adds multiple points sequentially', () => {
|
|
193
|
+
let mark = t.addPoint(xy(0, 0));
|
|
194
|
+
mark = t.addPoint(xy(1, 1), mark);
|
|
195
|
+
mark = t.addPoint(xy(2, 2), mark);
|
|
196
|
+
|
|
197
|
+
expect(mark.points).toHaveLength(3);
|
|
198
|
+
expect(mark.points).toEqual([xy(0, 0), xy(1, 1), xy(2, 2)]);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('closes polygon when clicking first point', () => {
|
|
202
|
+
const firstPoint = xy(1, 2);
|
|
203
|
+
let mark = t.addPoint(firstPoint);
|
|
204
|
+
mark = t.addPoint(xy(3, 4), mark);
|
|
205
|
+
mark = t.addPoint(xy(5, 6), mark);
|
|
206
|
+
mark = t.addPoint(firstPoint, mark);
|
|
207
|
+
|
|
208
|
+
expect(mark.closed).toBe(true);
|
|
209
|
+
expect(mark.building).toBe(false);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('does not add duplicate points', () => {
|
|
213
|
+
const point = xy(1, 2);
|
|
214
|
+
let mark = t.addPoint(point);
|
|
215
|
+
mark = t.addPoint(xy(3, 4), mark);
|
|
216
|
+
// Adding the first point again would close it
|
|
217
|
+
// Let's add it one more time after closing to test duplicate handling
|
|
218
|
+
mark = t.addPoint(point, mark);
|
|
219
|
+
|
|
220
|
+
// When we add the first point to a polygon with 2+ points, it closes
|
|
221
|
+
expect(mark.points).toHaveLength(2);
|
|
222
|
+
expect(mark.closed).toBe(true);
|
|
223
|
+
expect(mark.building).toBe(false);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('does not add duplicate non-first points', () => {
|
|
227
|
+
const firstPoint = xy(1, 2);
|
|
228
|
+
const secondPoint = xy(3, 4);
|
|
229
|
+
let mark = t.addPoint(firstPoint);
|
|
230
|
+
mark = t.addPoint(secondPoint, mark);
|
|
231
|
+
mark = t.addPoint(xy(5, 6), mark);
|
|
232
|
+
// Try to add the second point again (not the first point)
|
|
233
|
+
mark = t.addPoint(secondPoint, mark);
|
|
234
|
+
|
|
235
|
+
// Should not add the duplicate point
|
|
236
|
+
expect(mark.points).toHaveLength(3);
|
|
237
|
+
expect(mark.points).toEqual([firstPoint, secondPoint, xy(5, 6)]);
|
|
238
|
+
expect(mark.closed).toBe(false);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('preserves mark properties when adding points', () => {
|
|
242
|
+
const mark = {
|
|
243
|
+
type: 'polygon',
|
|
244
|
+
points: [xy(1, 2)],
|
|
245
|
+
closed: false,
|
|
246
|
+
building: true,
|
|
247
|
+
label: 'My Shape',
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const result = t.addPoint(xy(3, 4), mark);
|
|
251
|
+
expect(result.label).toBe('My Shape');
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
describe('integration scenarios', () => {
|
|
256
|
+
it('creates complete triangle', () => {
|
|
257
|
+
const p1 = xy(0, 0);
|
|
258
|
+
const p2 = xy(1, 0);
|
|
259
|
+
const p3 = xy(0.5, 1);
|
|
260
|
+
|
|
261
|
+
let mark = t.addPoint(p1);
|
|
262
|
+
mark = t.addPoint(p2, mark);
|
|
263
|
+
mark = t.addPoint(p3, mark);
|
|
264
|
+
mark = t.addPoint(p1, mark);
|
|
265
|
+
|
|
266
|
+
expect(mark.points).toEqual([p1, p2, p3]);
|
|
267
|
+
expect(mark.closed).toBe(true);
|
|
268
|
+
expect(mark.building).toBe(false);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('creates complete square', () => {
|
|
272
|
+
const points = [xy(0, 0), xy(1, 0), xy(1, 1), xy(0, 1)];
|
|
273
|
+
|
|
274
|
+
let mark = t.addPoint(points[0]);
|
|
275
|
+
points.slice(1).forEach((p) => {
|
|
276
|
+
mark = t.addPoint(p, mark);
|
|
277
|
+
});
|
|
278
|
+
mark = t.addPoint(points[0], mark);
|
|
279
|
+
|
|
280
|
+
expect(mark.points).toEqual(points);
|
|
281
|
+
expect(mark.closed).toBe(true);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it('can force complete without closing', () => {
|
|
285
|
+
let mark = t.addPoint(xy(0, 0));
|
|
286
|
+
mark = t.addPoint(xy(1, 1), mark);
|
|
287
|
+
mark = t.complete(null, mark);
|
|
288
|
+
|
|
289
|
+
expect(mark.closed).toBe(true);
|
|
290
|
+
expect(mark.building).toBe(false);
|
|
291
|
+
expect(mark.points).toHaveLength(2);
|
|
292
|
+
});
|
|
64
293
|
});
|
|
65
294
|
});
|