1- import { nextTick } from 'node:process' ;
21import { it , describe , expect , afterEach } from 'vitest' ;
32import { gray } from 'colorette' ;
43import { renderHook , cleanup as cleanupMountedReactTrees } from '@testing-library/react' ;
54import { useAsyncIterMemo , iterateFormatted } from '../libEntrypoint.js' ;
65import { pipe } from '../utils/pipe.js' ;
6+ import { IterableChannelTestHelper } from '../utils/IterableChannelTestHelper.js' ;
7+ import { feedChannelAcrossTicks } from '../utils/feedChannelAcrossTicks.js' ;
78import { asyncIterToArray } from '../utils/asyncIterToArray.js' ;
89import { asyncIterTake } from '../utils/asyncIterTake.js' ;
910import { asyncIterOf } from '../utils/asyncIterOf.js' ;
1011import { asyncIterTickSeparatedOf } from '../utils/asyncIterTickSeparatedOf.js' ;
11- import { IterableChannelTestHelper } from '../utils/IterableChannelTestHelper.js' ;
1212
1313afterEach ( ( ) => {
1414 cleanupMountedReactTrees ( ) ;
1515} ) ;
1616
1717describe ( '`useAsyncIterMemo` hook' , ( ) => {
18- it ( gray ( '___ ___ ___ 1 ' ) , async ( ) => {
18+ it ( gray ( 'When given mixed iterable and plain values, will work correctly ' ) , async ( ) => {
1919 const renderedHook = renderHook (
2020 ( { val1, val2, iter1, iter2 } ) =>
2121 useAsyncIterMemo ( ( ...deps ) => deps , [ val1 , val2 , iter1 , iter2 ] ) ,
@@ -37,177 +37,176 @@ describe('`useAsyncIterMemo` hook', () => {
3737 expect ( await asyncIterToArray ( resIter2 ) ) . toStrictEqual ( [ 'd' , 'e' , 'f' ] ) ;
3838 } ) ;
3939
40- it ( gray ( '___ ___ ___ 2' ) , async ( ) => {
41- const channel1 = new IterableChannelTestHelper < string > ( ) ;
42- const channel2 = new IterableChannelTestHelper < string > ( ) ;
43- let timesRerun = 0 ;
44-
45- const renderedHook = renderHook (
46- ( { val1, val2, iter1, iter2 } ) =>
47- useAsyncIterMemo (
48- ( ...deps ) => {
49- timesRerun ++ ;
50- return deps ;
40+ it (
41+ gray (
42+ 'When updated consecutively with formatted iterables of the same source iterables each time, will work correctly and not re-run factory function'
43+ ) ,
44+ async ( ) => {
45+ const channel1 = new IterableChannelTestHelper < string > ( ) ;
46+ const channel2 = new IterableChannelTestHelper < string > ( ) ;
47+ let timesRerun = 0 ;
48+
49+ const renderedHook = renderHook (
50+ ( { val1, val2, iter1, iter2 } ) =>
51+ useAsyncIterMemo (
52+ ( ...deps ) => {
53+ timesRerun ++ ;
54+ return deps ;
55+ } ,
56+ [ val1 , val2 , iter1 , iter2 ]
57+ ) ,
58+ {
59+ initialProps : {
60+ val1 : 'a' ,
61+ val2 : 'b' ,
62+ iter1 : iterateFormatted ( channel1 , v => `${ v } _formatted_1st_time` ) ,
63+ iter2 : iterateFormatted ( channel2 , v => `${ v } _formatted_1st_time` ) ,
5164 } ,
52- [ val1 , val2 , iter1 , iter2 ]
53- ) ,
54- {
55- initialProps : {
56- val1 : 'a' ,
57- val2 : 'b' ,
58- iter1 : iterateFormatted ( channel1 , v => `${ v } _formatted_1st_time` ) ,
59- iter2 : iterateFormatted ( channel2 , v => `${ v } _formatted_1st_time` ) ,
60- } ,
61- }
62- ) ;
63-
64- const hookFirstResult = renderedHook . result . current ;
65-
66- {
67- expect ( timesRerun ) . toStrictEqual ( 1 ) ;
65+ }
66+ ) ;
6867
69- const [ , , resIter1 , resIter2 ] = hookFirstResult ;
68+ const hookFirstResult = renderedHook . result . current ;
7069
71- feedChannelAcrossTicks ( channel1 , [ 'a' , 'b' , 'c' ] ) ;
72- const resIter1Values = await pipe ( resIter1 , asyncIterTake ( 3 ) , asyncIterToArray ) ;
73- expect ( resIter1Values ) . toStrictEqual ( [
74- 'a_formatted_1st_time' ,
75- 'b_formatted_1st_time' ,
76- 'c_formatted_1st_time' ,
77- ] ) ;
70+ {
71+ expect ( timesRerun ) . toStrictEqual ( 1 ) ;
72+
73+ const [ , , resIter1 , resIter2 ] = hookFirstResult ;
74+
75+ feedChannelAcrossTicks ( channel1 , [ 'a' , 'b' , 'c' ] ) ;
76+ const resIter1Values = await pipe ( resIter1 , asyncIterTake ( 3 ) , asyncIterToArray ) ;
77+ expect ( resIter1Values ) . toStrictEqual ( [
78+ 'a_formatted_1st_time' ,
79+ 'b_formatted_1st_time' ,
80+ 'c_formatted_1st_time' ,
81+ ] ) ;
82+
83+ feedChannelAcrossTicks ( channel2 , [ 'd' , 'e' , 'f' ] ) ;
84+ const resIter2Values = await pipe ( resIter2 , asyncIterTake ( 3 ) , asyncIterToArray ) ;
85+ expect ( resIter2Values ) . toStrictEqual ( [
86+ 'd_formatted_1st_time' ,
87+ 'e_formatted_1st_time' ,
88+ 'f_formatted_1st_time' ,
89+ ] ) ;
90+ }
7891
79- feedChannelAcrossTicks ( channel2 , [ 'd' , 'e' , 'f' ] ) ;
80- const resIter2Values = await pipe ( resIter2 , asyncIterTake ( 3 ) , asyncIterToArray ) ;
92+ renderedHook . rerender ( {
93+ val1 : 'a' ,
94+ val2 : 'b' ,
95+ iter1 : iterateFormatted ( channel1 , v => `${ v } _formatted_2nd_time` ) ,
96+ iter2 : iterateFormatted ( channel2 , v => `${ v } _formatted_2nd_time` ) ,
97+ } ) ;
8198
82- expect ( resIter2Values ) . toStrictEqual ( [
83- 'd_formatted_1st_time' ,
84- 'e_formatted_1st_time' ,
85- 'f_formatted_1st_time' ,
86- ] ) ;
87- }
99+ const hookSecondResult = renderedHook . result . current ;
88100
89- renderedHook . rerender ( {
90- val1 : 'a' ,
91- val2 : 'b' ,
92- iter1 : iterateFormatted ( channel1 , v => `${ v } _formatted_2nd_time` ) ,
93- iter2 : iterateFormatted ( channel2 , v => `${ v } _formatted_2nd_time` ) ,
94- } ) ;
95-
96- const hookSecondResult = renderedHook . result . current ;
97-
98- {
99- expect ( timesRerun ) . toStrictEqual ( 1 ) ;
100- expect ( hookFirstResult ) . toStrictEqual ( hookSecondResult ) ;
101-
102- const [ , , resIter1 , resIter2 ] = hookSecondResult ;
103-
104- feedChannelAcrossTicks ( channel1 , [ 'a' , 'b' , 'c' ] ) ;
105- const resIter1Values = await pipe ( resIter1 , asyncIterTake ( 3 ) , asyncIterToArray ) ;
106- expect ( resIter1Values ) . toStrictEqual ( [
107- 'a_formatted_2nd_time' ,
108- 'b_formatted_2nd_time' ,
109- 'c_formatted_2nd_time' ,
110- ] ) ;
111-
112- feedChannelAcrossTicks ( channel2 , [ 'd' , 'e' , 'f' ] ) ;
113- const resIter2Values = await pipe ( resIter2 , asyncIterTake ( 3 ) , asyncIterToArray ) ;
114- expect ( resIter2Values ) . toStrictEqual ( [
115- 'd_formatted_2nd_time' ,
116- 'e_formatted_2nd_time' ,
117- 'f_formatted_2nd_time' ,
118- ] ) ;
101+ {
102+ expect ( timesRerun ) . toStrictEqual ( 1 ) ;
103+ expect ( hookFirstResult ) . toStrictEqual ( hookSecondResult ) ;
104+
105+ const [ , , resIter1 , resIter2 ] = hookSecondResult ;
106+
107+ feedChannelAcrossTicks ( channel1 , [ 'a' , 'b' , 'c' ] ) ;
108+ const resIter1Values = await pipe ( resIter1 , asyncIterTake ( 3 ) , asyncIterToArray ) ;
109+ expect ( resIter1Values ) . toStrictEqual ( [
110+ 'a_formatted_2nd_time' ,
111+ 'b_formatted_2nd_time' ,
112+ 'c_formatted_2nd_time' ,
113+ ] ) ;
114+
115+ feedChannelAcrossTicks ( channel2 , [ 'd' , 'e' , 'f' ] ) ;
116+ const resIter2Values = await pipe ( resIter2 , asyncIterTake ( 3 ) , asyncIterToArray ) ;
117+ expect ( resIter2Values ) . toStrictEqual ( [
118+ 'd_formatted_2nd_time' ,
119+ 'e_formatted_2nd_time' ,
120+ 'f_formatted_2nd_time' ,
121+ ] ) ;
122+ }
119123 }
120- } ) ;
124+ ) ;
125+
126+ it (
127+ gray (
128+ 'When updated consecutively with formatted iterables of different source iterables each time, will work correctly and re-run factory function'
129+ ) ,
130+ async ( ) => {
131+ const iter1 = asyncIterTickSeparatedOf ( 'a' , 'b' , 'c' ) ;
132+ const iter2 = asyncIterTickSeparatedOf ( 'd' , 'e' , 'f' ) ;
133+ let timesRerun = 0 ;
134+
135+ const renderedHook = renderHook (
136+ ( { val1, val2, iter1, iter2 } ) =>
137+ useAsyncIterMemo (
138+ ( ...deps ) => {
139+ timesRerun ++ ;
140+ return deps ;
141+ } ,
142+ [ val1 , val2 , iter1 , iter2 ]
143+ ) ,
144+ {
145+ initialProps : {
146+ val1 : 'a' ,
147+ val2 : 'b' ,
148+ iter1 : iterateFormatted ( iter1 , v => `${ v } _formatted_1st_time` ) ,
149+ iter2 : iterateFormatted ( iter2 , v => `${ v } _formatted_1st_time` ) ,
150+ } ,
151+ }
152+ ) ;
121153
122- it ( gray ( '___ ___ ___ 3' ) , async ( ) => {
123- const iter1 = asyncIterTickSeparatedOf ( 'a' , 'b' , 'c' ) ;
124- const iter2 = asyncIterTickSeparatedOf ( 'd' , 'e' , 'f' ) ;
125- let timesRerun = 0 ;
154+ const hookFirstResult = renderedHook . result . current ;
126155
127- const renderedHook = renderHook (
128- ( { val1, val2, iter1, iter2 } ) =>
129- useAsyncIterMemo (
130- ( ...deps ) => {
131- timesRerun ++ ;
132- return deps ;
133- } ,
134- [ val1 , val2 , iter1 , iter2 ]
135- ) ,
136156 {
137- initialProps : {
138- val1 : 'a' ,
139- val2 : 'b' ,
140- iter1 : iterateFormatted ( iter1 , v => `${ v } _formatted_1st_time` ) ,
141- iter2 : iterateFormatted ( iter2 , v => `${ v } _formatted_1st_time` ) ,
142- } ,
157+ expect ( timesRerun ) . toStrictEqual ( 1 ) ;
158+
159+ const [ , , resIter1 , resIter2 ] = hookFirstResult ;
160+
161+ const resIter1Values = await pipe ( resIter1 , asyncIterTake ( 3 ) , asyncIterToArray ) ;
162+ expect ( resIter1Values ) . toStrictEqual ( [
163+ 'a_formatted_1st_time' ,
164+ 'b_formatted_1st_time' ,
165+ 'c_formatted_1st_time' ,
166+ ] ) ;
167+
168+ const resIter2Values = await pipe ( resIter2 , asyncIterTake ( 3 ) , asyncIterToArray ) ;
169+ expect ( resIter2Values ) . toStrictEqual ( [
170+ 'd_formatted_1st_time' ,
171+ 'e_formatted_1st_time' ,
172+ 'f_formatted_1st_time' ,
173+ ] ) ;
143174 }
144- ) ;
145-
146- const hookFirstResult = renderedHook . result . current ;
147175
148- {
149- expect ( timesRerun ) . toStrictEqual ( 1 ) ;
176+ const differentIter1 = asyncIterTickSeparatedOf ( 'a' , 'b' , 'c' ) ;
177+ const differentIter2 = asyncIterTickSeparatedOf ( 'd' , 'e' , 'f' ) ;
150178
151- const [ , , resIter1 , resIter2 ] = hookFirstResult ;
179+ renderedHook . rerender ( {
180+ val1 : 'a' ,
181+ val2 : 'b' ,
182+ iter1 : iterateFormatted ( differentIter1 , v => `${ v } _formatted_2nd_time` ) ,
183+ iter2 : iterateFormatted ( differentIter2 , v => `${ v } _formatted_2nd_time` ) ,
184+ } ) ;
152185
153- const resIter1Values = await pipe ( resIter1 , asyncIterTake ( 3 ) , asyncIterToArray ) ;
154- expect ( resIter1Values ) . toStrictEqual ( [
155- 'a_formatted_1st_time' ,
156- 'b_formatted_1st_time' ,
157- 'c_formatted_1st_time' ,
158- ] ) ;
159-
160- const resIter2Values = await pipe ( resIter2 , asyncIterTake ( 3 ) , asyncIterToArray ) ;
161- expect ( resIter2Values ) . toStrictEqual ( [
162- 'd_formatted_1st_time' ,
163- 'e_formatted_1st_time' ,
164- 'f_formatted_1st_time' ,
165- ] ) ;
166- }
186+ const hookSecondResult = renderedHook . result . current ;
167187
168- const differentIter1 = asyncIterTickSeparatedOf ( 'a' , 'b' , 'c' ) ;
169- const differentIter2 = asyncIterTickSeparatedOf ( 'd' , 'e' , 'f' ) ;
170-
171- renderedHook . rerender ( {
172- val1 : 'a' ,
173- val2 : 'b' ,
174- iter1 : iterateFormatted ( differentIter1 , v => `${ v } _formatted_2nd_time` ) ,
175- iter2 : iterateFormatted ( differentIter2 , v => `${ v } _formatted_2nd_time` ) ,
176- } ) ;
177-
178- const hookSecondResult = renderedHook . result . current ;
179-
180- {
181- expect ( timesRerun ) . toStrictEqual ( 2 ) ;
182-
183- expect ( hookFirstResult [ 0 ] ) . toStrictEqual ( hookSecondResult [ 0 ] ) ;
184- expect ( hookFirstResult [ 1 ] ) . toStrictEqual ( hookSecondResult [ 1 ] ) ;
185- expect ( hookFirstResult [ 2 ] ) . not . toStrictEqual ( hookSecondResult [ 2 ] ) ;
186- expect ( hookFirstResult [ 3 ] ) . not . toStrictEqual ( hookSecondResult [ 3 ] ) ;
187-
188- const resIter1Values = await pipe ( hookSecondResult [ 2 ] , asyncIterTake ( 3 ) , asyncIterToArray ) ;
189- expect ( resIter1Values ) . toStrictEqual ( [
190- 'a_formatted_2nd_time' ,
191- 'b_formatted_2nd_time' ,
192- 'c_formatted_2nd_time' ,
193- ] ) ;
194-
195- const resIter2Values = await pipe ( hookSecondResult [ 3 ] , asyncIterTake ( 3 ) , asyncIterToArray ) ;
196- expect ( resIter2Values ) . toStrictEqual ( [
197- 'd_formatted_2nd_time' ,
198- 'e_formatted_2nd_time' ,
199- 'f_formatted_2nd_time' ,
200- ] ) ;
188+ {
189+ expect ( timesRerun ) . toStrictEqual ( 2 ) ;
190+
191+ expect ( hookFirstResult [ 0 ] ) . toStrictEqual ( hookSecondResult [ 0 ] ) ;
192+ expect ( hookFirstResult [ 1 ] ) . toStrictEqual ( hookSecondResult [ 1 ] ) ;
193+ expect ( hookFirstResult [ 2 ] ) . not . toStrictEqual ( hookSecondResult [ 2 ] ) ;
194+ expect ( hookFirstResult [ 3 ] ) . not . toStrictEqual ( hookSecondResult [ 3 ] ) ;
195+
196+ const resIter1Values = await pipe ( hookSecondResult [ 2 ] , asyncIterTake ( 3 ) , asyncIterToArray ) ;
197+ expect ( resIter1Values ) . toStrictEqual ( [
198+ 'a_formatted_2nd_time' ,
199+ 'b_formatted_2nd_time' ,
200+ 'c_formatted_2nd_time' ,
201+ ] ) ;
202+
203+ const resIter2Values = await pipe ( hookSecondResult [ 3 ] , asyncIterTake ( 3 ) , asyncIterToArray ) ;
204+ expect ( resIter2Values ) . toStrictEqual ( [
205+ 'd_formatted_2nd_time' ,
206+ 'e_formatted_2nd_time' ,
207+ 'f_formatted_2nd_time' ,
208+ ] ) ;
209+ }
201210 }
202- } ) ;
211+ ) ;
203212} ) ;
204-
205- async function feedChannelAcrossTicks < const T > (
206- channel : IterableChannelTestHelper < T > ,
207- values : T [ ]
208- ) : Promise < void > {
209- for ( const value of values ) {
210- await new Promise ( resolve => nextTick ( resolve ) ) ;
211- channel . put ( value ) ;
212- }
213- }
0 commit comments