broke the dammn thing
This commit is contained in:
parent
792440a71d
commit
860934de06
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -164,6 +164,17 @@ module.exports = function() {
|
||||
return success;
|
||||
};
|
||||
|
||||
Operation.prototype.getCustomType = function() {
|
||||
if (this.custom_type == null) {
|
||||
throw new Error("This operation was not initialized with a custom type");
|
||||
}
|
||||
if (this.custom_type.constructor === String) {
|
||||
this.custom_type = new this.custom_types[this.custom_type]();
|
||||
this.custom_type._setModel(this);
|
||||
}
|
||||
return this.custom_type;
|
||||
};
|
||||
|
||||
return Operation;
|
||||
|
||||
})();
|
||||
|
@ -11,8 +11,11 @@ module.exports = function() {
|
||||
ops.MapManager = (function(_super) {
|
||||
__extends(MapManager, _super);
|
||||
|
||||
function MapManager(uid) {
|
||||
this.map = {};
|
||||
function MapManager(custom_type, uid) {
|
||||
if (custom_type != null) {
|
||||
this.custom_type = custom_type;
|
||||
}
|
||||
this._map = {};
|
||||
MapManager.__super__.constructor.call(this, uid);
|
||||
}
|
||||
|
||||
@ -20,7 +23,7 @@ module.exports = function() {
|
||||
|
||||
MapManager.prototype.applyDelete = function() {
|
||||
var name, p, _ref;
|
||||
_ref = this.map;
|
||||
_ref = this._map;
|
||||
for (name in _ref) {
|
||||
p = _ref[name];
|
||||
p.applyDelete();
|
||||
@ -32,25 +35,50 @@ module.exports = function() {
|
||||
return MapManager.__super__.cleanup.call(this);
|
||||
};
|
||||
|
||||
MapManager.prototype.map = function(f) {
|
||||
var n, v, _ref;
|
||||
_ref = this._map;
|
||||
for (n in _ref) {
|
||||
v = _ref[n];
|
||||
f(n, v);
|
||||
}
|
||||
return void 0;
|
||||
};
|
||||
|
||||
MapManager.prototype.val = function(name, content) {
|
||||
var o, prop, result, _ref;
|
||||
var o, prop, rep, res, result, _ref;
|
||||
if (arguments.length > 1) {
|
||||
this.retrieveSub(name).replace(content);
|
||||
if ((content != null) && (content._model != null) && content._model instanceof ops.Operation) {
|
||||
rep = content._model;
|
||||
} else {
|
||||
rep = content;
|
||||
}
|
||||
this.retrieveSub(name).replace(rep);
|
||||
return this;
|
||||
} else if (name != null) {
|
||||
prop = this.map[name];
|
||||
prop = this._map[name];
|
||||
if ((prop != null) && !prop.isContentDeleted()) {
|
||||
return prop.val();
|
||||
res = prop.val();
|
||||
if (res instanceof ops.Operation) {
|
||||
return res.getCustomType();
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
return void 0;
|
||||
}
|
||||
} else {
|
||||
result = {};
|
||||
_ref = this.map;
|
||||
_ref = this._map;
|
||||
for (name in _ref) {
|
||||
o = _ref[name];
|
||||
if (!o.isContentDeleted()) {
|
||||
result[name] = o.val();
|
||||
res = prop.val();
|
||||
if (res instanceof ops.Operation) {
|
||||
result[name] = res.getCustomType();
|
||||
} else {
|
||||
result[name] = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -59,7 +87,7 @@ module.exports = function() {
|
||||
|
||||
MapManager.prototype["delete"] = function(name) {
|
||||
var _ref;
|
||||
if ((_ref = this.map[name]) != null) {
|
||||
if ((_ref = this._map[name]) != null) {
|
||||
_ref.deleteContent();
|
||||
}
|
||||
return this;
|
||||
@ -67,7 +95,7 @@ module.exports = function() {
|
||||
|
||||
MapManager.prototype.retrieveSub = function(property_name) {
|
||||
var event_properties, event_this, rm, rm_uid;
|
||||
if (this.map[property_name] == null) {
|
||||
if (this._map[property_name] == null) {
|
||||
event_properties = {
|
||||
name: property_name
|
||||
};
|
||||
@ -78,16 +106,35 @@ module.exports = function() {
|
||||
alt: this
|
||||
};
|
||||
rm = new ops.ReplaceManager(event_properties, event_this, rm_uid);
|
||||
this.map[property_name] = rm;
|
||||
this._map[property_name] = rm;
|
||||
rm.setParent(this, property_name);
|
||||
rm.execute();
|
||||
}
|
||||
return this.map[property_name];
|
||||
return this._map[property_name];
|
||||
};
|
||||
|
||||
MapManager.prototype._encode = function() {
|
||||
var json;
|
||||
json = {
|
||||
'type': this.type,
|
||||
'uid': this.getUid()
|
||||
};
|
||||
if (this.custom_type.constructor === String) {
|
||||
json.custom_type = this.custom_type;
|
||||
} else {
|
||||
json.custom_type = this.custom_type._name;
|
||||
}
|
||||
return json;
|
||||
};
|
||||
|
||||
return MapManager;
|
||||
|
||||
})(ops.Operation);
|
||||
ops.MapManager.parse = function(json) {
|
||||
var custom_type, uid;
|
||||
uid = json['uid'], custom_type = json['custom_type'];
|
||||
return new this(custom_type, uid);
|
||||
};
|
||||
ops.ListManager = (function(_super) {
|
||||
__extends(ListManager, _super);
|
||||
|
||||
@ -413,7 +460,11 @@ module.exports = function() {
|
||||
Replaceable.prototype.type = "Replaceable";
|
||||
|
||||
Replaceable.prototype.val = function() {
|
||||
return this.content;
|
||||
if ((this.content != null) && (this.content.getCustomType != null)) {
|
||||
return this.content.getCustomType();
|
||||
} else {
|
||||
return this.content;
|
||||
}
|
||||
};
|
||||
|
||||
Replaceable.prototype.applyDelete = function() {
|
||||
|
80
build/node/Types/Object.js
Normal file
80
build/node/Types/Object.js
Normal file
@ -0,0 +1,80 @@
|
||||
var YObject;
|
||||
|
||||
YObject = (function() {
|
||||
function YObject(_at__object) {
|
||||
var name, val, _ref;
|
||||
this._object = _at__object != null ? _at__object : {};
|
||||
if (this._object.constructor === Object) {
|
||||
_ref = this._object;
|
||||
for (name in _ref) {
|
||||
val = _ref[name];
|
||||
if (val.constructor === Object) {
|
||||
this._object[name] = new YObject(val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new Error("Y.Object accepts Json Objects only");
|
||||
}
|
||||
}
|
||||
|
||||
YObject.prototype._name = "Object";
|
||||
|
||||
YObject.prototype._getModel = function(types, ops) {
|
||||
var n, o, _ref;
|
||||
if (this._model == null) {
|
||||
this._model = new ops.MapManager(this).execute();
|
||||
_ref = this._object;
|
||||
for (n in _ref) {
|
||||
o = _ref[n];
|
||||
this._model.val(n, o);
|
||||
}
|
||||
}
|
||||
delete this._object;
|
||||
return this._model;
|
||||
};
|
||||
|
||||
YObject.prototype._setModel = function(_at__model) {
|
||||
this._model = _at__model;
|
||||
return delete this._object;
|
||||
};
|
||||
|
||||
YObject.prototype.observe = function(f) {
|
||||
return this._model.observe(f);
|
||||
};
|
||||
|
||||
YObject.prototype.val = function(name, content) {
|
||||
var n, res, v, _ref;
|
||||
if (this._model != null) {
|
||||
return this._model.val.apply(this._model, arguments);
|
||||
} else {
|
||||
if (content != null) {
|
||||
return this._object[name] = content;
|
||||
} else if (name != null) {
|
||||
return this._object[name];
|
||||
} else {
|
||||
res = {};
|
||||
_ref = this._object;
|
||||
for (n in _ref) {
|
||||
v = _ref[n];
|
||||
res[n] = v;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return YObject;
|
||||
|
||||
})();
|
||||
|
||||
if (typeof window !== "undefined" && window !== null) {
|
||||
if (window.Y != null) {
|
||||
window.Y.Object = YObject;
|
||||
} else {
|
||||
throw new Error("You must first import Y!");
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof module !== "undefined" && module !== null) {
|
||||
module.exports = YObject;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
var Engine, HistoryBuffer, adaptConnector, createY, json_ops_uninitialized;
|
||||
var Engine, HistoryBuffer, adaptConnector, createY, text_ops_uninitialized;
|
||||
|
||||
json_ops_uninitialized = require("./Operations/Json");
|
||||
text_ops_uninitialized = require("./Operations/Text");
|
||||
|
||||
HistoryBuffer = require("./HistoryBuffer");
|
||||
|
||||
@ -9,7 +9,7 @@ Engine = require("./Engine");
|
||||
adaptConnector = require("./ConnectorAdapter");
|
||||
|
||||
createY = function(connector) {
|
||||
var HB, engine, ops, ops_manager, user_id;
|
||||
var HB, ct, engine, model, ops, ops_manager, user_id;
|
||||
user_id = null;
|
||||
if (connector.user_id != null) {
|
||||
user_id = connector.user_id;
|
||||
@ -21,7 +21,7 @@ createY = function(connector) {
|
||||
};
|
||||
}
|
||||
HB = new HistoryBuffer(user_id);
|
||||
ops_manager = json_ops_uninitialized(HB, this.constructor);
|
||||
ops_manager = text_ops_uninitialized(HB, this.constructor);
|
||||
ops = ops_manager.operations;
|
||||
engine = new Engine(HB, ops);
|
||||
adaptConnector(connector, engine, HB, ops_manager.execution_listener);
|
||||
@ -30,11 +30,16 @@ createY = function(connector) {
|
||||
ops.Operation.prototype.engine = engine;
|
||||
ops.Operation.prototype.connector = connector;
|
||||
ops.Operation.prototype.custom_ops = this.constructor;
|
||||
return new ops.Object(HB.getReservedUniqueIdentifier()).execute();
|
||||
ct = new createY.Object();
|
||||
model = new ops.MapManager(ct, HB.getReservedUniqueIdentifier()).execute();
|
||||
ct._setModel(model);
|
||||
return ct;
|
||||
};
|
||||
|
||||
module.exports = createY;
|
||||
|
||||
if ((typeof window !== "undefined" && window !== null) && (window.Y == null)) {
|
||||
if (typeof window !== "undefined" && window !== null) {
|
||||
window.Y = createY;
|
||||
}
|
||||
|
||||
createY.Object = require("./Types/Object");
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -201,6 +201,16 @@ module.exports = ()->
|
||||
@unchecked = uninstantiated
|
||||
success
|
||||
|
||||
getCustomType: ()->
|
||||
if not @custom_type?
|
||||
throw new Error "This operation was not initialized with a custom type"
|
||||
if @custom_type.constructor is String
|
||||
# has not been initialized yet (only the name is specified)
|
||||
@custom_type = new @custom_types[@custom_type]()
|
||||
@custom_type._setModel @
|
||||
@custom_type
|
||||
|
||||
|
||||
#
|
||||
# @nodoc
|
||||
# A simple Delete-type operation that deletes an operation.
|
||||
|
@ -1,147 +0,0 @@
|
||||
text_ops_uninitialized = require "./Text"
|
||||
|
||||
module.exports = ()->
|
||||
text_ops = text_ops_uninitialized()
|
||||
ops = text_ops.operations
|
||||
|
||||
#
|
||||
# Manages Object-like values.
|
||||
#
|
||||
class ops.Object extends ops.MapManager
|
||||
|
||||
#
|
||||
# Identifies this class.
|
||||
# Use it to check whether this is a json-type or something else.
|
||||
#
|
||||
# @example
|
||||
# var x = y.val('unknown')
|
||||
# if (x.type === "Object") {
|
||||
# console.log JSON.stringify(x.toJson())
|
||||
# }
|
||||
#
|
||||
type: "Object"
|
||||
|
||||
applyDelete: ()->
|
||||
super()
|
||||
|
||||
cleanup: ()->
|
||||
super()
|
||||
|
||||
#
|
||||
# Transform this to a Json. If your browser supports Object.observe it will be transformed automatically when a change arrives.
|
||||
# Otherwise you will loose all the sharing-abilities (the new object will be a deep clone)!
|
||||
# @return {Json}
|
||||
#
|
||||
# TODO: at the moment you don't consider changing of properties.
|
||||
# E.g.: let x = {a:[]}. Then x.a.push 1 wouldn't change anything
|
||||
#
|
||||
toJson: (transform_to_value = false)->
|
||||
if not @bound_json? or not Object.observe? or true # TODO: currently, you are not watching mutable strings for changes, and, therefore, the @bound_json is not updated. TODO TODO wuawuawua easy
|
||||
val = @val()
|
||||
json = {}
|
||||
for name, o of val
|
||||
if o instanceof ops.Object
|
||||
json[name] = o.toJson(transform_to_value)
|
||||
else if o instanceof ops.ListManager
|
||||
json[name] = o.toJson(transform_to_value)
|
||||
else if transform_to_value and o instanceof ops.Operation
|
||||
json[name] = o.val()
|
||||
else
|
||||
json[name] = o
|
||||
@bound_json = json
|
||||
if Object.observe?
|
||||
that = @
|
||||
Object.observe @bound_json, (events)->
|
||||
for event in events
|
||||
if not event.changedBy? and (event.type is "add" or event.type = "update")
|
||||
# this event is not created by Y.
|
||||
that.val(event.name, event.object[event.name])
|
||||
@observe (events)->
|
||||
for event in events
|
||||
if event.created_ isnt @HB.getUserId()
|
||||
notifier = Object.getNotifier(that.bound_json)
|
||||
oldVal = that.bound_json[event.name]
|
||||
if oldVal?
|
||||
notifier.performChange 'update', ()->
|
||||
that.bound_json[event.name] = that.val(event.name)
|
||||
, that.bound_json
|
||||
notifier.notify
|
||||
object: that.bound_json
|
||||
type: 'update'
|
||||
name: event.name
|
||||
oldValue: oldVal
|
||||
changedBy: event.changedBy
|
||||
else
|
||||
notifier.performChange 'add', ()->
|
||||
that.bound_json[event.name] = that.val(event.name)
|
||||
, that.bound_json
|
||||
notifier.notify
|
||||
object: that.bound_json
|
||||
type: 'add'
|
||||
name: event.name
|
||||
oldValue: oldVal
|
||||
changedBy:event.changedBy
|
||||
@bound_json
|
||||
|
||||
#
|
||||
# @overload val()
|
||||
# Get this as a Json object.
|
||||
# @return [Json]
|
||||
#
|
||||
# @overload val(name)
|
||||
# Get value of a property.
|
||||
# @param {String} name Name of the object property.
|
||||
# @return [Object Type||String|Object] Depending on the value of the property. If mutable it will return a Operation-type object, if immutable it will return String/Object.
|
||||
#
|
||||
# @overload val(name, content)
|
||||
# Set a new property.
|
||||
# @param {String} name Name of the object property.
|
||||
# @param {Object|String} content Content of the object property.
|
||||
# @return [Object Type] This object. (supports chaining)
|
||||
#
|
||||
val: (name, content)->
|
||||
if name? and arguments.length > 1
|
||||
if content? and content.constructor?
|
||||
type = ops[content.constructor.name]
|
||||
if type? and type.create?
|
||||
args = []
|
||||
for i in [1...arguments.length]
|
||||
args.push arguments[i]
|
||||
o = type.create.apply null, args
|
||||
super name, o
|
||||
else
|
||||
throw new Error "The #{content.constructor.name}-type is not (yet) supported in Y."
|
||||
else
|
||||
super name, content
|
||||
else # is this even necessary ? I have to define every type anyway.. (see Number type below)
|
||||
super name
|
||||
|
||||
#
|
||||
# @private
|
||||
#
|
||||
_encode: ()->
|
||||
{
|
||||
'type' : @type
|
||||
'uid' : @getUid()
|
||||
}
|
||||
|
||||
ops.Object.parse = (json)->
|
||||
{
|
||||
'uid' : uid
|
||||
} = json
|
||||
new this(uid)
|
||||
|
||||
ops.Object.create = (content, mutable)->
|
||||
json = new ops.Object().execute()
|
||||
for n,o of content
|
||||
json.val n, o, mutable
|
||||
json
|
||||
|
||||
|
||||
ops.Number = {}
|
||||
ops.Number.create = (content)->
|
||||
content
|
||||
|
||||
text_ops
|
||||
|
||||
|
@ -13,46 +13,65 @@ module.exports = ()->
|
||||
#
|
||||
# @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.
|
||||
#
|
||||
constructor: (uid)->
|
||||
@map = {}
|
||||
constructor: (custom_type, uid)->
|
||||
if custom_type?
|
||||
@custom_type = custom_type
|
||||
@_map = {}
|
||||
super uid
|
||||
|
||||
type: "MapManager"
|
||||
|
||||
applyDelete: ()->
|
||||
for name,p of @map
|
||||
for name,p of @_map
|
||||
p.applyDelete()
|
||||
super()
|
||||
|
||||
cleanup: ()->
|
||||
super()
|
||||
|
||||
map: (f)->
|
||||
for n,v of @_map
|
||||
f(n,v)
|
||||
undefined
|
||||
|
||||
#
|
||||
# @see JsonOperations.val
|
||||
#
|
||||
val: (name, content)->
|
||||
if arguments.length > 1
|
||||
@retrieveSub(name).replace content
|
||||
if content? and content._model? and content._model instanceof ops.Operation
|
||||
rep = content._model
|
||||
else
|
||||
rep = content
|
||||
@retrieveSub(name).replace rep
|
||||
@
|
||||
else if name?
|
||||
prop = @map[name]
|
||||
prop = @_map[name]
|
||||
if prop? and not prop.isContentDeleted()
|
||||
prop.val()
|
||||
res = prop.val()
|
||||
if res instanceof ops.Operation
|
||||
res.getCustomType()
|
||||
else
|
||||
res
|
||||
else
|
||||
undefined
|
||||
else
|
||||
result = {}
|
||||
for name,o of @map
|
||||
for name,o of @_map
|
||||
if not o.isContentDeleted()
|
||||
result[name] = o.val()
|
||||
res = prop.val()
|
||||
if res instanceof ops.Operation
|
||||
result[name] = res.getCustomType()
|
||||
else
|
||||
result[name] = res
|
||||
result
|
||||
|
||||
delete: (name)->
|
||||
@map[name]?.deleteContent()
|
||||
@_map[name]?.deleteContent()
|
||||
@
|
||||
|
||||
retrieveSub: (property_name)->
|
||||
if not @map[property_name]?
|
||||
if not @_map[property_name]?
|
||||
event_properties =
|
||||
name: property_name
|
||||
event_this = @
|
||||
@ -61,10 +80,33 @@ module.exports = ()->
|
||||
sub: property_name
|
||||
alt: @
|
||||
rm = new ops.ReplaceManager event_properties, event_this, rm_uid # this operation shall not be saved in the HB
|
||||
@map[property_name] = rm
|
||||
@_map[property_name] = rm
|
||||
rm.setParent @, property_name
|
||||
rm.execute()
|
||||
@map[property_name]
|
||||
@_map[property_name]
|
||||
|
||||
#
|
||||
# @private
|
||||
#
|
||||
_encode: ()->
|
||||
json = {
|
||||
'type' : @type
|
||||
'uid' : @getUid()
|
||||
}
|
||||
if @custom_type.constructor is String
|
||||
json.custom_type = @custom_type
|
||||
else
|
||||
json.custom_type = @custom_type._name
|
||||
json
|
||||
|
||||
ops.MapManager.parse = (json)->
|
||||
{
|
||||
'uid' : uid
|
||||
'custom_type' : custom_type
|
||||
} = json
|
||||
new this(custom_type, uid)
|
||||
|
||||
|
||||
|
||||
#
|
||||
# @nodoc
|
||||
@ -393,7 +435,10 @@ module.exports = ()->
|
||||
# Return the content that this operation holds.
|
||||
#
|
||||
val: ()->
|
||||
@content
|
||||
if @content? and @content.getCustomType?
|
||||
@content.getCustomType()
|
||||
else
|
||||
@content
|
||||
|
||||
applyDelete: ()->
|
||||
res = super
|
||||
|
73
lib/Types/Object.coffee
Normal file
73
lib/Types/Object.coffee
Normal file
@ -0,0 +1,73 @@
|
||||
|
||||
class YObject
|
||||
|
||||
constructor: (@_object = {})->
|
||||
if @_object.constructor is Object
|
||||
for name, val of @_object
|
||||
if val.constructor is Object
|
||||
@_object[name] = new YObject(val)
|
||||
else
|
||||
throw new Error "Y.Object accepts Json Objects only"
|
||||
|
||||
_name: "Object"
|
||||
|
||||
_getModel: (types, ops)->
|
||||
if not @_model?
|
||||
@_model = new ops.MapManager(@).execute()
|
||||
for n,o of @_object
|
||||
@_model.val n, o
|
||||
delete @_object
|
||||
@_model
|
||||
|
||||
_setModel: (@_model)->
|
||||
delete @_object
|
||||
|
||||
observe: (f)->
|
||||
@_model.observe f
|
||||
|
||||
#
|
||||
# @overload val()
|
||||
# Get this as a Json object.
|
||||
# @return [Json]
|
||||
#
|
||||
# @overload val(name)
|
||||
# Get value of a property.
|
||||
# @param {String} name Name of the object property.
|
||||
# @return [Object Type||String|Object] Depending on the value of the property. If mutable it will return a Operation-type object, if immutable it will return String/Object.
|
||||
#
|
||||
# @overload val(name, content)
|
||||
# Set a new property.
|
||||
# @param {String} name Name of the object property.
|
||||
# @param {Object|String} content Content of the object property.
|
||||
# @return [Object Type] This object. (supports chaining)
|
||||
#
|
||||
val: (name, content)->
|
||||
if @_model?
|
||||
@_model.val.apply @_model, arguments
|
||||
else
|
||||
if content?
|
||||
@_object[name] = content
|
||||
else if name?
|
||||
@_object[name]
|
||||
else
|
||||
res = {}
|
||||
for n,v of @_object
|
||||
res[n] = v
|
||||
res
|
||||
|
||||
if window?
|
||||
if window.Y?
|
||||
window.Y.Object = YObject
|
||||
else
|
||||
throw new Error "You must first import Y!"
|
||||
|
||||
if module?
|
||||
module.exports = YObject
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
13
lib/y.coffee
13
lib/y.coffee
@ -1,5 +1,5 @@
|
||||
|
||||
json_ops_uninitialized = require "./Operations/Json"
|
||||
text_ops_uninitialized = require "./Operations/Text"
|
||||
|
||||
HistoryBuffer = require "./HistoryBuffer"
|
||||
Engine = require "./Engine"
|
||||
@ -15,7 +15,7 @@ createY = (connector)->
|
||||
user_id = id
|
||||
HB.resetUserId id
|
||||
HB = new HistoryBuffer user_id
|
||||
ops_manager = json_ops_uninitialized HB, this.constructor
|
||||
ops_manager = text_ops_uninitialized HB, this.constructor
|
||||
ops = ops_manager.operations
|
||||
|
||||
engine = new Engine HB, ops
|
||||
@ -27,8 +27,13 @@ createY = (connector)->
|
||||
ops.Operation.prototype.connector = connector
|
||||
ops.Operation.prototype.custom_ops = this.constructor
|
||||
|
||||
return new ops.Object(HB.getReservedUniqueIdentifier()).execute()
|
||||
ct = new createY.Object()
|
||||
model = new ops.MapManager(ct, HB.getReservedUniqueIdentifier()).execute()
|
||||
ct._setModel model
|
||||
ct
|
||||
|
||||
module.exports = createY
|
||||
if window? and not window.Y?
|
||||
if window?
|
||||
window.Y = createY
|
||||
|
||||
createY.Object = require "./Types/Object"
|
||||
|
@ -10,6 +10,18 @@ chai.use(sinonChai)
|
||||
Connector = require "../../y-test/lib/y-test.coffee"
|
||||
Y = require "../lib/y.coffee"
|
||||
|
||||
compare = (o1, o2)->
|
||||
if o1.type? and o1.type isnt o2.type
|
||||
throw new Error "different types"
|
||||
else if o1.type is "Object"
|
||||
for name, val of o1.val()
|
||||
compare(val, o2.val(name))
|
||||
else if o1.type?
|
||||
compare(o1.val(), o2.val())
|
||||
else if o1 isnt o2
|
||||
throw new Error "different values"
|
||||
|
||||
|
||||
Test = require "./TestSuite"
|
||||
|
||||
class JsonTest extends Test
|
||||
@ -43,12 +55,8 @@ class JsonTest extends Test
|
||||
p = elems[_.random(0, elems.length-1)]
|
||||
@getRandomRoot user_num, p
|
||||
|
||||
|
||||
getContent: (user_num)->
|
||||
@users[user_num].toJson(true)
|
||||
|
||||
getGeneratingFunctions: (user_num)->
|
||||
types = @users[user_num].operations
|
||||
types = @users[user_num]._model.operations
|
||||
super(user_num).concat [
|
||||
f : (y)=> # SET PROPERTY
|
||||
l = y.val().length
|
||||
@ -113,18 +121,8 @@ describe "JsonFramework", ->
|
||||
ops2 = u2.HB._encode()
|
||||
u1.engine.applyOp ops2, true
|
||||
u2.engine.applyOp ops1, true
|
||||
compare = (o1, o2)->
|
||||
if o1.type? and o1.type isnt o2.type
|
||||
throw new Error "different types"
|
||||
else if o1.type is "Object"
|
||||
for name, val of o1.val()
|
||||
compare(val, o2.val(name))
|
||||
else if o1.type?
|
||||
compare(o1.val(), o2.val())
|
||||
else if o1 isnt o2
|
||||
throw new Error "different values"
|
||||
compare u1, u2
|
||||
expect(test.getContent(0)).to.deep.equal(@yTest.getContent(1))
|
||||
|
||||
expect(compare(u1, u2)).to.not.be.undefined
|
||||
|
||||
it "can handle creaton of complex json (1)", ->
|
||||
@yTest.users[0].val('a', 'q', "mutable")
|
||||
@ -136,16 +134,16 @@ describe "JsonFramework", ->
|
||||
expect(@yTest.getSomeUser().val("a").val()).to.equal("At")
|
||||
|
||||
it "can handle creaton of complex json (2)", ->
|
||||
@yTest.getSomeUser().val('x', {'a':'b'})
|
||||
@yTest.getSomeUser().val('a', {'a':{q:"dtrndtrtdrntdrnrtdnrtdnrtdnrtdnrdnrdt"}}, "mutable")
|
||||
@yTest.getSomeUser().val('b', {'a':{}})
|
||||
@yTest.getSomeUser().val('c', {'a':'c'})
|
||||
@yTest.getSomeUser().val('c', {'a':'b'})
|
||||
@yTest.getSomeUser().val('x', new Y.Object({'a':'b'}))
|
||||
@yTest.getSomeUser().val('a', new Y.Object({'a':{q:"dtrndtrtdrntdrnrtdnrtdnrtdnrtdnrdnrdt"}}))
|
||||
@yTest.getSomeUser().val('b', new Y.Object({'a':{}}))
|
||||
@yTest.getSomeUser().val('c', new Y.Object({'a':'c'}))
|
||||
@yTest.getSomeUser().val('c', new Y.Object({'a':'b'}))
|
||||
@yTest.compareAll()
|
||||
q = @yTest.getSomeUser().val("a").val("a").val("q")
|
||||
q.insert(0,'A')
|
||||
@yTest.compareAll()
|
||||
expect(@yTest.getSomeUser().val("a").val("a").val("q").val()).to.equal("Adtrndtrtdrntdrnrtdnrtdnrtdnrtdnrdnrdt")
|
||||
expect(@yTest.getSomeUser().val("a").val("a").val("q")).to.equal("Adtrndtrtdrntdrnrtdnrtdnrtdnrtdnrdnrdt")
|
||||
|
||||
it "can handle creaton of complex json (3)", ->
|
||||
@yTest.users[0].val('l', [1,2,3], "mutable")
|
||||
@ -171,7 +169,7 @@ describe "JsonFramework", ->
|
||||
it "handles immutables and primitive data types (2)", ->
|
||||
@yTest.users[0].val('string', "text", "immutable")
|
||||
@yTest.users[1].val('number', 4, "immutable")
|
||||
@yTest.users[2].val('object', {q:"rr"}, "immutable")
|
||||
@yTest.users[2].val('object', {q:"rr"})
|
||||
@yTest.users[0].val('null', null)
|
||||
@yTest.compareAll()
|
||||
expect(@yTest.getSomeUser().val('string')).to.equal "text"
|
||||
|
@ -28,14 +28,14 @@ module.exports = class Test
|
||||
for i in [0...@number_of_engines]
|
||||
u = @makeNewUser (i+@name_suffix)
|
||||
for user in @users
|
||||
u.connector.join(user.connector) # TODO: change the test-connector to make this more convenient
|
||||
u._model.connector.join(user._model.connector) # TODO: change the test-connector to make this more convenient
|
||||
@users.push u
|
||||
@initUsers?(@users[0])
|
||||
@flushAll()
|
||||
|
||||
# is called by implementing class
|
||||
makeNewUser: (user)->
|
||||
user.HB.stopGarbageCollection()
|
||||
user._model.HB.stopGarbageCollection()
|
||||
user
|
||||
|
||||
getSomeUser: ()->
|
||||
@ -69,7 +69,7 @@ module.exports = class Test
|
||||
@getRandomText [1,2,'x','y'], 1 # only 4 keys
|
||||
|
||||
getGeneratingFunctions: (user_num)=>
|
||||
types = @users[user_num].operations
|
||||
types = @users[user_num]._model.operations
|
||||
[
|
||||
f : (y)=> # INSERT TEXT
|
||||
y
|
||||
@ -106,7 +106,7 @@ module.exports = class Test
|
||||
|
||||
applyRandomOp: (user_num)=>
|
||||
user = @users[user_num]
|
||||
user.connector.flushOneRandom()
|
||||
user._model.connector.flushOneRandom()
|
||||
|
||||
doSomething: ()->
|
||||
user_num = _.random (@number_of_engines-1)
|
||||
@ -119,15 +119,14 @@ module.exports = class Test
|
||||
final = false
|
||||
if @users.length <= 1 or not final
|
||||
for user,user_number in @users
|
||||
user.connector.flushAll()
|
||||
user._model.connector.flushAll()
|
||||
else
|
||||
for user,user_number in @users[1..]
|
||||
user.connector.flushAll()
|
||||
user._model.connector.flushAll()
|
||||
ops = @users[1].getHistoryBuffer()._encode @users[0].HB.getOperationCounter()
|
||||
@users[0].engine.applyOpsCheckDouble ops
|
||||
|
||||
|
||||
|
||||
compareAll: (test_number)->
|
||||
@flushAll(true)
|
||||
|
||||
@ -135,7 +134,7 @@ module.exports = class Test
|
||||
|
||||
number_of_created_operations = 0
|
||||
for i in [0...(@users.length)]
|
||||
number_of_created_operations += @users[i].connector.getOpsInExecutionOrder().length
|
||||
number_of_created_operations += @users[i]._model.connector.getOpsInExecutionOrder().length
|
||||
@ops += number_of_created_operations*@users.length
|
||||
|
||||
ops_per_msek = Math.floor(@ops/@time)
|
||||
@ -146,7 +145,7 @@ module.exports = class Test
|
||||
if @debug
|
||||
if not _.isEqual @getContent(i), @getContent(i+1)
|
||||
printOpsInExecutionOrder = (otnumber, otherotnumber)=>
|
||||
ops = _.filter @users[otnumber].connector.getOpsInExecutionOrder(), (o)->
|
||||
ops = _.filter @users[otnumber]._model.connector.getOpsInExecutionOrder(), (o)->
|
||||
typeof o.uid.op_name isnt 'string' and o.uid.creator isnt '_'
|
||||
for s,j in ops
|
||||
console.log "op#{j} = " + (JSON.stringify s)
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user