30 lines
1.8 KiB
JavaScript
30 lines
1.8 KiB
JavaScript
import { DatabaseSync } from "node:sqlite";
|
|
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { Timeline } from "../src/timeline.js";
|
|
|
|
test("timeline is idempotent, indexed across old history, bounded and expandable", () => {
|
|
const db = new DatabaseSync(":memory:"); const timeline = new Timeline(db);
|
|
try {
|
|
timeline.append({ id: "old", kind: "user", at: 1, text: "财务报销会议" + "材料".repeat(1000), source: { channel: "feishu", sender: "A" } });
|
|
timeline.append({ id: "old", kind: "user", at: 2, text: "overwrite", source: {} });
|
|
for (let i = 0; i < 250; i++) timeline.append({ id: `new-${i}`, kind: "assistant", at: i + 2, text: "other", source: {} });
|
|
const result = timeline.query({ query: "报销", limit: 5 });
|
|
assert.equal(result.entries[0].id, "old"); assert.equal(result.embedding, false);
|
|
assert.equal(result.entries[0].expandable, true); assert.equal(timeline.read({ id: "old" }).at, 1);
|
|
assert.equal(timeline.read({ id: "old", offset: 0, limit: 2 }).text, "财务");
|
|
assert.equal(timeline.query({ from: 2, to: 2 }).entries.length, 1);
|
|
assert.throws(() => timeline.query({ limit: 999 }));
|
|
timeline.append({ id: "tail", kind: "user", at: 500, text: "padding ".repeat(2500) + "uniqueTail", source: {} });
|
|
assert.equal(timeline.query({ query: "uniqueTail" }).entries[0].id, "tail");
|
|
} finally { db.close(); }
|
|
});
|
|
test("timeline excludes secrets and rejects unbounded data", () => {
|
|
const db = new DatabaseSync(":memory:"); const timeline = new Timeline(db);
|
|
try {
|
|
timeline.append({ id: "secret", kind: "user", at: 1, text: "password=example", source: {} });
|
|
assert.equal(timeline.read({ id: "secret" }).text, "[敏感内容未写入记忆]");
|
|
assert.throws(() => timeline.append({ id: "large", kind: "user", at: 1, text: "x".repeat(32001) }));
|
|
} finally { db.close(); }
|
|
});
|