array & type are observeable
This commit is contained in:
parent
9b3fe2f197
commit
60b75d1862
@ -1,6 +1,6 @@
|
||||
language: node_js
|
||||
before_install:
|
||||
- "npm install -g bower coffee-script"
|
||||
- "npm install -g bower"
|
||||
- "bower install"
|
||||
node_js:
|
||||
- "0.12"
|
||||
@ -8,4 +8,5 @@ node_js:
|
||||
- "0.10"
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- master
|
||||
- 0.6
|
||||
|
@ -11,6 +11,7 @@
|
||||
// Array of all the values
|
||||
this.valArray = valArray;
|
||||
this.eventHandler = new EventHandler( ops =>{
|
||||
var userEvents = [];
|
||||
for (var i in ops) {
|
||||
var op = ops[i];
|
||||
if (op.struct === "Insert") {
|
||||
@ -28,14 +29,27 @@
|
||||
}
|
||||
this.idArray.splice(pos, 0, JSON.stringify(op.id));
|
||||
this.valArray.splice(pos, 0, op.content);
|
||||
userEvents.push({
|
||||
type: "insert",
|
||||
object: this,
|
||||
index: pos,
|
||||
length: 1
|
||||
});
|
||||
} else if (op.struct === "Delete") {
|
||||
let pos = this.idArray.indexOf(JSON.stringify(op.target));
|
||||
this.idArray.splice(pos, 1);
|
||||
this.valArray.splice(pos, 1);
|
||||
userEvents.push({
|
||||
type: "delete",
|
||||
object: this,
|
||||
index: pos,
|
||||
length: 1
|
||||
});
|
||||
} else {
|
||||
throw new Error("Unexpected struct!");
|
||||
}
|
||||
}
|
||||
this.eventHandler.callUserEventListeners(userEvents);
|
||||
});
|
||||
}
|
||||
get (pos) {
|
||||
@ -121,6 +135,9 @@
|
||||
eventHandler.awaitedLastDeletes(dels.length, newLeft);
|
||||
});
|
||||
}
|
||||
observe (f) {
|
||||
this.eventHandler.addUserEventListener(f);
|
||||
}
|
||||
*_changed (transaction, op) {
|
||||
if (op.struct === "Insert") {
|
||||
var l = op.left;
|
||||
|
@ -89,6 +89,29 @@ describe("Array Type", function(){
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("throw insert & delete events", function(done){
|
||||
this.users[0].root.set("array", Y.Array).then(function(array){
|
||||
var event;
|
||||
array.observe(function(e){
|
||||
event = e;
|
||||
});
|
||||
array.insert(0, [0]);
|
||||
expect(event).toEqual([{
|
||||
type: "insert",
|
||||
object: array,
|
||||
index: 0,
|
||||
length: 1
|
||||
}]);
|
||||
array.delete(0);
|
||||
expect(event).toEqual([{
|
||||
type: "delete",
|
||||
object: array,
|
||||
index: 0,
|
||||
length: 1
|
||||
}]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe(`${numberOfYArrayTests} Random tests`, function(){
|
||||
var randomArrayTransactions = [
|
||||
|
@ -6,6 +6,7 @@ class EventHandler {
|
||||
this.waiting = [];
|
||||
this.awaiting = 0;
|
||||
this.onevent = onevent;
|
||||
this.userEventListeners = [];
|
||||
}
|
||||
receivedOp (op) {
|
||||
if (this.awaiting <= 0) {
|
||||
@ -18,6 +19,26 @@ class EventHandler {
|
||||
this.awaiting++;
|
||||
this.onevent(ops);
|
||||
}
|
||||
addUserEventListener (f) {
|
||||
this.userEventListeners.push(f);
|
||||
}
|
||||
removeUserEventListener (f) {
|
||||
this.userEventListeners = this.userEventListeners.filter(function(g){
|
||||
return f !== g;
|
||||
});
|
||||
}
|
||||
removeAllUserEventListeners () {
|
||||
this.userEventListeners = [];
|
||||
}
|
||||
callUserEventListeners (event) {
|
||||
for (var i in this.userEventListeners) {
|
||||
try {
|
||||
this.userEventListeners[i](event);
|
||||
} catch (e) {
|
||||
console.log("User events must not throw Errors!");//eslint-disable-line
|
||||
}
|
||||
}
|
||||
}
|
||||
awaitedLastInserts (n) {
|
||||
var ops = this.waiting.splice(this.waiting.length - n);
|
||||
for (var oid = 0; oid < ops.length; oid++) {
|
||||
@ -56,7 +77,7 @@ class EventHandler {
|
||||
}
|
||||
tryCallEvents () {
|
||||
this.awaiting--;
|
||||
if (this.awaiting <= 0) {
|
||||
if (this.awaiting <= 0 && this.waiting.length > 0) {
|
||||
var events = this.waiting;
|
||||
this.waiting = [];
|
||||
this.onevent(events);
|
||||
@ -73,30 +94,69 @@ class EventHandler {
|
||||
this.contents = {};
|
||||
this.opContents = {};
|
||||
this.eventHandler = new EventHandler( ops =>{
|
||||
var userEvents = [];
|
||||
for (var i in ops) {
|
||||
var op = ops[i];
|
||||
var oldValue;
|
||||
// key is the name to use to access (op)content
|
||||
var key = op.struct === "Delete" ? op.key : op.parentSub;
|
||||
|
||||
// compute oldValue
|
||||
if (this.opContents[key] != null) {
|
||||
let prevType = this.opContents[key];
|
||||
oldValue = () => { //eslint-disable-line
|
||||
let def = Promise.defer();
|
||||
this.os.requestTransaction(function*(){//eslint-disable-line
|
||||
def.resolve(yield* this.getType(prevType));
|
||||
});
|
||||
return def.promise;
|
||||
};
|
||||
} else {
|
||||
oldValue = this.contents[key];
|
||||
}
|
||||
// compute op event
|
||||
if (op.struct === "Insert"){
|
||||
if (op.left === null) {
|
||||
if (op.opContent != null) {
|
||||
this.opContents[op.parentSub] = op.opContent;
|
||||
} else {
|
||||
this.contents[op.parentSub] = op.content;
|
||||
}
|
||||
this.map[op.parentSub] = op.id;
|
||||
}
|
||||
} else if (op.struct === "Delete") {
|
||||
var key = op.key;
|
||||
if (compareIds(this.map[key], op.target)) {
|
||||
if (this.contents[key] != null) {
|
||||
delete this.contents[key];
|
||||
this.opContents[key] = op.opContent;
|
||||
} else {
|
||||
delete this.opContents[key];
|
||||
this.contents[key] = op.content;
|
||||
}
|
||||
this.map[key] = op.id;
|
||||
var insertEvent = {
|
||||
name: key,
|
||||
object: this
|
||||
};
|
||||
if (oldValue === undefined) {
|
||||
insertEvent.type = "add";
|
||||
} else {
|
||||
insertEvent.type = "update";
|
||||
insertEvent.oldValue = oldValue;
|
||||
}
|
||||
userEvents.push(insertEvent);
|
||||
}
|
||||
} else if (op.struct === "Delete") {
|
||||
if (compareIds(this.map[key], op.target)) {
|
||||
if (this.opContents[key] != null) {
|
||||
delete this.opContents[key];
|
||||
} else {
|
||||
delete this.contents[key];
|
||||
}
|
||||
var deleteEvent = {
|
||||
name: key,
|
||||
object: this,
|
||||
oldValue: oldValue,
|
||||
type: "delete"
|
||||
};
|
||||
userEvents.push(deleteEvent);
|
||||
}
|
||||
} else {
|
||||
throw new Error("Unexpected Operation!");
|
||||
}
|
||||
}
|
||||
this.eventHandler.callUserEventListeners(userEvents);
|
||||
});
|
||||
}
|
||||
get (key) {
|
||||
@ -173,12 +233,9 @@ class EventHandler {
|
||||
}
|
||||
return def.promise;
|
||||
}
|
||||
/*
|
||||
*delete (key) {
|
||||
var t = yield "transaction";
|
||||
var model = yield* t.getOperation(this._model);
|
||||
yield* Y.Struct.Map.delete.call(t, model, key);
|
||||
}*/
|
||||
observe (f) {
|
||||
this.eventHandler.addUserEventListener(f);
|
||||
}
|
||||
*_changed (transaction, op) {
|
||||
if (op.struct === "Delete") {
|
||||
op.key = (yield* transaction.getOperation(op.target)).parentSub;
|
||||
|
@ -136,6 +136,46 @@ describe("Map Type", function(){
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
it("throws add & update & delete events (with type and primitive content)", function(done){
|
||||
var y = this.users[0].root;
|
||||
var event;
|
||||
y.observe(function(e){
|
||||
event = e; // just put it on event, should be thrown synchronously anyway
|
||||
});
|
||||
y.set("stuff", 4);
|
||||
expect(event).toEqual([{
|
||||
type: "add",
|
||||
object: y,
|
||||
name: "stuff"
|
||||
}]);
|
||||
// update, oldValue is in contents
|
||||
y.set("stuff", Y.Array);
|
||||
expect(event).toEqual([{
|
||||
type: "update",
|
||||
object: y,
|
||||
name: "stuff",
|
||||
oldValue: 4
|
||||
}]);
|
||||
y.get("stuff").then(function(replacedArray){
|
||||
// update, oldValue is in opContents
|
||||
y.set("stuff", 5);
|
||||
var getYArray = event[0].oldValue;
|
||||
expect(typeof getYArray.constructor === "function").toBeTruthy();
|
||||
getYArray().then(function(array){
|
||||
expect(array).toEqual(replacedArray);
|
||||
|
||||
// delete
|
||||
y.delete("stuff");
|
||||
expect(event).toEqual([{
|
||||
type: "delete",
|
||||
name: "stuff",
|
||||
object: y,
|
||||
oldValue: 5
|
||||
}]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe(`${numberOfYMapTests} Random tests`, function(){
|
||||
var randomMapTransactions = [
|
||||
|
Loading…
x
Reference in New Issue
Block a user