mirror of
https://github.com/hanzoai/zap-es.git
synced 2026-10-30 18:17:07 +00:00
180 lines
4.1 KiB
TypeScript
180 lines
4.1 KiB
TypeScript
// Based on https://github.com/jdiaz5513/capnp-ts (MIT - Julián Díaz)
|
|
|
|
import { test, assert as t } from "vitest";
|
|
|
|
import { Message, ObjectSize, Orphan, Struct, utils } from "zap-es";
|
|
import { Int32List } from "src/serialization";
|
|
|
|
/** Just a silly struct that holds a single pointer to... itself? */
|
|
|
|
class TestStruct extends Struct {
|
|
static readonly _zap = {
|
|
displayName: "TestStruct",
|
|
id: "f38ff832f33d57da",
|
|
size: new ObjectSize(8, 2),
|
|
};
|
|
|
|
adoptTest(value: Orphan<TestStruct>): void {
|
|
utils.adopt(value, utils.getPointer(0, this));
|
|
}
|
|
|
|
disownTest(): Orphan<TestStruct> {
|
|
return utils.disown(this.getTest());
|
|
}
|
|
|
|
getTest(): TestStruct {
|
|
return utils.getPointerAs(0, TestStruct, this);
|
|
}
|
|
|
|
hasTest(): boolean {
|
|
return !utils.isNull(utils.getPointer(0, this));
|
|
}
|
|
|
|
initTest(): TestStruct {
|
|
return utils.initStructAt(0, TestStruct, this);
|
|
}
|
|
|
|
setTest(value: TestStruct): void {
|
|
utils.copyFrom(value, utils.getPointer(0, this));
|
|
}
|
|
|
|
getFoo(): number {
|
|
return utils.getUint32(0, this);
|
|
}
|
|
|
|
setFoo(value: number): void {
|
|
utils.setUint32(0, value, this);
|
|
}
|
|
|
|
disownList(): Orphan<Int32List> {
|
|
return utils.disown(this.getList());
|
|
}
|
|
|
|
getList(): Int32List {
|
|
return utils.getPointerAs(1, Int32List, this);
|
|
}
|
|
|
|
initList(length: number): Int32List {
|
|
return utils.initList(1, Int32List, length, this);
|
|
}
|
|
}
|
|
|
|
test("new Orphan()", () => {
|
|
const message = new Message();
|
|
const root = message.initRoot(TestStruct);
|
|
|
|
const structOrphan = new Orphan(root);
|
|
|
|
if (structOrphan._zap === undefined) {
|
|
throw new Error("orphan already adopted?");
|
|
}
|
|
|
|
t.equal(
|
|
structOrphan._zap.size.dataByteLength,
|
|
TestStruct._zap.size.dataByteLength,
|
|
"should copy the data byte length",
|
|
);
|
|
t.equal(
|
|
structOrphan._zap.size.pointerLength,
|
|
TestStruct._zap.size.pointerLength,
|
|
"should copy the pointer count",
|
|
);
|
|
|
|
t.ok(utils.isNull(root), "should zero out the struct pointer");
|
|
|
|
const list = new Message().initRoot(TestStruct).initList(2);
|
|
|
|
const listOrphan = new Orphan(list);
|
|
|
|
if (listOrphan._zap === undefined) {
|
|
throw new Error("orphan already adopted?");
|
|
}
|
|
|
|
t.equal(listOrphan._zap.length, 2, "should copy the list length");
|
|
t.equal(
|
|
listOrphan._zap.elementSize,
|
|
Int32List._zap.size,
|
|
"should copy the list element size",
|
|
);
|
|
|
|
t.ok(utils.isNull(list), "should zero out the list pointer");
|
|
});
|
|
|
|
test("Orphan._moveTo()", () => {
|
|
const root = new Message().initRoot(TestStruct);
|
|
const oldChild = root.initTest();
|
|
const oldList = root.initList(2);
|
|
oldChild.setFoo(100);
|
|
oldList.set(1, 300);
|
|
|
|
const structOrphan = root.disownTest();
|
|
const listOrphan = root.disownList();
|
|
|
|
const newChild = root.initTest();
|
|
const newList = root.initList(5);
|
|
|
|
t.equal(
|
|
newChild.getFoo(),
|
|
0,
|
|
"should not contain disowned struct data in new struct",
|
|
);
|
|
t.equal(
|
|
newList.get(1),
|
|
0,
|
|
"should not contain disowned list data in new list",
|
|
);
|
|
|
|
newChild.setFoo(200);
|
|
newList.set(1, 400);
|
|
|
|
structOrphan._moveTo(newChild);
|
|
listOrphan._moveTo(newList);
|
|
|
|
t.equal(
|
|
newChild.getFoo(),
|
|
100,
|
|
"should overwrite target struct pointer and keep old data",
|
|
);
|
|
t.equal(
|
|
newList.get(1),
|
|
300,
|
|
"should overwrite target list pointer and keep old data",
|
|
);
|
|
t.equal(newList.length, 2, "should set the correct list length");
|
|
|
|
t.throws(
|
|
() => {
|
|
structOrphan._moveTo(root.initTest());
|
|
},
|
|
// "should not allow re-adoption",
|
|
);
|
|
|
|
t.throws(
|
|
() => {
|
|
const o = root.disownTest();
|
|
o._moveTo(new Message().initRoot(TestStruct));
|
|
},
|
|
// "should not allow moving to a different message",
|
|
);
|
|
});
|
|
|
|
test("Orphan.dispose()", () => {
|
|
const root = new Message().initRoot(TestStruct);
|
|
root.initTest().setFoo(100);
|
|
root.initList(1).set(1, 200);
|
|
|
|
const structOrphan = root.disownTest();
|
|
const listOrphan = root.disownList();
|
|
|
|
t.equal(root.segment.getUint32(32), 100);
|
|
t.equal(root.segment.getInt32(60), 200);
|
|
|
|
structOrphan.dispose();
|
|
|
|
t.equal(root.segment.getUint32(32), 0);
|
|
|
|
listOrphan.dispose();
|
|
|
|
t.equal(root.segment.getInt32(60), 0);
|
|
});
|