Files
crypto-price-bot/internal/services/tele/view/price_test.go
T
thuanle 95e9217ef4 fix: render basis with explicit sign and absolute delta
Format basis row as +/-$abs(delta) to match the spec and avoid
awkward %+s formatting behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-26 17:39:57 +07:00

138 lines
3.6 KiB
Go

package view
import (
"strings"
"testing"
)
func assertContainsAll(t *testing.T, msg string, rows ...string) {
t.Helper()
for _, r := range rows {
if !strings.Contains(msg, r) {
t.Fatalf("expected row %q in message:\n%s", r, msg)
}
}
}
func assertContainsNone(t *testing.T, msg string, rows ...string) {
t.Helper()
for _, r := range rows {
if strings.Contains(msg, r) {
t.Fatalf("unexpected row %q in message:\n%s", r, msg)
}
}
}
func TestRenderRichTokenMessage_AllSources(t *testing.T) {
msg := RenderRichTokenMessage(RichTokenMessageInput{
Token: "ETH",
HasSpot: true,
SpotPrice: 3245,
HasFuture: true,
FuturePrice: 3251,
FundingRate: 0.000123,
FundingTimeMs: 1740000000000,
HasAlpha: true,
AlphaPrice: 3248,
HasAlpha24h: true,
Alpha24hChange: -3.21,
HasMarginAPR: true,
MarginAPRPercent: 7.665,
})
expectedOrder := []string{
"🪙 ETH",
"💵 Spot:",
"📈 Future:",
"🅰️ Alpha:",
"🧭 Basis:",
"💸 Funding:",
"🏦 Margin:",
"📊 Alpha 24h:",
}
last := -1
for _, part := range expectedOrder {
i := strings.Index(msg, part)
if i == -1 {
t.Fatalf("missing row %q in message:\n%s", part, msg)
}
if i < last {
t.Fatalf("row %q appears out of order in message:\n%s", part, msg)
}
last = i
}
}
func TestRenderRichTokenMessage_FutureOnly(t *testing.T) {
msg := RenderRichTokenMessage(RichTokenMessageInput{
Token: "ABC",
HasFuture: true,
FuturePrice: 1234,
FundingRate: 0.000081,
FundingTimeMs: 1740000000000,
HasMarginAPR: true,
MarginAPRPercent: 6.2,
})
assertContainsAll(t, msg, "🪙 ABC", "📈 Future:", "💸 Funding:", "🏦 Margin:")
assertContainsNone(t, msg, "💵 Spot:", "🅰️ Alpha:", "🧭 Basis:", "📊 Alpha 24h:")
}
func TestRenderRichTokenMessage_SpotOnly(t *testing.T) {
msg := RenderRichTokenMessage(RichTokenMessageInput{
Token: "XRP",
HasSpot: true,
SpotPrice: 2.1,
HasMarginAPR: true,
MarginAPRPercent: 5.11,
})
assertContainsAll(t, msg, "🪙 XRP", "💵 Spot:", "🏦 Margin:")
assertContainsNone(t, msg, "📈 Future:", "🅰️ Alpha:", "🧭 Basis:", "💸 Funding:", "📊 Alpha 24h:")
}
func TestRenderRichTokenMessage_AlphaOnly(t *testing.T) {
msg := RenderRichTokenMessage(RichTokenMessageInput{
Token: "ABC",
HasAlpha: true,
AlphaPrice: 0.1234,
HasAlpha24h: true,
Alpha24hChange: 12.4,
})
assertContainsAll(t, msg, "🪙 ABC", "🅰️ Alpha:", "📊 Alpha 24h:")
assertContainsNone(t, msg, "💵 Spot:", "📈 Future:", "🧭 Basis:", "💸 Funding:", "🏦 Margin:")
}
func TestRenderRichTokenMessage_SpotAndFuture(t *testing.T) {
msg := RenderRichTokenMessage(RichTokenMessageInput{
Token: "SOL",
HasSpot: true,
SpotPrice: 182.4,
HasFuture: true,
FuturePrice: 183.0,
FundingRate: -0.000041,
FundingTimeMs: 1740000000000,
HasMarginAPR: true,
MarginAPRPercent: 5.11,
})
assertContainsAll(t, msg, "🪙 SOL", "💵 Spot:", "📈 Future:", "🧭 Basis: +$0.6000", "💸 Funding:", "🏦 Margin:")
assertContainsNone(t, msg, "🅰️ Alpha:", "📊 Alpha 24h:")
}
func TestRenderRichTokenMessage_SpotAndFutureNegativeBasis(t *testing.T) {
msg := RenderRichTokenMessage(RichTokenMessageInput{
Token: "ADA",
HasSpot: true,
SpotPrice: 1.2,
HasFuture: true,
FuturePrice: 1.1,
FundingRate: 0.000011,
FundingTimeMs: 1740000000000,
})
assertContainsAll(t, msg, "🧭 Basis: -$0.10000 (-8.33%)")
}