Заведи каркас пакета и утилитный слой MCP-сервера
package.json, tsconfig, eslint, генерация типов из OpenAPI-спеки, модули config/redact/errors/money/sanitize/cache с тестами и обезличенные фикстуры живых ответов API openrusrouter.ru. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
29 files changed
+11350
No files matched your search
@@ -0,0 +1,61 @@
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import {
|
||||
add,
|
||||
compare,
|
||||
divPow10,
|
||||
mul,
|
||||
mulByBigInt,
|
||||
parseDecimal,
|
||||
round,
|
||||
toFixed,
|
||||
toString,
|
||||
} from "../src/money.js";
|
||||
|
||||
const d = parseDecimal;
|
||||
|
||||
test("0.1 + 0.2 = 0.3", () => {
|
||||
assert.equal(toString(add(d("0.1"), d("0.2"))), "0.3");
|
||||
});
|
||||
|
||||
test("мелкая цена × много токенов без потери точности", () => {
|
||||
assert.equal(toString(mulByBigInt(d("0.00000012"), 50_000_000n)), "6");
|
||||
assert.equal(toString(mulByBigInt(d("0.0000001289925"), 123_456_789n)), "15.9249998550825");
|
||||
// цена за 1M токенов
|
||||
assert.equal(toString(divPow10(d("79.91392973"), 6)), "0.00007991392973");
|
||||
assert.equal(toString(mul(d("1.5"), d("0.25"))), "0.375");
|
||||
assert.equal(toString(mul(d("-1.5"), d("0.2"))), "-0.3");
|
||||
});
|
||||
|
||||
test("round HALF UP — от нуля на .5", () => {
|
||||
assert.equal(toString(round(d("0.125"), 2)), "0.13");
|
||||
assert.equal(toString(round(d("-0.125"), 2)), "-0.13");
|
||||
assert.equal(toString(round(d("0.124999"), 2)), "0.12");
|
||||
assert.equal(toString(round(d("2.5"), 0)), "3");
|
||||
assert.equal(toString(round(d("-2.5"), 0)), "-3");
|
||||
assert.equal(toString(round(d("0.0005"), 3)), "0.001");
|
||||
assert.equal(toString(round(d("-0.0004"), 3)), "0");
|
||||
assert.equal(toFixed(d("1.005"), 2), "1.01");
|
||||
assert.equal(toFixed(d("7"), 2), "7.00");
|
||||
assert.equal(toFixed(d("-0.001"), 2), "0.00");
|
||||
});
|
||||
|
||||
test("parseDecimal строгий", () => {
|
||||
assert.throws(() => parseDecimal(0.1), TypeError);
|
||||
for (const bad of ["1e-7", "", "1,5", " 1", "1.", ".5", "+1", "--1", "NaN"]) {
|
||||
assert.throws(() => parseDecimal(bad), SyntaxError, bad);
|
||||
}
|
||||
assert.equal(toString(d("-12.3400")), "-12.34");
|
||||
});
|
||||
|
||||
test("compare и канонический toString для нулей и отрицательных", () => {
|
||||
assert.equal(compare(d("0"), d("0.0")), 0);
|
||||
assert.equal(compare(d("0.00"), d("-0")), 0);
|
||||
for (const z of ["0", "0.0", "0.00", "-0", "-0.000"]) {
|
||||
assert.equal(toString(d(z)), "0", z);
|
||||
}
|
||||
assert.equal(compare(d("-1.5"), d("-1.49")), -1);
|
||||
assert.equal(compare(d("10"), d("9.999")), 1);
|
||||
assert.equal(toString(d("-0.050")), "-0.05");
|
||||
assert.equal(toString(d("100")), "100");
|
||||
});
|
||||
Reference in new issue
Block a user