Upgrade React 18.3.1 → 19.2.4 with full type compatibility. Changes: - react, react-dom → ^19.0.0 - @types/react, @types/react-dom → ^19.0.0 - lucide-react → ^0.577.0 (React 19 type fixes) - @tiptap/* → ^3.20.4 (React 19 support) - useRef calls now require explicit initial value (undefined) - RefObject types updated for React 19 (includes null) - MutableRefObject → RefObject (deprecated in 19) - act() import moved from react-dom/test-utils to react - Scoped JSX namespace imports added where needed
54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
import React, { act } from 'react';
|
|
import { createRoot } from 'react-dom/client';
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
import { useVisibleAIGroup } from '../../../src/renderer/hooks/useVisibleAIGroup';
|
|
|
|
class FakeIntersectionObserver {
|
|
constructor(_callback: IntersectionObserverCallback, _options?: IntersectionObserverInit) {}
|
|
|
|
observe(): void {}
|
|
unobserve(): void {}
|
|
disconnect(): void {}
|
|
takeRecords(): IntersectionObserverEntry[] {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
describe('useVisibleAIGroup', () => {
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
document.body.innerHTML = '';
|
|
});
|
|
|
|
it('uses provided rootRef as IntersectionObserver root', async () => {
|
|
const observerSpy = vi.fn(
|
|
(cb: IntersectionObserverCallback, opts?: IntersectionObserverInit) =>
|
|
new FakeIntersectionObserver(cb, opts)
|
|
);
|
|
|
|
vi.stubGlobal('IntersectionObserver', observerSpy as unknown as typeof IntersectionObserver);
|
|
|
|
const host = document.createElement('div');
|
|
document.body.appendChild(host);
|
|
const rootEl = document.createElement('div');
|
|
|
|
function Harness(): React.JSX.Element {
|
|
const rootRef = React.useRef<HTMLElement>(rootEl);
|
|
useVisibleAIGroup({ onVisibleChange: () => undefined, rootRef });
|
|
return React.createElement('div');
|
|
}
|
|
|
|
const root = createRoot(host);
|
|
await act(async () => {
|
|
root.render(React.createElement(Harness));
|
|
await Promise.resolve();
|
|
});
|
|
|
|
expect(observerSpy).toHaveBeenCalled();
|
|
const lastCall = observerSpy.mock.calls[observerSpy.mock.calls.length - 1];
|
|
expect(lastCall?.[1]?.root).toBe(rootEl);
|
|
|
|
root.unmount();
|
|
});
|
|
});
|