mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 04:12:10 +03:00
90 lines
3.3 KiB
TypeScript
90 lines
3.3 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
|
|
import {
|
|
toNumber,
|
|
toNumberOrNull,
|
|
toNumberArray,
|
|
} from "../../src/shared/utils/numeric.ts";
|
|
|
|
// Shared input matrix covering the coercion edge cases that motivated
|
|
// consolidating ~51 near-duplicate `toNumber` definitions (#7879).
|
|
const CASES: Array<{ label: string; input: unknown; finite: number | null }> = [
|
|
{ label: "null", input: null, finite: null },
|
|
{ label: "undefined", input: undefined, finite: null },
|
|
{ label: "empty string", input: "", finite: null },
|
|
{ label: "whitespace string", input: " ", finite: null },
|
|
{ label: "numeric string", input: "12", finite: 12 },
|
|
{ label: "decimal string", input: "12.5", finite: 12.5 },
|
|
{ label: "negative string", input: "-3", finite: -3 },
|
|
{ label: "zero string", input: "0", finite: 0 },
|
|
{ label: "non-numeric string", input: "abc", finite: null },
|
|
{ label: "partially-numeric string", input: "12abc", finite: null },
|
|
{ label: "NaN", input: NaN, finite: null },
|
|
{ label: "Infinity", input: Infinity, finite: null },
|
|
{ label: "-Infinity", input: -Infinity, finite: null },
|
|
{ label: "plain object", input: {}, finite: null },
|
|
{ label: "empty array", input: [], finite: null },
|
|
{ label: "exponential string", input: "1e3", finite: 1000 },
|
|
{ label: "boolean true", input: true, finite: null },
|
|
];
|
|
|
|
test("toNumber: matrix with default fallback (0)", () => {
|
|
for (const { label, input, finite } of CASES) {
|
|
const expected = finite ?? 0;
|
|
assert.equal(toNumber(input), expected, `toNumber(${label}) should be ${expected}`);
|
|
}
|
|
});
|
|
|
|
test("toNumber: matrix with custom fallback", () => {
|
|
for (const { label, input, finite } of CASES) {
|
|
const expected = finite ?? -1;
|
|
assert.equal(
|
|
toNumber(input, -1),
|
|
expected,
|
|
`toNumber(${label}, -1) should be ${expected}`
|
|
);
|
|
}
|
|
});
|
|
|
|
test("toNumber: numbers pass through untouched", () => {
|
|
assert.equal(toNumber(42), 42);
|
|
assert.equal(toNumber(-7.5), -7.5);
|
|
assert.equal(toNumber(0), 0);
|
|
});
|
|
|
|
test("toNumberOrNull: matrix returns null instead of 0 fallback", () => {
|
|
for (const { label, input, finite } of CASES) {
|
|
assert.equal(
|
|
toNumberOrNull(input),
|
|
finite,
|
|
`toNumberOrNull(${label}) should be ${finite}`
|
|
);
|
|
}
|
|
});
|
|
|
|
test("toNumberOrNull: numbers pass through untouched", () => {
|
|
assert.equal(toNumberOrNull(42), 42);
|
|
assert.equal(toNumberOrNull(0), 0);
|
|
});
|
|
|
|
test("toNumberArray: non-array input returns the fallback unchanged", () => {
|
|
assert.deepEqual(toNumberArray(null), []);
|
|
assert.deepEqual(toNumberArray(undefined), []);
|
|
assert.deepEqual(toNumberArray("not an array"), []);
|
|
assert.deepEqual(toNumberArray({}), []);
|
|
assert.deepEqual(toNumberArray(null, [1, 2]), [1, 2]);
|
|
});
|
|
|
|
test("toNumberArray: maps each element through toNumber, bad elements become 0", () => {
|
|
assert.deepEqual(toNumberArray(["12", "12.5", "abc", null, 3]), [12, 12.5, 0, 0, 3]);
|
|
assert.deepEqual(toNumberArray([]), []);
|
|
});
|
|
|
|
test("toNumberArray: element-level fallback (0) is independent of the array-level fallback", () => {
|
|
// Array itself IS present (so array-level fallback does not apply), but one
|
|
// element fails to coerce and must fall back to 0, not to the caller's
|
|
// array-level fallback value.
|
|
assert.deepEqual(toNumberArray(["abc"], [99]), [0]);
|
|
});
|