Skip to content

Commit 1d1ba06

Browse files
authored
test: add coverage for getPrefix and positionFns utilities (#788)
Add comprehensive tests for: - browserPrefixToKey, browserPrefixToStyle, getPrefix - canDragX, canDragY, createCoreData, createDraggableData This improves statement coverage from 69.5% to 74.5%, passing the 70% threshold required by CI.
1 parent cbfa655 commit 1d1ba06

File tree

2 files changed

+271
-1
lines changed

2 files changed

+271
-1
lines changed

test/utils/getPrefix.test.js

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2+
import { getPrefix, browserPrefixToKey, browserPrefixToStyle } from '../../lib/utils/getPrefix';
3+
4+
describe('getPrefix utilities', () => {
5+
describe('browserPrefixToKey', () => {
6+
it('should return prop unchanged when no prefix', () => {
7+
expect(browserPrefixToKey('transform', '')).toBe('transform');
8+
});
9+
10+
it('should prefix and capitalize for Webkit', () => {
11+
expect(browserPrefixToKey('transform', 'Webkit')).toBe('WebkitTransform');
12+
});
13+
14+
it('should prefix and capitalize for Moz', () => {
15+
expect(browserPrefixToKey('transform', 'Moz')).toBe('MozTransform');
16+
});
17+
18+
it('should handle kebab-case properties', () => {
19+
expect(browserPrefixToKey('user-select', 'Webkit')).toBe('WebkitUserSelect');
20+
});
21+
22+
it('should handle multi-hyphen properties', () => {
23+
expect(browserPrefixToKey('border-top-left-radius', 'Webkit')).toBe('WebkitBorderTopLeftRadius');
24+
});
25+
});
26+
27+
describe('browserPrefixToStyle', () => {
28+
it('should return prop unchanged when no prefix', () => {
29+
expect(browserPrefixToStyle('transform', '')).toBe('transform');
30+
});
31+
32+
it('should add CSS prefix for Webkit', () => {
33+
expect(browserPrefixToStyle('transform', 'Webkit')).toBe('-webkit-transform');
34+
});
35+
36+
it('should add CSS prefix for Moz', () => {
37+
expect(browserPrefixToStyle('transform', 'Moz')).toBe('-moz-transform');
38+
});
39+
40+
it('should add CSS prefix for ms', () => {
41+
expect(browserPrefixToStyle('transform', 'ms')).toBe('-ms-transform');
42+
});
43+
});
44+
45+
describe('getPrefix', () => {
46+
let originalWindow;
47+
48+
beforeEach(() => {
49+
originalWindow = global.window;
50+
});
51+
52+
afterEach(() => {
53+
global.window = originalWindow;
54+
});
55+
56+
it('should return empty string when window is undefined', () => {
57+
global.window = undefined;
58+
expect(getPrefix('transform')).toBe('');
59+
});
60+
61+
it('should return empty string when documentElement.style is unavailable', () => {
62+
global.window = { document: {} };
63+
expect(getPrefix('transform')).toBe('');
64+
});
65+
66+
it('should return empty string when prop exists unprefixed', () => {
67+
global.window = {
68+
document: {
69+
documentElement: {
70+
style: { transform: '' }
71+
}
72+
}
73+
};
74+
expect(getPrefix('transform')).toBe('');
75+
});
76+
77+
it('should return Webkit prefix when WebkitTransform exists', () => {
78+
global.window = {
79+
document: {
80+
documentElement: {
81+
style: { WebkitTransform: '' }
82+
}
83+
}
84+
};
85+
expect(getPrefix('transform')).toBe('Webkit');
86+
});
87+
88+
it('should return Moz prefix when MozTransform exists', () => {
89+
global.window = {
90+
document: {
91+
documentElement: {
92+
style: { MozTransform: '' }
93+
}
94+
}
95+
};
96+
expect(getPrefix('transform')).toBe('Moz');
97+
});
98+
99+
it('should return empty string when no prefix matches', () => {
100+
global.window = {
101+
document: {
102+
documentElement: {
103+
style: {}
104+
}
105+
}
106+
};
107+
expect(getPrefix('someUnknownProperty')).toBe('');
108+
});
109+
110+
it('should use transform as default prop', () => {
111+
global.window = {
112+
document: {
113+
documentElement: {
114+
style: { transform: '' }
115+
}
116+
}
117+
};
118+
expect(getPrefix()).toBe('');
119+
});
120+
});
121+
});

test/utils/positionFns.test.js

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, it, expect } from 'vitest';
2-
import { snapToGrid } from '../../lib/utils/positionFns';
2+
import { snapToGrid, canDragX, canDragY, createCoreData, createDraggableData } from '../../lib/utils/positionFns';
33

