Skip to content

Commit 66147fa

Browse files
authored
test: add registry test cases (#4766)
* test: add registry test cases * fix: delete some useless code * fix: fix gemini suggestion
1 parent d87ad0c commit 66147fa

28 files changed

+4026
-3
lines changed

__tests__/registry/edge-anchor/ratio.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ describe('ratio edge anchor', () => {
100100
expect(result).toEqual({ x: 100, y: 100 })
101101
})
102102

103-
it('should return first point when getPointAtRatio returns null', () => {
103+
it('should return null when getPointAtRatio returns null', () => {
104104
const mockView = {
105105
getPointAtRatio: vi.fn(() => null),
106106
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import { beforeEach, describe, expect, it, vi } from 'vitest'
2+
import type { BBoxEndpointOptions } from '../../../src/registry/node-anchor/bbox'
3+
import * as bboxModule from '../../../src/registry/node-anchor/bbox'
4+
5+
vi.mock('../../../src/geometry', () => ({
6+
Point: {
7+
prototype: {
8+
rotate: vi.fn(function (angle, center) {
9+
return { x: this.x, y: this.y, rotated: true, angle, center }
10+
}),
11+
},
12+
},
13+
}))
14+
15+
describe('BBox Node Anchor', () => {
16+
let mockView: any
17+
let mockMagnet: any
18+
let mockRef: any
19+
let mockCell: any
20+
21+
beforeEach(() => {
22+
mockCell = {
23+
visible: true,
24+
getAngle: vi.fn(() => 30),
25+
getBBox: vi.fn(() => ({
26+
getCenter: vi.fn(() => ({ x: 50, y: 50 })),
27+
})),
28+
}
29+
30+
mockView = {
31+
cell: mockCell,
32+
getUnrotatedBBoxOfElement: vi.fn(() => ({
33+
center: { x: 100, y: 100 },
34+
topCenter: { x: 100, y: 50 },
35+
bottomCenter: { x: 100, y: 150 },
36+
leftMiddle: { x: 50, y: 100 },
37+
rightMiddle: { x: 150, y: 100 },
38+
topLeft: { x: 50, y: 50 },
39+
topRight: { x: 150, y: 50 },
40+
bottomLeft: { x: 50, y: 150 },
41+
bottomRight: { x: 150, y: 150 },
42+
width: 100,
43+
height: 100,
44+
})),
45+
getBBoxOfElement: vi.fn(() => ({
46+
center: { x: 100, y: 100 },
47+
topCenter: { x: 100, y: 50 },
48+
bottomCenter: { x: 100, y: 150 },
49+
leftMiddle: { x: 50, y: 100 },
50+
rightMiddle: { x: 150, y: 100 },
51+
topLeft: { x: 50, y: 50 },
52+
topRight: { x: 150, y: 50 },
53+
bottomLeft: { x: 50, y: 150 },
54+
bottomRight: { x: 150, y: 150 },
55+
width: 100,
56+
height: 100,
57+
})),
58+
}
59+
60+
mockMagnet = document.createElement('div')
61+
mockRef = { x: 200, y: 200 }
62+
})
63+
64+
describe('createBBoxAnchor function', () => {
65+
const testCases = [
66+
{ method: 'center', expected: { x: 100, y: 100 } },
67+
{ method: 'top', expected: { x: 100, y: 50 } },
68+
{ method: 'bottom', expected: { x: 100, y: 150 } },
69+
{ method: 'left', expected: { x: 50, y: 100 } },
70+
{ method: 'right', expected: { x: 150, y: 100 } },
71+
{ method: 'topLeft', expected: { x: 50, y: 50 } },
72+
{ method: 'topRight', expected: { x: 150, y: 50 } },
73+
{ method: 'bottomLeft', expected: { x: 50, y: 150 } },
74+
{ method: 'bottomRight', expected: { x: 150, y: 150 } },
75+
]
76+
77+
testCases.forEach(({ method, expected }) => {
78+
it(`should return correct ${method} position`, () => {
79+
const anchor = bboxModule[method as keyof typeof bboxModule]
80+
const result = anchor(mockView, mockMagnet, mockRef, {})
81+
82+
expect(result).toEqual(expected)
83+
})
84+
})
85+
})
86+
87+
describe('with offset options', () => {
88+
it('should apply dx and dy offsets', () => {
89+
const options: BBoxEndpointOptions = {
90+
dx: 10,
91+
dy: -5,
92+
}
93+
94+
const result = bboxModule.center(mockView, mockMagnet, mockRef, options)
95+
96+
expect(result).toEqual({ x: 110, y: 95 })
97+
})
98+
99+
it('should handle percentage offsets', () => {
100+
const options: BBoxEndpointOptions = {
101+
dx: '10%',
102+
dy: '20%',
103+
}
104+
105+
const result = bboxModule.center(mockView, mockMagnet, mockRef, options)
106+
107+
expect(result).toEqual({ x: 110, y: 120 })
108+
})
109+
})
110+
111+
describe('rotate option', () => {
112+
it('should use normal bbox when rotate is false', () => {
113+
const options: BBoxEndpointOptions = {
114+
rotate: false,
115+
}
116+
117+
const result = bboxModule.center(mockView, mockMagnet, mockRef, options)
118+
119+
expect(mockView.getBBoxOfElement).toHaveBeenCalledWith(mockMagnet)
120+
expect(result).toEqual({ x: 100, y: 100 })
121+
})
122+
})
123+
124+
describe('when cell is not visible', () => {
125+
beforeEach(() => {
126+
mockCell.visible = false
127+
mockCell.getBBox = vi.fn(() => ({
128+
center: { x: 75, y: 75 },
129+
width: 50,
130+
height: 50,
131+
}))
132+
})
133+
134+
it('should use cell bbox when cell is not visible', () => {
135+
const result = bboxModule.center(mockView, mockMagnet, mockRef, {})
136+
137+
expect(mockView.getBBoxOfElement).not.toHaveBeenCalled()
138+
expect(mockView.getUnrotatedBBoxOfElement).not.toHaveBeenCalled()
139+
expect(result).toEqual({ x: 75, y: 75 })
140+
})
141+
})
142+
143+
describe('exported anchors', () => {
144+
const anchors = [
145+
'center',
146+
'top',
147+
'bottom',
148+
'left',
149+
'right',
150+
'topLeft',
151+
'topRight',
152+
'bottomLeft',
153+
'bottomRight',
154+
]
155+
156+
anchors.forEach((anchor) => {
157+
it(`should export ${anchor} anchor function`, () => {
158+
expect(bboxModule[anchor as keyof typeof bboxModule]).toBeDefined()
159+
expect(typeof bboxModule[anchor as keyof typeof bboxModule]).toBe(
160+
'function',
161+
)
162+
})
163+
})
164+
})
165+
})
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import { describe, expect, it, vi } from 'vitest'
2+
import { Point } from '../../../src/geometry'
3+
import { midSide } from '../../../src/registry/node-anchor/middle-side'
4+
5+
const createMockView = (bbox: any, angle: number = 0) => ({
6+
cell: {
7+
getBBox: vi.fn(() => ({
8+
getCenter: vi.fn(
9+
() => new Point(bbox.x + bbox.width / 2, bbox.y + bbox.height / 2),
10+
),
11+
})),
12+
getAngle: vi.fn(() => angle),
13+
visible: true,
14+
},
15+
getBBoxOfElement: vi.fn(() => bbox),
16+
getUnrotatedBBoxOfElement: vi.fn(() => bbox),
17+
})
18+
19+
const createMockBBox = (
20+
x: number,
21+
y: number,
22+
width: number,
23+
height: number,
24+
) => ({
25+
x,
26+
y,
27+
width,
28+
height,
29+
inflate: vi.fn(function (padding: number) {
30+
this.x -= padding
31+
this.y -= padding
32+
this.width += padding * 2
33+
this.height += padding * 2
34+
return this
35+
}),
36+
getLeftMiddle: vi.fn(() => new Point(x, y + height / 2)),
37+
getRightMiddle: vi.fn(() => new Point(x + width, y + height / 2)),
38+
getTopCenter: vi.fn(() => new Point(x + width / 2, y)),
39+
getBottomCenter: vi.fn(() => new Point(x + width / 2, y + height)),
40+
getNearestSideToPoint: vi.fn((point: Point) => {
41+
const distances = {
42+
left: Math.abs(point.x - x),
43+
right: Math.abs(point.x - (x + width)),
44+
top: Math.abs(point.y - y),
45+
bottom: Math.abs(point.y - (y + height)),
46+
}
47+
return Object.entries(distances).reduce(
48+
(min, [side, dist]) =>
49+
dist < min.distance ? { side, distance: dist } : min,
50+
{ side: 'left', distance: Infinity },
51+
).side
52+
}),
53+
})
54+
55+
describe('midSide anchor', () => {
56+
it('应该返回左边中点当参考点在左侧', () => {
57+
const bbox = createMockBBox(0, 0, 100, 100)
58+
const view = createMockView(bbox)
59+
const refPoint = new Point(-10, 50)
60+
const magnet = document.createElement('div')
61+
62+
const result = midSide(view, magnet, refPoint, {})
63+
64+
expect(result.x).toBe(0)
65+
expect(result.y).toBe(50)
66+
})
67+
68+
it('应该返回右边中点当参考点在右侧', () => {
69+
const bbox = createMockBBox(0, 0, 100, 100)
70+
const view = createMockView(bbox)
71+
const refPoint = new Point(110, 50)
72+
const magnet = document.createElement('div')
73+
74+
const result = midSide(view, magnet, refPoint, {})
75+
76+
expect(result.x).toBe(100)
77+
expect(result.y).toBe(50)
78+
})
79+
80+
it('应该返回上边中点当参考点在上方', () => {
81+
const bbox = createMockBBox(0, 0, 100, 100)
82+
const view = createMockView(bbox)
83+
const refPoint = new Point(50, -10)
84+
const magnet = document.createElement('div')
85+
86+
const result = midSide(view, magnet, refPoint, {})
87+
88+
expect(result.x).toBe(50)
89+
expect(result.y).toBe(0)
90+
})
91+
92+
it('应该返回下边中点当参考点在下方', () => {
93+
const bbox = createMockBBox(0, 0, 100, 100)
94+
const view = createMockView(bbox)
95+
const refPoint = new Point(50, 110)
96+
const magnet = document.createElement('div')
97+
98+
const result = midSide(view, magnet, refPoint, {})
99+
100+
expect(result.x).toBe(50)
101+
expect(result.y).toBe(100)
102+
})
103+
104+
it('应该应用padding选项', () => {
105+
const bbox = createMockBBox(0, 0, 100, 100)
106+
const view = createMockView(bbox)
107+
const refPoint = new Point(-10, 50)
108+
const magnet = document.createElement('div')
109+
110+
const result = midSide(view, magnet, refPoint, { padding: 10 })
111+
112+
expect(bbox.inflate).toHaveBeenCalledWith(10)
113+
})
114+
115+
it('应该处理旋转的节点', () => {
116+
const bbox = createMockBBox(0, 0, 100, 100)
117+
const view = createMockView(bbox, 45)
118+
const refPoint = new Point(-10, 50)
119+
const magnet = document.createElement('div')
120+
121+
const result = midSide(view, magnet, refPoint, { rotate: true })
122+
123+
// 旋转后的点应该被正确计算
124+
expect(result).toBeDefined()
125+
})
126+
127+
it('应该处理水平方向约束', () => {
128+
const bbox = createMockBBox(0, 0, 100, 100)
129+
const view = createMockView(bbox)
130+
const refPoint = new Point(50, -10)
131+
const magnet = document.createElement('div')
132+
133+
const result = midSide(view, magnet, refPoint, { direction: 'H' })
134+
135+
expect(result.x === 0 || result.x === 100).toBe(true)
136+
expect(result.y).toBe(50)
137+
})
138+
139+
it('应该处理垂直方向约束', () => {
140+
const bbox = createMockBBox(0, 0, 100, 100)
141+
const view = createMockView(bbox)
142+
const refPoint = new Point(-10, 50)
143+
const magnet = document.createElement('div')
144+
145+
const result = midSide(view, magnet, refPoint, { direction: 'V' })
146+
147+
expect(result.y === 0 || result.y === 100).toBe(true)
148+
expect(result.x).toBe(50)
149+
})
150+
151+
it('应该处理不可见节点', () => {
152+
const bbox = createMockBBox(0, 0, 100, 100)
153+
const view = {
154+
...createMockView(bbox),
155+
cell: {
156+
...createMockView(bbox).cell,
157+
visible: false,
158+
getBBox: vi.fn(() => bbox),
159+
},
160+
}
161+
const refPoint = new Point(-10, 50)
162+
const magnet = document.createElement('div')
163+
164+
const result = midSide(view, magnet, refPoint, {})
165+
166+
expect(result.x).toBe(0)
167+
expect(result.y).toBe(50)
168+
})
169+
})

0 commit comments

Comments
 (0)