1
- import { nextTick } from 'node:process' ;
2
1
import { it , describe , expect , afterEach } from 'vitest' ;
3
2
import { gray } from 'colorette' ;
4
3
import { renderHook , cleanup as cleanupMountedReactTrees } from '@testing-library/react' ;
5
4
import { useAsyncIterMemo , iterateFormatted } from '../libEntrypoint.js' ;
6
5
import { pipe } from '../utils/pipe.js' ;
6
+ import { IterableChannelTestHelper } from '../utils/IterableChannelTestHelper.js' ;
7
+ import { feedChannelAcrossTicks } from '../utils/feedChannelAcrossTicks.js' ;
7
8
import { asyncIterToArray } from '../utils/asyncIterToArray.js' ;
8
9
import { asyncIterTake } from '../utils/asyncIterTake.js' ;
9
10
import { asyncIterOf } from '../utils/asyncIterOf.js' ;
10
11
import { asyncIterTickSeparatedOf } from '../utils/asyncIterTickSeparatedOf.js' ;
11
- import { IterableChannelTestHelper } from '../utils/IterableChannelTestHelper.js' ;
12
12
13
13
afterEach ( ( ) => {
14
14
cleanupMountedReactTrees ( ) ;
15
15
} ) ;
16
16
17
17
describe ( '`useAsyncIterMemo` hook' , ( ) => {
18
- it ( gray ( '___ ___ ___ 1 ' ) , async ( ) => {
18
+ it ( gray ( 'When given mixed iterable and plain values, will work correctly ' ) , async ( ) => {
19
19
const renderedHook = renderHook (
20
20
( { val1, val2, iter1, iter2 } ) =>
21
21
useAsyncIterMemo ( ( ...deps ) => deps , [ val1 , val2 , iter1 , iter2 ] ) ,
@@ -37,177 +37,176 @@ describe('`useAsyncIterMemo` hook', () => {
37
37
expect ( await asyncIterToArray ( resIter2 ) ) . toStrictEqual ( [ 'd' , 'e' , 'f' ] ) ;
38
38
} ) ;
39
39
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` ) ,
51
64
} ,
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
+ ) ;
68
67
69
- const [ , , resIter1 , resIter2 ] = hookFirstResult ;
68
+ const hookFirstResult = renderedHook . result . current ;
70
69
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
+ }
78
91
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
+ } ) ;
81
98
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 ;
88
100
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
+ }
119
123
}
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
+ ) ;
121
153
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 ;
126
155
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
- ) ,
136
156
{
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
+ ] ) ;
143
174
}
144
- ) ;
145
-
146
- const hookFirstResult = renderedHook . result . current ;
147
175
148
- {
149
- expect ( timesRerun ) . toStrictEqual ( 1 ) ;
176
+ const differentIter1 = asyncIterTickSeparatedOf ( 'a' , 'b' , 'c' ) ;
177
+ const differentIter2 = asyncIterTickSeparatedOf ( 'd' , 'e' , 'f' ) ;
150
178
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
+ } ) ;
152
185
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 ;
167
187
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
+ }
201
210
}
202
- } ) ;
211
+ ) ;
203
212
} ) ;
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