extjs-gpl
Version:
GPL licensed version of Sencha Ext JS
1,321 lines (1,010 loc) • 57.4 kB
JavaScript
/* global expect, Ext, jasmine, spyOn */
describe('Ext.data.NodeInterface', function() {
var fakeScope = {};
function spyOnEvent(object, eventName, fn) {
var obj = {
fn: fn || Ext.emptyFn
},
spy = spyOn(obj, "fn");
object.addListener(eventName, obj.fn);
return spy;
}
beforeEach(function() {
Ext.define('spec.TreeNode', {
extend: 'Ext.data.TreeModel',
fields: [
{name: 'text', type: 'string'}
],
proxy: {
type: 'memory'
}
});
});
afterEach(function() {
Ext.undefine('spec.TreeNode');
Ext.data.Model.schema.clear();
});
describe('decorating', function() {
var fields;
beforeEach(function() {
fields = spec.TreeNode.prototype.fieldsMap;
});
it('should decorate the Model with a parentId field that has the same type as the idProperty', function() {
var field = fields.parentId,
type = fields[spec.TreeNode.idProperty].getType();
expect(field.getPersist()).toBe(true);
expect(field.getType()).toBe(type);
expect(field.getDefaultValue()).toBeNull();
});
it('should decorate the Model with an index field', function() {
var field = fields.index;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('int');
expect(field.getDefaultValue()).toBe(-1);
});
it('should decorate the Model with a depth field', function() {
var field = fields.depth;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('int');
expect(field.getDefaultValue()).toBe(0);
});
it('should decorate the Model with an expanded field', function() {
var field = fields.expanded;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('bool');
expect(field.getDefaultValue()).toBe(false);
});
it('should decorate the Model with an expandable field', function() {
var field = fields.expandable;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('bool');
expect(field.getDefaultValue()).toBe(true);
});
it('should decorate the Model with a checked field', function() {
var field = fields.checked;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('auto');
expect(field.getDefaultValue()).toBe(null);
});
it('should decorate the Model with a leaf field', function() {
var field = fields.leaf;
expect(field.getPersist()).toBe(true);
expect(field.getType()).toBe('bool');
expect(field.getDefaultValue()).toBe(false);
});
it('should decorate the Model with a cls field', function() {
var field = fields.cls;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('string');
expect(field.getDefaultValue()).toBe('');
});
it('should decorate the Model with an iconCls field', function() {
var field = fields.iconCls;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('string');
expect(field.getDefaultValue()).toBe('');
});
it('should decorate the Model with an icon field', function() {
var field = fields.icon;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('string');
expect(field.getDefaultValue()).toBe('');
});
it('should decorate the Model with a root field', function() {
var field = fields.root;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('bool');
expect(field.getDefaultValue()).toBe(false);
});
it('should decorate the Model with an isLast field', function() {
var field = fields.isLast;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('bool');
expect(field.getDefaultValue()).toBe(false);
});
it('should decorate the Model with an isFirst field', function() {
var field = fields.isFirst;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('bool');
expect(field.getDefaultValue()).toBe(false);
});
it('should decorate the Model with an allowDrop field', function() {
var field = fields.allowDrop;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('bool');
expect(field.getDefaultValue()).toBe(true);
});
it('should decorate the Model with an allowDrag field', function() {
var field = fields.allowDrag;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('bool');
expect(field.getDefaultValue()).toBe(true);
});
it('should decorate the Model with a loaded field', function() {
var field = fields.loaded;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('bool');
expect(field.getDefaultValue()).toBe(false);
});
it('should decorate the Model with a loading field', function() {
var field = fields.loading;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('bool');
expect(field.getDefaultValue()).toBe(false);
});
it('should decorate the Model with an href field', function() {
var field = fields.href;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('string');
expect(field.getDefaultValue()).toBe('');
});
it('should decorate the Model with an hrefTarget field', function() {
var field = fields.hrefTarget;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('string');
expect(field.getDefaultValue()).toBe('');
});
it('should decorate the Model with a qtip field', function() {
var field = fields.qtip;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('string');
expect(field.getDefaultValue()).toBe('');
});
it('should decorate the Model with a qtitle field', function() {
var field = fields.qtitle;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('string');
expect(field.getDefaultValue()).toBe('');
});
it('should decorate the Model with a children field', function() {
var field = fields.children;
expect(field.getPersist()).toBe(false);
expect(field.getType()).toBe('auto');
expect(field.getDefaultValue()).toBe(null);
});
it('should decorate Model class of a given record', function() {
var MyModel, record1, record2;
MyModel = Ext.define('spec.MyModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'text', type: 'string'}
],
proxy: {
type: 'memory'
}
});
record1 = MyModel.create({text: 'record1'});
record2 = MyModel.create({text: 'record2'});
expect(MyModel.prototype.isNode).toBeUndefined();
expect(record1.isNode).toBeUndefined();
expect(record2.isNode).toBeUndefined();
Ext.data.NodeInterface.decorate(record1);
expect(MyModel.prototype.isNode).toBeTruthy();
expect(record1.isNode).toBeTruthy();
expect(record2.isNode).toBeTruthy();
Ext.undefine('spec.MyModel');
});
});
describe('methods', function() {
var leftChild, rightChild, rootNode, spareNode, spy;
function insertDefaultChildren() {
rootNode.appendChild(leftChild);
rootNode.appendChild(rightChild);
rootNode.updateInfo(false, {
isFirst: true,
isLast: true,
depth: 0,
index: 0,
parentId: null
});
}
beforeEach(function() {
leftChild = new spec.TreeNode({
id: 'left'
});
rightChild = new spec.TreeNode({
id: 'right'
});
rootNode = new spec.TreeNode({
id: 'root'
});
//we use this in several tests as an example node to add
spareNode = new spec.TreeNode({
id: 'spare'
});
});
describe("isFirst", function() {
beforeEach(function() {
insertDefaultChildren.call(this);
});
it("should have rootNode which is first", function() {
expect(rootNode.isFirst()).toBe(true);
});
it("should have leftChild which is first", function() {
expect(leftChild.isFirst()).toBe(true);
});
it("should have rightChild which is not first", function() {
expect(rightChild.isFirst()).toBe(false);
});
});
describe("isLast", function() {
beforeEach(function(){
insertDefaultChildren.call(this);
});
it("should have rootNode which is last", function() {
expect(rootNode.isLast()).toBe(true);
});
it("should have leftChild which is not last", function() {
expect(leftChild.isLast()).toBe(false);
});
it("should have rightChild which is last", function() {
expect(rightChild.isLast()).toBe(true);
});
});
describe("hasChildNodes", function() {
beforeEach(function() {
rootNode.appendChild(leftChild);
});
it("should have rootNode with children", function() {
expect(rootNode.hasChildNodes()).toBe(true);
});
it("should have leftChild whithout children", function() {
expect(leftChild.hasChildNodes()).toBe(false);
});
});
describe("isExpandable", function() {
it("should have node expandable if it has children", function() {
spareNode.appendChild(leftChild);
expect(spareNode.isExpandable()).toBe(true);
});
it("should have node expandable if has no children", function() {
expect(spareNode.isExpandable()).toBe(true);
});
it("should have node not expandable if it is a leaf node", function() {
spareNode.set('leaf', true);
expect(spareNode.isExpandable()).toBe(false);
});
});
describe("append", function(){
describe("appending children", function() {
it("should fire beforeappend", function() {
spy = spyOnEvent(rootNode, "beforeappend").andCallThrough();
rootNode.appendChild(leftChild);
expect(spy).toHaveBeenCalledWith(rootNode, leftChild);
});
it("should cancel append if beforeappend return false", function() {
spy = spyOnEvent(rootNode, "beforeappend").andReturn(false);
expect(rootNode.appendChild(leftChild)).toBe(false);
expect(spy.callCount).toEqual(1);
});
it("should set firstChild", function() {
rootNode.appendChild(leftChild);
expect(rootNode.firstChild).toEqual(leftChild);
});
it("should set lastChild", function() {
rootNode.appendChild(leftChild);
expect(rootNode.lastChild).toEqual(leftChild);
});
it("should add node to childnodes", function() {
var childNodes;
rootNode.appendChild(leftChild);
childNodes = rootNode.childNodes;
expect(childNodes.length).toEqual(1);
expect(childNodes[0]).toEqual(leftChild);
});
it("should fire append event", function() {
spy = spyOnEvent(rootNode, "append").andCallThrough();
rootNode.appendChild(leftChild);
expect(spy).toHaveBeenCalledWith(rootNode, leftChild, 0);
});
it("should return node", function() {
var ret = rootNode.appendChild(leftChild);
expect(ret).toEqual(leftChild);
});
it("should append array of nodes", function() {
rootNode.appendChild([leftChild, rightChild]);
var childNodes = rootNode.childNodes;
expect(childNodes[0]).toEqual(leftChild);
expect(childNodes[1]).toEqual(rightChild);
expect(childNodes.length).toEqual(2);
});
});
describe("appending with existing siblings", function() {
beforeEach(function() {
insertDefaultChildren.call(this);
});
it("should set next sibling", function() {
expect(leftChild.nextSibling).toEqual(rightChild);
expect(rightChild.nextSibling).toBeNull();
});
it("should set previous sibling", function() {
expect(rightChild.previousSibling).toEqual(leftChild);
expect(leftChild.previousSibling).toBeNull();
});
});
describe("appending children from an existing node", function() {
var oldParent, spy;
beforeEach(function() {
oldParent = new spec.TreeNode({id: 'oldparent'});
oldParent.appendChild(spareNode);
});
it("should remove from existing node", function() {
spy = spyOn(oldParent, "removeChild").andCallThrough();
rootNode.appendChild(spareNode);
expect(spy).toHaveBeenCalledWith(spareNode, false, undefined, true);
});
it("should fire beforeremove event", function(){
spy = spyOnEvent(oldParent, "beforeremove").andCallThrough();
rootNode.appendChild(spareNode);
expect(spy).toHaveBeenCalledWith(oldParent, spareNode, true);
});
it("should fire remove event", function(){
spy = spyOnEvent(oldParent, "remove").andCallThrough();
rootNode.appendChild(spareNode);
// Just use the context argumemt from the args as the last arg
expect(spy).toHaveBeenCalledWith(oldParent, spareNode, true, spy.mostRecentCall.args[3]);
});
it("should fire beforemove event", function() {
spy = spyOnEvent(spareNode, "beforemove").andCallThrough();
rootNode.appendChild(spareNode);
expect(spy).toHaveBeenCalledWith(spareNode, oldParent, rootNode, 0);
});
it("should fire move event", function() {
spy = spyOnEvent(spareNode, "move").andCallThrough();
rootNode.appendChild(spareNode);
expect(spy).toHaveBeenCalledWith(spareNode, oldParent, rootNode, 0);
});
});
});
describe("insert", function(){
beforeEach(function(){
rootNode.appendChild(rightChild);
});
describe("inserting children", function() {
it("should call appendChild if the node to insert before is null", function() {
spy = spyOn(rootNode, "appendChild");
rootNode.insertBefore(leftChild);
expect(spy).toHaveBeenCalledWith(leftChild);
});
it("should do nothing if the node to insert before is equal to the node to insert", function() {
expect(rootNode.insertBefore(leftChild, leftChild)).toBe(false);
});
it("should fire beforeinsert", function() {
spy = spyOnEvent(rootNode, "beforeinsert").andCallThrough();
rootNode.insertBefore(leftChild, rightChild);
expect(spy).toHaveBeenCalledWith(rootNode, leftChild, rightChild);
});
it("should cancel insert if beforeinsert return false", function() {
spy = spyOnEvent(rootNode, "beforeinsert").andReturn(false);
expect(rootNode.insertBefore(leftChild, rightChild)).toBe(false);
expect(spy.callCount).toEqual(1);
});
it("should set firstChild", function() {
rootNode.insertBefore(leftChild, rightChild);
expect(rootNode.firstChild).toEqual(leftChild);
});
it("should set lastChild", function() {
rootNode.insertBefore(leftChild, rightChild);
expect(rootNode.lastChild).toEqual(rightChild);
});
it("should fire insert", function() {
spy = spyOnEvent(rootNode, "insert").andCallThrough();
rootNode.insertBefore(leftChild, rightChild);
expect(spy).toHaveBeenCalledWith(rootNode, leftChild, rightChild);
});
it("should update indexes for all siblings after the position where the node was inserted", function() {
rootNode.insertBefore(spareNode, rightChild);
rootNode.insertBefore(leftChild, spareNode);
expect(spareNode.get('index')).toEqual(1);
expect(rightChild.get('index')).toEqual(2);
});
it("should handle siblings", function(){
expect(leftChild.previousSibling).toBeNull();
expect(leftChild.nextSibling).toBeNull();
expect(rightChild.previousSibling).toBeNull();
expect(rightChild.nextSibling).toBeNull();
rootNode.insertBefore(leftChild, rightChild);
expect(leftChild.previousSibling).toBeNull();
expect(leftChild.nextSibling).toEqual(rightChild);
expect(rightChild.previousSibling).toEqual(leftChild);
expect(rightChild.nextSibling).toBeNull();
});
describe("move", function() {
beforeEach(function() {
rootNode.appendChild(leftChild);
});
it("should fire beforemove", function() {
spy = spyOnEvent(leftChild, "beforemove").andCallThrough();
rootNode.insertBefore(leftChild, rightChild);
expect(spy).toHaveBeenCalledWith(leftChild, rootNode, rootNode, 0, rightChild);
});
it("should cancel insert if beforemove return false", function() {
spy = spyOnEvent(leftChild, "beforemove").andReturn(false);
expect(rootNode.insertBefore(leftChild, rightChild)).toBe(false);
expect(spy.callCount).toEqual(1);
});
it("should fire move", function() {
spy = spyOnEvent(leftChild, "move").andCallThrough();
rootNode.insertBefore(leftChild, rightChild);
expect(spy).toHaveBeenCalledWith(leftChild, rootNode, rootNode, 0, rightChild);
});
});
});
});
describe("removing children", function() {
it("should return false when removing bad node", function(){
expect(rootNode.removeChild(leftChild)).toBe(false);
});
it("should fire beforeremove event", function(){
insertDefaultChildren.call(this);
spy = spyOnEvent(rootNode, "beforeremove").andCallThrough();
rootNode.removeChild(leftChild);
expect(spy).toHaveBeenCalledWith(rootNode, leftChild, false);
});
it("should cancel remove if beforeremove returns false", function() {
insertDefaultChildren.call(this);
spy = spyOnEvent(rootNode, "beforeremove").andReturn(false);
expect(rootNode.removeChild(leftChild)).toBe(false);
expect(spy.callCount).toEqual(1);
});
it("should fire remove event", function() {
insertDefaultChildren.call(this);
spy = spyOnEvent(rootNode, "remove").andCallThrough();
rootNode.removeChild(leftChild);
// Just use the context argumemt from the args as the last arg
expect(spy).toHaveBeenCalledWith(rootNode, leftChild, false, spy.mostRecentCall.args[3]);
});
it("should remove child from childNodes", function() {
var childNodes, count;
insertDefaultChildren.call(this);
childNodes = rootNode.childNodes;
count = childNodes.length;
rootNode.removeChild(leftChild);
expect(childNodes.length).toEqual(count - 1);
expect(childNodes[0]).toEqual(rightChild);
});
it("should manage siblings", function() {
insertDefaultChildren.call(this);
//this gives us a third child - 'right' is actually now center
rootNode.appendChild(spareNode);
rootNode.removeChild(rightChild);
expect(leftChild.nextSibling, spareNode);
expect(spareNode.previousSibling, leftChild);
});
it("should erase node if asked", function() {
insertDefaultChildren.call(this);
spy = spyOn(leftChild, "erase").andCallThrough();
rootNode.removeChild(leftChild, true);
expect(spy).toHaveBeenCalled();
});
it("should clear node if asked", function() {
insertDefaultChildren.call(this);
spy = spyOn(leftChild, "clear").andCallThrough();
rootNode.removeChild(leftChild, false);
expect(spy).toHaveBeenCalled();
});
it("should update indexes for all siblings after the node's old position", function() {
insertDefaultChildren.call(this);
rootNode.appendChild(spareNode);
rootNode.removeChild(leftChild);
expect(rightChild.get('index')).toEqual(0);
expect(spareNode.get('index')).toEqual(1);
});
});
describe("clearing references", function() {
beforeEach(function(){
insertDefaultChildren.call(this);
rootNode.appendChild(spareNode);
});
it("should nullify parentNode", function() {
expect(rightChild.parentNode).not.toBeNull();
rightChild.clear();
expect(rightChild.parentNode).toBeNull();
});
it("should nullifies nextSibling", function() {
expect(rightChild.nextSibling).not.toBeNull();
rightChild.clear();
expect(rightChild.nextSibling).toBeNull();
});
it("should nullifies previousSibling", function() {
expect(rightChild.previousSibling).not.toBeNull();
rightChild.clear();
expect(rightChild.previousSibling).toBeNull();
});
it("should remove lastChild and firstChild references", function() {
rightChild.clear(true);
expect(rightChild.firstChild).toBeNull();
expect(rightChild.lastChild).toBeNull();
});
});
describe("item", function() {
it("should return the child node at the specified index", function() {
rootNode.appendChild(leftChild);
rootNode.appendChild(rightChild);
rootNode.appendChild(spareNode);
expect(rootNode.getChildAt(0)).toEqual(leftChild);
expect(rootNode.getChildAt(1)).toEqual(rightChild);
expect(rootNode.getChildAt(2)).toEqual(spareNode);
});
});
describe("silent destroy", function() {
it("should purge node listeners", function() {
spy = spyOn(leftChild, "clearListeners").andCallThrough();
leftChild.destroy();
expect(spy).toHaveBeenCalled();
});
it("should erase children", function() {
var spy2;
insertDefaultChildren.call(this);
spy = spyOn(leftChild, "erase").andCallThrough();
spy2 = spyOn(rightChild, "erase").andCallThrough();
rootNode.erase();
expect(spy).toHaveBeenCalled();
expect(spy2).toHaveBeenCalled();
});
it("should nullify childNodes", function() {
insertDefaultChildren.call(this);
expect(rootNode.childNodes).not.toBeNull();
rootNode.erase(true);
expect(rootNode.childNodes).toBeNull();
});
});
describe("non-silent destroy", function() {
it("should remove node", function() {
insertDefaultChildren.call(this);
spy = spyOn(leftChild, "remove").andCallThrough();
leftChild.erase(false);
expect(spy).toHaveBeenCalled();
});
});
describe("remove", function() {
it("should remove from parent", function() {
spy = spyOn(rootNode, "removeChild").andCallThrough();
rootNode.appendChild(leftChild);
leftChild.remove();
expect(spy).toHaveBeenCalledWith(leftChild, undefined, undefined);
});
it("should return node", function() {
expect(leftChild.remove()).toEqual(leftChild);
});
});
describe("removeAll", function() {
it("should remove all children", function() {
rootNode.appendChild([leftChild, rightChild, spareNode]);
rootNode.removeAll();
expect(rootNode.childNodes.length).toBe(0);
});
});
describe("replacing children", function() {
beforeEach(function() {
insertDefaultChildren.call(this);
});
it("should keep the same childNodes length", function() {
var count = rootNode.childNodes.length;
rootNode.replaceChild(spareNode, leftChild);
expect(rootNode.childNodes.length).toEqual(count);
});
it("should replace node", function() {
rootNode.replaceChild(spareNode, leftChild);
expect(rootNode.childNodes[0], spareNode);
});
});
describe("getting depth", function() {
beforeEach(function() {
insertDefaultChildren.call(this);
leftChild.appendChild(spareNode);
});
it("should have a depth of 0 for rootNode", function(){
expect(rootNode.getDepth()).toEqual(0);
});
it("should have a depth of 1 for leftChild and rightChild", function(){
expect(rightChild.getDepth()).toEqual(1);
expect(leftChild.getDepth()).toEqual(1);
});
it("should have a depth of 2 for spareNode", function(){
expect(spareNode.getDepth()).toEqual(2);
});
});
describe("getting path", function() {
beforeEach(function() {
insertDefaultChildren.call(this);
leftChild.appendChild(spareNode);
});
it("should set root path", function() {
expect(rootNode.getPath()).toEqual("/root");
});
it("should set middle path", function() {
expect(leftChild.getPath()).toEqual("/root/left");
expect(rightChild.getPath()).toEqual("/root/right");
});
it("should set leaf path", function() {
expect(spareNode.getPath()).toEqual("/root/left/spare");
});
});
describe("indexOf", function(){
it("should always return -1 when the node is empty", function(){
expect(rootNode.indexOf(spareNode)).toBe(-1);
});
it("should return -1 when the passed node is not a child", function(){
rootNode.appendChild(leftChild);
expect(rootNode.indexOf(spareNode)).toBe(-1);
});
it("should return the correct index when the node exists", function(){
rootNode.appendChild([leftChild, spareNode, rightChild]);
expect(rootNode.indexOf(spareNode)).toBe(1);
});
});
describe("indexOfId", function(){
it("should always return -1 when the node is empty", function(){
expect(rootNode.indexOfId('spare')).toBe(-1);
});
it("should return -1 when the passed node is not a child", function(){
rootNode.appendChild(leftChild);
expect(rootNode.indexOfId('spare')).toBe(-1);
});
it("should return the correct index when the node exists", function(){
rootNode.appendChild([leftChild, spareNode, rightChild]);
expect(rootNode.indexOfId('spare')).toBe(1);
});
});
describe("bubbling", function() {
var bubbleFn;
beforeEach(function() {
insertDefaultChildren.call(this);
leftChild.appendChild(spareNode);
bubbleFn = jasmine.createSpy();
});
it("should call bubbleFn 3 times", function() {
spareNode.bubble(bubbleFn);
expect(bubbleFn.callCount).toEqual(3);
});
it("should call bubbleFn with node spare, left, root", function() {
spareNode.bubble(bubbleFn);
expect(bubbleFn.calls[0].args).toEqual([spareNode]);
expect(bubbleFn.calls[1].args).toEqual([leftChild]);
expect(bubbleFn.calls[2].args).toEqual([rootNode]);
});
it("should call bubbleFn with a defined scope", function() {
spareNode.bubble(bubbleFn, fakeScope);
expect(bubbleFn.calls[0].object).toBe(fakeScope);
expect(bubbleFn.calls[1].object).toBe(fakeScope);
expect(bubbleFn.calls[2].object).toBe(fakeScope);
});
it("should call bubbleFn with customs arguments", function() {
var customArgs = ['some', 'args'];
spareNode.bubble(bubbleFn, spareNode, customArgs);
expect(bubbleFn.calls[0].args).toEqual(customArgs);
expect(bubbleFn.calls[1].args).toEqual(customArgs);
expect(bubbleFn.calls[2].args).toEqual(customArgs);
});
it("should stop when bubbleFn return false", function() {
bubbleFn.andCallFake(function(node) {
if (node.getId() === 'left') {
return false;
}
});
spareNode.bubble(bubbleFn);
expect(bubbleFn.callCount).toEqual(2);
});
});
describe("cascading", function() {
var cascadeFn;
beforeEach(function(){
insertDefaultChildren.call(this);
leftChild.appendChild(spareNode);
cascadeFn = jasmine.createSpy();
});
it("should call cascadeFn 4 times", function() {
rootNode.cascade(cascadeFn);
expect(cascadeFn.callCount).toEqual(4);
});
it("should call cascadeFn with node root, leftChild, spareNode, rightChild", function() {
rootNode.cascade(cascadeFn);
expect(cascadeFn.calls[0].args).toEqual([rootNode]);
expect(cascadeFn.calls[1].args).toEqual([leftChild]);
expect(cascadeFn.calls[2].args).toEqual([spareNode]);
expect(cascadeFn.calls[3].args).toEqual([rightChild]);
});
it("should call cascadeFn with a defined scope", function() {
rootNode.cascade(cascadeFn, fakeScope);
expect(cascadeFn.calls[0].object).toBe(fakeScope);
expect(cascadeFn.calls[1].object).toBe(fakeScope);
expect(cascadeFn.calls[2].object).toBe(fakeScope);
expect(cascadeFn.calls[3].object).toBe(fakeScope);
});
it("should call cascadeFn with customs arguments", function() {
var customArgs = ['some', 'args'];
rootNode.cascade(cascadeFn, rootNode, customArgs);
expect(cascadeFn.calls[0].args).toEqual(customArgs);
expect(cascadeFn.calls[1].args).toEqual(customArgs);
expect(cascadeFn.calls[2].args).toEqual(customArgs);
expect(cascadeFn.calls[3].args).toEqual(customArgs);
});
it("should stop at end of branch when cascadeFn return false", function() {
cascadeFn.andCallFake(function(node) {
if (node.getId() === 'left') {
return false;
}
});
rootNode.cascade(cascadeFn);
expect(cascadeFn.callCount).toEqual(3);
});
});
describe("each child", function() {
var eachFn;
beforeEach(function (){
insertDefaultChildren.call(this);
eachFn = jasmine.createSpy();
});
it("should be called 2 times", function() {
rootNode.eachChild(eachFn);
expect(eachFn.callCount).toEqual(2);
});
it("should call eachFn with node root, leftChild, rightChild", function() {
rootNode.eachChild(eachFn);
expect(eachFn.calls[0].args).toEqual([leftChild]);
expect(eachFn.calls[1].args).toEqual([rightChild]);
});
it("should call eachFn with a defined scope", function() {
rootNode.eachChild(eachFn, fakeScope);
expect(eachFn.calls[0].object).toBe(fakeScope);
expect(eachFn.calls[1].object).toBe(fakeScope);
});
it("should call eachFn with customs arguments", function() {
var customArgs = ['some', 'args'];
rootNode.eachChild(eachFn, rootNode, customArgs);
expect(eachFn.calls[0].args).toEqual(customArgs);
expect(eachFn.calls[1].args).toEqual(customArgs);
});
it("should stop when eachFn return false", function() {
eachFn.andCallFake(function(node) {
if (node.getId() === 'left') {
return false;
}
});
rootNode.eachChild(eachFn);
expect(eachFn.callCount).toEqual(1);
});
});
describe("ancestors", function() {
beforeEach(function (){
insertDefaultChildren.call(this);
leftChild.appendChild(spareNode);
});
it("should have parent as ancestor", function() {
expect(spareNode.isAncestor(leftChild)).toBe(true);
});
it("should have root as ancestor", function() {
expect(spareNode.isAncestor(rootNode)).toBe(true);
});
it("should not have uncle as ancestor", function() {
expect(spareNode.isAncestor(rightChild)).toBe(false);
});
});
describe("contains", function() {
beforeEach(function (){
insertDefaultChildren.call(this);
leftChild.appendChild(spareNode);
});
it("should contain child", function() {
expect(rootNode.contains(leftChild)).toBe(true);
});
it("should contain grand child", function() {
expect(rootNode.contains(spareNode)).toBe(true);
});
it("should not contain parent", function() {
expect(spareNode.contains(leftChild)).toBe(false);
});
});
describe("finding children", function() {
beforeEach(function (){
insertDefaultChildren.call(this);
leftChild.appendChild(spareNode);
});
describe("findChild", function() {
it("should find shallow children", function() {
expect(rootNode.findChild('id', 'left')).toEqual(leftChild);
});
it("should not find deep children if deep is not specified", function() {
expect(rootNode.findChild('id', 'spare')).toBeNull();
});
it("should not find deep children if deep is false", function() {
expect(rootNode.findChild('id', 'spare', false)).toBeNull();
});
it("should find deep children if deep is true", function() {
expect(rootNode.findChild('id', 'spare', true)).toEqual(spareNode);
});
});
describe("findChildBy", function() {
var child;
it("should find shallow children", function(){
child = rootNode.findChildBy(function(node) {
return node.getId() === 'right';
});
expect(child).toEqual(rightChild);
});
it("should not find deep children if deep is not specified", function(){
child = rootNode.findChildBy(function(node) {
return node.getId() === 'spare';
});
expect(child).toBeNull();
});
it("should not find deep children if deep is false", function(){
child = rootNode.findChildBy(function(node) {
return node.getId() === 'spare';
}, this, false);
expect(child).toBeNull();
});
it("should find deep children if deep is true", function(){
child = rootNode.findChildBy(function(node) {
return node.getId() === 'spare';
}, this, true);
expect(child).toEqual(spareNode);
});
it("should call function with good scope", function(){
var findChildFn = jasmine.createSpy().andReturn(false);
child = rootNode.findChildBy(findChildFn, fakeScope, true);
expect(findChildFn.calls[0].object).toBe(fakeScope);
expect(findChildFn.calls[1].object).toBe(fakeScope);
expect(findChildFn.calls[2].object).toBe(fakeScope);
});
});
});
describe("sort", function() {
var node1,
node2,
node3,
node4,
sortFn;
beforeEach(function() {
Ext.define('spec.EmployeeTreeNode', {
extend: 'Ext.data.Model',
fields: [
{ name: 'lastname', type: 'string' },
{ name: 'firstname', type: 'string' }
]
});
Ext.data.NodeInterface.decorate(spec.EmployeeTreeNode);
node1 = new spec.EmployeeTreeNode({lastname: "Avins", firstname: "Jamie"});
node2 = new spec.EmployeeTreeNode({lastname: "Dougan", firstname: "Robert"});
node3 = new spec.EmployeeTreeNode({lastname: "Ferrero", firstname: "Nicolas"});
node4 = new spec.EmployeeTreeNode({lastname: "Spencer", firstname: "Edward"});
rootNode.appendChild([node4, node2, node3, node1]);
sortFn = jasmine.createSpy();
sortFn.andCallFake(function(a, b){
if (a.get('lastname') === b.get('lastname')) {
return 0;
}
return (a.get('lastname') < b.get('lastname')) ? -1 : 1;
});
rootNode.sort(sortFn);
});
afterEach(function() {
Ext.undefine('spec.EmployeeTreeNode');
});
it("should sort the child by lastname with the correct function", function() {
expect(rootNode.childNodes[0]).toEqual(node1);
expect(rootNode.childNodes[1]).toEqual(node2);
expect(rootNode.childNodes[2]).toEqual(node3);
expect(rootNode.childNodes[3]).toEqual(node4);
});
});
describe("copy", function(){
it("should not copy childNodes by default", function(){
var node = new spec.TreeNode({
text: 'Text',
id: 1
});
var newNode = node.copy();
expect(newNode.getData()).toEqual({
allowDrag: true,
allowDrop: true,
checked: null,
children: null,
cls: '',
depth: 0,
expandable: true,
expanded: false,
href: '',
hrefTarget: '',
icon: '',
iconCls: '',
glyph: '',
id: 1,
index: -1,
isFirst: false,
isLast: false,
leaf: false,
loaded: false,
loading: false,
parentId: null,
qtip: '',
qtitle: '',
qshowDelay: 0,
root: false,
text: 'Text',
visible: true
});
});
it("should accept a new id", function(){
var node = new spec.TreeNode({
text: 'Text',
id: 1
});
var newNode = node.copy(2);
expect(newNode.getData()).toEqual({
allowDrag: true,
allowDrop: true,
checked: null,
children: null,
cls: '',
depth: 0,
expandable: true,
expanded: false,
href: '',
hrefTarget: '',
icon: '',
iconCls: '',
glyph: '',
id: 2,
index: -1,
isFirst: false,
isLast: false,
leaf: false,
loaded: false,
loading: false,
parentId: null,
qtip: '',
qtitle: '',
qshowDelay: 0,
root: false,
text: 'Text',
visible: true
});
});
it("should clone children if deep: true is specified", function(){
var root = new spec.TreeNode({
id: 1,
text: 'Root'
});
var child1 = root.appendChild(new spec.TreeNode({
id: 2,
text: 'Child1'
}));
var child2 = child1.appendChild(new spec.TreeNode({
id: 3,
text: 'Child2'
}));
child2.appendChild(new spec.TreeNode({
id: 4,
text: 'Child3'
}));
var session,
newNode = root.copy(undefined, true);
expect(newNode.childNodes[0].getId()).toBe(2);
expect(newNode.childNodes[0].get('text')).toBe('Child1');
newNode = newNode.childNodes[0];
expect(newNode.childNodes[0].getId()).toBe(3);
expect(newNode.childNodes[0].get('text')).toBe('Child2');
newNode = newNode.childNodes[0];
expect(newNode.childNodes[0].getId()).toBe(4);
expect(newNode.childNodes[0].get('text')).toBe('Child3');
// Test new API (newId, session, deep)
newNode = root.copy(undefined, null, true);
expect(newNode.childNodes[0].getId()).toBe(2);
expect(newNode.childNodes[0].get('text')).toBe('Child1');
newNode = newNode.childNodes[0];
expect(newNode.childNodes[0].getId()).toBe(3);
expect(newNode.childNodes[0].get('text')).toBe('Child2');
newNode = newNode.childNodes[0];
expect(newNode.childNodes[0].getId()).toBe(4);
expect(newNode.childNodes[0].get('text')).toBe('Child3');
// Test new API (newId, session, deep)
session = new Ext.data.Session();
newNode = root.copy(undefined, session, true);
expect(newNode.childNodes[0].getId()).toBe(2);
expect(newNode.childNodes[0].get('text')).toBe('Child1');
// Copy must be in new session
expect(session.peekRecord(spec.TreeNode, newNode.id)).toBe(newNode);
newNode = newNode.childNodes[0];
expect(newNode.childNodes[0].getId()).