]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | describe('Ext.data.NodeInterface', function() {\r |
2 | function spyOnEvent(object, eventName, fn) {\r | |
3 | var obj = {\r | |
4 | fn: fn || Ext.emptyFn\r | |
5 | },\r | |
6 | spy = spyOn(obj, "fn");\r | |
7 | object.addListener(eventName, obj.fn);\r | |
8 | return spy;\r | |
9 | }\r | |
10 | \r | |
11 | beforeEach(function() {\r | |
12 | Ext.define('spec.TreeNode', {\r | |
13 | extend: 'Ext.data.TreeModel',\r | |
14 | fields: [\r | |
15 | {name: 'text', type: 'string'}\r | |
16 | ],\r | |
17 | proxy: {\r | |
18 | type: 'memory'\r | |
19 | }\r | |
20 | });\r | |
21 | });\r | |
22 | \r | |
23 | afterEach(function() {\r | |
24 | Ext.undefine('spec.TreeNode');\r | |
25 | Ext.data.Model.schema.clear();\r | |
26 | });\r | |
27 | \r | |
28 | describe('decorating', function() {\r | |
29 | var fields;\r | |
30 | \r | |
31 | beforeEach(function() {\r | |
32 | fields = spec.TreeNode.prototype.fieldsMap;\r | |
33 | });\r | |
34 | \r | |
35 | it('should decorate the Model with a parentId field that has the same type as the idProperty', function() {\r | |
36 | var field = fields.parentId,\r | |
37 | type = fields[spec.TreeNode.idProperty].getType();\r | |
38 | \r | |
39 | expect(field.getPersist()).toBe(true);\r | |
40 | expect(field.getType()).toBe(type);\r | |
41 | expect(field.getDefaultValue()).toBeNull();\r | |
42 | });\r | |
43 | it('should decorate the Model with an index field', function() {\r | |
44 | var field = fields.index;\r | |
45 | \r | |
46 | expect(field.getPersist()).toBe(false);\r | |
47 | expect(field.getType()).toBe('int');\r | |
48 | expect(field.getDefaultValue()).toBe(-1);\r | |
49 | });\r | |
50 | it('should decorate the Model with a depth field', function() {\r | |
51 | var field = fields.depth;\r | |
52 | \r | |
53 | expect(field.getPersist()).toBe(false);\r | |
54 | expect(field.getType()).toBe('int');\r | |
55 | expect(field.getDefaultValue()).toBe(0);\r | |
56 | });\r | |
57 | it('should decorate the Model with an expanded field', function() {\r | |
58 | var field = fields.expanded;\r | |
59 | \r | |
60 | expect(field.getPersist()).toBe(false);\r | |
61 | expect(field.getType()).toBe('bool');\r | |
62 | expect(field.getDefaultValue()).toBe(false);\r | |
63 | });\r | |
64 | it('should decorate the Model with an expandable field', function() {\r | |
65 | var field = fields.expandable;\r | |
66 | \r | |
67 | expect(field.getPersist()).toBe(false);\r | |
68 | expect(field.getType()).toBe('bool');\r | |
69 | expect(field.getDefaultValue()).toBe(true);\r | |
70 | });\r | |
71 | it('should decorate the Model with a checked field', function() {\r | |
72 | var field = fields.checked;\r | |
73 | \r | |
74 | expect(field.getPersist()).toBe(false);\r | |
75 | expect(field.getType()).toBe('auto');\r | |
76 | expect(field.getDefaultValue()).toBe(null);\r | |
77 | });\r | |
78 | it('should decorate the Model with a leaf field', function() {\r | |
79 | var field = fields.leaf;\r | |
80 | \r | |
81 | expect(field.getPersist()).toBe(true);\r | |
82 | expect(field.getType()).toBe('bool');\r | |
83 | expect(field.getDefaultValue()).toBe(false);\r | |
84 | });\r | |
85 | it('should decorate the Model with a cls field', function() {\r | |
86 | var field = fields.cls;\r | |
87 | \r | |
88 | expect(field.getPersist()).toBe(false);\r | |
89 | expect(field.getType()).toBe('string');\r | |
90 | expect(field.getDefaultValue()).toBe('');\r | |
91 | });\r | |
92 | it('should decorate the Model with an iconCls field', function() {\r | |
93 | var field = fields.iconCls;\r | |
94 | \r | |
95 | expect(field.getPersist()).toBe(false);\r | |
96 | expect(field.getType()).toBe('string');\r | |
97 | expect(field.getDefaultValue()).toBe('');\r | |
98 | });\r | |
99 | it('should decorate the Model with an icon field', function() {\r | |
100 | var field = fields.icon;\r | |
101 | \r | |
102 | expect(field.getPersist()).toBe(false);\r | |
103 | expect(field.getType()).toBe('string');\r | |
104 | expect(field.getDefaultValue()).toBe('');\r | |
105 | });\r | |
106 | it('should decorate the Model with a root field', function() {\r | |
107 | var field = fields.root;\r | |
108 | \r | |
109 | expect(field.getPersist()).toBe(false);\r | |
110 | expect(field.getType()).toBe('bool');\r | |
111 | expect(field.getDefaultValue()).toBe(false);\r | |
112 | });\r | |
113 | it('should decorate the Model with an isLast field', function() {\r | |
114 | var field = fields.isLast;\r | |
115 | \r | |
116 | expect(field.getPersist()).toBe(false);\r | |
117 | expect(field.getType()).toBe('bool');\r | |
118 | expect(field.getDefaultValue()).toBe(false);\r | |
119 | });\r | |
120 | it('should decorate the Model with an isFirst field', function() {\r | |
121 | var field = fields.isFirst;\r | |
122 | \r | |
123 | expect(field.getPersist()).toBe(false);\r | |
124 | expect(field.getType()).toBe('bool');\r | |
125 | expect(field.getDefaultValue()).toBe(false);\r | |
126 | });\r | |
127 | it('should decorate the Model with an allowDrop field', function() {\r | |
128 | var field = fields.allowDrop;\r | |
129 | \r | |
130 | expect(field.getPersist()).toBe(false);\r | |
131 | expect(field.getType()).toBe('bool');\r | |
132 | expect(field.getDefaultValue()).toBe(true);\r | |
133 | });\r | |
134 | \r | |
135 | it('should decorate the Model with an allowDrag field', function() {\r | |
136 | var field = fields.allowDrag;\r | |
137 | \r | |
138 | expect(field.getPersist()).toBe(false);\r | |
139 | expect(field.getType()).toBe('bool');\r | |
140 | expect(field.getDefaultValue()).toBe(true);\r | |
141 | });\r | |
142 | it('should decorate the Model with a loaded field', function() {\r | |
143 | var field = fields.loaded;\r | |
144 | \r | |
145 | expect(field.getPersist()).toBe(false);\r | |
146 | expect(field.getType()).toBe('bool');\r | |
147 | expect(field.getDefaultValue()).toBe(false);\r | |
148 | });\r | |
149 | it('should decorate the Model with a loading field', function() {\r | |
150 | var field = fields.loading;\r | |
151 | \r | |
152 | expect(field.getPersist()).toBe(false);\r | |
153 | expect(field.getType()).toBe('bool');\r | |
154 | expect(field.getDefaultValue()).toBe(false);\r | |
155 | });\r | |
156 | it('should decorate the Model with an href field', function() {\r | |
157 | var field = fields.href;\r | |
158 | \r | |
159 | expect(field.getPersist()).toBe(false);\r | |
160 | expect(field.getType()).toBe('string');\r | |
161 | expect(field.getDefaultValue()).toBe('');\r | |
162 | });\r | |
163 | it('should decorate the Model with an hrefTarget field', function() {\r | |
164 | var field = fields.hrefTarget;\r | |
165 | \r | |
166 | expect(field.getPersist()).toBe(false);\r | |
167 | expect(field.getType()).toBe('string');\r | |
168 | expect(field.getDefaultValue()).toBe('');\r | |
169 | });\r | |
170 | it('should decorate the Model with a qtip field', function() {\r | |
171 | var field = fields.qtip;\r | |
172 | \r | |
173 | expect(field.getPersist()).toBe(false);\r | |
174 | expect(field.getType()).toBe('string');\r | |
175 | expect(field.getDefaultValue()).toBe('');\r | |
176 | });\r | |
177 | it('should decorate the Model with a qtitle field', function() {\r | |
178 | var field = fields.qtitle;\r | |
179 | \r | |
180 | expect(field.getPersist()).toBe(false);\r | |
181 | expect(field.getType()).toBe('string');\r | |
182 | expect(field.getDefaultValue()).toBe('');\r | |
183 | });\r | |
184 | it('should decorate the Model with a children field', function() {\r | |
185 | var field = fields.children;\r | |
186 | \r | |
187 | expect(field.getPersist()).toBe(false);\r | |
188 | expect(field.getType()).toBe('auto');\r | |
189 | expect(field.getDefaultValue()).toBe(null);\r | |
190 | });\r | |
191 | it('should decorate Model class of a given record', function() {\r | |
192 | var MyModel, record1, record2;\r | |
193 | MyModel = Ext.define('spec.MyModel', {\r | |
194 | extend: 'Ext.data.Model',\r | |
195 | fields: [\r | |
196 | {name: 'text', type: 'string'}\r | |
197 | ],\r | |
198 | proxy: {\r | |
199 | type: 'memory'\r | |
200 | }\r | |
201 | });\r | |
202 | record1 = MyModel.create({text: 'record1'});\r | |
203 | record2 = MyModel.create({text: 'record2'});\r | |
204 | expect(MyModel.prototype.isNode).toBeUndefined();\r | |
205 | expect(record1.isNode).toBeUndefined();\r | |
206 | expect(record2.isNode).toBeUndefined();\r | |
207 | \r | |
208 | Ext.data.NodeInterface.decorate(record1);\r | |
209 | expect(MyModel.prototype.isNode).toBeTruthy();\r | |
210 | expect(record1.isNode).toBeTruthy();\r | |
211 | expect(record2.isNode).toBeTruthy();\r | |
212 | \r | |
213 | Ext.undefine('spec.MyModel');\r | |
214 | });\r | |
215 | \r | |
216 | });\r | |
217 | \r | |
218 | \r | |
219 | describe('methods', function() {\r | |
220 | var leftChild, rightChild, rootNode, spareNode, spy;\r | |
221 | \r | |
222 | function insertDefaultChildren() {\r | |
223 | rootNode.appendChild(leftChild);\r | |
224 | rootNode.appendChild(rightChild);\r | |
225 | rootNode.updateInfo(false, {\r | |
226 | isFirst: true,\r | |
227 | isLast: true,\r | |
228 | depth: 0,\r | |
229 | index: 0,\r | |
230 | parentId: null\r | |
231 | });\r | |
232 | }\r | |
233 | \r | |
234 | beforeEach(function() {\r | |
235 | leftChild = new spec.TreeNode({\r | |
236 | id: 'left'\r | |
237 | });\r | |
238 | \r | |
239 | rightChild = new spec.TreeNode({\r | |
240 | id: 'right'\r | |
241 | });\r | |
242 | \r | |
243 | rootNode = new spec.TreeNode({\r | |
244 | id: 'root'\r | |
245 | });\r | |
246 | \r | |
247 | //we use this in several tests as an example node to add\r | |
248 | spareNode = new spec.TreeNode({\r | |
249 | id: 'spare'\r | |
250 | });\r | |
251 | \r | |
252 | });\r | |
253 | \r | |
254 | describe("isFirst", function() {\r | |
255 | beforeEach(function() {\r | |
256 | insertDefaultChildren.call(this);\r | |
257 | });\r | |
258 | \r | |
259 | it("should have rootNode which is first", function() {\r | |
260 | expect(rootNode.isFirst()).toBe(true);\r | |
261 | });\r | |
262 | it("should have leftChild which is first", function() {\r | |
263 | expect(leftChild.isFirst()).toBe(true);\r | |
264 | });\r | |
265 | it("should have rightChild which is not first", function() {\r | |
266 | expect(rightChild.isFirst()).toBe(false);\r | |
267 | });\r | |
268 | });\r | |
269 | \r | |
270 | describe("isLast", function() {\r | |
271 | beforeEach(function(){\r | |
272 | insertDefaultChildren.call(this);\r | |
273 | });\r | |
274 | \r | |
275 | it("should have rootNode which is last", function() {\r | |
276 | expect(rootNode.isLast()).toBe(true);\r | |
277 | });\r | |
278 | it("should have leftChild which is not last", function() {\r | |
279 | expect(leftChild.isLast()).toBe(false);\r | |
280 | });\r | |
281 | it("should have rightChild which is last", function() {\r | |
282 | expect(rightChild.isLast()).toBe(true);\r | |
283 | });\r | |
284 | });\r | |
285 | \r | |
286 | describe("hasChildNodes", function() {\r | |
287 | beforeEach(function() {\r | |
288 | rootNode.appendChild(leftChild);\r | |
289 | });\r | |
290 | \r | |
291 | it("should have rootNode with children", function() {\r | |
292 | expect(rootNode.hasChildNodes()).toBe(true);\r | |
293 | });\r | |
294 | it("should have leftChild whithout children", function() {\r | |
295 | expect(leftChild.hasChildNodes()).toBe(false);\r | |
296 | });\r | |
297 | });\r | |
298 | \r | |
299 | describe("isExpandable", function() {\r | |
300 | it("should have node expandable if it has children", function() {\r | |
301 | spareNode.appendChild(leftChild);\r | |
302 | expect(spareNode.isExpandable()).toBe(true);\r | |
303 | });\r | |
304 | \r | |
305 | it("should have node expandable if has no children", function() {\r | |
306 | expect(spareNode.isExpandable()).toBe(true);\r | |
307 | }); \r | |
308 | it("should have node not expandable if it is a leaf node", function() {\r | |
309 | spareNode.set('leaf', true);\r | |
310 | expect(spareNode.isExpandable()).toBe(false);\r | |
311 | }); \r | |
312 | });\r | |
313 | \r | |
314 | describe("append", function(){\r | |
315 | describe("appending children", function() {\r | |
316 | \r | |
317 | it("should fire beforeappend", function() {\r | |
318 | spy = spyOnEvent(rootNode, "beforeappend").andCallThrough();\r | |
319 | \r | |
320 | rootNode.appendChild(leftChild);\r | |
321 | \r | |
322 | expect(spy).toHaveBeenCalledWith(rootNode, leftChild);\r | |
323 | });\r | |
324 | \r | |
325 | it("should cancel append if beforeappend return false", function() {\r | |
326 | spy = spyOnEvent(rootNode, "beforeappend").andReturn(false);\r | |
327 | expect(rootNode.appendChild(leftChild)).toBe(false);\r | |
328 | \r | |
329 | expect(spy.callCount).toEqual(1);\r | |
330 | });\r | |
331 | \r | |
332 | it("should set firstChild", function() {\r | |
333 | \r | |
334 | rootNode.appendChild(leftChild);\r | |
335 | \r | |
336 | expect(rootNode.firstChild).toEqual(leftChild);\r | |
337 | });\r | |
338 | \r | |
339 | it("should set lastChild", function() {\r | |
340 | \r | |
341 | rootNode.appendChild(leftChild);\r | |
342 | \r | |
343 | expect(rootNode.lastChild).toEqual(leftChild);\r | |
344 | });\r | |
345 | \r | |
346 | it("should add node to childnodes", function() {\r | |
347 | var childNodes;\r | |
348 | \r | |
349 | rootNode.appendChild(leftChild);\r | |
350 | \r | |
351 | childNodes = rootNode.childNodes;\r | |
352 | \r | |
353 | expect(childNodes.length).toEqual(1);\r | |
354 | expect(childNodes[0]).toEqual(leftChild);\r | |
355 | });\r | |
356 | \r | |
357 | it("should fire append event", function() {\r | |
358 | spy = spyOnEvent(rootNode, "append").andCallThrough();\r | |
359 | \r | |
360 | rootNode.appendChild(leftChild);\r | |
361 | \r | |
362 | expect(spy).toHaveBeenCalledWith(rootNode, leftChild, 0);\r | |
363 | });\r | |
364 | \r | |
365 | it("should return node", function() {\r | |
366 | var ret = rootNode.appendChild(leftChild);\r | |
367 | \r | |
368 | expect(ret).toEqual(leftChild);\r | |
369 | });\r | |
370 | \r | |
371 | it("should append array of nodes", function() {\r | |
372 | rootNode.appendChild([leftChild, rightChild]);\r | |
373 | \r | |
374 | var childNodes = rootNode.childNodes;\r | |
375 | \r | |
376 | expect(childNodes[0]).toEqual(leftChild);\r | |
377 | expect(childNodes[1]).toEqual(rightChild);\r | |
378 | expect(childNodes.length).toEqual(2);\r | |
379 | });\r | |
380 | });\r | |
381 | \r | |
382 | describe("appending with existing siblings", function() {\r | |
383 | beforeEach(function() {\r | |
384 | insertDefaultChildren.call(this); \r | |
385 | });\r | |
386 | \r | |
387 | it("should set next sibling", function() {\r | |
388 | expect(leftChild.nextSibling).toEqual(rightChild);\r | |
389 | expect(rightChild.nextSibling).toBeNull();\r | |
390 | });\r | |
391 | \r | |
392 | it("should set previous sibling", function() {\r | |
393 | expect(rightChild.previousSibling).toEqual(leftChild);\r | |
394 | expect(leftChild.previousSibling).toBeNull();\r | |
395 | });\r | |
396 | });\r | |
397 | \r | |
398 | describe("appending children from an existing node", function() {\r | |
399 | var oldParent, spy;\r | |
400 | \r | |
401 | beforeEach(function() {\r | |
402 | oldParent = new spec.TreeNode({id: 'oldparent'});\r | |
403 | oldParent.appendChild(spareNode);\r | |
404 | });\r | |
405 | \r | |
406 | it("should remove from existing node", function() {\r | |
407 | spy = spyOn(oldParent, "removeChild").andCallThrough();\r | |
408 | \r | |
409 | rootNode.appendChild(spareNode);\r | |
410 | \r | |
411 | expect(spy).toHaveBeenCalledWith(spareNode, false, undefined, true);\r | |
412 | });\r | |
413 | \r | |
414 | it("should fire beforeremove event", function(){\r | |
415 | spy = spyOnEvent(oldParent, "beforeremove").andCallThrough();\r | |
416 | \r | |
417 | rootNode.appendChild(spareNode);\r | |
418 | \r | |
419 | expect(spy).toHaveBeenCalledWith(oldParent, spareNode, true);\r | |
420 | });\r | |
421 | \r | |
422 | it("should fire remove event", function(){\r | |
423 | spy = spyOnEvent(oldParent, "remove").andCallThrough();\r | |
424 | \r | |
425 | rootNode.appendChild(spareNode);\r | |
426 | \r | |
427 | // Just use the context argumemt from the args as the last arg\r | |
428 | expect(spy).toHaveBeenCalledWith(oldParent, spareNode, true, spy.mostRecentCall.args[3]);\r | |
429 | });\r | |
430 | \r | |
431 | it("should fire beforemove event", function() {\r | |
432 | spy = spyOnEvent(spareNode, "beforemove").andCallThrough();\r | |
433 | \r | |
434 | rootNode.appendChild(spareNode);\r | |
435 | \r | |
436 | expect(spy).toHaveBeenCalledWith(spareNode, oldParent, rootNode, 0);\r | |
437 | });\r | |
438 | it("should fire move event", function() {\r | |
439 | spy = spyOnEvent(spareNode, "move").andCallThrough();\r | |
440 | \r | |
441 | rootNode.appendChild(spareNode);\r | |
442 | \r | |
443 | expect(spy).toHaveBeenCalledWith(spareNode, oldParent, rootNode, 0); \r | |
444 | });\r | |
445 | });\r | |
446 | });\r | |
447 | \r | |
448 | describe("insert", function(){\r | |
449 | \r | |
450 | beforeEach(function(){\r | |
451 | rootNode.appendChild(rightChild);\r | |
452 | });\r | |
453 | \r | |
454 | describe("inserting children", function() {\r | |
455 | it("should call appendChild if the node to insert before is null", function() {\r | |
456 | spy = spyOn(rootNode, "appendChild");\r | |
457 | \r | |
458 | rootNode.insertBefore(leftChild);\r | |
459 | \r | |
460 | expect(spy).toHaveBeenCalledWith(leftChild);\r | |
461 | });\r | |
462 | \r | |
463 | it("should do nothing if the node to insert before is equal to the node to insert", function() {\r | |
464 | expect(rootNode.insertBefore(leftChild, leftChild)).toBe(false);\r | |
465 | });\r | |
466 | \r | |
467 | it("should fire beforeinsert", function() {\r | |
468 | spy = spyOnEvent(rootNode, "beforeinsert").andCallThrough();\r | |
469 | \r | |
470 | rootNode.insertBefore(leftChild, rightChild);\r | |
471 | \r | |
472 | expect(spy).toHaveBeenCalledWith(rootNode, leftChild, rightChild); \r | |
473 | });\r | |
474 | \r | |
475 | it("should cancel insert if beforeinsert return false", function() {\r | |
476 | spy = spyOnEvent(rootNode, "beforeinsert").andReturn(false);\r | |
477 | \r | |
478 | expect(rootNode.insertBefore(leftChild, rightChild)).toBe(false);\r | |
479 | \r | |
480 | expect(spy.callCount).toEqual(1);\r | |
481 | });\r | |
482 | \r | |
483 | it("should set firstChild", function() {\r | |
484 | rootNode.insertBefore(leftChild, rightChild);\r | |
485 | \r | |
486 | expect(rootNode.firstChild).toEqual(leftChild);\r | |
487 | });\r | |
488 | \r | |
489 | it("should set lastChild", function() {\r | |
490 | rootNode.insertBefore(leftChild, rightChild);\r | |
491 | \r | |
492 | expect(rootNode.lastChild).toEqual(rightChild);\r | |
493 | });\r | |
494 | \r | |
495 | it("should fire insert", function() {\r | |
496 | spy = spyOnEvent(rootNode, "insert").andCallThrough();\r | |
497 | \r | |
498 | rootNode.insertBefore(leftChild, rightChild);\r | |
499 | \r | |
500 | expect(spy).toHaveBeenCalledWith(rootNode, leftChild, rightChild); \r | |
501 | });\r | |
502 | \r | |
503 | it("should update indexes for all siblings after the position where the node was inserted", function() {\r | |
504 | rootNode.insertBefore(spareNode, rightChild);\r | |
505 | \r | |
506 | rootNode.insertBefore(leftChild, spareNode);\r | |
507 | \r | |
508 | expect(spareNode.get('index')).toEqual(1);\r | |
509 | expect(rightChild.get('index')).toEqual(2);\r | |
510 | });\r | |
511 | \r | |
512 | \r | |
513 | it("should handle siblings", function(){\r | |
514 | expect(leftChild.previousSibling).toBeNull();\r | |
515 | expect(leftChild.nextSibling).toBeNull();\r | |
516 | expect(rightChild.previousSibling).toBeNull();\r | |
517 | expect(rightChild.nextSibling).toBeNull();\r | |
518 | \r | |
519 | rootNode.insertBefore(leftChild, rightChild);\r | |
520 | \r | |
521 | expect(leftChild.previousSibling).toBeNull();\r | |
522 | expect(leftChild.nextSibling).toEqual(rightChild);\r | |
523 | expect(rightChild.previousSibling).toEqual(leftChild);\r | |
524 | expect(rightChild.nextSibling).toBeNull();\r | |
525 | });\r | |
526 | \r | |
527 | describe("move", function() {\r | |
528 | beforeEach(function() {\r | |
529 | rootNode.appendChild(leftChild);\r | |
530 | });\r | |
531 | \r | |
532 | it("should fire beforemove", function() {\r | |
533 | spy = spyOnEvent(leftChild, "beforemove").andCallThrough();\r | |
534 | \r | |
535 | rootNode.insertBefore(leftChild, rightChild);\r | |
536 | \r | |
537 | expect(spy).toHaveBeenCalledWith(leftChild, rootNode, rootNode, 0, rightChild); \r | |
538 | });\r | |
539 | \r | |
540 | it("should cancel insert if beforemove return false", function() {\r | |
541 | spy = spyOnEvent(leftChild, "beforemove").andReturn(false);\r | |
542 | \r | |
543 | expect(rootNode.insertBefore(leftChild, rightChild)).toBe(false);\r | |
544 | \r | |
545 | expect(spy.callCount).toEqual(1);\r | |
546 | });\r | |
547 | \r | |
548 | it("should fire move", function() {\r | |
549 | spy = spyOnEvent(leftChild, "move").andCallThrough();\r | |
550 | \r | |
551 | rootNode.insertBefore(leftChild, rightChild);\r | |
552 | \r | |
553 | expect(spy).toHaveBeenCalledWith(leftChild, rootNode, rootNode, 0, rightChild); \r | |
554 | }); \r | |
555 | \r | |
556 | });\r | |
557 | });\r | |
558 | });\r | |
559 | \r | |
560 | describe("removing children", function() {\r | |
561 | it("should return false when removing bad node", function(){\r | |
562 | expect(rootNode.removeChild(leftChild)).toBe(false); \r | |
563 | });\r | |
564 | \r | |
565 | it("should fire beforeremove event", function(){\r | |
566 | insertDefaultChildren.call(this);\r | |
567 | \r | |
568 | spy = spyOnEvent(rootNode, "beforeremove").andCallThrough();\r | |
569 | \r | |
570 | rootNode.removeChild(leftChild);\r | |
571 | \r | |
572 | expect(spy).toHaveBeenCalledWith(rootNode, leftChild, false);\r | |
573 | });\r | |
574 | \r | |
575 | it("should cancel remove if beforeremove returns false", function() {\r | |
576 | insertDefaultChildren.call(this);\r | |
577 | \r | |
578 | spy = spyOnEvent(rootNode, "beforeremove").andReturn(false);\r | |
579 | \r | |
580 | expect(rootNode.removeChild(leftChild)).toBe(false);\r | |
581 | \r | |
582 | expect(spy.callCount).toEqual(1);\r | |
583 | });\r | |
584 | \r | |
585 | it("should fire remove event", function() {\r | |
586 | insertDefaultChildren.call(this);\r | |
587 | \r | |
588 | spy = spyOnEvent(rootNode, "remove").andCallThrough();\r | |
589 | \r | |
590 | rootNode.removeChild(leftChild);\r | |
591 | \r | |
592 | // Just use the context argumemt from the args as the last arg\r | |
593 | expect(spy).toHaveBeenCalledWith(rootNode, leftChild, false, spy.mostRecentCall.args[3]);\r | |
594 | });\r | |
595 | \r | |
596 | it("should remove child from childNodes", function() {\r | |
597 | var childNodes, count;\r | |
598 | \r | |
599 | insertDefaultChildren.call(this);\r | |
600 | \r | |
601 | childNodes = rootNode.childNodes;\r | |
602 | count = childNodes.length;\r | |
603 | \r | |
604 | rootNode.removeChild(leftChild);\r | |
605 | \r | |
606 | expect(childNodes.length).toEqual(count - 1);\r | |
607 | expect(childNodes[0]).toEqual(rightChild);\r | |
608 | });\r | |
609 | \r | |
610 | it("should manage siblings", function() {\r | |
611 | insertDefaultChildren.call(this);\r | |
612 | \r | |
613 | //this gives us a third child - 'right' is actually now center\r | |
614 | rootNode.appendChild(spareNode);\r | |
615 | \r | |
616 | rootNode.removeChild(rightChild);\r | |
617 | \r | |
618 | expect(leftChild.nextSibling, spareNode);\r | |
619 | \r | |
620 | expect(spareNode.previousSibling, leftChild);\r | |
621 | });\r | |
622 | \r | |
623 | it("should erase node if asked", function() {\r | |
624 | insertDefaultChildren.call(this);\r | |
625 | \r | |
626 | spy = spyOn(leftChild, "erase").andCallThrough();\r | |
627 | \r | |
628 | rootNode.removeChild(leftChild, true);\r | |
629 | \r | |
630 | expect(spy).toHaveBeenCalled();\r | |
631 | });\r | |
632 | \r | |
633 | it("should clear node if asked", function() {\r | |
634 | insertDefaultChildren.call(this);\r | |
635 | \r | |
636 | spy = spyOn(leftChild, "clear").andCallThrough();\r | |
637 | \r | |
638 | rootNode.removeChild(leftChild, false);\r | |
639 | \r | |
640 | expect(spy).toHaveBeenCalled();\r | |
641 | }); \r | |
642 | it("should update indexes for all siblings after the node's old position", function() {\r | |
643 | insertDefaultChildren.call(this);\r | |
644 | \r | |
645 | rootNode.appendChild(spareNode);\r | |
646 | \r | |
647 | rootNode.removeChild(leftChild);\r | |
648 | \r | |
649 | expect(rightChild.get('index')).toEqual(0);\r | |
650 | expect(spareNode.get('index')).toEqual(1);\r | |
651 | });\r | |
652 | });\r | |
653 | \r | |
654 | describe("clearing references", function() {\r | |
655 | beforeEach(function(){\r | |
656 | insertDefaultChildren.call(this);\r | |
657 | rootNode.appendChild(spareNode);\r | |
658 | });\r | |
659 | \r | |
660 | it("should nullify parentNode", function() {\r | |
661 | expect(rightChild.parentNode).not.toBeNull();\r | |
662 | \r | |
663 | rightChild.clear();\r | |
664 | \r | |
665 | expect(rightChild.parentNode).toBeNull();\r | |
666 | });\r | |
667 | \r | |
668 | it("should nullifies nextSibling", function() {\r | |
669 | expect(rightChild.nextSibling).not.toBeNull();\r | |
670 | \r | |
671 | rightChild.clear();\r | |
672 | \r | |
673 | expect(rightChild.nextSibling).toBeNull();\r | |
674 | });\r | |
675 | \r | |
676 | it("should nullifies previousSibling", function() {\r | |
677 | expect(rightChild.previousSibling).not.toBeNull();\r | |
678 | \r | |
679 | rightChild.clear();\r | |
680 | \r | |
681 | expect(rightChild.previousSibling).toBeNull();\r | |
682 | });\r | |
683 | \r | |
684 | it("should remove lastChild and firstChild references", function() {\r | |
685 | rightChild.clear(true);\r | |
686 | \r | |
687 | expect(rightChild.firstChild).toBeNull();\r | |
688 | expect(rightChild.lastChild).toBeNull();\r | |
689 | });\r | |
690 | });\r | |
691 | \r | |
692 | describe("item", function() {\r | |
693 | it("should return the child node at the specified index", function() {\r | |
694 | rootNode.appendChild(leftChild);\r | |
695 | rootNode.appendChild(rightChild);\r | |
696 | rootNode.appendChild(spareNode);\r | |
697 | \r | |
698 | expect(rootNode.getChildAt(0)).toEqual(leftChild);\r | |
699 | expect(rootNode.getChildAt(1)).toEqual(rightChild);\r | |
700 | expect(rootNode.getChildAt(2)).toEqual(spareNode);\r | |
701 | });\r | |
702 | });\r | |
703 | \r | |
704 | describe("silent destroy", function() {\r | |
705 | it("should purge node listeners", function() {\r | |
706 | spy = spyOn(leftChild.mixins.observable, "clearListeners").andCallThrough();\r | |
707 | \r | |
708 | leftChild.destroy(true);\r | |
709 | \r | |
710 | expect(spy).toHaveBeenCalled();\r | |
711 | });\r | |
712 | \r | |
713 | it("should erase children", function() {\r | |
714 | var spy2;\r | |
715 | \r | |
716 | insertDefaultChildren.call(this);\r | |
717 | \r | |
718 | spy = spyOn(leftChild, "erase").andCallThrough();\r | |
719 | spy2 = spyOn(rightChild, "erase").andCallThrough();\r | |
720 | \r | |
721 | rootNode.erase();\r | |
722 | \r | |
723 | expect(spy).toHaveBeenCalled();\r | |
724 | expect(spy2).toHaveBeenCalled();\r | |
725 | });\r | |
726 | \r | |
727 | it("should nullify childNodes", function() {\r | |
728 | insertDefaultChildren.call(this);\r | |
729 | \r | |
730 | expect(rootNode.childNodes).not.toBeNull();\r | |
731 | \r | |
732 | rootNode.erase(true);\r | |
733 | \r | |
734 | expect(rootNode.childNodes).toBeNull();\r | |
735 | });\r | |
736 | });\r | |
737 | \r | |
738 | describe("non-silent destroy", function() {\r | |
739 | it("should remove node", function() {\r | |
740 | insertDefaultChildren.call(this);\r | |
741 | \r | |
742 | spy = spyOn(leftChild, "remove").andCallThrough();\r | |
743 | \r | |
744 | leftChild.erase(false);\r | |
745 | \r | |
746 | expect(spy).toHaveBeenCalled();\r | |
747 | });\r | |
748 | });\r | |
749 | \r | |
750 | describe("remove", function() {\r | |
751 | it("should remove from parent", function() {\r | |
752 | spy = spyOn(rootNode, "removeChild").andCallThrough();\r | |
753 | \r | |
754 | rootNode.appendChild(leftChild);\r | |
755 | \r | |
756 | leftChild.remove();\r | |
757 | \r | |
758 | expect(spy).toHaveBeenCalledWith(leftChild, undefined, undefined);\r | |
759 | });\r | |
760 | \r | |
761 | it("should return node", function() {\r | |
762 | expect(leftChild.remove()).toEqual(leftChild);\r | |
763 | });\r | |
764 | });\r | |
765 | \r | |
766 | describe("removeAll", function() {\r | |
767 | it("should remove all children", function() {\r | |
768 | rootNode.appendChild([leftChild, rightChild, spareNode]);\r | |
769 | rootNode.removeAll();\r | |
770 | expect(rootNode.childNodes.length).toBe(0);\r | |
771 | });\r | |
772 | });\r | |
773 | \r | |
774 | describe("replacing children", function() {\r | |
775 | beforeEach(function() {\r | |
776 | insertDefaultChildren.call(this);\r | |
777 | });\r | |
778 | \r | |
779 | it("should keep the same childNodes length", function() {\r | |
780 | var count = rootNode.childNodes.length;\r | |
781 | \r | |
782 | rootNode.replaceChild(spareNode, leftChild);\r | |
783 | \r | |
784 | expect(rootNode.childNodes.length).toEqual(count);\r | |
785 | });\r | |
786 | \r | |
787 | it("should replace node", function() {\r | |
788 | rootNode.replaceChild(spareNode, leftChild);\r | |
789 | \r | |
790 | expect(rootNode.childNodes[0], spareNode);\r | |
791 | });\r | |
792 | });\r | |
793 | \r | |
794 | describe("getting depth", function() {\r | |
795 | beforeEach(function() {\r | |
796 | insertDefaultChildren.call(this);\r | |
797 | leftChild.appendChild(spareNode);\r | |
798 | });\r | |
799 | \r | |
800 | it("should have a depth of 0 for rootNode", function(){\r | |
801 | expect(rootNode.getDepth()).toEqual(0);\r | |
802 | });\r | |
803 | \r | |
804 | it("should have a depth of 1 for leftChild and rightChild", function(){\r | |
805 | expect(rightChild.getDepth()).toEqual(1);\r | |
806 | expect(leftChild.getDepth()).toEqual(1);\r | |
807 | });\r | |
808 | \r | |
809 | it("should have a depth of 2 for spareNode", function(){\r | |
810 | expect(spareNode.getDepth()).toEqual(2); \r | |
811 | });\r | |
812 | });\r | |
813 | \r | |
814 | describe("getting path", function() {\r | |
815 | beforeEach(function() {\r | |
816 | insertDefaultChildren.call(this);\r | |
817 | leftChild.appendChild(spareNode);\r | |
818 | });\r | |
819 | \r | |
820 | it("should set root path", function() {\r | |
821 | expect(rootNode.getPath()).toEqual("/root");\r | |
822 | });\r | |
823 | \r | |
824 | it("should set middle path", function() {\r | |
825 | expect(leftChild.getPath()).toEqual("/root/left");\r | |
826 | expect(rightChild.getPath()).toEqual("/root/right");\r | |
827 | });\r | |
828 | \r | |
829 | it("should set leaf path", function() {\r | |
830 | expect(spareNode.getPath()).toEqual("/root/left/spare");\r | |
831 | });\r | |
832 | });\r | |
833 | \r | |
834 | describe("indexOf", function(){\r | |
835 | it("should always return -1 when the node is empty", function(){\r | |
836 | expect(rootNode.indexOf(spareNode)).toBe(-1);\r | |
837 | });\r | |
838 | \r | |
839 | it("should return -1 when the passed node is not a child", function(){\r | |
840 | rootNode.appendChild(leftChild);\r | |
841 | expect(rootNode.indexOf(spareNode)).toBe(-1); \r | |
842 | });\r | |
843 | \r | |
844 | it("should return the correct index when the node exists", function(){\r | |
845 | rootNode.appendChild([leftChild, spareNode, rightChild]); \r | |
846 | expect(rootNode.indexOf(spareNode)).toBe(1); \r | |
847 | });\r | |
848 | });\r | |
849 | \r | |
850 | describe("indexOfId", function(){\r | |
851 | it("should always return -1 when the node is empty", function(){\r | |
852 | expect(rootNode.indexOfId('spare')).toBe(-1);\r | |
853 | });\r | |
854 | \r | |
855 | it("should return -1 when the passed node is not a child", function(){\r | |
856 | rootNode.appendChild(leftChild);\r | |
857 | expect(rootNode.indexOfId('spare')).toBe(-1); \r | |
858 | });\r | |
859 | \r | |
860 | it("should return the correct index when the node exists", function(){\r | |
861 | rootNode.appendChild([leftChild, spareNode, rightChild]); \r | |
862 | expect(rootNode.indexOfId('spare')).toBe(1); \r | |
863 | });\r | |
864 | });\r | |
865 | \r | |
866 | describe("bubbling", function() {\r | |
867 | var bubbleFn;\r | |
868 | \r | |
869 | beforeEach(function() {\r | |
870 | insertDefaultChildren.call(this);\r | |
871 | leftChild.appendChild(spareNode);\r | |
872 | bubbleFn = jasmine.createSpy();\r | |
873 | });\r | |
874 | \r | |
875 | it("should call bubbleFn 3 times", function() {\r | |
876 | spareNode.bubble(bubbleFn);\r | |
877 | \r | |
878 | expect(bubbleFn.callCount).toEqual(3);\r | |
879 | });\r | |
880 | \r | |
881 | it("should call bubbleFn with node spare, left, root", function() {\r | |
882 | spareNode.bubble(bubbleFn);\r | |
883 | \r | |
884 | expect(bubbleFn.calls[0].args).toEqual([spareNode]);\r | |
885 | expect(bubbleFn.calls[1].args).toEqual([leftChild]);\r | |
886 | expect(bubbleFn.calls[2].args).toEqual([rootNode]);\r | |
887 | });\r | |
888 | \r | |
889 | it("should call bubbleFn with a defined scope", function() {\r | |
890 | spareNode.bubble(bubbleFn, fakeScope);\r | |
891 | \r | |
892 | expect(bubbleFn.calls[0].object).toBe(fakeScope);\r | |
893 | expect(bubbleFn.calls[1].object).toBe(fakeScope);\r | |
894 | expect(bubbleFn.calls[2].object).toBe(fakeScope);\r | |
895 | });\r | |
896 | \r | |
897 | it("should call bubbleFn with customs arguments", function() {\r | |
898 | var customArgs = ['some', 'args'];\r | |
899 | \r | |
900 | spareNode.bubble(bubbleFn, spareNode, customArgs);\r | |
901 | \r | |
902 | expect(bubbleFn.calls[0].args).toEqual(customArgs);\r | |
903 | expect(bubbleFn.calls[1].args).toEqual(customArgs);\r | |
904 | expect(bubbleFn.calls[2].args).toEqual(customArgs);\r | |
905 | });\r | |
906 | \r | |
907 | it("should stop when bubbleFn return false", function() {\r | |
908 | bubbleFn.andCallFake(function(node) {\r | |
909 | if (node.getId() == 'left') {\r | |
910 | return false;\r | |
911 | }\r | |
912 | });\r | |
913 | \r | |
914 | spareNode.bubble(bubbleFn);\r | |
915 | \r | |
916 | expect(bubbleFn.callCount).toEqual(2);\r | |
917 | });\r | |
918 | });\r | |
919 | \r | |
920 | describe("cascading", function() {\r | |
921 | var cascadeFn;\r | |
922 | \r | |
923 | beforeEach(function(){\r | |
924 | insertDefaultChildren.call(this);\r | |
925 | leftChild.appendChild(spareNode);\r | |
926 | cascadeFn = jasmine.createSpy();\r | |
927 | });\r | |
928 | \r | |
929 | it("should call cascadeFn 4 times", function() {\r | |
930 | rootNode.cascadeBy(cascadeFn);\r | |
931 | \r | |
932 | expect(cascadeFn.callCount).toEqual(4);\r | |
933 | });\r | |
934 | \r | |
935 | it("should call cascadeFn with node root, leftChild, spareNode, rightChild", function() {\r | |
936 | rootNode.cascadeBy(cascadeFn);\r | |
937 | \r | |
938 | expect(cascadeFn.calls[0].args).toEqual([rootNode]);\r | |
939 | expect(cascadeFn.calls[1].args).toEqual([leftChild]);\r | |
940 | expect(cascadeFn.calls[2].args).toEqual([spareNode]);\r | |
941 | expect(cascadeFn.calls[3].args).toEqual([rightChild]);\r | |
942 | });\r | |
943 | \r | |
944 | it("should call cascadeFn with a defined scope", function() {\r | |
945 | rootNode.cascadeBy(cascadeFn, fakeScope);\r | |
946 | \r | |
947 | expect(cascadeFn.calls[0].object).toBe(fakeScope);\r | |
948 | expect(cascadeFn.calls[1].object).toBe(fakeScope);\r | |
949 | expect(cascadeFn.calls[2].object).toBe(fakeScope);\r | |
950 | expect(cascadeFn.calls[3].object).toBe(fakeScope);\r | |
951 | });\r | |
952 | \r | |
953 | it("should call cascadeFn with customs arguments", function() {\r | |
954 | var customArgs = ['some', 'args'];\r | |
955 | \r | |
956 | rootNode.cascadeBy(cascadeFn, rootNode, customArgs);\r | |
957 | \r | |
958 | expect(cascadeFn.calls[0].args).toEqual(customArgs);\r | |
959 | expect(cascadeFn.calls[1].args).toEqual(customArgs);\r | |
960 | expect(cascadeFn.calls[2].args).toEqual(customArgs);\r | |
961 | expect(cascadeFn.calls[3].args).toEqual(customArgs);\r | |
962 | });\r | |
963 | \r | |
964 | it("should stop at end of branch when cascadeFn return false", function() {\r | |
965 | cascadeFn.andCallFake(function(node) {\r | |
966 | if (node.getId() == 'left') {\r | |
967 | return false;\r | |
968 | }\r | |
969 | });\r | |
970 | \r | |
971 | rootNode.cascadeBy(cascadeFn);\r | |
972 | \r | |
973 | expect(cascadeFn.callCount).toEqual(3);\r | |
974 | });\r | |
975 | });\r | |
976 | \r | |
977 | describe("each child", function() {\r | |
978 | var eachFn;\r | |
979 | \r | |
980 | beforeEach(function (){\r | |
981 | insertDefaultChildren.call(this);\r | |
982 | eachFn = jasmine.createSpy();\r | |
983 | });\r | |
984 | \r | |
985 | it("should be called 2 times", function() {\r | |
986 | \r | |
987 | rootNode.eachChild(eachFn);\r | |
988 | \r | |
989 | expect(eachFn.callCount).toEqual(2);\r | |
990 | });\r | |
991 | \r | |
992 | it("should call eachFn with node root, leftChild, rightChild", function() {\r | |
993 | rootNode.eachChild(eachFn);\r | |
994 | \r | |
995 | expect(eachFn.calls[0].args).toEqual([leftChild]);\r | |
996 | expect(eachFn.calls[1].args).toEqual([rightChild]);\r | |
997 | });\r | |
998 | \r | |
999 | it("should call eachFn with a defined scope", function() {\r | |
1000 | rootNode.eachChild(eachFn, fakeScope);\r | |
1001 | \r | |
1002 | expect(eachFn.calls[0].object).toBe(fakeScope);\r | |
1003 | expect(eachFn.calls[1].object).toBe(fakeScope);\r | |
1004 | });\r | |
1005 | \r | |
1006 | it("should call eachFn with customs arguments", function() {\r | |
1007 | var customArgs = ['some', 'args'];\r | |
1008 | \r | |
1009 | rootNode.eachChild(eachFn, rootNode, customArgs);\r | |
1010 | \r | |
1011 | expect(eachFn.calls[0].args).toEqual(customArgs);\r | |
1012 | expect(eachFn.calls[1].args).toEqual(customArgs);\r | |
1013 | });\r | |
1014 | \r | |
1015 | it("should stop when eachFn return false", function() {\r | |
1016 | eachFn.andCallFake(function(node) {\r | |
1017 | if (node.getId() == 'left') {\r | |
1018 | return false;\r | |
1019 | }\r | |
1020 | });\r | |
1021 | \r | |
1022 | rootNode.eachChild(eachFn);\r | |
1023 | \r | |
1024 | expect(eachFn.callCount).toEqual(1);\r | |
1025 | });\r | |
1026 | });\r | |
1027 | \r | |
1028 | describe("ancestors", function() {\r | |
1029 | beforeEach(function (){\r | |
1030 | insertDefaultChildren.call(this);\r | |
1031 | leftChild.appendChild(spareNode);\r | |
1032 | });\r | |
1033 | \r | |
1034 | it("should have parent as ancestor", function() {\r | |
1035 | expect(spareNode.isAncestor(leftChild)).toBe(true);\r | |
1036 | });\r | |
1037 | \r | |
1038 | it("should have root as ancestor", function() {\r | |
1039 | expect(spareNode.isAncestor(rootNode)).toBe(true);\r | |
1040 | });\r | |
1041 | \r | |
1042 | it("should not have uncle as ancestor", function() {\r | |
1043 | expect(spareNode.isAncestor(rightChild)).toBe(false);\r | |
1044 | }); \r | |
1045 | });\r | |
1046 | \r | |
1047 | describe("contains", function() {\r | |
1048 | beforeEach(function (){\r | |
1049 | insertDefaultChildren.call(this);\r | |
1050 | leftChild.appendChild(spareNode);\r | |
1051 | });\r | |
1052 | \r | |
1053 | it("should contain child", function() {\r | |
1054 | expect(rootNode.contains(leftChild)).toBe(true);\r | |
1055 | });\r | |
1056 | \r | |
1057 | it("should contain grand child", function() {\r | |
1058 | expect(rootNode.contains(spareNode)).toBe(true);\r | |
1059 | });\r | |
1060 | \r | |
1061 | it("should not contain parent", function() {\r | |
1062 | expect(spareNode.contains(leftChild)).toBe(false);\r | |
1063 | }); \r | |
1064 | });\r | |
1065 | \r | |
1066 | describe("finding children", function() {\r | |
1067 | beforeEach(function (){\r | |
1068 | insertDefaultChildren.call(this);\r | |
1069 | leftChild.appendChild(spareNode);\r | |
1070 | });\r | |
1071 | \r | |
1072 | describe("findChild", function() {\r | |
1073 | it("should find shallow children", function() {\r | |
1074 | expect(rootNode.findChild('id', 'left')).toEqual(leftChild);\r | |
1075 | });\r | |
1076 | \r | |
1077 | it("should not find deep children if deep is not specified", function() {\r | |
1078 | expect(rootNode.findChild('id', 'spare')).toBeNull();\r | |
1079 | });\r | |
1080 | \r | |
1081 | it("should not find deep children if deep is false", function() {\r | |
1082 | expect(rootNode.findChild('id', 'spare', false)).toBeNull();\r | |
1083 | });\r | |
1084 | \r | |
1085 | it("should find deep children if deep is true", function() {\r | |
1086 | expect(rootNode.findChild('id', 'spare', true)).toEqual(spareNode);\r | |
1087 | }); \r | |
1088 | });\r | |
1089 | \r | |
1090 | describe("findChildBy", function() {\r | |
1091 | var child;\r | |
1092 | \r | |
1093 | it("should find shallow children", function(){\r | |
1094 | child = rootNode.findChildBy(function(node) {\r | |
1095 | return node.getId() == 'right';\r | |
1096 | });\r | |
1097 | \r | |
1098 | expect(child).toEqual(rightChild);\r | |
1099 | });\r | |
1100 | \r | |
1101 | it("should not find deep children if deep is not specified", function(){\r | |
1102 | child = rootNode.findChildBy(function(node) {\r | |
1103 | return node.getId() == 'spare';\r | |
1104 | });\r | |
1105 | \r | |
1106 | expect(child).toBeNull();\r | |
1107 | });\r | |
1108 | \r | |
1109 | it("should not find deep children if deep is false", function(){\r | |
1110 | child = rootNode.findChildBy(function(node) {\r | |
1111 | return node.getId() == 'spare';\r | |
1112 | }, this, false);\r | |
1113 | \r | |
1114 | expect(child).toBeNull();\r | |
1115 | });\r | |
1116 | \r | |
1117 | it("should find deep children if deep is true", function(){\r | |
1118 | child = rootNode.findChildBy(function(node) {\r | |
1119 | return node.getId() == 'spare';\r | |
1120 | }, this, true);\r | |
1121 | \r | |
1122 | expect(child).toEqual(spareNode);\r | |
1123 | });\r | |
1124 | \r | |
1125 | it("should call function with good scope", function(){\r | |
1126 | var findChildFn = jasmine.createSpy().andReturn(false);\r | |
1127 | \r | |
1128 | child = rootNode.findChildBy(findChildFn, fakeScope, true);\r | |
1129 | \r | |
1130 | expect(findChildFn.calls[0].object).toBe(fakeScope);\r | |
1131 | expect(findChildFn.calls[1].object).toBe(fakeScope);\r | |
1132 | expect(findChildFn.calls[2].object).toBe(fakeScope); \r | |
1133 | });\r | |
1134 | });\r | |
1135 | });\r | |
1136 | \r | |
1137 | describe("sort", function() {\r | |
1138 | var node1,\r | |
1139 | node2,\r | |
1140 | node3,\r | |
1141 | node4,\r | |
1142 | sortFn;\r | |
1143 | \r | |
1144 | beforeEach(function() {\r | |
1145 | Ext.define('spec.EmployeeTreeNode', {\r | |
1146 | extend: 'Ext.data.Model',\r | |
1147 | fields: [\r | |
1148 | { name: 'lastname', type: 'string' },\r | |
1149 | { name: 'firstname', type: 'string' }\r | |
1150 | ]\r | |
1151 | });\r | |
1152 | Ext.data.NodeInterface.decorate(spec.EmployeeTreeNode);\r | |
1153 | node1 = new spec.EmployeeTreeNode({lastname: "Avins", firstname: "Jamie"});\r | |
1154 | node2 = new spec.EmployeeTreeNode({lastname: "Dougan", firstname: "Robert"});\r | |
1155 | node3 = new spec.EmployeeTreeNode({lastname: "Ferrero", firstname: "Nicolas"});\r | |
1156 | node4 = new spec.EmployeeTreeNode({lastname: "Spencer", firstname: "Edward"});\r | |
1157 | \r | |
1158 | rootNode.appendChild([node4, node2, node3, node1]);\r | |
1159 | \r | |
1160 | sortFn = jasmine.createSpy();\r | |
1161 | sortFn.andCallFake(function(a, b){\r | |
1162 | if (a.get('lastname') === b.get('lastname')) {\r | |
1163 | return 0;\r | |
1164 | }\r | |
1165 | return (a.get('lastname') < b.get('lastname')) ? -1 : 1;\r | |
1166 | });\r | |
1167 | \r | |
1168 | rootNode.sort(sortFn);\r | |
1169 | });\r | |
1170 | afterEach(function() {\r | |
1171 | Ext.undefine('spec.EmployeeTreeNode');\r | |
1172 | });\r | |
1173 | \r | |
1174 | it("should sort the child by lastname with the correct function", function() {\r | |
1175 | expect(rootNode.childNodes[0]).toEqual(node1);\r | |
1176 | expect(rootNode.childNodes[1]).toEqual(node2);\r | |
1177 | expect(rootNode.childNodes[2]).toEqual(node3);\r | |
1178 | expect(rootNode.childNodes[3]).toEqual(node4);\r | |
1179 | });\r | |
1180 | \r | |
1181 | });\r | |
1182 | \r | |
1183 | describe("copy", function(){\r | |
1184 | it("should not copy childNodes by default", function(){\r | |
1185 | var node = new spec.TreeNode({\r | |
1186 | text: 'Text',\r | |
1187 | id: 1\r | |
1188 | });\r | |
1189 | \r | |
1190 | var newNode = node.copy();\r | |
1191 | \r | |
1192 | expect(newNode.getData()).toEqual({\r | |
1193 | allowDrag: true,\r | |
1194 | allowDrop: true,\r | |
1195 | checked: null,\r | |
1196 | children: null,\r | |
1197 | cls: '',\r | |
1198 | depth: 0,\r | |
1199 | expandable: true,\r | |
1200 | expanded: false,\r | |
1201 | href: '',\r | |
1202 | hrefTarget: '',\r | |
1203 | icon: '',\r | |
1204 | iconCls: '',\r | |
1205 | id: 1,\r | |
1206 | index: -1,\r | |
1207 | isFirst: false,\r | |
1208 | isLast: false,\r | |
1209 | leaf: false,\r | |
1210 | loaded: false,\r | |
1211 | loading: false,\r | |
1212 | parentId: null,\r | |
1213 | qtip: '',\r | |
1214 | qtitle: '',\r | |
1215 | qshowDelay: 0,\r | |
1216 | root: false,\r | |
1217 | text: 'Text',\r | |
1218 | visible: true\r | |
1219 | });\r | |
1220 | });\r | |
1221 | \r | |
1222 | it("should accept a new id", function(){\r | |
1223 | var node = new spec.TreeNode({\r | |
1224 | text: 'Text',\r | |
1225 | id: 1\r | |
1226 | });\r | |
1227 | \r | |
1228 | var newNode = node.copy(2);\r | |
1229 | \r | |
1230 | expect(newNode.getData()).toEqual({\r | |
1231 | allowDrag: true,\r | |
1232 | allowDrop: true,\r | |
1233 | checked: null,\r | |
1234 | children: null,\r | |
1235 | cls: '',\r | |
1236 | depth: 0,\r | |
1237 | expandable: true,\r | |
1238 | expanded: false,\r | |
1239 | href: '',\r | |
1240 | hrefTarget: '',\r | |
1241 | icon: '',\r | |
1242 | iconCls: '',\r | |
1243 | id: 2,\r | |
1244 | index: -1,\r | |
1245 | isFirst: false,\r | |
1246 | isLast: false,\r | |
1247 | leaf: false,\r | |
1248 | loaded: false,\r | |
1249 | loading: false,\r | |
1250 | parentId: null,\r | |
1251 | qtip: '',\r | |
1252 | qtitle: '',\r | |
1253 | qshowDelay: 0,\r | |
1254 | root: false,\r | |
1255 | text: 'Text',\r | |
1256 | visible: true\r | |
1257 | });\r | |
1258 | });\r | |
1259 | \r | |
1260 | it("should clone children if deep: true is specified", function(){\r | |
1261 | var root = new spec.TreeNode({\r | |
1262 | id: 1,\r | |
1263 | text: 'Root'\r | |
1264 | }); \r | |
1265 | var child1 = root.appendChild(new spec.TreeNode({\r | |
1266 | id: 2,\r | |
1267 | text: 'Child1'\r | |
1268 | }));\r | |
1269 | var child2 = child1.appendChild(new spec.TreeNode({\r | |
1270 | id: 3,\r | |
1271 | text: 'Child2'\r | |
1272 | }));\r | |
1273 | child2.appendChild(new spec.TreeNode({\r | |
1274 | id: 4,\r | |
1275 | text: 'Child3'\r | |
1276 | }));\r | |
1277 | \r | |
1278 | var newNode = root.copy(undefined, true);\r | |
1279 | expect(newNode.childNodes[0].getId()).toBe(2);\r | |
1280 | expect(newNode.childNodes[0].get('text')).toBe('Child1');\r | |
1281 | \r | |
1282 | newNode = newNode.childNodes[0];\r | |
1283 | expect(newNode.childNodes[0].getId()).toBe(3);\r | |
1284 | expect(newNode.childNodes[0].get('text')).toBe('Child2');\r | |
1285 | \r | |
1286 | newNode = newNode.childNodes[0];\r | |
1287 | expect(newNode.childNodes[0].getId()).toBe(4);\r | |
1288 | expect(newNode.childNodes[0].get('text')).toBe('Child3');\r | |
1289 | });\r | |
1290 | });\r | |
1291 | \r | |
1292 | });\r | |
1293 | \r | |
1294 | describe("serialize", function(){\r | |
1295 | it('should create an object representation of the node', function() {\r | |
1296 | var node = new spec.TreeNode({\r | |
1297 | text: 'Root',\r | |
1298 | id: 1\r | |
1299 | }),\r | |
1300 | c1 = node.appendChild(new spec.TreeNode({\r | |
1301 | text: 'C1',\r | |
1302 | id: 2\r | |
1303 | })),\r | |
1304 | c2 = node.appendChild(new spec.TreeNode({\r | |
1305 | text: 'C1',\r | |
1306 | id: 3\r | |
1307 | }));\r | |
1308 | c1.appendChild( new spec.TreeNode({\r | |
1309 | text: 'c1.1',\r | |
1310 | id: 4\r | |
1311 | }));\r | |
1312 | c2.appendChild( new spec.TreeNode({\r | |
1313 | text: 'c2.1',\r | |
1314 | id: 5\r | |
1315 | }));\r | |
1316 | \r | |
1317 | expect(node.serialize()).toEqual({\r | |
1318 | "text": "Root",\r | |
1319 | "id": 1,\r | |
1320 | "parentId": null,\r | |
1321 | "leaf": false,\r | |
1322 | "children": [\r | |
1323 | {\r | |
1324 | "text": "C1",\r | |
1325 | "id": 2,\r | |
1326 | "parentId": 1,\r | |
1327 | "leaf": false,\r | |
1328 | "children": [\r | |
1329 | {\r | |
1330 | "text": "c1.1",\r | |
1331 | "id": 4,\r | |
1332 | "parentId": 2,\r | |
1333 | "leaf": false\r | |
1334 | }\r | |
1335 | ]\r | |
1336 | },\r | |
1337 | {\r | |
1338 | "text": "C1",\r | |
1339 | "id": 3,\r | |
1340 | "parentId": 1,\r | |
1341 | "leaf": false,\r | |
1342 | "children": [\r | |
1343 | {\r | |
1344 | "text": "c2.1",\r | |
1345 | "id": 5,\r | |
1346 | "parentId": 3,\r | |
1347 | "leaf": false\r | |
1348 | }\r | |
1349 | ]\r | |
1350 | }\r | |
1351 | ]\r | |
1352 | });\r | |
1353 | });\r | |
1354 | \r | |
1355 | it("should not include children if there are none", function(){\r | |
1356 | var o = new spec.TreeNode({\r | |
1357 | text: 'foo'\r | |
1358 | }), s = o.serialize();\r | |
1359 | \r | |
1360 | expect(s.text).toBe('foo');\r | |
1361 | expect(s.children).toBeUndefined();\r | |
1362 | });\r | |
1363 | \r | |
1364 | it("should include children if they exist", function(){\r | |
1365 | var o = new spec.TreeNode({\r | |
1366 | text: 'foo'\r | |
1367 | }), s;\r | |
1368 | \r | |
1369 | o.appendChild(new spec.TreeNode({\r | |
1370 | text: 'bar'\r | |
1371 | }));\r | |
1372 | \r | |
1373 | s = o.serialize();\r | |
1374 | expect(s.text).toBe('foo');\r | |
1375 | expect(s.children[0].text).toBe('bar');\r | |
1376 | }); \r | |
1377 | });\r | |
1378 | \r | |
1379 | describe("collapse", function() {\r | |
1380 | it("should fire the collapse callback when there are no child nodes", function() {\r | |
1381 | var root = new spec.TreeNode(),\r | |
1382 | called;\r | |
1383 | \r | |
1384 | root.collapseChildren(false, function() {\r | |
1385 | called = true;\r | |
1386 | });\r | |
1387 | expect(called).toBe(true);\r | |
1388 | root = null;\r | |
1389 | }); \r | |
1390 | });\r | |
1391 | \r | |
1392 | describe("modified property tracking", function() {\r | |
1393 | // Tests for https://sencha.jira.com/browse/EXTJSIV-9223 and https://sencha.jira.com/browse/EXTJSIV-9165\r | |
1394 | it("should track modifications of fields set as a result of node movement", function() {\r | |
1395 | \r | |
1396 | // Create a TreeNode subclass in which the index property is persistent.\r | |
1397 | Ext.define('spec.PersistentIndexTreeNode', {\r | |
1398 | extend: 'Ext.data.TreeModel',\r | |
1399 | fields: [\r | |
1400 | {name: 'text', type: 'string'},\r | |
1401 | {name: 'index', type: 'int', persist: true, defaultValue: -1}\r | |
1402 | ],\r | |
1403 | proxy: {\r | |
1404 | type: 'memory'\r | |
1405 | }\r | |
1406 | });\r | |
1407 | \r | |
1408 | var root = new spec.PersistentIndexTreeNode({\r | |
1409 | id: 'TestRoot'\r | |
1410 | }),\r | |
1411 | root1 = new spec.PersistentIndexTreeNode({\r | |
1412 | id: 'OtherTestRoot'\r | |
1413 | }),\r | |
1414 | node = new spec.PersistentIndexTreeNode({\r | |
1415 | id: 'node'\r | |
1416 | }),\r | |
1417 | node1;\r | |
1418 | root.appendChild(node);\r | |
1419 | \r | |
1420 | // The modified shows that parentId was changed *from* null.\r | |
1421 | // And the index was changed from -1 (not attached) to 0\r | |
1422 | expect(node.modified).toEqual({\r | |
1423 | index: -1,\r | |
1424 | parentId: null\r | |
1425 | });\r | |
1426 | \r | |
1427 | // Clears modified\r | |
1428 | node.commit();\r | |
1429 | expect(node.modified).toBeNull();\r | |
1430 | \r | |
1431 | // Move from parent "TestRoot", index 0 to parent "OtherTestRoot", index 0\r | |
1432 | // Index should appear in modified object because it has moved parent\r | |
1433 | root1.appendChild(node);\r | |
1434 | expect(node.modified).toEqual({\r | |
1435 | parentId: 'TestRoot',\r | |
1436 | index: 0\r | |
1437 | });\r | |
1438 | \r | |
1439 | // Clears modified\r | |
1440 | node.commit();\r | |
1441 | \r | |
1442 | // Should clear the parentId, so the modified now indicates that it was removed from index 0 of "OtherTestRoot"\r | |
1443 | // removeChild does NOT clear context data properties.\r | |
1444 | // Mainly because TreeStore.clearRemovedOnLoad uses these values to determine whether\r | |
1445 | // nodes in the removed list are descendants of a loading node so that tey can be evicted from the removed list.\r | |
1446 | root1.removeChild(node);\r | |
1447 | expect(node.modified).toEqual({\r | |
1448 | lastParentId: undefined,\r | |
1449 | parentId: 'OtherTestRoot'\r | |
1450 | });\r | |
1451 | \r | |
1452 | node = new spec.PersistentIndexTreeNode({\r | |
1453 | id: 'node'\r | |
1454 | });\r | |
1455 | node1 = new spec.PersistentIndexTreeNode({\r | |
1456 | id: 'node1'\r | |
1457 | });\r | |
1458 | root.clear();\r | |
1459 | root.appendChild([node, node1]);\r | |
1460 | \r | |
1461 | expect([node.get('index'), node1.get('index')]).toEqual([0, 1]);\r | |
1462 | node.commit();\r | |
1463 | node1.commit();\r | |
1464 | \r | |
1465 | // Move node1 to index:0\r | |
1466 | root.insertBefore(node1, node);\r | |
1467 | \r | |
1468 | // Indexes data values are switched\r | |
1469 | expect([node1.get('index'), node.get('index')]).toEqual([0, 1]);\r | |
1470 | \r | |
1471 | // node1 must report that its index was modified from initial value 1\r | |
1472 | expect(node1.modified).toEqual({\r | |
1473 | index: 1\r | |
1474 | });\r | |
1475 | \r | |
1476 | // node must report that its index was modified from initial value 0\r | |
1477 | expect(node.modified).toEqual({\r | |
1478 | index: 0\r | |
1479 | });\r | |
1480 | \r | |
1481 | root1.appendChild(node1);\r | |
1482 | \r | |
1483 | Ext.undefine('spec.PersistentIndexTreeNode');\r | |
1484 | });\r | |
1485 | });\r | |
1486 | });\r |