diff --git a/package-lock.json b/package-lock.json index e3d03e2..abfc7b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,10 @@ "devDependencies": { "@astrojs/language-server": "^2.3.3", "@size-limit/preset-small-lib": "^9.0.0", - "@testing-library/react-hooks": "^8.0.1", + "@testing-library/react": "^14.1.2", "@testing-library/vue": "^8.0.1", - "@types/react": "^17", + "@types/react": "^18", + "@types/use-sync-external-store": "^0.0.6", "@vitejs/plugin-vue": "^4.2.3", "@vitest/coverage-v8": "^0.34.4", "@vitest/ui": "^0.34.4", @@ -24,13 +25,14 @@ "jotai": "^2.4.2", "npm-run-all": "^4.1.5", "prettier": "^3.1.0", - "react": "^17", - "react-is": "^17", - "react-test-renderer": "^17", + "react": "^18", + "react-is": "^18", + "react-test-renderer": "^18", "size-limit": "^7.0.8", "tslib": "^2.3.1", "tsup": "^8.0.1", "typescript": "^4.6.3", + "use-sync-external-store": "^1.2.0", "vitest": "^0.33.0", "vue": "^3.3.4" }, @@ -1029,6 +1031,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/@testing-library/dom/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/@testing-library/dom/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1041,34 +1049,22 @@ "node": ">=8" } }, - "node_modules/@testing-library/react-hooks": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz", - "integrity": "sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==", + "node_modules/@testing-library/react": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.1.2.tgz", + "integrity": "sha512-z4p7DVBTPjKM5qDZ0t5ZjzkpSNb+fZy1u6bzO7kk8oeGagpPCAtgh4cx1syrfp7a+QWkM021jGqjJaxJJnXAZg==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", - "react-error-boundary": "^3.1.0" + "@testing-library/dom": "^9.0.0", + "@types/react-dom": "^18.0.0" }, "engines": { - "node": ">=12" + "node": ">=14" }, "peerDependencies": { - "@types/react": "^16.9.0 || ^17.0.0", - "react": "^16.9.0 || ^17.0.0", - "react-dom": "^16.9.0 || ^17.0.0", - "react-test-renderer": "^16.9.0 || ^17.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "react-test-renderer": { - "optional": true - } + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@testing-library/vue": { @@ -1138,9 +1134,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "17.0.65", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.65.tgz", - "integrity": "sha512-oxur785xZYHvnI7TRS61dXbkIhDPnGfsXKv0cNXR/0ml4SipRIFpSMzA7HMEfOywFwJ5AOnPrXYTEiTRUQeGlQ==", + "version": "18.2.38", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.38.tgz", + "integrity": "sha512-cBBXHzuPtQK6wNthuVMV6IjHAFkdl/FOPFIlkd81/Cd1+IqkHu/A+w4g43kaQQoYHik/ruaQBDL72HyCy1vuMw==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -1148,11 +1144,26 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-dom": { + "version": "18.2.17", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz", + "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/scheduler": { "version": "0.16.2", "dev": true, "license": "MIT" }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "dev": true + }, "node_modules/@vitejs/plugin-vue": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.2.3.tgz", @@ -4733,12 +4744,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/pretty-format/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", @@ -4790,54 +4795,35 @@ "license": "MIT" }, "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "dev": true, "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "dev": true, - "optional": true, "peer": true, "dependencies": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.0" }, "peerDependencies": { - "react": "17.0.2" - } - }, - "node_modules/react-error-boundary": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", - "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - }, - "peerDependencies": { - "react": ">=16.13.1" + "react": "^18.2.0" } }, "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, "node_modules/react-shallow-renderer": { @@ -4854,18 +4840,17 @@ } }, "node_modules/react-test-renderer": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-17.0.2.tgz", - "integrity": "sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.2.0.tgz", + "integrity": "sha512-JWD+aQ0lh2gvh4NM3bBM42Kx+XybOxCpgYK7F8ugAlpaTSnWsX+39Z4XkOykGZAHrjwwTZT3x3KxswVWxHPUqA==", "dev": true, "dependencies": { - "object-assign": "^4.1.1", - "react-is": "^17.0.2", - "react-shallow-renderer": "^16.13.1", - "scheduler": "^0.20.2" + "react-is": "^18.2.0", + "react-shallow-renderer": "^16.15.0", + "scheduler": "^0.23.0" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.2.0" } }, "node_modules/read-pkg": { @@ -5087,13 +5072,12 @@ } }, "node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", "dev": true, "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "node_modules/semver": { @@ -5968,6 +5952,15 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "dev": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/v8-to-istanbul": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", diff --git a/package.json b/package.json index 22de119..38abeb9 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ ], "engines": { "node": ">=10" - }, "scripts": { "build": "run-s build:*", @@ -112,9 +111,10 @@ "devDependencies": { "@astrojs/language-server": "^2.3.3", "@size-limit/preset-small-lib": "^9.0.0", - "@testing-library/react-hooks": "^8.0.1", + "@testing-library/react": "^14.1.2", "@testing-library/vue": "^8.0.1", - "@types/react": "^17", + "@types/react": "^18", + "@types/use-sync-external-store": "^0.0.6", "@vitejs/plugin-vue": "^4.2.3", "@vitest/coverage-v8": "^0.34.4", "@vitest/ui": "^0.34.4", @@ -125,13 +125,14 @@ "jotai": "^2.4.2", "npm-run-all": "^4.1.5", "prettier": "^3.1.0", - "react": "^17", - "react-is": "^17", - "react-test-renderer": "^17", + "react": "^18", + "react-is": "^18", + "react-test-renderer": "^18", "size-limit": "^7.0.8", "tslib": "^2.3.1", "tsup": "^8.0.1", "typescript": "^4.6.3", + "use-sync-external-store": "^1.2.0", "vitest": "^0.33.0", "vue": "^3.3.4" } diff --git a/src/react/ComponentScope.test.tsx b/src/react/ComponentScope.test.tsx index fc8738b..c4bda2c 100644 --- a/src/react/ComponentScope.test.tsx +++ b/src/react/ComponentScope.test.tsx @@ -1,4 +1,4 @@ -import { act, renderHook } from "@testing-library/react-hooks"; +import { act, renderHook } from "@testing-library/react"; import { atom, useAtom } from "jotai"; import { createLifecycleUtils } from "../shared/testing/lifecycle"; import { ComponentScope, molecule } from "./"; diff --git a/src/react/ScopeProvider.test.tsx b/src/react/ScopeProvider.test.tsx index 3d2753f..be8dd9d 100644 --- a/src/react/ScopeProvider.test.tsx +++ b/src/react/ScopeProvider.test.tsx @@ -1,4 +1,4 @@ -import { act, renderHook } from "@testing-library/react-hooks"; +import { act, renderHook } from "@testing-library/react"; import { atom, useAtom } from "jotai"; import React, { ReactNode, useContext, useRef, useState } from "react"; import { createLifecycleUtils } from "../shared/testing/lifecycle"; diff --git a/src/react/sanity.test.tsx b/src/react/sanity.test.tsx new file mode 100644 index 0000000..102807d --- /dev/null +++ b/src/react/sanity.test.tsx @@ -0,0 +1,23 @@ +import { renderHook } from "@testing-library/react"; +import { StrictMode, useEffect } from "react"; + +describe("Strict mode", () => { + test("Runs `useEffect` twice", () => { + const runs = vi.fn(); + const cleanups = vi.fn(); + const result = renderHook( + () => { + useEffect(() => { + runs(); + return cleanups; + }, []); + }, + { wrapper: StrictMode }, + ); + expect(runs).toBeCalledTimes(2); + expect(cleanups).toBeCalledTimes(1); + result.unmount(); + expect(runs).toBeCalledTimes(2); + expect(cleanups).toBeCalledTimes(2); + }); +}); diff --git a/src/react/useInjector.test.tsx b/src/react/useInjector.test.tsx index 682425e..a4a1647 100644 --- a/src/react/useInjector.test.tsx +++ b/src/react/useInjector.test.tsx @@ -1,4 +1,4 @@ -import { act, renderHook } from "@testing-library/react-hooks"; +import { act, renderHook } from "@testing-library/react"; import { atom, getDefaultStore, useAtomValue } from "jotai"; import React from "react"; import { diff --git a/src/react/useMolecule.test.tsx b/src/react/useMolecule.test.tsx index 82a48fb..1105541 100644 --- a/src/react/useMolecule.test.tsx +++ b/src/react/useMolecule.test.tsx @@ -1,4 +1,4 @@ -import { renderHook } from "@testing-library/react-hooks"; +import { renderHook } from "@testing-library/react"; import React, { useContext } from "react"; import { createScope, molecule, onMount, onUnmount, use } from "."; import { ScopeProvider } from "./ScopeProvider";