44
describe('positionFns utilities', () => {
55
describe('snapToGrid', () => {
@@ -36,4 +36,153 @@ describe('positionFns utilities', () => {
3636
expect(snapToGrid([10, 10], 4, 4)).toEqual([0, 0]);
3737
});
3838
});
39+
40+
describe('canDragX', () => {
41+
it('should return true for axis "both"', () => {
42+
const draggable = { props: { axis: 'both' } };
43+
expect(canDragX(draggable)).toBe(true);
44+
});
45+
46+
it('should return true for axis "x"', () => {
47+
const draggable = { props: { axis: 'x' } };
48+
expect(canDragX(draggable)).toBe(true);
49+
});
50+
51+
it('should return false for axis "y"', () => {
52+
const draggable = { props: { axis: 'y' } };
53+
expect(canDragX(draggable)).toBe(false);
54+
});
55+
56+
it('should return false for axis "none"', () => {
57+
const draggable = { props: { axis: 'none' } };
58+
expect(canDragX(draggable)).toBe(false);
59+
});
60+
});
61+
62+
describe('canDragY', () => {
63+
it('should return true for axis "both"', () => {
64+
const draggable = { props: { axis: 'both' } };
65+
expect(canDragY(draggable)).toBe(true);
66+
});
67+
68+
it('should return true for axis "y"', () => {
69+
const draggable = { props: { axis: 'y' } };
70+
expect(canDragY(draggable)).toBe(true);
71+
});
72+
73+
it('should return false for axis "x"', () => {
74+
const draggable = { props: { axis: 'x' } };
75+
expect(canDragY(draggable)).toBe(false);
76+
});
77+
78+
it('should return false for axis "none"', () => {
79+
const draggable = { props: { axis: 'none' } };
80+
expect(canDragY(draggable)).toBe(false);
81+
});
82+
});
83+
84+
describe('createCoreData', () => {
85+
const mockNode = document.createElement('div');
86+
87+
it('should create initial data when lastX/lastY are NaN', () => {
88+
const draggableCore = {
89+
lastX: NaN,
90+
lastY: NaN,
91+
findDOMNode: () => mockNode
92+
};
93+
const data = createCoreData(draggableCore, 100, 200);
94+
expect(data).toEqual({
95+
node: mockNode,
96+
deltaX: 0,
97+
deltaY: 0,
98+
lastX: 100,
99+
lastY: 200,
100+
x: 100,
101+
y: 200
102+
});
103+
});
104+
105+
it('should calculate deltas when lastX/lastY are set', () => {
106+
const draggableCore = {
107+
lastX: 50,
108+
lastY: 100,
109+
findDOMNode: () => mockNode
110+
};
111+
const data = createCoreData(draggableCore, 150, 250);
112+
expect(data).toEqual({
113+
node: mockNode,
114+
deltaX: 100,
115+
deltaY: 150,
116+
lastX: 50,
117+
lastY: 100,
118+
x: 150,
119+
y: 250
120+
});
121+
});
122+
123+
it('should throw when node is unmounted', () => {
124+
const draggableCore = {
125+
lastX: NaN,
126+
lastY: NaN,
127+
findDOMNode: () => null
128+
};
129+
expect(() => createCoreData(draggableCore, 0, 0)).toThrow('Unmounted during event');
130+
});
131+
});
132+
133+
describe('createDraggableData', () => {
134+
const mockNode = document.createElement('div');
135+
136+
it('should create data with scale of 1', () => {
137+
const draggable = {
138+
props: { scale: 1 },
139+
state: { x: 100, y: 200 }
140+
};
141+
const coreData = {
142+
node: mockNode,
143+
deltaX: 10,
144+
deltaY: 20,
145+
lastX: 100,
146+
lastY: 200,
147+
x: 110,
148+
y: 220
149+
};
150+
const data = createDraggableData(draggable, coreData);
151+
expect(data).toEqual({
152+
node: mockNode,
153+
x: 110,
154+
y: 220,
155+
deltaX: 10,
156+
deltaY: 20,
157+
lastX: 100,
158+
lastY: 200
159+
});
160+
});
161+
162+
it('should apply scale to delta values', () => {
163+
const draggable = {
164+
props: { scale: 2 },
165+
state: { x: 100, y: 200 }
166+
};
167+
const coreData = {
168+
node: mockNode,
169+
deltaX: 20,
170+
deltaY: 40,
171+
lastX: 100,
172+
lastY: 200,
173+
x: 120,
174+
y: 240
175+
};
176+
const data = createDraggableData(draggable, coreData);
177+
expect(data).toEqual({
178+
node: mockNode,
179+
x: 110, // 100 + (20/2)
180+
y: 220, // 200 + (40/2)
181+
deltaX: 10, // 20/2
182+
deltaY: 20, // 40/2
183+
lastX: 100,
184+
lastY: 200
185+
});
186+
});
187+
});
39188
});

0 commit comments

Comments
 (0)