import { vi } from 'vitest'; import { renderHook } from '@testing-library/react-hooks'; import { useReactTable } from '@tanstack/react-table'; import { withTableState } from './withTableState'; import { useState } from 'react'; import { render } from '@testing-library/react'; describe('withTableState', () => { it('should create paginated and sorted table state', () => { const mockTableState = { limit: 10, offset: 10, sortBy: 'name', sortOrder: 'asc', }; const mockSetTableState = vi.fn(); const mockOptions = { data: [], columns: [] }; const result = withTableState( mockTableState, mockSetTableState, mockOptions, ); expect(result.state).toEqual({ pagination: { pageIndex: 1, pageSize: 10, }, sorting: [ { id: 'name', desc: false, }, ], }); }); it('sets default options', () => { expect( withTableState( { limit: 10, offset: 10, sortBy: 'name', sortOrder: 'asc', }, vi.fn(), { data: [], columns: [] }, ), ).toMatchObject({ getCoreRowModel: expect.any(Function), enableSorting: true, enableMultiSort: false, manualPagination: true, manualSorting: true, enableSortingRemoval: false, enableHiding: true, onPaginationChange: expect.any(Function), onSortingChange: expect.any(Function), onColumnVisibilityChange: expect.any(Function), }); }); it('should update page index and size', () => { const mockTableState = { limit: 10, offset: 10, sortBy: 'name', sortOrder: 'asc', }; const mockSetTableState = vi.fn(); const mockOptions = { data: [], columns: [] }; const { result } = renderHook(() => useReactTable( withTableState(mockTableState, mockSetTableState, mockOptions), ), ); result.current.setPagination({ pageIndex: 3, pageSize: 5, }); expect(mockSetTableState).toHaveBeenCalledWith({ limit: 5, offset: 15, }); }); it('should update sorting', () => { const mockTableState = { limit: 10, offset: 10, sortBy: 'name', sortOrder: 'asc', }; const mockSetTableState = vi.fn(); const mockOptions = { data: [], columns: [] }; const { result } = renderHook(() => useReactTable( withTableState(mockTableState, mockSetTableState, mockOptions), ), ); result.current.setSorting([ { id: 'createdAt', desc: true, }, ]); expect(mockSetTableState).toHaveBeenCalledWith({ sortBy: 'createdAt', sortOrder: 'desc', }); }); it('should handle column visibility', () => { const mockTableState = { limit: 10, offset: 10, sortBy: 'name', sortOrder: 'asc', columns: ['name'], }; const mockSetTableState = vi.fn(); const mockOptions = { data: [], columns: [ { id: 'name', show: true, }, { id: 'createdAt', show: false, }, ], }; const { result } = renderHook(() => useReactTable( withTableState(mockTableState, mockSetTableState, mockOptions), ), ); expect(result.current.getState().columnVisibility).toMatchObject({ name: true, }); result.current.setColumnVisibility({ name: false, createdAt: true }); expect(mockSetTableState).toHaveBeenCalledWith({ columns: ['createdAt'], }); }); it('is always using external state', () => { const initialProps = { limit: 5, offset: 40, sortBy: 'name', sortOrder: 'desc', }; const { result, rerender } = renderHook( (state) => useReactTable( withTableState(state as any, vi.fn(), { data: [], columns: [], }), ), { initialProps }, ); expect(result.current.getState()).toMatchObject({ pagination: { pageIndex: 8, pageSize: 5, }, sorting: [ { id: 'name', desc: true, }, ], }); rerender({ limit: 10, offset: 10, sortBy: 'createdAt', sortOrder: 'asc', }); expect(result.current.getState()).toMatchObject({ pagination: { pageIndex: 1, pageSize: 10, }, sorting: [ { id: 'createdAt', desc: false, }, ], }); }); it('works end-to-end with useReactTable', () => { const Component = () => { const [state, setState] = useState({ limit: 5, offset: 40, sortBy: 'name', sortOrder: 'desc', }); const setTableState = (newState: any) => { setState((state) => ({ ...state, ...newState })); }; const table = useReactTable( withTableState(state, setTableState, { data: [], columns: [], }), ); return ( <>