Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / src / core / test / unit / spec / dom / Element.js
diff --git a/src/core/test/unit/spec/dom/Element.js b/src/core/test/unit/spec/dom/Element.js
new file mode 100644 (file)
index 0000000..1032f36
--- /dev/null
@@ -0,0 +1,633 @@
+describe("Ext.core.Element", function() {
+    var domEl,
+        element;
+        
+    afterEach(function() {
+        if (element) {
+            element.remove();
+        }
+
+        if (domEl && domEl.parentNode === document.body) {
+            document.body.removeChild(domEl);
+        }
+    });
+    
+    describe("instantiation", function() {
+        beforeEach(function() {
+            domEl = document.createElement("div");
+            Ext.getBody().appendChild(domEl);
+        });
+        
+
+        
+        it("should set dom element id if it hasn't already one", function() {
+            element = new Ext.core.Element(domEl);
+
+            expect(domEl.id).toBeDefined();
+        });
+
+        it("should not set dom element id if it has already one", function() {
+            var id = Ext.id();
+
+            domEl.id = id;
+            element = new Ext.core.Element(domEl);
+
+            expect(domEl.id).toEqual(id);
+        });
+
+        it("should set dom property to dom element", function() {
+            element = new Ext.core.Element(domEl);
+
+            expect(element.dom).toBe(domEl);
+        });
+
+        it("should set id property to dom id", function() {
+            var id = Ext.id();
+
+            domEl.id = id;
+            element = new Ext.core.Element(domEl);
+
+            expect(element.id).toEqual(id);
+        });
+
+        it("should not set dom or id property if first argument is undefined", function() {
+            element = new Ext.core.Element();
+
+            expect(element.id).toBeUndefined();
+            expect(element.dom).toBeUndefined();
+        });
+
+        it("should find a dom element if a string corresponding to it's id is passed as first argument", function() {
+            var id = Ext.id();
+
+            domEl.id = id;
+
+            element = new Ext.core.Element(id);
+
+            expect(element.dom).toBe(domEl);
+        });
+    });
+
+    describe("methods", function() {
+        beforeEach(function() {
+            element = Ext.getBody().createChild({tag: "div"});
+            domEl = element.dom;
+        });
+
+        describe("set", function() {
+            it("should call Ext.core.DomHelper.applyStyles if object passed as first argument has style property", function() {
+                var style = {width:'100px'};
+
+                spyOn(Ext.core.DomHelper, "applyStyles");
+
+                element.set({style: style});
+
+                expect(Ext.core.DomHelper.applyStyles).toHaveBeenCalledWith(element.dom, style);
+            });
+
+            it("should set dom element className if object passed as first argument has cls property", function() {
+                var cls = "x-test-class";
+
+                element.set({cls: cls});
+
+                expect(element.dom.className).toEqual(cls);
+            });
+
+            it("should use setAttribute by default", function() {
+                spyOn(element.dom, "setAttribute");
+
+                element.set({align: "center"});
+
+                expect(element.dom.setAttribute).toHaveBeenCalledWith("align", "center");
+            });
+
+            it("should be able to use expandos", function() {
+                spyOn(element.dom, "setAttribute");
+
+                element.set({align: "center"}, false);
+
+
+                expect(element.dom.align).toEqual("center");
+            });
+
+        });
+
+        describe("is", function() {
+            it("Returns true if this element matches the passed simple selector", function() {
+                element.set({cls: "x-test-class"});
+
+                expect(element.is("div.x-test-class")).toBe(true);
+            });
+        });
+
+        describe("focus", function() {
+            it("should focus dom element", function() {
+                spyOn(element.dom, "focus");
+
+                element.focus();
+
+                expect(element.dom.focus).toHaveBeenCalled();
+            });
+
+            it("should be able to defer dom element focus", function() {
+                spyOn(element.dom, "focus");
+                element.focus(1);
+
+                waitsFor(function(){
+                    return element.dom.focus.calls.length === 1;
+                }, "element.dom.focus was never called");
+
+                runs(function() {
+                    expect(element.dom.focus).toHaveBeenCalled();
+                });
+            });
+
+            it("should ignore any exception", function() {
+                element.dom.focus = function() {
+                    throw "error";
+                };
+
+                expect(element.focus).not.toThrow("error");
+            });
+        });
+
+        describe("blur", function() {
+            it("should blur dom element", function() {
+                spyOn(element.dom, "blur");
+
+                element.blur();
+
+                expect(element.dom.blur).toHaveBeenCalled();
+            });
+
+
+            it("should ignore any exception", function() {
+                element.dom.blur = function() {
+                    throw "error";
+                };
+
+                expect(element.blur).not.toThrow("error");
+            });
+        });
+
+        describe("getValue", function() {
+            beforeEach(function() {
+                element.dom.value = "10";
+            });
+
+            it("should return the dom value", function() {
+                expect(element.getValue()).toEqual("10");
+            });
+
+            it("should return the dom value as Number", function() {
+                expect(element.getValue(true)).toEqual(10);
+            });
+        });
+
+        describe("listeners", function() {
+            var options;
+
+            beforeEach(function() {
+                options = {delay: 10};
+            });
+
+            describe("addListener", function() {
+                it("should call Ext.EventManager.on", function() {
+                    spyOn(Ext.EventManager, "on");
+
+                    element.addListener("click", Ext.emptyFn, fakeScope, options);
+
+                    expect(Ext.EventManager.on).toHaveBeenCalledWith(element.dom, "click", Ext.emptyFn, fakeScope, options);
+                });
+            });
+
+            describe("removeListener", function() {
+                it("should call Ext.EventManager.un", function() {
+                    spyOn(Ext.EventManager, "un");
+
+                    element.removeListener("click", Ext.emptyFn, fakeScope);
+
+                    expect(Ext.EventManager.un).toHaveBeenCalledWith(element.dom, "click", Ext.emptyFn, fakeScope);
+                });
+            });
+
+            describe("removeAllListener", function() {
+                it("should call Ext.EventManager.removeAll", function() {
+                    spyOn(Ext.EventManager, "removeAll");
+
+                    element.removeAllListeners();
+
+                    expect(Ext.EventManager.removeAll).toHaveBeenCalledWith(element.dom);
+                });
+            });
+
+            describe("purgeAllListener", function() {
+                it("should call Ext.EventManager.purgeElement", function() {
+                    spyOn(Ext.EventManager, "purgeElement");
+
+                    element.purgeAllListeners();
+
+                    expect(Ext.EventManager.purgeElement).toHaveBeenCalledWith(element);
+                });
+            });
+        });
+        
+        describe("addUnits", function() {
+            it("should return an empty string if size passed is an empty string", function() {
+                expect(element.addUnits("")).toEqual("");
+            });
+
+            it("should return auto if size passed is 'auto' string", function() {
+                expect(element.addUnits("auto")).toEqual("auto");
+            });
+
+            it("should return an empty string if size passed is undefined", function() {
+                expect(element.addUnits(undefined)).toEqual("");
+            });
+
+            it("should return an empty string if size passed is null", function() {
+                expect(element.addUnits(null)).toEqual("");
+            });
+        });
+
+        describe("remove", function() {
+            beforeEach(function() {
+                spyOn(Ext, "removeNode").andCallThrough();
+                element.remove();
+            });
+
+            it("should remove dom property", function() {
+                expect(element.dom).toBeUndefined();
+            });
+
+            it("should call Ext.removeNode", function() {
+                expect(Ext.removeNode).toHaveBeenCalledWith(domEl);
+            });
+        });
+
+        describe("hover", function() {
+            var overFn, outFn, options;
+            beforeEach(function() {
+                overFn = function() {
+                    return 1;
+                };
+
+                outFn = function() {
+                    return 2;
+                };
+
+                options = {
+                    foo: true
+                };
+
+                spyOn(element, "on");
+            });
+
+            describe("mouseenter event", function() {
+                it("should add a listener on mouseenter", function() {
+                    element.hover(overFn, outFn, fakeScope, options);
+
+                    expect(element.on).toHaveBeenCalledWith("mouseenter", overFn, fakeScope, options);
+                });
+
+                it("should set scope to element.dom if it is not passed in arguments", function() {
+                    element.hover(overFn, outFn, null, options);
+
+                    expect(element.on).toHaveBeenCalledWith("mouseenter", overFn, element.dom, options);
+                });
+            });
+
+            describe("mouseleave event", function() {
+                it("should add a listener on mouseleave", function() {
+                    element.hover(overFn, outFn, fakeScope, options);
+
+                    expect(element.on).toHaveBeenCalledWith("mouseleave", outFn, fakeScope, options);
+                });
+
+                it("should set scope to element.dom if it is not passed in arguments", function() {
+                    element.hover(overFn, outFn, null, options);
+
+                    expect(element.on).toHaveBeenCalledWith("mouseleave", outFn, element.dom, options);
+                });
+            });
+        });
+
+        describe("contains", function() {
+            /**
+             * TODO: Removed tests for now, need to reinstate once the refactoring is done.
+             */
+        });
+
+        describe("getAttributeNs", function() {
+            it("should call element getAttribute", function() {
+                spyOn(element, "getAttribute");
+
+                element.getAttributeNS("ns1", "align");
+
+                expect(element.getAttribute).toHaveBeenCalledWith("align", "ns1");
+            });
+        });
+
+        describe("getAttribute", function() {
+            var element2, element3;
+            beforeEach(function() {
+                element2 = Ext.getBody().createChild({tag: "div"});
+                
+
+                if (element.dom.setAttribute) {
+                    element.dom.setAttribute("qtip", "bar");
+                    element2.dom.setAttribute("ext:qtip", "foo");
+                } else {
+                    element.dom["qtip"] = "bar";
+                    element2.dom["ext:qtip"] = "foo";               
+                }
+
+                if (element.dom.setAttributeNS) {
+                    element3 = Ext.getBody().createChild({tag: "div"});
+                    element3.dom.setAttributeNS("ext", "qtip", "foobar");
+                }
+            });
+            
+            afterEach(function() {
+                if (element2) {
+                    element2.remove();
+                }
+                
+                if (element3) {
+                    element3.remove();
+                }
+            });
+            
+            describe("without namespace", function() {
+                it("should return the attribute value if it exists", function() {
+                    expect(element.getAttribute("qtip")).toEqual("bar");
+                });
+
+                it("should return null if the attribute does not exist", function() {
+                    expect(element.getAttribute("nothing")).toBeNull();
+                });
+            });
+
+            describe("with namespace", function() {
+                it("should return null on a non-namespaced attribute", function() {
+                    expect(element.getAttribute("qtip", "ext")).toBeNull();
+                });
+
+                it("should return null if the attribute belong to another namespace", function() {
+                    expect(element2.getAttribute("qtip", "nothing")).toBeNull();
+                });
+
+                it("should return the attribute value if it belongs to the namespace", function() {
+                    if (element3) {
+                        expect(element3.getAttribute("qtip", "ext")).toEqual("foobar");
+                    }
+                });
+                
+                it("should handle xml namespace", function() {
+                    expect(element2.getAttribute("qtip", "ext")).toEqual("foo");
+                });
+            });
+        });
+
+        describe("update", function() {
+            beforeEach(function() {
+                element.dom.innerHTML = "hello world";
+            });
+
+            it("should update dom element innerHTML", function() {
+                element.update("foobar");
+
+                expect(element.dom).hasHTML("foobar");
+            });
+
+            it("should return element", function() {
+                expect(element.update("foobar")).toBe(element);
+            });
+        });
+
+        describe("prototype aliases", function() {
+            it("should aliases addListener with on", function() {
+                expect(element.on).toBe(element.addListener);
+            });
+
+            it("should aliases removeListener with un", function() {
+                expect(element.un).toBe(element.removeListener);
+            });
+
+            it("should aliases removeAllListeners with clearListeners", function() {
+                expect(element.clearListeners).toBe(element.removeAllListeners);
+            });
+        });
+    });
+
+    describe("class methods", function() {
+        var element2, domEl2, id;
+
+        beforeEach(function() {
+            element = Ext.getBody().createChild({tag: "div"});
+            domEl = element.dom;
+
+            id = Ext.id();
+            domEl2 = document.createElement("div");
+            domEl2.id = id;
+            document.body.appendChild(domEl2);
+
+            spyOn(Ext.core.Element, "addToCache").andCallThrough();
+        });
+
+        afterEach(function() {
+            if (element2) {
+                element2.remove();
+            }
+            if (domEl2 && domEl2.parentNode === document.body) {
+                document.body.removeChild(domEl2);
+            }
+        });
+        
+        describe("get", function() {
+            describe("alias", function() {
+                it("should alias Ext.core.Element.get with Ext.get", function() {
+                    expect(Ext.get).toBe(Ext.core.Element.get);
+                });
+            });
+
+            describe("passing string id as first argument", function() {
+                describe("with a dom element which is not already encapsulated", function() {
+                    it("should return a new Ext.core.Element", function() {
+                        element2 = Ext.get(id);
+
+                        expect(element2 instanceof Ext.core.Element).toBe(true);
+                    });
+
+                    it("should encapsulate the dom element in the Ext.core.Element", function() {
+                        element2 = Ext.get(id);
+
+                        expect(element2.dom).toBe(domEl2);
+                    });
+
+                    it("should add element to Ext.cache", function() {
+                        element2 = Ext.get(id);
+         
+                        expect(Ext.core.Element.addToCache).toHaveBeenCalledWith(element2);
+                    });
+                });
+
+                describe("with a dom element which is already encapsulated", function() {
+                    it("should return the corresponding Ext.element", function() {
+                        expect(Ext.get(domEl)).toBe(element);
+                    });
+
+                    it("should not add element to Ext.cache if it is already in", function() {
+                        Ext.get(domEl);
+
+                        expect(Ext.core.Element.addToCache).not.toHaveBeenCalled();
+                    });
+                });
+            });
+
+            describe("passing dom element as first argument", function() {
+                describe("with a dom element which is not already encapsulated", function() {
+                    it("should return a new Ext.core.Element", function() {
+                        element2 = Ext.get(domEl2);
+
+                        expect(element2 instanceof Ext.core.Element).toBe(true);
+                    });
+
+                    it("should encapsulate the dom element in the Ext.core.Element", function() {
+                        element2 = Ext.get(domEl2);
+
+                        expect(element2.dom).toBe(domEl2);
+                    });
+
+                    it("should add element to Ext.cache", function() {
+                        element2 = Ext.get(domEl2);
+
+                        expect(Ext.core.Element.addToCache).toHaveBeenCalledWith(element2);
+                    });
+                });
+
+                describe("with a dom element which is already encapsulated", function() {
+                    it("should return the corresponding Ext.element", function() {
+                        expect(Ext.get(domEl.id)).toBe(element);
+                    });
+
+                    it("should not add element to Ext.cache if it is already in", function() {
+                        Ext.get(domEl.id);
+
+                        expect(Ext.core.Element.addToCache).not.toHaveBeenCalled();
+                    });
+                });
+            });
+
+            describe("passing an Ext.core.Element as first argument", function() {
+                it("should return Ext.core.Element", function() {
+                    expect(Ext.get(element)).toBe(element);
+                });
+            });
+
+            describe("passing a CompositeElement as first argument", function() {
+                var compositeElement;
+
+                beforeEach(function() {
+                    compositeElement = Ext.select("div");
+                });
+
+                it("should return Ext.core.Element", function() {
+                    expect(Ext.get(compositeElement)).toBe(compositeElement);
+                });
+            });
+
+            describe("passing an array as first argument", function() {
+                it("should call Ext.core.Element.select", function() {
+                    var arr = [domEl, domEl2];
+                    spyOn(Ext.core.Element, "select");
+
+                    Ext.get(arr);
+
+                    expect(Ext.core.Element.select).toHaveBeenCalledWith(arr);
+                });
+            });
+
+            describe("passing document as first argument", function() {
+                it("should return an Ext.core.Element", function() {
+                    expect(Ext.get(document) instanceof Ext.core.Element).toBe(true);
+                });
+
+                it("should return a bogus Ext.core.Element", function() {
+                    expect(Ext.get(document).id).not.toBeDefined();
+                });
+
+                it("should return an Ext.core.Element that encapsulate document", function() {
+                    expect(Ext.get(document).dom).toBe(document);
+                });
+            });
+        });
+
+        xdescribe("garbageCollector", function() {
+
+        });
+
+        describe("fly", function() {
+            var flyWeight;
+
+            beforeEach(function() {
+                spyOn(Ext, "getDom").andCallThrough();
+
+            });
+
+            describe("global flyweight", function() {
+                beforeEach(function() {
+                    flyWeight = Ext.fly(domEl2);
+                });
+
+                it("should return an Ext.core.Element.Flyweight", function() {
+                    expect(flyWeight instanceof Ext.core.Element.Flyweight).toBe(true);
+                });
+
+                it("should not cache a dom element", function() {
+                    expect(Ext.cache[domEl2.id]).toBeUndefined();
+                });
+
+                it("should call Ext.getDom", function() {
+                    expect(Ext.getDom).toHaveBeenCalledWith(domEl2);
+                });
+
+                it("should create a one time reference", function() {
+                    expect(Ext.core.Element._flyweights._global).toEqual(flyWeight);
+                });
+            });
+
+            describe("named reusable flyweight", function() {
+                beforeEach(function() {
+                    flyWeight = Ext.fly(domEl2, "myflyweight");
+                });
+
+                it("should return an Ext.core.Element.Flyweight", function() {
+                    expect(flyWeight instanceof Ext.core.Element.Flyweight).toBe(true);
+                });
+
+                it("should not cache a dom element", function() {
+                    expect(Ext.cache[domEl2.id]).toBeUndefined();
+                });
+
+                it("should call Ext.getDom", function() {
+                    expect(Ext.getDom).toHaveBeenCalledWith(domEl2);
+                });
+
+                it("should create a one time reference", function() {
+                    expect(Ext.core.Element._flyweights.myflyweight).toEqual(flyWeight);
+                });
+            });
+        });
+
+        describe("aliases", function() {
+            it("should aliases Ext.core.Element.get with Ext.get", function() {
+                expect(Ext.get).toBe(Ext.core.Element.get);
+            });
+
+            it("should aliases Ext.element.fly with Ext.fly", function() {
+                expect(Ext.fly).toBe(Ext.core.Element.fly);
+            });
+        });
+    });
+}, "/src/dom/Element.js");