Skip to content

Commit 2b4a770

Browse files
committed
refactor: add createLegacyRoot to reduce uncovered code percentage
Ignore root creation code from code covereage Introduced next react types for React.Root
1 parent d4ba70c commit 2b4a770

File tree

4 files changed

+85
-125
lines changed

4 files changed

+85
-125
lines changed

src/dom/pure.ts

Lines changed: 19 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,35 @@
1-
import * as ReactDOM from 'react-dom'
21
import { act } from 'react-dom/test-utils'
32

43
import { RendererProps, RendererOptions } from '../types/react'
54

65
import { createRenderHook } from '../core'
76
import { createTestHarness } from '../helpers/createTestHarness'
8-
9-
// @ts-ignore
10-
const isReactConcurrent = !!ReactDOM.createRoot;
7+
import { createRoot } from '../helpers/createRoot'
118

129
function createDomRenderer<TProps, TResult>(
1310
rendererProps: RendererProps<TProps, TResult>,
1411
{ wrapper }: RendererOptions<TProps>
1512
) {
1613
const container = document.createElement('div')
1714
const testHarness = createTestHarness(rendererProps, wrapper)
18-
if (isReactConcurrent) {
19-
// @ts-ignore
20-
const root = ReactDOM.createRoot(container)
21-
return {
22-
render(props?: TProps) {
23-
act(() => {
24-
root.render(testHarness(props))
25-
})
26-
},
27-
rerender(props?: TProps) {
28-
act(() => {
29-
root.render(testHarness(props))
30-
})
31-
},
32-
unmount() {
33-
act(() => {
34-
root.unmount()
35-
})
36-
},
37-
act
38-
}
39-
} else {
40-
return {
41-
render(props?: TProps) {
42-
act(() => {
43-
ReactDOM.render(testHarness(props), container)
44-
})
45-
},
46-
rerender(props?: TProps) {
47-
act(() => {
48-
ReactDOM.render(testHarness(props), container)
49-
})
50-
},
51-
unmount() {
52-
act(() => {
53-
ReactDOM.unmountComponentAtNode(container)
54-
})
55-
},
56-
act
57-
}
15+
const root = createRoot(container)
16+
return {
17+
render(props?: TProps) {
18+
act(() => {
19+
root.render(testHarness(props))
20+
})
21+
},
22+
rerender(props?: TProps) {
23+
act(() => {
24+
root.render(testHarness(props))
25+
})
26+
},
27+
unmount() {
28+
act(() => {
29+
root.unmount()
30+
})
31+
},
32+
act
5833
}
5934
}
6035

src/helpers/createRoot.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import * as ReactDOM from 'react-dom'
2+
import * as React from 'react'
3+
4+
/* istanbul ignore next */
5+
function createLegacyRoot(container: Element): ReactDOM.Root {
6+
return {
7+
render(element: React.ReactElement) {
8+
ReactDOM.render(element, container)
9+
},
10+
unmount() {
11+
ReactDOM.unmountComponentAtNode(container)
12+
}
13+
}
14+
}
15+
16+
/* istanbul ignore next */
17+
export function createRoot(container: Element) {
18+
return (ReactDOM.createRoot ? ReactDOM.createRoot : createLegacyRoot)(container)
19+
}
20+
21+
/* istanbul ignore next */
22+
export function hydrateLegacyRoot(container: Element, element: React.ReactElement): ReactDOM.Root {
23+
ReactDOM.hydrate(element, container)
24+
return createLegacyRoot(container)
25+
}
26+
27+
/* istanbul ignore next */
28+
export function hydrateRoot(container: Element, element: React.ReactElement) {
29+
return (ReactDOM.hydrateRoot ? ReactDOM.hydrateRoot : hydrateLegacyRoot)(container, element)
30+
}

src/server/pure.ts

Lines changed: 34 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -6,100 +6,54 @@ import { RendererOptions, RendererProps } from '../types/react'
66

77
import { createRenderHook } from '../core'
88
import { createTestHarness } from '../helpers/createTestHarness'
9-
10-
// @ts-ignore
11-
const isReactConcurrent = !!ReactDOM.createRoot;
9+
import { hydrateRoot } from '../helpers/createRoot'
1210

1311
function createServerRenderer<TProps, TResult>(
1412
rendererProps: RendererProps<TProps, TResult>,
1513
{ wrapper }: RendererOptions<TProps>
1614
) {
1715
let renderProps: TProps | undefined
18-
let container: HTMLDivElement | undefined
1916
let serverOutput: string = ''
2017
const testHarness = createTestHarness(rendererProps, wrapper, false)
21-
if (isReactConcurrent) {
22-
let root: any
23-
return {
24-
render(props?: TProps) {
25-
renderProps = props
26-
act(() => {
27-
try {
28-
serverOutput = ReactDOMServer.renderToString(testHarness(props))
29-
} catch (e: unknown) {
30-
rendererProps.setError(e as Error)
31-
}
32-
})
33-
},
34-
hydrate() {
35-
if (container) {
36-
throw new Error('The component can only be hydrated once')
37-
} else {
38-
container = document.createElement('div')
39-
container.innerHTML = serverOutput
40-
act(() => {
41-
// @ts-ignore
42-
root = ReactDOM.hydrateRoot(container, testHarness(renderProps))
43-
})
44-
}
45-
},
46-
rerender(props?: TProps) {
47-
if (!container) {
48-
throw new Error('You must hydrate the component before you can rerender')
18+
let root: ReactDOM.Root | undefined
19+
return {
20+
render(props?: TProps) {
21+
renderProps = props
22+
act(() => {
23+
try {
24+
serverOutput = ReactDOMServer.renderToString(testHarness(props))
25+
} catch (e: unknown) {
26+
rendererProps.setError(e as Error)
4927
}
28+
})
29+
},
30+
hydrate() {
31+
if (root) {
32+
throw new Error('The component can only be hydrated once')
33+
} else {
34+
const container = document.createElement('div')
35+
container.innerHTML = serverOutput
5036
act(() => {
51-
root.render(testHarness(props))
37+
root = hydrateRoot(container, testHarness(renderProps))
5238
})
53-
},
54-
unmount() {
55-
if (container) {
56-
act(() => {
57-
root.unmount()
58-
})
59-
}
60-
},
61-
act
62-
};
63-
} else {
64-
return {
65-
render(props?: TProps) {
66-
renderProps = props
67-
act(() => {
68-
try {
69-
serverOutput = ReactDOMServer.renderToString(testHarness(props))
70-
} catch (e: unknown) {
71-
rendererProps.setError(e as Error)
72-
}
73-
})
74-
},
75-
hydrate() {
76-
if (container) {
77-
throw new Error('The component can only be hydrated once')
78-
} else {
79-
container = document.createElement('div')
80-
container.innerHTML = serverOutput
81-
act(() => {
82-
ReactDOM.hydrate(testHarness(renderProps), container!)
83-
})
84-
}
85-
},
86-
rerender(props?: TProps) {
87-
if (!container) {
39+
}
40+
},
41+
rerender(props?: TProps) {
42+
act(() => {
43+
if (!root) {
8844
throw new Error('You must hydrate the component before you can rerender')
8945
}
90-
act(() => {
91-
ReactDOM.render(testHarness(props), container!)
92-
})
93-
},
94-
unmount() {
95-
if (container) {
96-
act(() => {
97-
ReactDOM.unmountComponentAtNode(container!)
98-
})
46+
root.render(testHarness(props))
47+
})
48+
},
49+
unmount() {
50+
act(() => {
51+
if (root) {
52+
root.unmount()
9953
}
100-
},
101-
act
102-
};
54+
})
55+
},
56+
act
10357
}
10458
}
10559

tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"extends": "./node_modules/kcd-scripts/shared-tsconfig.json",
33
"compilerOptions": {
4-
"target": "ES6"
4+
"target": "ES6",
5+
"types": ["node", "jest", "react/next", "react-dom/next"]
56
}
67
}

0 commit comments

Comments
 (0)