diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index c2e20a61..4a20e2ab 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -30,7 +30,7 @@ jobs: fail-fast: false matrix: node: [14, 16, 18] - react: [latest, canary, experimental] + react: ['18.x', latest, canary, experimental] runs-on: ubuntu-latest steps: - name: ⬇️ Checkout repo diff --git a/jest.config.js b/jest.config.js index 30654cdb..860358cd 100644 --- a/jest.config.js +++ b/jest.config.js @@ -3,14 +3,17 @@ const {jest: jestConfig} = require('kcd-scripts/config') module.exports = Object.assign(jestConfig, { coverageThreshold: { ...jestConfig.coverageThreshold, - // Full coverage across the build matrix (React versions) but not in a single job + // Full coverage across the build matrix (React 18, 19) but not in a single job // Ful coverage is checked via codecov - './src/pure.js': { - // minimum coverage of jobs using different React versions - branches: 97, + './src/act-compat': { + branches: 90, + }, + './src/pure': { + // minimum coverage of jobs using React 18 and 19 + branches: 95, functions: 88, - lines: 94, - statements: 94, + lines: 92, + statements: 92, }, }, }) diff --git a/src/__tests__/new-act.js b/src/__tests__/new-act.js index 0412a8a3..0464ad24 100644 --- a/src/__tests__/new-act.js +++ b/src/__tests__/new-act.js @@ -1,10 +1,13 @@ let asyncAct -jest.mock('react-dom/test-utils', () => ({ - act: cb => { - return cb() - }, -})) +jest.mock('react', () => { + return { + ...jest.requireActual('react'), + act: cb => { + return cb() + }, + } +}) beforeEach(() => { jest.resetModules() diff --git a/src/__tests__/render.js b/src/__tests__/render.js index 175174ca..16f7dbe2 100644 --- a/src/__tests__/render.js +++ b/src/__tests__/render.js @@ -3,12 +3,11 @@ import ReactDOM from 'react-dom' import ReactDOMServer from 'react-dom/server' import {fireEvent, render, screen, configure} from '../' -// Needs to be changed to 19.0.0 once alpha started. -const isReactExperimental = React.version.startsWith('18.3.0-experimental') -const isReactCanary = React.version.startsWith('18.3.0-canary') +const isReact18 = React.version.startsWith('18.') +const isReact19 = React.version.startsWith('19.') -// Needs to be changed to isReactExperimental || isReactCanary once alpha started. -const testGateReact18 = isReactExperimental ? test.skip : test +const testGateReact18 = isReact18 ? test : test.skip +const testGateReact19 = isReact19 ? test : test.skip describe('render API', () => { let originalConfig @@ -224,17 +223,21 @@ describe('render API', () => { expect(() => { render(
, {legacyRoot: true}) }).toErrorDev( - isReactCanary - ? [ - "Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://react.dev/link/switch-to-createroot", - ] - : [ - "Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot", - ], + [ + "Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot", + ], {withoutStack: true}, ) }) + testGateReact19('legacyRoot throws', () => { + expect(() => { + render(, {legacyRoot: true}) + }).toThrowErrorMatchingInlineSnapshot( + `\`legacyRoot: true\` is not supported in this version of React. Please use React 18 instead.`, + ) + }) + testGateReact18('legacyRoot uses legacy ReactDOM.hydrate', () => { const ui = const container = document.createElement('div') @@ -242,14 +245,21 @@ describe('render API', () => { expect(() => { render(ui, {container, hydrate: true, legacyRoot: true}) }).toErrorDev( - isReactCanary - ? [ - "Warning: ReactDOM.hydrate is no longer supported in React 18. Use hydrateRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://react.dev/link/switch-to-createroot", - ] - : [ - "Warning: ReactDOM.hydrate is no longer supported in React 18. Use hydrateRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot", - ], + [ + "Warning: ReactDOM.hydrate is no longer supported in React 18. Use hydrateRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot", + ], {withoutStack: true}, ) }) + + testGateReact19('legacyRoot throws even with hydrate', () => { + const ui = + const container = document.createElement('div') + container.innerHTML = ReactDOMServer.renderToString(ui) + expect(() => { + render(ui, {container, hydrate: true, legacyRoot: true}) + }).toThrowErrorMatchingInlineSnapshot( + `\`legacyRoot: true\` is not supported in this version of React. Please use React 18 instead.`, + ) + }) }) diff --git a/src/__tests__/renderHook.js b/src/__tests__/renderHook.js index 34259b44..c7c8b066 100644 --- a/src/__tests__/renderHook.js +++ b/src/__tests__/renderHook.js @@ -1,12 +1,11 @@ import React from 'react' import {renderHook} from '../pure' -// Needs to be changed to 19.0.0 once alpha started. -const isReactExperimental = React.version.startsWith('18.3.0-experimental') -const isReactCanary = React.version.startsWith('18.3.0') +const isReact18 = React.version.startsWith('18.') +const isReact19 = React.version.startsWith('19.') -// Needs to be changed to isReactExperimental || isReactCanary once alpha started. -const testGateReact18 = isReactExperimental ? test.skip : test +const testGateReact18 = isReact18 ? test : test.skip +const testGateReact19 = isReact19 ? test : test.skip test('gives committed result', () => { const {result} = renderHook(() => { @@ -85,14 +84,30 @@ testGateReact18('legacyRoot uses legacy ReactDOM.render', () => { }, ).result }).toErrorDev( - isReactCanary - ? [ - "Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://react.dev/link/switch-to-createroot", - ] - : [ - "Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot", - ], + [ + "Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot", + ], {withoutStack: true}, ) expect(result.current).toEqual('provided') }) + +testGateReact19('legacyRoot throws', () => { + const Context = React.createContext('default') + function Wrapper({children}) { + return