Files
plainleaf/client/data/memory_kv_primitives.test.ts
T

158 lines
4.7 KiB
TypeScript

import { expect, onTestFinished, test } from "vitest";
import { rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { MemoryKvPrimitives } from "./memory_kv_primitives.ts";
import { allTests } from "./kv_primitives.test.ts";
import type { KV } from "../../plug-api/types/datastore.ts";
function tempFilePath(): string {
const path = join(
tmpdir(),
`test-${Date.now()}-${Math.random().toString(36)}.json`,
);
onTestFinished(() => rm(path, { force: true }));
return path;
}
test("MemoryKvPrimitives loads from non-existent file without error", async () => {
const tempPath = `${tempFilePath()}_nonexistent`;
// Disable throttling for tests
const store = new MemoryKvPrimitives(tempPath, { throttleMs: 0 });
await store.init();
// Should create an empty store
const result = await store.batchGet([["test"]]);
expect(result).toEqual([undefined]);
});
test("MemoryKvPrimitives passes all KvPrimitives tests", async () => {
const tempPath = tempFilePath();
const store = new MemoryKvPrimitives(tempPath, { throttleMs: 0 });
await store.init();
await allTests(store);
await store.close();
});
test("MemoryKvPrimitives persists and loads data", async () => {
const tempPath = tempFilePath();
// Create and populate first instance
const store1 = new MemoryKvPrimitives(tempPath, { throttleMs: 0 });
await store1.init();
await store1.batchSet([
{ key: ["test", "key1"], value: "value1" },
{ key: ["test", "key2"], value: "value2" },
]);
// Force persistence
await store1.close();
// Create second instance that loads from the same file
const store2 = new MemoryKvPrimitives(tempPath, { throttleMs: 0 });
await store2.init();
// Check if data was loaded correctly
const results = await store2.batchGet([
["test", "key1"],
["test", "key2"],
]);
expect(results).toEqual(["value1", "value2"]);
});
test("MemoryKvPrimitives mutations trigger persistence", async () => {
const tempPath = tempFilePath();
// Create and populate first instance
const store1 = new MemoryKvPrimitives(tempPath, { throttleMs: 0 });
await store1.init();
await store1.batchSet([{ key: ["test", "key"], value: "value" }]);
// Create second instance without closing the first one
const store2 = new MemoryKvPrimitives(tempPath, { throttleMs: 0 });
await store2.init();
// Check if data was persisted
const results = await store2.batchGet([["test", "key"]]);
expect(results).toEqual(["value"]);
});
test("MemoryKvPrimitives persists delete operations", async () => {
const tempPath = tempFilePath();
// Create and populate store
const store1 = new MemoryKvPrimitives(tempPath, { throttleMs: 0 });
await store1.init();
await store1.batchSet([
{ key: ["test", "key1"], value: "value1" },
{ key: ["test", "key2"], value: "value2" },
]);
// Delete one key
await store1.batchDelete([["test", "key1"]]);
// Create second instance
const store2 = new MemoryKvPrimitives(tempPath, { throttleMs: 0 });
await store2.init();
// Check if delete was persisted
const results = await store2.batchGet([
["test", "key1"],
["test", "key2"],
]);
expect(results).toEqual([undefined, "value2"]);
});
test("MemoryKvPrimitives.fromFile creates and initializes store", async () => {
const tempPath = tempFilePath();
// Create JSON file with initial data
const initialData = {
"test\0key": "value",
};
await writeFile(tempPath, JSON.stringify(initialData), "utf-8");
// Use factory method with throttling disabled
const store = await MemoryKvPrimitives.fromFile(tempPath, {
throttleMs: 0,
});
// Check if data was loaded
const result = await store.batchGet([["test", "key"]]);
expect(result).toEqual(["value"]);
});
test("MemoryKvPrimitives query works with persisted data", async () => {
const tempPath = tempFilePath();
// Create and populate store
const store1 = new MemoryKvPrimitives(tempPath, { throttleMs: 0 });
await store1.init();
await store1.batchSet([
{ key: ["test", "key1"], value: "value1" },
{ key: ["test", "key2"], value: "value2" },
{ key: ["other", "key"], value: "value3" },
]);
// Force persistence
await store1.close();
// Create second instance
const store2 = await MemoryKvPrimitives.fromFile(tempPath, {
throttleMs: 0,
});
// Test query with prefix
const results: KV[] = [];
for await (const item of store2.query({ prefix: ["test"] })) {
results.push(item);
}
expect(results.length).toBe(2);
expect(results[0].key).toEqual(["test", "key1"]);
expect(results[0].value).toBe("value1");
expect(results[1].key).toEqual(["test", "key2"]);
expect(results[1].value).toBe("value2");
});