aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorXavi <xavi.rmz@gmail.com>2011-01-18 12:06:05 -0500
committerXavi <xavi.rmz@gmail.com>2011-01-18 12:06:05 -0500
commit0942b3b3f55c77664f3a72b1e2ae0b58cf108d4c (patch)
tree7159dfa9716438b77280de2c23e92991acfddea6 /test
parentb78e3fc39f96d63a60ea66e3d066815626e633d8 (diff)
parent3d0aa196c5420e7f68b32cee38f0cc740d4959c6 (diff)
downloadjquery-0942b3b3f55c77664f3a72b1e2ae0b58cf108d4c.tar.gz
jquery-0942b3b3f55c77664f3a72b1e2ae0b58cf108d4c.zip
Merge branch 'master' of git://github.com/jquery/jquery into bug_7931
Diffstat (limited to 'test')
-rw-r--r--test/data/jsonp.php4
-rw-r--r--test/data/testinit.js49
-rw-r--r--test/index.html2
-rw-r--r--test/unit/ajax.js552
-rw-r--r--test/unit/attributes.js12
-rw-r--r--test/unit/core.js152
-rw-r--r--test/unit/css.js15
-rw-r--r--test/unit/data.js242
-rw-r--r--test/unit/dimensions.js18
-rw-r--r--test/unit/effects.js35
-rw-r--r--test/unit/event.js77
-rw-r--r--test/unit/manipulation.js95
-rw-r--r--test/unit/offset.js2
-rw-r--r--test/unit/queue.js2
-rw-r--r--test/unit/selector.js72
-rw-r--r--test/unit/traversing.js2
16 files changed, 953 insertions, 378 deletions
diff --git a/test/data/jsonp.php b/test/data/jsonp.php
index 9ae1d8487..6c13d72e9 100644
--- a/test/data/jsonp.php
+++ b/test/data/jsonp.php
@@ -1,6 +1,10 @@
<?php
error_reporting(0);
$callback = $_REQUEST['callback'];
+if ( ! $callback ) {
+ $callback = explode("?",end(explode("/",$_SERVER['REQUEST_URI'])));
+ $callback = $callback[0];
+}
$json = $_REQUEST['json'];
if($json) {
echo $callback . '([ {"name": "John", "age": 21}, {"name": "Peter", "age": 25 } ])';
diff --git a/test/data/testinit.js b/test/data/testinit.js
index a66f71d25..c478390d5 100644
--- a/test/data/testinit.js
+++ b/test/data/testinit.js
@@ -45,3 +45,52 @@ function t(a,b,c) {
function url(value) {
return value + (/\?/.test(value) ? "&" : "?") + new Date().getTime() + "" + parseInt(Math.random()*100000);
}
+
+(function () {
+ // Store the old counts so that we only assert on tests that have actually leaked,
+ // instead of asserting every time a test has leaked sometime in the past
+ var oldCacheLength = 0,
+ oldFragmentsLength = 0,
+ oldTimersLength = 0,
+ oldActive = 0;
+
+ /**
+ * Ensures that tests have cleaned up properly after themselves. Should be passed as the
+ * teardown function on all modules' lifecycle object.
+ */
+ this.moduleTeardown = function () {
+ var i, fragmentsLength = 0, cacheLength = 0;
+
+ // Allow QUnit.reset to clean up any attached elements before checking for leaks
+ QUnit.reset();
+
+ for ( i in jQuery.cache ) {
+ ++cacheLength;
+ }
+
+ jQuery.fragments = {};
+
+ for ( i in jQuery.fragments ) {
+ ++fragmentsLength;
+ }
+
+ // Because QUnit doesn't have a mechanism for retrieving the number of expected assertions for a test,
+ // if we unconditionally assert any of these, the test will fail with too many assertions :|
+ if ( cacheLength !== oldCacheLength ) {
+ equals( cacheLength, oldCacheLength, "No unit tests leak memory in jQuery.cache" );
+ oldCacheLength = cacheLength;
+ }
+ if ( fragmentsLength !== oldFragmentsLength ) {
+ equals( fragmentsLength, oldFragmentsLength, "No unit tests leak memory in jQuery.fragments" );
+ oldFragmentsLength = fragmentsLength;
+ }
+ if ( jQuery.timers.length !== oldTimersLength ) {
+ equals( jQuery.timers.length, oldTimersLength, "No timers are still running" );
+ oldTimersLength = jQuery.timers.length;
+ }
+ if ( jQuery.active !== oldActive ) {
+ equals( jQuery.active, 0, "No AJAX requests are still active" );
+ oldActive = jQuery.active;
+ }
+ }
+}()); \ No newline at end of file
diff --git a/test/index.html b/test/index.html
index bbeda63a6..fc5f667d2 100644
--- a/test/index.html
+++ b/test/index.html
@@ -264,7 +264,7 @@ Z</textarea>
<div id="slidetoggleout" class='chain test out'>slideToggleOut<div>slideToggleOut</div></div>
<div id="fadetogglein" class='chain test'>fadeToggleIn<div>fadeToggleIn</div></div>
- <div id="fadetoggleout" class='chain test out'>fadeToggleOut<div>fadeToggleOut</div></div>
+ <div id="fadetoggleout" class='chain test out'>fadeToggleOut<div>fadeToggleOut</div></div>
<div id="fadeto" class='chain test'>fadeTo<div>fadeTo</div></div>
</div>
diff --git a/test/unit/ajax.js b/test/unit/ajax.js
index 773088fc9..3f672ae04 100644
--- a/test/unit/ajax.js
+++ b/test/unit/ajax.js
@@ -1,4 +1,4 @@
-module("ajax");
+module("ajax", { teardown: moduleTeardown });
// Safari 3 randomly crashes when running these tests,
// but only in the full suite - you can run just the Ajax
@@ -276,7 +276,7 @@ test(".ajax() - retry with jQuery.ajax( this )", function() {
start();
}
}
- })
+ });
});
@@ -316,6 +316,28 @@ test(".ajax() - headers" , function() {
});
+test(".ajax() - Accept header" , function() {
+
+ expect( 1 );
+
+ stop();
+
+ jQuery.ajax(url("data/headers.php?keys=accept"), {
+ headers: {
+ Accept: "very wrong accept value"
+ },
+ beforeSend: function( xhr ) {
+ xhr.setRequestHeader( "Accept", "*/*" );
+ },
+ success: function( data ) {
+ strictEqual( data , "accept: */*\n" , "Test Accept header is set to last value provided" );
+ start();
+ },
+ error: function(){ ok(false, "error"); }
+ });
+
+});
+
test(".ajax() - contentType" , function() {
expect( 2 );
@@ -1025,6 +1047,18 @@ test("load(String, Function) - check file with only a script tag", function() {
});
});
+test("load(String, Function) - dataFilter in ajaxSettings", function() {
+ expect(2);
+ stop();
+ jQuery.ajaxSetup({ dataFilter: function() { return "Hello World"; } });
+ var div = jQuery("<div/>").load(url("data/name.html"), function(responseText) {
+ strictEqual( div.html(), "Hello World" , "Test div was filled with filtered data" );
+ strictEqual( responseText, "Hello World" , "Test callback receives filtered data" );
+ jQuery.ajaxSetup({ dataFilter: 0 });
+ start();
+ });
+});
+
test("load(String, Object, Function)", function() {
expect(2);
stop();
@@ -1080,233 +1114,249 @@ test("jQuery.getScript(String, Function) - no callback", function() {
});
});
-test("jQuery.ajax() - JSONP, Local", function() {
- expect(10);
-
- var count = 0;
- function plus(){ if ( ++count == 9 ) start(); }
-
- stop();
-
- jQuery.ajax({
- url: "data/jsonp.php",
- dataType: "jsonp",
- success: function(data){
- ok( data.data, "JSON results returned (GET, no callback)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (GET, no callback)" );
- plus();
- }
- });
+jQuery.each( [ "Same Domain", "Cross Domain" ] , function( crossDomain , label ) {
- jQuery.ajax({
- url: "data/jsonp.php?callback=?",
- dataType: "jsonp",
- success: function(data){
- ok( data.data, "JSON results returned (GET, url callback)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (GET, url callback)" );
- plus();
- }
- });
+ test("jQuery.ajax() - JSONP, " + label, function() {
+ expect(17);
- jQuery.ajax({
- url: "data/jsonp.php",
- dataType: "jsonp",
- data: "callback=?",
- success: function(data){
- ok( data.data, "JSON results returned (GET, data callback)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (GET, data callback)" );
- plus();
- }
- });
+ var count = 0;
+ function plus(){ if ( ++count == 17 ) start(); }
- jQuery.ajax({
- url: "data/jsonp.php",
- dataType: "jsonp",
- data: {
- callback: "?"
- },
- success: function(data){
- ok( data.data, "JSON results returned (GET, processed data callback)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (GET, processed data callback)" );
- plus();
- }
- });
+ stop();
- jQuery.ajax({
- url: "data/jsonp.php",
- dataType: "jsonp",
- jsonp: "callback",
- success: function(data){
- ok( data.data, "JSON results returned (GET, data obj callback)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (GET, data obj callback)" );
- plus();
- }
- });
+ jQuery.ajax({
+ url: "data/jsonp.php",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, no callback)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (GET, no callback)" );
+ plus();
+ }
+ });
- jQuery.ajax({
- url: "data/jsonp.php",
- dataType: "jsonp",
- jsonpCallback: "jsonpResults",
- success: function(data){
- ok( data.data, "JSON results returned (GET, custom callback name)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (GET, custom callback name)" );
- plus();
- }
- });
+ jQuery.ajax({
+ url: "data/jsonp.php?callback=?",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, url callback)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (GET, url callback)" );
+ plus();
+ }
+ });
- jQuery.ajax({
- type: "POST",
- url: "data/jsonp.php",
- dataType: "jsonp",
- success: function(data){
- ok( data.data, "JSON results returned (POST, no callback)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (GET, data obj callback)" );
- plus();
- }
- });
+ jQuery.ajax({
+ url: "data/jsonp.php",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ data: "callback=?",
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, data callback)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (GET, data callback)" );
+ plus();
+ }
+ });
- jQuery.ajax({
- type: "POST",
- url: "data/jsonp.php",
- data: "callback=?",
- dataType: "jsonp",
- success: function(data){
- ok( data.data, "JSON results returned (POST, data callback)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (POST, data callback)" );
- plus();
- }
- });
+ jQuery.ajax({
+ url: "data/jsonp.php?callback=??",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, url context-free callback)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (GET, url context-free callback)" );
+ plus();
+ }
+ });
- jQuery.ajax({
- type: "POST",
- url: "data/jsonp.php",
- jsonp: "callback",
- dataType: "jsonp",
- success: function(data){
- ok( data.data, "JSON results returned (POST, data obj callback)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (POST, data obj callback)" );
- plus();
- }
- });
+ jQuery.ajax({
+ url: "data/jsonp.php",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ data: "callback=??",
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, data context-free callback)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (GET, data context-free callback)" );
+ plus();
+ }
+ });
- //#7578
- jQuery.ajax({
- url: "data/jsonp.php",
- dataType: "jsonp",
- beforeSend: function(){
- strictEqual( this.cache, false, "cache must be false on JSON request" );
- plus();
- return false;
- }
- });
-});
+ jQuery.ajax({
+ url: "data/jsonp.php/??",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, REST-like)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (GET, REST-like)" );
+ plus();
+ }
+ });
-test("jQuery.ajax() - JSONP - Custom JSONP Callback", function() {
- expect(1);
- stop();
+ jQuery.ajax({
+ url: "data/jsonp.php/???json=1",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ success: function(data){
+ strictEqual( jQuery.type(data), "array", "JSON results returned (GET, REST-like with param)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (GET, REST-like with param)" );
+ plus();
+ }
+ });
- window.jsonpResults = function(data) {
- ok( data.data, "JSON results returned (GET, custom callback function)" );
- window.jsonpResults = undefined;
- start();
- };
+ jQuery.ajax({
+ url: "data/jsonp.php",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ data: {
+ callback: "?"
+ },
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, processed data callback)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (GET, processed data callback)" );
+ plus();
+ }
+ });
- jQuery.ajax({
- url: "data/jsonp.php",
- dataType: "jsonp",
- jsonpCallback: "jsonpResults"
- });
-});
+ jQuery.ajax({
+ url: "data/jsonp.php",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ jsonp: "callback",
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, data obj callback)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (GET, data obj callback)" );
+ plus();
+ }
+ });
-test("jQuery.ajax() - JSONP, Remote", function() {
- expect(4);
+ window.jsonpResults = function(data) {
+ ok( data.data, "JSON results returned (GET, custom callback function)" );
+ window.jsonpResults = undefined;
+ plus();
+ };
- var count = 0;
- function plus(){ if ( ++count == 4 ) start(); }
+ jQuery.ajax({
+ url: "data/jsonp.php",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ jsonpCallback: "jsonpResults",
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, custom callback name)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (GET, custom callback name)" );
+ plus();
+ }
+ });
- var base = window.location.href.replace(/[^\/]*$/, "");
+ jQuery.ajax({
+ type: "POST",
+ url: "data/jsonp.php",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ success: function(data){
+ ok( data.data, "JSON results returned (POST, no callback)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (GET, data obj callback)" );
+ plus();
+ }
+ });
- stop();
+ jQuery.ajax({
+ type: "POST",
+ url: "data/jsonp.php",
+ data: "callback=?",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ success: function(data){
+ ok( data.data, "JSON results returned (POST, data callback)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (POST, data callback)" );
+ plus();
+ }
+ });
- jQuery.ajax({
- url: base + "data/jsonp.php",
- dataType: "jsonp",
- success: function(data){
- ok( data.data, "JSON results returned (GET, no callback)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (GET, no callback)" );
- plus();
- }
- });
+ jQuery.ajax({
+ type: "POST",
+ url: "data/jsonp.php",
+ jsonp: "callback",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ success: function(data){
+ ok( data.data, "JSON results returned (POST, data obj callback)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (POST, data obj callback)" );
+ plus();
+ }
+ });
- jQuery.ajax({
- url: base + "data/jsonp.php?callback=?",
- dataType: "jsonp",
- success: function(data){
- ok( data.data, "JSON results returned (GET, url callback)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (GET, url callback)" );
- plus();
- }
- });
+ //#7578
+ jQuery.ajax({
+ url: "data/jsonp.php",
+ dataType: "jsonp",
+ crossDomain: crossDomain,
+ beforeSend: function(){
+ strictEqual( this.cache, false, "cache must be false on JSON request" );
+ plus();
+ return false;
+ }
+ });
- jQuery.ajax({
- url: base + "data/jsonp.php",
- dataType: "jsonp",
- data: "callback=?",
- success: function(data){
- ok( data.data, "JSON results returned (GET, data callback)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (GET, data callback)" );
- plus();
- }
- });
+ jQuery.ajax({
+ url: "data/jsonp.php?callback=XXX",
+ dataType: "jsonp",
+ jsonp: false,
+ jsonpCallback: "XXX",
+ crossDomain: crossDomain,
+ beforeSend: function() {
+ ok( /^data\/jsonp.php\?callback=XXX&_=\d+$/.test( this.url ) ,
+ "The URL wasn't messed with (GET, custom callback name with no url manipulation)" );
+ plus();
+ },
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, custom callback name with no url manipulation)" );
+ plus();
+ },
+ error: function(data){
+ ok( false, "Ajax error JSON (GET, custom callback name with no url manipulation)" );
+ plus();
+ }
+ });
- jQuery.ajax({
- url: base + "data/jsonp.php",
- dataType: "jsonp",
- jsonp: "callback",
- success: function(data){
- ok( data.data, "JSON results returned (GET, data obj callback)" );
- plus();
- },
- error: function(data){
- ok( false, "Ajax error JSON (GET, data obj callback)" );
- plus();
- }
});
});
@@ -1778,25 +1828,19 @@ test("jQuery ajax - failing cross-domain", function() {
var i = 2;
- if ( jQuery.ajax({
+ jQuery.ajax({
url: 'http://somewebsitethatdoesnotexist-67864863574657654.com',
success: function(){ ok( false , "success" ); },
error: function(xhr,_,e){ ok( true , "file not found: " + xhr.status + " => " + e ); },
complete: function() { if ( ! --i ) start(); }
- }) === false ) {
- ok( true , "no transport" );
- if ( ! --i ) start();
- }
+ });
- if ( jQuery.ajax({
+ jQuery.ajax({
url: 'http://www.google.com',
success: function(){ ok( false , "success" ); },
error: function(xhr,_,e){ ok( true , "access denied: " + xhr.status + " => " + e ); },
complete: function() { if ( ! --i ) start(); }
- }) === false ) {
- ok( true , "no transport" );
- if ( ! --i ) start();
- }
+ });
});
@@ -1828,6 +1872,76 @@ test( "jQuery.ajax - Location object as url (#7531)", 1, function () {
ok( success, "document.location did not generate exception" );
});
+test( "jQuery.ajax - statusCode" , function() {
+
+ var count = 10;
+
+ expect( 16 );
+ stop();
+
+ function countComplete() {
+ if ( ! --count ) {
+ start();
+ }
+ }
+
+ function createStatusCodes( name , isSuccess ) {
+ name = "Test " + name + " " + ( isSuccess ? "success" : "error" );
+ return {
+ 200: function() {
+ ok( isSuccess , name );
+ },
+ 404: function() {
+ ok( ! isSuccess , name );
+ }
+ };
+ }
+
+ jQuery.each( {
+ "data/name.html": true,
+ "data/someFileThatDoesNotExist.html": false
+ } , function( uri , isSuccess ) {
+
+ jQuery.ajax( url( uri ) , {
+ statusCode: createStatusCodes( "in options" , isSuccess ),
+ complete: countComplete
+ });
+
+ jQuery.ajax( url( uri ) , {
+ complete: countComplete
+ }).statusCode( createStatusCodes( "immediately with method" , isSuccess ) );
+
+ jQuery.ajax( url( uri ) , {
+ complete: function(jXHR) {
+ jXHR.statusCode( createStatusCodes( "on complete" , isSuccess ) );
+ countComplete();
+ }
+ });
+
+ jQuery.ajax( url( uri ) , {
+ complete: function(jXHR) {
+ setTimeout( function() {
+ jXHR.statusCode( createStatusCodes( "very late binding" , isSuccess ) );
+ countComplete();
+ } , 100 );
+ }
+ });
+
+ jQuery.ajax( url( uri ) , {
+ statusCode: createStatusCodes( "all (options)" , isSuccess ),
+ complete: function(jXHR) {
+ jXHR.statusCode( createStatusCodes( "all (on complete)" , isSuccess ) );
+ setTimeout( function() {
+ jXHR.statusCode( createStatusCodes( "all (very late binding)" , isSuccess ) );
+ countComplete();
+ } , 100 );
+ }
+ }).statusCode( createStatusCodes( "all (immediately with method)" , isSuccess ) );
+
+ });
+
+});
+
}
//} \ No newline at end of file
diff --git a/test/unit/attributes.js b/test/unit/attributes.js
index a1ab58179..c58111de1 100644
--- a/test/unit/attributes.js
+++ b/test/unit/attributes.js
@@ -1,4 +1,4 @@
-module("attributes");
+module("attributes", { teardown: moduleTeardown });
var bareObj = function(value) { return value; };
var functionReturningObj = function(value) { return (function() { return value; }); };
@@ -703,12 +703,12 @@ var testToggleClass = function(valueObj) {
// toggleClass storage
e.toggleClass(true);
- ok( e.get(0).className === "", "Assert class is empty (data was empty)" );
+ ok( e[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" );
+ ok( jQuery._data(e[0], '__className__') === 'testD testE', "Assert data was stored" );
e.toggleClass();
ok( e.is(".testD.testE"), "Assert class present (restored from data)" );
e.toggleClass(false);
@@ -720,11 +720,9 @@ var testToggleClass = function(valueObj) {
e.toggleClass();
ok( e.is(".testD.testE"), "Assert class present (restored from data)" );
-
-
// Cleanup
e.removeClass("testD");
- e.removeData('__className__');
+ jQuery.removeData(e[0], '__className__', true);
};
test("toggleClass(String|boolean|undefined[, boolean])", function() {
@@ -785,7 +783,7 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() {
// Cleanup
e.removeClass("test");
- e.removeData('__className__');
+ jQuery.removeData(e[0], '__className__', true);
});
test("addClass, removeClass, hasClass", function() {
diff --git a/test/unit/core.js b/test/unit/core.js
index 8fd060578..8e57edf95 100644
--- a/test/unit/core.js
+++ b/test/unit/core.js
@@ -1,4 +1,4 @@
-module("core");
+module("core", { teardown: moduleTeardown });
test("Basic requirements", function() {
expect(7);
@@ -12,7 +12,7 @@ test("Basic requirements", function() {
});
test("jQuery()", function() {
- expect(23);
+ expect(24);
// Basic constructor's behavior
@@ -21,7 +21,7 @@ test("jQuery()", function() {
equals( jQuery(null).length, 0, "jQuery(null) === jQuery([])" );
equals( jQuery("").length, 0, "jQuery('') === jQuery([])" );
- var obj = jQuery("div")
+ var obj = jQuery("div");
equals( jQuery(obj).selector, "div", "jQuery(jQueryObj) == jQueryObj" );
// can actually yield more than one, when iframes are included, the window is an array as well
@@ -84,6 +84,17 @@ test("jQuery()", function() {
exec = true;
elem.click();
+
+ // manually clean up detached elements
+ elem.remove();
+
+ for ( var i = 0; i < 3; ++i ) {
+ elem = jQuery("<input type='text' value='TEST' />");
+ }
+ equals( elem[0].defaultValue, "TEST", "Ensure cached nodes are cloned properly (Bug #6655)" );
+
+ // manually clean up detached elements
+ elem.remove();
});
test("selector state", function() {
@@ -998,7 +1009,7 @@ test("jQuery._Deferred()", function() {
test("jQuery.Deferred()", function() {
- expect( 4 );
+ expect( 10 );
jQuery.Deferred( function( defer ) {
strictEqual( this , defer , "Defer passed as this & first argument" );
@@ -1018,11 +1029,35 @@ test("jQuery.Deferred()", function() {
}, function() {
ok( true , "Error on reject" );
});
+
+ ( new jQuery.Deferred( function( defer ) {
+ strictEqual( this , defer , "Defer passed as this & first argument (new)" );
+ this.resolve( "done" );
+ }) ).then( function( value ) {
+ strictEqual( value , "done" , "Passed function executed (new)" );
+ });
+
+ ( new jQuery.Deferred() ).resolve().then( function() {
+ ok( true , "Success on resolve (new)" );
+ }, function() {
+ ok( false , "Error on resolve (new)" );
+ });
+
+ ( new jQuery.Deferred() ).reject().then( function() {
+ ok( false , "Success on reject (new)" );
+ }, function() {
+ ok( true , "Error on reject (new)" );
+ });
+
+ var tmp = jQuery.Deferred();
+
+ strictEqual( tmp.promise() , tmp.promise() , "Test deferred always return same promise" );
+ strictEqual( tmp.promise() , tmp.promise().promise() , "Test deferred's promise always return same promise as deferred" );
});
test("jQuery.when()", function() {
- expect( 21 );
+ expect( 23 );
// Some other objects
jQuery.each( {
@@ -1045,6 +1080,10 @@ test("jQuery.when()", function() {
} );
+ ok( jQuery.isFunction( jQuery.when().then( function( resolveValue ) {
+ strictEqual( resolveValue , undefined , "Test the promise was resolved with no parameter" );
+ } ).promise ) , "Test calling when with no parameter triggers the creation of a new Promise" );
+
var cache, i;
for( i = 1 ; i < 4 ; i++ ) {
@@ -1058,3 +1097,106 @@ test("jQuery.when()", function() {
});
}
});
+
+test("jQuery.when() - joined", function() {
+
+ expect(8);
+
+ jQuery.when( 1, 2, 3 ).done( function( a, b, c ) {
+ strictEqual( a , 1 , "Test first param is first resolved value - non-observables" );
+ strictEqual( b , 2 , "Test second param is second resolved value - non-observables" );
+ strictEqual( c , 3 , "Test third param is third resolved value - non-observables" );
+ }).fail( function() {
+ ok( false , "Test the created deferred was resolved - non-observables");
+ });
+
+ var successDeferred = jQuery.Deferred().resolve( 1 , 2 , 3 ),
+ errorDeferred = jQuery.Deferred().reject( "error" , "errorParam" );
+
+ jQuery.when( 1 , successDeferred , 3 ).done( function( a, b, c ) {
+ strictEqual( a , 1 , "Test first param is first resolved value - resolved observable" );
+ same( b , [ 1 , 2 , 3 ] , "Test second param is second resolved value - resolved observable" );
+ strictEqual( c , 3 , "Test third param is third resolved value - resolved observable" );
+ }).fail( function() {
+ ok( false , "Test the created deferred was resolved - resolved observable");
+ });
+
+ jQuery.when( 1 , errorDeferred , 3 ).done( function() {
+ ok( false , "Test the created deferred was rejected - rejected observable");
+ }).fail( function( error , errorParam ) {
+ strictEqual( error , "error" , "Test first param is first rejected value - rejected observable" );
+ strictEqual( errorParam , "errorParam" , "Test second param is second rejected value - rejected observable" );
+ });
+});
+
+test("jQuery.subclass", function(){
+ expect(378);
+
+ var Subclass = jQuery.subclass(),
+ SubclassSubclass = Subclass.subclass(),
+ jQueryDocument = jQuery(document),
+ selectors, contexts, methods, method, arg, description;
+
+ jQueryDocument.toString = function(){ return 'jQueryDocument'; };
+
+ Subclass.fn.subclassMethod = function(){};
+ SubclassSubclass.fn.subclassSubclassMethod = function(){};
+
+ selectors = [
+ 'body',
+ 'html, body',
+ '<div></div>'
+ ];
+
+ methods = [ // all methods that return a new jQuery instance
+ ['eq', 1],
+ ['add', document],
+ ['end'],
+ ['has'],
+ ['closest', 'div'],
+ ['filter', document],
+ ['find', 'div']
+ ];
+
+ contexts = [undefined, document, jQueryDocument];
+
+ jQuery.each(selectors, function(i, selector){
+
+ jQuery.each(methods, function(){
+ method = this[0];
+ arg = this[1];
+
+ jQuery.each(contexts, function(i, context){
+
+ description = '("'+selector+'", '+context+').'+method+'('+(arg||'')+')';
+
+ same(
+ jQuery(selector, context)[method](arg).subclassMethod, undefined,
+ 'jQuery'+description+' doesnt have Subclass methods'
+ );
+ same(
+ jQuery(selector, context)[method](arg).subclassSubclassMethod, undefined,
+ 'jQuery'+description+' doesnt have SubclassSubclass methods'
+ );
+ same(
+ Subclass(selector, context)[method](arg).subclassMethod, Subclass.fn.subclassMethod,
+ 'Subclass'+description+' has Subclass methods'
+ );
+ same(
+ Subclass(selector, context)[method](arg).subclassSubclassMethod, undefined,
+ 'Subclass'+description+' doesnt have SubclassSubclass methods'
+ );
+ same(
+ SubclassSubclass(selector, context)[method](arg).subclassMethod, Subclass.fn.subclassMethod,
+ 'SubclassSubclass'+description+' has Subclass methods'
+ );
+ same(
+ SubclassSubclass(selector, context)[method](arg).subclassSubclassMethod, SubclassSubclass.fn.subclassSubclassMethod,
+ 'SubclassSubclass'+description+' has SubclassSubclass methods'
+ );
+
+ });
+ });
+ });
+
+});
diff --git a/test/unit/css.js b/test/unit/css.js
index fbbf937ca..555f13575 100644
--- a/test/unit/css.js
+++ b/test/unit/css.js
@@ -1,4 +1,4 @@
-module("css");
+module("css", { teardown: moduleTeardown });
test("css(String|Hash)", function() {
expect(41);
@@ -320,3 +320,16 @@ test(":visible selector works properly on children with a hidden parent (bug #45
jQuery('#table').css('display', 'none').html('<tr><td>cell</td><td>cell</td></tr>');
equals(jQuery('#table td:visible').length, 0, "hidden cell children not perceived as visible");
});
+
+test("internal ref to elem.runtimeStyle (bug #7608)", function () {
+ expect(1);
+ var result = true;
+
+ try {
+ jQuery("#foo").css( { width: "0%" } ).css("width");
+ } catch (e) {
+ result = false;
+ }
+
+ ok( result, "elem.runtimeStyle does not throw exception" );
+});
diff --git a/test/unit/data.js b/test/unit/data.js
index 310cd6bc4..889fc2da3 100644
--- a/test/unit/data.js
+++ b/test/unit/data.js
@@ -1,96 +1,177 @@
-module("data");
+module("data", { teardown: moduleTeardown });
test("expando", function(){
- expect(6);
+ expect(1);
equals("expando" in jQuery, true, "jQuery is exposing the expando");
+});
- var obj = {};
- equals( jQuery.data(obj), obj, "jQuery.data(obj) returns the object");
- equals( jQuery.expando in obj, false, "jQuery.data(obj) did not add an expando to the object" );
+function dataTests (elem) {
+ // expect(32)
- obj = {};
- jQuery.data(obj, 'test');
- equals( jQuery.expando in obj, false, "jQuery.data(obj,key) did not add an expando to the object" );
+ function getCacheLength() {
+ var cacheLength = 0;
+ for (var i in jQuery.cache) {
+ ++cacheLength;
+ }
- obj = {};
- jQuery.data(obj, "foo", "bar");
- equals( jQuery.expando in obj, false, "jQuery.data(obj,key,value) did not add an expando to the object" );
- equals( obj.foo, "bar", "jQuery.data(obj,key,value) sets fields directly on the object." );
-});
+ return cacheLength;
+ }
-test("jQuery.acceptData", function() {
- expect(7);
+ equals( jQuery.data(elem, "foo"), undefined, "No data exists initially" );
+ strictEqual( jQuery.hasData(elem), false, "jQuery.hasData agrees no data exists initially" );
- ok( jQuery.acceptData( document ), "document" );
- ok( jQuery.acceptData( document.documentElement ), "documentElement" );
- ok( jQuery.acceptData( {} ), "object" );
- ok( !jQuery.acceptData( document.createElement("embed") ), "embed" );
- ok( !jQuery.acceptData( document.createElement("applet") ), "applet" );
+ 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" );
- var flash = document.createElement("object");
- flash.setAttribute("classid", "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000");
- ok( jQuery.acceptData( flash ), "flash" );
+ strictEqual( jQuery.hasData(elem), false, "jQuery.hasData agrees no data exists even when an empty data obj exists" );
- var applet = document.createElement("object");
- applet.setAttribute("classid", "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93");
- ok( !jQuery.acceptData( applet ), "applet" );
-});
+ dataObj.foo = "bar";
+ equals( jQuery.data(elem, "foo"), "bar", "Data is readable by jQuery.data when set directly on a returned data object" );
-test("jQuery.data", function() {
- expect(15);
- var div = document.createElement("div");
+ strictEqual( jQuery.hasData(elem), true, "jQuery.hasData agrees data exists when data exists" );
- ok( jQuery.data(div, "test") === undefined, "Check for no 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(div, "test", "success");
- equals( jQuery.data(div, "test"), "success", "Check for added data" );
+ jQuery.data(elem, "foo", undefined);
+ equals( jQuery.data(elem, "foo"), "baz", "Data is not unset by passing undefined to jQuery.data" );
- ok( jQuery.data(div, "notexist") === undefined, "Check for no data exists" );
+ jQuery.data(elem, "foo", null);
+ strictEqual( jQuery.data(elem, "foo"), null, "Setting null using jQuery.data works OK" );
- var data = jQuery.data(div);
- same( data, { "test": "success" }, "Return complete data set" );
+ jQuery.data(elem, "foo", "foo1");
- jQuery.data(div, "test", "overwritten");
- equals( jQuery.data(div, "test"), "overwritten", "Check for overwritten data" );
+ 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(div, "test", undefined);
- equals( jQuery.data(div, "test"), "overwritten", "Check that data wasn't removed");
+ 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" );
- jQuery.data(div, "test", null);
- ok( jQuery.data(div, "test") === null, "Check for null 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" );
- jQuery.data(div, "test3", "orig");
- jQuery.data(div, { "test": "in", "test2": "in2" });
- equals( jQuery.data(div, "test"), "in", "Verify setting an object in data" );
- equals( jQuery.data(div, "test2"), "in2", "Verify setting an object in data" );
- equals( jQuery.data(div, "test3"), "orig", "Verify original not overwritten" );
+ strictEqual( elem.boom, undefined, "Data is never stored directly on the object" );
- var obj = {};
- jQuery.data( obj, "prop", true );
+ jQuery.removeData(elem, "foo");
+ strictEqual( jQuery.data(elem, "foo"), undefined, "jQuery.removeData removes single properties" );
- ok( obj.prop, "Data is being stored on the object" );
- equals( jQuery.data( obj, "prop" ), true, "Make sure the right value is retrieved" );
+ jQuery.removeData(elem);
+ strictEqual( jQuery.data(elem, jQuery.expando), internalDataObj, "jQuery.removeData does not remove internal data if it exists" );
- jQuery.data( window, "BAD", true );
- ok( !window[ jQuery.expando ], "Make sure there is no expando on the window object." );
- ok( !window.BAD, "And make sure that the property wasn't set directly on the window." );
- ok( jQuery.data( window, "BAD" ), "Make sure that the value was set." );
-});
+ jQuery.removeData(elem, undefined, true);
-test("jQuery.hasData", function() {
- expect(6);
+ 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;
- function testData(obj) {
- equals( jQuery.hasData(obj), false, "No data exists" );
- jQuery.data( obj, "foo", "bar" );
- equals( jQuery.hasData(obj), true, "Data exists" );
- jQuery.removeData( obj, "foo" );
- equals( jQuery.hasData(obj), false, "Data was removed" );
+ 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" );
}
- testData(document.createElement('div'));
- testData({});
+ 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" );
+ }
+}
+
+test("jQuery.data", function() {
+ expect(128);
+
+ var div = document.createElement("div");
+
+ dataTests(div);
+ dataTests({});
+
+ // remove bound handlers from window object to stop potential false positives caused by fix for #5280 in
+ // transports/xhr.js
+ jQuery(window).unbind("unload");
+
+ dataTests(window);
+ dataTests(document);
+
+ // clean up unattached element
+ jQuery(div).remove();
+});
+
+test("jQuery.acceptData", function() {
+ expect(7);
+
+ ok( jQuery.acceptData( document ), "document" );
+ ok( jQuery.acceptData( document.documentElement ), "documentElement" );
+ ok( jQuery.acceptData( {} ), "object" );
+ ok( !jQuery.acceptData( document.createElement("embed") ), "embed" );
+ ok( !jQuery.acceptData( document.createElement("applet") ), "applet" );
+
+ var flash = document.createElement("object");
+ flash.setAttribute("classid", "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000");
+ ok( jQuery.acceptData( flash ), "flash" );
+
+ var applet = document.createElement("object");
+ applet.setAttribute("classid", "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93");
+ ok( !jQuery.acceptData( applet ), "applet" );
});
test(".data()", function() {
@@ -98,7 +179,6 @@ test(".data()", function() {
var div = jQuery("#foo");
strictEqual( div.data("foo"), undefined, "Make sure that missing result is undefined" );
-
div.data("test", "success");
same( div.data(), {test: "success"}, "data() get the entire data object" );
strictEqual( div.data("foo"), undefined, "Make sure that missing result is still undefined" );
@@ -107,7 +187,7 @@ test(".data()", function() {
equals( nodiv.data(), null, "data() on empty set returns null" );
var obj = { foo: "bar" };
- equals( jQuery(obj).data(), obj, "Retrieve data object from a wrapped JS object (#7524)" );
+ deepEqual( jQuery(obj).data(), {}, "Retrieve data object from a wrapped JS object (#7524)" );
})
test(".data(String) and .data(String, Object)", function() {
@@ -194,11 +274,14 @@ test(".data(String) and .data(String, Object)", function() {
equals( $elem.data('null',null).data('null'), null, "null's are preserved");
equals( $elem.data('emptyString','').data('emptyString'), '', "Empty strings are preserved");
equals( $elem.data('false',false).data('false'), false, "false's are preserved");
- equals( $elem.data('exists'), true, "Existing data is returned" );
+ equals( $elem.data('exists'), undefined, "Existing data is not returned" );
// Clean up
$elem.removeData();
- ok( jQuery.isEmptyObject( $elem[0] ), "removeData clears the object" );
+ deepEqual( $elem[0], {exists:true}, "removeData does not clear the object" );
+
+ // manually clean up detached elements
+ parent.remove();
});
test("data-* attributes", function() {
@@ -218,6 +301,8 @@ test("data-* attributes", function() {
div.data("attr", "internal").attr("data-attr", "external");
equals( div.data("attr"), "internal", "Check for .data('attr') precedence (internal > external data-* attribute)" );
+ div.remove();
+
child.appendTo('#main');
equals( child.data("myobj"), "old data", "Value accessed from data-* attribute");
@@ -229,6 +314,8 @@ test("data-* attributes", function() {
var obj = child.data(), obj2 = dummy.data(), check = [ "myobj", "ignored", "other" ], num = 0, num2 = 0;
+ dummy.remove();
+
for ( var i = 0, l = check.length; i < l; i++ ) {
ok( obj[ check[i] ], "Make sure data- property exists when calling data-." );
ok( obj2[ check[i] ], "Make sure data- property exists when calling data-." );
@@ -323,13 +410,17 @@ test(".data(Object)", function() {
var obj = {test:"unset"},
jqobj = jQuery(obj);
+ jqobj.data("test", "unset");
jqobj.data({ "test": "in", "test2": "in2" });
- equals( obj.test, "in", "Verify setting an object on an object extends the object" );
- equals( obj.test2, "in2", "Verify setting an object on an object extends the object" );
+ equals( jQuery.data(obj).test, "in", "Verify setting an object on an object extends the data object" );
+ equals( obj.test2, undefined, "Verify setting an object on an object does not extend the object" );
+
+ // manually clean up detached elements
+ div.remove();
});
test("jQuery.removeData", function() {
- expect(7);
+ expect(6);
var div = jQuery("#foo")[0];
jQuery.data(div, "test", "testing");
jQuery.removeData(div, "test");
@@ -342,10 +433,9 @@ test("jQuery.removeData", function() {
var obj = {};
jQuery.data(obj, "test", "testing");
- equals( obj.test, "testing", "verify data on plain object");
+ equals( jQuery(obj).data("test"), "testing", "verify data on plain object");
jQuery.removeData(obj, "test");
equals( jQuery.data(obj, "test"), undefined, "Check removal of data on plain object" );
- equals( obj.test, undefined, "Check removal of data directly from plain object" );
jQuery.data( window, "BAD", true );
jQuery.removeData( window, "BAD" );
@@ -371,4 +461,4 @@ test(".removeData()", function() {
div.removeData("test.foo");
equals( div.data("test.foo"), undefined, "Make sure data is intact" );
-});
+}); \ No newline at end of file
diff --git a/test/unit/dimensions.js b/test/unit/dimensions.js
index b38e73bba..fa59a9f77 100644
--- a/test/unit/dimensions.js
+++ b/test/unit/dimensions.js
@@ -1,4 +1,4 @@
-module("dimensions");
+module("dimensions", { teardown: moduleTeardown });
function pass( val ) {
return val;
@@ -33,6 +33,8 @@ function testWidth( val ) {
var blah = jQuery("blah");
equals( blah.width( val(10) ), blah, "Make sure that setting a width on an empty set returns the set." );
equals( blah.width(), null, "Make sure 'null' is returned on an empty set");
+
+ jQuery.removeData($div[0], 'olddisplay', true);
}
test("width()", function() {
@@ -80,6 +82,8 @@ function testHeight( val ) {
var blah = jQuery("blah");
equals( blah.height( val(10) ), blah, "Make sure that setting a height on an empty set returns the set." );
equals( blah.height(), null, "Make sure 'null' is returned on an empty set");
+
+ jQuery.removeData($div[0], 'olddisplay', true);
}
test("height()", function() {
@@ -126,6 +130,9 @@ test("innerWidth()", function() {
// Temporarily require 0 for backwards compat - should be auto
equals( div.innerWidth(), 0, "Make sure that disconnected nodes are handled." );
+
+ div.remove();
+ jQuery.removeData($div[0], 'olddisplay', true);
});
test("innerHeight()", function() {
@@ -152,6 +159,9 @@ test("innerHeight()", function() {
// Temporarily require 0 for backwards compat - should be auto
equals( div.innerHeight(), 0, "Make sure that disconnected nodes are handled." );
+
+ div.remove();
+ jQuery.removeData($div[0], 'olddisplay', true);
});
test("outerWidth()", function() {
@@ -179,6 +189,9 @@ test("outerWidth()", function() {
// Temporarily require 0 for backwards compat - should be auto
equals( div.outerWidth(), 0, "Make sure that disconnected nodes are handled." );
+
+ div.remove();
+ jQuery.removeData($div[0], 'olddisplay', true);
});
test("outerHeight()", function() {
@@ -205,4 +218,7 @@ test("outerHeight()", function() {
// Temporarily require 0 for backwards compat - should be auto
equals( div.outerHeight(), 0, "Make sure that disconnected nodes are handled." );
+
+ div.remove();
+ jQuery.removeData($div[0], 'olddisplay', true);
});
diff --git a/test/unit/effects.js b/test/unit/effects.js
index b7b60abbe..b1dd28840 100644
--- a/test/unit/effects.js
+++ b/test/unit/effects.js
@@ -1,4 +1,4 @@
-module("effects");
+module("effects", { teardown: moduleTeardown });
test("sanity check", function() {
expect(1);
@@ -14,7 +14,7 @@ test("show()", function() {
equals( hiddendiv.css("display"), "block", "Make sure a pre-hidden div is visible." );
- var div = jQuery("<div>").hide().appendTo("body").show();
+ var div = jQuery("<div>").hide().appendTo("#main").show();
equal( div.css("display"), "block", "Make sure pre-hidden divs show" );
@@ -403,13 +403,16 @@ test("animate duration 0", function() {
$elem.hide(0, function(){
ok(true, "Hide callback with no duration");
});
+
+ // manually clean up detached elements
+ $elem.remove();
});
test("animate hyphenated properties", function(){
expect(1);
stop();
- jQuery("#nothiddendiv")
+ jQuery("#foo")
.css("font-size", 10)
.animate({"font-size": 20}, 200, function(){
equals( this.style.fontSize, "20px", "The font-size property was animated." );
@@ -433,7 +436,7 @@ test("stop()", function() {
expect(3);
stop();
- var $foo = jQuery("#nothiddendiv");
+ var $foo = jQuery("#foo");
var w = 0;
$foo.hide().width(200).width();
@@ -446,6 +449,8 @@ test("stop()", function() {
nw = $foo.width();
notEqual( nw, w, "Stop didn't reset the animation " + nw + "px " + w + "px");
setTimeout(function(){
+ $foo.removeData();
+ $foo.removeData(undefined, true);
equals( nw, $foo.width(), "The animation didn't continue" );
start();
}, 100);
@@ -456,7 +461,7 @@ test("stop() - several in queue", function() {
expect(3);
stop();
- var $foo = jQuery("#nothiddendivchild");
+ var $foo = jQuery("#foo");
var w = 0;
$foo.hide().width(200).width();
@@ -481,7 +486,7 @@ test("stop(clearQueue)", function() {
expect(4);
stop();
- var $foo = jQuery("#nothiddendiv");
+ var $foo = jQuery("#foo");
var w = 0;
$foo.hide().width(200).width();
@@ -508,7 +513,7 @@ test("stop(clearQueue, gotoEnd)", function() {
expect(1);
stop();
- var $foo = jQuery("#nothiddendivchild");
+ var $foo = jQuery("#foo");
var w = 0;
$foo.hide().width(200).width();
@@ -536,7 +541,7 @@ test("stop(clearQueue, gotoEnd)", function() {
test("toggle()", function() {
expect(6);
- var x = jQuery("#nothiddendiv");
+ var x = jQuery("#foo");
ok( x.is(":visible"), "is visible" );
x.toggle();
ok( x.is(":hidden"), "is hidden" );
@@ -737,6 +742,9 @@ jQuery.each( {
}
}
+ // manually remove generated element
+ jQuery(this).remove();
+
start();
});
});
@@ -763,6 +771,10 @@ jQuery.checkState = function(){
var cur = self.style[ c ] || jQuery.css(self, c);
equals( cur, v, "Make sure that " + c + " is reset (Old: " + v + " Cur: " + cur + ")");
});
+
+ // manually clean data on modified element
+ jQuery.removeData(this, 'olddisplay', true);
+
start();
}
@@ -829,9 +841,6 @@ jQuery.makeTest = function( text ){
jQuery("<h4></h4>")
.text( text )
.appendTo("#fx-tests")
- .click(function(){
- jQuery(this).next().toggle();
- })
.after( elem );
return elem;
@@ -895,7 +904,7 @@ test("hide hidden elements (bug #7141)", function() {
var div = jQuery("<div style='display:none'></div>").appendTo("#main");
equals( div.css("display"), "none", "Element is hidden by default" );
div.hide();
- ok( !div.data("olddisplay"), "olddisplay is undefined after hiding an already-hidden element" );
+ ok( !jQuery._data(div, "olddisplay"), "olddisplay is undefined after hiding an already-hidden element" );
div.show();
equals( div.css("display"), "block", "Show a double-hidden element" );
@@ -910,7 +919,7 @@ test("hide hidden elements, with animation (bug #7141)", function() {
var div = jQuery("<div style='display:none'></div>").appendTo("#main");
equals( div.css("display"), "none", "Element is hidden by default" );
div.hide(1, function () {
- ok( !div.data("olddisplay"), "olddisplay is undefined after hiding an already-hidden element" );
+ ok( !jQuery._data(div, "olddisplay"), "olddisplay is undefined after hiding an already-hidden element" );
div.show(1, function () {
equals( div.css("display"), "block", "Show a double-hidden element" );
start();
diff --git a/test/unit/event.js b/test/unit/event.js
index b4672a8b8..02824a9a3 100644
--- a/test/unit/event.js
+++ b/test/unit/event.js
@@ -1,4 +1,4 @@
-module("event");
+module("event", { teardown: moduleTeardown });
test("null or undefined handler", function() {
expect(2);
@@ -28,7 +28,7 @@ test("bind(), with data", function() {
};
jQuery("#firstp").bind("click", {foo: "bar"}, handler).click().unbind("click", handler);
- ok( !jQuery.data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." );
+ ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." );
});
test("click(), with data", function() {
@@ -39,7 +39,7 @@ test("click(), with data", function() {
};
jQuery("#firstp").click({foo: "bar"}, handler).click().unbind("click", handler);
- ok( !jQuery.data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." );
+ ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." );
});
test("bind(), with data, trigger with data", function() {
@@ -80,6 +80,9 @@ test("bind(), multiple events at once and namespaces", function() {
cur = "focusin";
div.trigger("focusin.a");
+ // manually clean up detached elements
+ div.remove();
+
div = jQuery("<div/>").bind("click mouseover", obj, function(e) {
equals( e.type, cur, "Verify right multi event was fired." );
equals( e.data, obj, "Make sure the data came in correctly." );
@@ -91,6 +94,9 @@ test("bind(), multiple events at once and namespaces", function() {
cur = "mouseover";
div.trigger("mouseover");
+ // manually clean up detached elements
+ div.remove();
+
div = jQuery("<div/>").bind("focusin.a focusout.b", function(e) {
equals( e.type, cur, "Verify right multi event was fired." );
});
@@ -100,6 +106,9 @@ test("bind(), multiple events at once and namespaces", function() {
cur = "focusout";
div.trigger("focusout.b");
+
+ // manually clean up detached elements
+ div.remove();
});
test("bind(), namespace with special add", function() {
@@ -295,15 +304,15 @@ test("live/delegate immediate propagation", function() {
$p.undelegate( "click" );
});
-test("bind/delegate bubbling, isDefaultPrevented (Bug #7793)", function() {
+test("bind/delegate bubbling, isDefaultPrevented", function() {
expect(2);
var $anchor2 = jQuery( "#anchor2" ),
$main = jQuery( "#main" ),
fakeClick = function($jq) {
// Use a native click so we don't get jQuery simulated bubbling
if ( document.createEvent ) {
- var e = document.createEvent( "MouseEvents" );
- e.initEvent( "click", true, true );
+ var e = document.createEvent( 'MouseEvents' );
+ e.initEvent( "click", true, true );
$jq[0].dispatchEvent(e);
}
else if ( $jq[0].click ) {
@@ -314,7 +323,15 @@ test("bind/delegate bubbling, isDefaultPrevented (Bug #7793)", function() {
e.preventDefault();
});
$main.delegate("#foo", "click", function(e) {
- equals( e.isDefaultPrevented(), true, "isDefaultPrevented true passed to bubbled event" );
+ var orig = e.originalEvent;
+
+ if ( typeof(orig.defaultPrevented) === "boolean" || typeof(orig.returnValue) === "boolean" || orig.getPreventDefault ) {
+ equals( e.isDefaultPrevented(), true, "isDefaultPrevented true passed to bubbled event" );
+
+ } else {
+ // Opera < 11 doesn't implement any interface we can use, so give it a pass
+ ok( true, "isDefaultPrevented not supported by this browser, test skipped" );
+ }
});
fakeClick( $anchor2 );
$anchor2.unbind( "click" );
@@ -505,7 +522,7 @@ test("bind(), with different this object", function() {
.bind("click", jQuery.proxy(handler1, thisObject)).click().unbind("click", handler1)
.bind("click", data, jQuery.proxy(handler2, thisObject)).click().unbind("click", handler2);
- ok( !jQuery.data(jQuery("#firstp")[0], "events"), "Event handler unbound when using different this object and data." );
+ ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using different this object and data." );
});
test("bind(name, false), unbind(name, false)", function() {
@@ -525,6 +542,9 @@ test("bind(name, false), unbind(name, false)", function() {
jQuery("#ap").unbind("click", false);
jQuery("#ap").trigger("click");
equals( main, 1, "Verify that the trigger happened correctly." );
+
+ // manually clean up events from elements outside the fixture
+ jQuery("#main").unbind("click");
});
test("bind()/trigger()/unbind() on plain object", function() {
@@ -547,7 +567,7 @@ test("bind()/trigger()/unbind() on plain object", function() {
}
});
- var events = jQuery(obj).data("__events__");
+ var events = jQuery._data(obj, "events");
ok( events, "Object has events bound." );
equals( obj.events, undefined, "Events object on plain objects is not events" );
equals( typeof events, "function", "'events' expando is a function on plain objects." );
@@ -567,7 +587,9 @@ test("bind()/trigger()/unbind() on plain object", function() {
// Make sure it doesn't complain when no events are found
jQuery(obj).unbind("test");
- equals( obj.__events__, undefined, "Make sure events object is removed" );
+ equals( obj && obj[ jQuery.expando ] &&
+ obj[ jQuery.expando ][ jQuery.expando ] &&
+ obj[ jQuery.expando ][ jQuery.expando ].events, undefined, "Make sure events object is removed" );
});
test("unbind(type)", function() {
@@ -661,13 +683,18 @@ test("hover()", function() {
test("trigger() shortcuts", function() {
expect(6);
- jQuery('<li><a href="#">Change location</a></li>').prependTo('#firstUL').find('a').bind('click', function() {
+
+ var elem = jQuery('<li><a href="#">Change location</a></li>').prependTo('#firstUL');
+ elem.find('a').bind('click', function() {
var close = jQuery('spanx', this); // same with jQuery(this).find('span');
equals( close.length, 0, "Context element does not exist, length must be zero" );
ok( !close[0], "Context element does not exist, direct access to element must return undefined" );
return false;
}).click();
+ // manually clean up detached elements
+ elem.remove();
+
jQuery("#check1").click(function() {
ok( true, "click event handler for checkbox gets fired twice, see #815" );
}).click();
@@ -686,9 +713,12 @@ test("trigger() shortcuts", function() {
jQuery('#simon1').click();
equals( clickCounter, 1, "Check that click, triggers onclick event handler on an a tag also" );
- jQuery('<img />').load(function(){
+ elem = jQuery('<img />').load(function(){
ok( true, "Trigger the load event, using the shortcut .load() (#2819)");
}).load();
+
+ // manually clean up detached elements
+ elem.remove();
});
test("trigger() bubbling", function() {
@@ -723,6 +753,10 @@ test("trigger() bubbling", function() {
equals( body, 2, "ap bubble" );
equals( main, 1, "ap bubble" );
equals( ap, 1, "ap bubble" );
+
+ // manually clean up events from elements outside the fixture
+ jQuery(document).unbind("click");
+ jQuery("html, body, #main").unbind("click");
});
test("trigger(type, [data], [fn])", function() {
@@ -766,7 +800,7 @@ test("trigger(type, [data], [fn])", function() {
pass = true;
try {
- jQuery('table:first').bind('test:test', function(){}).trigger('test:test');
+ jQuery('#main table:first').bind('test:test', function(){}).trigger('test:test');
} catch (e) {
pass = false;
}
@@ -947,9 +981,12 @@ test("toggle(Function, Function, ...)", function() {
equals( turn, 2, "Trying toggle with 3 functions, attempt 5 yields 2");
$div.unbind('click',fns[0]);
- var data = jQuery.data( $div[0], 'events' );
+ var data = jQuery._data( $div[0], 'events' );
ok( !data, "Unbinding one function from toggle unbinds them all");
+ // manually clean up detached elements
+ $div.remove();
+
// Test Multi-Toggles
var a = [], b = [];
$div = jQuery("<div/>");
@@ -965,6 +1002,9 @@ test("toggle(Function, Function, ...)", function() {
$div.click();
same( a, [1,2,1], "Check that a click worked with a second toggle, second click." );
same( b, [1,2], "Check that a click worked with a second toggle, second click." );
+
+ // manually clean up detached elements
+ $div.remove();
});
test(".live()/.die()", function() {
@@ -1065,7 +1105,7 @@ test(".live()/.die()", function() {
equals( clicked, 2, "live with a context" );
// Make sure the event is actually stored on the context
- ok( jQuery.data(container, "events").live, "live with a context" );
+ ok( jQuery._data(container, "events").live, "live with a context" );
// Test unbinding with a different context
jQuery("#foo", container).die("click");
@@ -1275,6 +1315,9 @@ test("live with multiple events", function(){
div.trigger("submit");
equals( count, 2, "Make sure both the click and submit were triggered." );
+
+ // manually clean up events from elements outside the fixture
+ div.die();
});
test("live with namespaces", function(){
@@ -1578,7 +1621,7 @@ test(".delegate()/.undelegate()", function() {
equals( clicked, 2, "delegate with a context" );
// Make sure the event is actually stored on the context
- ok( jQuery.data(container, "events").live, "delegate with a context" );
+ ok( jQuery._data(container, "events").live, "delegate with a context" );
// Test unbinding with a different context
jQuery("#main").undelegate("#foo", "click");
@@ -1907,7 +1950,7 @@ test("window resize", function() {
ok( true, "Resize event fired." );
}).resize().unbind("resize");
- ok( !jQuery(window).data("__events__"), "Make sure all the events are gone." );
+ ok( !jQuery._data(window, "__events__"), "Make sure all the events are gone." );
});
test("focusin bubbles", function() {
diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js
index e273cf08a..37234d86d 100644
--- a/test/unit/manipulation.js
+++ b/test/unit/manipulation.js
@@ -1,4 +1,4 @@
-module("manipulation");
+module("manipulation", { teardown: moduleTeardown });
// Ensure that an extended Array prototype doesn't break jQuery
Array.prototype.arrayProtoFn = function(arg) { throw("arrayProtoFn should not be called"); };
@@ -115,12 +115,19 @@ var testWrap = function(val) {
// Wrap an element with a jQuery set and event
result = jQuery("<div></div>").click(function(){
ok(true, "Event triggered.");
+
+ // Remove handlers on detached elements
+ result.unbind();
+ jQuery(this).unbind();
});
j = jQuery("<span/>").wrap(result);
equals( j[0].parentNode.nodeName.toLowerCase(), "div", "Wrapping works." );
j.parent().trigger("click");
+
+ // clean up attached elements
+ QUnit.reset();
}
test("wrap(String|Element)", function() {
@@ -395,7 +402,7 @@ test("append(Function) with incoming value", function() {
});
test("append the same fragment with events (Bug #6997, 5566)", function () {
- expect(4 + (document.fireEvent ? 1 : 0));
+ expect(2 + (document.fireEvent ? 1 : 0));
stop(1000);
var element;
@@ -408,8 +415,12 @@ test("append the same fragment with events (Bug #6997, 5566)", function () {
ok(true, "Event exists on original after being unbound on clone");
jQuery(this).unbind('click');
});
- element.clone(true).unbind('click')[0].fireEvent('onclick');
+ var clone = element.clone(true).unbind('click');
+ clone[0].fireEvent('onclick');
element[0].fireEvent('onclick');
+
+ // manually clean up detached elements
+ clone.remove();
}
element = jQuery("<a class='test6997'></a>").click(function () {
@@ -426,14 +437,6 @@ test("append the same fragment with events (Bug #6997, 5566)", function () {
jQuery("#listWithTabIndex li").before(element);
jQuery("#listWithTabIndex li.test6997").eq(1).click();
-
- element = jQuery("<select><option>Foo</option><option selected>Bar</option></select>");
-
- equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" );
-
- element = jQuery("<input type='checkbox'>").attr('checked', 'checked');
-
- equals( element.clone().is(":checked"), element.is(":checked"), "Checked input cloned correctly" );
});
test("appendTo(String|Element|Array&lt;Element&gt;|jQuery)", function() {
@@ -894,20 +897,36 @@ test("clone()", function() {
ok( true, "Bound event still exists." );
});
- div = div.clone(true).clone(true);
+ clone = div.clone(true);
+
+ // manually clean up detached elements
+ div.remove();
+
+ div = clone.clone(true);
+
+ // manually clean up detached elements
+ clone.remove();
+
equals( div.length, 1, "One element cloned" );
equals( div[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" );
div.trigger("click");
+ // manually clean up detached elements
+ div.remove();
+
div = jQuery("<div/>").append([ document.createElement("table"), document.createElement("table") ]);
div.find("table").click(function(){
ok( true, "Bound event still exists." );
});
- div = div.clone(true);
- equals( div.length, 1, "One element cloned" );
- equals( div[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" );
- div.find("table:last").trigger("click");
+ clone = div.clone(true);
+ equals( clone.length, 1, "One element cloned" );
+ equals( clone[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" );
+ clone.find("table:last").trigger("click");
+
+ // manually clean up detached elements
+ div.remove();
+ clone.remove();
// this is technically an invalid object, but because of the special
// classid instantiation it is the only kind that IE has trouble with,
@@ -928,12 +947,16 @@ test("clone()", function() {
equals( clone[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" );
div = jQuery("<div/>").data({ a: true });
- var div2 = div.clone(true);
- equals( div2.data("a"), true, "Data cloned." );
- div2.data("a", false);
- equals( div2.data("a"), false, "Ensure cloned element data object was correctly modified" );
+ clone = div.clone(true);
+ equals( clone.data("a"), true, "Data cloned." );
+ clone.data("a", false);
+ equals( clone.data("a"), false, "Ensure cloned element data object was correctly modified" );
equals( div.data("a"), true, "Ensure cloned element data object is copied, not referenced" );
+ // manually clean up detached elements
+ div.remove();
+ clone.remove();
+
var form = document.createElement("form");
form.action = "/test/";
var div = document.createElement("div");
@@ -945,6 +968,28 @@ test("clone()", function() {
equal( jQuery("body").clone().children()[0].id, "qunit-header", "Make sure cloning body works" );
});
+test("clone(form element) (Bug #3879, #6655)", function() {
+ expect(6);
+ element = jQuery("<select><option>Foo</option><option selected>Bar</option></select>");
+
+ equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" );
+
+ element = jQuery("<input type='checkbox' value='foo'>").attr('checked', 'checked');
+ clone = element.clone();
+
+ equals( clone.is(":checked"), element.is(":checked"), "Checked input cloned correctly" );
+ equals( clone[0].defaultValue, "foo", "Checked input defaultValue cloned correctly" );
+ equals( clone[0].defaultChecked, !jQuery.support.noCloneEvent, "Checked input defaultChecked cloned correctly" );
+
+ element = jQuery("<input type='text' value='foo'>");
+ clone = element.clone();
+ equals( clone[0].defaultValue, "foo", "Text input defaultValue cloned correctly" );
+
+ element = jQuery("<textarea>foo</textarea>");
+ clone = element.clone();
+ equals( clone[0].defaultValue, "foo", "Textarea defaultValue cloned correctly" );
+});
+
if (!isLocal) {
test("clone() on XML nodes", function() {
expect(2);
@@ -1141,15 +1186,21 @@ var testRemove = function(method) {
jQuery("#nonnodes").contents()[method]();
equals( jQuery("#nonnodes").contents().length, 0, "Check node,textnode,comment remove works" );
+ // manually clean up detached elements
+ if (method === "detach") {
+ first.remove();
+ }
+
QUnit.reset();
var count = 0;
var first = jQuery("#ap").children(":first");
- var cleanUp = first.click(function() { count++ })[method]().appendTo("body").click();
+ var cleanUp = first.click(function() { count++ })[method]().appendTo("#main").click();
equals( method == "remove" ? 0 : 1, count );
- cleanUp.detach();
+ // manually clean up detached elements
+ cleanUp.remove();
};
test("remove()", function() {
diff --git a/test/unit/offset.js b/test/unit/offset.js
index 69bf6d5d0..bac900d69 100644
--- a/test/unit/offset.js
+++ b/test/unit/offset.js
@@ -1,4 +1,4 @@
-module("offset");
+module("offset", { teardown: moduleTeardown });
test("disconnected node", function() {
expect(2);
diff --git a/test/unit/queue.js b/test/unit/queue.js
index eada0eede..31e587db2 100644
--- a/test/unit/queue.js
+++ b/test/unit/queue.js
@@ -1,4 +1,4 @@
-module("queue");
+module("queue", { teardown: moduleTeardown });
test("queue() with other types",function() {
expect(9);
diff --git a/test/unit/selector.js b/test/unit/selector.js
index 5b758c101..6a3832555 100644
--- a/test/unit/selector.js
+++ b/test/unit/selector.js
@@ -1,4 +1,4 @@
-module("selector");
+module("selector", { teardown: moduleTeardown });
test("element", function() {
expect(21);
@@ -58,13 +58,14 @@ if ( location.protocol != "file:" ) {
}
test("broken", function() {
- expect(8);
+ expect(19);
+
function broken(name, selector) {
try {
jQuery(selector);
ok( false, name + ": " + selector );
} catch(e){
- ok( typeof e === "string" && e.indexOf("Syntax error") >= 0,
+ ok( typeof e === "string" && e.indexOf("Syntax error") >= 0,
name + ": " + selector );
}
}
@@ -77,10 +78,31 @@ test("broken", function() {
broken( "Broken Selector", "<>", [] );
broken( "Broken Selector", "{}", [] );
broken( "Doesn't exist", ":visble", [] );
+ broken( "Nth-child", ":nth-child", [] );
+ broken( "Nth-child", ":nth-child(-)", [] );
+ // Sigh. WebKit thinks this is a real selector in qSA
+ // They've already fixed this and it'll be coming into
+ // current browsers soon.
+ //broken( "Nth-child", ":nth-child(asdf)", [] );
+ broken( "Nth-child", ":nth-child(2n+-0)", [] );
+ broken( "Nth-child", ":nth-child(2+0)", [] );
+ broken( "Nth-child", ":nth-child(- 1n)", [] );
+ broken( "Nth-child", ":nth-child(-1 n)", [] );
+ broken( "First-child", ":first-child(n)", [] );
+ broken( "Last-child", ":last-child(n)", [] );
+ broken( "Only-child", ":only-child(n)", [] );
+
+ // Make sure attribute value quoting works correctly. See: #6093
+ var attrbad = jQuery('<input type="hidden" value="2" name="foo.baz" id="attrbad1"/><input type="hidden" value="2" name="foo[baz]" id="attrbad2"/>').appendTo("body");
+
+ broken( "Attribute not escaped", "input[name=foo.baz]", [] );
+ broken( "Attribute not escaped", "input[name=foo[baz]]", [] );
+
+ attrbad.remove();
});
test("id", function() {
- expect(28);
+ expect(29);
t( "ID Selector", "#body", ["body"] );
t( "ID Selector w/ Element", "body#body", ["body"] );
t( "ID Selector w/ Element", "ul#first", [] );
@@ -116,6 +138,9 @@ test("id", function() {
same( jQuery("body").find("div#form").get(), [], "ID selector within the context of another element" );
+ //#7533
+ equal( jQuery("<div id=\"A'B~C.D[E]\"><p>foo</p></div>").find("p").length, 1, "Find where context root is a node and has an ID with CSS3 meta characters" );
+
t( "Underscore ID", "#types_all", ["types_all"] );
t( "Dash ID", "#fx-queue", ["fx-queue"] );
@@ -150,7 +175,7 @@ test("class", function() {
t( "Child escaped Class", "form > .test\\.foo\\[5\\]bar", ["test.foo[5]bar"] );
var div = document.createElement("div");
- div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
same( jQuery(".e", div).get(), [ div.firstChild ], "Finding a second class." );
div.lastChild.className = "e";
@@ -202,7 +227,7 @@ test("multiple", function() {
});
test("child and adjacent", function() {
- expect(27);
+ expect(31);
t( "Child", "p > a", ["simon1","google","groups","mark","yahoo","simon"] );
t( "Child", "p> a", ["simon1","google","groups","mark","yahoo","simon"] );
t( "Child", "p >a", ["simon1","google","groups","mark","yahoo","simon"] );
@@ -210,20 +235,25 @@ test("child and adjacent", function() {
t( "Child w/ Class", "p > a.blog", ["mark","simon"] );
t( "All Children", "code > *", ["anchor1","anchor2"] );
t( "All Grandchildren", "p > * > *", ["anchor1","anchor2"] );
- t( "Adjacent", "#main a + a", ["groups"] );
- t( "Adjacent", "#main a +a", ["groups"] );
- t( "Adjacent", "#main a+ a", ["groups"] );
- t( "Adjacent", "#main a+a", ["groups"] );
+ t( "Adjacent", "a + a", ["groups"] );
+ t( "Adjacent", "a +a", ["groups"] );
+ t( "Adjacent", "a+ a", ["groups"] );
+ t( "Adjacent", "a+a", ["groups"] );
t( "Adjacent", "p + p", ["ap","en","sap"] );
t( "Adjacent", "p#firstp + p", ["ap"] );
t( "Adjacent", "p[lang=en] + p", ["sap"] );
t( "Adjacent", "a.GROUPS + code + a", ["mark"] );
- t( "Comma, Child, and Adjacent", "#main a + a, code > a", ["groups","anchor1","anchor2"] );
+ t( "Comma, Child, and Adjacent", "a + a, code > a", ["groups","anchor1","anchor2"] );
t( "Element Preceded By", "p ~ div", ["foo", "moretests","tabindex-tests", "liveHandlerOrder", "siblingTest"] );
t( "Element Preceded By", "#first ~ div", ["moretests","tabindex-tests", "liveHandlerOrder", "siblingTest"] );
t( "Element Preceded By", "#groups ~ a", ["mark"] );
t( "Element Preceded By", "#length ~ input", ["idTest"] );
t( "Element Preceded By", "#siblingfirst ~ em", ["siblingnext"] );
+ same( jQuery("#siblingfirst").find("~ em").get(), q("siblingnext"), "Element Preceded By with a context." );
+ same( jQuery("#siblingfirst").find("+ em").get(), q("siblingnext"), "Element Directly Preceded By with a context." );
+ var a = jQuery("<div id='foo'></div><p id='bar'></p><p id='bar2'></p>");
+ same( jQuery("~ p", a[0]).get(), [a[1], a[2]], "Detached Element Directly Preceded By with a context." );
+ same( jQuery("+ p", a[0]).get(), [a[1]], "Detached Element Preceded By with a context." );
t( "Verify deep class selector", "div.blah > p > a", [] );
@@ -237,7 +267,8 @@ test("child and adjacent", function() {
});
test("attributes", function() {
- expect(39);
+ expect(41);
+
t( "Attribute Exists", "a[title]", ["google"] );
t( "Attribute Exists", "*[title]", ["google"] );
t( "Attribute Exists", "[title]", ["google"] );
@@ -294,10 +325,18 @@ test("attributes", function() {
t("Select options via :selected", "#select3 option:selected", ["option3b", "option3c"] );
t( "Grouped Form Elements", "input[name='foo[bar]']", ["hidden2"] );
+
+ // Make sure attribute value quoting works correctly. See: #6093
+ var attrbad = jQuery('<input type="hidden" value="2" name="foo.baz" id="attrbad1"/><input type="hidden" value="2" name="foo[baz]" id="attrbad2"/>').appendTo("body");
+
+ t("Find escaped attribute value", "input[name=foo\\.baz]", ["attrbad1"]);
+ t("Find escaped attribute value", "input[name=foo\\[baz\\]]", ["attrbad2"]);
+
+ attrbad.remove();
});
test("pseudo - child", function() {
- expect(31);
+ expect(38);
t( "First Child", "p:first-child", ["firstp","sndp"] );
t( "Last Child", "p:last-child", ["sap"] );
t( "Only Child", "#main a:only-child", ["simon1","anchor1","yahoo","anchor2","liveLink1","liveLink2"] );
@@ -306,6 +345,7 @@ test("pseudo - child", function() {
t( "First Child", "p:first-child", ["firstp","sndp"] );
t( "Nth Child", "p:nth-child(1)", ["firstp","sndp"] );
+ t( "Nth Child With Whitespace", "p:nth-child( 1 )", ["firstp","sndp"] );
t( "Not Nth Child", "p:not(:nth-child(1))", ["ap","en","sap","first"] );
// Verify that the child position isn't being cached improperly
@@ -322,15 +362,19 @@ test("pseudo - child", function() {
t( "Nth-child", "#main form#form > *:nth-child(2)", ["text1"] );
t( "Nth-child", "#main form#form > :nth-child(2)", ["text1"] );
+ t( "Nth-child", "#form select:first option:nth-child(-1)", [] );
t( "Nth-child", "#form select:first option:nth-child(3)", ["option1c"] );
t( "Nth-child", "#form select:first option:nth-child(0n+3)", ["option1c"] );
t( "Nth-child", "#form select:first option:nth-child(1n+0)", ["option1a", "option1b", "option1c", "option1d"] );
t( "Nth-child", "#form select:first option:nth-child(1n)", ["option1a", "option1b", "option1c", "option1d"] );
t( "Nth-child", "#form select:first option:nth-child(n)", ["option1a", "option1b", "option1c", "option1d"] );
+ t( "Nth-child", "#form select:first option:nth-child(+n)", ["option1a", "option1b", "option1c", "option1d"] );
t( "Nth-child", "#form select:first option:nth-child(even)", ["option1b", "option1d"] );
t( "Nth-child", "#form select:first option:nth-child(odd)", ["option1a", "option1c"] );
t( "Nth-child", "#form select:first option:nth-child(2n)", ["option1b", "option1d"] );
t( "Nth-child", "#form select:first option:nth-child(2n+1)", ["option1a", "option1c"] );
+ t( "Nth-child", "#form select:first option:nth-child(2n + 1)", ["option1a", "option1c"] );
+ t( "Nth-child", "#form select:first option:nth-child(+2n + 1)", ["option1a", "option1c"] );
t( "Nth-child", "#form select:first option:nth-child(3n)", ["option1c"] );
t( "Nth-child", "#form select:first option:nth-child(3n+1)", ["option1a", "option1d"] );
t( "Nth-child", "#form select:first option:nth-child(3n+2)", ["option1b"] );
@@ -339,7 +383,9 @@ test("pseudo - child", function() {
t( "Nth-child", "#form select:first option:nth-child(3n-2)", ["option1a", "option1d"] );
t( "Nth-child", "#form select:first option:nth-child(3n-3)", ["option1c"] );
t( "Nth-child", "#form select:first option:nth-child(3n+0)", ["option1c"] );
+ t( "Nth-child", "#form select:first option:nth-child(-1n+3)", ["option1a", "option1b", "option1c"] );
t( "Nth-child", "#form select:first option:nth-child(-n+3)", ["option1a", "option1b", "option1c"] );
+ t( "Nth-child", "#form select:first option:nth-child(-1n + 3)", ["option1a", "option1b", "option1c"] );
});
test("pseudo - misc", function() {
diff --git a/test/unit/traversing.js b/test/unit/traversing.js
index 31cffc2eb..f0471d74e 100644
--- a/test/unit/traversing.js
+++ b/test/unit/traversing.js
@@ -1,4 +1,4 @@
-module("traversing");
+module("traversing", { teardown: moduleTeardown });
test("find(String)", function() {
expect(5);