From a82d5ef31779bf1112a951909dfb09328e48581b Mon Sep 17 00:00:00 2001 From: Michael Peyper Date: Fri, 8 Jan 2021 23:13:08 +1100 Subject: [PATCH] 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 Co-authored-by: Jonathan Peyper --- src/core/asyncUtils.ts | 2 +- src/core/index.ts | 62 ++++++++++++++++++------------- src/dom/pure.ts | 6 +-- src/helpers/createTestHarness.tsx | 15 ++++++-- src/helpers/promises.ts | 10 +++-- src/native/pure.ts | 8 ++-- src/server/pure.ts | 8 ++-- 7 files changed, 66 insertions(+), 45 deletions(-) diff --git a/src/core/asyncUtils.ts b/src/core/asyncUtils.ts index 4c2ecf77..d12e468c 100644 --- a/src/core/asyncUtils.ts +++ b/src/core/asyncUtils.ts @@ -95,4 +95,4 @@ function asyncUtils(act: Act, addResolver: (callback: () => void) => void): Asyn } } -export default asyncUtils +export { asyncUtils } diff --git a/src/core/index.ts b/src/core/index.ts index 6f8f5809..7c4c5c83 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -1,7 +1,7 @@ import { CreateRenderer, Renderer, RenderResult, RenderHook, RenderHookOptions } from '../types' import { ResultContainer } from '../types/internal' -import asyncUtils from './asyncUtils' +import { asyncUtils } from './asyncUtils' import { cleanup, addCleanup, removeCleanup } from './cleanup' function resultContainer(): ResultContainer { @@ -40,39 +40,49 @@ function resultContainer(): ResultContainer { } } -const createRenderHook = >( +function createRenderHook>( createRenderer: CreateRenderer -) => ( - callback: (props: TProps) => TResult, - options: RenderHookOptions = {} as RenderHookOptions -): RenderHook => { - const { result, setValue, setError, addResolver } = resultContainer() - const renderProps = { callback, setValue, setError } - let hookProps = options.initialProps +) { + const renderHook = ( + callback: (props: TProps) => TResult, + options: RenderHookOptions = {} as RenderHookOptions + ): RenderHook => { + const { result, setValue, setError, addResolver } = resultContainer() + const renderProps = { callback, setValue, setError } + let hookProps = options.initialProps - const { render, rerender, unmount, act, ...renderUtils } = createRenderer(renderProps, options) + const { render, rerender, unmount, act, ...renderUtils } = createRenderer(renderProps, options) - render(hookProps) + render(hookProps) - function rerenderHook(newProps = hookProps) { - hookProps = newProps - rerender(hookProps) - } + const rerenderHook = (newProps = hookProps) => { + hookProps = newProps + rerender(hookProps) + } - function unmountHook() { - removeCleanup(unmountHook) - unmount() - } + const unmountHook = () => { + removeCleanup(unmountHook) + unmount() + } - addCleanup(unmountHook) + addCleanup(unmountHook) - return { - result, - rerender: rerenderHook, - unmount: unmountHook, - ...asyncUtils(act, addResolver), - ...renderUtils + return { + result, + rerender: rerenderHook, + unmount: unmountHook, + ...asyncUtils(act, addResolver), + ...renderUtils + } } + + // If the function name does not get used before it is returned, + // it's name is removed by babel-plugin-minify-dead-code-elimination. + // This dummy usage works around that. + renderHook.name // eslint-disable-line @typescript-eslint/no-unused-expressions + + + return renderHook } export { createRenderHook, cleanup, addCleanup, removeCleanup } diff --git a/src/dom/pure.ts b/src/dom/pure.ts index c2f90916..2b2d1f32 100644 --- a/src/dom/pure.ts +++ b/src/dom/pure.ts @@ -13,18 +13,18 @@ function createDomRenderer( ) { const container = document.createElement('div') - const testHook = createTestHarness(rendererProps, wrapper) + const testHarness = createTestHarness(rendererProps, wrapper) return { render(props?: TProps) { document.body.appendChild(container) act(() => { - ReactDOM.render(testHook(props), container) + ReactDOM.render(testHarness(props), container) }) }, rerender(props?: TProps) { act(() => { - ReactDOM.render(testHook(props), container) + ReactDOM.render(testHarness(props), container) }) }, unmount() { diff --git a/src/helpers/createTestHarness.tsx b/src/helpers/createTestHarness.tsx index b382a080..d50472d2 100644 --- a/src/helpers/createTestHarness.tsx +++ b/src/helpers/createTestHarness.tsx @@ -24,12 +24,12 @@ function TestComponent({ return null } -export const createTestHarness = ( +function createTestHarness( rendererProps: RendererProps, Wrapper?: WrapperComponent, suspense: boolean = true -) => { - return (props?: TProps) => { +) { + const testHarness = (props?: TProps) => { let component = if (Wrapper) { component = {component} @@ -39,4 +39,13 @@ export const createTestHarness = ( } return component } + + // If the function name does not get used before it is returned, + // it's name is removed by babel-plugin-minify-dead-code-elimination. + // This dummy usage works around that. + testHarness.name // eslint-disable-line @typescript-eslint/no-unused-expressions + + return testHarness } + +export { createTestHarness } diff --git a/src/helpers/promises.ts b/src/helpers/promises.ts index d7dec9bd..8f7612ba 100644 --- a/src/helpers/promises.ts +++ b/src/helpers/promises.ts @@ -1,9 +1,11 @@ -const resolveAfter = (ms: number) => - new Promise((resolve) => { +function resolveAfter(ms: number) { + return new Promise((resolve) => { setTimeout(resolve, ms) }) +} -const isPromise = (value: unknown): boolean => - typeof (value as PromiseLike).then === 'function' +function isPromise(value: unknown): boolean { + return typeof (value as PromiseLike).then === 'function' +} export { isPromise, resolveAfter } diff --git a/src/native/pure.ts b/src/native/pure.ts index e9156bc1..b343bb66 100644 --- a/src/native/pure.ts +++ b/src/native/pure.ts @@ -7,22 +7,22 @@ import { createRenderHook, cleanup, addCleanup, removeCleanup } from '../core' import { createTestHarness } from '../helpers/createTestHarness' function createNativeRenderer( - testHookProps: RendererProps, + rendererProps: RendererProps, { wrapper }: RendererOptions ) { let container: ReactTestRenderer - const testHook = createTestHarness(testHookProps, wrapper) + const testHarness = createTestHarness(rendererProps, wrapper) return { render(props?: TProps) { act(() => { - container = create(testHook(props)) + container = create(testHarness(props)) }) }, rerender(props?: TProps) { act(() => { - container.update(testHook(props)) + container.update(testHarness(props)) }) }, unmount() { diff --git a/src/server/pure.ts b/src/server/pure.ts index ec0737b1..ae7f21d0 100644 --- a/src/server/pure.ts +++ b/src/server/pure.ts @@ -14,7 +14,7 @@ function createServerRenderer( ) { const container = document.createElement('div') - const testHook = createTestHarness(rendererProps, wrapper, false) + const testHarness = createTestHarness(rendererProps, wrapper, false) let renderProps: TProps | undefined let hydrated = false @@ -23,7 +23,7 @@ function createServerRenderer( render(props?: TProps) { renderProps = props act(() => { - const serverOutput = ReactDOMServer.renderToString(testHook(props)) + const serverOutput = ReactDOMServer.renderToString(testHarness(props)) container.innerHTML = serverOutput }) }, @@ -33,7 +33,7 @@ function createServerRenderer( } else { document.body.appendChild(container) act(() => { - ReactDOM.hydrate(testHook(renderProps), container) + ReactDOM.hydrate(testHarness(renderProps), container) }) hydrated = true } @@ -43,7 +43,7 @@ function createServerRenderer( throw new Error('You must hydrate the component before you can rerender') } act(() => { - ReactDOM.render(testHook(props), container) + ReactDOM.render(testHarness(props), container) }) }, unmount() {