@@ -13,12 +13,10 @@ afterEach(() => {
1313} ) ;
1414
1515function useSuspendingHook ( promise : Promise < string > ) {
16- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
17- // @ts -ignore: React 18 does not have `use` hook
1816 return React . use ( promise ) ;
1917}
2018
21- test ( 'renderHook renders hook asynchronously ' , async ( ) => {
19+ test ( 'renders hook and returns committed result ' , async ( ) => {
2220 const { result } = await renderHook ( ( ) => {
2321 const [ state , setState ] = React . useState ( 1 ) ;
2422
@@ -32,7 +30,39 @@ test('renderHook renders hook asynchronously', async () => {
3230 expect ( result . current ) . toEqual ( 2 ) ;
3331} ) ;
3432
35- test ( 'renderHook with wrapper option' , async ( ) => {
33+ test ( 'handles hook with state updates during effects' , async ( ) => {
34+ function useTestHook ( ) {
35+ const [ count , setCount ] = React . useState ( 0 ) ;
36+
37+ React . useEffect ( ( ) => {
38+ setCount ( ( prev ) => prev + 1 ) ;
39+ } , [ ] ) ;
40+
41+ return count ;
42+ }
43+
44+ const { result } = await renderHook ( useTestHook ) ;
45+ expect ( result . current ) . toBe ( 1 ) ;
46+ } ) ;
47+
48+ test ( 'handles multiple state updates in effects' , async ( ) => {
49+ function useTestHook ( ) {
50+ const [ first , setFirst ] = React . useState ( 1 ) ;
51+ const [ second , setSecond ] = React . useState ( 2 ) ;
52+
53+ React . useEffect ( ( ) => {
54+ setFirst ( 10 ) ;
55+ setSecond ( 20 ) ;
56+ } , [ ] ) ;
57+
58+ return { first, second } ;
59+ }
60+
61+ const { result } = await renderHook ( useTestHook ) ;
62+ expect ( result . current ) . toEqual ( { first : 10 , second : 20 } ) ;
63+ } ) ;
64+
65+ test ( 'works with wrapper option' , async ( ) => {
3666 const Context = React . createContext ( 'default' ) ;
3767
3868 function useTestHook ( ) {
@@ -47,7 +77,24 @@ test('renderHook with wrapper option', async () => {
4777 expect ( result . current ) . toEqual ( 'provided' ) ;
4878} ) ;
4979
50- test ( 'rerender function updates hook asynchronously' , async ( ) => {
80+ test ( 'works with initialProps option' , async ( ) => {
81+ function useTestHook ( props : { value : number } ) {
82+ const [ state , setState ] = React . useState ( props . value ) ;
83+
84+ React . useEffect ( ( ) => {
85+ setState ( props . value * 2 ) ;
86+ } , [ props . value ] ) ;
87+
88+ return state ;
89+ }
90+
91+ const { result } = await renderHook ( useTestHook , {
92+ initialProps : { value : 5 } ,
93+ } ) ;
94+ expect ( result . current ) . toEqual ( 10 ) ;
95+ } ) ;
96+
97+ test ( 'rerender updates hook with new props' , async ( ) => {
5198 function useTestHook ( props : { value : number } ) {
5299 const [ state , setState ] = React . useState ( props . value ) ;
53100
@@ -67,7 +114,7 @@ test('rerender function updates hook asynchronously', async () => {
67114 expect ( result . current ) . toEqual ( 20 ) ;
68115} ) ;
69116
70- test ( 'unmount function unmounts hook asynchronously ' , async ( ) => {
117+ test ( 'unmount triggers cleanup effects ' , async ( ) => {
71118 let cleanupCalled = false ;
72119
73120 function useTestHook ( ) {
@@ -87,36 +134,41 @@ test('unmount function unmounts hook asynchronously', async () => {
87134 expect ( cleanupCalled ) . toBe ( true ) ;
88135} ) ;
89136
90- test ( 'handles hook with state updates during effects' , async ( ) => {
91- function useTestHook ( ) {
92- const [ count , setCount ] = React . useState ( 0 ) ;
137+ test ( 'handles hook with cleanup and re-initialization' , async ( ) => {
138+ let effectCount = 0 ;
139+ let cleanupCount = 0 ;
140+
141+ function useTestHook ( props : { key : string } ) {
142+ const [ value , setValue ] = React . useState ( props . key ) ;
93143
94144 React . useEffect ( ( ) => {
95- setCount ( ( prev ) => prev + 1 ) ;
96- } , [ ] ) ;
145+ effectCount ++ ;
146+ setValue ( ` ${ props . key } -effect` ) ;
97147
98- return count ;
99- }
148+ return ( ) => {
149+ cleanupCount ++ ;
150+ } ;
151+ } , [ props . key ] ) ;
100152
101- const { result } = await renderHook ( useTestHook ) ;
102- expect ( result . current ) . toBe ( 1 ) ;
103- } ) ;
153+ return value ;
154+ }
104155
105- test ( 'handles multiple state updates in effects' , async ( ) => {
106- function useTestHook ( ) {
107- const [ first , setFirst ] = React . useState ( 1 ) ;
108- const [ second , setSecond ] = React . useState ( 2 ) ;
156+ const { result, rerender, unmount } = await renderHook ( useTestHook , {
157+ initialProps : { key : 'initial' } ,
158+ } ) ;
109159
110- React . useEffect ( ( ) => {
111- setFirst ( 10 ) ;
112- setSecond ( 20 ) ;
113- } , [ ] ) ;
160+ expect ( result . current ) . toBe ( 'initial-effect' ) ;
161+ expect ( effectCount ) . toBe ( 1 ) ;
162+ expect ( cleanupCount ) . toBe ( 0 ) ;
114163
115- return { first, second } ;
116- }
164+ await rerender ( { key : 'updated' } ) ;
165+ expect ( result . current ) . toBe ( 'updated-effect' ) ;
166+ expect ( effectCount ) . toBe ( 2 ) ;
167+ expect ( cleanupCount ) . toBe ( 1 ) ;
117168
118- const { result } = await renderHook ( useTestHook ) ;
119- expect ( result . current ) . toEqual ( { first : 10 , second : 20 } ) ;
169+ await unmount ( ) ;
170+ expect ( effectCount ) . toBe ( 2 ) ;
171+ expect ( cleanupCount ) . toBe ( 2 ) ;
120172} ) ;
121173
122174test ( 'handles hook with suspense' , async ( ) => {
@@ -227,40 +279,3 @@ test('handles custom hooks with complex logic', async () => {
227279 } ) ;
228280 expect ( result . current . count ) . toBe ( 4 ) ;
229281} ) ;
230-
231- test ( 'handles hook with cleanup and re-initialization' , async ( ) => {
232- let effectCount = 0 ;
233- let cleanupCount = 0 ;
234-
235- function useTestHook ( props : { key : string } ) {
236- const [ value , setValue ] = React . useState ( props . key ) ;
237-
238- React . useEffect ( ( ) => {
239- effectCount ++ ;
240- setValue ( `${ props . key } -effect` ) ;
241-
242- return ( ) => {
243- cleanupCount ++ ;
244- } ;
245- } , [ props . key ] ) ;
246-
247- return value ;
248- }
249-
250- const { result, rerender, unmount } = await renderHook ( useTestHook , {
251- initialProps : { key : 'initial' } ,
252- } ) ;
253-
254- expect ( result . current ) . toBe ( 'initial-effect' ) ;
255- expect ( effectCount ) . toBe ( 1 ) ;
256- expect ( cleanupCount ) . toBe ( 0 ) ;
257-
258- await rerender ( { key : 'updated' } ) ;
259- expect ( result . current ) . toBe ( 'updated-effect' ) ;
260- expect ( effectCount ) . toBe ( 2 ) ;
261- expect ( cleanupCount ) . toBe ( 1 ) ;
262-
263- await unmount ( ) ;
264- expect ( effectCount ) . toBe ( 2 ) ;
265- expect ( cleanupCount ) . toBe ( 2 ) ;
266- } ) ;
0 commit comments