Skip to content

Commit a82d5ef

Browse files
mpeyperjpeyper
andauthored
fix: display returned function names correctly in stack traces (#528)
Refactors for consistency. * refactor: change functions to be more consistent between regular functions and arrow functions * refactor: rename testHook to be testHarness for consistency * refactor: remove default exports for consistency * fix: display returned function names correctly in stack traces * refactor: remove variable assignment in function name workaround Co-authored-by: Jonathan Peyper <[email protected]> Co-authored-by: Jonathan Peyper <[email protected]>
1 parent 4786242 commit a82d5ef

File tree

7 files changed

+66
-45
lines changed

7 files changed

+66
-45
lines changed

src/core/asyncUtils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,4 @@ function asyncUtils(act: Act, addResolver: (callback: () => void) => void): Asyn
9595
}
9696
}
9797

98-
export default asyncUtils
98+
export { asyncUtils }

src/core/index.ts

+36-26
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { CreateRenderer, Renderer, RenderResult, RenderHook, RenderHookOptions } from '../types'
22
import { ResultContainer } from '../types/internal'
33

4-
import asyncUtils from './asyncUtils'
4+
import { asyncUtils } from './asyncUtils'
55
import { cleanup, addCleanup, removeCleanup } from './cleanup'
66

77
function resultContainer<TValue>(): ResultContainer<TValue> {
@@ -40,39 +40,49 @@ function resultContainer<TValue>(): ResultContainer<TValue> {
4040
}
4141
}
4242

