import React from 'react'; import { renderHook } from '@testing-library/react-native'; import { useDropCompensation } from '../../hooks/drag/useDropCompensation'; import { DragStateProvider } from '../../contexts/DragStateContext'; import { createMockSharedValue } from '../utils/test-utils'; describe('useDropCompensation', () => { const createWrapper = () => { const Wrapper = ({ children }: { children: React.ReactNode }) => ( {children} ); return Wrapper; }; it('does not throw when initialized', async () => { const translateY = createMockSharedValue(0); const shiftY = createMockSharedValue(0); await expect( renderHook( () => useDropCompensation({ itemId: 'item-1', index: 0, translateY: translateY as any, shiftY: shiftY as any, }), { wrapper: createWrapper() }, ), ).resolves.toBeDefined(); }); it('handles index unchanged scenario', async () => { const translateY = createMockSharedValue(0); const shiftY = createMockSharedValue(0); const { rerender } = await renderHook( ({ index }) => useDropCompensation({ itemId: 'item-1', index, translateY: translateY as any, shiftY: shiftY as any, }), { wrapper: createWrapper(), initialProps: { index: 0 }, }, ); // Rerender with same index await rerender({ index: 0 }); // Should not modify translateY when index doesn't change expect(translateY.value).toBe(0); }); it('works with different item IDs', async () => { const translateY = createMockSharedValue(0); const shiftY = createMockSharedValue(0); const { rerender } = await renderHook( ({ itemId, index }) => useDropCompensation({ itemId, index, translateY: translateY as any, shiftY: shiftY as any, }), { wrapper: createWrapper(), initialProps: { itemId: 'item-1', index: 0 }, }, ); // Rerender with different itemId (view recycling) await rerender({ itemId: 'item-2', index: 0 }); expect(translateY.value).toBe(0); }); it('tracks index changes via shared value', async () => { const translateY = createMockSharedValue(0); const shiftY = createMockSharedValue(0); const { rerender } = await renderHook( ({ index }) => useDropCompensation({ itemId: 'item-1', index, translateY: translateY as any, shiftY: shiftY as any, }), { wrapper: createWrapper(), initialProps: { index: 0 }, }, ); // Rerender with new index await rerender({ index: 1 }); // Hook should track the index change }); it('handles multiple items with different indices', async () => { // Iterate sequentially to avoid overlapping act() calls for (const index of [0, 1, 2, 3, 4]) { const translateY = createMockSharedValue(0); const shiftY = createMockSharedValue(0); // useDropCompensation returns void - just verify it doesn't throw await expect( renderHook( () => useDropCompensation({ itemId: `item-${index}`, index, translateY: translateY as any, shiftY: shiftY as any, }), { wrapper: createWrapper() }, ), ).resolves.toBeDefined(); } }); it('unmounts cleanly', async () => { const translateY = createMockSharedValue(0); const shiftY = createMockSharedValue(0); const { unmount } = await renderHook( () => useDropCompensation({ itemId: 'item-1', index: 0, translateY: translateY as any, shiftY: shiftY as any, }), { wrapper: createWrapper() }, ); expect(() => unmount()).not.toThrow(); }); it('works with non-zero initial shiftY', async () => { const translateY = createMockSharedValue(0); const shiftY = createMockSharedValue(80); await renderHook( () => useDropCompensation({ itemId: 'item-1', index: 0, translateY: translateY as any, shiftY: shiftY as any, }), { wrapper: createWrapper() }, ); // Hook should handle non-zero shiftY expect(shiftY.value).toBe(80); }); it('works with non-zero initial translateY', async () => { const translateY = createMockSharedValue(100); const shiftY = createMockSharedValue(0); await renderHook( () => useDropCompensation({ itemId: 'item-1', index: 0, translateY: translateY as any, shiftY: shiftY as any, }), { wrapper: createWrapper() }, ); // Hook should handle non-zero translateY expect(translateY.value).toBe(100); }); });