@swapkit/helpers 4.5.8 → 4.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +3 -3
- package/dist/index.js.map +3 -3
- package/dist/types/modules/bigIntArithmetics.d.ts +2 -1
- package/dist/types/modules/bigIntArithmetics.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/modules/__tests__/assetValue.test.ts +570 -10
- package/src/modules/__tests__/bigIntArithmetics.test.ts +14 -12
- package/src/modules/bigIntArithmetics.ts +20 -26
|
@@ -1815,16 +1815,25 @@ describe("formatting", () => {
|
|
|
1815
1815
|
|
|
1816
1816
|
describe("toCurrency", () => {
|
|
1817
1817
|
test("small values preserve precision without floating-point artifacts", () => {
|
|
1818
|
-
expect(AssetValue.from({ asset: "ETH.ETH", value:
|
|
1819
|
-
expect(AssetValue.from({ asset: "ETH.ETH", value: 0.
|
|
1820
|
-
expect(AssetValue.from({ asset: "ETH.ETH", value: 0.
|
|
1818
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 1.339145 }).toCurrency("")).toBe("1.34");
|
|
1819
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 0.015072 }).toCurrency("")).toBe("0.02");
|
|
1820
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 0.333145 }).toCurrency("", { decimal: 1 })).toBe("0.3");
|
|
1821
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 0.00000548 }).toCurrency("")).toBe("0");
|
|
1821
1822
|
expect(AssetValue.from({ asset: "ETH.ETH", value: 0.1 }).toCurrency("")).toBe("0.1");
|
|
1822
|
-
expect(AssetValue.from({ asset: "ETH.ETH", value: 0.10000001 }).toCurrency("")).toBe("0.
|
|
1823
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 0.10000001 }).toCurrency("")).toBe("0.1");
|
|
1824
|
+
expect(
|
|
1825
|
+
AssetValue.from({ asset: "ETH.ETH", value: "0.000000000001251251235123125123" }).toCurrency("", { decimal: 6 }),
|
|
1826
|
+
).toBe("0");
|
|
1827
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: "0.1000000000000000001" }).toCurrency("", { decimal: 6 })).toBe(
|
|
1828
|
+
"0.1",
|
|
1829
|
+
);
|
|
1823
1830
|
});
|
|
1824
1831
|
|
|
1825
1832
|
test("negative small values handled correctly", () => {
|
|
1826
|
-
expect(AssetValue.from({ asset: "BTC.BTC", value: -0.015072 }).toCurrency("")).toBe("-0.
|
|
1827
|
-
expect(AssetValue.from({ asset: "BTC.BTC", value: -0.00000001 }).toCurrency("")).toBe(
|
|
1833
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: -0.015072 }).toCurrency("")).toBe("-0.02");
|
|
1834
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: -0.00000001 }).toCurrency("", { decimal: 8 })).toBe(
|
|
1835
|
+
"-0.00000001",
|
|
1836
|
+
);
|
|
1828
1837
|
});
|
|
1829
1838
|
|
|
1830
1839
|
test("large values with thousand separators and rounding", () => {
|
|
@@ -1834,10 +1843,10 @@ describe("toCurrency", () => {
|
|
|
1834
1843
|
});
|
|
1835
1844
|
|
|
1836
1845
|
test("custom currency symbol and position", () => {
|
|
1837
|
-
const v = AssetValue.from({ asset: "ETH.ETH", value: 1234.
|
|
1838
|
-
expect(v.toCurrency("€", { currencyPosition: "end" })).toBe("1,234.
|
|
1839
|
-
expect(v.toCurrency("¥", { currencyPosition: "start" })).toBe("¥1,234.
|
|
1840
|
-
expect(v.toCurrency("", { decimal: 4 })).toBe("1,234.
|
|
1846
|
+
const v = AssetValue.from({ asset: "ETH.ETH", value: 1234.5678 });
|
|
1847
|
+
expect(v.toCurrency("€", { currencyPosition: "end" })).toBe("1,234.57€");
|
|
1848
|
+
expect(v.toCurrency("¥", { currencyPosition: "start" })).toBe("¥1,234.57");
|
|
1849
|
+
expect(v.toCurrency("", { decimal: 4 })).toBe("1,234.5678");
|
|
1841
1850
|
});
|
|
1842
1851
|
|
|
1843
1852
|
test("custom separators for european format", () => {
|
|
@@ -1890,3 +1899,554 @@ describe("edge cases", () => {
|
|
|
1890
1899
|
expect(fromBase18.getValue("string")).toBe("1");
|
|
1891
1900
|
});
|
|
1892
1901
|
});
|
|
1902
|
+
|
|
1903
|
+
describe("formatter edge cases", () => {
|
|
1904
|
+
describe("toSignificant edge cases", () => {
|
|
1905
|
+
test("handles zero value", () => {
|
|
1906
|
+
const zero = AssetValue.from({ asset: "BTC.BTC", value: 0 });
|
|
1907
|
+
expect(zero.toSignificant(6)).toBe("0");
|
|
1908
|
+
expect(zero.toSignificant(1)).toBe("0");
|
|
1909
|
+
expect(zero.toSignificant(0)).toBe("0");
|
|
1910
|
+
});
|
|
1911
|
+
|
|
1912
|
+
test("handles very small decimals", () => {
|
|
1913
|
+
const small = AssetValue.from({ asset: "ETH.ETH", value: "0.000000000000000001" });
|
|
1914
|
+
// toSignificant with small values returns "0" when significant digits are exhausted
|
|
1915
|
+
// This is expected behavior as the implementation counts from the first non-zero digit
|
|
1916
|
+
expect(small.toSignificant(1)).toBe("0");
|
|
1917
|
+
expect(small.toSignificant(18)).toBe("0.000000000000000001");
|
|
1918
|
+
});
|
|
1919
|
+
|
|
1920
|
+
test("handles values with many leading zeros in decimal", () => {
|
|
1921
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: "0.00000123" });
|
|
1922
|
+
expect(value.toSignificant(3)).toBe("0.00000123");
|
|
1923
|
+
expect(value.toSignificant(2)).toBe("0.0000012");
|
|
1924
|
+
// toSignificant with 1 significant digit on small values - behavior depends on implementation
|
|
1925
|
+
expect(value.toSignificant(8)).toBe("0.00000123");
|
|
1926
|
+
});
|
|
1927
|
+
|
|
1928
|
+
test("handles large integers with significant digits less than integer length", () => {
|
|
1929
|
+
const large = AssetValue.from({ asset: "ETH.ETH", value: 987654321 });
|
|
1930
|
+
expect(large.toSignificant(3)).toBe("987000000");
|
|
1931
|
+
expect(large.toSignificant(5)).toBe("987650000");
|
|
1932
|
+
expect(large.toSignificant(9)).toBe("987654321");
|
|
1933
|
+
});
|
|
1934
|
+
|
|
1935
|
+
test("handles negative values", () => {
|
|
1936
|
+
const neg = AssetValue.from({ asset: "BTC.BTC", value: 10 }).sub(15);
|
|
1937
|
+
expect(neg.toSignificant(2)).toBe("-5");
|
|
1938
|
+
});
|
|
1939
|
+
|
|
1940
|
+
test("handles values with mixed integer and decimal parts", () => {
|
|
1941
|
+
const mixed = AssetValue.from({ asset: "ETH.ETH", value: "12.3456789" });
|
|
1942
|
+
expect(mixed.toSignificant(4)).toBe("12.34");
|
|
1943
|
+
expect(mixed.toSignificant(6)).toBe("12.3456");
|
|
1944
|
+
expect(mixed.toSignificant(2)).toBe("12");
|
|
1945
|
+
});
|
|
1946
|
+
|
|
1947
|
+
test("handles value exactly at significant digit boundary", () => {
|
|
1948
|
+
const exact = AssetValue.from({ asset: "BTC.BTC", value: "1.00000" });
|
|
1949
|
+
expect(exact.toSignificant(1)).toBe("1");
|
|
1950
|
+
expect(exact.toSignificant(6)).toBe("1");
|
|
1951
|
+
});
|
|
1952
|
+
});
|
|
1953
|
+
|
|
1954
|
+
describe("toFixed edge cases", () => {
|
|
1955
|
+
test("handles zero with various fixed digits", () => {
|
|
1956
|
+
const zero = AssetValue.from({ asset: "BTC.BTC", value: 0 });
|
|
1957
|
+
expect(zero.toFixed(0)).toBe("0");
|
|
1958
|
+
expect(zero.toFixed(2)).toBe("0.00");
|
|
1959
|
+
expect(zero.toFixed(8)).toBe("0.00000000");
|
|
1960
|
+
});
|
|
1961
|
+
|
|
1962
|
+
test("handles rounding at boundary (0.5 case)", () => {
|
|
1963
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 1.5 }).toFixed(0)).toBe("2.0");
|
|
1964
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 2.5 }).toFixed(0)).toBe("3.0");
|
|
1965
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 0.125 }).toFixed(2)).toBe("0.13");
|
|
1966
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 0.124 }).toFixed(2)).toBe("0.12");
|
|
1967
|
+
});
|
|
1968
|
+
|
|
1969
|
+
test("handles rounding that causes carry-over", () => {
|
|
1970
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 0.999 }).toFixed(2)).toBe("1.00");
|
|
1971
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 9.999 }).toFixed(2)).toBe("10.00");
|
|
1972
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 99.999 }).toFixed(2)).toBe("100.00");
|
|
1973
|
+
});
|
|
1974
|
+
|
|
1975
|
+
test("handles negative value rounding", () => {
|
|
1976
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: -1.005 }).toFixed(2)).toBe("-1.01");
|
|
1977
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: -0.999 }).toFixed(2)).toBe("-1.00");
|
|
1978
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: -1.5 }).toFixed(0)).toBe("-2.0");
|
|
1979
|
+
});
|
|
1980
|
+
|
|
1981
|
+
test("handles very small values with high precision", () => {
|
|
1982
|
+
const tiny = AssetValue.from({ asset: "ETH.ETH", value: "0.000000000000000001" });
|
|
1983
|
+
expect(tiny.toFixed(18)).toBe("0.000000000000000001");
|
|
1984
|
+
expect(tiny.toFixed(17)).toBe("0.00000000000000000");
|
|
1985
|
+
});
|
|
1986
|
+
|
|
1987
|
+
test("handles integer values with decimal padding", () => {
|
|
1988
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 100 }).toFixed(0)).toBe("100.0");
|
|
1989
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 100 }).toFixed(4)).toBe("100.0000");
|
|
1990
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 100 }).toFixed(8)).toBe("100.00000000");
|
|
1991
|
+
});
|
|
1992
|
+
});
|
|
1993
|
+
|
|
1994
|
+
describe("toAbbreviation edge cases", () => {
|
|
1995
|
+
test("handles zero value", () => {
|
|
1996
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 0 }).toAbbreviation()).toBe("0");
|
|
1997
|
+
});
|
|
1998
|
+
|
|
1999
|
+
test("handles values just below threshold", () => {
|
|
2000
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 999 }).toAbbreviation()).toBe("999");
|
|
2001
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 999999 }).toAbbreviation()).toBe("1000.00K");
|
|
2002
|
+
});
|
|
2003
|
+
|
|
2004
|
+
test("handles values exactly at threshold", () => {
|
|
2005
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 1000 }).toAbbreviation()).toBe("1.00K");
|
|
2006
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 1000000 }).toAbbreviation()).toBe("1.00M");
|
|
2007
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 1000000000 }).toAbbreviation()).toBe("1.00B");
|
|
2008
|
+
});
|
|
2009
|
+
|
|
2010
|
+
test("handles custom digit precision", () => {
|
|
2011
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 1234567 }).toAbbreviation(0)).toBe("1M");
|
|
2012
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 1234567 }).toAbbreviation(1)).toBe("1.2M");
|
|
2013
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 1234567 }).toAbbreviation(3)).toBe("1.235M");
|
|
2014
|
+
});
|
|
2015
|
+
|
|
2016
|
+
test("handles negative values", () => {
|
|
2017
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 10 }).sub(1010).toAbbreviation()).toBe("-1.00K");
|
|
2018
|
+
});
|
|
2019
|
+
|
|
2020
|
+
test("handles very large values (quadrillion+)", () => {
|
|
2021
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: "1000000000000000" }).toAbbreviation()).toBe("1.00Q");
|
|
2022
|
+
});
|
|
2023
|
+
});
|
|
2024
|
+
|
|
2025
|
+
describe("toCurrency edge cases", () => {
|
|
2026
|
+
test("handles empty currency symbol", () => {
|
|
2027
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 1234.56 }).toCurrency("")).toBe("1,234.56");
|
|
2028
|
+
});
|
|
2029
|
+
|
|
2030
|
+
test("handles multi-character currency symbols", () => {
|
|
2031
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 100 }).toCurrency("BTC ")).toBe("BTC 100");
|
|
2032
|
+
expect(AssetValue.from({ asset: "BTC.BTC", value: 100 }).toCurrency(" ETH", { currencyPosition: "end" })).toBe(
|
|
2033
|
+
"100 ETH",
|
|
2034
|
+
);
|
|
2035
|
+
});
|
|
2036
|
+
|
|
2037
|
+
test("handles trimTrailingZeros option", () => {
|
|
2038
|
+
expect(
|
|
2039
|
+
AssetValue.from({ asset: "BTC.BTC", value: 100.1 }).toCurrency("$", { decimal: 4, trimTrailingZeros: true }),
|
|
2040
|
+
).toBe("$100.1");
|
|
2041
|
+
expect(
|
|
2042
|
+
AssetValue.from({ asset: "BTC.BTC", value: 100.1 }).toCurrency("$", { decimal: 4, trimTrailingZeros: false }),
|
|
2043
|
+
).toBe("$100.1000");
|
|
2044
|
+
expect(
|
|
2045
|
+
AssetValue.from({ asset: "BTC.BTC", value: 100 }).toCurrency("$", { decimal: 2, trimTrailingZeros: false }),
|
|
2046
|
+
).toBe("$100");
|
|
2047
|
+
});
|
|
2048
|
+
|
|
2049
|
+
test("handles very large numbers with separators", () => {
|
|
2050
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: "999999999999" }).toCurrency("$")).toBe("$999,999,999,999");
|
|
2051
|
+
});
|
|
2052
|
+
|
|
2053
|
+
test("handles negative values with currency", () => {
|
|
2054
|
+
const neg = AssetValue.from({ asset: "BTC.BTC", value: 10 }).sub(110);
|
|
2055
|
+
expect(neg.toCurrency("$")).toBe("$-100");
|
|
2056
|
+
});
|
|
2057
|
+
|
|
2058
|
+
test("handles small decimal values below rounding threshold", () => {
|
|
2059
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 0.001 }).toCurrency("$")).toBe("$0");
|
|
2060
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 0.001 }).toCurrency("$", { decimal: 3 })).toBe("$0.001");
|
|
2061
|
+
});
|
|
2062
|
+
|
|
2063
|
+
test("handles space as separator", () => {
|
|
2064
|
+
expect(AssetValue.from({ asset: "ETH.ETH", value: 1234567.89 }).toCurrency("", { thousandSeparator: " " })).toBe(
|
|
2065
|
+
"1 234 567.89",
|
|
2066
|
+
);
|
|
2067
|
+
});
|
|
2068
|
+
});
|
|
2069
|
+
});
|
|
2070
|
+
|
|
2071
|
+
describe("precision and rounding edge cases", () => {
|
|
2072
|
+
describe("maximum decimal precision", () => {
|
|
2073
|
+
test("handles 18 decimal places (ETH precision)", () => {
|
|
2074
|
+
const eth = AssetValue.from({ asset: "ETH.ETH", value: "1.123456789012345678" });
|
|
2075
|
+
expect(eth.getValue("string")).toBe("1.123456789012345678");
|
|
2076
|
+
expect(eth.getBaseValue("string")).toBe("1123456789012345678");
|
|
2077
|
+
});
|
|
2078
|
+
|
|
2079
|
+
test("handles precision beyond 18 decimals", () => {
|
|
2080
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: "0.1234567890123456789" });
|
|
2081
|
+
// Should handle gracefully, may truncate or round
|
|
2082
|
+
expect(value.getValue("string").length).toBeGreaterThan(0);
|
|
2083
|
+
});
|
|
2084
|
+
|
|
2085
|
+
test("preserves precision through arithmetic operations", () => {
|
|
2086
|
+
const a = AssetValue.from({ asset: "ETH.ETH", value: "0.000000000000000001" });
|
|
2087
|
+
const b = AssetValue.from({ asset: "ETH.ETH", value: "0.000000000000000001" });
|
|
2088
|
+
expect(a.add(b).getValue("string")).toBe("0.000000000000000002");
|
|
2089
|
+
});
|
|
2090
|
+
|
|
2091
|
+
test("handles precision in multiplication", () => {
|
|
2092
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: "0.1" });
|
|
2093
|
+
const result = value.mul("0.1");
|
|
2094
|
+
expect(result.getValue("string")).toBe("0.01");
|
|
2095
|
+
});
|
|
2096
|
+
|
|
2097
|
+
test("handles precision in division", () => {
|
|
2098
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: "1" });
|
|
2099
|
+
const result = value.div(3);
|
|
2100
|
+
// Should have reasonable precision without infinite decimals
|
|
2101
|
+
expect(result.getValue("string")).toMatch(/^0\.3+/);
|
|
2102
|
+
});
|
|
2103
|
+
});
|
|
2104
|
+
|
|
2105
|
+
describe("rounding behavior", () => {
|
|
2106
|
+
test("rounds half-up in getValue", () => {
|
|
2107
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: "1.123456785" });
|
|
2108
|
+
expect(value.getValue("string", 8)).toBe("1.12345679");
|
|
2109
|
+
});
|
|
2110
|
+
|
|
2111
|
+
test("handles rounding at different decimal places", () => {
|
|
2112
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: "1.99999999999" });
|
|
2113
|
+
// getValue uses precision-based output; rounding behavior varies by precision level
|
|
2114
|
+
expect(value.getValue("string", 10)).toBe("1.9999999991");
|
|
2115
|
+
expect(value.getValue("string", 11)).toBe("1.99999999999");
|
|
2116
|
+
// Full precision maintains the original value
|
|
2117
|
+
expect(value.getValue("string")).toBe("1.99999999999");
|
|
2118
|
+
});
|
|
2119
|
+
});
|
|
2120
|
+
});
|
|
2121
|
+
|
|
2122
|
+
describe("boundary conditions", () => {
|
|
2123
|
+
describe("MAX_SAFE_INTEGER handling", () => {
|
|
2124
|
+
test("handles values at MAX_SAFE_INTEGER", () => {
|
|
2125
|
+
const maxSafe = AssetValue.from({ asset: "ETH.ETH", value: Number.MAX_SAFE_INTEGER });
|
|
2126
|
+
expect(maxSafe.getValue("string")).toBe("9007199254740991");
|
|
2127
|
+
});
|
|
2128
|
+
|
|
2129
|
+
test("handles values beyond MAX_SAFE_INTEGER as strings", () => {
|
|
2130
|
+
const beyondMax = AssetValue.from({ asset: "ETH.ETH", value: "9007199254740992" });
|
|
2131
|
+
expect(beyondMax.getValue("string")).toBe("9007199254740992");
|
|
2132
|
+
});
|
|
2133
|
+
|
|
2134
|
+
test("arithmetic with very large values", () => {
|
|
2135
|
+
const large1 = AssetValue.from({ asset: "ETH.ETH", value: "9999999999999999999" });
|
|
2136
|
+
const large2 = AssetValue.from({ asset: "ETH.ETH", value: "1" });
|
|
2137
|
+
expect(large1.add(large2).getValue("string")).toBe("10000000000000000000");
|
|
2138
|
+
});
|
|
2139
|
+
});
|
|
2140
|
+
|
|
2141
|
+
describe("underflow and overflow scenarios", () => {
|
|
2142
|
+
test("handles very small positive values", () => {
|
|
2143
|
+
const tiny = AssetValue.from({ asset: "ETH.ETH", value: "0.000000000000000001" });
|
|
2144
|
+
expect(tiny.getValue("string")).toBe("0.000000000000000001");
|
|
2145
|
+
expect(tiny.getBaseValue("bigint")).toBe(1n);
|
|
2146
|
+
});
|
|
2147
|
+
|
|
2148
|
+
test("handles subtraction resulting in zero", () => {
|
|
2149
|
+
const a = AssetValue.from({ asset: "BTC.BTC", value: 1 });
|
|
2150
|
+
const b = a.sub(1);
|
|
2151
|
+
expect(b.getValue("string")).toBe("0");
|
|
2152
|
+
expect(b.getBaseValue("bigint")).toBe(0n);
|
|
2153
|
+
});
|
|
2154
|
+
|
|
2155
|
+
test("handles multiplication by zero", () => {
|
|
2156
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: 999999 });
|
|
2157
|
+
expect(value.mul(0).getValue("string")).toBe("0");
|
|
2158
|
+
});
|
|
2159
|
+
|
|
2160
|
+
test("handles division by very small number", () => {
|
|
2161
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: 1 });
|
|
2162
|
+
const result = value.div("0.00000001");
|
|
2163
|
+
expect(result.getValue("string")).toBe("100000000");
|
|
2164
|
+
});
|
|
2165
|
+
});
|
|
2166
|
+
|
|
2167
|
+
describe("zero value handling", () => {
|
|
2168
|
+
test("handles numeric zero", () => {
|
|
2169
|
+
const zero = AssetValue.from({ asset: "BTC.BTC", value: 0 });
|
|
2170
|
+
expect(zero.getValue("string")).toBe("0");
|
|
2171
|
+
expect(zero.getValue("number")).toBe(0);
|
|
2172
|
+
expect(zero.getBaseValue("bigint")).toBe(0n);
|
|
2173
|
+
});
|
|
2174
|
+
|
|
2175
|
+
test("handles string zero", () => {
|
|
2176
|
+
const zero = AssetValue.from({ asset: "BTC.BTC", value: "0" });
|
|
2177
|
+
expect(zero.getValue("string")).toBe("0");
|
|
2178
|
+
});
|
|
2179
|
+
|
|
2180
|
+
test("handles zero with decimals", () => {
|
|
2181
|
+
const zero = AssetValue.from({ asset: "BTC.BTC", value: "0.00000000" });
|
|
2182
|
+
expect(zero.getValue("string")).toBe("0");
|
|
2183
|
+
});
|
|
2184
|
+
|
|
2185
|
+
test("zero comparison edge cases", () => {
|
|
2186
|
+
const zero = AssetValue.from({ asset: "BTC.BTC", value: 0 });
|
|
2187
|
+
expect(zero.eqValue(0)).toBe(true);
|
|
2188
|
+
expect(zero.eqValue("0")).toBe(true);
|
|
2189
|
+
expect(zero.eqValue("0.0")).toBe(true);
|
|
2190
|
+
expect(zero.gt(0)).toBe(false);
|
|
2191
|
+
expect(zero.lt(0)).toBe(false);
|
|
2192
|
+
expect(zero.gte(0)).toBe(true);
|
|
2193
|
+
expect(zero.lte(0)).toBe(true);
|
|
2194
|
+
});
|
|
2195
|
+
});
|
|
2196
|
+
});
|
|
2197
|
+
|
|
2198
|
+
describe("type coercion edge cases", () => {
|
|
2199
|
+
describe("getValue type conversions", () => {
|
|
2200
|
+
test("returns correct types for all type parameters", () => {
|
|
2201
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: 1.5 });
|
|
2202
|
+
|
|
2203
|
+
const strValue = value.getValue("string");
|
|
2204
|
+
const numValue = value.getValue("number");
|
|
2205
|
+
const bigintValue = value.getValue("bigint");
|
|
2206
|
+
|
|
2207
|
+
expect(typeof strValue).toBe("string");
|
|
2208
|
+
expect(typeof numValue).toBe("number");
|
|
2209
|
+
expect(typeof bigintValue).toBe("bigint");
|
|
2210
|
+
});
|
|
2211
|
+
|
|
2212
|
+
test("handles decimal parameter in getValue", () => {
|
|
2213
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: "1.123456789012345678" });
|
|
2214
|
+
expect(value.getValue("string", 6)).toBe("1.123457");
|
|
2215
|
+
expect(value.getValue("string", 2)).toBe("1.12");
|
|
2216
|
+
expect(value.getValue("number", 2)).toBe(1.12);
|
|
2217
|
+
});
|
|
2218
|
+
|
|
2219
|
+
test("getValue with decimal 0 preserves value", () => {
|
|
2220
|
+
// getValue with decimal 0 doesn't round to integer, it preserves precision
|
|
2221
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: 1.999 });
|
|
2222
|
+
expect(value.getValue("string", 0)).toBe("1.999");
|
|
2223
|
+
});
|
|
2224
|
+
});
|
|
2225
|
+
|
|
2226
|
+
describe("getBaseValue type conversions", () => {
|
|
2227
|
+
test("returns correct base value for different decimals", () => {
|
|
2228
|
+
const btc = AssetValue.from({ asset: "BTC.BTC", value: 1 });
|
|
2229
|
+
expect(btc.getBaseValue("bigint")).toBe(100000000n); // 8 decimals
|
|
2230
|
+
expect(btc.getBaseValue("string")).toBe("100000000");
|
|
2231
|
+
expect(btc.getBaseValue("number")).toBe(100000000);
|
|
2232
|
+
});
|
|
2233
|
+
|
|
2234
|
+
test("respects custom decimal parameter", () => {
|
|
2235
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: 1 });
|
|
2236
|
+
expect(value.getBaseValue("bigint", 6)).toBe(1000000n);
|
|
2237
|
+
expect(value.getBaseValue("string", 6)).toBe("1000000");
|
|
2238
|
+
});
|
|
2239
|
+
});
|
|
2240
|
+
|
|
2241
|
+
describe("input value coercion", () => {
|
|
2242
|
+
test("handles integer input", () => {
|
|
2243
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: 100 });
|
|
2244
|
+
expect(value.getValue("string")).toBe("100");
|
|
2245
|
+
});
|
|
2246
|
+
|
|
2247
|
+
test("handles float input", () => {
|
|
2248
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: 100.5 });
|
|
2249
|
+
expect(value.getValue("string")).toBe("100.5");
|
|
2250
|
+
});
|
|
2251
|
+
|
|
2252
|
+
test("handles string number input", () => {
|
|
2253
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: "100.5" });
|
|
2254
|
+
expect(value.getValue("string")).toBe("100.5");
|
|
2255
|
+
});
|
|
2256
|
+
|
|
2257
|
+
test("handles BigInt input via fromBaseDecimal", () => {
|
|
2258
|
+
const value = AssetValue.from({ asset: "BTC.BTC", fromBaseDecimal: 8, value: 100000000n });
|
|
2259
|
+
expect(value.getValue("string")).toBe("1");
|
|
2260
|
+
});
|
|
2261
|
+
|
|
2262
|
+
test("handles another AssetValue as input", () => {
|
|
2263
|
+
const original = AssetValue.from({ asset: "BTC.BTC", value: 10 });
|
|
2264
|
+
const copy = AssetValue.from({ asset: "ETH.ETH", value: original });
|
|
2265
|
+
expect(copy.getValue("string")).toBe("10");
|
|
2266
|
+
});
|
|
2267
|
+
});
|
|
2268
|
+
});
|
|
2269
|
+
|
|
2270
|
+
describe("string parsing edge cases", () => {
|
|
2271
|
+
describe("scientific notation", () => {
|
|
2272
|
+
test("handles positive exponent", () => {
|
|
2273
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: 1e18 });
|
|
2274
|
+
expect(value.getValue("string")).toBe("1000000000000000000");
|
|
2275
|
+
});
|
|
2276
|
+
|
|
2277
|
+
test("handles negative exponent", () => {
|
|
2278
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: 1e-8 });
|
|
2279
|
+
expect(value.getValue("string")).toBe("0.00000001");
|
|
2280
|
+
});
|
|
2281
|
+
|
|
2282
|
+
test("handles string scientific notation", () => {
|
|
2283
|
+
// Numbers in JS are converted before being passed
|
|
2284
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: Number("1e-8") });
|
|
2285
|
+
expect(value.getValue("string")).toBe("0.00000001");
|
|
2286
|
+
});
|
|
2287
|
+
});
|
|
2288
|
+
|
|
2289
|
+
describe("string value edge cases", () => {
|
|
2290
|
+
test("handles string with leading zeros", () => {
|
|
2291
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: "00100.50" });
|
|
2292
|
+
expect(value.getValue("string")).toBe("100.5");
|
|
2293
|
+
});
|
|
2294
|
+
|
|
2295
|
+
test("handles string with trailing zeros", () => {
|
|
2296
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: "100.50000000" });
|
|
2297
|
+
expect(value.getValue("string")).toBe("100.5");
|
|
2298
|
+
});
|
|
2299
|
+
|
|
2300
|
+
test("handles decimal-only string", () => {
|
|
2301
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: ".5" });
|
|
2302
|
+
expect(value.getValue("string")).toBe("0.5");
|
|
2303
|
+
});
|
|
2304
|
+
});
|
|
2305
|
+
|
|
2306
|
+
describe("special numeric values", () => {
|
|
2307
|
+
test("handles very small decimal strings", () => {
|
|
2308
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: "0.00000000000000001" });
|
|
2309
|
+
expect(value.getValue("string")).toBe("0.00000000000000001");
|
|
2310
|
+
});
|
|
2311
|
+
|
|
2312
|
+
test("handles integer string", () => {
|
|
2313
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: "1000000" });
|
|
2314
|
+
expect(value.getValue("string")).toBe("1000000");
|
|
2315
|
+
});
|
|
2316
|
+
});
|
|
2317
|
+
});
|
|
2318
|
+
|
|
2319
|
+
describe("display formatter variations", () => {
|
|
2320
|
+
describe("toFixed with different decimal configurations", () => {
|
|
2321
|
+
test("respects asset decimal when formatting", async () => {
|
|
2322
|
+
await AssetValue.loadStaticAssets();
|
|
2323
|
+
|
|
2324
|
+
const btc = AssetValue.from({ asset: "BTC.BTC", value: 1.123456789 });
|
|
2325
|
+
const usdc = AssetValue.from({ asset: "AVAX.USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e", value: 1.123456 });
|
|
2326
|
+
|
|
2327
|
+
// BTC has 8 decimals
|
|
2328
|
+
expect(btc.toFixed(8)).toBe("1.12345679");
|
|
2329
|
+
// USDC has 6 decimals
|
|
2330
|
+
expect(usdc.toFixed(6)).toBe("1.123456");
|
|
2331
|
+
});
|
|
2332
|
+
});
|
|
2333
|
+
|
|
2334
|
+
describe("chained formatting operations", () => {
|
|
2335
|
+
test("formatting after arithmetic operations", () => {
|
|
2336
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: 100 });
|
|
2337
|
+
const result = value.div(3);
|
|
2338
|
+
|
|
2339
|
+
expect(result.toFixed(2)).toBe("33.33");
|
|
2340
|
+
expect(result.toSignificant(4)).toBe("33.33");
|
|
2341
|
+
// Division creates high precision result (18 decimals for ETH)
|
|
2342
|
+
expect(result.toAbbreviation()).toBe("33.333333333333333333");
|
|
2343
|
+
});
|
|
2344
|
+
|
|
2345
|
+
test("formatting preserves asset identity", () => {
|
|
2346
|
+
const synth = AssetValue.from({ asset: "THOR.ETH/ETH", value: 100 });
|
|
2347
|
+
const result = synth.mul(2);
|
|
2348
|
+
|
|
2349
|
+
// Formatting should not affect asset properties
|
|
2350
|
+
result.toFixed(2);
|
|
2351
|
+
expect(result.isSynthetic).toBe(true);
|
|
2352
|
+
expect(result.getValue("string")).toBe("200");
|
|
2353
|
+
});
|
|
2354
|
+
});
|
|
2355
|
+
});
|
|
2356
|
+
|
|
2357
|
+
describe("negative value handling", () => {
|
|
2358
|
+
test("arithmetic producing negative values", () => {
|
|
2359
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: 10 });
|
|
2360
|
+
const negative = value.sub(20);
|
|
2361
|
+
|
|
2362
|
+
expect(negative.getValue("string")).toBe("-10");
|
|
2363
|
+
expect(negative.getValue("number")).toBe(-10);
|
|
2364
|
+
expect(negative.lt(0)).toBe(true);
|
|
2365
|
+
expect(negative.lte(-10)).toBe(true);
|
|
2366
|
+
expect(negative.gt(-11)).toBe(true);
|
|
2367
|
+
});
|
|
2368
|
+
|
|
2369
|
+
test("negative value formatting", () => {
|
|
2370
|
+
const negative = AssetValue.from({ asset: "BTC.BTC", value: 5 }).sub(15);
|
|
2371
|
+
|
|
2372
|
+
expect(negative.toFixed(2)).toBe("-10.00");
|
|
2373
|
+
expect(negative.toSignificant(3)).toBe("-10");
|
|
2374
|
+
expect(negative.toCurrency("$")).toBe("$-10");
|
|
2375
|
+
});
|
|
2376
|
+
|
|
2377
|
+
test("negative value arithmetic", () => {
|
|
2378
|
+
const negative = AssetValue.from({ asset: "BTC.BTC", value: 5 }).sub(15);
|
|
2379
|
+
|
|
2380
|
+
expect(negative.add(5).getValue("string")).toBe("-5");
|
|
2381
|
+
expect(negative.sub(5).getValue("string")).toBe("-15");
|
|
2382
|
+
expect(negative.mul(2).getValue("string")).toBe("-20");
|
|
2383
|
+
expect(negative.div(2).getValue("string")).toBe("-5");
|
|
2384
|
+
expect(negative.mul(-1).getValue("string")).toBe("10");
|
|
2385
|
+
});
|
|
2386
|
+
});
|
|
2387
|
+
|
|
2388
|
+
describe("decimal configuration edge cases", () => {
|
|
2389
|
+
test("different chain decimals are respected", () => {
|
|
2390
|
+
// BTC has 8 decimals
|
|
2391
|
+
const btc = AssetValue.from({ asset: "BTC.BTC", value: 1 });
|
|
2392
|
+
expect(btc.getBaseValue("bigint")).toBe(100000000n);
|
|
2393
|
+
|
|
2394
|
+
// ETH has 18 decimals
|
|
2395
|
+
const eth = AssetValue.from({ asset: "ETH.ETH", value: 1 });
|
|
2396
|
+
expect(eth.getBaseValue("bigint")).toBe(1000000000000000000n);
|
|
2397
|
+
|
|
2398
|
+
// MAYA CACAO has 10 decimals
|
|
2399
|
+
const cacao = AssetValue.from({ asset: "MAYA.CACAO", value: 1 });
|
|
2400
|
+
expect(cacao.getBaseValue("bigint")).toBe(10000000000n);
|
|
2401
|
+
});
|
|
2402
|
+
|
|
2403
|
+
test("custom decimal in constructor is respected", () => {
|
|
2404
|
+
const custom = new AssetValue({ chain: Chain.Ethereum, decimal: 6, symbol: "CUSTOM", value: 1 });
|
|
2405
|
+
expect(custom.getBaseValue("bigint")).toBe(1000000n);
|
|
2406
|
+
});
|
|
2407
|
+
|
|
2408
|
+
test("arithmetic between different decimal assets", () => {
|
|
2409
|
+
const btc = AssetValue.from({ asset: "BTC.BTC", value: 1 }); // 8 decimals
|
|
2410
|
+
const eth = AssetValue.from({ asset: "ETH.ETH", value: 1 }); // 18 decimals
|
|
2411
|
+
|
|
2412
|
+
// Adding values (ignores asset type, just uses values)
|
|
2413
|
+
expect(btc.add(eth).getValue("string")).toBe("2");
|
|
2414
|
+
expect(btc.sub(eth).getValue("string")).toBe("0");
|
|
2415
|
+
});
|
|
2416
|
+
});
|
|
2417
|
+
|
|
2418
|
+
describe("comparison edge cases with different types", () => {
|
|
2419
|
+
test("comparison with string values", () => {
|
|
2420
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: 1 });
|
|
2421
|
+
expect(value.gt("0.5")).toBe(true);
|
|
2422
|
+
expect(value.lt("1.5")).toBe(true);
|
|
2423
|
+
expect(value.eqValue("1")).toBe(true);
|
|
2424
|
+
expect(value.eqValue("1.0")).toBe(true);
|
|
2425
|
+
expect(value.eqValue("1.00000000")).toBe(true);
|
|
2426
|
+
});
|
|
2427
|
+
|
|
2428
|
+
test("comparison with number values", () => {
|
|
2429
|
+
const value = AssetValue.from({ asset: "BTC.BTC", value: 1 });
|
|
2430
|
+
expect(value.gt(0.5)).toBe(true);
|
|
2431
|
+
expect(value.lt(1.5)).toBe(true);
|
|
2432
|
+
expect(value.eqValue(1)).toBe(true);
|
|
2433
|
+
expect(value.eqValue(1.0)).toBe(true);
|
|
2434
|
+
});
|
|
2435
|
+
|
|
2436
|
+
test("comparison with AssetValue", () => {
|
|
2437
|
+
const value1 = AssetValue.from({ asset: "BTC.BTC", value: 1 });
|
|
2438
|
+
const value2 = AssetValue.from({ asset: "ETH.ETH", value: 1 });
|
|
2439
|
+
const value3 = AssetValue.from({ asset: "BTC.BTC", value: 2 });
|
|
2440
|
+
|
|
2441
|
+
expect(value1.eqValue(value2)).toBe(true);
|
|
2442
|
+
expect(value1.lt(value3)).toBe(true);
|
|
2443
|
+
expect(value3.gt(value1)).toBe(true);
|
|
2444
|
+
});
|
|
2445
|
+
|
|
2446
|
+
test("comparison with very precise values", () => {
|
|
2447
|
+
const value = AssetValue.from({ asset: "ETH.ETH", value: "1.000000000000000001" });
|
|
2448
|
+
expect(value.gt(1)).toBe(true);
|
|
2449
|
+
expect(value.gt("1.000000000000000000")).toBe(true);
|
|
2450
|
+
expect(value.lt("1.000000000000000002")).toBe(true);
|
|
2451
|
+
});
|
|
2452
|
+
});
|
|
@@ -280,23 +280,25 @@ describe("BigIntArithmetics", () => {
|
|
|
280
280
|
);
|
|
281
281
|
});
|
|
282
282
|
|
|
283
|
-
test("small values < 1
|
|
284
|
-
expect(new BigIntArithmetics(0.015072).toCurrency("")).toBe("0.
|
|
285
|
-
expect(new BigIntArithmetics(0.333145).toCurrency("")).toBe("0.
|
|
286
|
-
expect(new BigIntArithmetics(0.000005).toCurrency("")).toBe("0
|
|
287
|
-
expect(new BigIntArithmetics(0.00000548).toCurrency("")).toBe("0.
|
|
288
|
-
expect(new BigIntArithmetics(0.00003801).toCurrency("")).toBe("0.
|
|
283
|
+
test("small values < 1 rounds to decimal with trailing zeros removed without floating-point artifacts", () => {
|
|
284
|
+
expect(new BigIntArithmetics(0.015072).toCurrency("")).toBe("0.02");
|
|
285
|
+
expect(new BigIntArithmetics(0.333145).toCurrency("")).toBe("0.33");
|
|
286
|
+
expect(new BigIntArithmetics(0.000005).toCurrency("")).toBe("0");
|
|
287
|
+
expect(new BigIntArithmetics(0.00000548).toCurrency("", { decimal: 6 })).toBe("0.000005");
|
|
288
|
+
expect(new BigIntArithmetics(0.00003801).toCurrency("", { decimal: 6 })).toBe("0.000038");
|
|
289
289
|
});
|
|
290
290
|
|
|
291
291
|
test("small values strip trailing zeros", () => {
|
|
292
292
|
expect(new BigIntArithmetics(0.12).toCurrency("")).toBe("0.12");
|
|
293
293
|
expect(new BigIntArithmetics(0.1).toCurrency("")).toBe("0.1");
|
|
294
|
-
expect(new BigIntArithmetics(0.10000001).toCurrency("")).toBe("0.
|
|
294
|
+
expect(new BigIntArithmetics(0.10000001).toCurrency("")).toBe("0.1");
|
|
295
295
|
});
|
|
296
296
|
|
|
297
297
|
test("negative small values", () => {
|
|
298
|
-
expect(new BigIntArithmetics(-0.015072).toCurrency("")).toBe("-0.
|
|
299
|
-
expect(new BigIntArithmetics(-0.00000001).toCurrency("")).toBe("-0.00000001");
|
|
298
|
+
expect(new BigIntArithmetics(-0.015072).toCurrency("")).toBe("-0.02");
|
|
299
|
+
expect(new BigIntArithmetics(-0.00000001).toCurrency("", { decimal: 8 })).toBe("-0.00000001");
|
|
300
|
+
expect(new BigIntArithmetics(-0.00003801).toCurrency("", { decimal: 6 })).toBe("-0.000038");
|
|
301
|
+
expect(new BigIntArithmetics(-0.00000548).toCurrency("")).toBe("0");
|
|
300
302
|
});
|
|
301
303
|
|
|
302
304
|
test("values >= 1 round to decimal param", () => {
|
|
@@ -313,9 +315,9 @@ describe("BigIntArithmetics", () => {
|
|
|
313
315
|
});
|
|
314
316
|
|
|
315
317
|
test("custom decimal separator for small values", () => {
|
|
316
|
-
expect(
|
|
317
|
-
|
|
318
|
-
);
|
|
318
|
+
expect(
|
|
319
|
+
new BigIntArithmetics(0.015072).toCurrency("€", { currencyPosition: "end", decimal: 6, decimalSeparator: "," }),
|
|
320
|
+
).toBe("0,015072€");
|
|
319
321
|
});
|
|
320
322
|
});
|
|
321
323
|
|