0

I'm writing unit tests for a function that's supposed to return a float. I'm trying to prevent someone from sending a set of characters (notice I didn't say string) to the function, like 3.2.1. If I use the normal tests for this "number", they all seem to fail with:

Uncaught SyntaxError: missing ) after argument list.

EG:

  • var result = isNaN(3.2.1); //same error
  • var result = parseFloat(3.2.1); //expecting a NaN, but get the error instead
  • var result = typeof 3.2.1 === 'number' //same error

I suppose I could wrap it in quotes and test it as a string (all the tests above work as expected when the predicate is a string).

Various SO questions that haven't answered this one:

So, the actual question: how can I test for a 'number' that has multiple decimal points and reject it?

Here's my actual code where most of the tests run successfully:

/**
* 
* @param {*} value 
* Converts a numeric string value to a float for use by a timeout interval
* datatype: ParseTimeoutInterval(string)
* example: ParseTimeoutInterval('2.5')
* return type: float
* return example: 2.5
*/
SerialWidget.prototype.ParseTimeoutInterval = function (value) {

try {
    var self = this;

    self.CallListeners('debug', 'ParseTimeoutInterval: value = ' + value);

    if (value) {
        var result = parseFloat(value);
        if(result < 0 || isNaN(result)){
            self.CallListeners('debug', 'ParseTimeoutInterval: value is negative or NaN');
            return null;            
        }
    return result.toPrecision(2);

    } else {
        return null;    
    }
    self.CallListeners('debug', 'ParseTimeoutInterval: value is not a number');
    return null;

} catch (ex) {
    self.OnError('ParseTimeoutInterval', ex.message);
}
};
delliottg
  • 3,950
  • 3
  • 38
  • 52
  • 3
    There's no such a number (or any other data type in JS) with two decimal dots, it's just a syntax error, as you've already found out. Hence nobody can send it as it is, the only way is to send alike string. – Teemu Jun 25 '18 at 18:33
  • This is a great observation, after playing with my tests I realized I can't even get them past the linter using 3.2.1, it has to be enclosed in a string. – delliottg Jun 25 '18 at 19:29

1 Answers1

2

Assuming you're good with checking a string, you could then split it into an array and check the length.

var badNumber = '3.2.1';
if (badNumber.split('.').length > 2) {
    console.error('uh oh. THAT\'s not a number!');
} else {
    // proceed
}
mccambridge
  • 983
  • 7
  • 16
  • 1
    Can you split a non-string? '3.2.1' is not the same as 3.2.1 – delliottg Jun 25 '18 at 18:30
  • 2
    I was making a big assumption that you were getting it from a source that was able to create it. But trying to make it work in a console, I wonder if you can ever even work with `3.2.1` in JS. Might be wrong -- but I don't think that's syntactically valid. – mccambridge Jun 25 '18 at 18:33
  • 1
    `String(3.2.1)` doesn't work. So I can't imagine anything else could work. – mccambridge Jun 25 '18 at 18:34
  • 1
    I believe you're correct, and I've been fretting about something that's not actually an issue since the characters can't even be sent from the test (or at least won't get past the linter I'm using in VS Code. – delliottg Jun 25 '18 at 19:30