added tests for new xml type.

This commit is contained in:
DadaMonad 2015-02-24 20:34:27 +00:00
parent 3ba89edf7d
commit 9a8f8fba05
12 changed files with 17305 additions and 79 deletions

View File

@ -54,6 +54,11 @@ YList = (function() {
return this;
};
YList.prototype.push = function(content) {
this._model.push(content);
return this;
};
return YList;
})();

View File

@ -1,21 +1,12 @@
var YXml;
YXml = (function() {
function YXml(tagname, attributes, children, classes) {
function YXml(tagname, attributes) {
var a, a_name, c, c_name, _classes, _i, _len, _ref;
if (attributes == null) {
attributes = {};
}
if (children == null) {
children = [];
}
if (classes == null) {
classes = {};
}
this._xml = {};
if (tagname == null) {
throw new Error("You must specify a tagname");
}
this._xml.tagname = tagname;
if (attributes.constructor !== Object) {
throw new Error("The attributes must be specified as a Object");
@ -27,10 +18,7 @@ YXml = (function() {
}
}
this._xml.attributes = attributes;
if (classes.constructor !== Object) {
throw new Error("The classes must be specified as an Array");
}
this._xml.classes = classes;
this._xml.classes = {};
_classes = this._xml.attributes["class"];
delete this._xml.attributes["class"];
if (_classes != null) {
@ -42,17 +30,18 @@ YXml = (function() {
}
}
}
if (children.constructor !== Array) {
throw new Error("You must specify the children as an Array that contains Strings and Y.Xml objects only");
}
void 0;
}
YXml.prototype._name = "Xml";
YXml.prototype._getModel = function(types, ops) {
YXml.prototype._getModel = function(Y, ops) {
if (this._model == null) {
this._model = new ops.MapManager(this).execute();
this._model.val("attributes", new Y.Object(this._xml.attributes)).val("classes", new Y.Object(this._xml.classes)).val("tagname", this._xml.tagname).val("children", this._xml.children);
this._model.val("attributes", new Y.Object(this._xml.attributes));
this._model.val("classes", new Y.Object(this._xml.classes));
this._model.val("tagname", this._xml.tagname);
this._model.val("children", new Y.List());
}
delete this._xml;
return this._model;
@ -63,29 +52,232 @@ YXml = (function() {
return delete this._xml;
};
YXml.prototype._setParent = function(parent) {
if (parent instanceof YXml) {
this.remove();
return this._model.val("parent", parent);
} else {
throw new Error("parent must be of type Y.Xml!");
}
};
YXml.prototype.toString = function() {
var child, name, value, xml, _i, _len, _ref, _ref1;
xml = "<" + this._model.val("tagname");
_ref = this.attr();
for (name in _ref) {
value = _ref[name];
xml += " " + name + '="' + value + '"';
}
xml += ">";
_ref1 = this._model.val("children").val();
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
child = _ref1[_i];
xml += child.toString();
}
xml += '</' + this._model.val("tagname") + '>';
return xml;
};
YXml.prototype.attr = function(name, value) {
var attrs, classes;
if (arguments.length > 1) {
if (value.constructor !== Strings) {
if (value.constructor !== String) {
throw new Error("The attributes must be of type String!");
}
this._model.val("attributes").val(name, value);
return this;
} else if (arguments.length > 0) {
return this._model.val("attributes").val(name);
if (name === "class") {
return Object.keys(this._model.val("classes").val()).join(" ");
} else {
return this._model.val("attributes").val(name);
}
} else {
return this._model.val("attributes").val();
attrs = this._model.val("attributes").val();
classes = Object.keys(this._model.val("classes").val()).join(" ");
if (classes.length > 0) {
attrs["class"] = classes;
}
return attrs;
}
};
YXml.prototype.addClass = function(name) {
this._model.val("classes").val(name, true);
YXml.prototype.addClass = function(names) {
var name, _i, _len, _ref;
_ref = names.split(" ");
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
name = _ref[_i];
this._model.val("classes").val(name, true);
}
return this;
};
YXml.prototype.removeClass = function(name) {
return this._model.val("classes")["delete"](name);
YXml.prototype.after = function() {
var c, content, contents, parent, position, _i, _j, _len, _len1, _ref;
parent = this._model.val("parent");
if (parent == null) {
throw new Error("This Xml Element must not have siblings! (for it does not have a parent)");
}
_ref = parent.val("children").val();
for (position = _i = 0, _len = _ref.length; _i < _len; position = ++_i) {
c = _ref[position];
if (c === this) {
break;
}
}
contents = [];
for (_j = 0, _len1 = arguments.length; _j < _len1; _j++) {
content = arguments[_j];
if (!(content instanceof YXml || content.constructor === String)) {
throw new Error("Y.Xml.after expects instances of YXml or String as a parameter");
}
contents.push(content);
}
return parent._model.val("children").insert(position + 1, contents);
};
YXml.prototype.append = function() {
var content, contents, _i, _len;
contents = [];
for (_i = 0, _len = arguments.length; _i < _len; _i++) {
content = arguments[_i];
if (!(content instanceof YXml || content.constructor === String)) {
throw new Error("Y.Xml.after expects instances of YXml or String as a parameter");
}
contents.push(content);
}
return this._model.val("children").push(contents);
};
YXml.prototype.before = function() {
var c, content, contents, parent, position, _i, _j, _len, _len1, _ref;
parent = this._model.val("parent");
if (parent == null) {
throw new Error("This Xml Element must not have siblings! (for it does not have a parent)");
}
_ref = parent.val("children").val();
for (position = _i = 0, _len = _ref.length; _i < _len; position = ++_i) {
c = _ref[position];
if (c === this) {
break;
}
}
contents = [];
for (_j = 0, _len1 = arguments.length; _j < _len1; _j++) {
content = arguments[_j];
if (!(content instanceof YXml || content.constructor === String)) {
throw new Error("Y.Xml.after expects instances of YXml or String as a parameter");
}
contents.push(content);
}
return parent._model.val("children").insert(position, contents);
};
YXml.prototype.empty = function() {
var child, _i, _len, _ref, _results;
_ref = this._model.val("children").val();
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
child = _ref[_i];
_results.push(child.remove());
}
return _results;
};
YXml.prototype.hasClass = function(className) {
if (this._model.val("classes").val(className) != null) {
return true;
} else {
return false;
}
};
YXml.prototype.prepend = function() {
var content, contents, _i, _len;
contents = [];
for (_i = 0, _len = arguments.length; _i < _len; _i++) {
content = arguments[_i];
if (!(content instanceof YXml || content.constructor === String)) {
throw new Error("Y.Xml.after expects instances of YXml or String as a parameter");
}
contents.push(content);
}
return this._model.val("children").insert(0, contents);
};
YXml.prototype.remove = function() {
var c, i, parent, _i, _len, _ref;
parent = this._model.val("parent");
if (parent instanceof YXml) {
_ref = parent.getChildren();
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
c = _ref[i];
if (c === this) {
parent._model["delete"](i);
break;
}
}
}
return void 0;
};
YXml.prototype.removeAttr = function(attrName) {
if (attrName === "class") {
this._model.val("classes", new Y.Object());
} else {
this._model.val("attributes")["delete"](attrName);
}
return this;
};
YXml.prototype.removeClass = function() {
var className, _i, _len;
if (arguments.length === 0) {
this._model.val("classes", new Y.Object());
} else {
for (_i = 0, _len = arguments.length; _i < _len; _i++) {
className = arguments[_i];
this._model.val("classes")["delete"](className);
}
}
return this;
};
YXml.prototype.toggleClass = function() {
var className, classes, _i, _len;
for (_i = 0, _len = arguments.length; _i < _len; _i++) {
className = arguments[_i];
classes = this._model.val("classes");
if (classes.val(className) != null) {
classes["delete"](className);
} else {
classes.val(className, true);
}
}
return this;
};
YXml.prototype.getParent = function() {
return this._model.val("parent");
};
YXml.prototype.getChildren = function() {
return this._model.val("children").val();
};
return YXml;
})();
if (typeof window !== "undefined" && window !== null) {
if (window.Y != null) {
window.Y.Xml = YXml;
} else {
throw new Error("You must first import Y!");
}
}
if (typeof module !== "undefined" && module !== null) {
module.exports = YXml;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

16641
build/test/Xml_test.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -13,8 +13,9 @@
mocha.ui('bdd');
mocha.reporter('html');
</script>
<script src="Text_test.js"></script>
<script src="Json_test.js"></script>
<script src="Xml_test.js"></script>
<!--script src="Text_test.js"></script>
<script src="Json_test.js"></script-->
<!--script src="Xml_test_browser.js"></script-->
<script>
//mocha.checkLeaks();

View File

@ -25,8 +25,8 @@ gulp.task 'default', ['build_browser']
files =
lib : ['./lib/**/*.coffee']
browser : ['./lib/y.coffee','./lib/y-object.coffee']
#test : ['./test/**/*_test.coffee']
test : ['./test/Json_test.coffee', './test/Text_test.coffee']
test : ['./test/**/*_test.coffee']
#test : ['./test/Json_test.coffee', './test/Text_test.coffee']
gulp : ['./gulpfile.coffee']
examples : ['./examples/**/*.js']
other: ['./lib/**/*', './test/*']

View File

@ -50,6 +50,10 @@ class YList
@_model.delete position, length
@
push: (content)->
@_model.push content
@
if window?
if window.Y?
window.Y.List = YList

View File

@ -1,9 +1,10 @@
class YXml
constructor: (tagname, attributes = {}, children = [], classes = {})->
constructor: (tagname, attributes = {})->
@_xml = {}
if not tagname?
throw new Error "You must specify a tagname"
#TODO: How to force the user to specify parameters?
#if not tagname?
# throw new Error "You must specify a tagname"
@_xml.tagname = tagname
if attributes.constructor isnt Object
throw new Error "The attributes must be specified as a Object"
@ -11,53 +12,246 @@ class YXml
if a.constructor isnt String
throw new Error "The attributes must be of type String!"
@_xml.attributes = attributes
if classes.constructor isnt Object
throw new Error "The classes must be specified as an Array"
@_xml.classes = classes
@_xml.classes = {}
_classes = @_xml.attributes.class
delete @_xml.attributes.class
if _classes?
for c_name, c in _classes.split(" ")
if c.length > 0
@_xml.classes[c_name] = c
if children.constructor isnt Array
throw new Error "You must specify the children as an Array that contains Strings and Y.Xml objects only"
undefined
_name: "Xml"
_getModel: (types, ops)->
_getModel: (Y, ops)->
if not @_model?
@_model = new ops.MapManager(@).execute()
@_model.val("attributes", new Y.Object(@_xml.attributes))
.val("classes", new Y.Object(@_xml.classes))
.val("tagname", @_xml.tagname)
.val("children", @_xml.children)
@_model.val("classes", new Y.Object(@_xml.classes))
@_model.val("tagname", @_xml.tagname)
@_model.val("children", new Y.List())
delete @_xml
@_model
_setModel: (@_model)->
delete @_xml
_setParent: (parent)->
if parent instanceof YXml
@remove()
@_model.val("parent", parent)
else
throw new Error "parent must be of type Y.Xml!"
toString: ()->
xml = "<"+@_model.val("tagname")
for name, value of @attr()
xml += " "+name+'="'+value+'"'
xml += ">"
for child in @_model.val("children").val()
xml += child.toString()
xml += '</'+@_model.val("tagname")+'>'
xml
#
# Get/set the attribute(s) of this element.
# .attr()
# .attr(name)
# .attr(name, value)
#
attr: (name, value)->
if arguments.length > 1
if value.constructor isnt Strings
if value.constructor isnt String
throw new Error "The attributes must be of type String!"
@_model.val("attributes").val(name, value)
@
else if arguments.length > 0
@_model.val("attributes").val(name)
if name is "class"
Object.keys(@_model.val("classes").val()).join(" ")
else
@_model.val("attributes").val(name)
else
@_model.val("attributes").val()
attrs = @_model.val("attributes").val()
classes = Object.keys(@_model.val("classes").val()).join(" ")
if classes.length > 0
attrs["class"] = classes
attrs
addClass: (name)->
@_model.val("classes").val(name, true)
#
# Adds the specified class(es) to this element
#
addClass: (names)->
for name in names.split(" ")
@_model.val("classes").val(name, true)
@
removeClass: (name)->
@_model.val("classes").delete(name)
#
# Insert content, specified by the parameter, after this element
# .after(content [, content])
#
after: ()->
parent = @_model.val("parent")
if not parent?
throw new Error "This Xml Element must not have siblings! (for it does not have a parent)"
# find the position of this element
for c,position in parent.val("children").val()
if c is @
break
contents = []
for content in arguments
if not (content instanceof YXml or content.constructor is String)
throw new Error "Y.Xml.after expects instances of YXml or String as a parameter"
contents.push content
parent._model.val("children").insert(position+1, contents)
#
# Insert content, specified by the parameter, to the end of this element
# .append(content [, content])
#
append: ()->
contents = []
for content in arguments
if not (content instanceof YXml or content.constructor is String)
throw new Error "Y.Xml.after expects instances of YXml or String as a parameter"
contents.push content
@_model.val("children").push(contents)
#
# Insert content, specified by the parameter, after this element
# .after(content [, content])
#
before: ()->
parent = @_model.val("parent")
if not parent?
throw new Error "This Xml Element must not have siblings! (for it does not have a parent)"
# find the position of this element
for c,position in parent.val("children").val()
if c is @
break
contents = []
for content in arguments
if not (content instanceof YXml or content.constructor is String)
throw new Error "Y.Xml.after expects instances of YXml or String as a parameter"
contents.push content
parent._model.val("children").insert(position, contents)
#
# Remove all child nodes of the set of matched elements from the DOM.
# .empty()
#
empty: ()->
for child in @_model.val("children").val()
child.remove()
#
# Determine whether any of the matched elements are assigned the given class.
# .hasClass(className)
#
hasClass: (className)->
if @_model.val("classes").val(className)?
true
else
false
#
# Insert content, specified by the parameter, to the beginning of this element.
# .prepend(content [, content])
#
prepend: ()->
contents = []
for content in arguments
if not (content instanceof YXml or content.constructor is String)
throw new Error "Y.Xml.after expects instances of YXml or String as a parameter"
contents.push content
@_model.val("children").insert(0, contents)
#
# Remove this element from the DOM
# .remove()
#
remove: ()->
parent = @_model.val("parent")
if parent instanceof YXml
for c,i in parent.getChildren()
if c is @
parent._model.delete i
break
undefined
#
# Remove an attribute from this element
# .removeAttr(attrName)
#
removeAttr: (attrName)->
if attrName is "class"
@_model.val("classes", new Y.Object())
else
@_model.val("attributes").delete(attrName)
@
#
# Remove a single class, multiple classes, or all classes from this element
# .removeClass([className])
#
removeClass: ()->
if arguments.length is 0
@_model.val("classes", new Y.Object())
else
for className in arguments
@_model.val("classes").delete(className)
@
#
# Add or remove one or more classes from this element,
# depending on either the classs presence or the value of the state argument.
# .toggleClass([className])
#
toggleClass: ()->
for className in arguments
classes = @_model.val("classes")
if classes.val(className)?
classes.delete(className)
else
classes.val(className, true)
@
#
# Get the parent of this Element
# @Note: Every XML element can only have one parent
# .getParent()
#
getParent: ()->
@_model.val("parent")
#
# Get all the children of this XML Element as an Array
# @Note: The children are either of type Y.Xml or String
# .getChildren()
#
getChildren: ()->
@_model.val("children").val()
if window?
if window.Y?
window.Y.Xml = YXml
else
throw new Error "You must first import Y!"
if module?
module.exports = YXml

View File

@ -7,8 +7,8 @@ _ = require("underscore")
chai.use(sinonChai)
Connector = require "../../y-test/lib/y-test.coffee"
Y = require "../lib/y.coffee"
Y.Test = require "../../y-test/lib/y-test.coffee"
Y.Text = require "../lib/Types/Text"
Y.List = require "../lib/Types/List"
@ -20,14 +20,13 @@ class JsonTest extends Test
super suffix, Y
makeNewUser: (userId)->
conn = new Connector userId
conn = new Y.Test userId
super new Y conn
type: "JsonTest"
getRandomRoot: (user_num, root, depth = @max_depth)->
root ?= @users[user_num]
types = @users[user_num].types
if depth is 0 or _.random(0,1) is 1 # take root
root
else # take child

View File

@ -14,7 +14,7 @@ module.exports = class Test
Y = Yjs
@number_of_test_cases_multiplier = 1
@repeat_this = 1 * @number_of_test_cases_multiplier
@doSomething_amount = 1230 * @number_of_test_cases_multiplier
@doSomething_amount = 123 * @number_of_test_cases_multiplier
@number_of_engines = 5 + @number_of_test_cases_multiplier - 1
@time = 0 # denotes to the time when run was started
@ -95,15 +95,12 @@ module.exports = class Test
getRandomRoot: (user_num)->
throw new Error "implement me!"
getContent: (user_num)->
throw new Error "implement me!"
compare: (o1, o2, depth = (@max_depth+1))->
if o1 is o2 or depth <= 0
true
else if o1._name? and o1._name isnt o2._name
throw new Error "different types"
else if o1._name is "Object"
else if o1._name is "Object" or o1.type is "MapManager"
for name, val of o1.val()
@compare(val, o2.val(name), depth-1)
else if o1._name?
@ -115,6 +112,8 @@ module.exports = class Test
@compare o, o2[i], (depth-1)
else if o1 isnt o2
throw new Error "different values"
else
throw new Error "I don't know what to do .. "
generateRandomOp: (user_num)=>
y = @getRandomRoot(user_num)

191
test/Xml_test.coffee Normal file
View File

@ -0,0 +1,191 @@
chai = require('chai')
expect = chai.expect
should = chai.should()
sinon = require('sinon')
sinonChai = require('sinon-chai')
_ = require("underscore")
chai.use(sinonChai)
Y = require "../lib/y.coffee"
Y.Test = require "../../y-test/lib/y-test.coffee"
Y.List = require "../lib/Types/List"
Y.Xml = require "../lib/Types/Xml"
Test = require "./TestSuite"
class XmlTest extends Test
constructor: (suffix)->
super suffix, Y
makeNewUser: (userId)->
conn = new Y.Test userId
super new Y conn
initUsers: (u)->
u.val("xml",new Y.Xml("root"))
type: "XmlTest"
compare: (o1, o2)->
if o1.constructor is Y.Xml
@compare o1._model, o2._model
else
super
getRandomRoot: (user_num, root, depth = @max_depth)->
root ?= @users[user_num]
if depth is 0 or _.random(0,1) is 1 # take root
root
else # take child
depth--
elems = null
if root._name is "Xml"
elems = root.getChildren()
else
return root
elems = elems.filter (elem)->
elem._name is "Xml"
if elems.length is 0
root
else
p = elems[_.random(0, elems.length-1)]
@getRandomRoot user_num, p, depth
getGeneratingFunctions: (user_num)->
super(user_num).concat [
]
describe "Y-Xml", ->
@timeout 500000
beforeEach (done)->
@yTest = new XmlTest()
@users = @yTest.users
@u1 = @users[1].val("xml")
@u2 = @users[2].val("xml")
@u3 = @users[3].val("xml")
done()
###
it "can handle many engines, many operations, concurrently (random)", ->
console.log "" # TODO
@yTest.run()
it "has a working test suite", ->
@yTest.compareAll()
###
it "Create Xml Element", ->
@u1.attr("stuff", "true")
console.log(@u1.toString())
@yTest.compareAll()
describe "has method ", ->
it "attr", ->
@u1.attr("attr", "newAttr")
@u1.attr("other_attr", "newAttr")
@yTest.compareAll()
expect(@u2.attr("attr")).to.equal("newAttr")
expect(@u2.attr().other_attr).to.equal("newAttr")
it "addClass", ->
@u1.addClass("newClass")
@u2.addClass("otherClass")
@yTest.compareAll()
expect(@u1.attr("class")).to.equal("newClass otherClass") # 1 < 2 and therefore this is the proper order
it "append", ->
child = new Y.Xml("child")
child2 = new Y.Xml("child2")
@u1.append child
@u1.append child2
expect(@u1.toString()).to.equal("<root><child></child><child2></child2></root>")
@yTest.compareAll()
it "prepend", ->
child = new Y.Xml("child")
child2 = new Y.Xml("child2")
@u1.prepend child2
@u1.prepend child
expect(@u1.toString()).to.equal("<root><child></child><child2></child2></root>")
@yTest.compareAll()
it "after", ->
child = new Y.Xml("child")
@u1.append child
child.after new Y.Xml("right-child")
expect(@u1.toString()).to.equal("<root><child></child><right-child></right-child></root>")
@yTest.compareAll()
it "before", ->
child = new Y.Xml("child")
@u1.append child
child.before new Y.Xml("left-child")
expect(@u1.toString()).to.equal("<root><left-child></left-child><child></child></root>")
@yTest.compareAll()
it "empty", ->
child = new Y.Xml("child")
@u1.append child
child.before new Y.Xml("left-child")
expect(@u1.toString()).to.equal("<root><left-child></left-child><child></child></root>")
@yTest.compareAll()
@u1.empty()
expect(@u1.toString()).to.equal("<root></root>")
@yTest.compareAll()
it "remove", ->
child = new Y.Xml("child")
child2 = new Y.Xml("child2")
@u1.prepend child2
@u1.prepend child
expect(@u1.toString()).to.equal("<root><child></child><child2></child2></root>")
@yTest.compareAll()
child2.remove()
expect(@u1.toString()).to.equal("<root><child></child></root>")
it "removeAttr", ->
@u1.attr("dtrn", "stuff")
@u1.attr("dutrianern", "stuff")
@yTest.compareAll()
@u2.removeAttr("dtrn")
@yTest.compareAll()
@expect(@u3.attr("dtrn")).to.be.undefined
it "removeClass", ->
@u1.addClass("dtrn")
@u1.addClass("iExist")
@yTest.compareAll()
@u2.removeClass("dtrn")
@yTest.compareAll()
@expect(@u3.attr("class")).to.equal("iExist")
it "toggleClass", ->
@u1.addClass("dtrn")
@u1.addClass("iExist")
@yTest.compareAll()
@u2.removeClass("dtrn")
@yTest.compareAll()
@expect(@u3.attr("class")).to.equal("iExist")
@u3.toggleClass("iExist")
@u3.toggleClass("wraa")
@yTest.compareAll()
expect(@u1.attr("class")).to.equal("wraa")
it "getParent", ->
child = new Y.Xml("child")
@u1.prepend(child)
expect(@u1).to.equal(child.getParent())
it "getChildren", ->
child = new Y.Xml("child")
@u1.prepend(child)
expect(@u1.getChildren()[0]).to.equal(child)