@@ -298,6 +298,22 @@ describe('option control', () => {
298298 } ) ;
299299 } ) ;
300300
301+ it ( 'rolls back controlled options on second timer (to account for async React 18+ updates)' , ( ) => {
302+ render (
303+ < ControlledComponent everyOption = { 123 } /> ,
304+ ) ;
305+
306+ fireOptionChange ( 'everyOption' , 234 ) ;
307+ jest . runOnlyPendingTimers ( ) ;
308+
309+ expect ( Widget . option . mock . calls . length ) . toBe ( 0 ) ;
310+
311+ jest . runAllTimers ( ) ;
312+
313+ expect ( Widget . option . mock . calls . length ) . toBe ( 1 ) ;
314+ expect ( Widget . option . mock . calls [ 0 ] ) . toEqual ( [ 'everyOption' , 123 ] ) ;
315+ } ) ;
316+
301317 it ( 'rolls back controlled complex option' , ( ) => {
302318 render (
303319 < ControlledComponent complexOption = { { a : 123 , b : 234 } } /> ,
@@ -412,6 +428,25 @@ describe('option control', () => {
412428 expect ( Widget . option . mock . calls [ 0 ] ) . toEqual ( [ 'everyOption' , 234 ] ) ;
413429 } ) ;
414430
431+ it ( 'applies option change with async React 18+ update' , ( ) => {
432+ const { rerender } = render (
433+ < ControlledComponent everyOption = { 123 } /> ,
434+ ) ;
435+
436+ fireOptionChange ( 'everyOption' , 234 ) ;
437+
438+ jest . runOnlyPendingTimers ( ) ;
439+ expect ( Widget . option . mock . calls . length ) . toBe ( 0 ) ;
440+
441+ rerender (
442+ < ControlledComponent everyOption = { 234 } /> ,
443+ ) ;
444+
445+ jest . runAllTimers ( ) ;
446+ expect ( Widget . option . mock . calls . length ) . toBe ( 1 ) ;
447+ expect ( Widget . option . mock . calls [ 0 ] ) . toEqual ( [ 'everyOption' , 234 ] ) ;
448+ } ) ;
449+
415450 it ( 'applies complex option change' , ( ) => {
416451 const { rerender } = render (
417452 < ControlledComponent complexOption = { { a : 123 } } /> ,
0 commit comments