Skip to content

Commit

Permalink
add tests for hg
Browse files Browse the repository at this point in the history
  • Loading branch information
d-roak committed Aug 28, 2024
1 parent e914934 commit 234de04
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 5 deletions.
2 changes: 1 addition & 1 deletion packages/crdt/src/cros/AddWinsSet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class AddWinsSet<T> implements CRO<T> {
this._add(value);
}

_remove(value: T): void {
private _remove(value: T): void {
if ((this.state.get(value) ?? 0) % 2 === 1) this.state.set(value, 0);
}

Expand Down
193 changes: 189 additions & 4 deletions packages/object/tests/hashgraph.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,28 @@ describe("HashGraph for AddWinSet tests", () => {
V1:ADD(1) /
\ _ V3:ADD(2)
*/
// expect(linearOps).toEqual([op0, op1, op2]);

const cro1 = obj1.cro as AddWinsSet<number>;
const cro2 = obj2.cro as AddWinsSet<number>;

cro1.add(1);
merge(obj2, obj1.hashGraph.getAllVertices());

cro1.remove(1);
cro2.add(2);
merge(obj1, obj2.hashGraph.getAllVertices());
merge(obj2, obj1.hashGraph.getAllVertices());

expect(cro1.contains(1)).toBe(false);
expect(cro1.contains(2)).toBe(true);
expect(obj1.hashGraph.vertices).toEqual(obj2.hashGraph.vertices);

const linearOps = obj1.hashGraph.linearizeOperations();
expect(linearOps).toEqual([
{ type: "add", value: 1 },
{ type: "add", value: 2 },
{ type: "remove", value: 1 },
]);
});

test("Test: Tricky Case", () => {
Expand All @@ -73,6 +94,32 @@ describe("HashGraph for AddWinSet tests", () => {
V1:ADD(1) /
\ ___ V3:ADD(1) <- V5:REMOVE(5)
*/

const cro1 = obj1.cro as AddWinsSet<number>;
const cro2 = obj2.cro as AddWinsSet<number>;

cro1.add(1);
merge(obj2, obj1.hashGraph.getAllVertices());

cro1.remove(1);
cro2.add(1);
cro1.add(10);
cro2.remove(5);
merge(obj1, obj2.hashGraph.getAllVertices());
merge(obj2, obj1.hashGraph.getAllVertices());

expect(cro1.contains(1)).toBe(true);
expect(cro1.contains(10)).toBe(true);
expect(cro1.contains(5)).toBe(false);
expect(obj1.hashGraph.vertices).toEqual(obj2.hashGraph.vertices);

const linearOps = obj1.hashGraph.linearizeOperations();
expect(linearOps).toEqual([
{ type: "add", value: 1 },
{ type: "add", value: 1 },
{ type: "remove", value: 5 },
{ type: "add", value: 10 },
]);
});

test("Test: Yuta Papa's Case", () => {
Expand All @@ -81,6 +128,30 @@ describe("HashGraph for AddWinSet tests", () => {
V1:ADD(1) /
\ ___ V3:REMOVE(2) <- V5:ADD(1)
*/

const cro1 = obj1.cro as AddWinsSet<number>;
const cro2 = obj2.cro as AddWinsSet<number>;

cro1.add(1);
merge(obj2, obj1.hashGraph.getAllVertices());

cro1.remove(1);
cro2.remove(2);
cro1.add(2);
cro2.add(1);
merge(obj1, obj2.hashGraph.getAllVertices());
merge(obj2, obj1.hashGraph.getAllVertices());

expect(cro1.contains(1)).toBe(true);
expect(cro1.contains(2)).toBe(true);
expect(obj1.hashGraph.vertices).toEqual(obj2.hashGraph.vertices);

const linearOps = obj1.hashGraph.linearizeOperations();
expect(linearOps).toEqual([
{ type: "add", value: 1 },
{ type: "add", value: 1 },
{ type: "add", value: 2 },
]);
});

test("Test: Mega Complex Case", () => {
Expand All @@ -93,18 +164,106 @@ describe("HashGraph for AddWinSet tests", () => {
\ /
\ ___ V4:RM(2) <-- V5:ADD(2) <-- V9:RM(1)
*/

const cro1 = obj1.cro as AddWinsSet<number>;
const cro2 = obj2.cro as AddWinsSet<number>;
const cro3 = obj3.cro as AddWinsSet<number>;

cro1.add(1);
merge(obj2, obj1.hashGraph.getAllVertices());

cro1.add(1);
cro1.remove(2);
cro2.remove(2);
cro2.add(2);

merge(obj3, obj1.hashGraph.getAllVertices());
cro3.add(3);
cro1.remove(1);

merge(obj1, obj2.hashGraph.getAllVertices());
cro1.remove(3);
cro2.remove(1);

merge(obj1, obj2.hashGraph.getAllVertices());
merge(obj1, obj3.hashGraph.getAllVertices());
merge(obj2, obj1.hashGraph.getAllVertices());
merge(obj2, obj3.hashGraph.getAllVertices());
merge(obj3, obj1.hashGraph.getAllVertices());
merge(obj3, obj2.hashGraph.getAllVertices());

expect(cro1.contains(1)).toBe(false);
expect(cro1.contains(2)).toBe(true);
expect(cro1.contains(3)).toBe(true);
expect(obj1.hashGraph.vertices).toEqual(obj2.hashGraph.vertices);
expect(obj1.hashGraph.vertices).toEqual(obj3.hashGraph.vertices);

const linearOps = obj1.hashGraph.linearizeOperations();
expect(linearOps).toEqual([
{ type: "add", value: 1 },
{ type: "remove", value: 2 },
{ type: "add", value: 2 },
{ type: "add", value: 1 },
{ type: "add", value: 3 },
{ type: "remove", value: 1 },
]);
});

test("Test: Mega Complex Case 1", () => {
/*
__ V6:ADD(3)
__ V5:ADD(3)
/
___ V2:ADD(1) <-- V3:RM(2) <-- V7:RM(1) <-- V8:RM(3)
___ V2:ADD(1) <-- V3:RM(2) <-- V6:RM(1) <-- V8:RM(3)
/ ^
V1:ADD(1)/ \
\ \
\ ___ V4:RM(2) <-------------------- V5:ADD(2) <-- V9:RM(1)
\ ___ V4:RM(2) <-------------------- V7:ADD(2) <-- V9:RM(1)
*/

const cro1 = obj1.cro as AddWinsSet<number>;
const cro2 = obj2.cro as AddWinsSet<number>;
const cro3 = obj3.cro as AddWinsSet<number>;

cro1.add(1);
merge(obj2, obj1.hashGraph.getAllVertices());

cro1.add(1);
cro1.remove(2);
cro2.remove(2);

merge(obj3, obj1.hashGraph.getAllVertices());
cro3.add(3);
cro1.remove(1);

merge(obj2, obj1.hashGraph.getAllVertices());
cro2.add(2);
cro1.remove(3);
cro2.remove(1);

merge(obj1, obj2.hashGraph.getAllVertices());
merge(obj1, obj3.hashGraph.getAllVertices());
merge(obj2, obj1.hashGraph.getAllVertices());
merge(obj2, obj3.hashGraph.getAllVertices());
merge(obj3, obj1.hashGraph.getAllVertices());
merge(obj3, obj2.hashGraph.getAllVertices());

expect(cro1.contains(1)).toBe(false);
expect(cro1.contains(2)).toBe(true);
expect(cro1.contains(3)).toBe(true);
expect(obj1.hashGraph.vertices).toEqual(obj2.hashGraph.vertices);
expect(obj1.hashGraph.vertices).toEqual(obj3.hashGraph.vertices);

const linearOps = obj1.hashGraph.linearizeOperations();
expect(linearOps).toEqual([
{ type: "add", value: 1 },
{ type: "remove", value: 2 },
{ type: "add", value: 1 },
{ type: "remove", value: 2 },
{ type: "add", value: 3 },
{ type: "remove", value: 1 },
{ type: "add", value: 2 },
{ type: "remove", value: 1 },
]);
});

test("Test: Joao's latest brain teaser", () => {
Expand All @@ -113,5 +272,31 @@ describe("HashGraph for AddWinSet tests", () => {
V1:Add(1) / \ - V5:RM(2)
\__ V3:RM(2) <- V4:RM(2) <--/
*/

const cro1 = obj1.cro as AddWinsSet<number>;
const cro2 = obj2.cro as AddWinsSet<number>;

cro1.add(1);
merge(obj2, obj1.hashGraph.getAllVertices());

cro1.add(2);
cro2.remove(2);
cro2.remove(2);
merge(obj1, obj2.hashGraph.getAllVertices());
merge(obj2, obj1.hashGraph.getAllVertices());

cro1.remove(2);
merge(obj2, obj1.hashGraph.getAllVertices());

expect(cro1.contains(1)).toBe(true);
expect(cro1.contains(2)).toBe(false);
expect(obj1.hashGraph.vertices).toEqual(obj2.hashGraph.vertices);

const linearOps = obj1.hashGraph.linearizeOperations();
expect(linearOps).toEqual([
{ type: "add", value: 1 },
{ type: "add", value: 2 },
{ type: "remove", value: 2 },
]);
});
});

0 comments on commit 234de04

Please sign in to comment.