Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / src / core / test / unit / spec / Ext-more.js
1 describe("Ext-more", function() {
2     describe("Ext.id", function(){
3         var el;
4         describe("if element passed as first argument is different of document or window", function() {
5             beforeEach(function() {
6                 el = document.createElement("div");
7                 document.body.appendChild(el);
8             });
9
10             afterEach(function(){
11                 Ext.getBody().dom.removeChild(el);
12             });
13
14             it("should generate an unique id for the element with default prefix ext-gen", function() {
15                 expect(Ext.id(el)).toEqual("ext-gen" + Ext.idSeed);
16             });
17
18             it("should generate an unique id for the element with custom prefix", function() {
19                 var prefix = "nico-yhwh";
20                 expect(Ext.id(el, prefix)).toEqual(prefix + Ext.idSeed);
21             });
22
23             it("should not override existing id", function() {
24                 var id = "unchanged";
25                 el.id = id;
26                 expect(Ext.id(el)).toEqual(id);
27             });
28         });
29
30         describe("if element passed as first argument is document", function() {
31             it("should return Ext.documentId", function() {
32                 expect(Ext.id(document)).toEqual(Ext.documentId);
33             });
34         });
35
36         describe("if element passed as first argument is window", function() {
37             it("should return Ext.windowId", function() {
38                 expect(Ext.id(window)).toEqual(Ext.windowId);
39             });
40         });
41     });
42
43     describe("Ext.getBody", function() {
44         it("should return current document body as an Ext.core.Element", function() {
45             expect(Ext.getBody()).toEqual(Ext.get(document.body)); 
46         });
47     });
48
49     describe("Ext.getHead", function() {
50         it("should return current document head as an Ext.core.Element", function() {
51             expect(Ext.getHead()).toEqual(Ext.get(document.getElementsByTagName("head")[0]));
52         });
53     });
54
55     describe("Ext.getDoc", function() {
56         it("should return the current HTML document object as an Ext.element", function() {
57             expect(Ext.getDoc()).toEqual(Ext.get(document));
58         });
59     });
60
61     describe("Ext.getCmp", function() {
62         it("should return a component", function() {
63             var cmp = new Ext.Component({id: 'foobar'});
64             expect(Ext.getCmp('foobar')).toBe(cmp);
65             cmp.destroy();
66         });
67     });
68
69     describe("Ext.getOrientation", function() {
70         it("should return the current orientation of the mobile device", function() {
71             if (window.innerHeight <= window.innerWidth) {
72                 expect(Ext.getOrientation()).toEqual("landscape");
73             } else {
74                 expect(Ext.getOrientation()).toEqual("portrait");
75             }
76         });
77     });
78
79     describe("Ext.callback", function() {
80         var cfn;
81
82         beforeEach(function() {
83             cfn = jasmine.createSpy();
84         });
85
86         afterEach(function() {
87             cfn = undefined; 
88         });
89
90         it("should execute the passed function in the specified scope", function() {
91             Ext.callback(cfn, fakeScope);
92             expect(cfn.calls[0].object).toBe(fakeScope);
93         });
94
95         it("should pass arguments to the callback function", function() {
96             Ext.callback(cfn, fakeScope, [1, 2, 3, 4, 6]);
97             expect(cfn).toHaveBeenCalledWith(1, 2, 3, 4,6); 
98         });
99
100         it("should be able to defer function call", function() {
101             runs(function() {
102                 Ext.callback(cfn, fakeScope, [1, 2, 3, 4, 6], 1);
103                 expect(cfn).not.toHaveBeenCalled();
104             });
105             waits(1);
106             runs(function() {
107                 expect(cfn).toHaveBeenCalledWith(1, 2, 3, 4, 6);
108                 expect(cfn.calls[0].object).toBe(fakeScope);
109             });
110
111         });
112     });
113
114     describe("Ext.destroy", function() {
115         var o1, o2, o3;
116
117         beforeEach(function() {
118             o1 = jasmine.createSpyObj("o1", ["destroy"]);
119
120             o2 = jasmine.createSpyObj("o2", ["destroy"]);
121
122             o3 = jasmine.createSpyObj("o3", ["dest"]);
123
124         });
125
126         it("should destroy an object", function() {
127             Ext.destroy(o1);
128
129             expect(o1.destroy).toHaveBeenCalled();
130         });
131
132         it("should no destroy an object without a destroy method", function() {
133             Ext.destroy(o3);
134
135             expect(o3.dest).not.toHaveBeenCalled();
136         });
137
138         it("should destroy an array of objects", function() {
139             Ext.destroy([o1, o2, o3]);
140
141             expect(o1.destroy).toHaveBeenCalled();
142             expect(o2.destroy).toHaveBeenCalled();
143             expect(o3.dest).not.toHaveBeenCalled();
144         });
145
146         it("should destroy multiple objects", function() {
147             Ext.destroy(o1, o2, o3);
148
149             expect(o1.destroy).toHaveBeenCalled();
150             expect(o2.destroy).toHaveBeenCalled();
151             expect(o3.dest).not.toHaveBeenCalled();
152         });
153
154         it("should remove dom if object is an Ext.element", function() {
155             var el = Ext.getBody().createChild({id: "to_destroy"});
156
157             Ext.destroy(el);
158
159             expect(Ext.fly("to_destroy")).toBeNull();
160         });
161     });
162
163     describe("Ext.htmlEncode", function() {
164         var htmlEncode = Ext.String.htmlEncode,
165         str;
166
167         it("should replace ampersands", function() {
168             str = "Fish & Chips";
169
170             expect(htmlEncode(str)).toEqual("Fish &amp; Chips");
171         });
172
173         it("should replace less than", function() {
174             str = "Fish > Chips";
175
176             expect(htmlEncode(str)).toEqual("Fish &gt; Chips");
177         });
178
179         it("should replace greater than", function() {
180             str = "Fish < Chips";
181
182             expect(htmlEncode(str)).toEqual("Fish &lt; Chips");
183         });
184
185         it("should replace double quote", function() {
186             str = 'Fish " Chips';
187
188             expect(htmlEncode(str)).toEqual("Fish &quot; Chips");
189         });
190     });
191
192     describe("Ext.htmlEncode", function() {
193         var htmlDecode = Ext.String.htmlDecode,
194         str;
195
196         it("should replace ampersands", function() {
197             str = "Fish &amp; Chips";
198
199             expect(htmlDecode(str)).toEqual("Fish & Chips");
200         });
201
202         it("should replace less than", function() {
203             str = "Fish &gt; Chips";
204
205             expect(htmlDecode(str)).toEqual("Fish > Chips");
206         });
207
208         it("should replace greater than", function() {
209             str = "Fish &lt; Chips";
210
211             expect(htmlDecode(str)).toEqual("Fish < Chips");
212         });
213
214         it("should replace double quote", function() {
215             str = 'Fish &quot; Chips';
216
217             expect(htmlDecode(str)).toEqual('Fish " Chips');
218         });
219     });
220
221     describe("Ext.urlAppend", function() {
222         var url = "http://example.com/";
223
224         it("should manage question mark", function() {
225             expect(Ext.urlAppend(url, "test=1")).toEqual("http://example.com/?test=1");
226         });
227
228         it("should manage ampersand", function() {
229             expect(Ext.urlAppend(url + "?test=1","foo=2")).toEqual("http://example.com/?test=1&foo=2");
230         });
231
232         it("should return directly url if content is empty", function() {
233             expect(Ext.urlAppend(url)).toEqual(url);
234         });
235     });
236
237     describe("Ext.getDom", function() {
238         var el1;
239
240         beforeEach(function() {
241             el1 = Ext.getBody().createChild({id: "elone"});
242         });
243
244         afterEach(function() {
245             el1.remove();
246         });
247
248         it("should return a dom element if an Ext.element is passed as first argument", function() {
249             expect(Ext.getDom(el1)).toEqual(el1.dom);
250         });
251
252         it("should return a dom element if the string (id) passed as first argument", function() {
253             expect(Ext.getDom("elone")).toEqual(el1.dom);
254         });
255     });
256
257     describe("Ext.removeNode", function(){
258         describe("if passed element isn't body", function() {
259             var el, id;
260             beforeEach(function() {
261                 el = Ext.getBody().createChild({
262                     tag: 'span',
263                     html: 'foobar'
264                 });
265                 id = el.id;
266
267             });
268
269             it("should remove a dom element from document", function(){
270                 Ext.removeNode(el.dom);
271                 expect(document.body.childNodes[0]).toBeUndefined();
272             });
273
274             it("should delete the cache reference", function() {
275                 Ext.removeNode(el.dom);
276                 expect(Ext.cache[id]).toBeUndefined();
277             });
278
279             it("should remove all listeners from the dom element", function() {
280                 var listener = jasmine.createSpy();
281                 el.on('mouseup', listener);
282                 Ext.removeNode(el.dom);
283                 jasmine.fireMouseEvent(el.dom, 'mouseup');
284                 expect(listener).not.toHaveBeenCalled();
285             });
286         });
287
288         describe("if passed element is body", function() {
289             it("should not delete the cache reference", function() {
290                 Ext.removeNode(document.body);
291                 expect(Ext.cache[Ext.getBody().id]).toBeDefined();
292             });
293
294             it("should not remove listeners from body", function() {
295                 var listener = jasmine.createSpy();
296                 Ext.getBody().on('mouseup', listener);
297                 Ext.removeNode(document.body);
298                 jasmine.fireMouseEvent(document.body, 'mouseup');
299                 expect(listener).toHaveBeenCalled();
300                 Ext.getBody().un('mouseup', listener);
301             });
302         });
303
304         describe("if enableNestedListenerRemoval is true", function() {
305             var el, child;
306
307             beforeEach(function(){
308                 Ext.enableNestedListenerRemoval = true;
309                 el = Ext.getBody().createChild();
310                 child = el.createChild();
311             });
312
313             afterEach(function(){
314                 Ext.enableNestedListenerRemoval = false;
315             });
316
317             it("should remove listener on children", function() {
318                 var listener = jasmine.createSpy();
319                 child.on('mouseup', listener); 
320                 Ext.removeNode(el.dom);
321                 jasmine.fireMouseEvent(child.dom, 'mouseup');
322                 expect(listener).not.toHaveBeenCalled();
323             });
324
325         });
326
327         describe("if enableNestedListenerRemoval is false (default)", function() {
328             var el, child;
329
330             beforeEach(function(){
331                 el = Ext.getBody().createChild();
332                 child = el.createChild();
333             });
334
335             it("should not remove listener on children", function() {
336                 var listener = jasmine.createSpy();
337                 child.on('mouseup', listener); 
338                 Ext.removeNode(el.dom);
339                 jasmine.fireMouseEvent(child.dom, 'mouseup');
340                 expect(listener).toHaveBeenCalled();
341                 Ext.EventManager.purgeElement(child.dom);
342             });
343         });
344     });
345
346     describe("Ext.addBehaviors", function() {
347         var listener, span1, span2, div1;
348
349         beforeEach(function() {
350             span1 = Ext.getBody().createChild({
351                 tag: 'span' 
352             });
353
354             span2 = Ext.getBody().createChild({
355                 tag: 'span'
356             });
357
358             div1 = Ext.getBody().createChild({
359                 cls: 'foo'
360             });
361
362             listener = jasmine.createSpy();
363         });
364
365         afterEach(function() {
366             span1.remove();
367             span2.remove();
368             div1.remove();
369         });
370
371         it("should apply event listeners to elements by selectors", function() {
372             Ext.addBehaviors({
373                 'span @mouseup': listener
374             });
375
376             jasmine.fireMouseEvent(span1.dom, 'mouseup');
377             jasmine.fireMouseEvent(span2.dom, 'mouseup');
378             jasmine.fireMouseEvent(div1.dom, 'mouseup');
379
380             expect(listener.calls.length).toEqual(2);
381
382         });
383
384         it("should manage multiple selectors", function() {
385             Ext.addBehaviors({
386                 'span, div.foo @mouseup': listener
387             });
388
389             jasmine.fireMouseEvent(span1.dom, 'mouseup');
390             jasmine.fireMouseEvent(span2.dom, 'mouseup');
391             jasmine.fireMouseEvent(div1.dom, 'mouseup');
392
393             expect(listener.calls.length).toEqual(3);
394
395         });
396     });
397
398     describe("Ext.getScrollBarWidth", function() {
399         it("should return a number between 10 and 40 (we assume that document is loaded)", function() {
400             expect(Ext.getScrollBarWidth() > 10).toBe(true);
401             expect(Ext.getScrollBarWidth() < 40).toBe(true);
402         }); 
403     });
404
405     describe("Ext.copyTo", function(){
406         var src, dest;
407
408         beforeEach(function() {
409             src = {
410                 a: 1,
411                 b: 2,
412                 c: 3,
413                 d: 4
414             };
415
416             dest = {};
417         });
418
419         afterEach(function(){
420             src = null;
421             dest = null;
422         });
423
424         describe("with an array of named properties", function() {
425             it("should copy a set of named properties fom the source object to the destination object.", function() {
426                 Ext.copyTo(dest, src, ['a', 'b', 'e']);
427
428                 expect(dest).toEqual({
429                     a: 1,
430                     b: 2 
431                 });
432             });
433         });
434
435         describe("with a string list of named properties", function() {
436             it("should copy a set of named properties fom the source object to the destination object.", function() {
437                 Ext.copyTo(dest, src, 'c,b,e');
438                 expect(dest).toEqual({
439                     b: 2,
440                     c: 3 
441                 });
442             });
443         });
444     });
445
446     describe("Ext.destroyMembers", function() {
447         var obj, destroyable;
448
449         beforeEach(function(){
450             destroyable = {
451                 destroy: jasmine.createSpy()
452             };
453             obj = {
454                 a: 1,
455                 b: 2,
456                 c: 3,
457                 d: 4,
458                 me : destroyable
459             };
460         });
461
462         it("should remove named properties from a passed object", function() {
463             Ext.destroyMembers(obj, 'a', 'c', 'i');
464             expect(obj).toEqual({
465                 b: 2,
466                 d: 4,
467                 me: destroyable
468             });
469         });
470
471         it("should attempt to destroy passed properties", function() {
472             Ext.destroyMembers(obj, 'a', 'c', 'me');
473
474             expect(destroyable.destroy).toHaveBeenCalled();
475         });
476     });
477
478     describe("Ext.partition", function() {
479         describe("with an array of boolean", function() {
480             it("should partition the set into two sets: a true and a false set", function() {
481                 expect(Ext.partition([true, true, false, false, true])).toEqual([[true,true,true], [false,false]]);
482             });
483         });
484         
485         describe("with an array to partition and a function to determine truth", function() {
486             it("should partition the set into two sets: a true and a false set", function() {
487                 var array = [
488                     'a',
489                     'b',
490                     'c',
491                     'a'
492                 ];
493                  expect(Ext.partition(array, function(item){
494                         return item == "a"
495                 })).toEqual([
496                     ['a', 'a'], 
497                     ['b', 'c']
498                 ]);
499             });
500         });
501         
502         describe("with a NodeList to partition and a function to determine truth", function() {
503             it("should partition the set into two sets: a true and a false set", function() {
504                 var p = [];
505                 
506                 p[0] = Ext.getBody().createChild({
507                     tag: "p",
508                     cls: "class1"
509                 });
510                 p[1] = Ext.getBody().createChild({
511                     tag: "p",
512                     cls: "class2"
513                 });
514                 p[2] = Ext.getBody().createChild({
515                     tag: "p",
516                     cls: "class1"
517                 });
518                 p[3] = Ext.getBody().createChild({
519                     tag: "p",
520                     cls: "class4"
521                 });
522                 p[4] = Ext.getBody().createChild({
523                     tag: "p",
524                     cls: "class5"
525                 });
526                 p[5] = Ext.getBody().createChild({
527                     tag: "p",
528                     cls: "class1"
529                 });                    
530                 
531                 expect(Ext.partition(Ext.query("p"), function(val){
532                         return val.className == "class1"
533                 })).toEqual([
534                     [p[0].dom, p[2].dom, p[5].dom], 
535                     [p[1].dom, p[3].dom, p[4].dom]
536                 ]);
537                 
538                 Ext.Array.each(p, function(el) {
539                     el.remove();
540                 });
541             });
542         });
543     });
544 });