@@ -84,6 +84,7 @@ function describeProps() {
84
84
describeReverseProp ( )
85
85
describeImmediateProp ( )
86
86
describeConfigProp ( )
87
+ describeLoopProp ( )
87
88
}
88
89
89
90
function describeToProp ( ) {
@@ -250,6 +251,106 @@ function describeConfigProp() {
250
251
} )
251
252
}
252
253
254
+ function describeLoopProp ( ) {
255
+ describe ( 'the "loop" prop' , ( ) => {
256
+ beforeEach ( ( ) => jest . useFakeTimers ( ) )
257
+ afterEach ( ( ) => jest . useRealTimers ( ) )
258
+
259
+ it ( 'resets the animation once finished' , async ( ) => {
260
+ const spring = new SpringValue ( 0 )
261
+ spring . start ( 1 , {
262
+ loop : true ,
263
+ config : { duration : frameLength * 3 } ,
264
+ } )
265
+
266
+ await advanceUntilValue ( spring , 1 )
267
+ const firstRun = getFrames ( spring )
268
+ expect ( firstRun ) . toMatchSnapshot ( )
269
+
270
+ // The loop resets the value before the next frame.
271
+ // FIXME: Reset on next frame instead?
272
+ expect ( spring . get ( ) ) . toBe ( 0 )
273
+
274
+ await advanceUntilValue ( spring , 1 )
275
+ expect ( getFrames ( spring ) ) . toEqual ( firstRun )
276
+ } )
277
+
278
+ it ( 'can pass a custom delay' , async ( ) => {
279
+ const spring = new SpringValue ( 0 )
280
+ spring . start ( 1 , { loop : { delay : 1000 } } )
281
+
282
+ await advanceUntilValue ( spring , 1 )
283
+ expect ( spring . get ( ) ) . toBe ( 1 )
284
+
285
+ jest . runAllTimers ( )
286
+ expect ( spring . get ( ) ) . toBe ( 0 )
287
+
288
+ await advanceUntilValue ( spring , 1 )
289
+ expect ( spring . get ( ) ) . toBe ( 1 )
290
+ } )
291
+
292
+ it ( 'supports deferred evaluation' , async ( ) => {
293
+ const spring = new SpringValue ( 0 )
294
+
295
+ let loop : any = true
296
+ spring . start ( 1 , { loop : ( ) => loop } )
297
+
298
+ await advanceUntilValue ( spring , 1 )
299
+ expect ( spring . idle ) . toBeFalsy ( )
300
+ expect ( spring . get ( ) ) . toBe ( 0 )
301
+
302
+ loop = { delay : 1000 }
303
+ await advanceUntilValue ( spring , 1 )
304
+ expect ( spring . idle ) . toBeTruthy ( )
305
+ expect ( spring . get ( ) ) . toBe ( 1 )
306
+
307
+ jest . runAllTimers ( )
308
+ expect ( spring . idle ) . toBeFalsy ( )
309
+ expect ( spring . get ( ) ) . toBe ( 0 )
310
+
311
+ loop = false
312
+ await advanceUntilValue ( spring , 1 )
313
+ expect ( spring . idle ) . toBeTruthy ( )
314
+ expect ( spring . get ( ) ) . toBe ( 1 )
315
+ } )
316
+
317
+ it ( 'does not affect earlier updates' , async ( ) => {
318
+ const spring = new SpringValue ( 0 )
319
+ spring . start ( 1 )
320
+
321
+ await advanceUntilValue ( spring , 0.5 )
322
+ spring . start ( { loop : true } )
323
+
324
+ await advanceUntilValue ( spring , 1 )
325
+ expect ( spring . idle ) . toBeTruthy ( )
326
+ } )
327
+
328
+ it ( 'does not affect later updates' , async ( ) => {
329
+ const spring = new SpringValue ( 0 )
330
+ spring . start ( 1 , { loop : true } )
331
+
332
+ await advanceUntilValue ( spring , 0.5 )
333
+ spring . start ( 2 )
334
+
335
+ await advanceUntilValue ( spring , 2 )
336
+ expect ( spring . idle ) . toBeTruthy ( )
337
+ } )
338
+
339
+ it ( 'can be combined with the "reset" prop' , async ( ) => {
340
+ const spring = new SpringValue ( 0 )
341
+ spring . start ( 1 )
342
+
343
+ await advanceUntilIdle ( )
344
+ spring . start ( { reset : true , loop : true } )
345
+ expect ( spring . get ( ) ) . toBe ( 0 )
346
+
347
+ await advanceUntilValue ( spring , 1 )
348
+ expect ( spring . get ( ) ) . toBe ( 0 )
349
+ expect ( spring . idle ) . toBeFalsy ( )
350
+ } )
351
+ } )
352
+ }
353
+
253
354
function describeMethods ( ) {
254
355
describe ( '"set" method' , ( ) => {
255
356
it ( 'stops the active animation' , async ( ) => {
0 commit comments