@@ -6,6 +6,12 @@ const { describe, test } = require('node:test')
6
6
const timers = require ( '../lib/util/timers' )
7
7
const { eventLoopBlocker } = require ( './utils/event-loop-blocker' )
8
8
9
+ // timers.setTimeout implements a low resolution timer with a 500 ms granularity
10
+ // It is expected that in the worst case, a timer will fire about 500 ms after the
11
+ // intended amount of time, an extra 200 ms is added to account event loop overhead
12
+ // Timers should never fire excessively early, 1ms early is tolerated
13
+ const ACCEPTABLE_DELTA = 700n
14
+
9
15
describe ( 'timers' , ( ) => {
10
16
test ( 'timers exports a clearTimeout' , ( t ) => {
11
17
t = tspl ( t , { plan : 1 } )
@@ -26,7 +32,7 @@ describe('timers', () => {
26
32
t . strictEqual ( timers . setTimeout ( ( ) => { } , 1e3 ) [ timers . kFastTimer ] , undefined )
27
33
} )
28
34
29
- test ( 'setTimeout instantiates a FastTimer when delay is smaller than 1e3 ms' , ( t ) => {
35
+ test ( 'setTimeout instantiates a FastTimer when delay is bigger than 1e3 ms' , ( t ) => {
30
36
t = tspl ( t , { plan : 1 } )
31
37
32
38
const timeout = timers . setTimeout ( ( ) => { } , 1001 )
@@ -51,7 +57,8 @@ describe('timers', () => {
51
57
52
58
t . strictEqual ( timer [ timers . kFastTimer ] , true )
53
59
t . strictEqual ( timer . _idleStart , - 1 )
54
- await new Promise ( ( resolve ) => setTimeout ( resolve , 750 ) )
60
+
61
+ timers . tick ( 750 )
55
62
t . notStrictEqual ( timer . _idleStart , - 1 )
56
63
57
64
timers . clearTimeout ( timer )
@@ -66,7 +73,7 @@ describe('timers', () => {
66
73
67
74
t . strictEqual ( timer [ timers . kFastTimer ] , true )
68
75
t . strictEqual ( timer . _idleStart , - 1 )
69
- await new Promise ( ( resolve ) => setTimeout ( resolve , 750 ) )
76
+ timers . tick ( 750 )
70
77
t . notStrictEqual ( timer . _idleStart , - 1 )
71
78
timers . clearTimeout ( timer )
72
79
t . strictEqual ( timer . _idleStart , - 1 )
@@ -83,21 +90,22 @@ describe('timers', () => {
83
90
timers . clearTimeout ( timer )
84
91
85
92
t . strictEqual ( timer . _idleStart , - 1 )
86
- await new Promise ( ( resolve ) => setTimeout ( resolve , 750 ) )
93
+ timers . tick ( 750 )
87
94
t . strictEqual ( timer . _idleStart , - 1 )
88
95
} )
89
96
90
97
test ( 'a cleared FastTimer can be refreshed' , async ( t ) => {
91
98
t = tspl ( t , { plan : 2 } )
92
99
93
- const timer = timers . setTimeout ( ( ) => {
100
+ const timer = timers . setFastTimeout ( ( ) => {
94
101
t . ok ( 'pass' )
95
102
} , 1001 )
96
103
97
104
t . strictEqual ( timer [ timers . kFastTimer ] , true )
98
105
timers . clearTimeout ( timer )
99
106
timer . refresh ( )
100
- await new Promise ( ( resolve ) => setTimeout ( resolve , 2000 ) )
107
+ timers . tick ( 500 )
108
+ timers . tick ( 1000 )
101
109
timers . clearTimeout ( timer )
102
110
} )
103
111
@@ -107,50 +115,24 @@ describe('timers', () => {
107
115
return actual - BigInt ( target )
108
116
}
109
117
110
- // timers.setTimeout implements a low resolution timer with a 500 ms granularity
111
- // It is expected that in the worst case, a timer will fire about 500 ms after the
112
- // intended amount of time, an extra 200 ms is added to account event loop overhead
113
- // Timers should never fire excessively early, 1ms early is tolerated
114
- const ACCEPTABLE_DELTA = 700n
115
-
116
- test ( 'meet acceptable resolution time' , async ( t ) => {
117
- const testTimeouts = [ 0 , 1 , 499 , 500 , 501 , 990 , 999 , 1000 , 1001 , 1100 , 1400 , 1499 , 1500 , 4000 , 5000 ]
118
-
119
- t = tspl ( t , { plan : 1 + testTimeouts . length * 2 } )
120
-
121
- const start = process . hrtime . bigint ( )
122
-
123
- for ( const target of testTimeouts ) {
124
- timers . setTimeout ( ( ) => {
125
- const delta = getDelta ( start , target )
126
-
127
- t . ok ( delta >= - 1n , `${ target } ms fired early` )
128
- t . ok ( delta < ACCEPTABLE_DELTA , `${ target } ms fired late, got difference of ${ delta } ms` )
129
- } , target )
130
- }
131
-
132
- setTimeout ( ( ) => t . ok ( true ) , 6000 )
133
- await t . completed
134
- } )
135
-
136
118
test ( 'refresh correctly with timeout < TICK_MS' , async ( t ) => {
137
119
t = tspl ( t , { plan : 3 } )
138
120
139
121
const start = process . hrtime . bigint ( )
140
122
141
123
const timeout = timers . setTimeout ( ( ) => {
142
- // 400 ms timer was refreshed after 600ms ; total target is 1000
143
- const delta = getDelta ( start , 1000 )
124
+ // 80 ms timer was refreshed after 120 ms ; total target is 200 ms
125
+ const delta = getDelta ( start , 200 )
144
126
145
127
t . ok ( delta >= - 1n , 'refreshed timer fired early' )
146
128
t . ok ( delta < ACCEPTABLE_DELTA , 'refreshed timer fired late' )
147
- } , 400 )
129
+ } , 80 )
148
130
149
- setTimeout ( ( ) => timeout . refresh ( ) , 200 )
150
- setTimeout ( ( ) => timeout . refresh ( ) , 400 )
151
- setTimeout ( ( ) => timeout . refresh ( ) , 600 )
131
+ setTimeout ( ( ) => timeout . refresh ( ) , 40 )
132
+ setTimeout ( ( ) => timeout . refresh ( ) , 80 )
133
+ setTimeout ( ( ) => timeout . refresh ( ) , 120 )
152
134
153
- setTimeout ( ( ) => t . ok ( true ) , 1500 )
135
+ setTimeout ( ( ) => t . ok ( true ) , 260 )
154
136
await t . completed
155
137
} )
156
138
@@ -171,7 +153,42 @@ describe('timers', () => {
171
153
setTimeout ( ( ) => timeout . refresh ( ) , 750 )
172
154
setTimeout ( ( ) => timeout . refresh ( ) , 1250 )
173
155
174
- setTimeout ( ( ) => t . ok ( true ) , 3000 )
156
+ setTimeout ( ( ) => t . ok ( true ) , 1800 )
157
+ await t . completed
158
+ } )
159
+
160
+ test ( 'refresh correctly FastTimer with timeout > TICK_MS' , async ( t ) => {
161
+ t = tspl ( t , { plan : 3 } )
162
+
163
+ // The long running FastTimer will ensure that the internal clock is
164
+ // incremented by the TICK_MS value in the onTick function
165
+ const longRunningFastTimer = timers . setTimeout ( ( ) => { } , 1e10 )
166
+
167
+ const start = timers . now ( )
168
+
169
+ const timeout = timers . setFastTimeout ( ( ) => {
170
+ const delta = ( timers . now ( ) - start ) - 2493
171
+
172
+ t . ok ( delta >= - 1n , `refreshed timer fired early (${ delta } ms)` )
173
+ t . ok ( delta < ACCEPTABLE_DELTA , `refreshed timer fired late (${ delta } ms)` )
174
+ } , 1001 )
175
+
176
+ timers . tick ( 250 )
177
+ timeout . refresh ( )
178
+
179
+ timers . tick ( 250 )
180
+ timeout . refresh ( )
181
+
182
+ timers . tick ( 250 )
183
+ timeout . refresh ( )
184
+
185
+ timers . tick ( 250 )
186
+ timeout . refresh ( )
187
+
188
+ timers . tick ( 1000 )
189
+
190
+ timers . clearTimeout ( longRunningFastTimer )
191
+ setTimeout ( ( ) => t . ok ( true ) , 500 )
175
192
await t . completed
176
193
} )
177
194
@@ -190,8 +207,8 @@ describe('timers', () => {
190
207
await new Promise ( ( resolve ) => setTimeout ( resolve , 1 ) )
191
208
192
209
t . strictEqual ( timers . now ( ) - startInternalClock , 499 )
193
- await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) )
194
- t . ok ( timers . now ( ) - startInternalClock <= 1497 )
210
+ timers . tick ( 1000 )
211
+ t . ok ( timers . now ( ) - startInternalClock <= 1588 )
195
212
196
213
timers . clearTimeout ( longRunningFastTimer )
197
214
} )
0 commit comments