UNPKG

extjs-gpl

Version:

GPL licensed version of Sencha Ext JS

1,321 lines (1,010 loc) 57.4 kB
/* 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()).