Files
lodash/test/number-coercion-methods.js
Benjamin Tan d5ef31929a Add initial test files from lodash v4. (#4172)
* Install test dependencies.

* Add initial test files.

These files were created using a simplistic AST manipulator using `recast` to
preserve formatting. There's bound to be a huge chunk of errors, but this serves
as a good start. QUnit was replaced with Mocha, with ES2015 imports running via
`esm`.

As far as possible, QUnit-specific syntax has been replaced with Mocha's
`describe` and `it`, while the native Node.js `assert` module is used for
assertions. Files in the `test` directory ending in `.test.js` will be treated
as test files.

* Add initial passing files to test run.
2019-02-12 09:11:32 -08:00

249 lines
7.7 KiB
JavaScript

import assert from 'assert';
import lodashStable from 'lodash';
import {
_,
identity,
whitespace,
MAX_SAFE_INTEGER,
MAX_INTEGER,
MAX_ARRAY_LENGTH,
symbol,
falsey,
} from './utils.js';
describe('number coercion methods', function() {
lodashStable.each(['toFinite', 'toInteger', 'toNumber', 'toSafeInteger'], function(methodName) {
var func = _[methodName];
it('`_.' + methodName + '` should preserve the sign of `0`', function() {
var values = [0, '0', -0, '-0'],
expected = [[0, Infinity], [0, Infinity], [-0, -Infinity], [-0, -Infinity]];
lodashStable.times(2, function(index) {
var others = lodashStable.map(values, index ? Object : identity);
var actual = lodashStable.map(others, function(value) {
var result = func(value);
return [result, 1 / result];
});
assert.deepStrictEqual(actual, expected);
});
});
});
lodashStable.each(['toFinite', 'toInteger', 'toLength', 'toNumber', 'toSafeInteger'], function(methodName) {
var func = _[methodName],
isToFinite = methodName == 'toFinite',
isToLength = methodName == 'toLength',
isToNumber = methodName == 'toNumber',
isToSafeInteger = methodName == 'toSafeInteger';
function negative(string) {
return '-' + string;
}
function pad(string) {
return whitespace + string + whitespace;
}
function positive(string) {
return '+' + string;
}
it('`_.' + methodName + '` should pass thru primitive number values', function() {
var values = [0, 1, NaN];
var expected = lodashStable.map(values, function(value) {
return (!isToNumber && value !== value) ? 0 : value;
});
var actual = lodashStable.map(values, func);
assert.deepStrictEqual(actual, expected);
});
it('`_.' + methodName + '` should convert number primitives and objects to numbers', function() {
var values = [2, 1.2, MAX_SAFE_INTEGER, MAX_INTEGER, Infinity, NaN];
var expected = lodashStable.map(values, function(value) {
if (!isToNumber) {
if (!isToFinite && value == 1.2) {
value = 1;
}
else if (value == Infinity) {
value = MAX_INTEGER;
}
else if (value !== value) {
value = 0;
}
if (isToLength || isToSafeInteger) {
value = Math.min(value, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
}
}
var neg = isToLength ? 0 : -value;
return [value, value, neg, neg];
});
var actual = lodashStable.map(values, function(value) {
return [func(value), func(Object(value)), func(-value), func(Object(-value))];
});
assert.deepStrictEqual(actual, expected);
});
it('`_.' + methodName + '` should convert string primitives and objects to numbers', function() {
var transforms = [identity, pad, positive, negative];
var values = [
'10', '1.234567890', (MAX_SAFE_INTEGER + ''),
'1e+308', '1e308', '1E+308', '1E308',
'5e-324', '5E-324',
'Infinity', 'NaN'
];
var expected = lodashStable.map(values, function(value) {
var n = +value;
if (!isToNumber) {
if (!isToFinite && n == 1.234567890) {
n = 1;
}
else if (n == Infinity) {
n = MAX_INTEGER;
}
else if ((!isToFinite && n == Number.MIN_VALUE) || n !== n) {
n = 0;
}
if (isToLength || isToSafeInteger) {
n = Math.min(n, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
}
}
var neg = isToLength ? 0 : -n;
return [n, n, n, n, n, n, neg, neg];
});
var actual = lodashStable.map(values, function(value) {
return lodashStable.flatMap(transforms, function(mod) {
return [func(mod(value)), func(Object(mod(value)))];
});
});
assert.deepStrictEqual(actual, expected);
});
it('`_.' + methodName + '` should convert binary/octal strings to numbers', function() {
var numbers = [42, 5349, 1715004],
transforms = [identity, pad],
values = ['0b101010', '0o12345', '0x1a2b3c'];
var expected = lodashStable.map(numbers, function(n) {
return lodashStable.times(8, lodashStable.constant(n));
});
var actual = lodashStable.map(values, function(value) {
var upper = value.toUpperCase();
return lodashStable.flatMap(transforms, function(mod) {
return [func(mod(value)), func(Object(mod(value))), func(mod(upper)), func(Object(mod(upper)))];
});
});
assert.deepStrictEqual(actual, expected);
});
it('`_.' + methodName + '` should convert invalid binary/octal strings to `' + (isToNumber ? 'NaN' : '0') + '`', function() {
var transforms = [identity, pad, positive, negative],
values = ['0b', '0o', '0x', '0b1010102', '0o123458', '0x1a2b3x'];
var expected = lodashStable.map(values, function(n) {
return lodashStable.times(8, lodashStable.constant(isToNumber ? NaN : 0));
});
var actual = lodashStable.map(values, function(value) {
return lodashStable.flatMap(transforms, function(mod) {
return [func(mod(value)), func(Object(mod(value)))];
});
});
assert.deepStrictEqual(actual, expected);
});
it('`_.' + methodName + '` should convert symbols to `' + (isToNumber ? 'NaN' : '0') + '`', function() {
if (Symbol) {
var object1 = Object(symbol),
object2 = Object(symbol),
values = [symbol, object1, object2],
expected = lodashStable.map(values, lodashStable.constant(isToNumber ? NaN : 0));
object2.valueOf = undefined;
var actual = lodashStable.map(values, func);
assert.deepStrictEqual(actual, expected);
}
});
it('`_.' + methodName + '` should convert empty values to `0` or `NaN`', function() {
var values = falsey.concat(whitespace);
var expected = lodashStable.map(values, function(value) {
return (isToNumber && value !== whitespace) ? Number(value) : 0;
});
var actual = lodashStable.map(values, function(value, index) {
return index ? func(value) : func();
});
assert.deepStrictEqual(actual, expected);
});
it('`_.' + methodName + '` should coerce objects to numbers', function() {
var values = [
{},
[],
[1],
[1, 2],
{ 'valueOf': '1.1' },
{ 'valueOf': '1.1', 'toString': lodashStable.constant('2.2') },
{ 'valueOf': lodashStable.constant('1.1'), 'toString': '2.2' },
{ 'valueOf': lodashStable.constant('1.1'), 'toString': lodashStable.constant('2.2') },
{ 'valueOf': lodashStable.constant('-0x1a2b3c') },
{ 'toString': lodashStable.constant('-0x1a2b3c') },
{ 'valueOf': lodashStable.constant('0o12345') },
{ 'toString': lodashStable.constant('0o12345') },
{ 'valueOf': lodashStable.constant('0b101010') },
{ 'toString': lodashStable.constant('0b101010') }
];
var expected = [
NaN, 0, 1, NaN,
NaN, 2.2, 1.1, 1.1,
NaN, NaN,
5349, 5349,
42, 42
];
if (isToFinite) {
expected = [
0, 0, 1, 0,
0, 2.2, 1.1, 1.1,
0, 0,
5349, 5349,
42, 42
];
}
else if (!isToNumber) {
expected = [
0, 0, 1, 0,
0, 2, 1, 1,
0, 0,
5349, 5349,
42, 42
];
}
var actual = lodashStable.map(values, func);
assert.deepStrictEqual(actual, expected);
});
});
});