diff --git a/__tests__/utils.test.ts b/__tests__/utils.test.ts index e09b20ed..c7ad7469 100644 --- a/__tests__/utils.test.ts +++ b/__tests__/utils.test.ts @@ -3,41 +3,29 @@ import { displayAmount, displayNumber } from "../src/app/utils"; describe("displayAmount", () => { it("sends error message if noDigits is less than 4", () => { let digits = 3; - const decimalSeparator = "."; - const thousandsSeparator = " "; const inputs: [number, string][] = [ [1234, "ERROR: displayAmount cannot work with noDigits less than 4"], ]; inputs.forEach(([input, expected]) => { - expect( - displayAmount(input, digits, decimalSeparator, thousandsSeparator) - ).toBe(expected); + expect(displayAmount(input, digits)).toBe(expected); }); digits = 0; inputs.forEach(([input, expected]) => { - expect( - displayAmount(input, digits, decimalSeparator, thousandsSeparator) - ).toBe(expected); + expect(displayAmount(input, digits)).toBe(expected); }); digits = -3; inputs.forEach(([input, expected]) => { - expect( - displayAmount(input, digits, decimalSeparator, thousandsSeparator) - ).toBe(expected); + expect(displayAmount(input, digits)).toBe(expected); }); digits = -10; inputs.forEach(([input, expected]) => { - expect( - displayAmount(input, digits, decimalSeparator, thousandsSeparator) - ).toBe(expected); + expect(displayAmount(input, digits)).toBe(expected); }); }); it("displays amounts in 4 digits with thousands_separator", () => { const digits = 4; - const decimalSeparator = "."; - const thousandsSeparator = " "; const inputs: [number, string][] = [ [0, "0"], [0.1, "0.1"], @@ -66,16 +54,12 @@ describe("displayAmount", () => { ]; inputs.forEach(([input, expected]) => { - expect( - displayAmount(input, digits, decimalSeparator, thousandsSeparator) - ).toBe(expected); + expect(displayAmount(input, digits)).toBe(expected); }); }); it("displays amounts in 4 digits without thousands_separator", () => { const digits = 4; - const decimalSeparator = "."; - const thousandsSeparator = ""; const inputs: [number, string][] = [ [0, "0"], [0.1, "0.1"], @@ -106,16 +90,12 @@ describe("displayAmount", () => { ]; inputs.forEach(([input, expected]) => { - expect( - displayAmount(input, digits, decimalSeparator, thousandsSeparator) - ).toBe(expected); + expect(displayAmount(input, digits, -1, ".", "")).toBe(expected); }); }); it("displays amounts in 6 digits with thousands_separator", () => { const digits = 6; - const decimalSeparator = "."; - const thousandsSeparator = " "; const inputs: [number, string][] = [ [0, "0"], [0.1, "0.1"], @@ -147,16 +127,12 @@ describe("displayAmount", () => { ]; inputs.forEach(([input, expected]) => { - expect( - displayAmount(input, digits, decimalSeparator, thousandsSeparator) - ).toBe(expected); + expect(displayAmount(input, digits, -1, ".", " ")).toBe(expected); }); }); it("displays amounts in 10 digits with thousands_separator", () => { const digits = 10; - const decimalSeparator = "."; - const thousandsSeparator = " "; const inputs: [number, string][] = [ [0, "0"], [0.1, "0.1"], @@ -189,16 +165,12 @@ describe("displayAmount", () => { ]; inputs.forEach(([input, expected]) => { - expect( - displayAmount(input, digits, decimalSeparator, thousandsSeparator) - ).toBe(expected); + expect(displayAmount(input, digits, -1, ".", " ")).toBe(expected); }); }); it("displays amounts in 6 digits with thousands_separator and fixed decimals = 3", () => { const digits = 6; - const decimalSeparator = "."; - const thousandsSeparator = " "; const inputs: [number, string][] = [ [0, "0.000"], [0.1, "0.100"], @@ -231,16 +203,12 @@ describe("displayAmount", () => { ]; inputs.forEach(([input, expected]) => { - expect( - displayAmount(input, digits, decimalSeparator, thousandsSeparator, 3) - ).toBe(expected); + expect(displayAmount(input, digits, 3, ".", " ")).toBe(expected); }); }); it("displays amounts in 10 digits with thousands_separator and fixed decimals = 3", () => { const digits = 10; - const decimalSeparator = "."; - const thousandsSeparator = " "; const inputs: [number, string][] = [ [0, "0.000"], [0.1, "0.100"], @@ -273,9 +241,7 @@ describe("displayAmount", () => { ]; inputs.forEach(([input, expected]) => { - expect( - displayAmount(input, digits, decimalSeparator, thousandsSeparator, 3) - ).toBe(expected); + expect(displayAmount(input, digits, 3, ".", " ")).toBe(expected); }); }); }); diff --git a/jest.config.mjs b/jest.config.mjs index b80fa9f9..ef162f9f 100644 --- a/jest.config.mjs +++ b/jest.config.mjs @@ -9,7 +9,7 @@ const createJestConfig = nextJest({ /** @type {import('jest').Config} */ const config = { // Add more setup options before each test is run - // setupFilesAfterEnv: ['/jest.setup.js'], + setupFilesAfterEnv: ["/jest.setup.js"], testEnvironment: "jest-environment-jsdom", }; diff --git a/jest.setup.js b/jest.setup.js new file mode 100644 index 00000000..e93bdd96 --- /dev/null +++ b/jest.setup.js @@ -0,0 +1,10 @@ +const originalToLocaleString = Number.prototype.toLocaleString; + +Number.prototype.toLocaleString = function (locales, options) { + // Call the original method with the 'en-US' locale + // which uses a comma as the thousands separator + // and dots for decimals + const result = originalToLocaleString.call(this, "en-US", options); + // Replace comma with space for thousands separator + return result.replace(/,/g, " "); +}; diff --git a/src/app/components/PriceChart.tsx b/src/app/components/PriceChart.tsx index 963d3e0a..d0aa93ca 100644 --- a/src/app/components/PriceChart.tsx +++ b/src/app/components/PriceChart.tsx @@ -35,63 +35,33 @@ function PriceChartCanvas(props: PriceChartProps) { const theme = tailwindConfig.daisyui.themes[0].dark; const noDigits = 8; - const decimalSeparator = "."; - const thousandSeparator = ","; const fixedDecimals = 6; - const volume = displayAmount( - props.volume || 0, - noDigits, - decimalSeparator, - thousandSeparator, - 2 - ); - - const percChange = displayAmount( - props.percChange || 0, - noDigits, - decimalSeparator, - thousandSeparator, - 2 - ); - - const change = displayAmount( - props.change || 0, - noDigits, - decimalSeparator, - thousandSeparator, - 2 - ); + const volume = displayAmount(props.volume || 0, noDigits, 2); + const percChange = displayAmount(props.percChange || 0, noDigits, 2); + const change = displayAmount(props.change || 0, noDigits, 2); const candleOpen = displayAmount( candlePrice?.open || 0, noDigits, - decimalSeparator, - thousandSeparator, fixedDecimals ); const candleHigh = displayAmount( candlePrice?.high || 0, noDigits, - decimalSeparator, - thousandSeparator, fixedDecimals ); const candleLow = displayAmount( candlePrice?.low || 0, noDigits, - decimalSeparator, - thousandSeparator, fixedDecimals ); const candleClose = displayAmount( candlePrice?.close || 0, noDigits, - decimalSeparator, - thousandSeparator, fixedDecimals ); diff --git a/src/app/components/PriceInfo.tsx b/src/app/components/PriceInfo.tsx index 2ac02cf2..49880f7e 100644 --- a/src/app/components/PriceInfo.tsx +++ b/src/app/components/PriceInfo.tsx @@ -5,44 +5,12 @@ import { displayAmount } from "../utils"; export function PriceInfo() { const priceInfo = useAppSelector((state) => state.priceInfo); const noDigits = 4; - const decimalSeparator = "."; - const thousandSeparator = ","; const fixedDecimals = 3; - const lastPrice = displayAmount( - priceInfo.lastPrice, - noDigits, - decimalSeparator, - thousandSeparator, - fixedDecimals - ); - const change = displayAmount( - priceInfo.change24h, - noDigits, - decimalSeparator, - thousandSeparator, - fixedDecimals - ); - const high = displayAmount( - priceInfo.high24h, - noDigits, - decimalSeparator, - thousandSeparator, - fixedDecimals - ); - const low = displayAmount( - priceInfo.low24h, - noDigits, - decimalSeparator, - thousandSeparator, - fixedDecimals - ); - const volume = displayAmount( - priceInfo.value24h, - noDigits, - decimalSeparator, - thousandSeparator, - fixedDecimals - ); + const lastPrice = displayAmount(priceInfo.lastPrice, noDigits, fixedDecimals); + const change = displayAmount(priceInfo.change24h, noDigits, fixedDecimals); + const high = displayAmount(priceInfo.high24h, noDigits, fixedDecimals); + const low = displayAmount(priceInfo.low24h, noDigits, fixedDecimals); + const volume = displayAmount(priceInfo.value24h, noDigits, fixedDecimals); const isNegativeOrZero = priceInfo.isNegativeOrZero; const basePair = "XRD"; diff --git a/src/app/utils.ts b/src/app/utils.ts index ee6d49e1..5b9b273a 100644 --- a/src/app/utils.ts +++ b/src/app/utils.ts @@ -1,5 +1,3 @@ -// utiluty function to display numbers in a fixed format - export function displayPositiveNumber(x: number, decimals: number): string { // the same as with displayNumber, but if the number is negative, it will return empty string if (x < 0) { @@ -9,19 +7,41 @@ export function displayPositiveNumber(x: number, decimals: number): string { } } +export function getLocaleSeparators(): { + localeDecimalSeparator: string; + localeThousandsSeparator: string; +} { + let localeDecimalSeparator = Number(1.1).toLocaleString().substring(1, 2); + let localeThousandsSeparator = Number(10000).toLocaleString().substring(2, 3); + if (localeThousandsSeparator == "0") { + localeThousandsSeparator = ""; + } + return { + localeDecimalSeparator, + localeThousandsSeparator, + }; +} + export function displayAmount( x: number, noDigits: number = 6, - decimalSeparator: string = ".", - thousandsSeparator: string = " ", - fixedDecimals: number = -1 + fixedDecimals: number = -1, + decimalSeparator: string | undefined = undefined, + thousandsSeparator: string | undefined = undefined ): string { if (noDigits < 4) { return "ERROR: displayAmount cannot work with noDigits less than 4"; } - if (decimalSeparator == "") { - return 'ERROR: desiplayAmount decimalSeparator cannot be ""'; + + const { localeDecimalSeparator, localeThousandsSeparator } = + getLocaleSeparators(); + if (decimalSeparator == undefined) { + decimalSeparator = localeDecimalSeparator; + } + if (thousandsSeparator == undefined) { + thousandsSeparator = localeThousandsSeparator; } + if (x < 1) { let roundedNumber = roundTo(x, noDigits - 2, RoundType.DOWN); if (fixedDecimals >= 0 && fixedDecimals <= noDigits - 2) {