123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- import * as _ from "lodash";
- import {
- NodeCreation,
- NodeDeletion,
- EdgeCreation,
- EdgeUpdate,
- PrimitiveRegistry,
- } from "./primitive_delta";
- import {
- CompositeLevel,
- } from "./composite_delta";
- import {
- mockUuid,
- } from "./test_helpers";
- import {
- assert,
- assertThrows,
- } from "../util/assert";
- describe("Composite delta", () => {
- it("Dependency", () => {
- const registry = new PrimitiveRegistry();
- const getId = mockUuid();
- const level = new CompositeLevel();
- const nodeCreation = registry.newNodeCreation(getId());
- const composite1 = level.createComposite([nodeCreation]);
- assert(_.isEqual(composite1.getDependencies(), []), "expected composite1 to have no dependencies");
- const nodeDeletion = registry.newNodeDeletion(nodeCreation, [], []);
- const nodeCreation2 = registry.newNodeCreation(getId());
- const composite2 = level.createComposite([nodeDeletion, nodeCreation2]);
- assert(_.isEqual(composite2.getDependencies(), [composite1]), "expected composite2 to depend on composite 1");
- });
- it("Conflict", () => {
- const registry = new PrimitiveRegistry();
- const getId = mockUuid();
- const level = new CompositeLevel();
- const nodeCreation = registry.newNodeCreation(getId());
- const compositeCreate = level.createComposite([nodeCreation]);
- const edgeCreation = registry.newEdgeCreation(nodeCreation, "label", nodeCreation);
- const compositeEdgeCreation = level.createComposite([edgeCreation]);
- assert(_.isEqual(compositeEdgeCreation.getConflicts(), []), "there should not yet be a conflict")
- const nodeDeletion = registry.newNodeDeletion(nodeCreation, [], []);
- const compositeDelete = level.createComposite([nodeDeletion]);
- assert(_.isEqual(compositeEdgeCreation.getConflicts(), [compositeDelete]), "expected compositeDelete1 to conflict with compositeDelete2");
- assert(_.isEqual(compositeDelete.getConflicts(), [compositeEdgeCreation]), "expected compositeDelete1 to conflict with compositeDelete2");
- });
- it("Conflict, but no composite yet", () => {
- const registry = new PrimitiveRegistry();
- const getId = mockUuid();
- const level = new CompositeLevel();
- // Same as above, but now we first create all the L0 deltas:
- const nodeCreation = registry.newNodeCreation(getId());
- const edgeCreation = registry.newEdgeCreation(nodeCreation, "label", nodeCreation);
- const nodeDeletion = registry.newNodeDeletion(nodeCreation, [], []);
- // And then the L1 deltas:
- const compositeCreate = level.createComposite([nodeCreation]);
- const compositeEdgeCreation = level.createComposite([edgeCreation]);
- assert(_.isEqual(compositeEdgeCreation.getConflicts(), []), "there should not yet be a conflict")
- const compositeDelete = level.createComposite([nodeDeletion]);
- assert(_.isEqual(compositeEdgeCreation.getConflicts(), [compositeDelete]), "expected compositeDelete1 to conflict with compositeDelete2");
- assert(_.isEqual(compositeDelete.getConflicts(), [compositeEdgeCreation]), "expected compositeDelete1 to conflict with compositeDelete2");
- });
- it("Conflicting deltas cannot be part of the same composite", () => {
- const registry = new PrimitiveRegistry();
- const getId = mockUuid();
- const level = new CompositeLevel();
- const nodeCreation = registry.newNodeCreation(getId());
- const edgeCreation = registry.newEdgeCreation(nodeCreation, "label", nodeCreation);
- const nodeDeletion = registry.newNodeDeletion(nodeCreation, [], []);
- assertThrows(() => {
- level.createComposite([nodeCreation, edgeCreation, nodeDeletion]);
- }, "should not be able to create a composite consisting of conflicting deltas");
- })
- // This was added after I found a bug:
- it("Dependency within composite", () => {
- const registry = new PrimitiveRegistry();
- const getId = mockUuid();
- const level = new CompositeLevel();
- const nodeCreation = registry.newNodeCreation(getId());
- const nodeDeletion = registry.newNodeDeletion(nodeCreation, [], []);
- const composite = level.createComposite([nodeCreation, nodeDeletion]);
- assert(_.isEqual(composite.getDependencies(), []), "expected composite to have no dependencies");
- assert(_.isEqual(composite.getConflicts(), []), "expected composite to have no conflicts");
- });
- it("Multi-level", () => {
- const registry = new PrimitiveRegistry();
- const getId = mockUuid();
- const lvl1 = new CompositeLevel(); // transactions on CS or CORR
- const lvl2 = new CompositeLevel(); // transactions on CS+CORR
- // CS: a node is created, then deleted
- const csNode = registry.newNodeCreation(getId());
- const csDel = registry.newNodeDeletion(csNode, [], []);
- const csNodeLvl1 = lvl1.createComposite([csNode]);
- const csDelLvl1 = lvl1.createComposite([csDel]);
- assert(csNodeLvl1.getConflicts().length === 0, "did not expect any conflicts so far");
- assert(csDelLvl1.getConflicts().length === 0, "did not expect any conflicts so far");
- // CORR: a link is created from a corr-node to the cs-node, followed by the deletion of the corr-node
- // const corrLink = corrLvl.createComposite([csNode, registry.newNodeCreation(getId()), corrLink]);
- const corrNode = registry.newNodeCreation(getId());
- const corrLink = registry.newEdgeCreation(corrNode, "cs", csNode);
- const corrDel = registry.newNodeDeletion(corrNode, [corrLink], []);
- assert(_.isEqual(corrLink.getConflicts(), [csDel]), "expected corrLink to conflict with csDel");
- assert(_.isEqual(csDel.getConflicts(), [corrLink]), "expected csDel to conflict with corrLink");
- const corrLinkLvl1 = lvl1.createComposite([corrNode, corrLink]);
- assert(_.isEqual(corrLinkLvl1.getConflicts(), [csDelLvl1]), "expected corrLinkLvl1 to conflict with csDelLvl1");
- assert(_.isEqual(csDelLvl1.getConflicts(), [corrLinkLvl1]), "expected csDelLvl1 to conflict with corrLinkLvl1");
- const csCorrLinkLvl2 = lvl2.createComposite([csNodeLvl1, corrLinkLvl1]);
- assert(csCorrLinkLvl2.getConflicts().length === 0, "expected no conflicts here");
- // Patch: in order to avoid a conflict between csDel and corrLink, in corrV2, we override csDel by csDel1.
- const csDel1 = registry.newNodeDeletion(csNode, [], [corrDel]);
- assert(_.isEqual(csDel1.getConflicts(), [csDel]), "expected csDel1 to only conflict with csDel");
- const corrDelLvl1 = lvl1.createComposite([corrDel]);
- const csDel1Lvl1 = lvl1.createComposite([csDel1]);
- assert(_.isEqual(csDel1Lvl1.getConflicts(), [csDelLvl1]), "expected csDel1Lvl1 to conflict with csDelLvl1");
- const csCorrDelLvl2 = lvl2.createComposite([corrDelLvl1, csDel1Lvl1]);
- assert(csCorrDelLvl2.getConflicts().length === 0, "expected no conflicts here");
- });
- });
|