Selector: pass jQuery unit tests with selector-native

- Ignore certain tests that obviously are not supported
- Beefed up the sortOrder, uniqueSort, isXMLDoc, and attr functions

Fixes gh-1742
Fixes gh-2048
Close gh-2703
This commit is contained in:
Timmy Willison 2015-11-10 13:26:15 -05:00
parent ab06be561e
commit 88046440da
9 changed files with 309 additions and 216 deletions

View File

@ -1,8 +1,10 @@
define( [
"./core",
"./var/document",
"./var/documentElement"
], function( jQuery, document, documentElement ) {
"./var/documentElement",
"./var/hasOwn",
"./var/indexOf"
], function( jQuery, document, documentElement, hasOwn, indexOf ) {
/*
* Optional (non-Sizzle) selector module for custom builds.
@ -29,69 +31,84 @@ define( [
* customize this stub for the project's specific needs.
*/
var hasDuplicate,
var hasDuplicate, sortInput,
sortStable = jQuery.expando.split( "" ).sort( sortOrder ).join( "" ) === jQuery.expando,
matches = documentElement.matches ||
documentElement.webkitMatchesSelector ||
documentElement.mozMatchesSelector ||
documentElement.oMatchesSelector ||
documentElement.msMatchesSelector,
sortOrder = function( a, b ) {
documentElement.msMatchesSelector;
// Flag for duplicate removal
if ( a === b ) {
hasDuplicate = true;
return 0;
function sortOrder( a, b ) {
// Flag for duplicate removal
if ( a === b ) {
hasDuplicate = true;
return 0;
}
// Sort on method existence if only one input has compareDocumentPosition
var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
if ( compare ) {
return compare;
}
// Calculate position if both inputs belong to the same document
compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
a.compareDocumentPosition( b ) :
// Otherwise we know they are disconnected
1;
// Disconnected nodes
if ( compare & 1 ) {
// Choose the first element that is related to our preferred document
if ( a === document || a.ownerDocument === document &&
jQuery.contains( document, a ) ) {
return -1;
}
if ( b === document || b.ownerDocument === document &&
jQuery.contains( document, b ) ) {
return 1;
}
var compare = b.compareDocumentPosition &&
a.compareDocumentPosition &&
a.compareDocumentPosition( b );
// Maintain original order
return sortInput ?
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
0;
}
if ( compare ) {
return compare & 4 ? -1 : 1;
}
// Disconnected nodes
if ( compare & 1 ) {
function uniqueSort( results ) {
var elem,
duplicates = [],
j = 0,
i = 0;
// Choose the first element that is related to our document
if ( a === document || jQuery.contains( document, a ) ) {
return -1;
}
if ( b === document || jQuery.contains( document, b ) ) {
return 1;
}
hasDuplicate = false;
sortInput = !sortStable && results.slice( 0 );
results.sort( sortOrder );
// Maintain original order
return 0;
}
return compare & 4 ? -1 : 1;
}
// Not directly comparable, sort on existence of method
return a.compareDocumentPosition ? -1 : 1;
},
uniqueSort = function( results ) {
var elem,
duplicates = [],
i = 0,
j = 0;
hasDuplicate = false;
results.sort( sortOrder );
if ( hasDuplicate ) {
while ( ( elem = results[ i++ ] ) ) {
if ( elem === results[ i ] ) {
j = duplicates.push( i );
}
}
while ( j-- ) {
results.splice( duplicates[ j ], 1 );
if ( hasDuplicate ) {
while ( ( elem = results[ i++ ] ) ) {
if ( elem === results[ i ] ) {
j = duplicates.push( i );
}
}
while ( j-- ) {
results.splice( duplicates[ j ], 1 );
}
}
return results;
};
// Clear input after sorting to release objects
// See https://github.com/jquery/sizzle/pull/225
sortInput = null;
return results;
}
jQuery.extend( {
find: function( selector, context, results, seed ) {
@ -157,7 +174,11 @@ jQuery.extend( {
return a === bup || !!( bup && bup.nodeType === 1 && adown.contains( bup ) );
},
isXMLDoc: function( elem ) {
return ( elem.ownerDocument || elem ).documentElement.nodeName !== "HTML";
// documentElement is verified for cases where it doesn't yet exist
// (such as loading iframes in IE - #4833)
var documentElement = elem && ( elem.ownerDocument || elem ).documentElement;
return documentElement ? documentElement.nodeName !== "HTML" : false;
},
expr: {
attrHandle: {},
@ -177,7 +198,13 @@ jQuery.extend( jQuery.find, {
return matches.call( elem, expr );
},
attr: function( elem, name ) {
return elem.getAttribute( name );
var fn = jQuery.expr.attrHandle[ name.toLowerCase() ],
// Don't get fooled by Object.prototype properties (jQuery #13807)
value = fn && hasOwn.call( jQuery.expr.attrHandle, name.toLowerCase() ) ?
fn( elem, name, jQuery.isXMLDoc( elem ) ) :
undefined;
return value !== undefined ? value : elem.getAttribute( name );
}
} );

View File

@ -145,7 +145,7 @@ QUnit.test( "jQuery()", function( assert ) {
"Empty attributes object is not interpreted as a document (trac-8950)" );
} );
QUnit.test( "jQuery(selector, context)", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "jQuery(selector, context)", function( assert ) {
assert.expect( 3 );
assert.deepEqual( jQuery( "div p", "#qunit-fixture" ).get(), q( "sndp", "en", "sap" ), "Basic selector with string as context" );
assert.deepEqual( jQuery( "div p", q( "qunit-fixture" )[ 0 ] ).get(), q( "sndp", "en", "sap" ), "Basic selector with element as context" );
@ -618,8 +618,12 @@ QUnit.test( "jQuery('html')", function( assert ) {
//equal( jQuery( "element[attribute=<div></div>]" ).length, 0,
// "When html is within brackets, do not recognize as html." );
assert.equal( jQuery( "element:not(<div></div>)" ).length, 0,
"When html is within parens, do not recognize as html." );
if ( jQuery.find.compile ) {
assert.equal( jQuery( "element:not(<div></div>)" ).length, 0,
"When html is within parens, do not recognize as html." );
} else {
assert.ok( "skip", "Complex :not not supported in selector-native" );
}
assert.equal( jQuery( "\\<div\\>" ).length, 0, "Ignore escaped html characters" );
} );

View File

@ -666,9 +666,7 @@ QUnit.test( "show() after hide() should always set display to initial value (#14
}
if ( jQuery.fn.toggle ) {
QUnit.test( "toggle()", function( assert ) {
QUnit[ jQuery.find.compile && jQuery.fn.toggle ? "test" : "skip" ]( "toggle()", function( assert ) {
assert.expect( 9 );
var div, oldHide,
x = jQuery( "#foo" );
@ -701,8 +699,6 @@ QUnit.test( "toggle()", function( assert ) {
jQuery.fn.hide = oldHide;
} );
}
QUnit.test( "jQuery.css(elem, 'height') doesn't clear radio buttons (bug #1095)", function( assert ) {
assert.expect( 4 );
@ -1012,7 +1008,7 @@ QUnit.test( "css opacity consistency across browsers (#12685)", function( assert
assert.equal( Math.round( el.css( "opacity" ) * 100 ), 20, "remove opacity override" );
} );
QUnit.test( ":visible/:hidden selectors", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( ":visible/:hidden selectors", function( assert ) {
assert.expect( 17 );
var $div, $table, $a;

41
test/unit/effects.js vendored
View File

@ -27,7 +27,7 @@ QUnit.module( "effects", {
}
} );
QUnit.test( "sanity check", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "sanity check", function( assert ) {
assert.expect( 1 );
assert.equal( jQuery( "#dl:visible, #qunit-fixture:visible, #foo:visible" ).length, 3, "QUnit state is correct for testing effects" );
} );
@ -769,7 +769,7 @@ QUnit.test( "stop( queue, ..., ... ) - Stop single queues", function( assert ) {
this.clock.tick( 500 );
} );
QUnit.test( "toggle()", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "toggle()", function( assert ) {
assert.expect( 6 );
var x = jQuery( "#foo" );
assert.ok( x.is( ":visible" ), "is visible" );
@ -1534,9 +1534,9 @@ QUnit.test( "User supplied callback called after show when fx off (#8892)", func
jQuery.fx.off = true;
foo.hide();
foo.fadeIn( 500, function() {
assert.ok( jQuery( this ).is( ":visible" ), "Element is visible in callback" );
assert.ok( supportjQuery( this ).is( ":visible" ), "Element is visible in callback" );
foo.fadeOut( 500, function() {
assert.ok( jQuery( this ).is( ":hidden" ), "Element is hidden in callback" );
assert.ok( supportjQuery( this ).is( ":hidden" ), "Element is hidden in callback" );
jQuery.fx.off = false;
} );
} );
@ -1592,7 +1592,7 @@ QUnit.test( "animate should set display for disconnected nodes", function( asser
clock.tick( 400 );
} );
QUnit.test( "Animation callback should not show animated element as :animated (#7157)", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "Animation callback should not show animated element as :animated (#7157)", function( assert ) {
assert.expect( 1 );
var foo = jQuery( "#foo" );
@ -1605,7 +1605,7 @@ QUnit.test( "Animation callback should not show animated element as :animated (#
this.clock.tick( 100 );
} );
QUnit.test( "Initial step callback should show element as :animated (#14623)", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "Initial step callback should show element as :animated (#14623)", function( assert ) {
assert.expect( 1 );
var foo = jQuery( "#foo" );
@ -2125,7 +2125,12 @@ QUnit.test( ".finish() completes all queued animations", function( assert ) {
assert.equal( parseFloat( div.css( prop ) ), value, prop + " finished at correct value" );
} );
assert.equal( div.queue().length, 0, "empty queue when done" );
assert.equal( div.is( ":animated" ), false, ":animated doesn't match" );
if ( jQuery.find.compile ) {
assert.equal( div.is( ":animated" ), false, ":animated doesn't match" );
} else {
assert.ok( "skip", ":animated selector not supported with selector-native" );
}
// cleanup
div.remove();
@ -2160,7 +2165,12 @@ QUnit.test( ".finish( false ) - unqueued animations", function( assert ) {
jQuery.each( animations, function( prop, value ) {
assert.equal( parseFloat( div.css( prop ) ), value, prop + " finished at correct value" );
} );
assert.equal( div.is( ":animated" ), false, ":animated doesn't match" );
if ( jQuery.find.compile ) {
assert.equal( div.is( ":animated" ), false, ":animated doesn't match" );
} else {
assert.ok( "skip", ":animated selector not supported with selector-native" );
}
// cleanup
div.remove();
@ -2194,12 +2204,23 @@ QUnit.test( ".finish( \"custom\" ) - custom queue animations", function( assert
// start the first animation
div.dequeue( "custom" );
assert.equal( div.is( ":animated" ), true, ":animated matches" );
if ( jQuery.find.compile ) {
assert.equal( div.is( ":animated" ), true, ":animated matches" );
} else {
assert.ok( "skip", ":animated selector not supported with selector-native" );
}
div.finish( "custom" );
jQuery.each( animations, function( prop, value ) {
assert.equal( parseFloat( div.css( prop ) ), value, prop + " finished at correct value" );
} );
assert.equal( div.is( ":animated" ), false, ":animated doesn't match" );
if ( jQuery.find.compile ) {
assert.equal( div.is( ":animated" ), false, ":animated doesn't match" );
} else {
assert.ok( "skip", ":animated selector not supported with selector-native" );
}
// cleanup
div.remove();

View File

@ -1750,7 +1750,8 @@ QUnit.test( "jQuery.off using dispatched jQuery.Event", function( assert ) {
.remove();
} );
QUnit.test( "delegated event with delegateTarget-relative selector", function( assert ) {
// selector-native does not support scope-fixing in delegation
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "delegated event with delegateTarget-relative selector", function( assert ) {
assert.expect( 3 );
var markup = jQuery( "<div><ul><li><a id=\"a0\"></a><ul id=\"ul0\"><li class=test><a id=\"a0_0\"></a></li><li><a id=\"a0_1\"></a></li></ul></li></ul></div>" ).appendTo( "#qunit-fixture" );

View File

@ -353,9 +353,9 @@ QUnit.test( "append(Function) returns String", function( assert ) {
QUnit.test( "append(Function) returns Element", function( assert ) {
assert.expect( 2 );
assert.expect( 2 );
var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:",
old = jQuery( "#sap" ).html();
old = jQuery( "#sap" ).html();
jQuery( "#sap" ).append( function( i, val ) {
assert.equal( val, old, "Make sure the incoming value is correct." );
@ -368,7 +368,7 @@ QUnit.test( "append(Function) returns Array<Element>", function( assert ) {
assert.expect( 2 );
var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:Yahoo",
old = jQuery( "#sap" ).html();
old = jQuery( "#sap" ).html();
jQuery( "#sap" ).append( function( i, val ) {
assert.equal( val, old, "Make sure the incoming value is correct." );
@ -381,7 +381,7 @@ QUnit.test( "append(Function) returns jQuery", function( assert ) {
assert.expect( 2 );
var expected = "This link has class=\"blog\": Simon Willison's WeblogYahooTry them out:",
old = jQuery( "#sap" ).html();
old = jQuery( "#sap" ).html();
jQuery( "#sap" ).append( function( i, val ) {
assert.equal( val, old, "Make sure the incoming value is correct." );
@ -583,7 +583,7 @@ QUnit.test( "appendTo(String)", function( assert ) {
QUnit.test( "appendTo(Element|Array<Element>)", function( assert ) {
assert.expect( 2 );
assert.expect( 2 );
var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:";
jQuery( document.getElementById( "first" ) ).appendTo( "#sap" );
@ -597,9 +597,9 @@ QUnit.test( "appendTo(Element|Array<Element>)", function( assert ) {
QUnit.test( "appendTo(jQuery)", function( assert ) {
assert.expect( 10 );
assert.expect( 10 );
var expected, num, div;
var expected, num, div;
assert.ok( jQuery( document.createElement( "script" ) ).appendTo( "body" ).length, "Make sure a disconnected script can be appended." );
expected = "This link has class=\"blog\": Simon Willison's WeblogYahooTry them out:";
@ -715,7 +715,7 @@ QUnit.test( "prepend(Function) with incoming value -- String", function( assert
QUnit.test( "prepend(Function) with incoming value -- Element", function( assert ) {
assert.expect( 2 );
assert.expect( 2 );
var old, expected;
expected = "Try them out:This link has class=\"blog\": Simon Willison's Weblog";
@ -731,7 +731,7 @@ QUnit.test( "prepend(Function) with incoming value -- Element", function( assert
QUnit.test( "prepend(Function) with incoming value -- Array<Element>", function( assert ) {
assert.expect( 2 );
assert.expect( 2 );
var old, expected;
expected = "Try them out:YahooThis link has class=\"blog\": Simon Willison's Weblog";
@ -747,7 +747,7 @@ QUnit.test( "prepend(Function) with incoming value -- Array<Element>", function(
QUnit.test( "prepend(Function) with incoming value -- jQuery", function( assert ) {
assert.expect( 2 );
assert.expect( 2 );
var old, expected;
expected = "YahooTry them out:This link has class=\"blog\": Simon Willison's Weblog";
@ -943,27 +943,27 @@ QUnit.test( "before and after w/ empty object (#10812)", function( assert ) {
QUnit.test( ".before() and .after() disconnected node", function( assert ) {
assert.expect( 2 );
assert.expect( 2 );
assert.equal( jQuery( "<input type='checkbox'/>" ).before( "<div/>" ).length, 1, "before() on disconnected node is no-op" );
assert.equal( jQuery( "<input type='checkbox'/>" ).before( "<div/>" ).length, 1, "before() on disconnected node is no-op" );
assert.equal( jQuery( "<input type='checkbox'/>" ).after( "<div/>" ).length, 1, "after() on disconnected node is no-op" );
} );
QUnit.test( "insert with .before() on disconnected node last", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expectedBefore = "This is a normal link: bugaYahoo";
var expectedBefore = "This is a normal link: bugaYahoo";
jQuery( "#yahoo" ).add( "<span/>" ).before( "<b>buga</b>" );
jQuery( "#yahoo" ).add( "<span/>" ).before( "<b>buga</b>" );
assert.equal( jQuery( "#en" ).text(), expectedBefore, "Insert String before with disconnected node last" );
} );
QUnit.test( "insert with .before() on disconnected node first", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expectedBefore = "This is a normal link: bugaYahoo";
var expectedBefore = "This is a normal link: bugaYahoo";
jQuery( "<span/>" ).add( "#yahoo" ).before( "<b>buga</b>" );
assert.equal( jQuery( "#en" ).text(), expectedBefore, "Insert String before with disconnected node first" );
@ -971,9 +971,9 @@ QUnit.test( "insert with .before() on disconnected node first", function( assert
QUnit.test( "insert with .before() on disconnected node last", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expectedAfter = "This is a normal link: Yahoobuga";
var expectedAfter = "This is a normal link: Yahoobuga";
jQuery( "#yahoo" ).add( "<span/>" ).after( "<b>buga</b>" );
assert.equal( jQuery( "#en" ).text(), expectedAfter, "Insert String after with disconnected node last" );
@ -981,9 +981,9 @@ QUnit.test( "insert with .before() on disconnected node last", function( assert
QUnit.test( "insert with .before() on disconnected node last", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expectedAfter = "This is a normal link: Yahoobuga";
var expectedAfter = "This is a normal link: Yahoobuga";
jQuery( "<span/>" ).add( "#yahoo" ).after( "<b>buga</b>" );
assert.equal( jQuery( "#en" ).text(), expectedAfter, "Insert String after with disconnected node first" );
@ -1000,112 +1000,112 @@ QUnit.test( "insertBefore(String)", function( assert ) {
QUnit.test( "insertBefore(Element)", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: Try them out:Yahoo";
var expected = "This is a normal link: Try them out:Yahoo";
jQuery( document.getElementById( "first" ) ).insertBefore( "#yahoo" );
assert.equal( jQuery( "#en" ).text(), expected, "Insert element before" );
} );
QUnit.test( "insertBefore(Array<Element>)", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: Try them out:diveintomarkYahoo";
var expected = "This is a normal link: Try them out:diveintomarkYahoo";
jQuery( [ document.getElementById( "first" ), document.getElementById( "mark" ) ] ).insertBefore( "#yahoo" );
assert.equal( jQuery( "#en" ).text(), expected, "Insert array of elements before" );
} );
QUnit.test( "insertBefore(jQuery)", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: diveintomarkTry them out:Yahoo";
var expected = "This is a normal link: diveintomarkTry them out:Yahoo";
jQuery( "#mark, #first" ).insertBefore( "#yahoo" );
assert.equal( jQuery( "#en" ).text(), expected, "Insert jQuery before" );
} );
QUnit.test( ".after(String)", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: Yahoobuga";
var expected = "This is a normal link: Yahoobuga";
jQuery( "#yahoo" ).after( "<b>buga</b>" );
assert.equal( jQuery( "#en" ).text(), expected, "Insert String after" );
} );
QUnit.test( ".after(Element)", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: YahooTry them out:";
var expected = "This is a normal link: YahooTry them out:";
jQuery( "#yahoo" ).after( document.getElementById( "first" ) );
assert.equal( jQuery( "#en" ).text(), expected, "Insert element after" );
} );
QUnit.test( ".after(Array<Element>)", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: YahooTry them out:diveintomark";
var expected = "This is a normal link: YahooTry them out:diveintomark";
jQuery( "#yahoo" ).after( [ document.getElementById( "first" ), document.getElementById( "mark" ) ] );
assert.equal( jQuery( "#en" ).text(), expected, "Insert array of elements after" );
} );
QUnit.test( ".after(jQuery)", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: YahooTry them out:Googlediveintomark";
var expected = "This is a normal link: YahooTry them out:Googlediveintomark";
jQuery( "#yahoo" ).after( [ jQuery( "#first" ), jQuery( "#mark, #google" ) ] );
assert.equal( jQuery( "#en" ).text(), expected, "Insert array of jQuery objects after" );
} );
QUnit.test( ".after(Function) returns String", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: Yahoobuga",
val = manipulationFunctionReturningObj;
var expected = "This is a normal link: Yahoobuga",
val = manipulationFunctionReturningObj;
jQuery( "#yahoo" ).after( val( "<b>buga</b>" ) );
assert.equal( jQuery( "#en" ).text(), expected, "Insert String after" );
} );
QUnit.test( ".after(Function) returns Element", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: YahooTry them out:",
val = manipulationFunctionReturningObj;
var expected = "This is a normal link: YahooTry them out:",
val = manipulationFunctionReturningObj;
jQuery( "#yahoo" ).after( val( document.getElementById( "first" ) ) );
assert.equal( jQuery( "#en" ).text(), expected, "Insert element after" );
} );
QUnit.test( ".after(Function) returns Array<Element>", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: YahooTry them out:diveintomark",
val = manipulationFunctionReturningObj;
var expected = "This is a normal link: YahooTry them out:diveintomark",
val = manipulationFunctionReturningObj;
jQuery( "#yahoo" ).after( val( [ document.getElementById( "first" ), document.getElementById( "mark" ) ] ) );
assert.equal( jQuery( "#en" ).text(), expected, "Insert array of elements after" );
} );
QUnit.test( ".after(Function) returns jQuery", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: YahooTry them out:Googlediveintomark",
val = manipulationFunctionReturningObj;
var expected = "This is a normal link: YahooTry them out:Googlediveintomark",
val = manipulationFunctionReturningObj;
jQuery( "#yahoo" ).after( val( [ jQuery( "#first" ), jQuery( "#mark, #google" ) ] ) );
assert.equal( jQuery( "#en" ).text(), expected, "Insert array of jQuery objects after" );
} );
QUnit.test( ".after(disconnected node)", function( assert ) {
assert.expect( 2 );
assert.expect( 2 );
var set = jQuery( "<div/>" ).before( "<span>test</span>" );
var set = jQuery( "<div/>" ).before( "<span>test</span>" );
assert.equal( set[ 0 ].nodeName.toLowerCase(), "div", "Insert after a disconnected node should be a no-op" );
assert.equal( set.length, 1, "Insert the element after the disconnected node should be a no-op" );
} );
@ -1121,27 +1121,27 @@ QUnit.test( "insertAfter(String)", function( assert ) {
QUnit.test( "insertAfter(Element)", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: YahooTry them out:";
var expected = "This is a normal link: YahooTry them out:";
jQuery( document.getElementById( "first" ) ).insertAfter( "#yahoo" );
assert.equal( jQuery( "#en" ).text(), expected, "Insert element after" );
} );
QUnit.test( "insertAfter(Array<Element>)", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: YahooTry them out:diveintomark";
var expected = "This is a normal link: YahooTry them out:diveintomark";
jQuery( [ document.getElementById( "first" ), document.getElementById( "mark" ) ] ).insertAfter( "#yahoo" );
assert.equal( jQuery( "#en" ).text(), expected, "Insert array of elements after" );
} );
QUnit.test( "insertAfter(jQuery)", function( assert ) {
assert.expect( 1 );
assert.expect( 1 );
var expected = "This is a normal link: YahoodiveintomarkTry them out:";
var expected = "This is a normal link: YahoodiveintomarkTry them out:";
jQuery( "#mark, #first" ).insertAfter( "#yahoo" );
assert.equal( jQuery( "#en" ).text(), expected, "Insert jQuery after" );
} );
@ -1559,8 +1559,17 @@ QUnit.test( "clone(multiple selected options) (Bug #8129)", function( assert ) {
var element = jQuery( "<select><option>Foo</option><option selected>Bar</option><option selected>Baz</option></select>" );
assert.equal( element.clone().find( "option:selected" ).length, element.find( "option:selected" ).length, "Multiple selected options cloned correctly" );
function getSelectedOptions( collection ) {
return collection.find( "option" ).filter(function( option ) {
return option.selected;
} );
}
assert.equal(
getSelectedOptions( element.clone() ).length,
getSelectedOptions( element ).length,
"Multiple selected options cloned correctly"
);
} );
QUnit.test( "clone() on XML nodes", function( assert ) {
@ -1754,7 +1763,7 @@ QUnit.test( "html(Function) with incoming value -- jQuery.contents()", function(
assert.expect( 14 );
var actualhtml, j, $div, $div2, insert;
var actualhtml, j, $div, $div2, insert;
j = jQuery( "#nonnodes" ).contents();
actualhtml = j.map( function() {
@ -1825,7 +1834,7 @@ QUnit.test( "clone()/html() don't expose jQuery/Sizzle expandos (#12858)", funct
QUnit.test( "remove() no filters", function( assert ) {
assert.expect( 2 );
assert.expect( 2 );
var first = jQuery( "#ap" ).children().first();
@ -1838,9 +1847,9 @@ QUnit.test( "remove() no filters", function( assert ) {
QUnit.test( "remove() with filters", function( assert ) {
assert.expect( 8 );
assert.expect( 8 );
var markup, div;
var markup, div;
jQuery( "#ap" ).children().remove( "a" );
assert.ok( jQuery( "#ap" ).text().length > 10, "Check text is not removed" );
assert.equal( jQuery( "#ap" ).children().length, 1, "Check filtered remove" );
@ -1853,12 +1862,18 @@ QUnit.test( "remove() with filters", function( assert ) {
div = jQuery( markup );
div.children().remove( "span:nth-child(2n)" );
assert.equal( div.text(), "13", "relative selector in remove" );
div = jQuery( markup );
div.children().remove( "span:first" );
assert.equal( div.text(), "234", "positional selector in remove" );
div = jQuery( markup );
div.children().remove( "span:last" );
assert.equal( div.text(), "123", "positional selector in remove" );
if ( jQuery.find.compile ) {
div = jQuery( markup );
div.children().remove( "span:first" );
assert.equal( div.text(), "234", "positional selector in remove" );
div = jQuery( markup );
div.children().remove( "span:last" );
assert.equal( div.text(), "123", "positional selector in remove" );
} else {
assert.ok( "skip", "Positional selectors not supported in selector-native" );
assert.ok( "skip", "Positional selectors not supported in selector-native" );
}
// using contents will get comments regular, text, and comment nodes
// Handle the case where no comment is in the document
@ -1912,50 +1927,56 @@ QUnit.test( "remove() in document order #13779", function( assert ) {
QUnit.test( "detach() no filters", function( assert ) {
assert.expect( 3 );
assert.expect( 3 );
var first = jQuery( "#ap" ).children().first();
var first = jQuery( "#ap" ).children().first();
first.data( "foo", "bar" );
first.data( "foo", "bar" );
jQuery( "#ap" ).children().detach();
assert.ok( jQuery( "#ap" ).text().length > 10, "Check text is not removed" );
assert.equal( jQuery( "#ap" ).children().length, 0, "Check remove" );
jQuery( "#ap" ).children().detach();
assert.ok( jQuery( "#ap" ).text().length > 10, "Check text is not removed" );
assert.equal( jQuery( "#ap" ).children().length, 0, "Check remove" );
assert.equal( first.data( "foo" ), "bar" );
first.remove();
assert.equal( first.data( "foo" ), "bar" );
first.remove();
} );
QUnit.test( "detach() with filters", function( assert ) {
assert.expect( 8 );
assert.expect( 8 );
var markup, div;
jQuery( "#ap" ).children().detach( "a" );
assert.ok( jQuery( "#ap" ).text().length > 10, "Check text is not removed" );
assert.equal( jQuery( "#ap" ).children().length, 1, "Check filtered remove" );
var markup, div;
jQuery( "#ap" ).children().detach( "a" );
assert.ok( jQuery( "#ap" ).text().length > 10, "Check text is not removed" );
assert.equal( jQuery( "#ap" ).children().length, 1, "Check filtered remove" );
jQuery( "#ap" ).children().detach( "a, code" );
assert.equal( jQuery( "#ap" ).children().length, 0, "Check multi-filtered remove" );
jQuery( "#ap" ).children().detach( "a, code" );
assert.equal( jQuery( "#ap" ).children().length, 0, "Check multi-filtered remove" );
// Positional and relative selectors
markup = "<div><span>1</span><span>2</span><span>3</span><span>4</span></div>";
div = jQuery( markup );
div.children().detach( "span:nth-child(2n)" );
assert.equal( div.text(), "13", "relative selector in detach" );
div = jQuery( markup );
div.children().detach( "span:first" );
assert.equal( div.text(), "234", "positional selector in detach" );
div = jQuery( markup );
div.children().detach( "span:last" );
assert.equal( div.text(), "123", "positional selector in detach" );
// Positional and relative selectors
markup = "<div><span>1</span><span>2</span><span>3</span><span>4</span></div>";
div = jQuery( markup );
div.children().detach( "span:nth-child(2n)" );
assert.equal( div.text(), "13", "relative selector in detach" );
// using contents will get comments regular, text, and comment nodes
// Handle the case where no comment is in the document
assert.ok( jQuery( "#nonnodes" ).contents().length >= 2, "Check node,textnode,comment remove works" );
jQuery( "#nonnodes" ).contents().detach();
assert.equal( jQuery( "#nonnodes" ).contents().length, 0, "Check node,textnode,comment remove works" );
if ( jQuery.find.compile ) {
div = jQuery( markup );
div.children().detach( "span:first" );
assert.equal( div.text(), "234", "positional selector in detach" );
div = jQuery( markup );
div.children().detach( "span:last" );
assert.equal( div.text(), "123", "positional selector in detach" );
} else {
assert.ok( "skip", "positional selectors not supported in selector-native" );
assert.ok( "skip", "positional selectors not supported in selector-native" );
}
// using contents will get comments regular, text, and comment nodes
// Handle the case where no comment is in the document
assert.ok( jQuery( "#nonnodes" ).contents().length >= 2, "Check node,textnode,comment remove works" );
jQuery( "#nonnodes" ).contents().detach();
assert.equal( jQuery( "#nonnodes" ).contents().length, 0, "Check node,textnode,comment remove works" );
} );
QUnit.test( "detach() event cleaning ", function( assert ) {

View File

@ -4,7 +4,7 @@ QUnit.module( "selector", { teardown: moduleTeardown } );
* This test page is for selector tests that require jQuery in order to do the selection
*/
QUnit.test( "element - jQuery only", function( assert ) {
QUnit.test( "element", function( assert ) {
assert.expect( 7 );
var fixture = document.getElementById( "qunit-fixture" );
@ -63,7 +63,7 @@ QUnit.test( "id", function( assert ) {
assert.t( "ID with weird characters in it", "#name\\+value", [ "name+value" ] );
} );
QUnit.test( "class - jQuery only", function( assert ) {
QUnit.test( "class", function( assert ) {
assert.expect( 4 );
assert.deepEqual( jQuery( ".blog", document.getElementsByTagName( "p" ) ).get(), q( "mark", "simon" ), "Finding elements with a context." );
@ -103,8 +103,6 @@ QUnit.test( "selectors with comma", function( assert ) {
QUnit.test( "child and adjacent", function( assert ) {
assert.expect( 27 );
var nothiddendiv;
assert.t( "Child", "p > a", [ "simon1","google","groups","mark","yahoo","simon" ] );
assert.t( "Child", "p> a", [ "simon1","google","groups","mark","yahoo","simon" ] );
assert.t( "Child", "p >a", [ "simon1","google","groups","mark","yahoo","simon" ] );
@ -120,24 +118,27 @@ QUnit.test( "child and adjacent", function( assert ) {
assert.t( "Element Preceded By", "#length ~ input", [ "idTest" ] );
assert.t( "Element Preceded By", "#siblingfirst ~ em", [ "siblingnext", "siblingthird" ] );
assert.t( "Element Preceded By (multiple)", "#siblingTest em ~ em ~ em ~ span", [ "siblingspan" ] );
assert.t( "Element Preceded By, Containing", "#liveHandlerOrder ~ div em:contains('1')", [ "siblingfirst" ] );
if ( jQuery.find.compile ) {
assert.t( "Element Preceded By, Containing", "#liveHandlerOrder ~ div em:contains('1')", [ "siblingfirst" ] );
assert.t( "Combinators are not skipped when mixing general and specific", "#siblingTest > em:contains('x') + em ~ span", [] );
assert.equal( jQuery( "#listWithTabIndex li:eq(2) ~ li" ).length, 1, "Find by general sibling combinator (#8310)" );
} else {
assert.ok( "skip", ":contains not supported in selector-native" );
assert.ok( "skip", ":contains not supported in selector-native" );
assert.ok( "skip", ":eq not supported in selector-native" );
}
assert.t( "Multiple combinators selects all levels", "#siblingTest em *", [ "siblingchild", "siblinggrandchild", "siblinggreatgrandchild" ] );
assert.t( "Multiple combinators selects all levels", "#siblingTest > em *", [ "siblingchild", "siblinggrandchild", "siblinggreatgrandchild" ] );
assert.t( "Multiple sibling combinators doesn't miss general siblings", "#siblingTest > em:first-child + em ~ span", [ "siblingspan" ] );
assert.t( "Combinators are not skipped when mixing general and specific", "#siblingTest > em:contains('x') + em ~ span", [] );
assert.equal( jQuery( "#listWithTabIndex" ).length, 1, "Parent div for next test is found via ID (#8310)" );
assert.equal( jQuery( "#listWithTabIndex li:eq(2) ~ li" ).length, 1, "Find by general sibling combinator (#8310)" );
assert.equal( jQuery( "#__sizzle__" ).length, 0, "Make sure the temporary id assigned by sizzle is cleared out (#8310)" );
assert.equal( jQuery( "#listWithTabIndex" ).length, 1, "Parent div for previous test is still found via ID (#8310)" );
assert.t( "Verify deep class selector", "div.blah > p > a", [] );
assert.t( "No element deep selector", "div.foo > span > a", [] );
nothiddendiv = document.getElementById( "nothiddendiv" );
assert.t( "Non-existent ancestors", ".fototab > .thumbnails > a", [] );
} );
@ -162,8 +163,8 @@ QUnit.test( "attributes", function( assert ) {
assert.t( "Attribute Equals", "#qunit-fixture a[rel=bookmark]", [ "simon1" ] );
assert.t( "Attribute Equals", "#qunit-fixture a[href='http://www.google.com/']", [ "google" ] );
assert.t( "Attribute Equals", "#qunit-fixture a[ rel = 'bookmark' ]", [ "simon1" ] );
assert.t( "Attribute Equals Number", "#qunit-fixture option[value=1]", [ "option1b","option2b","option3b","option4b","option5c" ] );
assert.t( "Attribute Equals Number", "#qunit-fixture li[tabIndex=-1]", [ "foodWithNegativeTabIndex" ] );
assert.t( "Attribute Equals Number", "#qunit-fixture option[value='1']", [ "option1b","option2b","option3b","option4b","option5c" ] );
assert.t( "Attribute Equals Number", "#qunit-fixture li[tabIndex='-1']", [ "foodWithNegativeTabIndex" ] );
document.getElementById( "anchor2" ).href = "#2";
assert.t( "href Attribute", "p a[href^='#']", [ "anchor2" ] );
@ -189,15 +190,25 @@ QUnit.test( "attributes", function( assert ) {
assert.t( "Attribute Begins With", "a[href ^= 'http://www']", [ "google","yahoo" ] );
assert.t( "Attribute Ends With", "a[href $= 'org/']", [ "mark" ] );
assert.t( "Attribute Contains", "a[href *= 'google']", [ "google","groups" ] );
assert.t( "Attribute Is Not Equal", "#ap a[hreflang!='en']", [ "google","groups","anchor1" ] );
if ( jQuery.find.compile ) {
assert.t( "Empty values", "#select1 option[value!='']", [ "option1b","option1c","option1d" ] );
assert.t( "Attribute Is Not Equal", "#ap a[hreflang!='en']", [ "google","groups","anchor1" ] );
assert.t( "Select options via :selected", "#select1 option:selected", [ "option1a" ] );
assert.t( "Select options via :selected", "#select2 option:selected", [ "option2d" ] );
assert.t( "Select options via :selected", "#select3 option:selected", [ "option3b", "option3c" ] );
assert.t( "Select options via :selected", "select[name='select2'] option:selected", [ "option2d" ] );
} else {
assert.ok( "skip", "!= not supported in selector-native" );
assert.ok( "skip", "!= not supported in selector-native" );
assert.ok( "skip", ":selected not supported in selector-native" );
assert.ok( "skip", ":selected not supported in selector-native" );
assert.ok( "skip", ":selected not supported in selector-native" );
assert.ok( "skip", ":selected not supported in selector-native" );
}
assert.t( "Empty values", "#select1 option[value='']", [ "option1a" ] );
assert.t( "Empty values", "#select1 option[value!='']", [ "option1b","option1c","option1d" ] );
assert.t( "Select options via :selected", "#select1 option:selected", [ "option1a" ] );
assert.t( "Select options via :selected", "#select2 option:selected", [ "option2d" ] );
assert.t( "Select options via :selected", "#select3 option:selected", [ "option3b", "option3c" ] );
assert.t( "Select options via :selected", "select[name='select2'] option:selected", [ "option2d" ] );
assert.t( "Grouped Form Elements", "input[name='foo[bar]']", [ "hidden2" ] );
@ -233,17 +244,24 @@ QUnit.test( "attributes", function( assert ) {
assert.t( "Value attribute is retrieved correctly", "input[value=Test]", [ "text1", "text2" ] );
// #12600
assert.ok(
jQuery( "<select value='12600'><option value='option' selected='selected'></option><option value=''></option></select>" )
.prop( "value", "option" )
.is( ":input[value='12600']" ),
if ( jQuery.find.compile ) {
// #12600
assert.ok(
jQuery( "<select value='12600'><option value='option' selected='selected'></option><option value=''></option></select>" )
.prop( "value", "option" )
.is( ":input[value='12600']" ),
":input[value=foo] selects select by attribute"
);
assert.ok( jQuery( "<input type='text' value='12600'/>" ).prop( "value", "option" ).is( ":input[value='12600']" ),
":input[value=foo] selects text input by attribute"
);
} else {
assert.ok( "skip", ":input not supported in selector-native" );
assert.ok( "skip", ":input not supported in selector-native" );
}
":input[value=foo] selects select by attribute"
);
assert.ok( jQuery( "<input type='text' value='12600'/>" ).prop( "value", "option" ).is( ":input[value='12600']" ),
":input[value=foo] selects text input by attribute"
);
// #11115
assert.ok( jQuery( "<input type='checkbox' checked='checked'/>" ).prop( "checked", false ).is( "[checked]" ),
@ -261,7 +279,7 @@ QUnit.test( "disconnected nodes", function( assert ) {
assert.equal( $div.is( "div" ), true, "Make sure .is('nodeName') works on disconnected nodes." );
} );
QUnit.test( "disconnected nodes - jQuery only", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "disconnected nodes", function( assert ) {
assert.expect( 3 );
var $opt = jQuery( "<option></option>" ).attr( "value", "whipit" ).appendTo( "#qunit-fixture" ).detach();

View File

@ -142,8 +142,9 @@ QUnit.test( "serialize()", function( assert ) {
"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%20Name=me&S1=abc&S3=YES&S4=",
"Multiple form serialization as query string" );
assert.equal( jQuery( "#form, #testForm :input" ).serialize(),
assert.equal( jQuery( "#form, #testForm input, #testForm select, #testForm textarea, #testForm button" ).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%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My%20Name=me&S1=abc&S3=YES&S4=",
"Mixed form/input serialization as query string" );
jQuery( "#html5email, #html5number" ).remove();
} );

View File

@ -13,7 +13,7 @@ QUnit.test( "find(String) under non-elements", function( assert ) {
assert.equal( j.find( "div" ).addBack().length, 3, "Check node,textnode,comment to find zero divs, but preserves pushStack" );
} );
QUnit.test( "find(leading combinator)", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "find(leading combinator)", function( assert ) {
assert.expect( 4 );
assert.deepEqual( jQuery( "#qunit-fixture" ).find( "> div" ).get(), q( "foo", "nothiddendiv", "moretests", "tabindex-tests", "liveHandlerOrder", "siblingTest", "fx-test-group" ), "find child elements" );
@ -130,7 +130,7 @@ QUnit.test( "is(jQuery)", function( assert ) {
assert.ok( !jQuery( "#simon" ).is( jQuery( ".blogTest" )[ 0 ] ), "Check for multiple classes: Expected classes 'blog' and 'link', but not 'blogTest'" );
} );
QUnit.test( "is() with :has() selectors", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "is() with :has() selectors", function( assert ) {
assert.expect( 6 );
assert.ok( jQuery( "#foo" ).is( ":has(p)" ), "Check for child: Expected a child 'p' element" );
@ -142,7 +142,7 @@ QUnit.test( "is() with :has() selectors", function( assert ) {
assert.ok( !jQuery( "#foo" ).is( jQuery( "div:has(ul)" ) ), "Check for child: Did not expect 'ul' element" );
} );
QUnit.test( "is() with positional selectors", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "is() with positional selectors", function( assert ) {
assert.expect( 27 );
var
@ -279,7 +279,7 @@ QUnit.test( "filter(jQuery)", function( assert ) {
assert.deepEqual( jQuery( "#form input" ).filter( elements ).get(), q( "text1" ), "filter(Element)" );
} );
QUnit.test( "filter() with positional selectors", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "filter() with positional selectors", function( assert ) {
assert.expect( 19 );
var filterit = function( sel, filter, length ) {
@ -354,7 +354,7 @@ QUnit.test( "closest()", function( assert ) {
assert.deepEqual( jq.contents().closest( "*" ).get(), jq.get(), "Text node input (#13332)" );
} );
QUnit.test( "closest() with positional selectors", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "closest() with positional selectors", function( assert ) {
assert.expect( 2 );
assert.deepEqual( jQuery( "#qunit-fixture" ).closest( "div:first" ).get(), [], "closest(div:first)" );
@ -377,8 +377,8 @@ QUnit.test( "closest(jQuery)", function( assert ) {
assert.ok( $child.closest( $body.add( $parent ) ).is( "#nothiddendiv" ), "Closest ancestor retrieved." );
} );
QUnit.test( "not(Selector|undefined)", function( assert ) {
assert.expect( 11 );
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "not(Selector)", function( assert ) {
assert.expect( 7 );
assert.equal( jQuery( "#qunit-fixture > p#ap > a" ).not( "#google" ).length, 2, "not('selector')" );
assert.deepEqual( jQuery( "p" ).not( ".result" ).get(), q( "firstp", "ap", "sndp", "en", "sap", "first" ), "not('.class')" );
assert.deepEqual( jQuery( "p" ).not( "#ap, #sndp, .result" ).get(), q( "firstp", "en", "sap", "first" ), "not('selector, selector')" );
@ -387,12 +387,6 @@ QUnit.test( "not(Selector|undefined)", function( assert ) {
assert.deepEqual( jQuery( "#ap *" ).not( "code, #mark" ).get(), q( "google", "groups", "anchor1" ), "not('tag, ID selector')" );
assert.deepEqual( jQuery( "#ap *" ).not( "#mark, code" ).get(), q( "google", "groups", "anchor1" ), "not('ID, tag selector')" );
var all = jQuery( "p" ).get();
assert.deepEqual( jQuery( "p" ).not( null ).get(), all, "not(null) should have no effect" );
assert.deepEqual( jQuery( "p" ).not( undefined ).get(), all, "not(undefined) should have no effect" );
assert.deepEqual( jQuery( "p" ).not( 0 ).get(), all, "not(0) should have no effect" );
assert.deepEqual( jQuery( "p" ).not( "" ).get(), all, "not('') should have no effect" );
assert.deepEqual(
jQuery( "#form option" ).not( "option.emptyopt:contains('Nothing'),optgroup *,[value='1']" ).get(),
q( "option1c", "option1d", "option2c", "option2d", "option3c", "option3d", "option3e", "option4d", "option4e", "option5a", "option5b" ),
@ -400,6 +394,16 @@ QUnit.test( "not(Selector|undefined)", function( assert ) {
);
} );
QUnit.test( "not(undefined)", function( assert ) {
assert.expect( 4 );
var all = jQuery( "p" ).get();
assert.deepEqual( jQuery( "p" ).not( null ).get(), all, "not(null) should have no effect" );
assert.deepEqual( jQuery( "p" ).not( undefined ).get(), all, "not(undefined) should have no effect" );
assert.deepEqual( jQuery( "p" ).not( 0 ).get(), all, "not(0) should have no effect" );
assert.deepEqual( jQuery( "p" ).not( "" ).get(), all, "not('') should have no effect" );
} );
QUnit.test( "not(Element)", function( assert ) {
assert.expect( 1 );
@ -500,7 +504,7 @@ QUnit.test( "siblings([String])", function( assert ) {
assert.equal( jQuery( "<a/>" ).siblings().length, 0, "Detached elements have no siblings (#11370)" );
} );
QUnit.test( "siblings([String]) - jQuery only", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "siblings([String])", function( assert ) {
assert.expect( 2 );
assert.deepEqual( jQuery( "#sndp" ).siblings( ":has(code)" ).get(), q( "sap" ), "Check for filtered siblings (has code child element)" );
assert.deepEqual( jQuery( "#sndp" ).siblings( ":has(a)" ).get(), q( "en", "sap" ), "Check for filtered siblings (has anchor child element)" );
@ -512,7 +516,7 @@ QUnit.test( "children([String])", function( assert ) {
assert.deepEqual( jQuery( "#foo" ).children( "#en, #sap" ).get(), q( "en", "sap" ), "Check for multiple filters" );
} );
QUnit.test( "children([String]) - jQuery only", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "children([String])", function( assert ) {
assert.expect( 1 );
assert.deepEqual( jQuery( "#foo" ).children( ":has(code)" ).get(), q( "sndp", "sap" ), "Check for filtered children" );
} );