43-
const createRenderHook = <TProps, TResult, TOptions extends {}, TRenderer extends Renderer<TProps>>(
43+
function createRenderHook<TProps, TResult, TOptions extends {}, TRenderer extends Renderer<TProps>>(
4444
createRenderer: CreateRenderer<TProps, TResult, TOptions, TRenderer>
45-
) => (
46-
callback: (props: TProps) => TResult,
47-
options: RenderHookOptions<TProps, TOptions> = {} as RenderHookOptions<TProps, TOptions>
48-
): RenderHook<TProps, TResult, TRenderer> => {
49-
const { result, setValue, setError, addResolver } = resultContainer<TResult>()
50-
const renderProps = { callback, setValue, setError }
51-
let hookProps = options.initialProps
45+
) {
46+
const renderHook = (
47+
callback: (props: TProps) => TResult,
48+
options: RenderHookOptions<TProps, TOptions> = {} as RenderHookOptions<TProps, TOptions>
49+
): RenderHook<TProps, TResult, TRenderer> => {
50+
const { result, setValue, setError, addResolver } = resultContainer<TResult>()
51+
const renderProps = { callback, setValue, setError }
52+
let hookProps = options.initialProps
5253

53-
const { render, rerender, unmount, act, ...renderUtils } = createRenderer(renderProps, options)
54+
const { render, rerender, unmount, act, ...renderUtils } = createRenderer(renderProps, options)
5455

55-
render(hookProps)
56+
render(hookProps)
5657

57-
function rerenderHook(newProps = hookProps) {
58-
hookProps = newProps
59-
rerender(hookProps)
60-
}
58+
const rerenderHook = (newProps = hookProps) => {
59+
hookProps = newProps
60+
rerender(hookProps)
61+
}
6162

62-
function unmountHook() {
63-
removeCleanup(unmountHook)
64-
unmount()
65-
}
63+
const unmountHook = () => {
64+
removeCleanup(unmountHook)
65+
unmount()
66+
}
6667

67-
addCleanup(unmountHook)
68+
addCleanup(unmountHook)
6869

69-
return {
70-
result,
71-
rerender: rerenderHook,
72-
unmount: unmountHook,
73-
...asyncUtils(act, addResolver),
74-
...renderUtils
70+
return {
71+
result,
72+
rerender: rerenderHook,
73+
unmount: unmountHook,
74+
...asyncUtils(act, addResolver),
75+
...renderUtils
76+
}
7577
}
78+
79+
// If the function name does not get used before it is returned,
80+
// it's name is removed by babel-plugin-minify-dead-code-elimination.
81+
// This dummy usage works around that.
82+
renderHook.name // eslint-disable-line @typescript-eslint/no-unused-expressions
83+
84+
85+
return renderHook
7686
}
7787

7888
export { createRenderHook, cleanup, addCleanup, removeCleanup }

src/dom/pure.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@ function createDomRenderer<TProps, TResult>(
1313
) {
1414
const container = document.createElement('div')
1515

16-
const testHook = createTestHarness(rendererProps, wrapper)
16+
const testHarness = createTestHarness(rendererProps, wrapper)
1717

1818
return {
1919
render(props?: TProps) {
2020
document.body.appendChild(container)
2121
act(() => {
22-
ReactDOM.render(testHook(props), container)
22+
ReactDOM.render(testHarness(props), container)
2323
})
2424
},
2525
rerender(props?: TProps) {
2626
act(() => {
27-
ReactDOM.render(testHook(props), container)
27+
ReactDOM.render(testHarness(props), container)
2828
})
2929
},
3030
unmount() {

src/helpers/createTestHarness.tsx

+12-3
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ function TestComponent<TProps, TResult>({
2424
return null
2525
}
2626

27-
export const createTestHarness = <TProps, TResult>(
27+
function createTestHarness<TProps, TResult>(
2828
rendererProps: RendererProps<TProps, TResult>,
2929
Wrapper?: WrapperComponent<TProps>,
3030
suspense: boolean = true
31-
) => {
32-
return (props?: TProps) => {
31+
) {
32+
const testHarness = (props?: TProps) => {
3333
let component = <TestComponent hookProps={props} {...rendererProps} />
3434
if (Wrapper) {
3535
component = <Wrapper {...(props as TProps)}>{component}</Wrapper>
@@ -39,4 +39,13 @@ export const createTestHarness = <TProps, TResult>(
3939
}
4040
return component
4141
}
42+
43+
// If the function name does not get used before it is returned,
44+
// it's name is removed by babel-plugin-minify-dead-code-elimination.
45+
// This dummy usage works around that.
46+
testHarness.name // eslint-disable-line @typescript-eslint/no-unused-expressions
47+
48+
return testHarness
4249
}
50+
51+
export { createTestHarness }

src/helpers/promises.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
const resolveAfter = (ms: number) =>
2-
new Promise((resolve) => {
1+
function resolveAfter(ms: number) {
2+
return new Promise((resolve) => {
33
setTimeout(resolve, ms)
44
})
5+
}
56

6-
const isPromise = <T>(value: unknown): boolean =>
7-
typeof (value as PromiseLike<T>).then === 'function'
7+
function isPromise<T>(value: unknown): boolean {
8+
return typeof (value as PromiseLike<T>).then === 'function'
9+
}
810

911
export { isPromise, resolveAfter }

src/native/pure.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,22 @@ import { createRenderHook, cleanup, addCleanup, removeCleanup } from '../core'
77
import { createTestHarness } from '../helpers/createTestHarness'
88

99
function createNativeRenderer<TProps, TResult>(
10-
testHookProps: RendererProps<TProps, TResult>,
10+
rendererProps: RendererProps<TProps, TResult>,
1111
{ wrapper }: RendererOptions<TProps>
1212
) {
1313
let container: ReactTestRenderer
1414

15-
const testHook = createTestHarness(testHookProps, wrapper)
15+
const testHarness = createTestHarness(rendererProps, wrapper)
1616

1717
return {
1818
render(props?: TProps) {
1919
act(() => {
20-
container = create(testHook(props))
20+
container = create(testHarness(props))
2121
})
2222
},
2323
rerender(props?: TProps) {
2424
act(() => {
25-
container.update(testHook(props))
25+
container.update(testHarness(props))
2626
})
2727
},
2828
unmount() {

src/server/pure.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function createServerRenderer<TProps, TResult>(
1414
) {
1515
const container = document.createElement('div')
1616

17-
const testHook = createTestHarness(rendererProps, wrapper, false)
17+
const testHarness = createTestHarness(rendererProps, wrapper, false)
1818

1919
let renderProps: TProps | undefined
2020
let hydrated = false
@@ -23,7 +23,7 @@ function createServerRenderer<TProps, TResult>(
2323
render(props?: TProps) {
2424
renderProps = props
2525
act(() => {
26-
const serverOutput = ReactDOMServer.renderToString(testHook(props))
26+
const serverOutput = ReactDOMServer.renderToString(testHarness(props))
2727
container.innerHTML = serverOutput
2828
})
2929
},
@@ -33,7 +33,7 @@ function createServerRenderer<TProps, TResult>(
3333
} else {
3434
document.body.appendChild(container)
3535
act(() => {
36-
ReactDOM.hydrate(testHook(renderProps), container)
36+
ReactDOM.hydrate(testHarness(renderProps), container)
3737
})
3838
hydrated = true
3939
}
@@ -43,7 +43,7 @@ function createServerRenderer<TProps, TResult>(
4343
throw new Error('You must hydrate the component before you can rerender')
4444
}
4545
act(() => {
46-
ReactDOM.render(testHook(props), container)
46+
ReactDOM.render(testHarness(props), container)
4747
})
4848
},
4949
unmount() {

0 commit comments

Comments
 (0)