fix: Fix PR issues

This commit is contained in:
deytenit committed 2026-03-07 10:51:54 +03:00
1 parent d2903a3715
commit 6aa3a03319
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(() => {