From 669a6c4e6c069b261b0b614ad2451909ce9224a2 Mon Sep 17 00:00:00 2001 From: Viki Date: Wed, 9 Oct 2024 15:33:07 +0800 Subject: [PATCH] test: add more test cases --- .../react-use/src/use-parallax/index.test.ts | 8 ++ .../src/use-parent-element/index.test.ts | 82 ++++++++++++++ .../react-use/src/use-parent-element/index.ts | 3 +- .../src/use-pausable-effect/index.test.ts | 101 ++++++++++++++++++ .../use-pausable-layout-effect/index.test.ts | 101 ++++++++++++++++++ 5 files changed, 293 insertions(+), 2 deletions(-) create mode 100644 packages/react-use/src/use-parallax/index.test.ts create mode 100644 packages/react-use/src/use-parent-element/index.test.ts create mode 100644 packages/react-use/src/use-pausable-effect/index.test.ts create mode 100644 packages/react-use/src/use-pausable-layout-effect/index.test.ts diff --git a/packages/react-use/src/use-parallax/index.test.ts b/packages/react-use/src/use-parallax/index.test.ts new file mode 100644 index 00000000..3355c130 --- /dev/null +++ b/packages/react-use/src/use-parallax/index.test.ts @@ -0,0 +1,8 @@ +import { describe, expect, it } from 'vitest' +import { useParallax } from './index' + +describe('useParallax', () => { + it('should defined', () => { + expect(useParallax).toBeDefined() + }) +}) diff --git a/packages/react-use/src/use-parent-element/index.test.ts b/packages/react-use/src/use-parent-element/index.test.ts new file mode 100644 index 00000000..5ff1d736 --- /dev/null +++ b/packages/react-use/src/use-parent-element/index.test.ts @@ -0,0 +1,82 @@ +import { act, renderHook } from '@/test' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { useParentElement } from './index' + +describe('useParentElement', () => { + let container: HTMLElement + + beforeEach(() => { + container = document.createElement('div') + document.body.appendChild(container) + }) + + afterEach(() => { + document.body.removeChild(container) + }) + + it('should defined', () => { + expect(useParentElement).toBeDefined() + }) + + it('should return null if target element is not provided', () => { + const { result } = renderHook(() => useParentElement(null)) + expect(result.current).toBeNull() + }) + + it('should return the parent element of the target', () => { + const child = document.createElement('div') + const parent = document.createElement('div') + parent.appendChild(child) + container.appendChild(parent) + + const { result } = renderHook(() => useParentElement(child)) + expect(result.current).toBe(parent) + }) + + it('should return null if target element has no parent', () => { + const child = document.createElement('div') + container.appendChild(child) + + const { result } = renderHook(() => useParentElement(child)) + expect(result.current).toBe(container) + }) + + it('should update parent when target changes', () => { + const child1 = document.createElement('div') + const child2 = document.createElement('div') + const parent1 = document.createElement('div') + const parent2 = document.createElement('div') + + parent1.appendChild(child1) + parent2.appendChild(child2) + container.appendChild(parent1) + container.appendChild(parent2) + + const { result } = renderHook(({ target }) => useParentElement(target), { + initialProps: { target: child1 }, + }) + + expect(result.current).toBe(parent1) + }) + + it('should handle updates correctly with useEffect', () => { + const child = document.createElement('div') + const parent = document.createElement('div') + parent.appendChild(child) + container.appendChild(parent) + + const { result } = renderHook(() => useParentElement(child)) + expect(result.current).toBe(parent) + }) + + it('should handle fake timers correctly', () => { + vi.useFakeTimers() + const child = document.createElement('div') + const parent = document.createElement('div') + parent.appendChild(child) + container.appendChild(parent) + + const { result } = renderHook(() => useParentElement(child)) + expect(result.current).toBe(parent) + }) +}) diff --git a/packages/react-use/src/use-parent-element/index.ts b/packages/react-use/src/use-parent-element/index.ts index 40058afe..3901cc37 100644 --- a/packages/react-use/src/use-parent-element/index.ts +++ b/packages/react-use/src/use-parent-element/index.ts @@ -16,8 +16,7 @@ export function useParentElement( const [parent, setParent] = useSafeState(null) useEffect(() => { - if (!el.current) return - setParent(getParentElement(el.current)) + setParent(el.current ? getParentElement(el.current) : null) }, [el.current]) return parent diff --git a/packages/react-use/src/use-pausable-effect/index.test.ts b/packages/react-use/src/use-pausable-effect/index.test.ts new file mode 100644 index 00000000..84c4cce5 --- /dev/null +++ b/packages/react-use/src/use-pausable-effect/index.test.ts @@ -0,0 +1,101 @@ +import { act, renderHook } from '@/test' +import { type Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { usePausableEffect } from './index' + +describe('usePausableEffect', () => { + let callback: Mock + + beforeEach(() => { + callback = vi.fn() + vi.useFakeTimers() + }) + + afterEach(() => { + vi.useRealTimers() + }) + + it('should ignore first render', () => { + renderHook(() => usePausableEffect(callback, [])) + + expect(callback).toHaveBeenCalledTimes(1) + }) + + it('should not call the effect when resume & no deps', () => { + const { result } = renderHook(() => usePausableEffect(callback, [])) + + act(() => result.current.resume()) + + expect(callback).toHaveBeenCalledTimes(1) + }) + + it('should resume calling the effect when dep changed', () => { + // biome-ignore lint/correctness/useExhaustiveDependencies: + const { rerender } = renderHook(({ count }) => usePausableEffect(callback, [count]), { + initialProps: { count: 1 }, + }) + + rerender({ count: 2 }) + + expect(callback).toHaveBeenCalled() + }) + + it('should not trigger effect when paused', () => { + // biome-ignore lint/correctness/useExhaustiveDependencies: + const { result, rerender } = renderHook(({ count }) => usePausableEffect(callback, [count]), { + initialProps: { count: 1 }, + }) + + act(() => { + result.current.pause() + }) + + rerender({ count: 2 }) + + expect(callback).toHaveBeenCalledTimes(1) + + rerender({ count: 3 }) + + expect(callback).toHaveBeenCalledTimes(1) + + act(() => { + result.current.resume() + }) + + rerender({ count: 4 }) + + expect(callback).toHaveBeenCalledTimes(2) + }) + + it('should handle multiple calls to pause and resume', () => { + // biome-ignore lint/correctness/useExhaustiveDependencies: + const { result, rerender } = renderHook(({ count }) => usePausableEffect(callback, [count]), { + initialProps: { count: 0 }, + }) + + act(() => { + result.current.pause() + result.current.resume() + result.current.pause() + }) + + expect(callback).toHaveBeenCalledTimes(1) + + rerender({ count: 1 }) + + expect(callback).toHaveBeenCalledTimes(1) + + rerender({ count: 2 }) + + expect(callback).toHaveBeenCalledTimes(1) + + act(() => { + result.current.resume() + }) + + expect(callback).toHaveBeenCalledTimes(1) + + rerender({ count: 3 }) + + expect(callback).toHaveBeenCalledTimes(2) + }) +}) diff --git a/packages/react-use/src/use-pausable-layout-effect/index.test.ts b/packages/react-use/src/use-pausable-layout-effect/index.test.ts new file mode 100644 index 00000000..202bb0b1 --- /dev/null +++ b/packages/react-use/src/use-pausable-layout-effect/index.test.ts @@ -0,0 +1,101 @@ +import { act, renderHook } from '@/test' +import { type Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { usePausableLayoutEffect } from './index' + +describe('usePausableLayoutEffect', () => { + let callback: Mock + + beforeEach(() => { + callback = vi.fn() + vi.useFakeTimers() + }) + + afterEach(() => { + vi.useRealTimers() + }) + + it('should ignore first render', () => { + renderHook(() => usePausableLayoutEffect(callback, [])) + + expect(callback).toHaveBeenCalledTimes(1) + }) + + it('should not call the effect when resume & no deps', () => { + const { result } = renderHook(() => usePausableLayoutEffect(callback, [])) + + act(() => result.current.resume()) + + expect(callback).toHaveBeenCalledTimes(1) + }) + + it('should resume calling the effect when dep changed', () => { + // biome-ignore lint/correctness/useExhaustiveDependencies: + const { rerender } = renderHook(({ count }) => usePausableLayoutEffect(callback, [count]), { + initialProps: { count: 1 }, + }) + + rerender({ count: 2 }) + + expect(callback).toHaveBeenCalled() + }) + + it('should not trigger effect when paused', () => { + // biome-ignore lint/correctness/useExhaustiveDependencies: + const { result, rerender } = renderHook(({ count }) => usePausableLayoutEffect(callback, [count]), { + initialProps: { count: 1 }, + }) + + act(() => { + result.current.pause() + }) + + rerender({ count: 2 }) + + expect(callback).toHaveBeenCalledTimes(1) + + rerender({ count: 3 }) + + expect(callback).toHaveBeenCalledTimes(1) + + act(() => { + result.current.resume() + }) + + rerender({ count: 4 }) + + expect(callback).toHaveBeenCalledTimes(2) + }) + + it('should handle multiple calls to pause and resume', () => { + // biome-ignore lint/correctness/useExhaustiveDependencies: + const { result, rerender } = renderHook(({ count }) => usePausableLayoutEffect(callback, [count]), { + initialProps: { count: 0 }, + }) + + act(() => { + result.current.pause() + result.current.resume() + result.current.pause() + }) + + expect(callback).toHaveBeenCalledTimes(1) + + rerender({ count: 1 }) + + expect(callback).toHaveBeenCalledTimes(1) + + rerender({ count: 2 }) + + expect(callback).toHaveBeenCalledTimes(1) + + act(() => { + result.current.resume() + }) + + expect(callback).toHaveBeenCalledTimes(1) + + rerender({ count: 3 }) + + expect(callback).toHaveBeenCalledTimes(2) + }) +})