Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / src / core / test / unit / spec / lang / Function.js
1 describe("Ext.Function", function() {
2     describe("bind", function() {
3         var fn,
4             bind;
5
6         beforeEach(function() {
7             fn = jasmine.createSpy("bindSpy");
8         });
9
10         it("should return a function if a function is passed as first argument", function() {
11             bind = Ext.Function.bind(fn, this);
12
13             expect(typeof bind === "function").toBe(true);
14         });
15
16         it("should use the correct scope", function() {
17             bind = Ext.Function.bind(fn, fakeScope);
18
19             bind();
20
21             expect(fn.calls[0].object).toBe(fakeScope);
22         });
23
24         it("should call the first function when it is executed", function() {
25             bind = Ext.Function.bind(fn, this);
26
27             bind();
28
29             expect(fn).toHaveBeenCalled();
30         });
31
32         describe("argument passing", function() {
33
34             it("should use default args if none are passed", function() {
35                 bind = Ext.Function.bind(fn, this, ['a', 'b']);
36
37                 bind();
38
39                 expect(fn).toHaveBeenCalledWith('a', 'b');
40             });
41
42             it("should use passed args if they are present", function() {
43                 bind = Ext.Function.bind(fn, this);
44
45                 bind('c', 'd');
46
47                 expect(fn).toHaveBeenCalledWith('c', 'd');
48             });
49
50             it("should append args", function() {
51                 bind = Ext.Function.bind(fn, this, ['a', 'b'], true);
52
53                 bind('c', 'd');
54
55                 expect(fn).toHaveBeenCalledWith('c', 'd', 'a', 'b');
56             });
57
58             it("should append args at the given index", function() {
59                 bind = Ext.Function.bind(fn, this, ['a', 'b'], 0);
60
61                 bind('c', 'd');
62
63                 expect(fn).toHaveBeenCalledWith('a', 'b', 'c', 'd');
64             });
65         });
66     });
67
68     describe("createInterceptor", function() {
69         var interceptor,
70             interceptorFn,
71             interceptedFn,
72             interceptorIsRunFirst,
73             interceptedIsRunAfter;
74
75         beforeEach(function() {
76             interceptorIsRunFirst = false;
77             interceptedIsRunAfter = false;
78
79             interceptorFn = jasmine.createSpy("interceptorSpy").andCallFake(function() {
80                 interceptorIsRunFirst = true;
81             });
82             interceptedFn = jasmine.createSpy("interceptedSpy").andCallFake(function() {
83                 interceptedIsRunAfter = interceptorIsRunFirst;
84             });
85         });
86
87         describe("if no function is passed", function() {
88             it("should return the same function", function() {
89                 expect(Ext.Function.createInterceptor(interceptedFn)).toEqual(interceptedFn);
90             });
91         });
92
93         describe("if a function is passed", function() {
94             beforeEach(function() {
95                 interceptor = Ext.Function.createInterceptor(interceptedFn, interceptorFn, fakeScope);
96                 interceptor();
97             });
98
99             it("should return a new function", function() {
100                 expect(typeof interceptor === "function").toBe(true);
101                 expect(interceptor).not.toEqual(interceptedFn);
102             });
103
104             it("should set the correct scope for the interceptor function", function() {
105                 expect(interceptorFn.calls[0].object).toBe(fakeScope);
106             });
107
108             it("should call the interceptor function first", function() {
109                 expect(interceptedIsRunAfter).toBe(true);
110             });
111
112         });
113
114         describe("if the interceptor function returns false", function() {
115             it("should not execute the original function", function() {
116                 interceptor = Ext.Function.createInterceptor(interceptedFn, function() {
117                     return false;
118                 });
119
120                 interceptor();
121                 expect(interceptedFn).not.toHaveBeenCalled();
122             });
123         });
124     });
125
126     describe("defer", function() {
127         var fn;
128
129         beforeEach(function(){
130             fn = jasmine.createSpy("deferSpy");
131         });
132
133         it("should execute the function after the specified number of milliseconds", function() {
134             Ext.defer(fn, 10);
135
136             waitsFor(function(){
137                 return fn.calls.length === 1;
138             }, "fn was never called");
139
140             runs(function() {
141                 expect(fn).toHaveBeenCalled();
142             });
143         });
144
145         it("should execute the function directly if the specified number of milliseconds is <= 0", function() {
146             Ext.defer(fn, 0);
147
148             expect(fn).toHaveBeenCalled();
149         });
150
151         it("should set the correct scope", function() {
152             Ext.defer(fn, 10, fakeScope);
153
154             waitsFor(function(){
155                 return fn.calls.length === 1;
156             }, "fn was never called");
157
158             runs(function() {
159                 expect(fn.calls[0].object).toBe(fakeScope);
160             });
161         });
162
163         it("should pass the correct arguments", function() {
164             Ext.defer(fn, 10, this, [1, 2, 3]);
165
166             waitsFor(function(){
167                 return fn.calls.length === 1;
168             }, "fn was never called");
169
170             runs(function() {
171                 expect(fn).toHaveBeenCalledWith(1,2,3);
172             });
173         });
174
175         it("should return a timeout number", function() {
176             expect(typeof Ext.defer(function() {}, 10) === 'number').toBe(true);
177         });
178     });
179
180     describe("createSequence", function() {
181         var sequence,
182             newFn,
183             origFn,
184             origFnIsRunFirst,
185             newFnIsRunAfter;
186
187         beforeEach(function() {
188             origFnIsRunFirst = false;
189             newFnIsRunAfter = false;
190
191             origFn = jasmine.createSpy("interceptedSpy").andCallFake(function() {
192                 origFnIsRunFirst = true;
193             });
194
195             newFn = jasmine.createSpy("sequenceSpy").andCallFake(function() {
196                 newFnIsRunAfter = origFnIsRunFirst;
197             });
198         });
199
200         describe("if no function is passed", function() {
201             it("should return the same function", function() {
202                 expect(Ext.Function.createSequence(origFn)).toEqual(origFn);
203             });
204         });
205
206         describe("if a function is passed", function() {
207             beforeEach(function() {
208                 sequence = Ext.Function.createSequence(origFn, newFn, fakeScope);
209                 sequence();
210             });
211
212             it("should return a new function", function() {
213                 expect(typeof sequence === "function").toBe(true);
214                 expect(sequence).not.toEqual(origFn);
215             });
216
217             it("should set the correct scope for the sequence function", function() {
218                 expect(newFn.calls[0].object).toBe(fakeScope);
219             });
220
221             it("should call the sequence function first", function() {
222                 expect(newFnIsRunAfter).toBe(true);
223             });
224
225         });
226     });
227 });