Skip to content

Commit

Permalink
Added client/server objects to the OT library as well as some rudimen…
Browse files Browse the repository at this point in the history
…tary tests.
  • Loading branch information
xavi- committed May 18, 2010
1 parent e5c3e75 commit e0d3e63
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 1 deletion.
76 changes: 76 additions & 0 deletions operational-transforms.js
Expand Up @@ -161,8 +161,84 @@
return produceOp;
})();

function Client(text, firstId, send) {
var ops = [];
var canSend = true;
var unackOp = [];
var toSendOp = [];

function _send() {
if(toSendOp <= 0) { return; }

canSend = false;
unackOp = toSendOp;
var lastId = firstId + ops.length;
send(lastId, unackOp, function(ops) {
for(var i = 0; i < ops.length; i++) { this.addOp.fromServer(lastId + i, ops[i]); }
ops.push(unackOp);

unackOp = [];
canSend = true;
setTimeout(_send, 0);
});

toSendOp = [];
}

this.addOp = {};
this.addOp.fromClient = function fromClient(op) {
if(op.length <= 0) { return; }

text = ot.applyOp(text, op);
toSendOp = ot.combine(toSendOp, op);

if(canSend) { _send(); }
};
this.addOp.fromServer = function fromServer(id, op) {
if(id <= firstId + ops.length) { return; }

localOp = ot.transform(toSendOp, ot.transform(unackOp, op));
text = ot.applyOp(text, localOp);
toSendOp = ot.transform(op, toSendOp);

ops.push(op);

return text;
};

this.text = function() { return text; };
}

function Server(text, firstId, broadcast) {
var ops = [];

this.addOp = function(relativeId, op, reply) {
var rtnOps = [];

if(relativeId < firstId) { return; }

for(var i = relativeId - firstId + 1; i < ops.length; i++) {
op = ot.transform(ops[i], op);
rtnOps.push(ops[i]);
}

ops.push(op);

text = ot.apply(text, op);

reply(rtnOps);
broadcast(op);

return rtnOps;
};

this.text = function() { return text; };
}

ot.combine = combine;
ot.transform = transform;
ot.applyOp = applyOp;
ot.produceOp = produceOp;
ot.Client = Client;
ot.Server = Server;
})(typeof exports === "object" ? exports : (window.ot = {}));
44 changes: 43 additions & 1 deletion test/ot-test.html
Expand Up @@ -77,6 +77,14 @@ <h2 id="qunit-userAgent"></h2>
[ { cmd: "ins", pos: 3, val: "woop" }, { cmd: "del", pos: 5 } ]),
[ { cmd: "ins", pos: 2, val: "woop" }, { cmd: "del", pos: 8, val: undefined } ],
"Edge case transform test");

same(ot.transform([ { cmd: "ins", pos: 5, val: "o" } ], [ { cmd: "ins", pos: 5, val: " world" } ]),
[ { cmd: "ins", pos: 5, val: " world" } ],
"Inserts near each other don't work");

same(ot.transform([ { cmd: "ins", pos: 5, val: " world" } ], [ { cmd: "ins", pos: 5, val: "o" } ]),
[ { cmd: "ins", pos: 11, val: "o" } ],
"Inserts near each other don't work");
});

test("producing operations: simple tests", function() {
Expand All @@ -90,12 +98,16 @@ <h2 id="qunit-userAgent"></h2>

same(ot.produceOp("hello", "helkaklo"), [ { cmd: "ins", pos: 3, val: "kak" } ], "Insert at begin middle");

same(ot.produceOp("helklo", "hello"), [ { cmd: "del", pos: 3 } ], "Delete at begin middle");
same(ot.produceOp("helklo", "hello"), [ { cmd: "del", pos: 3 } ], "Delete at middle");
});

test("combine operations integrated tests", function() {
var opsA, opsB;

opsA = [];
opsB = ot.produceOp("hi", "hide");
same(ot.combine(opsA, opsB), ot.produceOp("hi", "hide"), "combining with a null op");

opsA = ot.produceOp("hi", "hid");
opsB = ot.produceOp("hid", "hide");
same(ot.combine(opsA, opsB), ot.produceOp("hi", "hide"), "combining ins's");
Expand Down Expand Up @@ -165,6 +177,36 @@ <h2 id="qunit-userAgent"></h2>
equals(ot.applyOp(ot.applyOp("012", opsA), ot.transform(opsA, opsB)), "-2-10123456789");
equals(ot.applyOp(ot.applyOp("012", opsB), ot.transform(opsB, opsA)), "-2-10123456789");
});

test("Test OT Client", function() {
var sentOps = [];

var send = (function() {
var pendingCallback;

function send(lastId, op, callback) {
sentOps.push(op);
pendingCallback = callback;
}

send.ack = function(ops) {
pendingCallback(ops);
};

return send;
})();

var client = new ot.Client("hello", 5, send);

client.addOp.fromClient([ { cmd: "ins", pos: 5, val: "o" } ]);
client.addOp.fromServer(7, [ { cmd: "ins", pos: 5, val: " world" } ]);
send.ack([]);

equals("hello worldo", client.text());
});

test("Test OT Server", function() {
});
</script>
</body>
</html>

0 comments on commit e0d3e63

Please sign in to comment.