tests/testthat/test-cache.R

# Tests for cache.R - Memory Cache, File Cache, Vector Cache

test_that("CacheConfig initializes correctly", {
  config <- CacheConfig$new(
    backend = "memory",
    memory_max_size = 1000,
    memory_ttl_seconds = 300
  )

  expect_equal(config$backend, "memory")
  expect_equal(config$memory_max_size, 1000)
  expect_equal(config$memory_ttl_seconds, 300)
})

test_that("CacheStats tracks operations", {
  stats <- CacheStats$new()

  expect_equal(stats$hits, 0)
  expect_equal(stats$misses, 0)

  stats$record_hit()
  stats$record_hit()
  stats$record_miss()

  expect_equal(stats$hits, 2)
  expect_equal(stats$misses, 1)
  expect_equal(stats$hit_rate(), 2/3)

  stats_list <- stats$to_list()
  expect_true(is.list(stats_list))
  expect_equal(stats_list$hits, 2)
})

test_that("CacheEntry tracks expiration", {
  entry <- CacheEntry$new(value = "test", ttl = 1)

  expect_equal(entry$value, "test")
  expect_false(entry$is_expired())

  # Wait for expiration (only if running slow tests)
  # Sys.sleep(1.1)
  # expect_true(entry$is_expired())
})

test_that("NoCache returns NULL for all operations", {
  cache <- NoCache$new()

  cache$set("key", "value")
  expect_null(cache$get("key"))
  expect_false(cache$exists("key"))
  expect_false(cache$delete("key"))
  expect_equal(cache$size(), 0)
})

test_that("MemoryCache basic operations work", {
  cache <- MemoryCache$new()

  # Set and get
  cache$set("key1", "value1")
  expect_equal(cache$get("key1"), "value1")
  expect_equal(cache$size(), 1)

  # Exists
  expect_true(cache$exists("key1"))
  expect_false(cache$exists("nonexistent"))

  # Delete
  expect_true(cache$delete("key1"))
  expect_null(cache$get("key1"))
  expect_equal(cache$size(), 0)
})

test_that("MemoryCache respects max size (LRU eviction)", {
  config <- CacheConfig$new(memory_max_size = 3)
  cache <- MemoryCache$new(config)

  cache$set("a", 1)
  cache$set("b", 2)
  cache$set("c", 3)
  expect_equal(cache$size(), 3)

  # Adding 4th should evict oldest (a)
  cache$set("d", 4)
  expect_equal(cache$size(), 3)
  expect_null(cache$get("a"))
  expect_equal(cache$get("d"), 4)
})

test_that("MemoryCache LRU access order works", {
  config <- CacheConfig$new(memory_max_size = 3)
  cache <- MemoryCache$new(config)

  cache$set("a", 1)
  cache$set("b", 2)
  cache$set("c", 3)

  # Access 'a' to make it recently used
  cache$get("a")

  # Add 'd' - should evict 'b' (least recently used)
  cache$set("d", 4)

  expect_equal(cache$get("a"), 1)  # Still there
  expect_null(cache$get("b"))       # Evicted
  expect_equal(cache$get("c"), 3)
  expect_equal(cache$get("d"), 4)
})

test_that("MemoryCache clear works", {
  cache <- MemoryCache$new()

  cache$set("a", 1)
  cache$set("b", 2)
  expect_equal(cache$size(), 2)

  cache$clear()
  expect_equal(cache$size(), 0)
})

test_that("MemoryCache get_many works", {
  cache <- MemoryCache$new()

  cache$set("a", 1)
  cache$set("b", 2)
  cache$set("c", 3)

  result <- cache$get_many(c("a", "b", "missing"))
  expect_equal(result$a, 1)
  expect_equal(result$b, 2)
  expect_false("missing" %in% names(result))
})

test_that("MemoryCache set_many works", {
  cache <- MemoryCache$new()

  cache$set_many(list(a = 1, b = 2, c = 3))

  expect_equal(cache$get("a"), 1)
  expect_equal(cache$get("b"), 2)
  expect_equal(cache$get("c"), 3)
  expect_equal(cache$size(), 3)
})

test_that("MemoryCache tracks stats correctly", {
  cache <- MemoryCache$new()

  cache$set("a", 1)
  cache$get("a")  # Hit
  cache$get("missing")  # Miss

  expect_equal(cache$stats$hits, 1)
  expect_equal(cache$stats$misses, 1)
  expect_equal(cache$stats$sets, 1)
})

test_that("FileCache basic operations work", {
  # Use temp directory
  config <- CacheConfig$new(
    backend = "file",
    file_cache_dir = file.path(tempdir(), "vectrix_test_cache")
  )
  cache <- FileCache$new(config)

  # Clean up first
  cache$clear()

  # Set and get
  cache$set("key1", list(data = "test"))
  result <- cache$get("key1")
  expect_equal(result$data, "test")

  # Exists
  expect_true(cache$exists("key1"))

  # Delete
  expect_true(cache$delete("key1"))
  expect_null(cache$get("key1"))

  # Clean up
  cache$clear()
})

test_that("VectorCache query caching works", {
  base_cache <- MemoryCache$new()
  vec_cache <- VectorCache$new(base_cache)

  # Cache search results
  query <- c(0.1, 0.2, 0.3)
  results <- list(list(id = "a", score = 0.9), list(id = "b", score = 0.8))

  vec_cache$set_search_results("test_collection", query, results)

  cached <- vec_cache$get_search_results("test_collection", query)
  expect_equal(length(cached), 2)
  expect_equal(cached[[1]]$id, "a")
})

test_that("VectorCache vector caching works", {
  base_cache <- MemoryCache$new()
  vec_cache <- VectorCache$new(base_cache)

  vec_data <- list(id = "vec1", vector = c(1, 2, 3), text = "test")

  vec_cache$set_vector("collection", "vec1", vec_data)
  cached <- vec_cache$get_vector("collection", "vec1")

  expect_equal(cached$id, "vec1")
  expect_equal(cached$vector, c(1, 2, 3))
})

test_that("VectorCache invalidation works", {
  base_cache <- MemoryCache$new()
  vec_cache <- VectorCache$new(base_cache)

  vec_cache$set_vector("col", "v1", list(data = 1))
  expect_true(!is.null(vec_cache$get_vector("col", "v1")))

  vec_cache$invalidate_vector("col", "v1")
  expect_null(vec_cache$get_vector("col", "v1"))
})

test_that("create_cache factory works", {
  # Memory cache
  config1 <- CacheConfig$new(backend = "memory")
  cache1 <- create_cache(config1)
  expect_true(inherits(cache1, "MemoryCache"))

  # No cache
  config2 <- CacheConfig$new(backend = "none")
  cache2 <- create_cache(config2)
  expect_true(inherits(cache2, "NoCache"))
})

test_that("create_vector_cache factory works", {
  vec_cache <- create_vector_cache("memory")
  expect_true(inherits(vec_cache, "VectorCache"))
})

Try the VectrixDB package in your browser

Any scripts or data that you put into this service are public.

VectrixDB documentation built on Feb. 20, 2026, 5:09 p.m.