diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index dd1f31f1..82920e42 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -30,11 +30,15 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - react-version: [16, 17] - testing-library-version: [12] include: + - react-version: 16 + testing-library-version: 12 + - react-version: 17 + testing-library-version: 12 - react-version: 18 testing-library-version: 16 + - react-version: 19 + testing-library-version: 16.3.2 steps: - name: Checkout uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 diff --git a/package.json b/package.json index a841d93d..dc558876 100644 --- a/package.json +++ b/package.json @@ -58,8 +58,8 @@ "sanitize-html": "2.17.0" }, "peerDependencies": { - "react": "^16.14.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0" + "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "devDependencies": { "@babel/core": "7.28.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6ab1324..ae5c48df 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,10 +30,10 @@ importers: specifier: 1.30.0 version: 1.30.0 react: - specifier: ^16.14.0 || ^17.0.0 || ^18.0.0 + specifier: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 version: 16.14.0 react-dom: - specifier: ^16.14.0 || ^17.0.0 || ^18.0.0 + specifier: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 version: 16.14.0(react@16.14.0) sanitize-html: specifier: 2.17.0 diff --git a/src/quiz/use-quiz.test.ts b/src/quiz/use-quiz.test.ts index f1b71d97..eb640be8 100644 --- a/src/quiz/use-quiz.test.ts +++ b/src/quiz/use-quiz.test.ts @@ -1,4 +1,4 @@ -import { renderHook, act } from "@testing-library/react-hooks"; +import { renderHook, act } from "../test-utils/renderHook"; import { useQuiz } from "./use-quiz"; diff --git a/src/test-utils/renderHook.ts b/src/test-utils/renderHook.ts new file mode 100644 index 00000000..4f1fdfac --- /dev/null +++ b/src/test-utils/renderHook.ts @@ -0,0 +1,48 @@ +/** + * Runtime `renderHook` helper that picks a compatible implementation based on + * the installed testing-library packages: + * + * - Prefer `@testing-library/react`'s `renderHook` (available in newer RTL). + * - Fallback to `@testing-library/react-hooks` for older setups. + * + * This keeps tests working across React versions (React 16/17/18 with RHTL, + * React 18/19 with RTL's `renderHook`). + */ + +import * as rtl from "@testing-library/react"; +import * as rhtl from "@testing-library/react-hooks"; + +type ActFn = (cb: () => void) => void; + +type RenderHookResult = { + result: { current: T }; +}; + +// Generic renderHook signature used by our tests: accepts a callback returning +// a value and returns an object with a `result.current` property. +let renderHook: (cb: () => T) => RenderHookResult; +let actImpl: ActFn | undefined; + +type RTLLike = { + renderHook?: (cb: () => T) => RenderHookResult; + act?: ActFn; +}; + +if (typeof (rtl as unknown as RTLLike).renderHook === "function") { + const r = rtl as unknown as Required; + renderHook = r.renderHook; + actImpl = r.act; +} else { + const h = rhtl as unknown as Required; + renderHook = h.renderHook; + actImpl = h.act; +} + +const act: ActFn = (cb: () => void) => { + if (actImpl) return actImpl(cb); + // Fallback synchronous runner for environments without `act`. + return cb(); +}; + +export { renderHook, act }; +export default renderHook;