-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfundingMath.test.ts
More file actions
127 lines (103 loc) · 4.52 KB
/
fundingMath.test.ts
File metadata and controls
127 lines (103 loc) · 4.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { describe, it, expect } from 'vitest';
import { classifyRate, rateColor, RATE_THRESHOLDS } from '../src/utils/rateColor';
import { formatUSD, formatRate, formatPct, formatDuration, formatRateRaw } from '../src/utils/format';
// ─── classifyRate ─────────────────────────────────────────────────────────────
describe('classifyRate', () => {
it('returns cold for zero rate', () => {
expect(classifyRate(0)).toBe('cold');
});
it('returns cold for rate below cold threshold', () => {
expect(classifyRate(0.0001)).toBe('cold');
});
it('returns warm at exactly cold threshold', () => {
expect(classifyRate(RATE_THRESHOLDS.cold)).toBe('warm');
});
it('returns warm in the warm band', () => {
expect(classifyRate(0.0003)).toBe('warm');
});
it('returns hot in the hot band', () => {
expect(classifyRate(0.0006)).toBe('hot');
});
it('returns fire at and above fire threshold', () => {
expect(classifyRate(0.001)).toBe('fire');
expect(classifyRate(0.005)).toBe('fire');
});
it('handles negative rates as cold', () => {
expect(classifyRate(-0.001)).toBe('cold');
});
});
// ─── rateColor ────────────────────────────────────────────────────────────────
describe('rateColor', () => {
it('returns a CSS variable string for each heat level', () => {
expect(rateColor('cold')).toMatch(/var\(--/);
expect(rateColor('warm')).toMatch(/var\(--/);
expect(rateColor('hot')).toMatch(/var\(--/);
expect(rateColor('fire')).toMatch(/var\(--/);
});
it('returns different colors for different heat levels', () => {
const colors = new Set(['cold', 'warm', 'hot', 'fire'].map(h => rateColor(h as any)));
expect(colors.size).toBe(4);
});
});
// ─── formatUSD ───────────────────────────────────────────────────────────────
describe('formatUSD', () => {
it('formats values under 1000 with 2 decimals', () => {
expect(formatUSD(42.5)).toBe('$42.50');
expect(formatUSD(0)).toBe('$0.00');
});
it('formats thousands with K suffix', () => {
expect(formatUSD(1500)).toBe('$1.5K');
expect(formatUSD(10000)).toBe('$10.0K');
});
it('formats millions with M suffix', () => {
expect(formatUSD(1_250_000)).toBe('$1.25M');
});
it('handles negative values', () => {
expect(formatUSD(-500)).toBe('-$500.00');
expect(formatUSD(-2000)).toBe('-$2.0K');
});
});
// ─── formatRate ──────────────────────────────────────────────────────────────
describe('formatRate', () => {
it('shows + sign for positive rates', () => {
expect(formatRate(0.0005)).toContain('+');
});
it('shows - sign for negative rates', () => {
expect(formatRate(-0.0005)).toContain('-');
});
it('converts decimal to percentage', () => {
expect(formatRate(0.001)).toContain('0.1000');
});
});
describe('formatRateRaw', () => {
it('does not show + prefix', () => {
expect(formatRateRaw(0.001).startsWith('+')).toBe(false);
});
it('shows 4 decimal places', () => {
expect(formatRateRaw(0.001)).toBe('0.1000%');
});
});
// ─── formatPct ───────────────────────────────────────────────────────────────
describe('formatPct', () => {
it('adds + for positive values', () => {
expect(formatPct(5)).toBe('+5.00%');
});
it('shows negative correctly', () => {
expect(formatPct(-2.5)).toBe('-2.50%');
});
it('respects custom decimal places', () => {
expect(formatPct(1.23456, 1)).toBe('+1.2%');
});
});
// ─── formatDuration ──────────────────────────────────────────────────────────
describe('formatDuration', () => {
it('shows minutes for sub-hour durations', () => {
expect(formatDuration(0.5)).toContain('m');
});
it('shows hours for 1–24h range', () => {
expect(formatDuration(6)).toContain('h');
});
it('shows days for >24h', () => {
expect(formatDuration(48)).toContain('d');
});
});