mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-07 18:07:49 +00:00
wip: code formatting nits continued
This commit is contained in:
260
test/number-coercion-methods.spec.js
Normal file
260
test/number-coercion-methods.spec.js
Normal file
@@ -0,0 +1,260 @@
|
||||
import lodashStable from 'lodash';
|
||||
|
||||
import {
|
||||
_,
|
||||
identity,
|
||||
whitespace,
|
||||
MAX_SAFE_INTEGER,
|
||||
MAX_INTEGER,
|
||||
MAX_ARRAY_LENGTH,
|
||||
symbol,
|
||||
falsey,
|
||||
} from './utils';
|
||||
|
||||
describe('number coercion methods', () => {
|
||||
lodashStable.each(['toFinite', 'toInteger', 'toNumber', 'toSafeInteger'], (methodName) => {
|
||||
const func = _[methodName];
|
||||
|
||||
it(`\`_.${methodName}\` should preserve the sign of \`0\``, () => {
|
||||
const values = [0, '0', -0, '-0'];
|
||||
const expected = [
|
||||
[0, Infinity],
|
||||
[0, Infinity],
|
||||
[-0, -Infinity],
|
||||
[-0, -Infinity],
|
||||
];
|
||||
|
||||
lodashStable.times(2, (index) => {
|
||||
const others = lodashStable.map(values, index ? Object : identity);
|
||||
|
||||
const actual = lodashStable.map(others, (value) => {
|
||||
const result = func(value);
|
||||
return [result, 1 / result];
|
||||
});
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
lodashStable.each(
|
||||
['toFinite', 'toInteger', 'toLength', 'toNumber', 'toSafeInteger'],
|
||||
(methodName) => {
|
||||
const func = _[methodName];
|
||||
const isToFinite = methodName === 'toFinite';
|
||||
const isToLength = methodName === 'toLength';
|
||||
const isToNumber = methodName === 'toNumber';
|
||||
const 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`, () => {
|
||||
const values = [0, 1, NaN];
|
||||
|
||||
const expected = lodashStable.map(values, (value) =>
|
||||
!isToNumber && value !== value ? 0 : value,
|
||||
);
|
||||
|
||||
const actual = lodashStable.map(values, func);
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it(`\`_.${methodName}\` should convert number primitives and objects to numbers`, () => {
|
||||
const values = [2, 1.2, MAX_SAFE_INTEGER, MAX_INTEGER, Infinity, NaN];
|
||||
|
||||
const expected = lodashStable.map(values, (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,
|
||||
);
|
||||
}
|
||||
}
|
||||
const neg = isToLength ? 0 : -value;
|
||||
return [value, value, neg, neg];
|
||||
});
|
||||
|
||||
const actual = lodashStable.map(values, (value) => [
|
||||
func(value),
|
||||
func(Object(value)),
|
||||
func(-value),
|
||||
func(Object(-value)),
|
||||
]);
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it(`\`_.${methodName}\` should convert string primitives and objects to numbers`, () => {
|
||||
const transforms = [identity, pad, positive, negative];
|
||||
|
||||
const values = [
|
||||
'10',
|
||||
'1.234567890',
|
||||
`${MAX_SAFE_INTEGER}`,
|
||||
'1e+308',
|
||||
'1e308',
|
||||
'1E+308',
|
||||
'1E308',
|
||||
'5e-324',
|
||||
'5E-324',
|
||||
'Infinity',
|
||||
'NaN',
|
||||
];
|
||||
|
||||
const expected = lodashStable.map(values, (value) => {
|
||||
let n = +value;
|
||||
if (!isToNumber) {
|
||||
if (!isToFinite && n === 1.23456789) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
const neg = isToLength ? 0 : -n;
|
||||
return [n, n, n, n, n, n, neg, neg];
|
||||
});
|
||||
|
||||
const actual = lodashStable.map(values, (value) =>
|
||||
lodashStable.flatMap(transforms, (mod) => [
|
||||
func(mod(value)),
|
||||
func(Object(mod(value))),
|
||||
]),
|
||||
);
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it(`\`_.${methodName}\` should convert binary/octal strings to numbers`, () => {
|
||||
const numbers = [42, 5349, 1715004];
|
||||
const transforms = [identity, pad];
|
||||
const values = ['0b101010', '0o12345', '0x1a2b3c'];
|
||||
|
||||
const expected = lodashStable.map(numbers, (n) =>
|
||||
lodashStable.times(8, lodashStable.constant(n)),
|
||||
);
|
||||
|
||||
const actual = lodashStable.map(values, (value) => {
|
||||
const upper = value.toUpperCase();
|
||||
return lodashStable.flatMap(transforms, (mod) => [
|
||||
func(mod(value)),
|
||||
func(Object(mod(value))),
|
||||
func(mod(upper)),
|
||||
func(Object(mod(upper))),
|
||||
]);
|
||||
});
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it(`\`_.${methodName}\` should convert invalid binary/octal strings to \`${
|
||||
isToNumber ? 'NaN' : '0'
|
||||
}\``, () => {
|
||||
const transforms = [identity, pad, positive, negative];
|
||||
const values = ['0b', '0o', '0x', '0b1010102', '0o123458', '0x1a2b3x'];
|
||||
|
||||
const expected = lodashStable.map(values, (n) =>
|
||||
lodashStable.times(8, lodashStable.constant(isToNumber ? NaN : 0)),
|
||||
);
|
||||
|
||||
const actual = lodashStable.map(values, (value) =>
|
||||
lodashStable.flatMap(transforms, (mod) => [
|
||||
func(mod(value)),
|
||||
func(Object(mod(value))),
|
||||
]),
|
||||
);
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it(`\`_.${methodName}\` should convert symbols to \`${
|
||||
isToNumber ? 'NaN' : '0'
|
||||
}\``, () => {
|
||||
if (Symbol) {
|
||||
const object1 = Object(symbol);
|
||||
const object2 = Object(symbol);
|
||||
const values = [symbol, object1, object2];
|
||||
const expected = lodashStable.map(
|
||||
values,
|
||||
lodashStable.constant(isToNumber ? NaN : 0),
|
||||
);
|
||||
|
||||
object2.valueOf = undefined;
|
||||
const actual = lodashStable.map(values, func);
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
}
|
||||
});
|
||||
|
||||
it(`\`_.${methodName}\` should convert empty values to \`0\` or \`NaN\``, () => {
|
||||
const values = falsey.concat(whitespace);
|
||||
|
||||
const expected = lodashStable.map(values, (value) =>
|
||||
isToNumber && value !== whitespace ? Number(value) : 0,
|
||||
);
|
||||
|
||||
const actual = lodashStable.map(values, (value, index) =>
|
||||
index ? func(value) : func(),
|
||||
);
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it(`\`_.${methodName}\` should coerce objects to numbers`, () => {
|
||||
const 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') },
|
||||
];
|
||||
|
||||
let 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];
|
||||
}
|
||||
const actual = lodashStable.map(values, func);
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user