Upgrade to ExtJS 3.2.0 - Released 03/30/2010
[extjs.git] / test / unit / widgets / Container.js
1 /*!
2  * Ext JS Library 3.2.0
3  * Copyright(c) 2006-2010 Ext JS, Inc.
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 Ext.test.session.addTest('Ext.Container', {
8     name: 'Test Ext.Container methods',
9     
10     test_add: function(){
11         var ct = new Ext.Container({
12             defaultType: 'box'
13         });
14         ct.add(new Ext.Component());
15         
16         Y.Assert.areEqual(1, ct.items.getCount(), 'Check adding a single item works');
17         
18         ct.add(new Ext.Component({itemId: 'a'}), new Ext.Component({itemId: 'b'}), new Ext.Component({itemId: 'c'}));
19         Y.Assert.areEqual(4, ct.items.getCount(), 'Test add with param array');
20         Y.Assert.areEqual('b', ct.items.itemAt(2).itemId, 'Test that they are correctly added in order');
21         
22         ct.add({
23              xtype: 'component'   
24         });
25         Y.Assert.areEqual(5, ct.items.getCount(), 'Test for lazy instantiation');
26         
27         ct.add({});
28         Y.Assert.isTrue(ct.items.last().isXType('box'), 'Test default type');
29         ct.destroy();
30         ct = null;
31     },
32     
33     test_cascade: function(){
34         var ct = new Ext.Container({itemId: 'ct', depth: 0}),
35             i, 
36             j, 
37             k,
38             ci,
39             cj,
40             order = [ct.itemId];
41            
42         /* our container will have:
43          * 3 items at depth 1
44          * 9 items at depth 2
45          * 27 items at depth 3
46          */ 
47         for(i = 0; i < 3; ++i){
48             id = 'item' + i;
49             ci = ct.add({
50                 itemId: id,
51                 depth: 1
52             });
53             order.push(id);
54             for(j = 0; j < 3; ++j){
55                 id = 'item' + i  + '_' + j;
56                 cj = ci.add({
57                     itemId: id,
58                     depth: 2
59                 });
60                 order.push(id);
61                 for(k = 0; k < 3; ++k){
62                     id = 'item' + i  + '_' + j + '_' + k;
63                     cj.add({
64                         itemId: id,
65                         depth: 3
66                     });
67                     order.push(id);
68                 }
69             }
70         }
71         
72         
73         var cnt = 0,
74             items = [];
75         ct.cascade(function(c){
76             items.push(c.itemId);
77             ++cnt;    
78         });  
79         Y.Assert.areEqual(40, cnt, 'Test each item is iterated');
80         Y.ArrayAssert.itemsAreEqual(order, items, 'Test that items are iterated depth first');
81         
82         items = [];
83         ct.cascade(function(){
84             items.push(this.itemId);
85         });
86         Y.ArrayAssert.itemsAreEqual(order, items, 'Test that the scope defaults to the current component');
87         
88         cnt = 0;
89         ct.cascade(function(c){
90             cnt += c.depth * this.val;
91         }, {val: 3});
92         
93         Y.Assert.areEqual(306, cnt, 'Test that custom scope works');
94         
95         cnt = 0;
96         ct.cascade(function(a, b){
97             cnt += this.depth * (a + b);
98         }, null, [1, 2]);
99         
100         Y.Assert.areEqual(306, cnt, 'Test that custom args work');
101         
102         cnt = 0;
103         ct.cascade(function(){
104             if(this.itemId == 'item0' || this.itemId == 'item2'){
105                 return false;
106             }
107             ++cnt;
108         });
109         Y.Assert.areEqual(14, cnt, 'Test that returning false stops iteration on a branch');
110         
111         ct.destroy();
112         ct = null;
113     },
114     
115     test_find: function(){
116         var ct = new Ext.Container({
117             prop: 'foo',
118             special: 'main',
119             items: [{
120                 xtype: 'container',
121                 prop: 'foo',
122                 id: 'a',
123                 items: [{}, {prop: 'foo', id: 'd'}, {}, {}, {}, {
124                     xtype: 'container',
125                     items: [{}, {}, {}, {}]
126                 }]
127             },{
128                 xtype: 'container',
129                 prop: 'bar',
130                 id: 'b',
131                 items: [{prop: 'foo', id: 'e'}, {prop: 'food'}, {
132                     xtype: 'container',
133                     items: {
134                         xtype: 'container',
135                         items: {
136                             xtype: 'container',
137                             items: {
138                                 xtype: 'container',
139                                 items: {
140                                     prop: 'foo',
141                                     id: 'f'
142                                 }
143                             }
144                         }
145                     }
146                 }]
147             },{
148                 prop: 'foo',
149                 xtype: 'box',
150                 id: 'c'
151             }]
152         });
153         
154         var arr = ct.find('prop', 'foo');
155         Y.Assert.areEqual(5, arr.length, 'Ensure correct items are found, at all depths');
156         Y.ArrayAssert.itemsAreEqual(['a', 'd', 'e', 'f', 'c'], Ext.pluck(arr, 'id'), 'Test order the items are found, should be depth first');
157         
158         arr = ct.find('none', 'x');
159         Y.ArrayAssert.isEmpty(arr, 'Test with non existent property');
160         
161         arr = ct.find('foo', 'not here');
162         Y.ArrayAssert.isEmpty(arr, 'Test with property that exists, but no matches');
163         
164         arr = ct.items.first().find('prop', 'foo');
165         Y.Assert.areEqual(1, arr.length, 'Ensure correct items are found, at one child level');
166         Y.ArrayAssert.itemsAreEqual(['d'], Ext.pluck(arr, 'id'), 'Test order the items are found');
167         
168         arr = ct.find('special', 'main');
169         Y.ArrayAssert.isEmpty(arr, 'Ensure the container itself isn\'t found');
170         
171         ct.destroy();
172         ct = null;
173     },
174     
175     test_findBy: function(){
176         var ct = new Ext.Container({
177             foo: 0,
178             items: [{
179                 foo: 1,
180                 items: [{
181                     foo: 5
182                 },{
183                     foo: 6
184                 },{
185                     foo: 7
186                 }]
187             },{
188                 foo: 2,
189                 items: [{
190                     foo: 8
191                 },{
192                     foo: 9
193                 },{
194                     foo: 10
195                 }]
196             },{
197                 foo: 3,
198                 items: {
199                     foo: 11
200                 }
201             },{
202                 foo: 4,
203                 items: [{
204                     foo: 12
205                 },{
206                     foo: 13
207                 },{
208                     foo: 14,
209                     items: [{
210                         foo: 15
211                     },{
212                         foo: 16
213                     }]
214                 }]
215             }]
216         });
217         
218         var arr = ct.findBy(function(){
219             return this.foo % 2 == 0; 
220         });
221         
222         Y.Assert.areEqual(8, arr.length, 'Test correct items are returned, also tests that scope defaults to the component');
223         Y.ArrayAssert.itemsAreEqual([6, 2, 8, 10, 4, 12, 14, 16], Ext.pluck(arr, 'foo'), 'Test items are returned in the correct order');
224         
225         arr = ct.findBy(function(c){
226             return c.foo == 0;
227         });
228         
229         Y.ArrayAssert.isEmpty(arr, 'Ensure that the container is not included in the findBy');
230         
231         arr = ct.findBy(function(c){
232             return c.foo % this.val == 0;
233         }, {val: 3});
234         
235         Y.Assert.areEqual(5, arr.length, 'Test correct items are returned, also test custom scope');
236         
237         ct.destroy();
238         ct = null;
239     },
240     
241     test_findByType: function(){
242         var ct = new Ext.Container({
243             items: [{
244                 xtype: 'box'
245             },{
246                 xtype: 'component'
247             },{
248                 xtype: 'container',
249                 items: [{
250                     xtype: 'panel',
251                     items: {
252                         xtype: 'panel',
253                         items: {
254                             xtype: 'box'
255                         }
256                     }
257                 },{
258                     xtype: 'container',
259                     items: {
260                         xtype: 'container',
261                         items: {
262                             xtype: 'container',
263                             items: {
264                                 xtype: 'box'
265                             }
266                         }
267                     }
268                 },{
269                     xtype: 'box'
270                 }]
271             },{
272                 xtype: 'form',
273                 items: {
274                     xtype: 'fieldset',
275                     items: [{
276                         xtype: 'datefield'
277                     },{
278                         xtype: 'textfield'
279                     }]
280                 }
281             }]
282         }); 
283         
284         var arr = ct.findByType('component');
285         Y.Assert.areEqual(15, arr.length, 'Check correct number of items are returned');
286         
287         arr = ct.findByType('box', true);
288         Y.Assert.areEqual(4, arr.length, 'Test shallow parameter is respected');
289         
290         arr = ct.findByType('grid');
291         Y.Assert.areEqual(0, arr.length, 'Ensure that no items are returned if there\'s no matches');
292         
293         arr = ct.findByType('container');
294         Y.Assert.areEqual(8, arr.length, 'Check all items are found at different depths');
295         
296         ct.destroy();
297         ct = null;   
298     },
299     
300     test_getComponent: function(){
301         var component1 = new Ext.Component({itemId: 'd'}),
302             component2 = new Ext.Component({itemId: 'e'}),
303             component3 = new Ext.Component();
304             
305         var ct = new Ext.Container({
306             items: [{
307                 id: 'a'
308             },{
309                 itemId: 'b'
310             },{
311                 itemId: 'c'
312             },{
313                 //nothing
314             }, component1, {
315                 //nothing
316             }, component2]
317         });
318         
319         Y.Assert.areEqual('b', ct.getComponent(1).itemId, 'Test accessing by index');
320         Y.Assert.areEqual('a', ct.getComponent(0).id, 'Test accessing by index');
321         
322         Y.Assert.isUndefined(ct.getComponent(100), 'Test grabbing an index outside of bounds');
323         Y.Assert.isUndefined(ct.getComponent(null), 'Test with passing null');
324         Y.Assert.isUndefined(ct.getComponent('foo'), 'Test with passing id that doesn\'t exist');
325         Y.Assert.isUndefined(ct.getComponent(component3), 'Test with passing a component that doesn\'t belong to the container');
326         
327         Y.Assert.areEqual(component1, ct.getComponent(component1), 'Test passing in a component instance');
328         Y.Assert.areEqual(component2, ct.getComponent(component2), 'Test passing in a component instance');
329         
330         Y.Assert.areEqual('d', ct.getComponent('d').itemId, 'Test passing in itemId');
331         Y.Assert.areEqual('c', ct.getComponent('c').itemId, 'Test the above with an itemId');
332         
333         component3.destroy();
334         ct.destroy();
335         ct = null;
336     },
337     
338     test_insert: function(){
339         var ct = new Ext.Container({
340             items: [{
341                 itemId: 'first',
342                 xtype: 'component'
343             },{
344                 xtype: 'component'
345             },{
346                 xtype: 'component'
347             }]
348         });
349         
350         ct.insert(1, {itemId: 'a'});
351         Y.Assert.areEqual('a', ct.items.itemAt(1).itemId, 'Test simple insert');
352         
353         ct.insert(0, {itemId: 'b'});
354         Y.Assert.areEqual('b', ct.items.first().itemId, 'Test insert at 0');
355         
356         ct.insert(ct.items.getCount(), {itemId: 'c'});
357         Y.Assert.areEqual('c', ct.items.last().itemId, 'Test inserting at the last index');
358         
359         ct.insert(100, {itemId: 'd'});
360         Y.Assert.areEqual('d', ct.items.last().itemId, 'Test inserting well after the last index');
361         
362         ct.insert(2, {itemId: 'e'}, {itemId: 'f'}, {itemId: 'g'});
363         Y.Assert.areEqual('e', ct.items.itemAt(2).itemId, 'Test inserting multiple items at once');
364         Y.Assert.areEqual('f', ct.items.itemAt(3).itemId, 'Test inserting multiple items at once');
365         Y.Assert.areEqual('g', ct.items.itemAt(4).itemId, 'Test inserting multiple items at once');
366         
367         ct.insert(3, new Ext.Component({itemId: 'h'}));
368         Y.Assert.areEqual('h', ct.items.itemAt(3).itemId, 'Test simple insert');
369         
370         Y.Assert.areEqual('first', ct.items.itemAt(1).itemId, 'Test original component held position');
371         
372         ct.destroy();
373         ct = null;
374     },
375     
376     test_remove: function(){
377         var items = [],
378             ct,
379             c,
380             component1 = new Ext.Component(),
381             component2 = new Ext.Component(),
382             component3 = new Ext.Component();
383             
384         for(var i = 0; i < 10; ++i){
385             items.push({itemId: 'item' + i});
386         }
387         items.push(component1, component2);
388         ct = new Ext.Container({items: items});
389         
390         ct.remove(0);
391         Y.Assert.areEqual(11, ct.items.getCount(), 'Test remove by index');
392         
393         c = ct.remove(100);
394         Y.Assert.areEqual(11, ct.items.getCount(), 'Test remove by index, where the index doesn\'t exist')
395         Y.Assert.isUndefined(c, 'Ensure undefined is returned if the item doesn\'t exist');
396         
397         c = ct.remove(component1);
398         Y.Assert.areEqual(10, ct.items.getCount(), 'Test remove with a component instance');
399         Y.Assert.areEqual(component1, c, 'Test component is returned correctly');
400         
401         c = ct.remove(component3);
402         Y.Assert.areEqual(10, ct.items.getCount(), 'Test removing an instance that doesn\'t exist in the component');
403         Y.Assert.isUndefined(c, 'Ensure that the empty is returned in this case');
404         
405         c = ct.remove('item5');
406         Y.Assert.areEqual(9, ct.items.getCount(), 'Test removing with an itemId');
407         Y.Assert.areEqual('item5', c.itemId, 'Ensure component is returned properly');
408         
409         //test autoDestroy behaviour
410         c = ct.remove(0);
411         Y.Assert.isTrue(c.isDestroyed, 'Test that container autoDestroy/true is respected');
412         
413         c = ct.remove(0, true);
414         Y.Assert.isTrue(c.isDestroyed, 'Test that container autoDestroy/true and destroy/true works');
415         
416         c = ct.remove(0, false);
417         Y.Assert.isUndefined(c.isDestroyed, 'Test that destroy/false overrides autoDestroy/true');
418         
419         ct.autoDestroy = false;
420         c = ct.remove(0);
421         Y.Assert.isUndefined(c.isDestroyed, 'Test that autoDestroy/false is respected');
422         
423         c = ct.remove(0, false);
424         Y.Assert.isUndefined(c.isDestroyed, 'Test autoDestroy/false and destroy/false works');
425         
426         c = ct.remove(0, true);
427         Y.Assert.isTrue(c.isDestroyed, 'Test destroy/true overrides autoDestroy/false');
428         
429         component3.destroy();
430         ct.destroy();
431         ct = null;
432     },
433     
434     test_removeAll: function(){
435         var ct = new Ext.Container(),
436             arr,
437             i;
438             
439         arr = ct.removeAll();
440         Y.ArrayAssert.isEmpty(arr, 'Test removeAll with no items returns an empty array');
441         
442         for(i = 0; i < 3; ++i){
443             ct.add({
444                 itemId: 'item' + i
445             });
446         }
447         
448         arr = ct.removeAll();
449         Y.Assert.areEqual(0, ct.items.getCount(), 'Ensure all items are removed');
450         Y.ArrayAssert.itemsAreEqual(['item0', 'item1', 'item2'], Ext.pluck(arr, 'itemId'), 'Ensure they are removed in a consistent order');
451         
452         for(i = 0; i < 2; ++i){
453             ct.add({
454                 itemId: 'item' + i
455             });
456         }
457         arr = ct.removeAll(true);
458         Y.ArrayAssert.itemsAreEqual([true, true], Ext.pluck(arr, 'isDestroyed'), 'Check destroy is honoured');
459         
460         ct.autoDestroy = true;
461         for(i = 0; i < 3; ++i){
462             ct.add({
463                 itemId: 'item' + i
464             });
465         }
466         arr = ct.removeAll();
467         Y.ArrayAssert.itemsAreEqual([true, true, true], Ext.pluck(arr, 'isDestroyed'), 'Check autoDestroy is honoured');
468         
469         ct.destroy();
470         ct = null;
471     }
472 });