jquery core: Closes #5189. Added a generic function to handle getting/setting key...
[jquery.git] / test / unit / attributes.js
index 144cf47..9b5411f 100644 (file)
@@ -1,6 +1,11 @@
+module("attributes");
+
 test("attr(String)", function() {
        expect(27);
+       
+       // This one sometimes fails randomally ?!
        equals( jQuery('#text1').attr('value'), "Test", 'Check for value attribute' );
+       
        equals( jQuery('#text1').attr('value', "Test2").attr('defaultValue'), "Test", 'Check for defaultValue attribute' );
        equals( jQuery('#text1').attr('type'), "text", 'Check for type attribute' );
        equals( jQuery('#radio1').attr('type'), "radio", 'Check for type attribute' );
@@ -31,19 +36,19 @@ test("attr(String)", function() {
 
        ok( $body.attr('foo') === undefined, 'Make sure that a non existent attribute returns undefined' );
        ok( $body.attr('nextSibling') === null, 'Make sure a null expando returns null' );
-       
+
        body.setAttribute('foo', 'baz');
        equals( $body.attr('foo'), 'baz', 'Make sure the dom attribute is retrieved when no expando is found' );
-       
+
        body.foo = 'bar';
        equals( $body.attr('foo'), 'bar', 'Make sure the expando is preferred over the dom attribute' );
-       
+
        $body.attr('foo','cool');
        equals( $body.attr('foo'), 'cool', 'Make sure that setting works well when both expando and dom attribute are available' );
-       
+
        body.foo = undefined;
        ok( $body.attr('foo') === undefined, 'Make sure the expando is preferred over the dom attribute, even if undefined' );
-       
+
        body.removeAttribute('foo'); // Cleanup
 });
 
@@ -66,16 +71,19 @@ test("attr(String, Function)", function() {
 });
 
 test("attr(Hash)", function() {
-       expect(1);
+       expect(3);
        var pass = true;
        jQuery("div").attr({foo: 'baz', zoo: 'ping'}).each(function(){
                if ( this.getAttribute('foo') != "baz" && this.getAttribute('zoo') != "ping" ) pass = false;
        });
        ok( pass, "Set Multiple Attributes" );
+       equals( jQuery('#text1').attr({'value': function() { return this.id; }})[0].value, "text1", "Set attribute to computed value #1" );
+       equals( jQuery('#text1').attr({'title': function(i) { return i; }}).attr('title'), "0", "Set attribute to computed value #2");
+
 });
 
 test("attr(String, Object)", function() {
-       expect(21);
+       expect(24);
        var div = jQuery("div").attr("foo", "bar"),
                fail = false;
        for ( var i = 0; i < div.size(); i++ ) {
@@ -103,6 +111,15 @@ test("attr(String, Object)", function() {
        jQuery("#name").attr('maxLength', '10');
        equals( document.getElementById('name').maxLength, '10', 'Set maxlength attribute' );
 
+       var table = jQuery('#table').append("<tr><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr>"),
+               td = table.find('td:first');
+       td.attr("rowspan", "2");
+       equals( td[0].rowSpan, 2, "Check rowspan is correctly set" );
+       td.attr("colspan", "2");
+       equals( td[0].colSpan, 2, "Check colspan is correctly set" );
+       table.attr("cellspacing", "2");
+       equals( table[0].cellSpacing, 2, "Check cellspacing is correctly set" );
+
        // for #1070
        jQuery("#name").attr('someAttr', '0');
        equals( jQuery("#name").attr('someAttr'), '0', 'Set attribute to a string of "0"' );
@@ -139,7 +156,7 @@ test("attr(String, Object)", function() {
        }
        ok( thrown, "Exception thrown when trying to change type property" );
        equals( "checkbox", jQuery(check).attr('type'), "Verify that you can change the type of an input element that isn't in the DOM" );
-       
+
        var check = jQuery("<input />");
        var thrown = true;
        try {
@@ -149,7 +166,7 @@ test("attr(String, Object)", function() {
        }
        ok( thrown, "Exception thrown when trying to change type property" );
        equals( "checkbox", check.attr('type'), "Verify that you can change the type of an input element that isn't in the DOM" );
-       
+
        var button = jQuery("#button");
        var thrown = false;
        try {
@@ -183,7 +200,7 @@ test("attr('tabindex')", function() {
        // elements not natively tabbable
        equals(jQuery('#listWithTabIndex').attr('tabindex'), 5, 'not natively tabbable, with tabindex set to 0');
        equals(jQuery('#divWithNoTabIndex').attr('tabindex'), undefined, 'not natively tabbable, no tabindex set');
-       
+
        // anchor with href
        equals(jQuery('#linkWithNoTabIndex').attr('tabindex'), 0, 'anchor with href, no tabindex set');
        equals(jQuery('#linkWithTabIndex').attr('tabindex'), 2, 'anchor with href, tabindex set to 2');
@@ -212,7 +229,7 @@ test("attr('tabindex', value)", function() {
        // set a negative string
        element.attr('tabindex', '-1');
        equals(element.attr('tabindex'), -1, 'set tabindex to -1 (string)');
-       
+
        // set a positive number
        element.attr('tabindex', 1);
        equals(element.attr('tabindex'), 1, 'set tabindex to 1 (number)');
@@ -224,7 +241,7 @@ test("attr('tabindex', value)", function() {
        // set a negative number
        element.attr('tabindex', -1);
        equals(element.attr('tabindex'), -1, 'set tabindex to -1 (number)');
-       
+
        element = jQuery('#linkWithTabIndex');
        equals(element.attr('tabindex'), 2, 'start with tabindex 2');
 
@@ -250,26 +267,28 @@ test("addClass(String)", function() {
 
 test("removeClass(String) - simple", function() {
        expect(5);
-       
+
        var $divs = jQuery('div');
-       
+
        $divs.addClass("test").removeClass("test");
-               
+
        ok( !$divs.is('.test'), "Remove Class" );
 
        reset();
+       $divs = jQuery('div');
 
        $divs.addClass("test").addClass("foo").addClass("bar");
        $divs.removeClass("test").removeClass("bar").removeClass("foo");
-       
+
        ok( !$divs.is('.test,.bar,.foo'), "Remove multiple classes" );
 
        reset();
+       $divs = jQuery('div');
 
        // Make sure that a null value doesn't cause problems
        $divs.eq(0).addClass("test").removeClass(null);
        ok( $divs.eq(0).is('.test'), "Null value passed to removeClass" );
-       
+
        $divs.eq(0).addClass("test").removeClass("");
        ok( $divs.eq(0).is('.test'), "Empty string passed to removeClass" );
 
@@ -279,8 +298,9 @@ test("removeClass(String) - simple", function() {
        ok( !j.hasClass("asdf"), "Check node,textnode,comment for removeClass" );
 });
 
-test("toggleClass(String)", function() {
-       expect(6);
+test("toggleClass(String|boolean|undefined[, boolean])", function() {
+       expect(17);
+
        var e = jQuery("#firstp");
        ok( !e.is(".test"), "Assert class not present" );
        e.toggleClass("test");
@@ -288,12 +308,46 @@ test("toggleClass(String)", function() {
        e.toggleClass("test");
        ok( !e.is(".test"), "Assert class not present" );
 
+       // class name with a boolean
        e.toggleClass("test", false);
        ok( !e.is(".test"), "Assert class not present" );
        e.toggleClass("test", true);
        ok( e.is(".test"), "Assert class present" );
        e.toggleClass("test", false);
        ok( !e.is(".test"), "Assert class not present" );
+
+       // multiple class names
+       e.addClass("testA testB");
+       ok( (e.is(".testA.testB")), "Assert 2 different classes present" );
+       e.toggleClass("testB testC");
+       ok( (e.is(".testA.testC") && !e.is(".testB")), "Assert 1 class added, 1 class removed, and 1 class kept" );
+       e.toggleClass("testA testC");
+       ok( (!e.is(".testA") && !e.is(".testB") && !e.is(".testC")), "Assert no class present" );
+
+       // toggleClass storage
+       e.toggleClass(true);
+       ok( e.get(0).className === "", "Assert class is empty (data was empty)" );
+       e.addClass("testD testE");
+       ok( e.is(".testD.testE"), "Assert class present" );
+       e.toggleClass();
+       ok( !e.is(".testD.testE"), "Assert class not present" );
+       ok( e.data('__className__') === 'testD testE', "Assert data was stored" );
+       e.toggleClass();
+       ok( e.is(".testD.testE"), "Assert class present (restored from data)" );
+       e.toggleClass(false);
+       ok( !e.is(".testD.testE"), "Assert class not present" );
+       e.toggleClass(true);
+       ok( e.is(".testD.testE"), "Assert class present (restored from data)" );
+       e.toggleClass();
+       e.toggleClass(false);
+       e.toggleClass();
+       ok( e.is(".testD.testE"), "Assert class present (restored from data)" );
+
+
+
+       // Cleanup
+       e.removeClass("testD");
+       e.removeData('__className__');
 });
 
 test("removeAttr(String", function() {
@@ -301,19 +355,24 @@ test("removeAttr(String", function() {
        equals( jQuery('#mark').removeAttr("class")[0].className, "", "remove class" );
 });
 
-test("jQuery.className", function() {
+test("addClass, removeClass, hasClass", function() {
        expect(6);
-       var x = jQuery("<p>Hi</p>")[0];
-       var c = jQuery.className;
-       c.add(x, "hi");
+
+       var jq = jQuery("<p>Hi</p>"), x = jq[0];
+
+       jq.addClass("hi");
        equals( x.className, "hi", "Check single added class" );
-       c.add(x, "foo bar");
+
+       jq.addClass("foo bar");
        equals( x.className, "hi foo bar", "Check more added classes" );
-       c.remove(x);
+
+       jq.removeClass();
        equals( x.className, "", "Remove all classes" );
-       c.add(x, "hi foo bar");
-       c.remove(x, "foo");
+
+       jq.addClass("hi foo bar");
+       jq.removeClass("foo");
        equals( x.className, "hi bar", "Check removal of one class" );
-       ok( c.has(x, "hi"), "Check has1" );
-       ok( c.has(x, "bar"), "Check has2" );
-});
\ No newline at end of file
+
+       ok( jq.hasClass("hi"), "Check has1" );
+       ok( jq.hasClass("bar"), "Check has2" );
+});