Core: Improve isNumeric logic and test coverage

Also add back accidentally deleted comments about the implementation.

Fixes gh-2780
Ref gh-2663
Ref gh-2781
Closes gh-2827
This commit is contained in:
Steve Mao 2016-01-14 20:22:15 +11:00 committed by Richard Gibson
parent e04e246552
commit 7103d8ef47
2 changed files with 28 additions and 3 deletions

View File

@ -217,7 +217,11 @@ jQuery.extend( {
// that can be coerced to finite numbers (gh-2662) // that can be coerced to finite numbers (gh-2662)
var type = jQuery.type( obj ); var type = jQuery.type( obj );
return ( type === "number" || type === "string" ) && return ( type === "number" || type === "string" ) &&
( obj - parseFloat( obj ) + 1 ) >= 0;
// parseFloat NaNs numeric-cast false positives ("")
// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
// subtraction forces infinities to NaN
!isNaN( obj - parseFloat( obj ) );
}, },
isPlainObject: function( obj ) { isPlainObject: function( obj ) {

View File

@ -449,7 +449,7 @@ QUnit.test( "isFunction", function( assert ) {
} ); } );
QUnit.test( "isNumeric", function( assert ) { QUnit.test( "isNumeric", function( assert ) {
assert.expect( 38 ); assert.expect( 41 );
var t = jQuery.isNumeric, var t = jQuery.isNumeric,
ToString = function( value ) { ToString = function( value ) {
@ -464,8 +464,29 @@ QUnit.test( "isNumeric", function( assert ) {
assert.ok( t( -16 ), "Negative integer number" ); assert.ok( t( -16 ), "Negative integer number" );
assert.ok( t( 0 ), "Zero integer number" ); assert.ok( t( 0 ), "Zero integer number" );
assert.ok( t( 32 ), "Positive integer number" ); assert.ok( t( 32 ), "Positive integer number" );
if ( +"0b1" === 1 ) {
assert.ok( t( "0b111110" ), "Binary integer literal string" ); // jshint ignore:line
} else {
assert.ok( true, "Browser does not support binary integer literal" );
}
assert.ok( t( "040" ), "Octal integer literal string" ); assert.ok( t( "040" ), "Octal integer literal string" );
assert.ok( t( "0xFF" ), "Hexadecimal integer literal string" ); assert.ok( t( "0xFF" ), "Hexadecimal integer literal string" );
if ( +"0b1" === 1 ) {
assert.ok( t( 0b111110 ), "Binary integer literal" ); // jshint ignore:line
} else {
assert.ok( true, "Browser does not support binary integer literal" );
}
if ( +"0o1" === 1 ) {
assert.ok( t( 0o76 ), "Octal integer literal" ); // jshint ignore:line
} else {
assert.ok( true, "Browser does not support octal integer literal" );
}
assert.ok( t( 0xFFF ), "Hexadecimal integer literal" ); assert.ok( t( 0xFFF ), "Hexadecimal integer literal" );
assert.ok( t( "-1.6" ), "Negative floating point string" ); assert.ok( t( "-1.6" ), "Negative floating point string" );
assert.ok( t( "4.536" ), "Positive floating point string" ); assert.ok( t( "4.536" ), "Positive floating point string" );
@ -475,7 +496,7 @@ QUnit.test( "isNumeric", function( assert ) {
assert.ok( t( 8e5 ), "Exponential notation" ); assert.ok( t( 8e5 ), "Exponential notation" );
assert.ok( t( "123e-2" ), "Exponential notation string" ); assert.ok( t( "123e-2" ), "Exponential notation string" );
assert.equal( t( new ToString( "42" ) ), false, "Custom .toString returning number" ); assert.equal( t( new ToString( "42" ) ), false, "Only limited to strings and numbers" );
assert.equal( t( "" ), false, "Empty string" ); assert.equal( t( "" ), false, "Empty string" );
assert.equal( t( " " ), false, "Whitespace characters string" ); assert.equal( t( " " ), false, "Whitespace characters string" );
assert.equal( t( "\t\t" ), false, "Tab characters string" ); assert.equal( t( "\t\t" ), false, "Tab characters string" );