1+ import type { UseDraggableReturn } from '@vueuse/core' ;
12import type { Ref } from 'vue' ;
23import type { UsePointerOptions } from './use-pointer' ;
3- import { beforeEach , describe , expect , it } from 'vitest' ;
4- import { computed , ref } from 'vue' ;
4+ import { useDraggable } from '@vueuse/core' ;
5+ import { beforeEach , describe , expect , it , vi } from 'vitest' ;
6+ import { computed , nextTick , ref } from 'vue' ;
57import { usePointer } from './use-pointer' ;
68
9+ vi . mock ( '@vueuse/core' , async ( ) => {
10+ const actual = await vi . importActual ( '@vueuse/core' ) ;
11+
12+ return {
13+ ...actual ,
14+ useDraggable : vi . fn ( ) ,
15+ } ;
16+ } ) ;
17+
718describe ( 'usePointer' , ( ) => {
819 let collapsed : Ref < boolean > ;
920 let sizePercentage : Ref < number > ;
@@ -12,6 +23,10 @@ describe('usePointer', () => {
1223 let dividerEl : Ref < HTMLElement | null > ;
1324 let panelEl : Ref < HTMLElement | null > ;
1425
26+ let mockDragX : Ref < number > ;
27+ let mockDragY : Ref < number > ;
28+ let mockDragDragging : Ref < boolean > ;
29+
1530 beforeEach ( ( ) => {
1631 collapsed = ref ( false ) ;
1732 sizePercentage = ref ( 50 ) ;
@@ -40,6 +55,12 @@ describe('usePointer', () => {
4055 minSizePixels : computed ( ( ) => 50 ) ,
4156 snapPixels : computed ( ( ) => [ 100 , 200 , 300 ] ) ,
4257 } ;
58+
59+ mockDragX = ref ( 75 ) ;
60+ mockDragY = ref ( 75 ) ;
61+ mockDragDragging = ref ( false ) ;
62+
63+ vi . mocked ( useDraggable ) . mockReturnValue ( { x : mockDragX , y : mockDragY , isDragging : mockDragDragging } as UseDraggableReturn ) ;
4364 } ) ;
4465
4566 it ( 'should return handleDblClick and isDragging' , ( ) => {
@@ -51,51 +72,190 @@ describe('usePointer', () => {
5172 expect ( typeof result . isDragging . value ) . toBe ( 'boolean' ) ;
5273 } ) ;
5374
54- it ( 'should handle double click to snap to closest point' , ( ) => {
55- const { handleDblClick } = usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
75+ describe ( 'dbl click' , ( ) => {
76+ it ( 'should handle double click to snap to closest point' , ( ) => {
77+ const { handleDblClick } = usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
5678
57- sizePixels . value = 195 ; // Close to 200
58- handleDblClick ( ) ;
79+ sizePixels . value = 195 ; // Close to 200
80+ handleDblClick ( ) ;
5981
60- expect ( sizePixels . value ) . toBe ( 200 ) ;
61- } ) ;
82+ expect ( sizePixels . value ) . toBe ( 200 ) ;
83+ } ) ;
6284
63- it ( 'should remain collapsed on handle double click when collapsed' , ( ) => {
64- collapsed . value = true ;
65- const { handleDblClick } = usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
85+ it ( 'should remain collapsed on handle double click when collapsed' , ( ) => {
86+ collapsed . value = true ;
87+ const { handleDblClick } = usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
6688
67- handleDblClick ( ) ;
89+ handleDblClick ( ) ;
6890
69- expect ( collapsed . value ) . toBe ( true ) ;
70- } ) ;
91+ expect ( collapsed . value ) . toBe ( true ) ;
92+ } ) ;
7193
72- it ( 'should not snap on double click when disabled' , ( ) => {
73- options . disabled = ref ( true ) ;
74- const originalSize = sizePixels . value ;
75- const { handleDblClick } = usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
94+ it ( 'should not snap on double click when disabled' , ( ) => {
95+ options . disabled = ref ( true ) ;
96+ const originalSize = sizePixels . value ;
97+ const { handleDblClick } = usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
7698
77- handleDblClick ( ) ;
99+ handleDblClick ( ) ;
78100
79- expect ( sizePixels . value ) . toBe ( originalSize ) ;
80- } ) ;
101+ expect ( sizePixels . value ) . toBe ( originalSize ) ;
102+ } ) ;
103+
104+ it ( 'should not snap on double click when no snap points exist' , ( ) => {
105+ options . snapPixels = computed ( ( ) => [ ] ) ;
106+ const originalSize = sizePixels . value ;
107+ const { handleDblClick } = usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
81108
82- it ( 'should not snap on double click when no snap points exist' , ( ) => {
83- options . snapPixels = computed ( ( ) => [ ] ) ;
84- const originalSize = sizePixels . value ;
85- const { handleDblClick } = usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
109+ handleDblClick ( ) ;
86110
87- handleDblClick ( ) ;
111+ expect ( sizePixels . value ) . toBe ( originalSize ) ;
112+ } ) ;
88113
89- expect ( sizePixels . value ) . toBe ( originalSize ) ;
114+ it ( 'should handle when collapsible is false' , ( ) => {
115+ options . collapsible = ref ( false ) ;
116+ collapsed . value = false ;
117+ const { handleDblClick } = usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
118+
119+ handleDblClick ( ) ;
120+
121+ expect ( collapsed . value ) . toBe ( false ) ; // Should remain visible when not collapsible
122+ } ) ;
90123 } ) ;
91124
92- it ( 'should handle when collapsible is false' , ( ) => {
93- options . collapsible = ref ( false ) ;
94- collapsed . value = false ;
95- const { handleDblClick } = usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
125+ describe ( 'dragging' , ( ) => {
126+ it ( 'should not do anything when disabled' , async ( ) => {
127+ options . disabled = true ;
128+
129+ usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
130+
131+ mockDragDragging . value = true ;
132+ mockDragX . value = 30 ; // below the minsize - threshold
133+ await nextTick ( ) ;
134+ expect ( collapsed . value ) . toBe ( false ) ;
135+ } ) ;
136+
137+ it ( 'should update sizePercentage when dragging horizontally' , async ( ) => {
138+ usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
139+
140+ mockDragX . value = 100 ; // Move to 100px
141+ await nextTick ( ) ;
142+ expect ( sizePercentage . value ) . toBe ( 25 ) ; // 100/400 * 100 = 25%
143+ } ) ;
144+
145+ it ( 'should update sizePercentage when dragging vertically' , async ( ) => {
146+ options . orientation = ref ( 'vertical' ) ;
147+ usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
148+
149+ mockDragY . value = 150 ; // Move to 150px
150+ await nextTick ( ) ;
151+ expect ( sizePercentage . value ) . toBe ( 37.5 ) ; // 150/400 * 100 = 37.5%
152+ } ) ;
153+
154+ it ( 'should handle primary end positioning' , async ( ) => {
155+ options . primary = ref ( 'end' ) ;
156+ usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
157+
158+ mockDragX . value = 100 ; // Drag position at 100px
159+ await nextTick ( ) ;
160+ // With primary end, actual position = 400 - 100 = 300px
161+
162+ expect ( sizePercentage . value ) . toBe ( 75 ) ; // 300/400 * 100 = 75%
163+ } ) ;
164+
165+ it ( 'should collapse when dragging below collapse threshold' , async ( ) => {
166+ options . minSizePixels = computed ( ( ) => 50 ) ;
167+ options . collapseThreshold = ref ( 10 ) ;
168+ usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
169+
170+ mockDragX . value = 30 ; // Below minSize (50) - collapseThreshold (10) = 40
171+ await nextTick ( ) ;
172+ expect ( collapsed . value ) . toBe ( true ) ;
173+ } ) ;
174+
175+ it ( 'should expand when dragging above expand threshold' , async ( ) => {
176+ collapsed . value = true ;
177+ options . collapseThreshold = ref ( 15 ) ;
178+ usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
179+
180+ mockDragX . value = 20 ; // Above collapseThreshold (15)
181+ await nextTick ( ) ;
182+ expect ( collapsed . value ) . toBe ( false ) ;
183+ } ) ;
184+
185+ it ( 'should not collapse when collapsible is false' , async ( ) => {
186+ options . collapsible = ref ( false ) ;
187+ usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
188+
189+ mockDragX . value = 10 ; // Very low position
190+ await nextTick ( ) ;
191+ expect ( collapsed . value ) . toBe ( false ) ;
192+ } ) ;
193+
194+ it ( 'should snap to snap points within threshold' , async ( ) => {
195+ options . snapPixels = computed ( ( ) => [ 100 , 200 , 300 ] ) ;
196+ options . snapThreshold = ref ( 8 ) ;
197+ usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
198+
199+ mockDragX . value = 195 ; // Within 8px of snap point 200
200+ await nextTick ( ) ;
201+ expect ( sizePercentage . value ) . toBe ( 50 ) ; // 200/400 * 100 = 50%
202+ } ) ;
203+
204+ it ( 'should not snap when outside snap threshold' , async ( ) => {
205+ options . snapPixels = computed ( ( ) => [ 100 , 200 , 300 ] ) ;
206+ options . snapThreshold = ref ( 5 ) ;
207+ usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
208+
209+ mockDragX . value = 190 ; // Outside 5px threshold of snap point 200
210+ await nextTick ( ) ;
211+ expect ( sizePercentage . value ) . toBe ( 47.5 ) ; // 190/400 * 100 = 47.5%
212+ } ) ;
213+
214+ it ( 'should handle RTL direction with horizontal orientation' , async ( ) => {
215+ options . direction = ref ( 'rtl' ) ;
216+ options . orientation = ref ( 'horizontal' ) ;
217+ options . snapPixels = computed ( ( ) => [ 100 ] ) ;
218+ options . snapThreshold = ref ( 5 ) ;
219+ usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
220+
221+ // With RTL, snap point 100 becomes 400 - 100 = 300
222+ mockDragX . value = 298 ; // Within threshold of transformed snap point
223+ await nextTick ( ) ;
224+ expect ( sizePercentage . value ) . toBe ( 75 ) ; // 300/400 * 100 = 75%
225+ } ) ;
226+
227+ it ( 'should clamp sizePercentage between 0 and 100' , async ( ) => {
228+ usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
229+
230+ mockDragX . value = - 50 ; // Negative position
231+ await nextTick ( ) ;
232+ expect ( sizePercentage . value ) . toBe ( 0 ) ;
233+
234+ mockDragX . value = 500 ; // Beyond component size
235+ await nextTick ( ) ;
236+ expect ( sizePercentage . value ) . toBe ( 100 ) ;
237+ } ) ;
238+
239+ it ( 'should update threshold location when dragging stops' , async ( ) => {
240+ usePointer ( collapsed , sizePercentage , sizePixels , options ) ;
241+
242+ // Start dragging
243+ mockDragDragging . value = true ;
244+ await nextTick ( ) ;
245+
246+ // Collapse during drag
247+ mockDragX . value = 30 ;
248+ await nextTick ( ) ;
249+ expect ( collapsed . value ) . toBe ( true ) ;
96250
97- handleDblClick ( ) ;
251+ // Stop dragging
252+ mockDragDragging . value = false ;
253+ await nextTick ( ) ;
98254
99- expect ( collapsed . value ) . toBe ( false ) ; // Should remain visible when not collapsible
255+ // Should now be in expand mode for next drag
256+ mockDragX . value = 5 ; // Below expand threshold
257+ await nextTick ( ) ;
258+ expect ( collapsed . value ) . toBe ( true ) ; // Should remain collapsed
259+ } ) ;
100260 } ) ;
101261} ) ;
0 commit comments