@x5e/gink
Version:
an eventually consistent database
313 lines (307 loc) • 15.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.result = void 0;
const implementation_1 = require("../implementation");
const utils_1 = require("../implementation/utils");
it("test bundle", async () => {
for (const store of [
new implementation_1.IndexedDbStore("Database.bundle", true),
new implementation_1.MemoryStore(true),
]) {
const instance = new implementation_1.Database({ store });
await instance.ready;
const bundleInfo = await (await instance.startBundle({ comment: "hello world" })).commit();
(0, utils_1.ensure)(bundleInfo.comment === "hello world", `comment="${bundleInfo.comment}"`);
const chainTracker = await store.getChainTracker();
const allChains = chainTracker.getChains();
(0, utils_1.ensure)(allChains.length === 1);
(0, utils_1.ensure)(allChains[0][0] === bundleInfo.medallion);
(0, utils_1.ensure)(allChains[0][1] === bundleInfo.chainStart);
}
});
it("test commit", async () => {
for (const store of [
new implementation_1.IndexedDbStore("test commit", true),
new implementation_1.MemoryStore(true),
]) {
const instance = new implementation_1.Database({ store });
await instance.ready;
const bundleInfo = await (await instance.startBundle()).commit("hello world");
(0, utils_1.ensure)(bundleInfo.comment === "hello world", `comment="${bundleInfo.comment}"`);
const chainTracker = await store.getChainTracker();
const allChains = chainTracker.getChains();
(0, utils_1.ensure)(allChains.length === 1);
(0, utils_1.ensure)(allChains[0][0] === bundleInfo.medallion);
(0, utils_1.ensure)(allChains[0][1] === bundleInfo.chainStart);
}
});
it("test listeners", async () => {
for (const store of [
new implementation_1.IndexedDbStore("Database.listeners.test", true),
new implementation_1.MemoryStore(true),
]) {
await store.ready;
const db = new implementation_1.Database({ store });
await db.ready;
const root = implementation_1.Directory.get();
const sequence = await implementation_1.Sequence.create();
const box = await implementation_1.Box.create(db);
const rootListener = async () => {
rootListener.calledTimes++;
};
rootListener.calledTimes = 0;
const allContainersListener = async () => {
allContainersListener.calledTimes++;
};
allContainersListener.calledTimes = 0;
db.addListener(rootListener, root.address);
db.addListener(allContainersListener);
await root.set("foo", "bar");
await sequence.push("foo");
await box.set("test");
(0, utils_1.ensure)(rootListener.calledTimes === 1);
(0, utils_1.ensure)(allContainersListener.calledTimes === 3);
await root.clear();
(0, utils_1.ensure)(rootListener.calledTimes === 2);
}
});
/*
it("test container naming", async function () {
for (const store of [
new IndexedDbStore("Database.naming.test", true),
new MemoryStore(true),
]) {
await store.ready;
const db = new Database({store});
await db.ready;
const root = Directory.get();
const seq1 = await Sequence.create();
const seq2 = await Sequence.create();
const seq3 = await Sequence.create();
await root.setName("root");
await seq1.setName("seq");
await seq2.setName("seq");
await seq3.setName("seq");
ensure((await root.getName()) === "root");
ensure((await seq1.getName()) === "seq");
const rootContainers = await db.getContainersWithName("root");
ensure(rootContainers.length === 1);
ensure(root.address.timestamp === rootContainers[0].timestamp);
ensure(root.address.medallion === rootContainers[0].medallion);
ensure(root.address.offset === rootContainers[0].offset);
const seqContainers = await db.getContainersWithName("seq");
ensure(seqContainers.length === 3);
ensure(seq1.address.timestamp === seqContainers[0].timestamp);
ensure(seq1.address.medallion === seqContainers[0].medallion);
ensure(seq1.address.offset === seqContainers[0].offset);
ensure(seq3.address.timestamp === seqContainers[2].timestamp);
ensure(seq3.address.medallion === seqContainers[2].medallion);
ensure(seq3.address.offset === seqContainers[2].offset);
}
});
*/
it("test full database reset", async function () {
for (const store of [
new implementation_1.IndexedDbStore("Database.reset.test", true),
new implementation_1.MemoryStore(true),
]) {
await store.ready;
const db = new implementation_1.Database({ store });
await db.ready;
const prop = await implementation_1.Property.create();
const root = implementation_1.Directory.get();
const seq = await implementation_1.Sequence.create();
const box = await implementation_1.Box.create();
const ks = await implementation_1.KeySet.create();
const ps = await implementation_1.PairSet.create();
const group = await implementation_1.Group.create();
await root.set("foo", "bar");
await seq.push("foo");
await box.set("foo");
await ks.add("foo");
await ps.include([root, seq]);
(0, utils_1.ensure)(await ps.contains([root, seq]));
await group.include(root);
await prop.set(root, "foo");
await prop.set(seq, "foo");
await prop.set(box, "foo");
await prop.set(ks, "foo");
await prop.set(ps, "foo");
await prop.set(group, "foo");
await root.setName("root");
await seq.setName("seq");
await box.setName("box");
await ks.setName("ks");
await ps.setName("ps");
await group.setName("group");
const resetTo = (0, utils_1.generateTimestamp)();
await root.set("foo", "changed");
await seq.push("changed");
await box.set("changed");
await ks.add("changed");
await ps.exclude([root, seq]);
await group.exclude(root);
await prop.set(root, "changed");
await prop.set(seq, "changed");
await prop.set(box, "changed");
await prop.set(ks, "changed");
await prop.set(ps, "changed");
await prop.set(group, "changed");
await root.setName("root2");
await seq.setName("seq2");
await box.setName("box2");
await ks.setName("ks2");
await ps.setName("ps2");
await group.setName("group2");
const afterChanges = (0, utils_1.generateTimestamp)();
await db.reset(resetTo);
(0, utils_1.ensure)((await root.get("foo")) === "bar");
(0, utils_1.ensure)((await seq.at(0)) === "foo");
(0, utils_1.ensure)((await box.get()) === "foo");
(0, utils_1.ensure)(await ks.has("foo"));
(0, utils_1.ensure)(await ps.contains([root, seq]));
(0, utils_1.ensure)(await group.isIncluded(root));
(0, utils_1.ensure)((await prop.get(root)) === "foo");
(0, utils_1.ensure)((await prop.get(seq)) === "foo");
(0, utils_1.ensure)((await prop.get(box)) === "foo");
(0, utils_1.ensure)((await prop.get(ks)) === "foo");
(0, utils_1.ensure)((await prop.get(ps)) === "foo");
(0, utils_1.ensure)((await prop.get(group)) === "foo");
(0, utils_1.ensure)((await root.getName()) === "root");
(0, utils_1.ensure)((await seq.getName()) === "seq");
(0, utils_1.ensure)((await box.getName()) === "box");
(0, utils_1.ensure)((await ks.getName()) === "ks");
(0, utils_1.ensure)((await ps.getName()) === "ps");
(0, utils_1.ensure)((await group.getName()) === "group");
await db.reset();
(0, utils_1.ensure)((await root.get("foo")) === undefined);
(0, utils_1.ensure)((await seq.at(0)) === undefined);
(0, utils_1.ensure)((await box.get()) === undefined);
(0, utils_1.ensure)(!(await ks.has("foo")));
(0, utils_1.ensure)(!(await ps.contains([root, seq])));
(0, utils_1.ensure)(!(await group.isIncluded(root)));
(0, utils_1.ensure)((await prop.get(root)) === undefined);
(0, utils_1.ensure)((await prop.get(seq)) === undefined);
(0, utils_1.ensure)((await prop.get(box)) === undefined);
(0, utils_1.ensure)((await prop.get(ks)) === undefined);
(0, utils_1.ensure)((await prop.get(ps)) === undefined);
(0, utils_1.ensure)((await prop.get(group)) === undefined);
(0, utils_1.ensure)((await root.getName()) === undefined);
(0, utils_1.ensure)((await seq.getName()) === undefined);
(0, utils_1.ensure)((await box.getName()) === undefined);
(0, utils_1.ensure)((await ks.getName()) === undefined);
(0, utils_1.ensure)((await ps.getName()) === undefined);
(0, utils_1.ensure)((await group.getName()) === undefined);
await db.reset(afterChanges);
(0, utils_1.ensure)((await root.get("foo")) === "changed");
(0, utils_1.ensure)((await seq.at(1)) === "changed");
(0, utils_1.ensure)((await box.get()) === "changed");
(0, utils_1.ensure)(await ks.has("changed"));
(0, utils_1.ensure)(!(await ps.contains([root, seq])));
(0, utils_1.ensure)(!(await group.isIncluded(root)));
(0, utils_1.ensure)((await prop.get(root)) === "changed");
(0, utils_1.ensure)((await prop.get(seq)) === "changed");
(0, utils_1.ensure)((await prop.get(box)) === "changed");
(0, utils_1.ensure)((await prop.get(ks)) === "changed");
(0, utils_1.ensure)((await prop.get(ps)) === "changed");
(0, utils_1.ensure)((await prop.get(group)) === "changed");
(0, utils_1.ensure)((await root.getName()) === "root2");
(0, utils_1.ensure)((await seq.getName()) === "seq2");
(0, utils_1.ensure)((await box.getName()) === "box2");
(0, utils_1.ensure)((await ks.getName()) === "ks2");
(0, utils_1.ensure)((await ps.getName()) === "ps2");
(0, utils_1.ensure)((await group.getName()) === "group2");
await root.delete("foo");
await seq.pop(); // should still have foo
await box.clear();
await ks.delete("changed");
await ps.include([ks, group]);
await group.include(seq);
await db.reset(resetTo);
(0, utils_1.ensure)((await root.get("foo")) === "bar");
(0, utils_1.ensure)((await seq.at(0)) === "foo");
(0, utils_1.ensure)((await box.get()) === "foo");
(0, utils_1.ensure)(await ks.has("foo"));
(0, utils_1.ensure)(await ps.contains([root, seq]));
(0, utils_1.ensure)(await group.isIncluded(root));
(0, utils_1.ensure)((await prop.get(root)) === "foo");
(0, utils_1.ensure)((await prop.get(seq)) === "foo");
(0, utils_1.ensure)((await prop.get(box)) === "foo");
(0, utils_1.ensure)((await prop.get(ks)) === "foo");
(0, utils_1.ensure)((await prop.get(ps)) === "foo");
(0, utils_1.ensure)((await prop.get(group)) === "foo");
(0, utils_1.ensure)((await root.getName()) === "root");
(0, utils_1.ensure)((await seq.getName()) === "seq");
(0, utils_1.ensure)((await box.getName()) === "box");
(0, utils_1.ensure)((await ks.getName()) === "ks");
(0, utils_1.ensure)((await ps.getName()) === "ps");
(0, utils_1.ensure)((await group.getName()) === "group");
// Test resetting graph
const prop2 = await implementation_1.Property.create();
const v1 = await implementation_1.Vertex.create();
const v2 = await implementation_1.Vertex.create();
const et = await implementation_1.EdgeType.create();
const e1 = await et.create(v1, v2);
const e2 = await et.create(v2, v1);
const e3 = await et.create(v1, v2);
const baselineEdges = await v1.getEdgesFrom();
const originalE1 = baselineEdges[0];
const originalE3 = baselineEdges[1];
const e1Effective = await e1.getEffective();
const e3Effective = await e3.getEffective();
await v1.setName("v1");
await v2.setName("v2");
await et.setName("et");
await prop.set(e1, "p1e1");
await prop.set(e2, "p1e2");
await prop.set(e3, "p1e3");
await prop2.set(e1, "p2e1");
await prop2.set(e2, "p2e2");
await prop2.set(e3, "p2e3");
const graphResetTo = (0, utils_1.generateTimestamp)();
await v1.setName("v1changed");
await v2.setName("v2changed");
await et.setName("etchanged");
await prop.set(e1, "foo2");
await prop.set(e2, "foo2");
await prop.set(e3, "foo2");
await prop2.set(e1, "bar2");
await prop2.set(e2, "bar2");
await prop2.set(e3, "bar2");
const edgesFrom = await v1.getEdgesFrom();
(0, utils_1.ensure)(edgesFrom.length === 2);
(0, utils_1.ensure)((await v1.getEdgesTo()).length === 1);
(0, utils_1.ensure)((await v2.getEdgesFrom()).length === 1);
(0, utils_1.ensure)((await v2.getEdgesTo()).length === 2);
await e1.remove();
await e2.remove();
// Not removing e3
(0, utils_1.ensure)((await v1.getEdgesFrom()).length === 1);
(0, utils_1.ensure)((await v1.getEdgesTo()).length === 0);
(0, utils_1.ensure)((await v2.getEdgesFrom()).length === 0);
(0, utils_1.ensure)((await v2.getEdgesTo()).length === 1);
await db.reset(graphResetTo);
const v1From1 = await v1.getEdgesFrom();
(0, utils_1.ensure)(v1From1.length === 2);
(0, utils_1.ensure)((await v1.getEdgesTo()).length === 1);
(0, utils_1.ensure)((await v2.getEdgesFrom()).length === 1);
(0, utils_1.ensure)((await v2.getEdgesTo()).length === 2);
(0, utils_1.ensure)((await v1.getName()) === "v1");
(0, utils_1.ensure)((await v2.getName()) === "v2");
(0, utils_1.ensure)((await et.getName()) === "et");
// Ensure edges are not the same as baseline
(0, utils_1.ensure)(v1From1[0].timestamp !== originalE1.timestamp);
(0, utils_1.ensure)((await v1From1[0].getEffective()) === e1Effective);
// e3 was not removed, so it should have the same timestamp
(0, utils_1.ensure)(v1From1[1].timestamp === originalE3.timestamp);
(0, utils_1.ensure)((await v1From1[1].getEffective()) === e3Effective);
// make sure properties were reconstructed on
// previously deleted edges
(0, utils_1.ensure)((await prop.get(v1From1[0])) === "p1e1");
(0, utils_1.ensure)((await prop.get(v1From1[1])) === "p1e3");
(0, utils_1.ensure)((await prop2.get(v1From1[0])) === "p2e1");
(0, utils_1.ensure)((await prop2.get(v1From1[1])) === "p2e3");
}
});
exports.result = 1;
//# sourceMappingURL=Database.test.js.map