+function dataTests (elem) {
+ // expect(32)
+
+ function getCacheLength() {
+ var cacheLength = 0;
+ for (var i in jQuery.cache) {
+ ++cacheLength;
+ }
+
+ return cacheLength;
+ }
+
+ equals( jQuery.data(elem, "foo"), undefined, "No data exists initially" );
+ strictEqual( jQuery.hasData(elem), false, "jQuery.hasData agrees no data exists initially" );
+
+ var dataObj = jQuery.data(elem);
+ equals( typeof dataObj, "object", "Calling data with no args gives us a data object reference" );
+ strictEqual( jQuery.data(elem), dataObj, "Calling jQuery.data returns the same data object when called multiple times" );
+
+ strictEqual( jQuery.hasData(elem), false, "jQuery.hasData agrees no data exists even when an empty data obj exists" );
+
+ dataObj.foo = "bar";
+ equals( jQuery.data(elem, "foo"), "bar", "Data is readable by jQuery.data when set directly on a returned data object" );
+
+ strictEqual( jQuery.hasData(elem), true, "jQuery.hasData agrees data exists when data exists" );
+
+ jQuery.data(elem, "foo", "baz");
+ equals( jQuery.data(elem, "foo"), "baz", "Data can be changed by jQuery.data" );
+ equals( dataObj.foo, "baz", "Changes made through jQuery.data propagate to referenced data object" );
+
+ jQuery.data(elem, "foo", undefined);
+ equals( jQuery.data(elem, "foo"), "baz", "Data is not unset by passing undefined to jQuery.data" );
+
+ jQuery.data(elem, "foo", null);
+ strictEqual( jQuery.data(elem, "foo"), null, "Setting null using jQuery.data works OK" );
+
+ jQuery.data(elem, "foo", "foo1");
+
+ jQuery.data(elem, { "bar" : "baz", "boom" : "bloz" });
+ strictEqual( jQuery.data(elem, "foo"), "foo1", "Passing an object extends the data object instead of replacing it" );
+ equals( jQuery.data(elem, "boom"), "bloz", "Extending the data object works" );
+
+ jQuery._data(elem, "foo", "foo2");
+ equals( jQuery._data(elem, "foo"), "foo2", "Setting internal data works" );
+ equals( jQuery.data(elem, "foo"), "foo1", "Setting internal data does not override user data" );
+
+ var internalDataObj = jQuery.data(elem, jQuery.expando);
+ strictEqual( jQuery._data(elem), internalDataObj, "Internal data object is accessible via jQuery.expando property" );
+ notStrictEqual( dataObj, internalDataObj, "Internal data object is not the same as user data object" );
+
+ strictEqual( elem.boom, undefined, "Data is never stored directly on the object" );
+
+ jQuery.removeData(elem, "foo");
+ strictEqual( jQuery.data(elem, "foo"), undefined, "jQuery.removeData removes single properties" );
+
+ jQuery.removeData(elem);
+ strictEqual( jQuery.data(elem, jQuery.expando), internalDataObj, "jQuery.removeData does not remove internal data if it exists" );
+
+ jQuery.removeData(elem, undefined, true);
+
+ strictEqual( jQuery.data(elem, jQuery.expando), undefined, "jQuery.removeData on internal data works" );
+ strictEqual( jQuery.hasData(elem), false, "jQuery.hasData agrees all data has been removed from object" );
+
+ jQuery._data(elem, "foo", "foo2");
+ strictEqual( jQuery.hasData(elem), true, "jQuery.hasData shows data exists even if it is only internal data" );
+
+ jQuery.data(elem, "foo", "foo1");
+ equals( jQuery._data(elem, "foo"), "foo2", "Setting user data does not override internal data" );
+
+ jQuery.removeData(elem, undefined, true);
+ equals( jQuery.data(elem, "foo"), "foo1", "jQuery.removeData for internal data does not remove user data" );
+
+ if (elem.nodeType) {
+ var oldCacheLength = getCacheLength();
+ jQuery.removeData(elem, "foo");
+
+ equals( getCacheLength(), oldCacheLength - 1, "Removing the last item in the data object destroys it" );
+ }
+ else {
+ jQuery.removeData(elem, "foo");
+ var expected, actual;
+
+ if (jQuery.support.deleteExpando) {
+ expected = false;
+ actual = jQuery.expando in elem;
+ }
+ else {
+ expected = null;
+ actual = elem[ jQuery.expando ];
+ }
+
+ equals( actual, expected, "Removing the last item in the data object destroys it" );
+ }
+
+ jQuery.data(elem, "foo", "foo1");
+ jQuery._data(elem, "foo", "foo2");
+
+ equals( jQuery.data(elem, "foo"), "foo1", "(sanity check) Ensure data is set in user data object" );
+ equals( jQuery._data(elem, "foo"), "foo2", "(sanity check) Ensure data is set in internal data object" );
+
+ jQuery.removeData(elem, "foo", true);
+
+ strictEqual( jQuery.data(elem, jQuery.expando), undefined, "Removing the last item in internal data destroys the internal data object" );
+
+ jQuery._data(elem, "foo", "foo2");
+ equals( jQuery._data(elem, "foo"), "foo2", "(sanity check) Ensure data is set in internal data object" );
+
+ jQuery.removeData(elem, "foo");
+ equals( jQuery._data(elem, "foo"), "foo2", "(sanity check) jQuery.removeData for user data does not remove internal data" );
+
+ if (elem.nodeType) {
+ oldCacheLength = getCacheLength();
+ jQuery.removeData(elem, "foo", true);
+ equals( getCacheLength(), oldCacheLength - 1, "Removing the last item in the internal data object also destroys the user data object when it is empty" );
+ }
+ else {
+ jQuery.removeData(elem, "foo", true);
+
+ if (jQuery.support.deleteExpando) {
+ expected = false;
+ actual = jQuery.expando in elem;
+ }
+ else {
+ expected = null;
+ actual = elem[ jQuery.expando ];
+ }
+
+ equals( actual, expected, "Removing the last item in the internal data object also destroys the user data object when it is empty" );
+ }
+}
+