@@ -211,6 +211,86 @@ describe('Cache', () => {
211211 } ) ;
212212 } ) ;
213213
214+ describe ( 'has' , ( ) => {
215+ test ( 'expects to return false when key does not exist' , ( ) => {
216+ const cache = new Cache < string > ( ) ;
217+ expect ( cache . has ( 'nonexistent' ) ) . toBeFalsy ( ) ;
218+ } ) ;
219+
220+ test ( 'expects to return true when key exists and is not expired' , ( ) => {
221+ const cache = new Cache < string > ( ) ;
222+ cache . set ( 'key' , 'value' ) ;
223+ expect ( cache . has ( 'key' ) ) . toBeTruthy ( ) ;
224+ } ) ;
225+
226+ test ( 'expects to return false and remove entry when key exists but is expired' , ( ) => {
227+ const TTL = 1000 ; // 1 sec.
228+ const cache = new Cache < string > ( TTL ) ;
229+
230+ cache . set ( 'key' , 'value' ) ;
231+ expect ( cache . has ( 'key' ) ) . toBeTruthy ( ) ;
232+
233+ // Exceeds the TTL, so the entry should be removed.
234+ vi . advanceTimersByTime ( TTL + 100 ) ;
235+ expect ( cache . has ( 'key' ) ) . toBeFalsy ( ) ;
236+
237+ // Validate that the entry is removed from the cache.
238+ expect ( cache . get ( 'key' ) ) . toBeUndefined ( ) ;
239+ expect ( cache . size ) . toBe ( 0 ) ;
240+ } ) ;
241+
242+ test ( 'expects not to affect other valid entries when checking an expired one' , ( ) => {
243+ const TTL = 1000 ;
244+ const cache = new Cache < string > ( TTL ) ;
245+
246+ // Add the first entry.
247+ cache . set ( 'expired' , 'old-value' ) ;
248+ vi . advanceTimersByTime ( 600 ) ;
249+
250+ // Add the second entry.
251+ cache . set ( 'valid' , 'new-value' ) ;
252+
253+ // Exceeds the TTL, so the first entry should be removed.
254+ vi . advanceTimersByTime ( 500 ) ; // Total: 1100ms
255+
256+ // Remove the expired entry.
257+ expect ( cache . has ( 'expired' ) ) . toBeFalsy ( ) ;
258+
259+ // Not affected by the valid entry.
260+ expect ( cache . has ( 'valid' ) ) . toBeTruthy ( ) ;
261+ expect ( cache . get ( 'valid' ) ) . toBe ( 'new-value' ) ;
262+ expect ( cache . size ) . toBe ( 1 ) ;
263+ } ) ;
264+
265+ test ( 'expects to delete multiple expired entries at once' , ( ) => {
266+ const TTL = 1000 ;
267+ const cache = new Cache < string > ( TTL ) ;
268+
269+ // Add multiple entries at once.
270+ cache . set ( 'key1' , 'value1' ) ;
271+ cache . set ( 'key2' , 'value2' ) ;
272+ cache . set ( 'key3' , 'value3' ) ;
273+
274+ expect ( cache . size ) . toBe ( 3 ) ;
275+
276+ // Exceed the TTL for the first entry.
277+ vi . advanceTimersByTime ( TTL + 100 ) ;
278+
279+ // Remove the entry, when checking the first key.
280+ expect ( cache . has ( 'key1' ) ) . toBeFalsy ( ) ;
281+
282+ // Not yet removed, as the expired entries are not checked until the has() method is called.
283+ expect ( cache . size ) . toBe ( 2 ) ;
284+
285+ // Remove the expired entries, when validating the second and third keys.
286+ expect ( cache . has ( 'key2' ) ) . toBeFalsy ( ) ;
287+ expect ( cache . has ( 'key3' ) ) . toBeFalsy ( ) ;
288+
289+ // All keys are expired, so the cache should be empty.
290+ expect ( cache . size ) . toBe ( 0 ) ;
291+ } ) ;
292+ } ) ;
293+
214294 describe ( 'delete and clear' , ( ) => {
215295 test ( 'expects to delete an entry' , ( ) => {
216296 const cache = new Cache < string > ( ) ;
0 commit comments