Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/backend/conat/test/sync/dkv-basics.test.ts
1451 views
1
/*
2
DEVELOPMENT:
3
4
pnpm test ./dkv-basics.test.ts
5
6
*/
7
import { DKV } from "@cocalc/conat/sync/dkv";
8
import { connect, before, after } from "@cocalc/backend/conat/test/setup";
9
import { wait } from "@cocalc/backend/conat/test/util";
10
11
beforeAll(before);
12
13
describe("create a general kv and do basic operations", () => {
14
const name = "test";
15
let client, kv;
16
17
it("creates the kv", async () => {
18
client = connect();
19
kv = new DKV({ name, client });
20
await kv.init();
21
});
22
23
it("sets and deletes a key", async () => {
24
expect(kv.has("foo")).toBe(false);
25
kv.set("foo", 10);
26
expect(kv.has("foo")).toBe(true);
27
expect(kv.getAll()).toEqual({ foo: 10 });
28
kv.delete("foo");
29
expect(kv.getAll()).toEqual({});
30
kv.set("co", "nat");
31
await kv.save();
32
});
33
34
let client2, kv2;
35
it("view the kv from a second client via sync, set a date value and observe it syncs", async () => {
36
client2 = connect();
37
kv2 = new DKV({ name, client: client2 });
38
await kv2.init();
39
expect(kv2.getAll()).toEqual({ co: "nat" });
40
41
const date = new Date("1974");
42
kv2.set("x", date);
43
// replication is not instant
44
expect(kv.get("x")).toBe(undefined);
45
await kv2.save();
46
await wait({ until: () => kv.get("x") });
47
expect(kv.getAll()).toEqual({ x: date, co: "nat" });
48
});
49
50
it("checks that clear works", async () => {
51
kv.clear();
52
await wait({ until: () => kv.length == 0 });
53
expect(kv.length).toBe(0);
54
await wait({ until: () => kv2.length == 0 });
55
});
56
57
it("checks that time works", async () => {
58
const key = "x".repeat(10000);
59
kv.set(key, "big key");
60
await kv.save();
61
expect(Math.abs(Date.now() - kv.time(key))).toBeLessThan(300);
62
expect(kv.time()).toEqual({ [key]: kv.time(key) });
63
expect(kv2.time()).toEqual({ [key]: kv2.time(key) });
64
});
65
66
it("check headers work", async () => {
67
kv.set("big", "headers", { headers: { silicon: "valley", x: { y: "z" } } });
68
// this uses local state
69
expect(kv.headers("big")).toEqual({ silicon: "valley", x: { y: "z" } });
70
await kv.save();
71
// this uses what got echoed back from server
72
expect(kv.headers("big")).toEqual({ silicon: "valley", x: { y: "z" } });
73
expect(kv2.headers("big")).toEqual({ silicon: "valley", x: { y: "z" } });
74
});
75
76
it("checks hasUnsavedChanges works", async () => {
77
expect(kv.hasUnsavedChanges()).toBe(false);
78
kv.set("unsaved", ["changes"]);
79
expect(kv.hasUnsavedChanges()).toBe(true);
80
expect(kv.unsavedChanges()).toEqual(["unsaved"]);
81
expect(kv2.hasUnsavedChanges()).toBe(false);
82
await kv.save();
83
expect(kv.hasUnsavedChanges()).toBe(false);
84
});
85
86
it("checks stats works", () => {
87
const { bytes, count } = kv.stats();
88
expect(bytes).not.toBeNaN();
89
expect(bytes).toBeGreaterThan(0);
90
expect(count).not.toBeNaN();
91
expect(count).toBeGreaterThan(0);
92
});
93
94
it("checks seq is ", async () => {
95
kv.set("x", "11");
96
await kv.save();
97
const seq = kv.seq("x");
98
expect(seq).toBeGreaterThan(0);
99
kv.set("x", 15);
100
await kv.save();
101
expect(kv.seq("x") - seq).toBe(1);
102
});
103
104
it("clean up", async () => {
105
kv.close();
106
client.close();
107
});
108
});
109
110
afterAll(after);
111
112