@@ -439,3 +439,186 @@ func TestCache_SetExplicitTTLOverridesDefault(t *testing.T) {
439439 t .Error ("key1 should be expired after explicit TTL" )
440440 }
441441}
442+
443+ func TestCache_SetAsync (t * testing.T ) {
444+ ctx := context .Background ()
445+ cache , err := New [string , int ](ctx )
446+ if err != nil {
447+ t .Fatalf ("New: %v" , err )
448+ }
449+ defer func () {
450+ if err := cache .Close (); err != nil {
451+ t .Logf ("Close error: %v" , err )
452+ }
453+ }()
454+
455+ // SetAsync should return immediately
456+ if err := cache .SetAsync (ctx , "key1" , 42 , 0 ); err != nil {
457+ t .Fatalf ("SetAsync: %v" , err )
458+ }
459+
460+ // Value should be immediately available in memory
461+ val , found , err := cache .Get (ctx , "key1" )
462+ if err != nil {
463+ t .Fatalf ("Get: %v" , err )
464+ }
465+ if ! found {
466+ t .Error ("key1 should be found after SetAsync" )
467+ }
468+ if val != 42 {
469+ t .Errorf ("Get value = %d; want 42" , val )
470+ }
471+ }
472+
473+ func TestCache_WithOptions (t * testing.T ) {
474+ ctx := context .Background ()
475+
476+ // Test WithMemorySize
477+ cache , err := New [string , int ](ctx , WithMemorySize (500 ))
478+ if err != nil {
479+ t .Fatalf ("New: %v" , err )
480+ }
481+ if cache .opts .MemorySize != 500 {
482+ t .Errorf ("memory size = %d; want 500" , cache .opts .MemorySize )
483+ }
484+ cache .Close ()
485+
486+ // Test WithDefaultTTL
487+ cache , err = New [string , int ](ctx , WithDefaultTTL (5 * time .Minute ))
488+ if err != nil {
489+ t .Fatalf ("New: %v" , err )
490+ }
491+ if cache .opts .DefaultTTL != 5 * time .Minute {
492+ t .Errorf ("default TTL = %v; want 5m" , cache .opts .DefaultTTL )
493+ }
494+ cache .Close ()
495+
496+ // Test WithWarmup
497+ cache , err = New [string , int ](ctx , WithWarmup (100 ))
498+ if err != nil {
499+ t .Fatalf ("New: %v" , err )
500+ }
501+ if cache .opts .WarmupLimit != 100 {
502+ t .Errorf ("warmup limit = %d; want 100" , cache .opts .WarmupLimit )
503+ }
504+ cache .Close ()
505+
506+ // Test WithCleanup
507+ cache , err = New [string , int ](ctx , WithCleanup (1 * time .Hour ))
508+ if err != nil {
509+ t .Fatalf ("New: %v" , err )
510+ }
511+ if ! cache .opts .CleanupEnabled {
512+ t .Error ("cleanup should be enabled" )
513+ }
514+ if cache .opts .CleanupMaxAge != 1 * time .Hour {
515+ t .Errorf ("cleanup max age = %v; want 1h" , cache .opts .CleanupMaxAge )
516+ }
517+ cache .Close ()
518+ }
519+
520+ func TestCache_DeleteNonExistent (t * testing.T ) {
521+ ctx := context .Background ()
522+ cache , err := New [string , int ](ctx )
523+ if err != nil {
524+ t .Fatalf ("New: %v" , err )
525+ }
526+ defer cache .Close ()
527+
528+ // Delete non-existent key should not error
529+ cache .Delete (ctx , "does-not-exist" )
530+
531+ // Cache should still work
532+ if err := cache .Set (ctx , "key1" , 42 , 0 ); err != nil {
533+ t .Fatalf ("Set: %v" , err )
534+ }
535+ val , found , _ := cache .Get (ctx , "key1" )
536+ if ! found || val != 42 {
537+ t .Error ("cache should still work after deleting non-existent key" )
538+ }
539+ }
540+
541+ func TestCache_EvictFromMain (t * testing.T ) {
542+ ctx := context .Background ()
543+ // Small cache to force eviction from main queue
544+ cache , err := New [int , int ](ctx , WithMemorySize (10 ))
545+ if err != nil {
546+ t .Fatalf ("New: %v" , err )
547+ }
548+ defer cache .Close ()
549+
550+ // Fill small queue and promote items to main by accessing them twice
551+ for i := range 15 {
552+ cache .Set (ctx , i , i , 0 )
553+ // Access immediately to promote to main
554+ cache .Get (ctx , i )
555+ }
556+
557+ // Add more items to force eviction from main queue
558+ for i := 100 ; i < 110 ; i ++ {
559+ cache .Set (ctx , i , i , 0 )
560+ cache .Get (ctx , i )
561+ }
562+
563+ // Cache should not exceed capacity
564+ if cache .Len () > 10 {
565+ t .Errorf ("cache length = %d; should not exceed 10" , cache .Len ())
566+ }
567+ }
568+
569+ func TestCache_GetExpired (t * testing.T ) {
570+ ctx := context .Background ()
571+ cache , err := New [string , int ](ctx )
572+ if err != nil {
573+ t .Fatalf ("New: %v" , err )
574+ }
575+ defer cache .Close ()
576+
577+ // Set with very short TTL
578+ if err := cache .Set (ctx , "key1" , 42 , 1 * time .Millisecond ); err != nil {
579+ t .Fatalf ("Set: %v" , err )
580+ }
581+
582+ // Wait for expiration
583+ time .Sleep (10 * time .Millisecond )
584+
585+ // Get should return not found
586+ _ , found , err := cache .Get (ctx , "key1" )
587+ if err != nil {
588+ t .Fatalf ("Get: %v" , err )
589+ }
590+ if found {
591+ t .Error ("expired key should not be found" )
592+ }
593+ }
594+
595+ func TestCache_SetUpdateExisting (t * testing.T ) {
596+ ctx := context .Background ()
597+ cache , err := New [string , int ](ctx )
598+ if err != nil {
599+ t .Fatalf ("New: %v" , err )
600+ }
601+ defer cache .Close ()
602+
603+ // Set initial value
604+ if err := cache .Set (ctx , "key1" , 42 , 0 ); err != nil {
605+ t .Fatalf ("Set: %v" , err )
606+ }
607+
608+ // Update value
609+ if err := cache .Set (ctx , "key1" , 100 , 0 ); err != nil {
610+ t .Fatalf ("Set update: %v" , err )
611+ }
612+
613+ // Should have new value
614+ val , found , err := cache .Get (ctx , "key1" )
615+ if err != nil {
616+ t .Fatalf ("Get: %v" , err )
617+ }
618+ if ! found {
619+ t .Error ("key1 should be found" )
620+ }
621+ if val != 100 {
622+ t .Errorf ("Get value = %d; want 100" , val )
623+ }
624+ }
0 commit comments