@@ -2,6 +2,8 @@ import { renderHook, act } from '@testing-library/react-hooks';
22import { TestUtils } from '@deephaven/utils' ;
33import useAsyncInterval from './useAsyncInterval' ;
44
5+ const { asMock } = TestUtils ;
6+
57beforeEach ( ( ) => {
68 jest . clearAllMocks ( ) ;
79 expect . hasAssertions ( ) ;
@@ -15,31 +17,43 @@ afterAll(() => {
1517
1618describe ( 'useAsyncInterval' , ( ) => {
1719 function createCallback ( ms : number ) {
18- return jest . fn (
19- async ( ) : Promise < void > =>
20- new Promise ( resolve => {
21- setTimeout ( resolve , ms ) ;
22- } )
23- ) ;
20+ return jest
21+ . fn (
22+ async ( ) : Promise < void > =>
23+ new Promise ( resolve => {
24+ setTimeout ( resolve , ms ) ;
25+
26+ // Don't track the above call to `setTimeout`
27+ asMock ( setTimeout ) . mock . calls . pop ( ) ;
28+ } )
29+ )
30+ . mockName ( 'callback' ) ;
2431 }
2532
2633 const targetIntervalMs = 1000 ;
2734
28- it ( 'should call the callback function after the target interval' , async ( ) => {
29- const callback = createCallback ( 50 ) ;
30-
31- renderHook ( ( ) => useAsyncInterval ( callback , targetIntervalMs ) ) ;
35+ it ( 'should call the callback function immediately any time the callback or target interval changes' , ( ) => {
36+ const callbackA = createCallback ( 50 ) ;
37+ const callbackB = createCallback ( 50 ) ;
3238
33- // First tick should be scheduled for target interval
34- expect ( callback ) . not . toHaveBeenCalled ( ) ;
35- expect ( window . setTimeout ) . toHaveBeenCalledWith (
36- expect . any ( Function ) ,
37- targetIntervalMs
39+ const { rerender } = renderHook (
40+ ( [ cb , target ] : [ ( ) => Promise < void > , number ] ) =>
41+ useAsyncInterval ( cb , target ) ,
42+ {
43+ initialProps : [ callbackA , targetIntervalMs ] ,
44+ }
3845 ) ;
3946
40- // Callback should be called after target interval
41- act ( ( ) => jest . advanceTimersByTime ( targetIntervalMs ) ) ;
42- expect ( callback ) . toHaveBeenCalledTimes ( 1 ) ;
47+ expect ( callbackA ) . toHaveBeenCalledTimes ( 1 ) ;
48+ jest . clearAllMocks ( ) ;
49+
50+ rerender ( [ callbackB , targetIntervalMs ] ) ;
51+ expect ( callbackA ) . not . toHaveBeenCalled ( ) ;
52+ expect ( callbackB ) . toHaveBeenCalledTimes ( 1 ) ;
53+ jest . clearAllMocks ( ) ;
54+
55+ rerender ( [ callbackB , targetIntervalMs + 20 ] ) ;
56+ expect ( callbackB ) . toHaveBeenCalledTimes ( 1 ) ;
4357 } ) ;
4458
4559 it ( 'should adjust the target interval based on how long async call takes' , async ( ) => {
@@ -48,11 +62,8 @@ describe('useAsyncInterval', () => {
4862
4963 renderHook ( ( ) => useAsyncInterval ( callback , targetIntervalMs ) ) ;
5064
51- // Callback should be called after target interval
52- expect ( callback ) . not . toHaveBeenCalled ( ) ;
53- act ( ( ) => jest . advanceTimersByTime ( targetIntervalMs ) ) ;
5465 expect ( callback ) . toHaveBeenCalledTimes ( 1 ) ;
55-
66+ expect ( window . setTimeout ) . not . toHaveBeenCalled ( ) ;
5667 jest . clearAllMocks ( ) ;
5768
5869 // Mimick the callback Promise resolving
@@ -79,11 +90,7 @@ describe('useAsyncInterval', () => {
7990
8091 renderHook ( ( ) => useAsyncInterval ( callback , targetIntervalMs ) ) ;
8192
82- // Callback should be called after target interval
83- expect ( callback ) . not . toHaveBeenCalled ( ) ;
84- act ( ( ) => jest . advanceTimersByTime ( targetIntervalMs ) ) ;
8593 expect ( callback ) . toHaveBeenCalledTimes ( 1 ) ;
86-
8794 jest . clearAllMocks ( ) ;
8895
8996 // Mimick the callback Promise resolving
@@ -99,12 +106,22 @@ describe('useAsyncInterval', () => {
99106 } ) ;
100107
101108 it ( 'should stop calling the callback function after unmounting' , async ( ) => {
102- const callback = createCallback ( 50 ) ;
109+ const callbackDelayMs = 50 ;
110+ const callback = createCallback ( callbackDelayMs ) ;
103111
104112 const { unmount } = renderHook ( ( ) =>
105113 useAsyncInterval ( callback , targetIntervalMs )
106114 ) ;
107115
116+ expect ( callback ) . toHaveBeenCalledTimes ( 1 ) ;
117+ jest . clearAllMocks ( ) ;
118+
119+ // Mimick the callback Promise resolving
120+ act ( ( ) => jest . advanceTimersByTime ( callbackDelayMs ) ) ;
121+ await TestUtils . flushPromises ( ) ;
122+
123+ expect ( window . setTimeout ) . toHaveBeenCalledTimes ( 1 ) ;
124+
108125 unmount ( ) ;
109126
110127 act ( ( ) => jest . advanceTimersByTime ( targetIntervalMs ) ) ;
@@ -120,7 +137,6 @@ describe('useAsyncInterval', () => {
120137 useAsyncInterval ( callback , targetIntervalMs )
121138 ) ;
122139
123- act ( ( ) => jest . advanceTimersByTime ( targetIntervalMs ) ) ;
124140 expect ( callback ) . toHaveBeenCalledTimes ( 1 ) ;
125141 jest . clearAllMocks ( ) ;
126142
0 commit comments