fix: Fix PR issues
This commit is contained in:
20 files changed
+291
-67
No files matched your search
@@ -1,15 +1,79 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { renderHook, act } from '@testing-library/react';
|
||||
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
|
||||
import { useResizeObserver } from './useResizeObserver';
|
||||
|
||||
describe('useResizeObserver', () => {
|
||||
let observerCallback: ResizeObserverCallback;
|
||||
const observeMock = vi.fn();
|
||||
const unobserveMock = vi.fn();
|
||||
const disconnectMock = vi.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
class MockResizeObserver {
|
||||
constructor(callback: ResizeObserverCallback) {
|
||||
observerCallback = callback;
|
||||
}
|
||||
observe = observeMock;
|
||||
unobserve = unobserveMock;
|
||||
disconnect = disconnectMock;
|
||||
}
|
||||
|
||||
vi.stubGlobal('ResizeObserver', MockResizeObserver);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should return initial dimensions', () => {
|
||||
const ref = React.createRef<HTMLDivElement>();
|
||||
const ref = { current: document.createElement('div') };
|
||||
const { result } = renderHook(() => useResizeObserver(ref));
|
||||
expect(result.current).toEqual({ width: 0, height: 0 });
|
||||
});
|
||||
|
||||
// Testing the actual resize observation is tricky in JSDOM.
|
||||
// A more complete test would require a full browser environment.
|
||||
it('should call observe on mount', () => {
|
||||
const element = document.createElement('div');
|
||||
const ref = { current: element };
|
||||
renderHook(() => useResizeObserver(ref));
|
||||
|
||||
expect(observeMock).toHaveBeenCalledWith(element);
|
||||
});
|
||||
|
||||
it('should update dimensions when ResizeObserver triggers', () => {
|
||||
const element = document.createElement('div');
|
||||
const ref = { current: element };
|
||||
const { result } = renderHook(() => useResizeObserver(ref));
|
||||
|
||||
const entries = [
|
||||
{
|
||||
contentRect: { width: 100, height: 200 },
|
||||
target: element,
|
||||
},
|
||||
] as unknown as ResizeObserverEntry[];
|
||||
|
||||
act(() => {
|
||||
observerCallback(entries, {} as ResizeObserver);
|
||||
});
|
||||
|
||||
expect(result.current).toEqual({ width: 100, height: 200 });
|
||||
});
|
||||
|
||||
it('should call disconnect on unmount', () => {
|
||||
const element = document.createElement('div');
|
||||
const ref = { current: element };
|
||||
const { unmount } = renderHook(() => useResizeObserver(ref));
|
||||
|
||||
unmount();
|
||||
|
||||
expect(disconnectMock).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not observe if ref is null', () => {
|
||||
const ref = { current: null };
|
||||
renderHook(() => useResizeObserver(ref));
|
||||
|
||||
expect(observeMock).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -49,7 +49,7 @@ export const useResizeObserver = <T extends HTMLElement>(
|
||||
resizeObserver.observe(observeTarget);
|
||||
|
||||
return () => {
|
||||
resizeObserver.unobserve(observeTarget);
|
||||
resizeObserver.disconnect();
|
||||
};
|
||||
}, [ref]);
|
||||
|
||||
|
||||
@@ -1,17 +1,35 @@
|
||||
import { renderHook, act } from '@testing-library/react';
|
||||
import { vi, describe, it, expect } from 'vitest';
|
||||
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
|
||||
import { useScroll } from './useScroll';
|
||||
|
||||
describe('useScroll', () => {
|
||||
const originalScrollX = window.scrollX;
|
||||
const originalScrollY = window.scrollY;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.stubGlobal('requestAnimationFrame', (callback: FrameRequestCallback) => {
|
||||
return setTimeout(callback, 0);
|
||||
});
|
||||
vi.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
vi.useRealTimers();
|
||||
window.scrollX = originalScrollX;
|
||||
window.scrollY = originalScrollY;
|
||||
});
|
||||
|
||||
it('should return initial scroll position', () => {
|
||||
window.scrollX = 50;
|
||||
window.scrollY = 150;
|
||||
const { result } = renderHook(() => useScroll());
|
||||
expect(result.current).toEqual({ x: 0, y: 0 });
|
||||
expect(result.current).toEqual({ x: 50, y: 150 });
|
||||
});
|
||||
|
||||
it('should update scroll position on scroll', () => {
|
||||
vi.useFakeTimers();
|
||||
renderHook(() => useScroll());
|
||||
const { result } = renderHook(() => useScroll());
|
||||
|
||||
act(() => {
|
||||
window.scrollX = 100;
|
||||
@@ -19,13 +37,34 @@ describe('useScroll', () => {
|
||||
window.dispatchEvent(new Event('scroll'));
|
||||
});
|
||||
|
||||
// We need to wait for the next animation frame
|
||||
// Wait for requestAnimationFrame (mocked via setTimeout)
|
||||
act(() => {
|
||||
vi.runAllTimers();
|
||||
});
|
||||
|
||||
// In JSDOM, window.scrollX/Y might not persist the manual assignment
|
||||
// depending on the environment setup, but we'll try to verify it.
|
||||
vi.useRealTimers();
|
||||
expect(result.current).toEqual({ x: 100, y: 200 });
|
||||
});
|
||||
|
||||
it('should throttle updates using requestAnimationFrame', () => {
|
||||
const { result } = renderHook(() => useScroll());
|
||||
|
||||
act(() => {
|
||||
window.scrollX = 100;
|
||||
window.scrollY = 200;
|
||||
window.dispatchEvent(new Event('scroll'));
|
||||
|
||||
window.scrollX = 300;
|
||||
window.scrollY = 400;
|
||||
window.dispatchEvent(new Event('scroll'));
|
||||
});
|
||||
|
||||
// Before timers run, it should still be initial or first set if not throttled correctly
|
||||
// But since we trigger twice in same tick, ticking.current prevents second RAF.
|
||||
|
||||
act(() => {
|
||||
vi.runAllTimers();
|
||||
});
|
||||
|
||||
expect(result.current).toEqual({ x: 300, y: 400 });
|
||||
});
|
||||
});
|
||||
@@ -19,7 +19,10 @@ export interface UseScrollResult {
|
||||
* ```
|
||||
*/
|
||||
export const useScroll = (): UseScrollResult => {
|
||||
const [scroll, setScroll] = useState({ x: 0, y: 0 });
|
||||
const [scroll, setScroll] = useState(() => ({
|
||||
x: typeof window !== 'undefined' ? window.scrollX : 0,
|
||||
y: typeof window !== 'undefined' ? window.scrollY : 0,
|
||||
}));
|
||||
const ticking = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
Reference in new issue
Block a user