Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / src / core / test / unit / spec / lang / Function.js
diff --git a/src/core/test/unit/spec/lang/Function.js b/src/core/test/unit/spec/lang/Function.js
new file mode 100644 (file)
index 0000000..a332789
--- /dev/null
@@ -0,0 +1,227 @@
+describe("Ext.Function", function() {
+    describe("bind", function() {
+        var fn,
+            bind;
+
+        beforeEach(function() {
+            fn = jasmine.createSpy("bindSpy");
+        });
+
+        it("should return a function if a function is passed as first argument", function() {
+            bind = Ext.Function.bind(fn, this);
+
+            expect(typeof bind === "function").toBe(true);
+        });
+
+        it("should use the correct scope", function() {
+            bind = Ext.Function.bind(fn, fakeScope);
+
+            bind();
+
+            expect(fn.calls[0].object).toBe(fakeScope);
+        });
+
+        it("should call the first function when it is executed", function() {
+            bind = Ext.Function.bind(fn, this);
+
+            bind();
+
+            expect(fn).toHaveBeenCalled();
+        });
+
+        describe("argument passing", function() {
+
+            it("should use default args if none are passed", function() {
+                bind = Ext.Function.bind(fn, this, ['a', 'b']);
+
+                bind();
+
+                expect(fn).toHaveBeenCalledWith('a', 'b');
+            });
+
+            it("should use passed args if they are present", function() {
+                bind = Ext.Function.bind(fn, this);
+
+                bind('c', 'd');
+
+                expect(fn).toHaveBeenCalledWith('c', 'd');
+            });
+
+            it("should append args", function() {
+                bind = Ext.Function.bind(fn, this, ['a', 'b'], true);
+
+                bind('c', 'd');
+
+                expect(fn).toHaveBeenCalledWith('c', 'd', 'a', 'b');
+            });
+
+            it("should append args at the given index", function() {
+                bind = Ext.Function.bind(fn, this, ['a', 'b'], 0);
+
+                bind('c', 'd');
+
+                expect(fn).toHaveBeenCalledWith('a', 'b', 'c', 'd');
+            });
+        });
+    });
+
+    describe("createInterceptor", function() {
+        var interceptor,
+            interceptorFn,
+            interceptedFn,
+            interceptorIsRunFirst,
+            interceptedIsRunAfter;
+
+        beforeEach(function() {
+            interceptorIsRunFirst = false;
+            interceptedIsRunAfter = false;
+
+            interceptorFn = jasmine.createSpy("interceptorSpy").andCallFake(function() {
+                interceptorIsRunFirst = true;
+            });
+            interceptedFn = jasmine.createSpy("interceptedSpy").andCallFake(function() {
+                interceptedIsRunAfter = interceptorIsRunFirst;
+            });
+        });
+
+        describe("if no function is passed", function() {
+            it("should return the same function", function() {
+                expect(Ext.Function.createInterceptor(interceptedFn)).toEqual(interceptedFn);
+            });
+        });
+
+        describe("if a function is passed", function() {
+            beforeEach(function() {
+                interceptor = Ext.Function.createInterceptor(interceptedFn, interceptorFn, fakeScope);
+                interceptor();
+            });
+
+            it("should return a new function", function() {
+                expect(typeof interceptor === "function").toBe(true);
+                expect(interceptor).not.toEqual(interceptedFn);
+            });
+
+            it("should set the correct scope for the interceptor function", function() {
+                expect(interceptorFn.calls[0].object).toBe(fakeScope);
+            });
+
+            it("should call the interceptor function first", function() {
+                expect(interceptedIsRunAfter).toBe(true);
+            });
+
+        });
+
+        describe("if the interceptor function returns false", function() {
+            it("should not execute the original function", function() {
+                interceptor = Ext.Function.createInterceptor(interceptedFn, function() {
+                    return false;
+                });
+
+                interceptor();
+                expect(interceptedFn).not.toHaveBeenCalled();
+            });
+        });
+    });
+
+    describe("defer", function() {
+        var fn;
+
+        beforeEach(function(){
+            fn = jasmine.createSpy("deferSpy");
+        });
+
+        it("should execute the function after the specified number of milliseconds", function() {
+            Ext.defer(fn, 10);
+
+            waitsFor(function(){
+                return fn.calls.length === 1;
+            }, "fn was never called");
+
+            runs(function() {
+                expect(fn).toHaveBeenCalled();
+            });
+        });
+
+        it("should execute the function directly if the specified number of milliseconds is <= 0", function() {
+            Ext.defer(fn, 0);
+
+            expect(fn).toHaveBeenCalled();
+        });
+
+        it("should set the correct scope", function() {
+            Ext.defer(fn, 10, fakeScope);
+
+            waitsFor(function(){
+                return fn.calls.length === 1;
+            }, "fn was never called");
+
+            runs(function() {
+                expect(fn.calls[0].object).toBe(fakeScope);
+            });
+        });
+
+        it("should pass the correct arguments", function() {
+            Ext.defer(fn, 10, this, [1, 2, 3]);
+
+            waitsFor(function(){
+                return fn.calls.length === 1;
+            }, "fn was never called");
+
+            runs(function() {
+                expect(fn).toHaveBeenCalledWith(1,2,3);
+            });
+        });
+
+        it("should return a timeout number", function() {
+            expect(typeof Ext.defer(function() {}, 10) === 'number').toBe(true);
+        });
+    });
+
+    describe("createSequence", function() {
+        var sequence,
+            newFn,
+            origFn,
+            origFnIsRunFirst,
+            newFnIsRunAfter;
+
+        beforeEach(function() {
+            origFnIsRunFirst = false;
+            newFnIsRunAfter = false;
+
+            origFn = jasmine.createSpy("interceptedSpy").andCallFake(function() {
+                origFnIsRunFirst = true;
+            });
+
+            newFn = jasmine.createSpy("sequenceSpy").andCallFake(function() {
+                newFnIsRunAfter = origFnIsRunFirst;
+            });
+        });
+
+        describe("if no function is passed", function() {
+            it("should return the same function", function() {
+                expect(Ext.Function.createSequence(origFn)).toEqual(origFn);
+            });
+        });
+
+        describe("if a function is passed", function() {
+            beforeEach(function() {
+                sequence = Ext.Function.createSequence(origFn, newFn, fakeScope);
+                sequence();
+            });
+
+            it("should return a new function", function() {
+                expect(typeof sequence === "function").toBe(true);
+                expect(sequence).not.toEqual(origFn);
+            });
+
+            it("should set the correct scope for the sequence function", function() {
+                expect(newFn.calls[0].object).toBe(fakeScope);
+            });
+
+            it("should call the sequence function first", function() {
+                expect(newFnIsRunAfter).toBe(true);
+            });
+
+        });
+    });
+});