Skip to content

Instantly share code, notes, and snippets.

@alexcjohnson
Created May 11, 2015 03:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexcjohnson/74902c646f08f456dd56 to your computer and use it in GitHub Desktop.
Save alexcjohnson/74902c646f08f456dd56 to your computer and use it in GitHub Desktop.
Plotly isNumeric implementation
/**
* inspired by is-number <https://github.com/jonschlinkert/is-number>
* but significantly simplified and sped up by ignoring number and string constructors
* ie these return false:
* new Number(1)
* new String('1')
*/
'use strict';
/**
* Is this string all whitespace?
* This solution kind of makes my brain hurt, but it's significantly faster
* than !str.trim() or any other solution I could find.
*
* whitespace codes from: http://en.wikipedia.org/wiki/Whitespace_character
* and verified with:
*
* for(var i = 0; i < 65536; i++) {
* var s = String.fromCharCode(i);
* if(+s===0 && !s.trim()) console.log(i, s);
* }
*
* which counts a couple of these as *not* whitespace, but finds nothing else
* that *is* whitespace. Note that charCodeAt stops at 16 bits, but it appears
* that there are no whitespace characters above this, and code points above
* this do not map onto white space characters.
*/
function allBlankCharCodes(str){
var l = str.length,
a;
for(var i = 0; i < l; i++) {
a = str.charCodeAt(i);
if((a < 9 || a > 13) && (a !== 32) && (a !== 133) && (a !== 160) &&
(a !== 5760) && (a !== 6158) && (a < 8192 || a > 8205) &&
(a !== 8232) && (a !== 8233) && (a !== 8239) && (a !== 8287) &&
(a !== 8288) && (a !== 12288) && (a !== 65279)) {
return false;
}
}
return true;
}
module.exports = function(n) {
var type = typeof n;
if(type === 'string') {
var original = n;
n = +n;
// whitespace strings cast to zero - filter them out
if(n===0 && allBlankCharCodes(original)) return false;
}
else if(type !== 'number') return false;
return n - n < 1;
};
/**
* adapted from is-number tests by AJ
* took out tests that only pass bcs javascript is weird
* but don't say anything about the routine
* like +'', +null, and +[] - these get turned into the number 0 before being tested
* so they pass, but I don't see the relevance of that conversion to the code here!
* of course '', null, and [] themselves should fail, and are tested as such.
*
* also took out Buffer, as we're concerned about browsers here.
*/
/*!
* is-number <https://github.com/jonschlinkert/is-number>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
var isNumeric = require('../src/isnumeric');
describe('isNumeric', function() {
'use strict';
var shouldPass = [
0xff,
5e3,
0,
0.1,
-0.1,
-1.1,
37,
3.14,
1,
1.1,
10,
10.10,
100,
-100,
'0.1',
'-0.1',
'-1.1',
'+0.1',
'+1.1',
'0',
'+0',
'-0',
'012',
'0xff',
'1',
'1.1',
'10',
'10.10',
'100',
'5e3',
Math.LN2,
Number(1),
// 012, Octal literal not allowed in strict mode
parseInt('012'),
parseFloat('012'),
Math.abs(1),
Math.acos(1),
Math.asin(1),
Math.atan(1),
Math.atan2(1, 2),
Math.ceil(1),
Math.cos(1),
Math.E,
Math.exp(1),
Math.floor(1),
Math.LN10,
Math.LN2,
Math.log(1),
Math.LOG10E,
Math.LOG2E,
Math.max(1, 2),
Math.min(1, 2),
Math.PI,
Math.pow(1, 2),
Math.pow(5, 5),
Math.random(1),
Math.round(1),
Math.sin(1),
Math.sqrt(1),
Math.SQRT1_2,
Math.SQRT2,
Math.tan(1),
Number.MAX_VALUE,
Number.MIN_VALUE,
'0.0',
'0x0',
'0e+5',
'000',
'0.0e-5',
'0.0E5',
'-0',
'-0.0',
'-0e+5',
'-000',
'-0.0e-5',
'-0.0E5',
'+0',
'+0.0',
'+0e+5',
'+000',
'+0.0e-5',
'+0.0E5',
' 1',
'1 ',
'\t \r\n0.0 \n\r\t'
];
var shouldFail = [
'',
'\t',
'\r',
'\n',
' \r \t \n\r\n',
' some text with spaces ',
'0.0 whats this?',
'3a',
'a3',
'3_4',
'3-4',
'3+4',
'3*4',
'3/4',
'abc',
'false',
'null',
'true',
'undefined',
/foo/,
[1, 2, 3],
[1],
[[1]],
[],
Boolean(true),
false,
function () {},
function() {},
function(){},
function(v) { return v; },
Infinity,
Math.sin,
NaN,
new Array(''),
new Array('abc'),
new Array(0),
new Boolean(true),
new Date(),
new RegExp('foo'),
new String('abc'),
null,
String('abc'),
true,
undefined,
{a: 1},
{abc: 'abc'},
{1: 2},
{},
'-0x0', // +/- hex turns out to not be supported by casting to number
'+0x0',
new Number(1), // performance decision: do not support object numbers and strings
new String('1')
];
shouldPass.forEach(function (num) {
it('treats ' + JSON.stringify(num) + ' as a number', function () {
expect(isNumeric(num)).toBe(true);
});
});
shouldFail.forEach(function (num) {
it('treats ' + JSON.stringify(num) + ' as NOT a number', function () {
expect(isNumeric(num)).toBe(false);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment