95 lines
3.5 KiB
TypeScript
95 lines
3.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
||
|
||
import {
|
||
formatDate,
|
||
formatMoney,
|
||
formatPercentagePoints,
|
||
formatSignedPercent,
|
||
formatSnapshotDay,
|
||
formatSnapshotTime,
|
||
instrumentLogoUrl,
|
||
} from "./display";
|
||
|
||
describe("shared display helpers", () => {
|
||
it("formats signed rates as percentages and percentage points without negative zero", () => {
|
||
expect(formatSignedPercent("0.151")).toBe("+15,1 %");
|
||
expect(formatSignedPercent("-0.15149")).toBe("−15,1 %");
|
||
expect(formatSignedPercent("0")).toBe("0,0 %");
|
||
expect(formatSignedPercent("-0.00049")).toBe("0,0 %");
|
||
expect(formatPercentagePoints("0.043")).toBe("+4,3 п.п.");
|
||
expect(formatPercentagePoints("-0.0435")).toBe("−4,4 п.п.");
|
||
});
|
||
it("uses padded Russian dates and preserves the UTC date of timestamps", () => {
|
||
expect(formatDate("2027-09-10")).toBe("10.09.2027");
|
||
expect(formatDate("2024-02-29")).toBe("29.02.2024");
|
||
expect(formatDate("2027-09-10T00:30:00+03:00")).toBe("09.09.2027");
|
||
});
|
||
it("formats snapshot time in the browser time zone", () => {
|
||
const instant = "2027-09-10T00:30:00+03:00";
|
||
|
||
const expected = new Intl.DateTimeFormat("ru-RU", {
|
||
dateStyle: "short",
|
||
timeStyle: "short",
|
||
}).format(new Date(instant));
|
||
|
||
expect(formatSnapshotTime(instant)).toBe(expected);
|
||
expect(formatSnapshotDay(instant)).toBe(
|
||
new Intl.DateTimeFormat("ru-RU", { dateStyle: "short" })
|
||
.format(new Date(instant)),
|
||
);
|
||
});
|
||
it("formats decimal strings without financial arithmetic", () => {
|
||
expect(formatMoney({ currency: "RUB", value: "-1234567.89" })).toBe(
|
||
"-1 234 567,89 ₽",
|
||
);
|
||
expect(formatMoney({ currency: "RUB", value: "10" })).toBe("10 ₽");
|
||
expect(formatMoney({ currency: "USD", value: "0.5" })).toBe("0,5 $");
|
||
expect(formatMoney({ currency: "RUB", value: "0001234.50" })).toBe(
|
||
"0 001 234,50 ₽",
|
||
);
|
||
expect(
|
||
formatMoney({
|
||
currency: "RUB",
|
||
value: "123456789012345678901234567890.01",
|
||
}),
|
||
).toBe("123 456 789 012 345 678 901 234 567 890,01 ₽");
|
||
expect(
|
||
formatMoney({ currency: "RUB", value: "1.5" }, { withZeroCents: true }),
|
||
).toBe("1,50 ₽");
|
||
expect(formatMoney(null)).toBe("—");
|
||
expect(formatMoney(
|
||
{ currency: "RUB", value: "136900" },
|
||
{ withSign: true },
|
||
)).toBe("+136 900 ₽");
|
||
expect(formatMoney(
|
||
{ currency: "RUB", value: "-4200" },
|
||
{ withSign: true },
|
||
)).toBe("−4 200 ₽");
|
||
expect(formatMoney(
|
||
{ currency: "RUB", value: "-0.00" },
|
||
{ withSign: true },
|
||
)).toBe("0,00 ₽");
|
||
});
|
||
|
||
it("rounds to the currency's minor units and drops the sign of a rounded zero", () => {
|
||
const rounded = { withRoundedCents: true };
|
||
expect(formatMoney({ currency: "RUB", value: "-0.004" }, rounded)).toBe("0,00 ₽");
|
||
expect(formatMoney({ currency: "RUB", value: "-0.005" }, rounded)).toBe("-0,01 ₽");
|
||
expect(formatMoney({ currency: "RUB", value: "999.995" }, rounded)).toBe("1 000,00 ₽");
|
||
expect(formatMoney({ currency: "JPY", value: "1500.5" }, rounded)).toBe("1 501 JPY");
|
||
expect(formatMoney({ currency: "KWD", value: "1.2345" }, rounded)).toBe("1,235 KWD");
|
||
expect(formatMoney({ currency: "ZZZ", value: "1.234" }, rounded)).toBe("1,23 ZZZ");
|
||
});
|
||
|
||
it("builds the brand logo url from an upstream file name", () => {
|
||
expect(instrumentLogoUrl("sber3.png")).toBe(
|
||
"https://invest-brands.cdn-tinkoff.ru/sber3x160.png",
|
||
);
|
||
expect(instrumentLogoUrl(" RU000A0JPNM1.png ")).toBe(
|
||
"https://invest-brands.cdn-tinkoff.ru/RU000A0JPNM1x160.png",
|
||
);
|
||
expect(instrumentLogoUrl(null)).toBeNull();
|
||
expect(instrumentLogoUrl(" ")).toBeNull();
|
||
});
|
||
});
|