From 91726541c75cfd95db4859324bb3a9e8203d6338 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Wed, 21 Jul 2021 16:06:31 -0700 Subject: [PATCH 01/16] Support React 18 --- package.json | 6 +++--- src/dom/pure.ts | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 9d9c0928..92dd78ee 100644 --- a/package.json +++ b/package.json @@ -63,9 +63,9 @@ "eslint": "7.31.0", "kcd-scripts": "11.2.0", "prettier": "^2.2.1", - "react": "17.0.2", - "react-dom": "^17.0.1", - "react-test-renderer": "17.0.2", + "react": "next", + "react-dom": "next", + "react-test-renderer": "next", "ts-node": "^10.0.0", "typescript": "4.3.5" }, diff --git a/src/dom/pure.ts b/src/dom/pure.ts index 42d66072..0f0af8eb 100644 --- a/src/dom/pure.ts +++ b/src/dom/pure.ts @@ -12,21 +12,22 @@ function createDomRenderer( ) { const container = document.createElement('div') const testHarness = createTestHarness(rendererProps, wrapper) - + // @ts-ignore + const root = ReactDOM.create(container); return { render(props?: TProps) { act(() => { - ReactDOM.render(testHarness(props), container) + root.render(testHarness(props)) }) }, rerender(props?: TProps) { act(() => { - ReactDOM.render(testHarness(props), container) + root.render(testHarness(props)) }) }, unmount() { act(() => { - ReactDOM.unmountComponentAtNode(container) + root.unmount() }) }, act From 6456f4a71b4eb41bf9c40ae997c0783b5c6d8f83 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Wed, 21 Jul 2021 16:26:56 -0700 Subject: [PATCH 02/16] fix some more obvious cases --- src/dom/pure.ts | 2 +- src/server/pure.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dom/pure.ts b/src/dom/pure.ts index 0f0af8eb..ff7a65e5 100644 --- a/src/dom/pure.ts +++ b/src/dom/pure.ts @@ -13,7 +13,7 @@ function createDomRenderer( const container = document.createElement('div') const testHarness = createTestHarness(rendererProps, wrapper) // @ts-ignore - const root = ReactDOM.create(container); + const root = ReactDOM.createRoot(container); return { render(props?: TProps) { act(() => { diff --git a/src/server/pure.ts b/src/server/pure.ts index 1978f2d0..19e591d8 100644 --- a/src/server/pure.ts +++ b/src/server/pure.ts @@ -15,7 +15,8 @@ function createServerRenderer( let container: HTMLDivElement | undefined let serverOutput: string = '' const testHarness = createTestHarness(rendererProps, wrapper, false) - + // @ts-ignore + const root = ReactDOM.createRoot(container); return { render(props?: TProps) { renderProps = props @@ -34,7 +35,7 @@ function createServerRenderer( container = document.createElement('div') container.innerHTML = serverOutput act(() => { - ReactDOM.hydrate(testHarness(renderProps), container!) + root.hydrateRoot(testHarness(renderProps)) }) } }, @@ -43,7 +44,7 @@ function createServerRenderer( throw new Error('You must hydrate the component before you can rerender') } act(() => { - ReactDOM.render(testHarness(props), container!) + root.render(testHarness(props)) }) }, unmount() { From 0d82a5f5b54799e1a79a9bbffa5ee0139ba771c9 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Wed, 21 Jul 2021 16:53:10 -0700 Subject: [PATCH 03/16] fix hydration --- src/server/pure.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/pure.ts b/src/server/pure.ts index 19e591d8..99701c42 100644 --- a/src/server/pure.ts +++ b/src/server/pure.ts @@ -15,8 +15,7 @@ function createServerRenderer( let container: HTMLDivElement | undefined let serverOutput: string = '' const testHarness = createTestHarness(rendererProps, wrapper, false) - // @ts-ignore - const root = ReactDOM.createRoot(container); + let root: any return { render(props?: TProps) { renderProps = props @@ -35,7 +34,8 @@ function createServerRenderer( container = document.createElement('div') container.innerHTML = serverOutput act(() => { - root.hydrateRoot(testHarness(renderProps)) + // @ts-ignore + root = ReactDOM.hydrateRoot(container, testHarness(renderProps)) }) } }, @@ -50,7 +50,7 @@ function createServerRenderer( unmount() { if (container) { act(() => { - ReactDOM.unmountComponentAtNode(container!) + root.unmount() }) } }, From 81db73a77d463c52f23131bd580d4a8390d5d021 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Wed, 21 Jul 2021 17:17:02 -0700 Subject: [PATCH 04/16] annotate a test so I can get help --- src/__tests__/resultHistory.test.ts | 3 ++- src/dom/pure.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/__tests__/resultHistory.test.ts b/src/__tests__/resultHistory.test.ts index edb8837f..ca18e825 100644 --- a/src/__tests__/resultHistory.test.ts +++ b/src/__tests__/resultHistory.test.ts @@ -23,7 +23,8 @@ describe('result history tests', () => { rerender(2) expect(result.error).toEqual(Error('expected')) - expect(result.all).toEqual([0, 1, Error('expected')]) + // double error thrown for dom, but not default or native... + expect(result.all).toEqual([0, 1, Error('expected'), Error('expected')]) rerender(3) diff --git a/src/dom/pure.ts b/src/dom/pure.ts index ff7a65e5..162e23c0 100644 --- a/src/dom/pure.ts +++ b/src/dom/pure.ts @@ -13,7 +13,7 @@ function createDomRenderer( const container = document.createElement('div') const testHarness = createTestHarness(rendererProps, wrapper) // @ts-ignore - const root = ReactDOM.createRoot(container); + const root = ReactDOM.createRoot(container) return { render(props?: TProps) { act(() => { From 1f0bf1db4e6b61e7fae79822aa341784478c047a Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Thu, 22 Jul 2021 18:12:23 -0700 Subject: [PATCH 05/16] Will definitely need something like this in order to support 17 and 18 at once --- src/dom/pure.ts | 60 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/src/dom/pure.ts b/src/dom/pure.ts index 162e23c0..cbab3e8a 100644 --- a/src/dom/pure.ts +++ b/src/dom/pure.ts @@ -6,6 +6,8 @@ import { RendererProps, RendererOptions } from '../types/react' import { createRenderHook } from '../core' import { createTestHarness } from '../helpers/createTestHarness' +const isReactConcurrent = !!ReactDOM.createRoot; + function createDomRenderer( rendererProps: RendererProps, { wrapper }: RendererOptions @@ -13,24 +15,46 @@ function createDomRenderer( const container = document.createElement('div') const testHarness = createTestHarness(rendererProps, wrapper) // @ts-ignore - const root = ReactDOM.createRoot(container) - return { - render(props?: TProps) { - act(() => { - root.render(testHarness(props)) - }) - }, - rerender(props?: TProps) { - act(() => { - root.render(testHarness(props)) - }) - }, - unmount() { - act(() => { - root.unmount() - }) - }, - act + if (isReactConcurrent) { + // @ts-ignore + const root = ReactDOM.createRoot(container) + return { + render(props?: TProps) { + act(() => { + root.render(testHarness(props)) + }) + }, + rerender(props?: TProps) { + act(() => { + root.render(testHarness(props)) + }) + }, + unmount() { + act(() => { + root.unmount() + }) + }, + act + } + } else { + return { + render(props?: TProps) { + act(() => { + ReactDOM.render(testHarness(props), container) + }) + }, + rerender(props?: TProps) { + act(() => { + ReactDOM.render(testHarness(props), container) + }) + }, + unmount() { + act(() => { + ReactDOM.unmountComponentAtNode(container) + }) + }, + act + } } } From 3cc6f2ee871e971108a38aa632f3ae1eba2502c8 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Fri, 23 Jul 2021 13:18:34 -0700 Subject: [PATCH 06/16] drop prepare run tests against all supported major react versions support both versions and fix ts --- .github/workflows/validate.yml | 4 ++ package.json | 1 - src/dom/pure.ts | 2 +- src/server/pure.ts | 115 +++++++++++++++++++++++---------- 4 files changed, 85 insertions(+), 37 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index b121fcd4..749f27b5 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -17,6 +17,7 @@ jobs: strategy: matrix: node: [12.13, 12, 14, 16] + react: [16, 17, next] runs-on: ubuntu-latest steps: - name: 🛑 Cancel Previous Runs @@ -37,6 +38,9 @@ jobs: env: HUSKY_SKIP_INSTALL: true + - name: Use React version + run: npm install --save-dev react@${{ matrix.react }} react-dom@${{ matrix.react }} react-test-renderer@${{ matrix.react }} + - name: ▶️ Run validate script run: npm run validate diff --git a/package.json b/package.json index 92dd78ee..9b44da7c 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,6 @@ "scripts": { "setup": "npm install && npm run validate -s", "validate": "kcd-scripts validate", - "prepare": "npm run build", "build": "kcd-scripts build --out-dir lib && npm run generate:submodules", "generate:submodules": "ts-node scripts/generate-submodules.ts", "test": "kcd-scripts test", diff --git a/src/dom/pure.ts b/src/dom/pure.ts index cbab3e8a..2e060b73 100644 --- a/src/dom/pure.ts +++ b/src/dom/pure.ts @@ -6,6 +6,7 @@ import { RendererProps, RendererOptions } from '../types/react' import { createRenderHook } from '../core' import { createTestHarness } from '../helpers/createTestHarness' +// @ts-ignore const isReactConcurrent = !!ReactDOM.createRoot; function createDomRenderer( @@ -14,7 +15,6 @@ function createDomRenderer( ) { const container = document.createElement('div') const testHarness = createTestHarness(rendererProps, wrapper) - // @ts-ignore if (isReactConcurrent) { // @ts-ignore const root = ReactDOM.createRoot(container) diff --git a/src/server/pure.ts b/src/server/pure.ts index 99701c42..355399fa 100644 --- a/src/server/pure.ts +++ b/src/server/pure.ts @@ -7,6 +7,9 @@ import { RendererOptions, RendererProps } from '../types/react' import { createRenderHook } from '../core' import { createTestHarness } from '../helpers/createTestHarness' +// @ts-ignore +const isReactConcurrent = !!ReactDOM.createRoot; + function createServerRenderer( rendererProps: RendererProps, { wrapper }: RendererOptions @@ -15,46 +18,88 @@ function createServerRenderer( let container: HTMLDivElement | undefined let serverOutput: string = '' const testHarness = createTestHarness(rendererProps, wrapper, false) - let root: any - return { - render(props?: TProps) { - renderProps = props - act(() => { - try { - serverOutput = ReactDOMServer.renderToString(testHarness(props)) - } catch (e: unknown) { - rendererProps.setError(e as Error) + if (isReactConcurrent) { + let root: any + return { + render(props?: TProps) { + renderProps = props + act(() => { + try { + serverOutput = ReactDOMServer.renderToString(testHarness(props)) + } catch (e: unknown) { + rendererProps.setError(e as Error) + } + }) + }, + hydrate() { + if (container) { + throw new Error('The component can only be hydrated once') + } else { + container = document.createElement('div') + container.innerHTML = serverOutput + act(() => { + // @ts-ignore + root = ReactDOM.hydrateRoot(container, testHarness(renderProps)) + }) + } + }, + rerender(props?: TProps) { + if (!container) { + throw new Error('You must hydrate the component before you can rerender') + } + act(() => { + root.render(testHarness(props)) + }) + }, + unmount() { + if (container) { + act(() => { + root.unmount() + }) } - }) - }, - hydrate() { - if (container) { - throw new Error('The component can only be hydrated once') - } else { - container = document.createElement('div') - container.innerHTML = serverOutput + }, + act + }; + } else { + return { + render(props?: TProps) { + renderProps = props act(() => { - // @ts-ignore - root = ReactDOM.hydrateRoot(container, testHarness(renderProps)) + try { + serverOutput = ReactDOMServer.renderToString(testHarness(props)) + } catch (e: unknown) { + rendererProps.setError(e as Error) + } }) - } - }, - rerender(props?: TProps) { - if (!container) { - throw new Error('You must hydrate the component before you can rerender') - } - act(() => { - root.render(testHarness(props)) - }) - }, - unmount() { - if (container) { + }, + hydrate() { + if (container) { + throw new Error('The component can only be hydrated once') + } else { + container = document.createElement('div') + container.innerHTML = serverOutput + act(() => { + ReactDOM.hydrate(testHarness(renderProps), container!) + }) + } + }, + rerender(props?: TProps) { + if (!container) { + throw new Error('You must hydrate the component before you can rerender') + } act(() => { - root.unmount() + ReactDOM.render(testHarness(props), container!) }) - } - }, - act + }, + unmount() { + if (container) { + act(() => { + ReactDOM.unmountComponentAtNode(container!) + }) + } + }, + act + }; } } From 15347e55514cdaa1175cdd58f9659bd291427244 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Fri, 23 Jul 2021 13:26:25 -0700 Subject: [PATCH 07/16] restore package.json fix test matrix to choose appropriate react versions --- .github/workflows/validate.yml | 2 +- package.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 749f27b5..51a1f1f7 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: node: [12.13, 12, 14, 16] - react: [16, 17, next] + react: [^16.9.0, ^17.0.2, next] runs-on: ubuntu-latest steps: - name: 🛑 Cancel Previous Runs diff --git a/package.json b/package.json index 9b44da7c..91040398 100644 --- a/package.json +++ b/package.json @@ -62,9 +62,9 @@ "eslint": "7.31.0", "kcd-scripts": "11.2.0", "prettier": "^2.2.1", - "react": "next", - "react-dom": "next", - "react-test-renderer": "next", + "react": "17.0.2", + "react-dom": "17.0.2", + "react-test-renderer": "17.0.2", "ts-node": "^10.0.0", "typescript": "4.3.5" }, From 25cfd74c79881b90d25492334d5b1df08c510e48 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Fri, 23 Jul 2021 13:30:42 -0700 Subject: [PATCH 08/16] restore test to passing but leave comment about 18 --- src/__tests__/resultHistory.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/__tests__/resultHistory.test.ts b/src/__tests__/resultHistory.test.ts index ca18e825..9faf9d52 100644 --- a/src/__tests__/resultHistory.test.ts +++ b/src/__tests__/resultHistory.test.ts @@ -24,7 +24,7 @@ describe('result history tests', () => { expect(result.error).toEqual(Error('expected')) // double error thrown for dom, but not default or native... - expect(result.all).toEqual([0, 1, Error('expected'), Error('expected')]) + expect(result.all).toEqual([0, 1, Error('expected')]) rerender(3) From 668088b801cefdb123d310656e35bff3f7bf1b37 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Fri, 23 Jul 2021 13:38:08 -0700 Subject: [PATCH 09/16] Fix install script one last time --- .github/workflows/validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 51a1f1f7..18ec4c9f 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -39,7 +39,7 @@ jobs: HUSKY_SKIP_INSTALL: true - name: Use React version - run: npm install --save-dev react@${{ matrix.react }} react-dom@${{ matrix.react }} react-test-renderer@${{ matrix.react }} + run: npm install --save-dev react@"${{ matrix.react }}" react-dom@"${{ matrix.react }}" react-test-renderer@"${{ matrix.react }}" - name: ▶️ Run validate script run: npm run validate From 8fa0041519f710190ae79607905fdb82088dea11 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Fri, 23 Jul 2021 13:43:00 -0700 Subject: [PATCH 10/16] add some shortcut scripts so it's easier to test locally --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 91040398..d8862090 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,9 @@ "coverage": "codecov", "docs:dev": "docz dev", "docs:build": "docz build", - "contributors:add": "all-contributors add" + "contributors:add": "all-contributors add", + "install-16": "npm install --save-dev react@\"^16.9.0\" react-dom@\"^16.9.0\" react-test-renderer@\"^16.9.0\"", + "install-next": "npm install --save-dev react@next react-dom@next react-test-renderer@next", }, "dependencies": { "@babel/runtime": "^7.12.5", From c95ef457787ace7bf5937294619b8db55dd06122 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Fri, 23 Jul 2021 15:03:02 -0700 Subject: [PATCH 11/16] remove invalid comma --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d8862090..3a5983e9 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "docs:build": "docz build", "contributors:add": "all-contributors add", "install-16": "npm install --save-dev react@\"^16.9.0\" react-dom@\"^16.9.0\" react-test-renderer@\"^16.9.0\"", - "install-next": "npm install --save-dev react@next react-dom@next react-test-renderer@next", + "install-next": "npm install --save-dev react@next react-dom@next react-test-renderer@next" }, "dependencies": { "@babel/runtime": "^7.12.5", From 00526a84940cbc64341018888e4d5b123b31d21f Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Fri, 23 Jul 2021 15:46:39 -0700 Subject: [PATCH 12/16] add support for the minimum specified supported version as well as latest of all majors after --- .github/workflows/validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 18ec4c9f..0d697b05 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: node: [12.13, 12, 14, 16] - react: [^16.9.0, ^17.0.2, next] + react: [16.9.0, ^16, ^17, next] runs-on: ubuntu-latest steps: - name: 🛑 Cancel Previous Runs From c060620d90391ae009e4c10c3e9dbb9ef9be7514 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Fri, 23 Jul 2021 16:17:04 -0700 Subject: [PATCH 13/16] temporarily drop coverageThreshold --- jest.config.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/jest.config.js b/jest.config.js index 66b8064e..9abc92d8 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,12 @@ const { jest: jestConfig } = require('kcd-scripts/config') +jestConfig.coverageThreshold = { + global: { + branches: 80, + functions: 80, + lines: 80, + statements: 80 + } +} module.exports = Object.assign(jestConfig, { setupFiles: ['/src/__tests__/utils/runForRenderers.ts'] }) From d4ba70ce2ca27465af0660b546be108abddecf23 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Fri, 23 Jul 2021 16:55:33 -0700 Subject: [PATCH 14/16] experimental tests should not block known quantities --- .github/workflows/validate.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 0d697b05..c0a40890 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -14,10 +14,12 @@ jobs: main: # ignore all-contributors PRs if: ${{ !contains(github.head_ref, 'all-contributors') }} + continue-on-error: ${{ contains(matrix.react, 'next') }} strategy: matrix: node: [12.13, 12, 14, 16] react: [16.9.0, ^16, ^17, next] + runs-on: ubuntu-latest steps: - name: 🛑 Cancel Previous Runs From 2b4a770545561534eeff697a72dd44b0de4ebeda Mon Sep 17 00:00:00 2001 From: Michael Peyper Date: Sat, 24 Jul 2021 22:20:07 +1000 Subject: [PATCH 15/16] refactor: add createLegacyRoot to reduce uncovered code percentage Ignore root creation code from code covereage Introduced next react types for React.Root --- src/dom/pure.ts | 63 +++++++-------------- src/helpers/createRoot.ts | 30 ++++++++++ src/server/pure.ts | 114 ++++++++++++-------------------------- tsconfig.json | 3 +- 4 files changed, 85 insertions(+), 125 deletions(-) create mode 100644 src/helpers/createRoot.ts diff --git a/src/dom/pure.ts b/src/dom/pure.ts index 2e060b73..e0759f1d 100644 --- a/src/dom/pure.ts +++ b/src/dom/pure.ts @@ -1,13 +1,10 @@ -import * as ReactDOM from 'react-dom' import { act } from 'react-dom/test-utils' import { RendererProps, RendererOptions } from '../types/react' import { createRenderHook } from '../core' import { createTestHarness } from '../helpers/createTestHarness' - -// @ts-ignore -const isReactConcurrent = !!ReactDOM.createRoot; +import { createRoot } from '../helpers/createRoot' function createDomRenderer( rendererProps: RendererProps, @@ -15,46 +12,24 @@ function createDomRenderer( ) { const container = document.createElement('div') const testHarness = createTestHarness(rendererProps, wrapper) - if (isReactConcurrent) { - // @ts-ignore - const root = ReactDOM.createRoot(container) - return { - render(props?: TProps) { - act(() => { - root.render(testHarness(props)) - }) - }, - rerender(props?: TProps) { - act(() => { - root.render(testHarness(props)) - }) - }, - unmount() { - act(() => { - root.unmount() - }) - }, - act - } - } else { - return { - render(props?: TProps) { - act(() => { - ReactDOM.render(testHarness(props), container) - }) - }, - rerender(props?: TProps) { - act(() => { - ReactDOM.render(testHarness(props), container) - }) - }, - unmount() { - act(() => { - ReactDOM.unmountComponentAtNode(container) - }) - }, - act - } + const root = createRoot(container) + return { + render(props?: TProps) { + act(() => { + root.render(testHarness(props)) + }) + }, + rerender(props?: TProps) { + act(() => { + root.render(testHarness(props)) + }) + }, + unmount() { + act(() => { + root.unmount() + }) + }, + act } } diff --git a/src/helpers/createRoot.ts b/src/helpers/createRoot.ts new file mode 100644 index 00000000..bd6a0175 --- /dev/null +++ b/src/helpers/createRoot.ts @@ -0,0 +1,30 @@ +import * as ReactDOM from 'react-dom' +import * as React from 'react' + +/* istanbul ignore next */ +function createLegacyRoot(container: Element): ReactDOM.Root { + return { + render(element: React.ReactElement) { + ReactDOM.render(element, container) + }, + unmount() { + ReactDOM.unmountComponentAtNode(container) + } + } +} + +/* istanbul ignore next */ +export function createRoot(container: Element) { + return (ReactDOM.createRoot ? ReactDOM.createRoot : createLegacyRoot)(container) +} + +/* istanbul ignore next */ +export function hydrateLegacyRoot(container: Element, element: React.ReactElement): ReactDOM.Root { + ReactDOM.hydrate(element, container) + return createLegacyRoot(container) +} + +/* istanbul ignore next */ +export function hydrateRoot(container: Element, element: React.ReactElement) { + return (ReactDOM.hydrateRoot ? ReactDOM.hydrateRoot : hydrateLegacyRoot)(container, element) +} diff --git a/src/server/pure.ts b/src/server/pure.ts index 355399fa..10696bb5 100644 --- a/src/server/pure.ts +++ b/src/server/pure.ts @@ -6,100 +6,54 @@ import { RendererOptions, RendererProps } from '../types/react' import { createRenderHook } from '../core' import { createTestHarness } from '../helpers/createTestHarness' - -// @ts-ignore -const isReactConcurrent = !!ReactDOM.createRoot; +import { hydrateRoot } from '../helpers/createRoot' function createServerRenderer( rendererProps: RendererProps, { wrapper }: RendererOptions ) { let renderProps: TProps | undefined - let container: HTMLDivElement | undefined let serverOutput: string = '' const testHarness = createTestHarness(rendererProps, wrapper, false) - if (isReactConcurrent) { - let root: any - return { - render(props?: TProps) { - renderProps = props - act(() => { - try { - serverOutput = ReactDOMServer.renderToString(testHarness(props)) - } catch (e: unknown) { - rendererProps.setError(e as Error) - } - }) - }, - hydrate() { - if (container) { - throw new Error('The component can only be hydrated once') - } else { - container = document.createElement('div') - container.innerHTML = serverOutput - act(() => { - // @ts-ignore - root = ReactDOM.hydrateRoot(container, testHarness(renderProps)) - }) - } - }, - rerender(props?: TProps) { - if (!container) { - throw new Error('You must hydrate the component before you can rerender') + let root: ReactDOM.Root | undefined + return { + render(props?: TProps) { + renderProps = props + act(() => { + try { + serverOutput = ReactDOMServer.renderToString(testHarness(props)) + } catch (e: unknown) { + rendererProps.setError(e as Error) } + }) + }, + hydrate() { + if (root) { + throw new Error('The component can only be hydrated once') + } else { + const container = document.createElement('div') + container.innerHTML = serverOutput act(() => { - root.render(testHarness(props)) + root = hydrateRoot(container, testHarness(renderProps)) }) - }, - unmount() { - if (container) { - act(() => { - root.unmount() - }) - } - }, - act - }; - } else { - return { - render(props?: TProps) { - renderProps = props - act(() => { - try { - serverOutput = ReactDOMServer.renderToString(testHarness(props)) - } catch (e: unknown) { - rendererProps.setError(e as Error) - } - }) - }, - hydrate() { - if (container) { - throw new Error('The component can only be hydrated once') - } else { - container = document.createElement('div') - container.innerHTML = serverOutput - act(() => { - ReactDOM.hydrate(testHarness(renderProps), container!) - }) - } - }, - rerender(props?: TProps) { - if (!container) { + } + }, + rerender(props?: TProps) { + act(() => { + if (!root) { throw new Error('You must hydrate the component before you can rerender') } - act(() => { - ReactDOM.render(testHarness(props), container!) - }) - }, - unmount() { - if (container) { - act(() => { - ReactDOM.unmountComponentAtNode(container!) - }) + root.render(testHarness(props)) + }) + }, + unmount() { + act(() => { + if (root) { + root.unmount() } - }, - act - }; + }) + }, + act } } diff --git a/tsconfig.json b/tsconfig.json index 7661340c..08ca21c1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "./node_modules/kcd-scripts/shared-tsconfig.json", "compilerOptions": { - "target": "ES6" + "target": "ES6", + "types": ["node", "jest", "react/next", "react-dom/next"] } } From ea9d4f9ed857ef33a57f81f3510ce7ae4789db4c Mon Sep 17 00:00:00 2001 From: Michael Peyper Date: Sat, 24 Jul 2021 22:27:52 +1000 Subject: [PATCH 16/16] chore: increase coverage threshold again --- jest.config.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/jest.config.js b/jest.config.js index 9abc92d8..66b8064e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,12 +1,4 @@ const { jest: jestConfig } = require('kcd-scripts/config') -jestConfig.coverageThreshold = { - global: { - branches: 80, - functions: 80, - lines: 80, - statements: 80 - } -} module.exports = Object.assign(jestConfig, { setupFiles: ['/src/__tests__/utils/runForRenderers.ts'] })