Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / test / unit / widgets / layout / HBoxLayout.js
1 /*!
2  * Ext JS Library 3.3.1
3  * Copyright(c) 2006-2010 Sencha Inc.
4  * licensing@sencha.com
5  * http://www.sencha.com/license
6  */
7 /**
8  * Tests Ext.data.Store functionality
9  * @author Ed Spencer
10  */
11 (function() {
12     var suite  = Ext.test.session.getSuite('Ext.layout.HBoxLayout'),
13         assert = Y.Assert;
14     
15     function buildFakeChild(config) {
16         config = config || {};
17               
18         Ext.applyIf(config, {
19             // width: 10,
20             getWidth: function() {
21                 return 10;
22             },
23             getHeight: function() {
24                 return 10;
25             },
26             getSize: function() {
27                 return {
28                     height: 10,
29                     width : 10
30                 };
31             },
32             margins: {
33                 top   : 0,
34                 right : 0,
35                 bottom: 0,
36                 left  : 0
37             }
38         });
39         
40         return config;
41     }
42     
43     function buildLayout(config) {
44         config = config || {};
45               
46         Ext.applyIf(config, {
47             padding: {
48                 top   : 0,
49                 right : 0,
50                 bottom: 0,
51                 left  : 0
52             }
53         });
54         
55         return new Ext.layout.HBoxLayout(config);
56     };
57     
58     suite.add(new Y.Test.Case({
59         name: 'calculating flexed box sizes',
60         
61         setUp: function() {
62             this.layout = buildLayout();
63             
64             this.items = [
65                 buildFakeChild({flex: 1}),
66                 buildFakeChild({flex: 1}),
67                 buildFakeChild({flex: 1}),
68                 buildFakeChild({flex: 1})
69             ];
70             
71             this.targetSize = {
72                 height: 100,
73                 width : 400
74             };
75         },
76         
77         testEqualFlexWidths: function() {
78             var calcs = this.layout.calculateChildBoxes(this.items, this.targetSize),
79                 boxes = calcs.boxes;
80             
81             assert.areEqual(100, boxes[0].width);
82             assert.areEqual(100, boxes[1].width);
83             assert.areEqual(100, boxes[2].width);
84             assert.areEqual(100, boxes[3].width);
85         },
86         
87         testDifferentFlexWidths: function() {
88             this.items = [
89                 buildFakeChild({flex: 1}),
90                 buildFakeChild({flex: 2}),
91                 buildFakeChild({flex: 3}),
92                 buildFakeChild({flex: 4})
93             ];
94             
95             var calcs = this.layout.calculateChildBoxes(this.items, this.targetSize),
96                 boxes = calcs.boxes;
97             
98             assert.areEqual(40, boxes[0].width);
99             assert.areEqual(80, boxes[1].width);
100             assert.areEqual(120, boxes[2].width);
101             assert.areEqual(160, boxes[3].width);
102         },
103         
104         testMarginsAccountedFor: function() {
105             var items = [
106                 buildFakeChild({flex: 1, margins: {left: 10, right: 10, top: 0, bottom: 0}}),
107                 buildFakeChild({flex: 1, margins: {left: 10, right: 10, top: 0, bottom: 0}}),
108                 buildFakeChild({flex: 1, margins: {left: 10, right: 10, top: 0, bottom: 0}}),
109                 buildFakeChild({flex: 1, margins: {left: 10, right: 10, top: 0, bottom: 0}})
110             ];
111              
112             var calcs = this.layout.calculateChildBoxes(items, this.targetSize),
113                 boxes = calcs.boxes;
114             
115             assert.areEqual(80, boxes[0].width);
116             assert.areEqual(80, boxes[1].width);
117             assert.areEqual(80, boxes[2].width);
118             assert.areEqual(80, boxes[3].width);
119         },
120         
121         testPaddingAccountedFor: function() {
122             this.layout = buildLayout({
123                 padding: {
124                     top   : 10,
125                     right : 10,
126                     bottom: 10,
127                     left  : 10
128                 }
129             });
130             
131             var calcs = this.layout.calculateChildBoxes(this.items, this.targetSize),
132                 boxes = calcs.boxes;
133             
134             //400px available internally, minus 20px total left + right padding = 380 / 4
135             assert.areEqual(95, boxes[0].width);
136             assert.areEqual(95, boxes[1].width);
137             assert.areEqual(95, boxes[2].width);
138             assert.areEqual(95, boxes[3].width);
139         },
140         
141         //one of the items is passed both a width and a flex - the flex should be ignored
142         testWidthDominatesFlex: function() {
143             var items = [
144                 buildFakeChild({flex: 1, width: 250, getWidth: function() {return 250;}}),
145                 buildFakeChild({flex: 1}),
146                 buildFakeChild({flex: 1}),
147                 buildFakeChild({flex: 1})
148             ];
149              
150             var calcs = this.layout.calculateChildBoxes(items, this.targetSize),
151                 boxes = calcs.boxes;
152             
153             assert.areEqual(250, boxes[0].width);
154             assert.areEqual(50, boxes[1].width);
155             assert.areEqual(50, boxes[2].width);
156             assert.areEqual(50, boxes[3].width);
157         }
158     }));
159     
160     suite.add(new Y.Test.Case({
161         name: 'minWidth of items',
162         
163         setUp: function() {
164             this.layout = buildLayout();
165             
166             this.layout.beforeCt = {
167                 getWidth: function() {
168                     return 0;
169                 },
170                 createChild: Ext.emptyFn
171             };
172             
173             this.layout.afterCt = {
174                 getWidth: function() {
175                     return 0;
176                 },
177                 createChild: Ext.emptyFn
178             };
179             
180             this.items = [
181                 buildFakeChild({width: 100, minWidth: 100}),
182                 buildFakeChild({width: 200, minWidth: 120}),
183                 buildFakeChild({width: 200, minWidth: 120}),
184                 buildFakeChild({width: 200, minWidth: 120})
185             ];
186         },
187         
188         testAvailableWidthIsSufficient: function() {
189             var targetSize = {
190                 width : 700,
191                 height: 25
192             };
193             
194             var calcs = this.layout.calculateChildBoxes(this.items, targetSize),
195                 boxes = calcs.boxes;
196             
197             assert.areEqual(0,   boxes[0].left);
198             assert.areEqual(100, boxes[1].left);
199             assert.areEqual(300, boxes[2].left);
200             assert.areEqual(500, boxes[3].left);
201             
202             assert.areEqual(100, boxes[0].width);
203             assert.areEqual(200, boxes[1].width);
204             assert.areEqual(200, boxes[2].width);
205             assert.areEqual(200, boxes[3].width);
206         },
207         
208         testHasShortfall: function() {
209             var targetSize = {
210                 width : 500,
211                 height: 25
212             };
213             
214             var calcs = this.layout.calculateChildBoxes(this.items, targetSize),
215                 boxes = calcs.boxes;
216             
217             assert.areEqual(100, boxes[0].width);
218             assert.areEqual(133, boxes[1].width);
219             assert.areEqual(133, boxes[2].width);
220             assert.areEqual(134, boxes[3].width);
221             
222             assert.areEqual(0,   boxes[0].left);
223             assert.areEqual(100, boxes[1].left);
224             assert.areEqual(233, boxes[2].left);
225             assert.areEqual(366, boxes[3].left);
226         },
227         
228         testTooNarrow: function() {
229             var targetSize = {
230                 width : 400,
231                 height: 25
232             };
233             
234             var calcs = this.layout.calculateChildBoxes(this.items, targetSize),
235                 boxes = calcs.boxes;
236             
237             assert.areEqual(0,   boxes[0].left);
238             assert.areEqual(100, boxes[1].left);
239             assert.areEqual(220, boxes[2].left);
240             assert.areEqual(340, boxes[3].left);
241             
242             assert.areEqual(100, boxes[0].width);
243             assert.areEqual(120, boxes[1].width);
244             assert.areEqual(120, boxes[2].width);
245             assert.areEqual(120, boxes[3].width);
246         }
247     }));
248     
249     suite.add(new Y.Test.Case({
250         name: 'aligning',
251         
252         setUp: function() {
253             this.items = [
254                 buildFakeChild({flex: 1, getHeight: function() {return 10;}}),
255                 buildFakeChild({flex: 1, getHeight: function() {return 20;}}),
256                 buildFakeChild({flex: 1, getHeight: function() {return 30;}}),
257                 buildFakeChild({flex: 1, getHeight: function() {return 40;}})
258             ];
259             
260             this.targetSize = {
261                 height: 100,
262                 width : 400
263             };
264         },
265         
266         testTop: function() {
267             this.layout = buildLayout({
268                 align: 'top'
269             });
270             
271             var calcs = this.layout.calculateChildBoxes(this.items, this.targetSize),
272                 boxes = calcs.boxes;
273             
274             assert.areEqual(0, boxes[0].top);
275             assert.areEqual(0, boxes[1].top);
276             assert.areEqual(0, boxes[2].top);
277             assert.areEqual(0, boxes[3].top);
278         },
279         
280         testMiddle: function() {
281             this.layout = buildLayout({
282                 align: 'middle'
283             });
284             
285             var calcs = this.layout.calculateChildBoxes(this.items, this.targetSize),
286                 boxes = calcs.boxes;
287             
288             assert.areEqual(45, boxes[0].top);
289             assert.areEqual(40, boxes[1].top);
290             assert.areEqual(35, boxes[2].top);
291             assert.areEqual(30, boxes[3].top);
292         },
293         
294         testStretch: function() {
295             this.layout = buildLayout({
296                 align: 'stretch'
297             });
298             
299             var calcs = this.layout.calculateChildBoxes(this.items, this.targetSize),
300                 boxes = calcs.boxes;
301             
302             assert.areEqual(0, boxes[0].top);
303             assert.areEqual(0, boxes[1].top);
304             assert.areEqual(0, boxes[2].top);
305             assert.areEqual(0, boxes[3].top);
306             
307             assert.areEqual(100, boxes[0].height);
308             assert.areEqual(100, boxes[1].height);
309             assert.areEqual(100, boxes[2].height);
310             assert.areEqual(100, boxes[3].height);
311         },
312         
313         testStretchMax: function() {
314             this.layout = buildLayout({
315                 align: 'stretchmax'
316             });
317             
318             var calcs = this.layout.calculateChildBoxes(this.items, this.targetSize),
319                 boxes = calcs.boxes;
320             
321             assert.areEqual(0, boxes[0].top);
322             assert.areEqual(0, boxes[1].top);
323             assert.areEqual(0, boxes[2].top);
324             assert.areEqual(0, boxes[3].top);
325             
326             assert.areEqual(40, boxes[0].height);
327             assert.areEqual(40, boxes[1].height);
328             assert.areEqual(40, boxes[2].height);
329             assert.areEqual(40, boxes[3].height);
330         }
331     }));
332     
333     suite.add(new Y.Test.Case({
334         name: 'packing',
335         
336         setUp: function() {
337             this.items = [
338                 buildFakeChild({getSize: function() {return {height: 10, width: 10};}}),
339                 buildFakeChild({getSize: function() {return {height: 10, width: 20};}}),
340                 buildFakeChild({getSize: function() {return {height: 10, width: 30};}}),
341                 buildFakeChild({getSize: function() {return {height: 10, width: 40};}})
342             ];
343             
344             this.targetSize = {
345                 height: 100,
346                 width : 400
347             };
348         },
349         
350         testPackStart: function() {
351             this.layout = buildLayout({
352                 pack: 'start'
353             });
354             
355             var calcs = this.layout.calculateChildBoxes(this.items, this.targetSize),
356                 boxes = calcs.boxes;
357             
358             assert.areEqual(0, boxes[0].left);
359             assert.areEqual(10, boxes[1].left);
360             assert.areEqual(30, boxes[2].left);
361             assert.areEqual(60, boxes[3].left);
362         },
363         
364         testPackCenter: function() {
365             this.layout = buildLayout({
366                 pack: 'center'
367             });
368             
369             var calcs = this.layout.calculateChildBoxes(this.items, this.targetSize),
370                 boxes = calcs.boxes;
371                         
372             assert.areEqual(150, boxes[0].left);
373             assert.areEqual(160, boxes[1].left);
374             assert.areEqual(180, boxes[2].left);
375             assert.areEqual(210, boxes[3].left);
376         },
377         
378         testPackEnd: function() {
379             this.layout = buildLayout({
380                 pack: 'end'
381             });
382             
383             var calcs = this.layout.calculateChildBoxes(this.items, this.targetSize),
384                 boxes = calcs.boxes;
385             
386             assert.areEqual(300, boxes[0].left);
387             assert.areEqual(310, boxes[1].left);
388             assert.areEqual(330, boxes[2].left);
389             assert.areEqual(360, boxes[3].left);
390         },
391         
392         testWidthPropertyDominatesGetWidth: function() {
393             var layout = buildLayout({
394                 pack : 'start',
395                 align: 'stretch'
396             });
397             
398             var items = [
399                 {
400                     title: 'Panel 1',
401                     flex: 1,
402                     html: 'flex : 1',
403                     frame: true,
404                     margins: {top: 0, left: 0, right: 0, bottom: 0},
405                     getHeight: function() {return 10;},
406                     getWidth: function() {return 10;}
407                 }, {
408                     title: 'Panel 2',
409                     width: 100,
410                     html: 'width : 100',
411                     frame: true,
412                     margins: {top: 0, left: 0, right: 0, bottom: 0},
413                     getHeight: function() {return 10;},
414                     
415                     //NOTE: this should be ignored by HBox because we have a different configured width property
416                     getWidth: function() {return 10;}
417                 }, {
418                     title: 'Panel 3',
419                     flex: 2,
420                     html: 'flex : 2',
421                     frame: true,
422                     margins: {top: 0, left: 0, right: 0, bottom: 0},
423                     getHeight: function() {return 10;},
424                     getWidth: function() {return 10;}
425                 }
426             ];
427             
428             var targetSize = {
429                 height: 630,
430                 width : 1628
431             };
432             
433             var calcs = layout.calculateChildBoxes(items, targetSize),
434                 boxes = calcs.boxes;
435             
436             assert.areEqual(0, boxes[0].left);
437             assert.areEqual(510, boxes[1].left);
438             assert.areEqual(610, boxes[2].left);
439         }
440     }));
441     
442     suite.add(new Y.Test.Case({
443         name: 'meta data from calculated box sizes',
444         
445         setUp: function() {
446             this.layout = buildLayout();
447             
448             this.items = [
449                 buildFakeChild({getHeight: function() {return 50;}, flex: 1}),
450                 buildFakeChild({getHeight: function() {return 60;}, flex: 1}),
451                 buildFakeChild({getHeight: function() {return 10;}, flex: 1}),
452                 buildFakeChild({getHeight: function() {return 80;}, flex: 1})
453             ];
454             
455             this.targetSize = {
456                 height: 100,
457                 width : 400
458             };
459         },
460         
461         testMaxHeight: function() {
462             var calcs = this.layout.calculateChildBoxes(this.items, this.targetSize),
463                 meta  = calcs.meta;
464             
465             assert.areEqual(80, meta.maxHeight);
466         }
467     }));
468     
469     suite.add(new Y.Test.Case({
470         name: 'update innerCt size',
471         
472         setUp: function() {
473             this.layout = buildLayout({
474                 align  : 'stretch',
475                 padding: {
476                     top   : 10,
477                     bottom: 20,
478                     left  : 0,
479                     right : 0
480                 }
481             });
482             
483             //fake the values that are calculated during onLayout
484             this.layoutTargetLastSize = {
485                 width : 400,
486                 height: 100
487             };
488             
489             this.childBoxCache = {
490                 meta: {
491                     maxHeight: 150
492                 }
493             };
494         },
495         
496         testMaintainsHeightForAlignStretch: function() {
497             var layout = this.layout,
498                 width, height;
499             
500             //a fake innerCt element that we can intercept calls to setSize on
501             layout.innerCt = {
502                 setSize: function(widthArg, heightArg) {
503                     width  = widthArg;
504                     height = heightArg;
505                 }
506             };
507             
508             layout.updateInnerCtSize(this.layoutTargetLastSize, this.childBoxCache);
509             
510             assert.areSame(400, width);
511             assert.areSame(100, height);
512         },
513         
514         //if aligning middle, increase height to accomodate the tallest child
515         testIncreasesHeightForAlignMiddle: function() {
516             this.layout = buildLayout({
517                 align  : 'middle',
518                 padding: {
519                     top   : 10,
520                     bottom: 20,
521                     left  : 0,
522                     right : 0
523                 }
524             });
525                         
526             var layout = this.layout,
527                 width, height;
528             
529             //a fake innerCt element that we can intercept calls to setSize on
530             layout.innerCt = {
531                 setSize: function(widthArg, heightArg) {
532                     width  = widthArg;
533                     height = heightArg;
534                 }
535             };
536             
537             layout.updateInnerCtSize(this.layoutTargetLastSize, this.childBoxCache);
538             
539             assert.areSame(400, width);
540             assert.areSame(180, height);
541         }
542     }));
543 })();