@@ -86,3 +86,169 @@ t.test("should allow requests for different keys independently", async (t) => {
8686 `Request ${ maxAmount + 1 } for key2 should not be allowed`
8787 ) ;
8888} ) ;
89+
90+ t . test ( "should handle TTL expiration" , async ( t ) => {
91+ const limiter = new RateLimiter ( maxAmount , ttl ) ;
92+ for ( let i = 0 ; i < maxAmount ; i ++ ) {
93+ limiter . isAllowed ( key , ttl , maxAmount ) ;
94+ }
95+
96+ clock . tick ( ttl + 1 ) ;
97+
98+ t . ok (
99+ limiter . isAllowed ( key , ttl , maxAmount ) ,
100+ `Request after TTL should be allowed`
101+ ) ;
102+ } ) ;
103+
104+ t . test ( "should allow requests exactly at limit" , async ( t ) => {
105+ const limiter = new RateLimiter ( maxAmount , ttl ) ;
106+ for ( let i = 0 ; i < maxAmount ; i ++ ) {
107+ t . ok (
108+ limiter . isAllowed ( key , ttl , maxAmount ) ,
109+ `Request ${ i + 1 } should be allowed`
110+ ) ;
111+ }
112+ t . notOk (
113+ limiter . isAllowed ( key , ttl , maxAmount ) ,
114+ `Request ${ maxAmount + 1 } should not be allowed`
115+ ) ;
116+ } ) ;
117+
118+ t . test ( "should handle multiple rapid requests" , async ( t ) => {
119+ const limiter = new RateLimiter ( maxAmount , ttl ) ;
120+ for ( let i = 0 ; i < maxAmount ; i ++ ) {
121+ t . ok (
122+ limiter . isAllowed ( key , ttl , maxAmount ) ,
123+ `Request ${ i + 1 } should be allowed`
124+ ) ;
125+ }
126+
127+ clock . tick ( 100 ) ;
128+
129+ t . notOk (
130+ limiter . isAllowed ( key , ttl , maxAmount ) ,
131+ `Request ${ maxAmount + 1 } should not be allowed`
132+ ) ;
133+ } ) ;
134+
135+ t . test ( "should handle different window sizes" , async ( t ) => {
136+ const limiter = new RateLimiter ( maxAmount , ttl ) ;
137+ const differentWindowSize = 1000 ; // 1 second window
138+ for ( let i = 0 ; i < maxAmount ; i ++ ) {
139+ t . ok (
140+ limiter . isAllowed ( key , differentWindowSize , maxAmount ) ,
141+ `Request ${ i + 1 } should be allowed`
142+ ) ;
143+ }
144+ t . notOk (
145+ limiter . isAllowed ( key , differentWindowSize , maxAmount ) ,
146+ `Request ${ maxAmount + 1 } should not be allowed`
147+ ) ;
148+ } ) ;
149+
150+ t . test ( "should handle sliding window with intermittent requests" , async ( t ) => {
151+ const limiter = new RateLimiter ( maxAmount , ttl ) ;
152+ for ( let i = 0 ; i < maxAmount ; i ++ ) {
153+ t . ok (
154+ limiter . isAllowed ( key , ttl , maxAmount ) ,
155+ `Request ${ i + 1 } should be allowed`
156+ ) ;
157+ clock . tick ( 100 ) ;
158+ }
159+
160+ clock . tick ( ttl + 1 ) ;
161+
162+ t . ok (
163+ limiter . isAllowed ( key , ttl , maxAmount ) ,
164+ `Request after sliding window should be allowed`
165+ ) ;
166+ } ) ;
167+
168+ t . test ( "should handle sliding window edge case" , async ( t ) => {
169+ const limiter = new RateLimiter ( maxAmount , ttl ) ;
170+ for ( let i = 0 ; i < maxAmount ; i ++ ) {
171+ t . ok (
172+ limiter . isAllowed ( key , ttl , maxAmount ) ,
173+ `Request ${ i + 1 } should be allowed`
174+ ) ;
175+ }
176+
177+ clock . tick ( ttl + 1 ) ;
178+
179+ t . ok (
180+ limiter . isAllowed ( key , ttl , maxAmount ) ,
181+ `Request after sliding window should be allowed`
182+ ) ;
183+
184+ clock . tick ( ttl + 1 ) ;
185+
186+ t . ok (
187+ limiter . isAllowed ( key , ttl , maxAmount ) ,
188+ `Request after sliding window should be allowed`
189+ ) ;
190+ } ) ;
191+
192+ t . test ( "should handle sliding window with delayed requests" , async ( t ) => {
193+ const limiter = new RateLimiter ( maxAmount , ttl ) ;
194+ for ( let i = 0 ; i < maxAmount ; i ++ ) {
195+ t . ok (
196+ limiter . isAllowed ( key , ttl , maxAmount ) ,
197+ `Request ${ i + 1 } should be allowed`
198+ ) ;
199+ clock . tick ( 100 ) ;
200+ }
201+
202+ clock . tick ( ttl + 1 ) ;
203+
204+ t . ok (
205+ limiter . isAllowed ( key , ttl , maxAmount ) ,
206+ `Request after sliding window should be allowed`
207+ ) ;
208+ } ) ;
209+
210+ t . test ( "should handle sliding window with burst requests" , async ( t ) => {
211+ const limiter = new RateLimiter ( maxAmount , ttl ) ;
212+ for ( let i = 0 ; i < maxAmount ; i ++ ) {
213+ t . ok (
214+ limiter . isAllowed ( key , ttl , maxAmount ) ,
215+ `Request ${ i + 1 } should be allowed`
216+ ) ;
217+ }
218+
219+ clock . tick ( ttl / 2 + 1 ) ;
220+
221+ t . notOk (
222+ limiter . isAllowed ( key , ttl , maxAmount ) ,
223+ `Request ${ maxAmount + 1 } should not be allowed`
224+ ) ;
225+ t . notOk (
226+ limiter . isAllowed ( key , ttl , maxAmount ) ,
227+ `Request ${ maxAmount + 2 } should not be allowed`
228+ ) ;
229+ t . notOk (
230+ limiter . isAllowed ( key , ttl , maxAmount ) ,
231+ `Request ${ maxAmount + 3 } should not be allowed`
232+ ) ;
233+
234+ clock . tick ( ttl / 2 + 1 ) ;
235+
236+ for ( let i = 0 ; i < 2 ; i ++ ) {
237+ t . ok (
238+ limiter . isAllowed ( key , ttl , maxAmount ) ,
239+ `Request ${ i + 1 } should be allowed`
240+ ) ;
241+ }
242+
243+ t . notOk (
244+ limiter . isAllowed ( key , ttl , maxAmount ) ,
245+ `Request ${ maxAmount + 1 } should not be allowed`
246+ ) ;
247+
248+ clock . tick ( ttl + 1 ) ;
249+
250+ t . ok (
251+ limiter . isAllowed ( key , ttl , maxAmount ) ,
252+ `Request after sliding window should be allowed`
253+ ) ;
254+ } ) ;
0 commit comments