# hash() / hash_raw() ----------------------------------------------------

expect_equal(hash(1:3), hash(1:3))
expect_true(hash(1:3) != hash(1:4))
expect_true(hash("a") != hash("b"))
expect_equal(nchar(hash(list(a = 1, b = "x"))), 32)
expect_equal(hash(mtcars), hash(mtcars))
expect_error(hash(function() 1))

expect_equal(hash_raw(serialize(1:3, NULL)), hash_raw(serialize(1:3, NULL)))
expect_true(hash_raw(serialize(1:3, NULL)) != hash_raw(serialize(1:4, NULL)))

# key_missing() ------------------------------------------------------------

expect_true(is.key_missing(key_missing()))
expect_false(is.key_missing(NULL))

# mcache() ----------------------------------------------------------------

mc <- mcache()
expect_true(is.key_missing(mc$get("a")))
expect_null(mc$get("a", missing = NULL))
mc$set("a", 1)
expect_true(mc$exists("a"))
expect_equal(mc$get("a"), 1)
expect_equal(mc$keys(), "a")
expect_equal(mc$size(), 1)
mc$remove("a")
expect_false(mc$exists("a"))

mc$set("a", 1)
mc$set("b", 2)
mc$reset()
expect_equal(mc$size(), 0)

mc_n <- mcache(max_n = 2)
mc_n$set("a", 1)
mc_n$set("b", 2)
mc_n$set("c", 3)
expect_equal(mc_n$size(), 2)
expect_false(mc_n$exists("a"))
expect_true(mc_n$exists("c"))

mc_age <- mcache(max_age = 0)
mc_age$set("a", 1)
expect_false(mc_age$exists("a"))


# dcache() ------------------------------------------------------------------

dc <- dcache()
expect_true(is.key_missing(dc$get("a")))
dc$set("a", 1)
expect_true(dc$exists("a"))
expect_equal(dc$get("a"), 1)
expect_equal(dc$keys(), "a")
expect_equal(dc$size(), 1)
dc$remove("a")
expect_false(dc$exists("a"))

dc_n <- dcache(max_n = 2)
dc_n$set("a", 1)
dc_n$set("b", 2)
dc_n$set("c", 3)
expect_equal(dc_n$size(), 2)
expect_false(dc_n$exists("a"))
expect_true(dc_n$exists("c"))

dc$destroy()
expect_error(dc$get("a"))

# data frames (summary tables) ---------------------------------------------

mtcars_summary <- aggregate(mpg ~ cyl, data = mtcars, FUN = mean)
iris_summary <- aggregate(. ~ Species, data = iris, FUN = mean)
airquality_summary <- aggregate(
  cbind(Ozone, Temp) ~ Month,
  data = airquality,
  FUN = mean,
  na.action = na.omit
)

# hash() is stable and content-sensitive for data frames
expect_equal(hash(mtcars_summary), hash(mtcars_summary))
expect_equal(hash(iris_summary), hash(iris_summary))
expect_equal(hash(airquality_summary), hash(airquality_summary))
expect_true(hash(mtcars_summary) != hash(iris_summary))

mtcars2 <- mtcars
mtcars2$mpg[1] <- mtcars2$mpg[1] + 1
expect_true(
  hash(aggregate(mpg ~ cyl, data = mtcars, FUN = mean)) !=
    hash(aggregate(mpg ~ cyl, data = mtcars2, FUN = mean))
)

# factors and NAs are hashed consistently
expect_equal(hash(iris), hash(iris))
expect_equal(hash(airquality), hash(airquality))
expect_true(hash(airquality) != hash(na.omit(airquality)))

# mcache()/dcache() round-trip data frames without losing structure
mc_df <- mcache()
mc_df$set("mtcars_summary", mtcars_summary)
mc_df$set("iris_summary", iris_summary)
mc_df$set("airquality_summary", airquality_summary)
expect_equal(mc_df$get("mtcars_summary"), mtcars_summary)
expect_equal(mc_df$get("iris_summary"), iris_summary)
expect_equal(mc_df$get("airquality_summary"), airquality_summary)

dc_df <- dcache()
dc_df$set("mtcars_summary", mtcars_summary)
dc_df$set("iris_summary", iris_summary)
dc_df$set("airquality_summary", airquality_summary)
expect_equal(dc_df$get("mtcars_summary"), mtcars_summary)
expect_equal(dc_df$get("iris_summary"), iris_summary)
expect_equal(dc_df$get("airquality_summary"), airquality_summary)
dc_df$destroy()
