aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/csp.php30
-rw-r--r--test/data/errorWithText.php5
-rw-r--r--test/data/headers.php16
-rw-r--r--test/data/jsonp.php4
-rw-r--r--test/data/params_html.php6
-rw-r--r--test/data/testinit.js49
-rw-r--r--test/delegatetest.html6
-rw-r--r--test/index.html9
-rw-r--r--test/polluted.php4
-rw-r--r--test/unit/ajax.js1070
-rw-r--r--test/unit/attributes.js78
-rw-r--r--test/unit/core.js346
-rw-r--r--test/unit/css.js79
-rw-r--r--test/unit/data.js251
-rw-r--r--test/unit/dimensions.js48
-rw-r--r--test/unit/effects.js99
-rw-r--r--test/unit/event.js380
-rw-r--r--test/unit/manipulation.js131
-rw-r--r--test/unit/offset.js102
-rw-r--r--test/unit/queue.js48
-rw-r--r--test/unit/selector.js110
-rw-r--r--test/unit/traversing.js43
22 files changed, 1929 insertions, 985 deletions
diff --git a/test/csp.php b/test/csp.php
new file mode 100644
index 000000000..acf8f32c9
--- /dev/null
+++ b/test/csp.php
@@ -0,0 +1,30 @@
+<?php header("X-Content-Security-Policy-Report-Only: allow *"); ?>
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>CSP Test Page</title>
+
+ <script src="../src/core.js"></script>
+ <script src="../src/support.js"></script>
+ <script src="../src/data.js"></script>
+ <script src="../src/queue.js"></script>
+ <script src="../src/attributes.js"></script>
+ <script src="../src/event.js"></script>
+ <script src="../src/sizzle/sizzle.js"></script>
+ <script src="../src/sizzle-jquery.js"></script>
+ <script src="../src/traversing.js"></script>
+ <script src="../src/manipulation.js"></script>
+ <script src="../src/css.js"></script>
+ <script src="../src/ajax.js"></script>
+ <script src="../src/ajax/jsonp.js"></script>
+ <script src="../src/ajax/script.js"></script>
+ <script src="../src/ajax/xhr.js"></script>
+ <script src="../src/effects.js"></script>
+ <script src="../src/offset.js"></script>
+ <script src="../src/dimensions.js"></script>
+</head>
+<body>
+ <p>CSP Test Page</p>
+</body>
+</html>
diff --git a/test/data/errorWithText.php b/test/data/errorWithText.php
new file mode 100644
index 000000000..abd873217
--- /dev/null
+++ b/test/data/errorWithText.php
@@ -0,0 +1,5 @@
+<?php
+
+header("HTTP/1.0 400 Bad Request");
+
+echo "plain text message"; \ No newline at end of file
diff --git a/test/data/headers.php b/test/data/headers.php
index f2c21c0cc..d500b16f4 100644
--- a/test/data/headers.php
+++ b/test/data/headers.php
@@ -4,17 +4,13 @@ header( "Sample-Header: Hello World" );
$headers = array();
-foreach( $_SERVER as $key => $value ) {
-
- if ( substr( $key , 0 , 5 ) == "HTTP_" ) {
-
- $key = str_replace( "_" , "-" , substr( $key , 5) );
- $headers[ $key ] = $value;
+foreach( $_SERVER as $key => $value ) {
- }
-
-}
+ $key = str_replace( "_" , "-" , substr( $key , 0 , 5 ) == "HTTP_" ? substr( $key , 5 ) : $key );
+ $headers[ $key ] = $value;
+
+}
foreach( explode( "_" , $_GET[ "keys" ] ) as $key ) {
- echo "$key: " . $headers[ strtoupper( $key ) ] . "\n";
+ echo "$key: " . @$headers[ strtoupper( $key ) ] . "\n";
}
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/params_html.php b/test/data/params_html.php
index 0bab00f29..e88ef1521 100644
--- a/test/data/params_html.php
+++ b/test/data/params_html.php
@@ -1,12 +1,12 @@
<div id="post">
-<?php
+<?php
foreach( $_POST as $key=>$value )
echo "<b id='$key'>$value</b>";
-?>
+?>
</div>
<div id="get">
<?php
foreach( $_GET as $key=>$value )
echo "<b id='$key'>$value</b>";
-?>
+?>
</div> \ No newline at end of file
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/delegatetest.html b/test/delegatetest.html
index 327085c84..6479d26ec 100644
--- a/test/delegatetest.html
+++ b/test/delegatetest.html
@@ -206,7 +206,7 @@
$(document).bind("focusin", function() {
jQuery("#boundFocus").blink();
});
-
+
$(document).bind("focusout", function() {
jQuery("#boundBlur").blink();
});
@@ -229,14 +229,14 @@
$(document).bind("change", function(){
jQuery("#boundChange").blink();
});
-
+
$("#text_submit").addSubmitTest("#textSubmit", true);
$("#password_submit").addSubmitTest("#passwordSubmit", true);
$("#submit_submit").addSubmitTest("#submitSubmit", true);
$(document).bind("submit", function(){
jQuery("#boundSubmit").blink();
});
-
+
</script>
</body>
</html>
diff --git a/test/index.html b/test/index.html
index 238b7d582..fc5f667d2 100644
--- a/test/index.html
+++ b/test/index.html
@@ -20,10 +20,9 @@
<script src="../src/manipulation.js"></script>
<script src="../src/css.js"></script>
<script src="../src/ajax.js"></script>
- <script src="../src/xhr.js"></script>
- <script src="../src/transports/jsonp.js"></script>
- <script src="../src/transports/script.js"></script>
- <script src="../src/transports/xhr.js"></script>
+ <script src="../src/ajax/jsonp.js"></script>
+ <script src="../src/ajax/script.js"></script>
+ <script src="../src/ajax/xhr.js"></script>
<script src="../src/effects.js"></script>
<script src="../src/offset.js"></script>
<script src="../src/dimensions.js"></script>
@@ -265,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/polluted.php b/test/polluted.php
index 3ddb7acd2..55df0dd89 100644
--- a/test/polluted.php
+++ b/test/polluted.php
@@ -15,7 +15,7 @@
$suite = file_get_contents('index.html');
echo str_replace( '<!-- Includes -->', $includes, $suite );
exit;
- }
+ }
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@@ -43,7 +43,7 @@
<h1 id="header">jQuery Test Suite</h1>
<h2 id="banner" class="fail"></h2>
<h2 id="userAgent">Choose other libraries to include</h2>
-
+
<form class="otherlibs" action="" method="post">
<?php
$libs = scandir('otherlibs');
diff --git a/test/unit/ajax.js b/test/unit/ajax.js
index 35c030247..b44f0773f 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
@@ -70,44 +70,6 @@ test("jQuery.ajax() - success callbacks - (url, options) syntax", function() {
}, 13);
});
-test("jQuery.ajax() - success/error callbacks (remote)", function() {
-
- var supports = jQuery.support.cors;
-
- expect( supports ? 9 : 6 );
-
- jQuery.ajaxSetup({ timeout: 0 });
-
- stop();
-
- setTimeout(function(){
- jQuery('#foo').ajaxStart(function(){
- ok( true, "ajaxStart" );
- }).ajaxStop(function(){
- ok( true, "ajaxStop" );
- start();
- }).ajaxSend(function(){
- ok( supports , "ajaxSend" );
- }).ajaxComplete(function(){
- ok( true, "ajaxComplete" );
- }).ajaxError(function(){
- ok( ! supports, "ajaxError" );
- }).ajaxSuccess(function(){
- ok( supports, "ajaxSuccess" );
- });
-
- jQuery.ajax({
- // JULIAN TODO: Get an url especially for jQuery
- url: "http://rockstarapps.com/test.php",
- dataType: "text",
- beforeSend: function(){ ok(supports, "beforeSend"); },
- success: function( val ){ ok(supports, "success"); ok(supports && val.length, "data received"); },
- error: function(_ , a , b ){ ok(!supports, "error"); },
- complete: function(){ ok(true, "complete"); }
- });
- }, 13);
-});
-
test("jQuery.ajax() - success callbacks (late binding)", function() {
expect( 8 );
@@ -173,7 +135,7 @@ test("jQuery.ajax() - success callbacks (oncomplete binding)", function() {
.error(function(){ ok(false, "error"); })
.complete(function(){ start(); });
}
- })
+ });
}, 13);
});
@@ -211,7 +173,7 @@ test("jQuery.ajax() - success callbacks (very late binding)", function() {
.complete(function(){ start(); });
},100);
}
- })
+ });
}, 13);
});
@@ -221,7 +183,7 @@ test("jQuery.ajax() - success callbacks (order)", function() {
jQuery.ajaxSetup({ timeout: 0 });
stop();
-
+
var testString = "";
setTimeout(function(){
@@ -278,12 +240,52 @@ test("jQuery.ajax() - error callbacks", function() {
});
});
+test("jQuery.ajax() - responseText on error", function() {
+
+ expect( 1 );
+
+ stop();
+
+ jQuery.ajax({
+ url: url("data/errorWithText.php"),
+ error: function(xhr) {
+ strictEqual( xhr.responseText , "plain text message" , "Test jXHR.responseText is filled for HTTP errors" );
+ },
+ complete: function() {
+ start();
+ }
+ });
+});
+
+test(".ajax() - retry with jQuery.ajax( this )", function() {
+
+ expect( 1 );
+
+ stop();
+
+ var firstTime = 1;
+
+ jQuery.ajax({
+ url: url("data/errorWithText.php"),
+ error: function() {
+ if ( firstTime ) {
+ firstTime = 0;
+ jQuery.ajax( this );
+ } else {
+ ok( true , "Test retrying with jQuery.ajax(this) works" );
+ start();
+ }
+ }
+ });
+
+});
+
test(".ajax() - headers" , function() {
expect( 2 );
-
+
stop();
-
+
var requestHeaders = {
siMPle: "value",
"SometHing-elsE": "other value",
@@ -291,11 +293,11 @@ test(".ajax() - headers" , function() {
},
list = [],
i;
-
+
for( i in requestHeaders ) {
list.push( i );
}
-
+
jQuery.ajax(url("data/headers.php?keys="+list.join( "_" ) ), {
headers: requestHeaders,
success: function( data , _ , xhr ) {
@@ -304,19 +306,77 @@ test(".ajax() - headers" , function() {
tmp.push( i , ": " , requestHeaders[ i ] , "\n" );
}
tmp = tmp.join( "" );
-
+
equals( data , tmp , "Headers were sent" );
equals( xhr.getResponseHeader( "Sample-Header" ) , "Hello World" , "Sample header received" );
start();
},
error: function(){ ok(false, "error"); }
});
-
+
+});
+
+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 );
+
+ stop();
+
+ var count = 2;
+
+ function restart() {
+ if ( ! --count ) {
+ start();
+ }
+ }
+
+ jQuery.ajax(url("data/headers.php?keys=content-type" ), {
+ contentType: "test",
+ success: function( data ) {
+ strictEqual( data , "content-type: test\n" , "Test content-type is sent when options.contentType is set" );
+ },
+ complete: function() {
+ restart();
+ }
+ });
+
+ jQuery.ajax(url("data/headers.php?keys=content-type" ), {
+ contentType: false,
+ success: function( data ) {
+ strictEqual( data , "content-type: \n" , "Test content-type is not sent when options.contentType===false" );
+ },
+ complete: function() {
+ restart();
+ }
+ });
+
});
test(".ajax() - hash", function() {
expect(3);
-
+
jQuery.ajax({
url: "data/name.html#foo",
beforeSend: function( xhr, settings ) {
@@ -324,7 +384,7 @@ test(".ajax() - hash", function() {
return false;
}
});
-
+
jQuery.ajax({
url: "data/name.html?abc#foo",
beforeSend: function( xhr, settings ) {
@@ -332,7 +392,7 @@ test(".ajax() - hash", function() {
return false;
}
});
-
+
jQuery.ajax({
url: "data/name.html?abc#foo",
data: { "test": 123 },
@@ -343,10 +403,57 @@ test(".ajax() - hash", function() {
});
});
+test("jQuery ajax - cross-domain detection", function() {
+
+ expect( 4 );
+
+ var loc = document.location,
+ otherPort = loc.port === 666 ? 667 : 666,
+ otherProtocol = loc.protocol === "http:" ? "https:" : "http:";
+
+ jQuery.ajax({
+ dataType: "jsonp",
+ url: otherProtocol + "//" + loc.host,
+ beforeSend: function( _ , s ) {
+ ok( s.crossDomain , "Test different protocols are detected as cross-domain" );
+ return false;
+ }
+ });
+
+ jQuery.ajax({
+ dataType: "jsonp",
+ url: loc.protocol + '//somewebsitethatdoesnotexist-656329477541.com:' + ( loc.port || 80 ),
+ beforeSend: function( _ , s ) {
+ ok( s.crossDomain , "Test different hostnames are detected as cross-domain" );
+ return false;
+ }
+ });
+
+ jQuery.ajax({
+ dataType: "jsonp",
+ url: loc.protocol + "//" + loc.hostname + ":" + otherPort,
+ beforeSend: function( _ , s ) {
+ ok( s.crossDomain , "Test different ports are detected as cross-domain" );
+ return false;
+ }
+ });
+
+ jQuery.ajax({
+ dataType: "jsonp",
+ url: loc.protocol + "//" + loc.host,
+ crossDomain: true,
+ beforeSend: function( _ , s ) {
+ ok( s.crossDomain , "Test forced crossDomain is detected as cross-domain" );
+ return false;
+ }
+ });
+
+});
+
test(".ajax() - 304", function() {
expect( 1 );
stop();
-
+
jQuery.ajax({
url: url("data/notmodified.php"),
success: function(){ ok(true, "304 ok"); },
@@ -409,142 +516,12 @@ test("jQuery.ajax() - abort", function() {
equals( xhr.readyState, 0, "XHR readyState indicates successful abortion" );
});
-test("jQuery.ajax() - readyState (success)", function() {
- expect( 1 );
-
- jQuery.ajaxSetup({ timeout: 0 });
-
- stop();
-
- var control = "";
-
- setTimeout(function(){
- jQuery.ajax({
- url: url("data/name.html"),
- beforeSend: function( xhr ) {
- xhr.onreadystatechange = function() {
- control += xhr.readyState;
- }
- },
- complete: function(){
- setTimeout( function() {
- equals( control , "1234" , "onreadystatechange was properly called" );
- }, 13 );
- start();
- }
- });
- }, 13);
-});
-
-test("jQuery.ajax() - readyState (abort)", function() {
- expect( 2 );
-
- jQuery.ajaxSetup({ timeout: 0 });
-
- stop();
-
- var control = "";
-
- setTimeout(function(){
-
- jQuery.ajaxSetup({ timeout: 500 });
-
- jQuery.ajax({
- url: url("data/name.php?wait=5"),
- beforeSend: function( xhr ) {
- xhr.onreadystatechange = function() {
- control += xhr.readyState;
- }
- },
- complete: function( xhr ){
- setTimeout( function() {
- equals( control , "14" , "onreadystatechange was properly called" );
- equals( xhr.readyState, 0 , "readyState is 0" );
- }, 13 );
- start();
- }
- });
- }, 13);
-});
-
-test("jQuery.xhr() - reuse", function() {
- expect( 15 );
-
- jQuery.ajaxSetup({ timeout: 0 });
-
- stop();
-
- var number = 0;
-
- setTimeout(function(){
- jQuery('#foo').ajaxStart(function(){
- ok( true, "ajaxStart" );
- }).ajaxStop(function(){
- ok( true, "ajaxStop" );
- start();
- }).ajaxSend(function(){
- number++;
- ok( true, "ajaxSend (" + number +")" );
- }).ajaxComplete(function(){
- ok( true, "ajaxComplete (" + number +")" );
- }).ajaxError(function(){
- ok( false, "ajaxError (" + number +")" );
- }).ajaxSuccess(function(){
- ok( true, "ajaxSuccess (" + number +")" );
- });
-
- jQuery.ajax({
- url: url("data/name.html"),
- beforeSend: function(){ ok(true, "beforeSend (1)"); },
- success: function( _1 , _2 , xhr ){
- ok(true, "success (1)");
- xhr.complete(function() {
- ok(true, "complete (1bis)");
- });
- xhr.open( "GET", url("data/name.html") );
- xhr.success( function(){ ok(true, "beforeSend (2)"); } )
- xhr.send( null, {
- success: function(){ ok(true, "success (2)"); },
- error: function(){ ok(false, "error (2)"); },
- complete: function(){ ok(true, "complete (2)"); }
- } );
- },
- error: function(){ ok(false, "error (1)"); },
- complete: function(){ ok(true, "complete (1)"); }
- });
- }, 13);
-});
-
-test("jQuery.xhr() - early binding", function() {
- expect( 2 );
-
- jQuery.ajaxSetup({ timeout: 0 });
-
- stop();
-
- jQuery.xhr()
- .success( function(){ ok(true, "success"); } )
- .error( function(){ ok(false, "error"); } )
- .complete( function(){ ok(true, "complete"); start(); } )
- .open( "GET", url("data/name.html") )
- .send();
-});
-
-test("jQuery.xhr() - get native implementation", function() {
-
- var xhr = jQuery.xhr(true);
-
- ok( xhr.readyState !== undefined , "implements XMLHttpRequest" );
- ok( ! jQuery.isFunction( xhr.success ) , "is not jQuery's abstraction" );
-
-});
-
test("Ajax events with context", function() {
expect(14);
-
+
stop();
var context = document.createElement("div");
-
+
function event(e){
equals( this, context, e.type );
}
@@ -560,7 +537,7 @@ test("Ajax events with context", function() {
equals( typeof this.url, "string", "context is settings on callback " + msg );
};
}
-
+
jQuery('#foo').add(context)
.ajaxSend(event)
.ajaxComplete(event)
@@ -606,7 +583,7 @@ test("jQuery.ajax context modification", function() {
stop();
- var obj = {}
+ var obj = {};
jQuery.ajax({
url: url("data/name.html"),
@@ -622,6 +599,47 @@ test("jQuery.ajax context modification", function() {
equals( obj.test, "foo", "Make sure the original object is maintained." );
});
+test("jQuery.ajax context modification through ajaxSetup", function() {
+ expect(4);
+
+ stop();
+
+ var obj = {};
+
+ jQuery.ajaxSetup({
+ context: obj
+ });
+
+ strictEqual( jQuery.ajaxSettings.context, obj, "Make sure the context is properly set in ajaxSettings." );
+
+ jQuery.ajax({
+ url: url("data/name.html"),
+ complete: function() {
+ strictEqual( this, obj, "Make sure the original object is maintained." );
+ jQuery.ajax({
+ url: url("data/name.html"),
+ context: {},
+ complete: function() {
+ ok( this !== obj, "Make sure overidding context is possible." );
+ jQuery.ajaxSetup({
+ context: false
+ });
+ jQuery.ajax({
+ url: url("data/name.html"),
+ beforeSend: function(){
+ this.test = "foo2";
+ },
+ complete: function() {
+ ok( this !== obj, "Make sure unsetting context is possible." );
+ start();
+ }
+ });
+ }
+ });
+ }
+ });
+});
+
test("jQuery.ajax() - disabled globals", function() {
expect( 3 );
stop();
@@ -653,34 +671,6 @@ test("jQuery.ajax() - disabled globals", function() {
});
});
-test("jQuery.xhr() - disabled globals through xhr.send(data , false)", function() {
- expect( 2 );
- stop();
-
- jQuery('#foo').ajaxStart(function(){
- ok( false, "ajaxStart" );
- }).ajaxStop(function(){
- ok( false, "ajaxStop" );
- }).ajaxSend(function(){
- ok( false, "ajaxSend" );
- }).ajaxComplete(function(){
- ok( false, "ajaxComplete" );
- }).ajaxError(function(){
- ok( false, "ajaxError" );
- }).ajaxSuccess(function(){
- ok( false, "ajaxSuccess" );
- });
-
- jQuery.xhr()
- .success(function(){ ok(true, "success"); })
- .error(function(){ ok(false, "error"); })
- .complete(function(){
- ok(true, "complete");
- setTimeout(function(){ start(); }, 13);
- })
- .open("GET", url("data/name.html")).send(undefined, false);
-});
-
test("jQuery.ajax - xml: non-namespace elements inside namespaced elements", function() {
expect(3);
stop();
@@ -707,6 +697,10 @@ test("jQuery.ajax - xml: non-namespace elements inside namespaced elements (over
equals( jQuery("jsconf", resp).length, 1, 'jsconf in responseXML' );
equals( jQuery("thing", resp).length, 2, 'things in responseXML' );
start();
+ },
+ error: function(_1,_2,error) {
+ ok( false, error );
+ start();
}
});
});
@@ -721,7 +715,7 @@ test("jQuery.ajax - HEAD requests", function() {
success: function(data, status, xhr){
var h = xhr.getAllResponseHeaders();
ok( /Date/i.test(h), 'No Date in HEAD response' );
-
+
jQuery.ajax({
url: url("data/name.html"),
data: { whip_it: "good" },
@@ -842,20 +836,20 @@ test("serialize()", function() {
'Check input serialization as query string');
equals( jQuery('#testForm').serialize(),
- 'T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
+ 'T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
'Check form serialization as query string');
equals( jQuery('#testForm :input').serialize(),
- 'T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
+ 'T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
'Check input serialization as query string');
equals( jQuery('#form, #testForm').serialize(),
- "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3&T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
+ "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3&T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
'Multiple form serialization as query string');
/* Temporarily disabled. Opera 10 has problems with form serialization.
equals( jQuery('#form, #testForm :input').serialize(),
- "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
+ "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
'Mixed form/input serialization as query string');
*/
jQuery("#html5email, #html5number").remove();
@@ -863,9 +857,9 @@ test("serialize()", function() {
test("jQuery.param()", function() {
expect(22);
-
+
equals( !jQuery.ajaxSettings.traditional, true, "traditional flag, falsy by default" );
-
+
var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
equals( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
@@ -880,13 +874,13 @@ test("jQuery.param()", function() {
params = {foo: { bar: 'baz', beep: 42, quux: 'All your base are belong to us' } };
equals( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" );
-
+
params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
equals( decodeURIComponent( jQuery.param(params) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=undefined&i[]=10&i[]=11&j=true&k=false&l[]=undefined&l[]=0&m=cowboy+hat?", "huge structure" );
-
+
params = { a: [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { b: [ 7, [ 8, 9 ], [ { c: 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { e: { f: { g: [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
equals( decodeURIComponent( jQuery.param(params) ), "a[]=0&a[1][]=1&a[1][]=2&a[2][]=3&a[2][1][]=4&a[2][1][]=5&a[2][2][]=6&a[3][b][]=7&a[3][b][1][]=8&a[3][b][1][]=9&a[3][b][2][0][c]=10&a[3][b][2][0][d]=11&a[3][b][3][0][]=12&a[3][b][4][0][0][]=13&a[3][b][5][e][f][g][]=14&a[3][b][5][e][f][g][1][]=15&a[3][b][]=16&a[]=17", "nested arrays" );
-
+
params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
equals( jQuery.param(params,true), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=undefined&l=0&m=cowboy+hat%3F", "huge structure, forced traditional" );
@@ -898,7 +892,7 @@ test("jQuery.param()", function() {
equals( jQuery.param({"foo": {"bar": {}} }), "foo%5Bbar%5D=", "Empty object param" );
jQuery.ajaxSetup({ traditional: true });
-
+
var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
equals( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
@@ -913,16 +907,16 @@ test("jQuery.param()", function() {
params = {"foo[bar]":"baz", "foo[beep]":42, "foo[quux]":"All your base are belong to us"};
equals( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" );
-
+
params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
equals( jQuery.param(params), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=undefined&l=0&m=cowboy+hat%3F", "huge structure" );
-
+
params = { a: [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { b: [ 7, [ 8, 9 ], [ { c: 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { e: { f: { g: [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
equals( jQuery.param(params), "a=0&a=1%2C2&a=3%2C4%2C5%2C6&a=%5Bobject+Object%5D&a=17", "nested arrays (not possible when jQuery.param.traditional == true)" );
-
+
params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
equals( decodeURIComponent( jQuery.param(params,false) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=undefined&i[]=10&i[]=11&j=true&k=false&l[]=undefined&l[]=0&m=cowboy+hat?", "huge structure, forced not traditional" );
-
+
params = { param1: null };
equals( jQuery.param(params,false), "param1=null", "Make sure that null params aren't traversed." );
});
@@ -971,7 +965,7 @@ test("pass-through request object", function() {
test("ajax cache", function () {
expect(18);
-
+
stop();
var count = 0;
@@ -1094,6 +1088,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();
@@ -1149,217 +1155,249 @@ test("jQuery.getScript(String, Function) - no callback", function() {
});
});
-test("jQuery.ajax() - JSONP, Local", function() {
- expect(9);
+jQuery.each( [ "Same Domain", "Cross Domain" ] , function( crossDomain , label ) {
- var count = 0;
- function plus(){ if ( ++count == 9 ) start(); }
+ test("jQuery.ajax() - JSONP, " + label, function() {
+ expect(17);
- 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();
- }
- });
+ var count = 0;
+ function plus(){ if ( ++count == 17 ) start(); }
- 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();
- }
- });
+ stop();
- 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();
- }
- });
-
- 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();
- }
});
});
@@ -1384,7 +1422,7 @@ test("jQuery.ajax() - script, Remote with POST", function() {
expect(3);
var base = window.location.href.replace(/[^\/]*$/, "");
-
+
stop();
jQuery.ajax({
@@ -1482,12 +1520,12 @@ test("jQuery.ajax() - json by content-type disabled with options", function() {
jQuery.ajax({
url: url("data/json.php"),
data: { header: "json", json: "array" },
- autoDataType: {
+ contents: {
json: false
},
success: function( text ) {
equals( typeof text , "string" , "json wasn't auto-determined" );
- var json = this.dataConverters["text => json"]( text );
+ var json = jQuery.parseJSON( text );
ok( json.length >= 2, "Check length");
equals( json[0].name, 'John', 'Check JSON: first, name' );
equals( json[0].age, 21, 'Check JSON: first, age' );
@@ -1525,7 +1563,7 @@ test("jQuery.getJSON(String, Function) - JSON object", function() {
test("jQuery.getJSON - Using Native JSON", function() {
expect(2);
-
+
var old = window.JSON;
JSON = {
parse: function(str){
@@ -1714,7 +1752,7 @@ test("data option: evaluate function values (#2806)", function() {
equals( result, "key=value" );
start();
}
- })
+ });
});
test("data option: empty bodies for non-GET requests", function() {
@@ -1727,7 +1765,7 @@ test("data option: empty bodies for non-GET requests", function() {
equals( result, "" );
start();
}
- })
+ });
});
test("jQuery.ajax - If-Modified-Since support", function() {
@@ -1740,19 +1778,19 @@ test("jQuery.ajax - If-Modified-Since support", function() {
jQuery.ajax({
url: url,
ifModified: true,
- success: function(data, status) {
+ success: function(data, status) {
equals(status, "success");
-
+
jQuery.ajax({
url: url,
ifModified: true,
- success: function(data, status) {
+ success: function(data, status) {
if ( data === "FAIL" ) {
ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
} else {
equals(status, "notmodified");
- ok(data == null, "response body should be empty")
+ ok(data == null, "response body should be empty");
}
start();
},
@@ -1787,19 +1825,19 @@ test("jQuery.ajax - Etag support", function() {
jQuery.ajax({
url: url,
ifModified: true,
- success: function(data, status) {
+ success: function(data, status) {
equals(status, "success");
-
+
jQuery.ajax({
url: url,
ifModified: true,
- success: function(data, status) {
+ success: function(data, status) {
if ( data === "FAIL" ) {
ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
} else {
equals(status, "notmodified");
- ok(data == null, "response body should be empty")
+ ok(data == null, "response body should be empty");
}
start();
},
@@ -1826,42 +1864,38 @@ test("jQuery.ajax - Etag support", function() {
test("jQuery ajax - failing cross-domain", function() {
expect( 2 );
-
+
stop();
-
+
var i = 2;
-
+
jQuery.ajax({
- url: 'http://somewebsitethatdoesnotexist.com',
+ 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(); }
});
-
+
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(); }
});
-
+
});
test("jQuery ajax - atom+xml", function() {
stop();
-
+
jQuery.ajax({
url: url( 'data/atom+xml.php' ),
success: function(){ ok( true , "success" ); },
error: function(){ ok( false , "error" ); },
complete: function() { start(); }
});
-
-});
-test("jQuery.ajax - active counter", function() {
- ok( jQuery.active == 0, "ajax active counter should be zero: " + jQuery.active );
});
test( "jQuery.ajax - Location object as url (#7531)", 1, function () {
@@ -1875,6 +1909,150 @@ 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 = 12;
+
+ expect( 20 );
+ 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 ) );
+
+ var testString = "";
+
+ jQuery.ajax( url( uri ), {
+ success: function( a , b , jXHR ) {
+ ok( isSuccess , "success" );
+ var statusCode = {};
+ statusCode[ jXHR.status ] = function() {
+ testString += "B";
+ };
+ jXHR.statusCode( statusCode );
+ testString += "A";
+ },
+ error: function( jXHR ) {
+ ok( ! isSuccess , "error" );
+ var statusCode = {};
+ statusCode[ jXHR.status ] = function() {
+ testString += "B";
+ };
+ jXHR.statusCode( statusCode );
+ testString += "A";
+ },
+ complete: function() {
+ strictEqual( testString , "AB" , "Test statusCode callbacks are ordered like " +
+ ( isSuccess ? "success" : "error" ) + " callbacks" );
+ countComplete();
+ }
+ } );
+
+ });
+});
+
+test("jQuery.ajax - transitive conversions", function() {
+
+ expect( 8 );
+
+ stop();
+
+ jQuery.when(
+
+ jQuery.ajax( url("data/json.php") , {
+ converters: {
+ "json myjson": function( data ) {
+ ok( true , "converter called" );
+ return data;
+ }
+ },
+ dataType: "myjson",
+ success: function() {
+ ok( true , "Transitive conversion worked" );
+ strictEqual( this.dataTypes[0] , "text" , "response was retrieved as text" );
+ strictEqual( this.dataTypes[1] , "myjson" , "request expected myjson dataType" );
+ }
+ }),
+
+ jQuery.ajax( url("data/json.php") , {
+ converters: {
+ "json myjson": function( data ) {
+ ok( true , "converter called (*)" );
+ return data;
+ }
+ },
+ contents: false, /* headers are wrong so we ignore them */
+ dataType: "* myjson",
+ success: function() {
+ ok( true , "Transitive conversion worked (*)" );
+ strictEqual( this.dataTypes[0] , "text" , "response was retrieved as text (*)" );
+ strictEqual( this.dataTypes[1] , "myjson" , "request expected myjson dataType (*)" );
+ }
+ })
+
+ ).then( start , start );
+
+});
+
+test("jQuery.ajax - active counter", function() {
+ ok( jQuery.active == 0, "ajax active counter should be zero: " + jQuery.active );
+});
+
}
//} \ No newline at end of file
diff --git a/test/unit/attributes.js b/test/unit/attributes.js
index f9506b30b..c58111de1 100644
--- a/test/unit/attributes.js
+++ b/test/unit/attributes.js
@@ -1,16 +1,16 @@
-module("attributes");
+module("attributes", { teardown: moduleTeardown });
var bareObj = function(value) { return value; };
var functionReturningObj = function(value) { return (function() { return value; }); };
test("jQuery.props: itegrity test", function() {
-
+
expect(1);
-
+
// This must be maintained and equal jQuery.props
- // Ensure that accidental or erroneous property
+ // Ensure that accidental or erroneous property
// overwrites don't occur
- // This is simply for better code coverage and future proofing.
+ // This is simply for better code coverage and future proofing.
var propsShouldBe = {
"for": "htmlFor",
"class": "className",
@@ -23,7 +23,7 @@ test("jQuery.props: itegrity test", function() {
usemap: "useMap",
frameborder: "frameBorder"
};
-
+
same(propsShouldBe, jQuery.props, "jQuery.props passes integrity check");
});
@@ -33,7 +33,7 @@ test("attr(String)", function() {
// This one sometimes fails randomly ?!
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' );
@@ -255,30 +255,30 @@ test("attr(String, Object)", function() {
test("attr(jquery_method)", function(){
expect(7);
-
+
var $elem = jQuery("<div />"),
elem = $elem[0];
-
- // one at a time
+
+ // one at a time
$elem.attr({'html': 'foo'}, true);
equals( elem.innerHTML, 'foo', 'attr(html)');
-
+
$elem.attr({'text': 'bar'}, true);
equals( elem.innerHTML, 'bar', 'attr(text)');
-
+
$elem.attr({'css': {color:'red'}}, true);
ok( /^(#ff0000|red)$/i.test(elem.style.color), 'attr(css)');
-
+
$elem.attr({'height': 10}, true);
equals( elem.style.height, '10px', 'attr(height)');
-
+
// Multiple attributes
-
+
$elem.attr({
width:10,
css:{ paddingLeft:1, paddingRight:1 }
}, true);
-
+
equals( elem.style.width, '10px', 'attr({...})');
equals( elem.style.paddingLeft, '1px', 'attr({...})');
equals( elem.style.paddingRight, '1px', 'attr({...})');
@@ -491,7 +491,7 @@ test( "val(Array of Numbers) (Bug #7123)", function() {
ok( elements[1].checked, "Second element was checked" );
ok( !elements[2].checked, "Third element was unchecked" );
ok( !elements[3].checked, "Fourth element remained unchecked" );
-
+
elements.remove();
});
@@ -672,7 +672,7 @@ test("removeClass(Function) with incoming value", function() {
ok( !$divs.is('.test'), "Remove Class" );
- QUnit.reset();
+ QUnit.reset();
});
var testToggleClass = function(valueObj) {
@@ -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() {
@@ -740,21 +738,21 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() {
var e = jQuery("#firstp"), old = e.attr("class");
ok( !e.is(".test"), "Assert class not present" );
-
+
e.toggleClass(function(i, val) {
equals( val, old, "Make sure the incoming value is correct." );
return "test";
});
ok( e.is(".test"), "Assert class present" );
-
+
old = e.attr("class");
-
+
e.toggleClass(function(i, val) {
equals( val, old, "Make sure the incoming value is correct." );
return "test";
});
ok( !e.is(".test"), "Assert class not present" );
-
+
old = e.attr("class");
// class name with a boolean
@@ -764,18 +762,18 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() {
return "test";
}, false );
ok( !e.is(".test"), "Assert class not present" );
-
+
old = e.attr("class");
-
+
e.toggleClass(function(i, val, state) {
equals( val, old, "Make sure the incoming value is correct." );
equals( state, true, "Make sure that the state is passed in." );
return "test";
}, true );
ok( e.is(".test"), "Assert class present" );
-
+
old = e.attr("class");
-
+
e.toggleClass(function(i, val, state) {
equals( val, old, "Make sure the incoming value is correct." );
equals( state, false, "Make sure that the state is passed in." );
@@ -785,30 +783,30 @@ 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() {
expect(17);
-
+
var jq = jQuery("<p>Hi</p>"), x = jq[0];
-
+
jq.addClass("hi");
equals( x.className, "hi", "Check single added class" );
-
+
jq.addClass("foo bar");
equals( x.className, "hi foo bar", "Check more added classes" );
-
+
jq.removeClass();
equals( x.className, "", "Remove all classes" );
-
+
jq.addClass("hi foo bar");
jq.removeClass("foo");
equals( x.className, "hi bar", "Check removal of one class" );
-
+
ok( jq.hasClass("hi"), "Check has1" );
ok( jq.hasClass("bar"), "Check has2" );
-
+
var jq = jQuery("<p class='class1\nclass2\tcla.ss3\n\rclass4'></p>");
ok( jq.hasClass("class1"), "Check hasClass with line feed" );
ok( jq.is(".class1"), "Check is with line feed" );
@@ -817,7 +815,7 @@ test("addClass, removeClass, hasClass", function() {
ok( jq.hasClass("cla.ss3"), "Check hasClass with dot" );
ok( jq.hasClass("class4"), "Check hasClass with carriage return" );
ok( jq.is(".class4"), "Check is with carriage return" );
-
+
jq.removeClass("class2");
ok( jq.hasClass("class2")==false, "Check the class has been properly removed" );
jq.removeClass("cla");
diff --git a/test/unit/core.js b/test/unit/core.js
index 9f9078a49..7638554ac 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() {
@@ -151,7 +162,7 @@ test("selector state", function() {
test = jQuery("#main").eq(0);
equals( test.selector, "#main.slice(0,1)", "#main eq Selector" );
equals( test.context, document, "#main eq Context" );
-
+
var d = "<div />";
equals(
jQuery(d).appendTo(jQuery(d)).selector,
@@ -253,38 +264,38 @@ test("isPlainObject", function() {
// The use case that we want to match
ok(jQuery.isPlainObject({}), "{}");
-
+
// Not objects shouldn't be matched
ok(!jQuery.isPlainObject(""), "string");
ok(!jQuery.isPlainObject(0) && !jQuery.isPlainObject(1), "number");
ok(!jQuery.isPlainObject(true) && !jQuery.isPlainObject(false), "boolean");
ok(!jQuery.isPlainObject(null), "null");
ok(!jQuery.isPlainObject(undefined), "undefined");
-
+
// Arrays shouldn't be matched
ok(!jQuery.isPlainObject([]), "array");
-
+
// Instantiated objects shouldn't be matched
ok(!jQuery.isPlainObject(new Date), "new Date");
-
+
var fn = function(){};
-
+
// Functions shouldn't be matched
ok(!jQuery.isPlainObject(fn), "fn");
-
+
// Again, instantiated objects shouldn't be matched
ok(!jQuery.isPlainObject(new fn), "new fn (no methods)");
-
+
// Makes the function a little more realistic
// (and harder to detect, incidentally)
fn.prototype = {someMethod: function(){}};
-
+
// Again, instantiated objects shouldn't be matched
ok(!jQuery.isPlainObject(new fn), "new fn");
// DOM Element
ok(!jQuery.isPlainObject(document.createElement("div")), "DOM Element");
-
+
// Window
ok(!jQuery.isPlainObject(window), "window");
@@ -298,7 +309,7 @@ test("isPlainObject", function() {
document.body.removeChild( iframe );
start();
};
-
+
var doc = iframe.contentDocument || iframe.contentWindow.document;
doc.open();
doc.write("<body onload='window.parent.iframeDone(Object);'>");
@@ -659,7 +670,7 @@ test("jQuery.merge()", function() {
// Fixed at [5998], #3641
same( parse([-2,-1], [0,1,2]), [-2,-1,0,1,2], "Second array including a zero (falsy)");
-
+
// After fixing #5527
same( parse([], [null, undefined]), [null, undefined], "Second array including null and undefined values");
same( parse({length:0}, [1,2]), {length:2, 0:1, 1:2}, "First array like");
@@ -694,7 +705,7 @@ test("jQuery.extend(Object, Object)", function() {
equals( deep1.foo2, document, "Make sure that a deep clone was not attempted on the document" );
ok( jQuery.extend(true, {}, nestedarray).arr !== arr, "Deep extend of object must clone child array" );
-
+
// #5991
ok( jQuery.isArray( jQuery.extend(true, { arr: {} }, nestedarray).arr ), "Cloned array heve to be an Array" );
ok( jQuery.isPlainObject( jQuery.extend(true, { arr: arr }, { arr: {} }).arr ), "Cloned object heve to be an plain object" );
@@ -715,13 +726,13 @@ test("jQuery.extend(Object, Object)", function() {
empty = {};
jQuery.extend(true, empty, optionsWithCustomObject);
ok( empty.foo && empty.foo.date === customObject, "Custom objects copy correctly (no methods)" );
-
+
// Makes the class a little more realistic
myKlass.prototype = { someMethod: function(){} };
empty = {};
jQuery.extend(true, empty, optionsWithCustomObject);
ok( empty.foo && empty.foo.date === customObject, "Custom objects copy correctly" );
-
+
var ret = jQuery.extend(true, { foo: 4 }, { foo: new Number(5) } );
ok( ret.foo == 5, "Wrapped numbers copy correctly" );
@@ -849,10 +860,10 @@ test("jQuery.makeArray", function(){
test("jQuery.isEmptyObject", function(){
expect(2);
-
+
equals(true, jQuery.isEmptyObject({}), "isEmptyObject on empty object literal" );
equals(false, jQuery.isEmptyObject({a:1}), "isEmptyObject on non-empty object literal" );
-
+
// What about this ?
// equals(true, jQuery.isEmptyObject(null), "isEmptyObject on null" );
});
@@ -883,23 +894,23 @@ test("jQuery.proxy", function(){
test("jQuery.parseJSON", function(){
expect(8);
-
+
equals( jQuery.parseJSON(), null, "Nothing in, null out." );
equals( jQuery.parseJSON( null ), null, "Nothing in, null out." );
equals( jQuery.parseJSON( "" ), null, "Nothing in, null out." );
-
+
same( jQuery.parseJSON("{}"), {}, "Plain object parsing." );
same( jQuery.parseJSON('{"test":1}'), {"test":1}, "Plain object parsing." );
same( jQuery.parseJSON('\n{"test":1}'), {"test":1}, "Make sure leading whitespaces are handled." );
-
+
try {
jQuery.parseJSON("{a:1}");
ok( false, "Test malformed JSON string." );
} catch( e ) {
ok( true, "Test malformed JSON string." );
}
-
+
try {
jQuery.parseJSON("{'a':1}");
ok( false, "Test malformed JSON string." );
@@ -907,3 +918,290 @@ test("jQuery.parseJSON", function(){
ok( true, "Test malformed JSON string." );
}
});
+
+test("jQuery._Deferred()", function() {
+
+ expect( 10 );
+
+ var deferred,
+ object,
+ test;
+
+ deferred = jQuery._Deferred();
+
+ test = false;
+
+ deferred.done( function( value ) {
+ equals( value , "value" , "Test pre-resolve callback" );
+ test = true;
+ } );
+
+ deferred.resolve( "value" );
+
+ ok( test , "Test pre-resolve callbacks called right away" );
+
+ test = false;
+
+ deferred.done( function( value ) {
+ equals( value , "value" , "Test post-resolve callback" );
+ test = true;
+ } );
+
+ ok( test , "Test post-resolve callbacks called right away" );
+
+ deferred.cancel();
+
+ test = true;
+
+ deferred.done( function() {
+ ok( false , "Cancel was ignored" );
+ test = false;
+ } );
+
+ ok( test , "Test cancel" );
+
+ deferred = jQuery._Deferred().resolve();
+
+ try {
+ deferred.done( function() {
+ throw "Error";
+ } , function() {
+ ok( true , "Test deferred do not cancel on exception" );
+ } );
+ } catch( e ) {
+ strictEqual( e , "Error" , "Test deferred propagates exceptions");
+ deferred.done();
+ }
+
+ test = "";
+ deferred = jQuery._Deferred().done( function() {
+
+ test += "A";
+
+ }, function() {
+
+ test += "B";
+
+ } ).resolve();
+
+ strictEqual( test , "AB" , "Test multiple done parameters" );
+
+ test = "";
+
+ deferred.done( function() {
+
+ deferred.done( function() {
+
+ test += "C";
+
+ } );
+
+ test += "A";
+
+ }, function() {
+
+ test += "B";
+ } );
+
+ strictEqual( test , "ABC" , "Test done callbacks order" );
+
+ deferred = jQuery._Deferred();
+
+ deferred.resolveWith( jQuery , [ document ] ).done( function( doc ) {
+ ok( this === jQuery && arguments.length === 1 && doc === document , "Test fire context & args" );
+ });
+});
+
+test("jQuery.Deferred()", function() {
+
+ expect( 10 );
+
+ jQuery.Deferred( function( defer ) {
+ strictEqual( this , defer , "Defer passed as this & first argument" );
+ this.resolve( "done" );
+ }).then( function( value ) {
+ strictEqual( value , "done" , "Passed function executed" );
+ });
+
+ jQuery.Deferred().resolve().then( function() {
+ ok( true , "Success on resolve" );
+ }, function() {
+ ok( false , "Error on resolve" );
+ });
+
+ jQuery.Deferred().reject().then( function() {
+ ok( false , "Success on reject" );
+ }, 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( 23 );
+
+ // Some other objects
+ jQuery.each( {
+
+ "an empty string": "",
+ "a non-empty string": "some string",
+ "zero": 0,
+ "a number other than zero": 1,
+ "true": true,
+ "false": false,
+ "null": null,
+ "undefined": undefined,
+ "a plain object": {}
+
+ } , function( message , value ) {
+
+ ok( jQuery.isFunction( jQuery.when( value ).then( function( resolveValue ) {
+ strictEqual( resolveValue , value , "Test the promise was resolved with " + message );
+ } ).promise ) , "Test " + message + " triggers the creation of a new Promise" );
+
+ } );
+
+ 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++ ) {
+ jQuery.when( cache || jQuery.Deferred( function() {
+ this.resolve( i );
+ }) ).then( function( value ) {
+ strictEqual( value , 1 , "Function executed" + ( i > 1 ? " only once" : "" ) );
+ cache = value;
+ }, function() {
+ ok( false , "Fail called" );
+ });
+ }
+});
+
+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 cddd90256..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);
@@ -178,24 +178,24 @@ if ( !jQuery.support.opacity ) {
test("css(String, Function)", function() {
expect(3);
-
+
var sizes = ["10px", "20px", "30px"];
-
- jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" +
- "<div class='cssFunction'></div>" +
+
+ jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" +
+ "<div class='cssFunction'></div>" +
"<div class='cssFunction'></div></div>")
.appendTo("body");
-
+
var index = 0;
-
+
jQuery("#cssFunctionTest div").css("font-size", function() {
var size = sizes[index];
index++;
return size;
});
-
+
index = 0;
-
+
jQuery("#cssFunctionTest div").each(function() {
var computedSize = jQuery(this).css("font-size")
var expectedSize = sizes[index]
@@ -208,24 +208,24 @@ test("css(String, Function)", function() {
test("css(String, Function) with incoming value", function() {
expect(3);
-
+
var sizes = ["10px", "20px", "30px"];
-
- jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" +
- "<div class='cssFunction'></div>" +
+
+ jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" +
+ "<div class='cssFunction'></div>" +
"<div class='cssFunction'></div></div>")
.appendTo("body");
-
+
var index = 0;
-
+
jQuery("#cssFunctionTest div").css("font-size", function() {
var size = sizes[index];
index++;
return size;
});
-
+
index = 0;
-
+
jQuery("#cssFunctionTest div").css("font-size", function(i, computedSize) {
var expectedSize = sizes[index]
equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize );
@@ -238,61 +238,61 @@ test("css(String, Function) with incoming value", function() {
test("css(Object) where values are Functions", function() {
expect(3);
-
+
var sizes = ["10px", "20px", "30px"];
-
- jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" +
- "<div class='cssFunction'></div>" +
+
+ jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" +
+ "<div class='cssFunction'></div>" +
"<div class='cssFunction'></div></div>")
.appendTo("body");
var index = 0;
-
+
jQuery("#cssFunctionTest div").css({fontSize: function() {
var size = sizes[index];
index++;
return size;
}});
-
+
index = 0;
-
+
jQuery("#cssFunctionTest div").each(function() {
var computedSize = jQuery(this).css("font-size")
var expectedSize = sizes[index]
equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize );
index++;
});
-
+
jQuery("#cssFunctionTest").remove();
});
test("css(Object) where values are Functions with incoming values", function() {
expect(3);
-
+
var sizes = ["10px", "20px", "30px"];
-
- jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" +
- "<div class='cssFunction'></div>" +
+
+ jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" +
+ "<div class='cssFunction'></div>" +
"<div class='cssFunction'></div></div>")
.appendTo("body");
var index = 0;
-
+
jQuery("#cssFunctionTest div").css({fontSize: function() {
var size = sizes[index];
index++;
return size;
}});
-
+
index = 0;
-
+
jQuery("#cssFunctionTest div").css({"font-size": function(i, computedSize) {
var expectedSize = sizes[index]
equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize );
index++;
return computedSize;
}});
-
+
jQuery("#cssFunctionTest").remove();
});
@@ -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 1a0f84c1f..889fc2da3 100644
--- a/test/unit/data.js
+++ b/test/unit/data.js
@@ -1,22 +1,159 @@
-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)
+
+ 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);
- obj = {};
- jQuery.data(obj, 'test');
- equals( jQuery.expando in obj, false, "jQuery.data(obj,key) did not add an expando to the object" );
+ 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 ];
+ }
- 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." );
+ 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() {
@@ -37,53 +174,11 @@ test("jQuery.acceptData", function() {
ok( !jQuery.acceptData( applet ), "applet" );
});
-test("jQuery.data", function() {
- expect(15);
- var div = document.createElement("div");
-
- ok( jQuery.data(div, "test") === undefined, "Check for no data exists" );
-
- jQuery.data(div, "test", "success");
- equals( jQuery.data(div, "test"), "success", "Check for added data" );
-
- ok( jQuery.data(div, "notexist") === undefined, "Check for no data exists" );
-
- var data = jQuery.data(div);
- same( data, { "test": "success" }, "Return complete data set" );
-
- jQuery.data(div, "test", "overwritten");
- equals( jQuery.data(div, "test"), "overwritten", "Check for overwritten data" );
-
- jQuery.data(div, "test", undefined);
- equals( jQuery.data(div, "test"), "overwritten", "Check that data wasn't removed");
-
- jQuery.data(div, "test", null);
- ok( jQuery.data(div, "test") === null, "Check for null data");
-
- 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" );
-
- var obj = {};
- jQuery.data( obj, "prop", true );
-
- ok( obj.prop, "Data is being stored on the object" );
- equals( jQuery.data( obj, "prop" ), true, "Make sure the right value is retrieved" );
-
- 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." );
-});
-
test(".data()", function() {
expect(5);
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" );
@@ -92,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() {
@@ -179,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() {
@@ -191,7 +289,7 @@ test("data-* attributes", function() {
var div = jQuery("<div>"),
child = jQuery("<div data-myobj='old data' data-ignored=\"DOM\" data-other='test'></div>"),
dummy = jQuery("<div data-myobj='old data' data-ignored=\"DOM\" data-other='test'></div>");
-
+
equals( div.data("attr"), undefined, "Check for non-existing data-attr attribute" );
div.attr("data-attr", "exists");
@@ -199,10 +297,12 @@ test("data-* attributes", function() {
div.attr("data-attr", "exists2");
equals( div.data("attr"), "exists", "Check that updates to data- don't update .data()" );
-
+
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");
@@ -214,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-." );
@@ -249,7 +351,7 @@ test("data-* attributes", function() {
.attr("data-space", " ")
.attr("data-null", "null")
.attr("data-string", "test");
-
+
strictEqual( child.data('true'), true, "Primitive true read from attribute");
strictEqual( child.data('false'), false, "Primitive false read from attribute");
strictEqual( child.data('five'), 5, "Primitive number read from attribute");
@@ -265,7 +367,7 @@ test("data-* attributes", function() {
strictEqual( child.data('string'), "test", "Typical string read from attribute");
child.remove();
-
+
// tests from metadata plugin
function testData(index, elem) {
switch (index) {
@@ -289,10 +391,10 @@ test("data-* attributes", function() {
ok(false, ["Assertion failed on index ", index, ", with data ", data].join(''));
}
}
-
+
var metadata = '<ol><li class="test test2" data-foo="bar" data-bar="baz" data-arr="[1,2]">Some stuff</li><li class="test test2" data-test="bar" data-bar="baz">Some stuff</li><li class="test test2" data-zoooo="bar" data-bar=\'{"test":"baz"}\'>Some stuff</li><li class="test test2" data-number=true data-stuff="[2,8]">Some stuff</li></ol>',
elem = jQuery(metadata).appendTo('#main');
-
+
elem.find("li").each(testData);
elem.remove();
});
@@ -305,16 +407,20 @@ test(".data(Object)", function() {
div.data({ "test": "in", "test2": "in2" });
equals( div.data("test"), "in", "Verify setting an object in data" );
equals( div.data("test2"), "in2", "Verify setting an object in data" );
-
+
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");
@@ -324,13 +430,12 @@ test("jQuery.removeData", function() {
jQuery.removeData( div );
ok( !jQuery.data(div, "test2"), "Make sure that the data property no longer exists." );
ok( !div[ jQuery.expando ], "Make sure the expando no longer exists, as well." );
-
+
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" );
@@ -356,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 8255bf325..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() {
@@ -45,13 +47,13 @@ test("width() with function", function() {
test("width() with function args", function() {
expect( 2 );
-
+
var $div = jQuery("#nothiddendiv");
$div.width( 30 ).width(function(i, width) {
equals( width, 30, "Make sure previous value is corrrect." );
return width + 1;
});
-
+
equals( $div.width(), 31, "Make sure value was modified correctly." );
});
@@ -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() {
@@ -92,13 +96,13 @@ test("height() with function", function() {
test("height() with function args", function() {
expect( 2 );
-
+
var $div = jQuery("#nothiddendiv");
$div.height( 30 ).height(function(i, height) {
equals( height, 30, "Make sure previous value is corrrect." );
return height + 1;
});
-
+
equals( $div.height(), 31, "Make sure value was modified correctly." );
});
@@ -112,13 +116,13 @@ test("innerWidth()", function() {
border: "2px solid #fff",
width: 30
});
-
+
equals($div.innerWidth(), 30, "Test with margin and border");
$div.css("padding", "20px");
equals($div.innerWidth(), 70, "Test with margin, border and padding");
$div.hide();
equals($div.innerWidth(), 70, "Test hidden div");
-
+
// reset styles
$div.css({ display: "", border: "", padding: "", width: "", height: "" });
@@ -126,11 +130,14 @@ 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() {
expect(4);
-
+
var $div = jQuery("#nothiddendiv");
// set styles
$div.css({
@@ -138,13 +145,13 @@ test("innerHeight()", function() {
border: "2px solid #fff",
height: 30
});
-
+
equals($div.innerHeight(), 30, "Test with margin and border");
$div.css("padding", "20px");
equals($div.innerHeight(), 70, "Test with margin, border and padding");
$div.hide();
equals($div.innerHeight(), 70, "Test hidden div");
-
+
// reset styles
$div.css({ display: "", border: "", padding: "", width: "", height: "" });
@@ -152,14 +159,17 @@ 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() {
expect(7);
-
+
var $div = jQuery("#nothiddendiv");
$div.css("width", 30);
-
+
equals($div.outerWidth(), 30, "Test with only width set");
$div.css("padding", "20px");
equals($div.outerWidth(), 70, "Test with padding");
@@ -171,7 +181,7 @@ test("outerWidth()", function() {
equals($div.outerWidth(true), 94, "Test with padding, border and margin with margin option");
$div.hide();
equals($div.outerWidth(true), 94, "Test hidden div with padding, border and margin with margin option");
-
+
// reset styles
$div.css({ position: "", display: "", border: "", padding: "", width: "", height: "" });
@@ -179,14 +189,17 @@ 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() {
expect(7);
-
+
var $div = jQuery("#nothiddendiv");
$div.css("height", 30);
-
+
equals($div.outerHeight(), 30, "Test with only width set");
$div.css("padding", "20px");
equals($div.outerHeight(), 70, "Test with padding");
@@ -197,7 +210,7 @@ test("outerHeight()", function() {
equals($div.outerHeight(true), 94, "Test with padding, border and margin with margin option");
$div.hide();
equals($div.outerHeight(true), 94, "Test hidden div with padding, border and margin with margin option");
-
+
// reset styles
$div.css({ display: "", border: "", padding: "", width: "", height: "" });
@@ -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 74b336f1f..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" );
@@ -64,7 +64,7 @@ test("show()", function() {
// #show-tests * is set display: none in CSS
jQuery("#main").append('<div id="show-tests"><div><p><a href="#"></a></p><code></code><pre></pre><span></span></div><table><thead><tr><th></th></tr></thead><tbody><tr><td></td></tr></tbody></table><ul><li></li></ul></div><table id="test-table"></table>');
-
+
var old = jQuery("#test-table").show().css("display") !== "table";
jQuery("#test-table").remove();
@@ -130,6 +130,45 @@ test("show(Number) - other displays", function() {
});
});
+
+
+// Supports #7397
+test("Persist correct display value", function() {
+ expect(3);
+ QUnit.reset();
+ stop();
+
+ // #show-tests * is set display: none in CSS
+ jQuery("#main").append('<div id="show-tests"><span style="position:absolute;">foo</span></div>');
+
+ var $span = jQuery("#show-tests span"),
+ displayNone = $span.css("display"),
+ display = '', num = 0;
+
+ $span.show();
+
+ display = $span.css("display");
+
+ $span.hide();
+
+ $span.fadeIn(100, function() {
+
+ equals($span.css("display"), display, "Expecting display: " + display);
+
+ $span.fadeOut(100, function () {
+
+ equals($span.css("display"), displayNone, "Expecting display: " + displayNone);
+
+ $span.fadeIn(100, function() {
+
+ equals($span.css("display"), display, "Expecting display: " + display);
+
+ start();
+ });
+ });
+ });
+});
+
test("animate(Hash, Object, Function)", function() {
expect(1);
stop();
@@ -155,7 +194,7 @@ test("animate block as inline width/height", function() {
var span = jQuery("<span>").css("display", "inline-block").appendTo("body"),
expected = span.css("display");
-
+
span.remove();
if ( jQuery.support.inlineBlockNeedsLayout || expected === "inline-block" ) {
@@ -181,7 +220,7 @@ test("animate native inline width/height", function() {
var span = jQuery("<span>").css("display", "inline-block").appendTo("body"),
expected = span.css("display");
-
+
span.remove();
if ( jQuery.support.inlineBlockNeedsLayout || expected === "inline-block" ) {
@@ -364,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." );
@@ -394,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();
@@ -407,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);
@@ -417,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();
@@ -442,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();
@@ -469,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();
@@ -497,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" );
@@ -521,6 +565,23 @@ jQuery.checkOverflowDisplay = function(){
start();
}
+test("support negative values < -10000 (bug #7193)", function () {
+ expect(1);
+ stop();
+
+ jQuery.extend(jQuery.fx.step, {
+ "marginBottom": function(fx) {
+ equals( fx.cur(), -11000, "Element has margin-bottom of -11000" );
+ delete jQuery.fx.step.marginBottom;
+ }
+ });
+
+ jQuery("#main").css("marginBottom", "-11000px").animate({ marginBottom: "-11001px" }, {
+ duration: 1,
+ complete: start
+ });
+});
+
test("JS Overflow and Display", function() {
expect(2);
stop();
@@ -681,6 +742,9 @@ jQuery.each( {
}
}
+ // manually remove generated element
+ jQuery(this).remove();
+
start();
});
});
@@ -707,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();
}
@@ -773,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;
@@ -839,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" );
@@ -850,11 +915,11 @@ test("hide hidden elements, with animation (bug #7141)", function() {
expect(3);
QUnit.reset();
stop();
-
+
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 a647e5f3b..e4caee82a 100644
--- a/test/unit/event.js
+++ b/test/unit/event.js
@@ -1,23 +1,23 @@
-module("event");
+module("event", { teardown: moduleTeardown });
test("null or undefined handler", function() {
expect(2);
// Supports Fixes bug #7229
try {
-
+
jQuery("#firstp").click(null);
-
+
ok(true, "Passing a null handler will not throw an exception");
- } catch (e) {}
+ } catch (e) {}
try {
-
+
jQuery("#firstp").click(undefined);
-
+
ok(true, "Passing an undefined handler will not throw an exception");
- } catch (e) {}
+ } catch (e) {}
});
test("bind(), with data", function() {
@@ -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() {
@@ -175,7 +184,7 @@ test("bind(), no data", function() {
test("bind/one/unbind(Object)", function(){
expect(6);
-
+
var clickCounter = 0, mouseoverCounter = 0;
function handler(event) {
if (event.type == "click")
@@ -183,18 +192,18 @@ test("bind/one/unbind(Object)", function(){
else if (event.type == "mouseover")
mouseoverCounter++;
};
-
+
function handlerWithData(event) {
if (event.type == "click")
clickCounter += event.data;
else if (event.type == "mouseover")
mouseoverCounter += event.data;
};
-
+
function trigger(){
$elem.trigger("click").trigger("mouseover");
}
-
+
var $elem = jQuery("#firstp")
// Regular bind
.bind({
@@ -206,16 +215,16 @@ test("bind/one/unbind(Object)", function(){
click:handlerWithData,
mouseover:handlerWithData
}, 2 );
-
+
trigger();
-
+
equals( clickCounter, 3, "bind(Object)" );
equals( mouseoverCounter, 3, "bind(Object)" );
-
+
trigger();
equals( clickCounter, 4, "bind(Object)" );
equals( mouseoverCounter, 4, "bind(Object)" );
-
+
jQuery("#firstp").unbind({
click:handler,
mouseover:handler
@@ -228,10 +237,10 @@ test("bind/one/unbind(Object)", function(){
test("live/die(Object), delegate/undelegate(String, Object)", function() {
expect(6);
-
+
var clickCounter = 0, mouseoverCounter = 0,
$p = jQuery("#firstp"), $a = $p.find("a:first");
-
+
var events = {
click: function( event ) {
clickCounter += ( event.data || 1 );
@@ -240,26 +249,26 @@ test("live/die(Object), delegate/undelegate(String, Object)", function() {
mouseoverCounter += ( event.data || 1 );
}
};
-
+
function trigger() {
$a.trigger("click").trigger("mouseover");
}
-
+
$a.live( events );
$p.delegate( "a", events, 2 );
-
+
trigger();
equals( clickCounter, 3, "live/delegate" );
equals( mouseoverCounter, 3, "live/delegate" );
-
+
$p.undelegate( "a", events );
-
+
trigger();
equals( clickCounter, 4, "undelegate" );
equals( mouseoverCounter, 4, "undelegate" );
-
+
$a.die( events );
-
+
trigger();
equals( clickCounter, 4, "die" );
equals( mouseoverCounter, 4, "die" );
@@ -267,12 +276,12 @@ test("live/die(Object), delegate/undelegate(String, Object)", function() {
test("live/delegate immediate propagation", function() {
expect(2);
-
+
var $p = jQuery("#firstp"), $a = $p.find("a:first"), lastClick;
-
+
lastClick = "";
- $a.live( "click", function(e) {
- lastClick = "click1";
+ $a.live( "click", function(e) {
+ lastClick = "click1";
e.stopImmediatePropagation();
});
$a.live( "click", function(e) {
@@ -281,10 +290,10 @@ test("live/delegate immediate propagation", function() {
$a.trigger( "click" );
equals( lastClick, "click1", "live stopImmediatePropagation" );
$a.die( "click" );
-
+
lastClick = "";
- $p.delegate( "a", "click", function(e) {
- lastClick = "click1";
+ $p.delegate( "a", "click", function(e) {
+ lastClick = "click1";
e.stopImmediatePropagation();
});
$p.delegate( "a", "click", function(e) {
@@ -295,10 +304,53 @@ test("live/delegate immediate propagation", function() {
$p.undelegate( "click" );
});
+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 );
+ $jq[0].dispatchEvent(e);
+ }
+ else if ( $jq[0].click ) {
+ $jq[0].click(); // IE
+ }
+ };
+ $anchor2.click(function(e) {
+ e.preventDefault();
+ });
+ $main.delegate("#foo", "click", function(e) {
+ 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" );
+ $main.undelegate( "click" );
+ $anchor2.click(function(e) {
+ // Let the default action occur
+ });
+ $main.delegate("#foo", "click", function(e) {
+ equals( e.isDefaultPrevented(), false, "isDefaultPrevented false passed to bubbled event" );
+ });
+ fakeClick( $anchor2 );
+ $anchor2.unbind( "click" );
+ $main.undelegate( "click" );
+});
+
test("bind(), iframes", function() {
// events don't work with iframes, see #939 - this test fails in IE because of contentDocument
var doc = jQuery("#loadediframe").contents();
-
+
jQuery("div", doc).bind("click", function() {
ok( true, "Binding to element inside iframe" );
}).click().unbind('click');
@@ -360,7 +412,7 @@ test("bind(), namespaced events, cloned events", function() {
test("bind(), multi-namespaced events", function() {
expect(6);
-
+
var order = [
"click.test.abc",
"click.test.abc",
@@ -369,7 +421,7 @@ test("bind(), multi-namespaced events", function() {
"click.test",
"custom.test2"
];
-
+
function check(name, msg){
same(name, order.shift(), msg);
}
@@ -389,7 +441,7 @@ test("bind(), multi-namespaced events", function() {
jQuery("#firstp").bind("click.test.abc",function(e){
check("click.test.abc", "Namespaced click triggered");
});
-
+
// Those would not trigger/unbind (#5303)
jQuery("#firstp").trigger("click.a.test");
jQuery("#firstp").unbind("click.a.test");
@@ -453,7 +505,7 @@ test("bind(), make sure order is maintained", function() {
elem.unbind("click");
});
-
+
test("bind(), with different this object", function() {
expect(4);
var thisObject = { myThis: true },
@@ -465,12 +517,12 @@ test("bind(), with different this object", function() {
equals( this, thisObject, "bind() with different this object and data" );
equals( event.data, data, "bind() with different this object and data" );
};
-
+
jQuery("#firstp")
.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() {
@@ -490,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() {
@@ -512,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." );
@@ -531,29 +586,31 @@ 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() {
expect( 0 );
-
+
var $elem = jQuery("#firstp"),
message;
function error(){
ok( false, message );
}
-
+
message = "unbind passing function";
$elem.bind('error1', error).unbind('error1',error).triggerHandler('error1');
-
+
message = "unbind all from event";
$elem.bind('error1', error).unbind('error1').triggerHandler('error1');
-
+
message = "unbind all";
$elem.bind('error1', error).unbind().triggerHandler('error1');
-
+
message = "unbind many with function";
$elem.bind('error1 error2',error)
.unbind('error1 error2', error )
@@ -563,7 +620,7 @@ test("unbind(type)", function() {
$elem.bind('error1 error2',error)
.unbind('error1 error2')
.trigger('error1').triggerHandler('error2');
-
+
message = "unbind without a type or handler";
$elem.bind("error1 error2.test",error)
.unbind()
@@ -572,7 +629,7 @@ test("unbind(type)", function() {
test("unbind(eventObject)", function() {
expect(4);
-
+
var $elem = jQuery("#firstp"),
num;
@@ -581,7 +638,7 @@ test("unbind(eventObject)", function() {
$elem.trigger('foo').triggerHandler('bar');
equals( num, expected, "Check the right handlers are triggered" );
}
-
+
$elem
// This handler shouldn't be unbound
.bind('foo', function(){
@@ -595,14 +652,14 @@ test("unbind(eventObject)", function() {
.bind('bar', function(){
num += 4;
});
-
+
assert( 7 );
assert( 5 );
-
+
$elem.unbind('bar');
assert( 1 );
-
- $elem.unbind();
+
+ $elem.unbind();
assert( 0 );
});
@@ -626,34 +683,42 @@ 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();
-
+
var counter = 0;
jQuery('#firstp')[0].onclick = function(event) {
counter++;
};
jQuery('#firstp').click();
equals( counter, 1, "Check that click, triggers onclick event handler also" );
-
+
var clickCounter = 0;
jQuery('#simon1')[0].onclick = function(event) {
clickCounter++;
};
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() {
@@ -688,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() {
@@ -728,10 +797,10 @@ test("trigger(type, [data], [fn])", function() {
pass = false;
}
ok( pass, "Trigger focus on hidden element" );
-
+
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;
}
@@ -768,28 +837,28 @@ test("jQuery.Event.currentTarget", function(){
test("trigger(eventObject, [data], [fn])", function() {
expect(25);
-
+
var $parent = jQuery('<div id="par" />').hide().appendTo('body'),
$child = jQuery('<p id="child">foo</p>').appendTo( $parent );
-
- var event = jQuery.Event("noNew");
+
+ var event = jQuery.Event("noNew");
ok( event != window, "Instantiate jQuery.Event without the 'new' keyword" );
equals( event.type, "noNew", "Verify its type" );
-
+
equals( event.isDefaultPrevented(), false, "Verify isDefaultPrevented" );
equals( event.isPropagationStopped(), false, "Verify isPropagationStopped" );
equals( event.isImmediatePropagationStopped(), false, "Verify isImmediatePropagationStopped" );
-
+
event.preventDefault();
equals( event.isDefaultPrevented(), true, "Verify isDefaultPrevented" );
event.stopPropagation();
equals( event.isPropagationStopped(), true, "Verify isPropagationStopped" );
-
+
event.isPropagationStopped = function(){ return false };
event.stopImmediatePropagation();
equals( event.isPropagationStopped(), true, "Verify isPropagationStopped" );
equals( event.isImmediatePropagationStopped(), true, "Verify isPropagationStopped" );
-
+
$parent.bind('foo',function(e){
// Tries bubbling
equals( e.type, 'foo', 'Verify event type when passed passing an event object' );
@@ -797,72 +866,72 @@ test("trigger(eventObject, [data], [fn])", function() {
equals( e.currentTarget.id, 'par', 'Verify event.target when passed passing an event object' );
equals( e.secret, 'boo!', 'Verify event object\'s custom attribute when passed passing an event object' );
});
-
+
// test with an event object
event = new jQuery.Event("foo");
event.secret = 'boo!';
$child.trigger(event);
-
+
// test with a literal object
$child.trigger({type:'foo', secret:'boo!'});
-
+
$parent.unbind();
function error(){
ok( false, "This assertion shouldn't be reached");
}
-
+
$parent.bind('foo', error );
-
+
$child.bind('foo',function(e, a, b, c ){
equals( arguments.length, 4, "Check arguments length");
equals( a, 1, "Check first custom argument");
equals( b, 2, "Check second custom argument");
equals( c, 3, "Check third custom argument");
-
+
equals( e.isDefaultPrevented(), false, "Verify isDefaultPrevented" );
equals( e.isPropagationStopped(), false, "Verify isPropagationStopped" );
equals( e.isImmediatePropagationStopped(), false, "Verify isImmediatePropagationStopped" );
-
+
// Skips both errors
e.stopImmediatePropagation();
-
+
return "result";
});
-
+
// We should add this back in when we want to test the order
// in which event handlers are iterated.
//$child.bind('foo', error );
-
+
event = new jQuery.Event("foo");
$child.trigger( event, [1,2,3] ).unbind();
equals( event.result, "result", "Check event.result attribute");
-
+
// Will error if it bubbles
$child.triggerHandler('foo');
-
+
$child.unbind();
$parent.unbind().remove();
});
test("jQuery.Event.currentTarget", function(){
expect(1);
-
+
var counter = 0,
$elem = jQuery('<button>a</button>').click(function(e){
equals( e.currentTarget, this, "Check currentTarget on "+(counter++?"native":"fake") +" event" );
});
-
+
// Fake event
$elem.trigger('click');
-
+
// Cleanup
$elem.unbind();
});
test("toggle(Function, Function, ...)", function() {
expect(16);
-
+
var count = 0,
fn1 = function(e) { count++; },
fn2 = function(e) { count--; },
@@ -885,7 +954,7 @@ test("toggle(Function, Function, ...)", function() {
});
return false;
}).click().click().click();
-
+
var turn = 0;
var fns = [
function(){
@@ -898,7 +967,7 @@ test("toggle(Function, Function, ...)", function() {
turn = 3;
}
];
-
+
var $div = jQuery("<div>&nbsp;</div>").toggle( fns[0], fns[1], fns[2] );
$div.click();
equals( turn, 1, "Trying toggle with 3 functions, attempt 1 yields 1");
@@ -910,11 +979,14 @@ test("toggle(Function, Function, ...)", function() {
equals( turn, 1, "Trying toggle with 3 functions, attempt 4 yields 1");
$div.click();
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/>");
@@ -930,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() {
@@ -1030,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");
@@ -1052,7 +1127,7 @@ test(".live()/.die()", function() {
// Test binding with different this object, event data, and trigger data
jQuery("#foo").live("click", true, jQuery.proxy(function(e, data){
equals( e.data, true, "live with with different this object, event data, and trigger data" );
- equals( this.foo, "bar", "live with with different this object, event data, and trigger data" );
+ equals( this.foo, "bar", "live with with different this object, event data, and trigger data" );
equals( data, true, "live with with different this object, event data, and trigger data")
}, { foo: "bar" }));
jQuery("#foo").trigger("click", true).die("click");
@@ -1113,25 +1188,25 @@ test(".live()/.die()", function() {
// Cleanup
jQuery("#nothiddendiv").die("foo", callback);
-
+
// Make sure we don't loose the target by DOM modifications
// after the bubble already reached the liveHandler
var livec = 0, elemDiv = jQuery("#nothiddendivchild").html('<span></span>').get(0);
-
+
jQuery("#nothiddendivchild").live("click", function(e){ jQuery("#nothiddendivchild").html(''); });
jQuery("#nothiddendivchild").live("click", function(e){ if(e.target) {livec++;} });
-
+
jQuery("#nothiddendiv span").click();
equals( jQuery("#nothiddendiv span").length, 0, "Verify that first handler occurred and modified the DOM." );
equals( livec, 1, "Verify that second handler occurred even with nuked target." );
-
+
// Cleanup
jQuery("#nothiddendivchild").die("click");
// Verify that .live() ocurs and cancel buble in the same order as
// we would expect .bind() and .click() without delegation
var lived = 0, livee = 0;
-
+
// bind one pair in one order
jQuery('span#liveSpan1 a').live('click', function(){ lived++; return false; });
jQuery('span#liveSpan1').live('click', function(){ livee++; });
@@ -1149,22 +1224,22 @@ test(".live()/.die()", function() {
jQuery('span#liveSpan2 a').click();
equals( lived, 1, "Verify that only one first handler occurred." );
equals( livee, 0, "Verify that second handler doesn't." );
-
+
// Cleanup
jQuery("span#liveSpan1 a").die("click")
jQuery("span#liveSpan1").die("click");
jQuery("span#liveSpan2 a").die("click");
jQuery("span#liveSpan2").die("click");
-
+
// Test this, target and currentTarget are correct
- jQuery('span#liveSpan1').live('click', function(e){
+ jQuery('span#liveSpan1').live('click', function(e){
equals( this.id, 'liveSpan1', 'Check the this within a live handler' );
equals( e.currentTarget.id, 'liveSpan1', 'Check the event.currentTarget within a live handler' );
equals( e.target.nodeName.toUpperCase(), 'A', 'Check the event.target within a live handler' );
});
-
+
jQuery('span#liveSpan1 a').click();
-
+
jQuery('span#liveSpan1').die('click');
// Work with deep selectors
@@ -1240,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(){
@@ -1298,18 +1376,18 @@ test("live with change", function(){
expect(8);
var selectChange = 0, checkboxChange = 0;
-
+
var select = jQuery("select[name='S1']")
select.live("change", function() {
selectChange++;
});
-
- var checkbox = jQuery("#check2"),
+
+ var checkbox = jQuery("#check2"),
checkboxFunction = function(){
checkboxChange++;
}
checkbox.live("change", checkboxFunction);
-
+
// test click on select
// second click that changed it
@@ -1317,17 +1395,17 @@ test("live with change", function(){
select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
select.trigger("change");
equals( selectChange, 1, "Change on click." );
-
+
// test keys on select
selectChange = 0;
select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
select.trigger("change");
equals( selectChange, 1, "Change on keyup." );
-
+
// test click on checkbox
checkbox.trigger("change");
equals( checkboxChange, 1, "Change on checkbox." );
-
+
// test blur/focus on text
var text = jQuery("#name"), textChange = 0, oldTextVal = text.val();
text.live("change", function() {
@@ -1340,7 +1418,7 @@ test("live with change", function(){
text.val(oldTextVal);
text.die("change");
-
+
// test blur/focus on password
var password = jQuery("#name"), passwordChange = 0, oldPasswordVal = password.val();
password.live("change", function() {
@@ -1353,9 +1431,9 @@ test("live with change", function(){
password.val(oldPasswordVal);
password.die("change");
-
+
// make sure die works
-
+
// die all changes
selectChange = 0;
select.die("change");
@@ -1367,7 +1445,7 @@ test("live with change", function(){
select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
select.trigger("change");
equals( selectChange, 0, "Die on keyup works." );
-
+
// die specific checkbox
checkbox.die("change", checkboxFunction);
checkbox.trigger("change");
@@ -1376,7 +1454,7 @@ test("live with change", function(){
test("live with submit", function() {
var count1 = 0, count2 = 0;
-
+
jQuery("#testForm").live("submit", function(ev) {
count1++;
ev.preventDefault();
@@ -1390,7 +1468,7 @@ test("live with submit", function() {
jQuery("#testForm input[name=sub1]").submit();
equals( count1, 1, "Verify form submit." );
equals( count2, 1, "Verify body submit." );
-
+
jQuery("#testForm").die("submit");
jQuery("body").die("submit");
});
@@ -1543,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");
@@ -1568,7 +1646,7 @@ test(".delegate()/.undelegate()", function() {
// Test binding with different this object, event data, and trigger data
jQuery("#body").delegate("#foo", "click", true, jQuery.proxy(function(e, data){
equals( e.data, true, "delegate with with different this object, event data, and trigger data" );
- equals( this.foo, "bar", "delegate with with different this object, event data, and trigger data" );
+ equals( this.foo, "bar", "delegate with with different this object, event data, and trigger data" );
equals( data, true, "delegate with with different this object, event data, and trigger data")
}, { foo: "bar" }));
jQuery("#foo").trigger("click", true);
@@ -1630,25 +1708,25 @@ test(".delegate()/.undelegate()", function() {
// Cleanup
jQuery("#body").undelegate("#nothiddendiv", "foo", callback);
-
+
// Make sure we don't loose the target by DOM modifications
// after the bubble already reached the liveHandler
var livec = 0, elemDiv = jQuery("#nothiddendivchild").html('<span></span>').get(0);
-
+
jQuery("#body").delegate("#nothiddendivchild", "click", function(e){ jQuery("#nothiddendivchild").html(''); });
jQuery("#body").delegate("#nothiddendivchild", "click", function(e){ if(e.target) {livec++;} });
-
+
jQuery("#nothiddendiv span").click();
equals( jQuery("#nothiddendiv span").length, 0, "Verify that first handler occurred and modified the DOM." );
equals( livec, 1, "Verify that second handler occurred even with nuked target." );
-
+
// Cleanup
jQuery("#body").undelegate("#nothiddendivchild", "click");
// Verify that .live() ocurs and cancel buble in the same order as
// we would expect .bind() and .click() without delegation
var lived = 0, livee = 0;
-
+
// bind one pair in one order
jQuery("#body").delegate('span#liveSpan1 a', 'click', function(){ lived++; return false; });
jQuery("#body").delegate('span#liveSpan1', 'click', function(){ livee++; });
@@ -1666,19 +1744,19 @@ test(".delegate()/.undelegate()", function() {
jQuery('span#liveSpan2 a').click();
equals( lived, 1, "Verify that only one first handler occurred." );
equals( livee, 0, "Verify that second handler doesn't." );
-
+
// Cleanup
jQuery("#body").undelegate("click");
-
+
// Test this, target and currentTarget are correct
- jQuery("#body").delegate('span#liveSpan1', 'click', function(e){
+ jQuery("#body").delegate('span#liveSpan1', 'click', function(e){
equals( this.id, 'liveSpan1', 'Check the this within a delegate handler' );
equals( e.currentTarget.id, 'liveSpan1', 'Check the event.currentTarget within a delegate handler' );
equals( e.target.nodeName.toUpperCase(), 'A', 'Check the event.target within a delegate handler' );
});
-
+
jQuery('span#liveSpan1 a').click();
-
+
jQuery("#body").undelegate('span#liveSpan1', 'click');
// Work with deep selectors
@@ -1754,18 +1832,18 @@ test("delegate with change", function(){
expect(8);
var selectChange = 0, checkboxChange = 0;
-
+
var select = jQuery("select[name='S1']");
jQuery("#body").delegate("select[name='S1']", "change", function() {
selectChange++;
});
-
- var checkbox = jQuery("#check2"),
+
+ var checkbox = jQuery("#check2"),
checkboxFunction = function(){
checkboxChange++;
}
jQuery("#body").delegate("#check2", "change", checkboxFunction);
-
+
// test click on select
// second click that changed it
@@ -1773,17 +1851,17 @@ test("delegate with change", function(){
select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
select.trigger("change");
equals( selectChange, 1, "Change on click." );
-
+
// test keys on select
selectChange = 0;
select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
select.trigger("change");
equals( selectChange, 1, "Change on keyup." );
-
+
// test click on checkbox
checkbox.trigger("change");
equals( checkboxChange, 1, "Change on checkbox." );
-
+
// test blur/focus on text
var text = jQuery("#name"), textChange = 0, oldTextVal = text.val();
jQuery("#body").delegate("#name", "change", function() {
@@ -1796,7 +1874,7 @@ test("delegate with change", function(){
text.val(oldTextVal);
jQuery("#body").die("change");
-
+
// test blur/focus on password
var password = jQuery("#name"), passwordChange = 0, oldPasswordVal = password.val();
jQuery("#body").delegate("#name", "change", function() {
@@ -1809,9 +1887,9 @@ test("delegate with change", function(){
password.val(oldPasswordVal);
jQuery("#body").undelegate("#name", "change");
-
+
// make sure die works
-
+
// die all changes
selectChange = 0;
jQuery("#body").undelegate("select[name='S1']", "change");
@@ -1823,7 +1901,7 @@ test("delegate with change", function(){
select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
select.trigger("change");
equals( selectChange, 0, "Die on keyup works." );
-
+
// die specific checkbox
jQuery("#body").undelegate("#check2", "change", checkboxFunction);
checkbox.trigger("change");
@@ -1832,7 +1910,7 @@ test("delegate with change", function(){
test("delegate with submit", function() {
var count1 = 0, count2 = 0;
-
+
jQuery("#body").delegate("#testForm", "submit", function(ev) {
count1++;
ev.preventDefault();
@@ -1846,7 +1924,7 @@ test("delegate with submit", function() {
jQuery("#testForm input[name=sub1]").submit();
equals( count1, 1, "Verify form submit." );
equals( count2, 1, "Verify body submit." );
-
+
jQuery("#body").undelegate();
jQuery(document).undelegate();
});
@@ -1872,27 +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." );
-});
-
-test("focusin bubbles", function() {
- //create an input and focusin on it
- var input = jQuery("<input/>"), order = 0;
-
- input.prependTo("body");
-
- jQuery("body").bind("focusin.focusinBubblesTest",function(){
- equals(1,order++,"focusin on the body second")
- });
-
- input.bind("focusin.focusinBubblesTest",function(){
- equals(0,order++,"focusin on the element first")
- });
-
- input[0].focus();
- input.remove();
-
- jQuery("body").unbind("focusin.focusinBubblesTest");
+ ok( !jQuery._data(window, "__events__"), "Make sure all the events are gone." );
});
/*
diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js
index d49029eb8..37234d86d 100644
--- a/test/unit/manipulation.js
+++ b/test/unit/manipulation.js
@@ -1,4 +1,7 @@
-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"); };
var bareObj = function(value) { return value; };
var functionReturningObj = function(value) { return (function() { return value; }); };
@@ -51,7 +54,7 @@ test("text(Function) with incoming value", function() {
});
var testWrap = function(val) {
- expect(18);
+ expect(19);
var defaultText = 'Try them out:'
var result = jQuery('#first').wrap(val( '<div class="red"><span></span></div>' )).text();
equals( defaultText, result, 'Check for wrapping of on-the-fly html' );
@@ -80,10 +83,20 @@ var testWrap = function(val) {
equals( jQuery("#nonnodes > i").text(), j.text(), "Check node,textnode,comment wraps doesn't hurt text" );
// Try wrapping a disconnected node
+ var cacheLength = 0;
+ for (var i in jQuery.cache) {
+ cacheLength++;
+ }
+
j = jQuery("<label/>").wrap(val( "<li/>" ));
equals( j[0].nodeName.toUpperCase(), "LABEL", "Element is a label" );
equals( j[0].parentNode.nodeName.toUpperCase(), "LI", "Element has been wrapped" );
+ for (i in jQuery.cache) {
+ cacheLength--;
+ }
+ equals(cacheLength, 0, "No memory leak in jQuery.cache (bug #7165)");
+
// Wrap an element containing a text node
j = jQuery("<span/>").wrap("<div>test</div>");
equals( j[0].previousSibling.nodeType, 3, "Make sure the previous node is a text element" );
@@ -102,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() {
@@ -382,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;
@@ -395,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 () {
@@ -413,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() {
@@ -856,7 +872,7 @@ test("replaceAll(String|Element|Array&lt;Element&gt;|jQuery)", function() {
});
test("clone()", function() {
- expect(36);
+ expect(37);
equals( 'This is a normal link: Yahoo', jQuery('#en').text(), 'Assert text for #en' );
var clone = jQuery('#yahoo').clone();
equals( 'Try them out:Yahoo', jQuery('#first').append(clone).text(), 'Check for clone' );
@@ -881,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,
@@ -914,10 +946,16 @@ test("clone()", function() {
equals( clone.html(), div.html(), "Element contents cloned" );
equals( clone[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" );
- div = jQuery("<div/>").data({ a: true, b: true });
- div = div.clone(true);
- equals( div.data("a"), true, "Data cloned." );
- equals( div.data("b"), true, "Data cloned." );
+ div = jQuery("<div/>").data({ a: true });
+ 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/";
@@ -930,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);
@@ -1126,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() {
@@ -1232,3 +1298,20 @@ test("jQuery.cleanData", function() {
return div;
}
});
+
+test("jQuery.buildFragment - no plain-text caching (Bug #6779)", function() {
+ expect(1);
+
+ // DOM manipulation fails if added text matches an Object method
+ var $f = jQuery( "<div />" ).appendTo( "#main" ),
+ bad = [ "start-", "toString", "hasOwnProperty", "append", "here&there!", "-end" ];
+
+ for ( var i=0; i < bad.length; i++ ) {
+ try {
+ $f.append( bad[i] );
+ }
+ catch(e) {}
+ }
+ equals($f.text(), bad.join(''), "Cached strings that match Object properties");
+ $f.remove();
+});
diff --git a/test/unit/offset.js b/test/unit/offset.js
index 879753181..329d69f95 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);
@@ -13,9 +13,9 @@ var supportsScroll = false;
testoffset("absolute"/* in iframe */, function($, iframe) {
expect(4);
-
+
var doc = iframe.document, tests;
-
+
// force a scroll value on the main window
// this insures that the results will be wrong
// if the offset method is using the scroll offset
@@ -28,7 +28,7 @@ testoffset("absolute"/* in iframe */, function($, iframe) {
}
window.scrollTo(1, 1);
-
+
// get offset
tests = [
{ id: '#absolute-1', top: 1, left: 1 }
@@ -47,16 +47,16 @@ testoffset("absolute"/* in iframe */, function($, iframe) {
equals( jQuery( this.id, doc ).position().top, this.top, "jQuery('" + this.id + "').position().top" );
equals( jQuery( this.id, doc ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
});
-
+
forceScroll.remove();
});
testoffset("absolute", function( jQuery ) {
expect(178);
-
+
// get offset tests
var tests = [
- { id: '#absolute-1', top: 1, left: 1 },
+ { id: '#absolute-1', top: 1, left: 1 },
{ id: '#absolute-1-1', top: 5, left: 5 },
{ id: '#absolute-1-1-1', top: 9, left: 9 },
{ id: '#absolute-2', top: 20, left: 20 }
@@ -65,8 +65,8 @@ testoffset("absolute", function( jQuery ) {
equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
});
-
-
+
+
// get position
tests = [
{ id: '#absolute-1', top: 0, left: 0 },
@@ -78,13 +78,13 @@ testoffset("absolute", function( jQuery ) {
equals( jQuery( this.id ).position().top, this.top, "jQuery('" + this.id + "').position().top" );
equals( jQuery( this.id ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
});
-
+
// test #5781
var offset = jQuery( '#positionTest' ).offset({ top: 10, left: 10 }).offset();
equals( offset.top, 10, "Setting offset on element with position absolute but 'auto' values." )
equals( offset.left, 10, "Setting offset on element with position absolute but 'auto' values." )
-
-
+
+
// set offset
tests = [
{ id: '#absolute-2', top: 30, left: 30 },
@@ -108,9 +108,9 @@ testoffset("absolute", function( jQuery ) {
jQuery( this.id ).offset({ top: this.top, left: this.left });
equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
-
+
var top = this.top, left = this.left;
-
+
jQuery( this.id ).offset(function(i, val){
equals( val.top, top, "Verify incoming top position." );
equals( val.left, left, "Verify incoming top position." );
@@ -118,13 +118,13 @@ testoffset("absolute", function( jQuery ) {
});
equals( jQuery( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + (this.top + 1) + " })" );
equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + " })" );
-
+
jQuery( this.id )
.offset({ left: this.left + 2 })
.offset({ top: this.top + 2 });
equals( jQuery( this.id ).offset().top, this.top + 2, "Setting one property at a time." );
equals( jQuery( this.id ).offset().left, this.left + 2, "Setting one property at a time." );
-
+
jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
jQuery( this ).css({
top: props.top + 1,
@@ -138,10 +138,10 @@ testoffset("absolute", function( jQuery ) {
testoffset("relative", function( jQuery ) {
expect(60);
-
+
// IE is collapsing the top margin of 1px
var ie = jQuery.browser.msie && parseInt( jQuery.browser.version, 10 ) < 8;
-
+
// get offset
var tests = [
{ id: '#relative-1', top: ie ? 6 : 7, left: 7 },
@@ -152,8 +152,8 @@ testoffset("relative", function( jQuery ) {
equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
});
-
-
+
+
// get position
tests = [
{ id: '#relative-1', top: ie ? 5 : 6, left: 6 },
@@ -164,8 +164,8 @@ testoffset("relative", function( jQuery ) {
equals( jQuery( this.id ).position().top, this.top, "jQuery('" + this.id + "').position().top" );
equals( jQuery( this.id ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
});
-
-
+
+
// set offset
tests = [
{ id: '#relative-2', top: 200, left: 50 },
@@ -185,7 +185,7 @@ testoffset("relative", function( jQuery ) {
jQuery( this.id ).offset({ top: this.top, left: this.left });
equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
-
+
jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
jQuery( this ).css({
top: props.top + 1,
@@ -199,10 +199,10 @@ testoffset("relative", function( jQuery ) {
testoffset("static", function( jQuery ) {
expect(80);
-
+
// IE is collapsing the top margin of 1px
var ie = jQuery.browser.msie && parseInt( jQuery.browser.version, 10 ) < 8;
-
+
// get offset
var tests = [
{ id: '#static-1', top: ie ? 6 : 7, left: 7 },
@@ -214,8 +214,8 @@ testoffset("static", function( jQuery ) {
equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
});
-
-
+
+
// get position
tests = [
{ id: '#static-1', top: ie ? 5 : 6, left: 6 },
@@ -227,8 +227,8 @@ testoffset("static", function( jQuery ) {
equals( jQuery( this.id ).position().top, this.top, "jQuery('" + this.top + "').position().top" );
equals( jQuery( this.id ).position().left, this.left, "jQuery('" + this.left +"').position().left" );
});
-
-
+
+
// set offset
tests = [
{ id: '#static-2', top: 200, left: 200 },
@@ -252,7 +252,7 @@ testoffset("static", function( jQuery ) {
jQuery( this.id ).offset({ top: this.top, left: this.left });
equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
-
+
jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
jQuery( this ).css({
top: props.top + 1,
@@ -266,9 +266,9 @@ testoffset("static", function( jQuery ) {
testoffset("fixed", function( jQuery ) {
expect(28);
-
+
jQuery.offset.initialize();
-
+
var tests = [
{ id: '#fixed-1', top: 1001, left: 1001 },
{ id: '#fixed-2', top: 1021, left: 1021 }
@@ -288,7 +288,7 @@ testoffset("fixed", function( jQuery ) {
ok( true, 'Fixed position is not supported' );
}
});
-
+
tests = [
{ id: '#fixed-1', top: 100, left: 100 },
{ id: '#fixed-1', top: 0, left: 0 },
@@ -297,13 +297,13 @@ testoffset("fixed", function( jQuery ) {
{ id: '#fixed-2', top: 0, left: 0 },
{ id: '#fixed-2', top: -5, left: -5 }
];
-
+
jQuery.each( tests, function() {
if ( jQuery.offset.supportsFixedPosition ) {
jQuery( this.id ).offset({ top: this.top, left: this.left });
equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
-
+
jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
jQuery( this ).css({
top: props.top + 1,
@@ -324,38 +324,38 @@ testoffset("fixed", function( jQuery ) {
testoffset("table", function( jQuery ) {
expect(4);
-
+
equals( jQuery('#table-1').offset().top, 6, "jQuery('#table-1').offset().top" );
equals( jQuery('#table-1').offset().left, 6, "jQuery('#table-1').offset().left" );
-
+
equals( jQuery('#th-1').offset().top, 10, "jQuery('#th-1').offset().top" );
equals( jQuery('#th-1').offset().left, 10, "jQuery('#th-1').offset().left" );
});
testoffset("scroll", function( jQuery, win ) {
expect(16);
-
+
var ie = jQuery.browser.msie && parseInt( jQuery.browser.version, 10 ) < 8;
-
+
// IE is collapsing the top margin of 1px
equals( jQuery('#scroll-1').offset().top, ie ? 6 : 7, "jQuery('#scroll-1').offset().top" );
equals( jQuery('#scroll-1').offset().left, 7, "jQuery('#scroll-1').offset().left" );
-
+
// IE is collapsing the top margin of 1px
equals( jQuery('#scroll-1-1').offset().top, ie ? 9 : 11, "jQuery('#scroll-1-1').offset().top" );
equals( jQuery('#scroll-1-1').offset().left, 11, "jQuery('#scroll-1-1').offset().left" );
-
-
+
+
// scroll offset tests .scrollTop/Left
equals( jQuery('#scroll-1').scrollTop(), 5, "jQuery('#scroll-1').scrollTop()" );
equals( jQuery('#scroll-1').scrollLeft(), 5, "jQuery('#scroll-1').scrollLeft()" );
-
+
equals( jQuery('#scroll-1-1').scrollTop(), 0, "jQuery('#scroll-1-1').scrollTop()" );
equals( jQuery('#scroll-1-1').scrollLeft(), 0, "jQuery('#scroll-1-1').scrollLeft()" );
-
+
// equals( jQuery('body').scrollTop(), 0, "jQuery('body').scrollTop()" );
// equals( jQuery('body').scrollLeft(), 0, "jQuery('body').scrollTop()" );
-
+
win.name = "test";
if ( !supportsScroll ) {
@@ -367,11 +367,11 @@ testoffset("scroll", function( jQuery, win ) {
} else {
equals( jQuery(win).scrollTop(), 1000, "jQuery(window).scrollTop()" );
equals( jQuery(win).scrollLeft(), 1000, "jQuery(window).scrollLeft()" );
-
+
equals( jQuery(win.document).scrollTop(), 1000, "jQuery(document).scrollTop()" );
equals( jQuery(win.document).scrollLeft(), 1000, "jQuery(document).scrollLeft()" );
}
-
+
// test jQuery using parent window/document
// jQuery reference here is in the iframe
window.scrollTo(0,0);
@@ -383,7 +383,7 @@ testoffset("scroll", function( jQuery, win ) {
testoffset("body", function( jQuery ) {
expect(2);
-
+
equals( jQuery('body').offset().top, 1, "jQuery('#body').offset().top" );
equals( jQuery('body').offset().left, 1, "jQuery('#body').offset().left" );
});
@@ -423,11 +423,11 @@ test("offsetParent", function(){
});
function testoffset(name, fn) {
-
+
test(name, function() {
// pause execution for now
stop();
-
+
// load fixture in iframe
var iframe = loadFixture(),
win = iframe.contentWindow,
@@ -443,7 +443,7 @@ function testoffset(name, fn) {
}
}, 15 );
});
-
+
function loadFixture() {
var src = './data/offset/' + name + '.html?' + parseInt( Math.random()*1000, 10 ),
iframe = jQuery('<iframe />').css({
diff --git a/test/unit/queue.js b/test/unit/queue.js
index 79b753c11..31e587db2 100644
--- a/test/unit/queue.js
+++ b/test/unit/queue.js
@@ -1,11 +1,11 @@
-module("queue");
+module("queue", { teardown: moduleTeardown });
test("queue() with other types",function() {
expect(9);
var counter = 0;
-
+
var $div = jQuery({});
-
+
$div
.queue('foo',function(){
equals( ++counter, 1, "Dequeuing" );
@@ -21,26 +21,26 @@ test("queue() with other types",function() {
.queue('foo',function(){
equals( ++counter, 4, "Dequeuing" );
});
-
+
equals( $div.queue('foo').length, 4, "Testing queue length" );
-
+
$div.dequeue('foo');
-
+
equals( counter, 3, "Testing previous call to dequeue" );
equals( $div.queue('foo').length, 1, "Testing queue length" );
-
+
$div.dequeue('foo');
-
+
equals( counter, 4, "Testing previous call to dequeue" );
equals( $div.queue('foo').length, 0, "Testing queue length" );
});
test("queue(name) passes in the next item in the queue as a parameter", function() {
expect(2);
-
+
var div = jQuery({});
var counter = 0;
-
+
div.queue("foo", function(next) {
equals(++counter, 1, "Dequeueing");
next();
@@ -50,16 +50,16 @@ test("queue(name) passes in the next item in the queue as a parameter", function
}).queue("bar", function() {
equals(++counter, 3, "Other queues are not triggered by next()")
});
-
+
div.dequeue("foo");
});
test("queue(name) passes in the next item in the queue as a parameter", function() {
expect(2);
-
+
var div = jQuery({});
var counter = 0;
-
+
div.queue("foo", function(next) {
equals(++counter, 1, "Dequeueing");
next();
@@ -69,17 +69,17 @@ test("queue(name) passes in the next item in the queue as a parameter", function
}).queue("bar", function() {
equals(++counter, 3, "Other queues are not triggered by next()")
});
-
+
div.dequeue("foo");
});
test("queue() passes in the next item in the queue as a parameter to fx queues", function() {
expect(2);
stop();
-
+
var div = jQuery({});
var counter = 0;
-
+
div.queue(function(next) {
equals(++counter, 1, "Dequeueing");
var self = this;
@@ -111,10 +111,10 @@ test("delay()", function() {
test("clearQueue(name) clears the queue", function() {
expect(1);
-
+
var div = jQuery({});
var counter = 0;
-
+
div.queue("foo", function(next) {
counter++;
jQuery(this).clearQueue("foo");
@@ -122,18 +122,18 @@ test("clearQueue(name) clears the queue", function() {
}).queue("foo", function(next) {
counter++;
});
-
+
div.dequeue("foo");
-
+
equals(counter, 1, "the queue was cleared");
});
test("clearQueue() clears the fx queue", function() {
expect(1);
-
+
var div = jQuery({});
var counter = 0;
-
+
div.queue(function(next) {
counter++;
var self = this;
@@ -141,8 +141,8 @@ test("clearQueue() clears the fx queue", function() {
}).queue(function(next) {
counter++;
});
-
+
equals(counter, 1, "the queue was cleared");
-
+
div.removeData();
});
diff --git a/test/unit/selector.js b/test/unit/selector.js
index 6ec20bc40..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);
@@ -22,7 +22,7 @@ test("element", function() {
same( jQuery("div").find("p").get(), q("firstp","ap","sndp","en","sap","first"), "Finding elements with a context." );
same( jQuery("#form").find("select").get(), q("select1","select2","select3","select4","select5"), "Finding selects with a context." );
-
+
ok( jQuery("#length").length, '&lt;input name="length"&gt; cannot be found under IE, see #945' );
ok( jQuery("#lengthtest input").length, '&lt;input name="length"&gt; cannot be found under IE, see #945' );
@@ -58,17 +58,18 @@ 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 );
}
}
-
+
broken( "Broken Selector", "[", [] );
broken( "Broken Selector", "(", [] );
broken( "Broken 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", [] );
@@ -90,32 +112,35 @@ test("id", function() {
t( "Multiple ID selectors using UTF8", "#台北Táiběi, #台北", ["台北Táiběi","台北"] );
t( "Descendant ID selector using UTF8", "div #台北", ["台北"] );
t( "Child ID selector using UTF8", "form > #台北", ["台北"] );
-
+
t( "Escaped ID", "#foo\\:bar", ["foo:bar"] );
t( "Escaped ID", "#test\\.foo\\[5\\]bar", ["test.foo[5]bar"] );
t( "Descendant escaped ID", "div #foo\\:bar", ["foo:bar"] );
t( "Descendant escaped ID", "div #test\\.foo\\[5\\]bar", ["test.foo[5]bar"] );
t( "Child escaped ID", "form > #foo\\:bar", ["foo:bar"] );
t( "Child escaped ID", "form > #test\\.foo\\[5\\]bar", ["test.foo[5]bar"] );
-
+
t( "ID Selector, child ID present", "#form > #radio1", ["radio1"] ); // bug #267
t( "ID Selector, not an ancestor ID", "#form #first", [] );
t( "ID Selector, not a child ID", "#form > #option1a", [] );
-
+
t( "All Children of ID", "#foo > *", ["sndp", "en", "sap"] );
t( "All Children of ID with no children", "#firstUL > *", [] );
-
+
var a = jQuery('<div><a name="tName1">tName1 A</a><a name="tName2">tName2 A</a><div id="tName1">tName1 Div</div></div>').appendTo('#main');
equals( jQuery("#tName1")[0].id, 'tName1', "ID selector with same value for a name attribute" );
equals( jQuery("#tName2").length, 0, "ID selector non-existing but name attribute on an A tag" );
a.remove();
t( "ID Selector on Form with an input that has a name of 'id'", "#lengthtest", ["lengthtest"] );
-
+
t( "ID selector with non-existant ancestor", "#asdfasdf #foobar", [] ); // bug #986
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"] );
@@ -134,7 +159,7 @@ test("class", function() {
same( jQuery(".blog", "p").get(), q("mark", "simon"), "Finding elements with a context." );
same( jQuery(".blog", jQuery("p")).get(), q("mark", "simon"), "Finding elements with a context." );
same( jQuery("p").find(".blog").get(), q("mark", "simon"), "Finding elements with a context." );
-
+
t( "Class selector using UTF8", ".台北Táiběi", ["utf8class1"] );
//t( "Class selector using UTF8", ".台北", ["utf8class1","utf8class2"] );
t( "Class selector using UTF8", ".台北Táiběi.台北", ["utf8class1"] );
@@ -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";
@@ -194,7 +219,7 @@ test("name", function() {
test("multiple", function() {
expect(4);
-
+
t( "Comma Support", "h2, p", ["qunit-banner","qunit-userAgent","firstp","ap","sndp","en","sap","first"]);
t( "Comma Support", "h2 , p", ["qunit-banner","qunit-userAgent","firstp","ap","sndp","en","sap","first"]);
t( "Comma Support", "h2 , p", ["qunit-banner","qunit-userAgent","firstp","ap","sndp","en","sap","first"]);
@@ -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,12 +267,13 @@ 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"] );
t( "Attribute Exists", "a[ title ]", ["google"] );
-
+
t( "Attribute Equals", "a[rel='bookmark']", ["simon1"] );
t( "Attribute Equals", 'a[rel="bookmark"]', ["simon1"] );
t( "Attribute Equals", "a[rel=bookmark]", ["simon1"] );
@@ -263,13 +294,13 @@ test("attributes", function() {
t( "Attribute containing []", "input[name$='[bar]']", ["hidden2"] );
t( "Attribute containing []", "input[name$='foo[bar]']", ["hidden2"] );
t( "Attribute containing []", "input[name*='foo[bar]']", ["hidden2"] );
-
+
t( "Multiple Attribute Equals", "#form input[type='radio'], #form input[type='hidden']", ["radio1", "radio2", "hidden1"] );
t( "Multiple Attribute Equals", "#form input[type='radio'], #form input[type=\"hidden\"]", ["radio1", "radio2", "hidden1"] );
t( "Multiple Attribute Equals", "#form input[type='radio'], #form input[type=hidden]", ["radio1", "radio2", "hidden1"] );
-
+
t( "Attribute selector using UTF8", "span[lang=中文]", ["台北"] );
-
+
t( "Attribute Begins With", "a[href ^= 'http://www']", ["google","yahoo"] );
t( "Attribute Ends With", "a[href $= 'org/']", ["mark"] );
t( "Attribute Contains", "a[href *= 'google']", ["google","groups"] );
@@ -288,16 +319,24 @@ test("attributes", function() {
t("Empty values", "#select1 option[value='']", ["option1a"]);
t("Empty values", "#select1 option[value!='']", ["option1b","option1c","option1d"]);
-
+
t("Select options via :selected", "#select1 option:selected", ["option1a"] );
t("Select options via :selected", "#select2 option:selected", ["option2d"] );
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
@@ -315,22 +355,26 @@ test("pseudo - child", function() {
t( "First Child", "p:first-child", [] );
QUnit.reset();
-
+
t( "Last Child", "p:last-child", ["sap"] );
t( "Last Child", "#main a:last-child", ["simon1","anchor1","mark","yahoo","anchor2","simon","liveLink1","liveLink2"] );
-
+
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() {
@@ -347,7 +393,7 @@ test("pseudo - misc", function() {
t( "Headers", ":header", ["qunit-header", "qunit-banner", "qunit-userAgent"] );
t( "Has Children - :has()", "p:has(a)", ["firstp","ap","en","sap"] );
-
+
var select = document.getElementById("select1");
ok( (window.Sizzle || window.jQuery.find).matchesSelector( select, ":has(option)" ), "Has Option Matches" );
@@ -393,7 +439,7 @@ test("pseudo - :not", function() {
t( ":not() Multiple Class", "#foo a:not(.blog.link)", ["yahoo","anchor2"] );
});
-test("pseudo - position", function() {
+test("pseudo - position", function() {
expect(25);
t( "nth Element", "p:nth(1)", ["ap"] );
t( "First Element", "p:first", ["firstp"] );
diff --git a/test/unit/traversing.js b/test/unit/traversing.js
index 0d079f19a..56fed2200 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);
@@ -138,7 +138,7 @@ test("closest()", function() {
same( jq.closest("html", document.body).get(), [], "Context limited." );
same( jq.closest("body", document.body).get(), [], "Context limited." );
same( jq.closest("#nothiddendiv", document.body).get(), q("nothiddendiv"), "Context not reached." );
-
+
//Test that .closest() returns unique'd set
equals( jQuery('#main p').closest('#main').length, 1, "Closest should return a unique set" );
@@ -275,9 +275,9 @@ test("parents([String])", function() {
test("parentsUntil([String])", function() {
expect(9);
-
+
var parents = jQuery("#groups").parents();
-
+
same( jQuery("#groups").parentsUntil().get(), parents.get(), "parentsUntil with no selector (nextAll)" );
same( jQuery("#groups").parentsUntil(".foo").get(), parents.get(), "parentsUntil with invalid selector (nextAll)" );
same( jQuery("#groups").parentsUntil("#html").get(), parents.not(':last').get(), "Simple parentsUntil check" );
@@ -307,9 +307,9 @@ test("prev([String])", function() {
test("nextAll([String])", function() {
expect(4);
-
+
var elems = jQuery('#form').children();
-
+
same( jQuery("#label-for").nextAll().get(), elems.not(':first').get(), "Simple nextAll check" );
same( jQuery("#label-for").nextAll('input').get(), elems.not(':first').filter('input').get(), "Filtered nextAll check" );
same( jQuery("#label-for").nextAll('input,select').get(), elems.not(':first').filter('input,select').get(), "Multiple-filtered nextAll check" );
@@ -318,9 +318,9 @@ test("nextAll([String])", function() {
test("prevAll([String])", function() {
expect(4);
-
+
var elems = jQuery( jQuery('#form').children().slice(0, 12).get().reverse() );
-
+
same( jQuery("#area1").prevAll().get(), elems.get(), "Simple prevAll check" );
same( jQuery("#area1").prevAll('input').get(), elems.filter('input').get(), "Filtered prevAll check" );
same( jQuery("#area1").prevAll('input,select').get(), elems.filter('input,select').get(), "Multiple-filtered prevAll check" );
@@ -329,9 +329,9 @@ test("prevAll([String])", function() {
test("nextUntil([String])", function() {
expect(11);
-
+
var elems = jQuery('#form').children().slice( 2, 12 );
-
+
same( jQuery("#text1").nextUntil().get(), jQuery("#text1").nextAll().get(), "nextUntil with no selector (nextAll)" );
same( jQuery("#text1").nextUntil(".foo").get(), jQuery("#text1").nextAll().get(), "nextUntil with invalid selector (nextAll)" );
same( jQuery("#text1").nextUntil("#area1").get(), elems.get(), "Simple nextUntil check" );
@@ -342,15 +342,15 @@ test("nextUntil([String])", function() {
same( jQuery("#text1").nextUntil("#area1", "button,input").get(), elems.get(), "Multiple-filtered nextUntil check" );
equals( jQuery("#text1").nextUntil("#area1", "div").length, 0, "Filtered nextUntil check, no match" );
same( jQuery("#text1, #hidden1").nextUntil("#area1", "button,input").get(), elems.get(), "Multi-source, multiple-filtered nextUntil check" );
-
+
same( jQuery("#text1").nextUntil("[class=foo]").get(), jQuery("#text1").nextAll().get(), "Non-element nodes must be skipped, since they have no attributes" );
});
test("prevUntil([String])", function() {
expect(10);
-
+
var elems = jQuery("#area1").prevAll();
-
+
same( jQuery("#area1").prevUntil().get(), elems.get(), "prevUntil with no selector (prevAll)" );
same( jQuery("#area1").prevUntil(".foo").get(), elems.get(), "prevUntil with invalid selector (prevAll)" );
same( jQuery("#area1").prevUntil("label").get(), elems.not(':last').get(), "Simple prevUntil check" );
@@ -440,12 +440,13 @@ test("add(String|Element|Array|undefined)", function() {
test("add(String, Context)", function() {
expect(6);
-
- equals( jQuery(document).add("#form").length, 2, "Make sure that using regular context document still works." );
- equals( jQuery(document.body).add("#form").length, 2, "Using a body context." );
- equals( jQuery(document.body).add("#html").length, 1, "Using a body context." );
-
- equals( jQuery(document).add("#form", document).length, 2, "Use a passed in document context." );
- equals( jQuery(document).add("#form", document.body).length, 2, "Use a passed in body context." );
- equals( jQuery(document).add("#html", document.body).length, 1, "Use a passed in body context." );
+
+ deepEqual( jQuery( "#firstp" ).add( "#ap" ).get(), q( "firstp", "ap" ), "Add selector to selector " );
+ deepEqual( jQuery( document.getElementById("firstp") ).add( "#ap" ).get(), q( "firstp", "ap" ), "Add gEBId to selector" );
+ deepEqual( jQuery( document.getElementById("firstp") ).add( document.getElementById("ap") ).get(), q( "firstp", "ap" ), "Add gEBId to gEBId" );
+
+ var ctx = document.getElementById("firstp");
+ deepEqual( jQuery( "#firstp" ).add( "#ap", ctx ).get(), q( "firstp" ), "Add selector to selector " );
+ deepEqual( jQuery( document.getElementById("firstp") ).add( "#ap", ctx ).get(), q( "firstp" ), "Add gEBId to selector, not in context" );
+ deepEqual( jQuery( document.getElementById("firstp") ).add( "#ap", document.getElementsByTagName("body")[0] ).get(), q( "firstp", "ap" ), "Add gEBId to selector, in context" );
});