-- SPDX-FileCopyrightText: © 2026 Vladimir Zorin -- SPDX-License-Identifier: OWL-1.0 or later local testimony = require("testimony") local std = require("std") local mneme = require("mneme") local json = require("cjson.safe") local testify = testimony.new("== mneme: Lilush integration ==") local tmp_path = function() return "/tmp/mneme_integ_" .. std.nanoid() .. ".mneme" end -- ── Shell history (store.lua pattern) ───────────────────────────────── testify:that("shell history: save and load entries", function() local path = tmp_path() local db = mneme.open(path, { sync = "none" }) local ks = db:keyspace("shell") local zs = ks:sorted_set("entries") -- Save 10 history entries with timestamps for i = 1, 10 do local entry = json.encode({ cmd = "command_" .. i, cwd = "/home/user", exit_code = 0, ts = 1000000 + i, }) zs:add(1000000 + i, entry) end testimony.assert_equal(10, zs:card()) -- Load last 5 entries (highest timestamps) local results = zs:range_by_score(math.huge, -math.huge, { reverse = true, limit = 5 }) testimony.assert_equal(5, #results) -- Most recent first local first = json.decode(results[1].member) testimony.assert_equal("command_10", first.cmd) testimony.assert_equal(1000010, first.ts) local last = json.decode(results[5].member) testimony.assert_equal("command_6", last.cmd) db:close() std.fs.remove(path) end) testify:that("shell history: persistence across reopen", function() local path = tmp_path() do local db = mneme.open(path) local zs = db:keyspace("hist"):sorted_set("cmds") zs:add(100, "first_command") zs:add(200, "second_command") db:close() end do local db = mneme.open(path) local zs = db:keyspace("hist"):sorted_set("cmds") testimony.assert_equal(2, zs:card()) local results = zs:range_by_score(-math.huge, math.huge) testimony.assert_equal("first_command", results[1].member) testimony.assert_equal("second_command", results[2].member) db:close() end std.fs.remove(path) end) -- ── Session data with TTL (store.lua pattern) ──────────────────────── testify:that("session data: save with TTL and retrieve", function() local path = tmp_path() local db = mneme.open(path, { sync = "none" }) local ks = db:keyspace("session") ks:set("token", "s.abcdef12345", { ttl = 3600 }) local token = ks:get("token") testimony.assert_equal("s.abcdef12345", token) local remaining = ks:ttl("token") testimony.assert_not_nil(remaining) testimony.assert_true(remaining > 3500) db:close() std.fs.remove(path) end) testify:that("session data: TTL expiry works", function() local path = tmp_path() local db = mneme.open(path, { sync = "none" }) local ks = db:keyspace("session") ks:set("token", "expired_token", { ttl = 1 }) testimony.assert_equal("expired_token", ks:get("token")) os.execute("sleep 2") testimony.assert_nil(ks:get("token")) db:close() std.fs.remove(path) end) -- ── DNS cache (cache.lua pattern) ───────────────────────────────────── testify:that("DNS cache: store and retrieve with TTL", function() local path = tmp_path() local db = mneme.open(path, { sync = "none" }) local ks = db:keyspace("cache") -- Store a DNS record local record = json.encode({ records = { { name = "example.com", type = 1, class = 1, ttl = 300, rdata = { address = "93.184.216.34" } }, }, }) ks:set("example.com:1", record, { ttl = 300 }) -- Retrieve local raw = ks:get("example.com:1") testimony.assert_not_nil(raw) local decoded = json.decode(raw) testimony.assert_equal("93.184.216.34", decoded.records[1].rdata.address) -- TTL check local remaining = ks:ttl("example.com:1") testimony.assert_true(remaining > 290) db:close() std.fs.remove(path) end) testify:that("DNS cache: expired entry returns nil", function() local path = tmp_path() local db = mneme.open(path, { sync = "none" }) local ks = db:keyspace("cache") ks:set("short.example.com:1", "data", { ttl = 1 }) testimony.assert_not_nil(ks:get("short.example.com:1")) os.execute("sleep 2") testimony.assert_nil(ks:get("short.example.com:1")) db:close() std.fs.remove(path) end) -- ── Learned completions (sorted set frequency tracking) ─────────────── testify:that("Learned completions: sorted set frequency tracking", function() local path = tmp_path() local db = mneme.open(path, { sync = "none" }) local ks = db:keyspace("completions") local zs = ks:sorted_set("git") -- Simulate ZINCRBY: read score, add 1, re-add zs:add(1, "status") zs:add(1, "commit") zs:add(1, "push") -- "status" used again local current = zs:score("status") or 0 zs:add(current + 1, "status") -- "status" should have score 2 testimony.assert_true(math.abs(zs:score("status") - 2) < 0.01) testimony.assert_true(math.abs(zs:score("commit") - 1) < 0.01) -- Range by score descending (most frequent first) local top = zs:range_by_score(math.huge, -math.huge, { reverse = true, limit = 2 }) testimony.assert_equal("status", top[1].member) db:close() std.fs.remove(path) end) -- ── vectors ─────────────────────────────────────────────────────────── testify:that("vectors: store and search embeddings", function() local path = tmp_path() local db = mneme.open(path, { sync = "none" }) local ks = db:keyspace("embeddings") -- Store embeddings local dim = 8 local function make_vec(seed) local v = {} local s = seed for i = 1, dim do s = (s * 1103515245 + 12345) % (2 ^ 31) v[i] = (s / (2 ^ 31)) * 2 - 1 end return v end for i = 1, 20 do ks:vset("doc:" .. i, make_vec(i)) ks:set("meta:doc:" .. i, json.encode({ title = "Doc " .. i })) end -- Search local query = make_vec(5) -- close to doc:5 query[1] = query[1] + 0.01 local results = ks:vsearch(query, { metric = "cosine", top_k = 3 }) testimony.assert_equal(3, #results) testimony.assert_equal("doc:5", results[1].key) -- Retrieve metadata local meta_raw = ks:get("meta:doc:5") testimony.assert_not_nil(meta_raw) local meta = json.decode(meta_raw) testimony.assert_equal("Doc 5", meta.title) db:close() std.fs.remove(path) end) -- ── Full lifecycle ──────────────────────────────────────────────────── testify:that("end-to-end: open, save history + completion data, close, reopen, verify", function() local path = tmp_path() -- Session 1: write data do local db = mneme.open(path) local shell_ks = db:keyspace("shell") local comp_ks = db:keyspace("completions") -- Shell history local zs = shell_ks:sorted_set("entries") zs:add(1000, json.encode({ cmd = "ls -la", cwd = "/home" })) zs:add(2000, json.encode({ cmd = "git status", cwd = "/project" })) -- Learned completion data local comp = comp_ks:sorted_set("git") comp:add(5, "status") comp:add(3, "push") comp:add(1, "pull") db:close() end -- Session 2: verify and add more do local db = mneme.open(path) local shell_ks = db:keyspace("shell") local comp_ks = db:keyspace("completions") -- Verify history local zs = shell_ks:sorted_set("entries") testimony.assert_equal(2, zs:card()) -- Add more history zs:add(3000, json.encode({ cmd = "make build" })) testimony.assert_equal(3, zs:card()) -- Verify completion data local comp = comp_ks:sorted_set("git") testimony.assert_true(math.abs(comp:score("status") - 5) < 0.01) -- Both keyspaces present local names = db:keyspaces() testimony.assert_true(#names >= 2) db:close() end std.fs.remove(path) end) testify:conclude()