@@ -3,8 +3,35 @@ import { expect, test } from '@jest/globals'
3
3
import findIndex from './findIndex.mjs'
4
4
import Deferred from './Deferred.mjs'
5
5
import { range } from 'itertools'
6
+ import delay from './delay.mjs'
6
7
7
- test ( 'findIndex' , async ( ) => {
8
+ test ( 'findIndex compatibility' , async ( ) => {
9
+ let d = new Deferred ( )
10
+ let p = findIndex ( [ ...range ( 3 ) ] , async ( v ) => {
11
+ await d . promise
12
+ return v === 2
13
+ } , 1 )
14
+ d . resolve ( )
15
+ expect ( await p ) . toBe ( [ ...range ( 3 ) ] . findIndex ( ( v ) => v === 2 ) )
16
+
17
+ d = new Deferred ( )
18
+ p = findIndex ( [ ...range ( 3 ) ] , async ( v ) => {
19
+ await d . promise
20
+ return v === 5
21
+ } , 1 )
22
+ d . resolve ( )
23
+ expect ( await p ) . toBe ( [ ...range ( 3 ) ] . findIndex ( ( v ) => v === 5 ) )
24
+
25
+ d = new Deferred ( )
26
+ p = findIndex ( [ ] , async ( v ) => {
27
+ await d . promise
28
+ return v === 5
29
+ } , 1 )
30
+ d . resolve ( )
31
+ expect ( await p ) . toBe ( [ ] . findIndex ( ( v ) => v === 5 ) )
32
+ } )
33
+
34
+ test ( 'findIndex cancel subsequent' , async ( ) => {
8
35
const callCount = { }
9
36
; [ ...range ( 3 ) ] . forEach ( ( i ) => { callCount [ i ] = 0 } )
10
37
const d = new Deferred ( )
@@ -14,7 +41,157 @@ test('findIndex', async () => {
14
41
ds [ i ] . resolve ( )
15
42
await d . promise
16
43
return v === 0
17
- } )
44
+ } , 1 )
45
+ await ds [ 0 ] . promise
46
+ expect ( callCount [ 0 ] ) . toBe ( 1 )
47
+ expect ( callCount [ 1 ] ) . toBe ( 0 )
48
+ expect ( callCount [ 2 ] ) . toBe ( 0 )
49
+ d . resolve ( )
50
+ await delay ( )
51
+ const res = await p
52
+ expect ( res ) . toBe ( 0 )
53
+ expect ( callCount [ 0 ] ) . toBe ( 1 )
54
+ expect ( callCount [ 1 ] ) . toBe ( 0 )
55
+ expect ( callCount [ 2 ] ) . toBe ( 0 )
56
+ } )
57
+
58
+ test ( 'findIndex cancel subsequent 2' , async ( ) => {
59
+ const callCount = { }
60
+ ; [ ...range ( 6 ) ] . forEach ( ( i ) => { callCount [ i ] = 0 } )
61
+ const d = new Deferred ( )
62
+ const ds = [ ...range ( 3 ) ] . map ( ( ) => new Deferred ( ) )
63
+ const p = findIndex ( [ ...range ( 6 ) ] , async ( v , i ) => {
64
+ callCount [ i ] += 1
65
+ ds [ i ] . resolve ( )
66
+ await d . promise
67
+ return v === 0
68
+ } , 2 )
69
+ await ds [ 1 ] . promise
70
+ expect ( callCount [ 0 ] ) . toBe ( 1 )
71
+ expect ( callCount [ 1 ] ) . toBe ( 1 )
72
+ expect ( callCount [ 2 ] ) . toBe ( 0 )
73
+ expect ( callCount [ 3 ] ) . toBe ( 0 )
74
+ expect ( callCount [ 4 ] ) . toBe ( 0 )
75
+ expect ( callCount [ 5 ] ) . toBe ( 0 )
76
+ d . resolve ( )
77
+ await delay ( )
78
+ const res = await p
79
+ expect ( res === 0 || res === 1 ) . toBe ( true )
80
+ expect ( callCount [ 0 ] ) . toBe ( 1 )
81
+ expect ( callCount [ 1 ] ) . toBe ( 1 )
82
+ expect ( callCount [ 2 ] ) . toBe ( 0 )
83
+ expect ( callCount [ 3 ] ) . toBe ( 0 )
84
+ expect ( callCount [ 4 ] ) . toBe ( 0 )
85
+ expect ( callCount [ 5 ] ) . toBe ( 0 )
86
+ } )
87
+
88
+ test ( 'findIndex find first in order' , async ( ) => {
89
+ const arr = [ 0 , 1 , 0 ]
90
+ let d1 = new Deferred ( )
91
+ let d2 = new Deferred ( )
92
+ let p = findIndex ( arr , async ( v , index ) => {
93
+ if ( index === 0 ) {
94
+ await d1 . promise
95
+ } else {
96
+ await d2 . promise
97
+ }
98
+ return v === 0
99
+ } , 3 , true )
100
+ d1 . resolve ( )
101
+ await delay ( )
102
+ d2 . resolve ( )
103
+ let res = await p
104
+ expect ( res ) . toBe ( 0 )
105
+ d2 . resolve ( )
106
+
107
+ d1 = new Deferred ( )
108
+ d2 = new Deferred ( )
109
+ p = findIndex ( arr , async ( v , index ) => {
110
+ if ( index === 0 ) {
111
+ await d1 . promise
112
+ } else {
113
+ await d2 . promise
114
+ }
115
+ return v === 0
116
+ } , 3 , true )
117
+ d2 . resolve ( )
118
+ await delay ( )
119
+ d1 . resolve ( )
120
+ res = await p
121
+ expect ( res ) . toBe ( 0 )
122
+ d1 . resolve ( )
123
+ } )
124
+
125
+ test ( 'findIndex error' , async ( ) => {
126
+ const arr = [ 0 , 1 , 2 ]
127
+ try {
128
+ const d = new Deferred ( )
129
+ const p = findIndex ( arr , async ( v , index ) => {
130
+ if ( index === 1 ) {
131
+ throw new Error ( 'test' )
132
+ } else {
133
+ await d . promise
134
+ }
135
+ return v === 2
136
+ } , 3 )
137
+ d . resolve ( )
138
+ await p
139
+ expect ( false ) . toBe ( true )
140
+ } catch ( e ) {
141
+ expect ( e . message ) . toBe ( 'test' )
142
+ }
143
+ } )
144
+
145
+ test ( 'findIndex error after completion' , async ( ) => {
146
+ const arr = [ 0 , 1 ]
147
+ const d1 = new Deferred ( )
148
+ const d2 = new Deferred ( )
149
+ const p = findIndex ( arr , async ( v , index ) => {
150
+ if ( index === 0 ) {
151
+ await d1 . promise
152
+ return true
153
+ } else {
154
+ await d2 . promise
155
+ throw new Error ( 'should be ignored' )
156
+ }
157
+ } , 2 )
158
+ d1 . resolve ( )
159
+ d2 . resolve ( )
160
+ const res = await p
161
+ expect ( res ) . toBe ( 0 )
162
+ } )
163
+
164
+ test ( 'findIndex concurrency' , async ( ) => {
165
+ const callCount = { }
166
+ ; [ ...range ( 3 ) ] . forEach ( ( i ) => { callCount [ i ] = 0 } )
167
+ const d = new Deferred ( )
168
+ const ds = [ ...range ( 3 ) ] . map ( ( ) => new Deferred ( ) )
169
+ const p = findIndex ( [ ...range ( 10 ) ] , async ( v , i ) => {
170
+ callCount [ i ] += 1
171
+ ds [ i ] . resolve ( )
172
+ await d . promise
173
+ return v === 1
174
+ } , 3 )
175
+ await delay ( )
176
+ expect ( callCount [ 0 ] ) . toBe ( 1 )
177
+ expect ( callCount [ 1 ] ) . toBe ( 1 )
178
+ expect ( callCount [ 2 ] ) . toBe ( 1 )
179
+ d . resolve ( )
180
+ const res = await p
181
+ expect ( res ) . toBe ( 1 )
182
+ } )
183
+
184
+ test ( 'findIndex infinite concurrency' , async ( ) => {
185
+ const callCount = { }
186
+ ; [ ...range ( 3 ) ] . forEach ( ( i ) => { callCount [ i ] = 0 } )
187
+ const d = new Deferred ( )
188
+ const ds = [ ...range ( 3 ) ] . map ( ( ) => new Deferred ( ) )
189
+ const p = findIndex ( [ ...range ( 3 ) ] , async ( v , i ) => {
190
+ callCount [ i ] += 1
191
+ ds [ i ] . resolve ( )
192
+ await d . promise
193
+ return v === 0
194
+ } , Number . POSITIVE_INFINITY )
18
195
await ds [ 2 ] . promise
19
196
expect ( callCount [ 0 ] ) . toBe ( 1 )
20
197
expect ( callCount [ 1 ] ) . toBe ( 1 )
@@ -26,3 +203,71 @@ test('findIndex', async () => {
26
203
expect ( callCount [ 1 ] ) . toBe ( 1 )
27
204
expect ( callCount [ 2 ] ) . toBe ( 1 )
28
205
} )
206
+
207
+ test ( 'findIndex concurrency 1' , async ( ) => {
208
+ const callCount = { }
209
+ ; [ ...range ( 3 ) ] . forEach ( ( i ) => { callCount [ i ] = 0 } )
210
+ const d = new Deferred ( )
211
+ const ds = [ ...range ( 3 ) ] . map ( ( ) => new Deferred ( ) )
212
+ const p = findIndex ( [ ...range ( 3 ) ] , async ( v , i ) => {
213
+ callCount [ i ] += 1
214
+ ds [ i ] . resolve ( )
215
+ await d . promise
216
+ return v === 0
217
+ } )
218
+ await ds [ 0 ] . promise
219
+ expect ( callCount [ 0 ] ) . toBe ( 1 )
220
+ expect ( callCount [ 1 ] ) . toBe ( 0 )
221
+ expect ( callCount [ 2 ] ) . toBe ( 0 )
222
+ d . resolve ( )
223
+ const res = await p
224
+ expect ( res ) . toBe ( 0 )
225
+ expect ( callCount [ 0 ] ) . toBe ( 1 )
226
+ expect ( callCount [ 1 ] ) . toBe ( 0 )
227
+ expect ( callCount [ 2 ] ) . toBe ( 0 )
228
+ } )
229
+
230
+ test ( 'findIndex concurrency 1 ordered' , async ( ) => {
231
+ const callCount = { }
232
+ ; [ ...range ( 3 ) ] . forEach ( ( i ) => { callCount [ i ] = 0 } )
233
+ const d = new Deferred ( )
234
+ const ds = [ ...range ( 3 ) ] . map ( ( ) => new Deferred ( ) )
235
+ const p = findIndex ( [ ...range ( 3 ) ] , async ( v , i ) => {
236
+ callCount [ i ] += 1
237
+ ds [ i ] . resolve ( )
238
+ if ( i === 0 ) {
239
+ await d . promise
240
+ }
241
+ return true
242
+ } )
243
+ await ds [ 0 ] . promise
244
+ expect ( callCount [ 0 ] ) . toBe ( 1 )
245
+ expect ( callCount [ 1 ] ) . toBe ( 0 )
246
+ expect ( callCount [ 2 ] ) . toBe ( 0 )
247
+ d . resolve ( )
248
+ const res = await p
249
+ expect ( res ) . toBe ( 0 )
250
+ expect ( callCount [ 0 ] ) . toBe ( 1 )
251
+ expect ( callCount [ 1 ] ) . toBe ( 0 )
252
+ expect ( callCount [ 2 ] ) . toBe ( 0 )
253
+ } )
254
+
255
+ test ( 'findIndex concurrency 1 error' , async ( ) => {
256
+ const callCount = { }
257
+ ; [ ...range ( 3 ) ] . forEach ( ( i ) => { callCount [ i ] = 0 } )
258
+ try {
259
+ await findIndex ( [ ...range ( 3 ) ] , async ( v , i ) => {
260
+ callCount [ i ] += 1
261
+ if ( i === 0 ) {
262
+ throw new Error ( 'test' )
263
+ }
264
+ return true
265
+ } )
266
+ expect ( true ) . toBe ( false )
267
+ } catch ( e ) {
268
+ expect ( e . message ) . toBe ( 'test' )
269
+ }
270
+ expect ( callCount [ 0 ] ) . toBe ( 1 )
271
+ expect ( callCount [ 1 ] ) . toBe ( 0 )
272
+ expect ( callCount [ 2 ] ) . toBe ( 0 )
273
+ } )
0 commit comments