Skip to content

Commit

Permalink
fix: Ensure renderHook options extend options for render (#1308)
Browse files Browse the repository at this point in the history
  • Loading branch information
eps1lon committed Apr 23, 2024
1 parent 067d0c6 commit 48282c2
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 7 deletions.
63 changes: 56 additions & 7 deletions types/index.d.ts
Expand Up @@ -179,19 +179,58 @@ export interface RenderHookResult<Result, Props> {
unmount: () => void
}

export interface RenderHookOptions<
export interface BaseRenderHookOptions<
Props,
Q extends Queries = typeof queries,
Container extends Element | DocumentFragment = HTMLElement,
BaseElement extends Element | DocumentFragment = Container,
> extends RenderOptions<Q, Container, BaseElement> {
Q extends Queries,
Container extends RendererableContainer | HydrateableContainer,
BaseElement extends Element | DocumentFragment,
> extends BaseRenderOptions<Q, Container, BaseElement> {
/**
* The argument passed to the renderHook callback. Can be useful if you plan
* to use the rerender utility to change the values passed to your hook.
*/
initialProps?: Props
}

export interface ClientRenderHookOptions<
Props,
Q extends Queries,
Container extends Element | DocumentFragment,
BaseElement extends Element | DocumentFragment = Container,
> extends BaseRenderHookOptions<Props, Q, Container, BaseElement> {
/**
* If `hydrate` is set to `true`, then it will render with `ReactDOM.hydrate`. This may be useful if you are using server-side
* rendering and use ReactDOM.hydrate to mount your components.
*
* @see https://testing-library.com/docs/react-testing-library/api/#hydrate)
*/
hydrate?: false | undefined
}

export interface HydrateHookOptions<
Props,
Q extends Queries,
Container extends Element | DocumentFragment,
BaseElement extends Element | DocumentFragment = Container,
> extends BaseRenderHookOptions<Props, Q, Container, BaseElement> {
/**
* If `hydrate` is set to `true`, then it will render with `ReactDOM.hydrate`. This may be useful if you are using server-side
* rendering and use ReactDOM.hydrate to mount your components.
*
* @see https://testing-library.com/docs/react-testing-library/api/#hydrate)
*/
hydrate: true
}

export type RenderHookOptions<
Props,
Q extends Queries = typeof queries,
Container extends Element | DocumentFragment = HTMLElement,
BaseElement extends Element | DocumentFragment = Container,
> =
| ClientRenderHookOptions<Props, Q, Container, BaseElement>
| HydrateHookOptions<Props, Q, Container, BaseElement>

/**
* Allows you to render a hook within a test React component without having to
* create that component yourself.
Expand All @@ -200,11 +239,21 @@ export function renderHook<
Result,
Props,
Q extends Queries = typeof queries,
Container extends Element | DocumentFragment = HTMLElement,
Container extends RendererableContainer = HTMLElement,
BaseElement extends Element | DocumentFragment = Container,
>(
render: (initialProps: Props) => Result,
options?: ClientRenderHookOptions<Props, Q, Container, BaseElement>,
): RenderHookResult<Result, Props>
export function renderHook<
Result,
Props,
Q extends Queries = typeof queries,
Container extends HydrateableContainer = HTMLElement,
BaseElement extends Element | DocumentFragment = Container,
>(
render: (initialProps: Props) => Result,
options?: RenderHookOptions<Props, Q, Container, BaseElement>,
options?: HydrateHookOptions<Props, Q, Container, BaseElement>,
): RenderHookResult<Result, Props>

/**
Expand Down
19 changes: 19 additions & 0 deletions types/test.tsx
Expand Up @@ -45,6 +45,8 @@ export function testRenderOptions() {
const options = {container}
const {container: returnedContainer} = render(<button />, options)
expectType<HTMLDivElement, typeof returnedContainer>(returnedContainer)

render(<div />, {wrapper: () => null})
}

export function testSVGRenderOptions() {
Expand Down Expand Up @@ -191,6 +193,8 @@ export function testRenderHook() {
rerender()

unmount()

renderHook(() => null, {wrapper: () => null})
}

export function testRenderHookProps() {
Expand All @@ -215,6 +219,21 @@ export function testContainer() {
// @ts-expect-error Only allowed for createRoot
render('a', {container: document.createDocumentFragment(), hydrate: true})
render('a', {container: document, hydrate: true})

renderHook(() => null, {container: document.createElement('div')})
renderHook(() => null, {container: document.createDocumentFragment()})
// @ts-expect-error Only allowed in React 19
renderHook(() => null, {container: document})
renderHook(() => null, {
container: document.createElement('div'),
hydrate: true,
})
// @ts-expect-error Only allowed for createRoot
renderHook(() => null, {
container: document.createDocumentFragment(),
hydrate: true,
})
renderHook(() => null, {container: document, hydrate: true})
}

/*
Expand Down

0 comments on commit 48282c2

Please sign in to comment.