Files
herolib/lib/data/cache/cache_test.v
2025-01-31 15:39:44 +03:00

153 lines
2.7 KiB
V

module cache
import time
@[heap]
struct TestData {
value string
}
fn test_cache_creation() {
config := CacheConfig{
max_entries: 100
max_size_mb: 1.0
ttl_seconds: 60
eviction_ratio: 0.1
}
mut cache := new_cache[TestData](config)
assert cache.len() == 0
assert cache.config.max_entries == 100
assert cache.config.max_size_mb == 1.0
assert cache.config.ttl_seconds == 60
assert cache.config.eviction_ratio == 0.1
}
fn test_cache_set_get() {
mut cache := new_cache[TestData](CacheConfig{})
data := &TestData{
value: 'test'
}
cache.set(1, data)
assert cache.len() == 1
if cached := cache.get(1) {
assert cached.value == 'test'
} else {
assert false, 'Failed to get cached item'
}
if _ := cache.get(2) {
assert false, 'Should not find non-existent item'
}
}
fn test_cache_ttl() {
$if debug {
eprintln('> test_cache_ttl')
}
mut cache := new_cache[TestData](CacheConfig{
ttl_seconds: 1
})
data := &TestData{
value: 'test'
}
cache.set(1, data)
assert cache.len() == 1
if cached := cache.get(1) {
assert cached.value == 'test'
}
time.sleep(2 * time.second)
$if debug {
eprintln('> waited 2 seconds')
}
if _ := cache.get(1) {
assert false, 'Item should have expired'
}
assert cache.len() == 0
}
fn test_cache_eviction() {
mut cache := new_cache[TestData](CacheConfig{
max_entries: 2
eviction_ratio: 0.5
})
data1 := &TestData{
value: 'one'
}
data2 := &TestData{
value: 'two'
}
data3 := &TestData{
value: 'three'
}
cache.set(1, data1)
cache.set(2, data2)
assert cache.len() == 2
// Access data1 to make it more recently used
cache.get(1)
// Adding data3 should trigger eviction of data2 (least recently used)
cache.set(3, data3)
assert cache.len() == 2
if _ := cache.get(2) {
assert false, 'Item 2 should have been evicted'
}
if cached := cache.get(1) {
assert cached.value == 'one'
} else {
assert false, 'Item 1 should still be cached'
}
if cached := cache.get(3) {
assert cached.value == 'three'
} else {
assert false, 'Item 3 should be cached'
}
}
fn test_cache_clear() {
mut cache := new_cache[TestData](CacheConfig{})
data := &TestData{
value: 'test'
}
cache.set(1, data)
assert cache.len() == 1
cache.clear()
assert cache.len() == 0
if _ := cache.get(1) {
assert false, 'Cache should be empty after clear'
}
}
fn test_cache_size_limit() {
// Set a very small size limit to force eviction
mut cache := new_cache[TestData](CacheConfig{
max_size_mb: 0.0001 // ~100 bytes
eviction_ratio: 0.5
})
// Add multiple entries to exceed size limit
for i := u32(0); i < 10; i++ {
data := &TestData{
value: 'test${i}'
}
cache.set(i, data)
}
// Cache should have evicted some entries to stay under size limit
assert cache.len() < 10
}