feat: 接入 CoinGlass 清算热力图隔离链路
Some checks failed
ci / build + vet + guard + race (push) Has been cancelled

This commit is contained in:
dela
2026-05-25 16:57:22 +08:00
parent e5fb54cb72
commit 1b61541ff5
32 changed files with 2550 additions and 70 deletions

View File

@@ -0,0 +1,85 @@
package coinglass
import (
"encoding/json"
"math"
"testing"
"github.com/stretchr/testify/require"
)
func TestMapLiqHeatMap_FloatToString(t *testing.T) {
cases := []struct {
name string
envelope string
wantSymbol string
wantMin string
wantMax string
wantErr bool
probeRawKey string
}{
{
name: "happy path with float number fields",
envelope: `{"success":true,"code":"0","msg":"","data":{"priceMin":110234.5,"priceMax":118888.0,"grid":[[1,2],[3,4]]}}`,
wantSymbol: "Binance_BTCUSDT",
wantMin: "110234.5",
wantMax: "118888",
probeRawKey: "grid",
},
{
name: "string-typed numbers are passed through unchanged",
envelope: `{"success":true,"code":"0","msg":"","data":{"priceMin":"99999.99","priceMax":"100000.01"}}`,
wantSymbol: "Binance_BTCUSDT",
wantMin: "99999.99",
wantMax: "100000.01",
},
{
name: "alternate field names (minPrice/maxPrice)",
envelope: `{"success":true,"code":"0","msg":"","data":{"minPrice":1000.5,"maxPrice":2000.5}}`,
wantSymbol: "Binance_BTCUSDT",
wantMin: "1000.5",
wantMax: "2000.5",
},
{
name: "missing min/max fields → empty strings",
envelope: `{"success":true,"code":"0","msg":"","data":{"grid":[]}}`,
wantSymbol: "Binance_BTCUSDT",
wantMin: "",
wantMax: "",
},
{
name: "business error propagates",
envelope: `{"success":false,"code":"40001","msg":"bad params","data":null}`,
wantErr: true,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got, err := MapLiqHeatMap("Binance_BTCUSDT", "5", 1735689600000, []byte(tc.envelope))
if tc.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
require.Equal(t, tc.wantSymbol, got.Symbol)
require.IsType(t, "", got.PriceMin, "PriceMin must be string (G12.4 boundary)")
require.IsType(t, "", got.PriceMax, "PriceMax must be string (G12.4 boundary)")
require.Equal(t, tc.wantMin, got.PriceMin)
require.Equal(t, tc.wantMax, got.PriceMax)
require.NotEmpty(t, got.RawGrid, "RawGrid must carry raw data verbatim")
require.True(t, json.Valid(got.RawGrid), "RawGrid must be valid JSON")
})
}
}
func TestFormatFloat_RejectsNaNAndInf(t *testing.T) {
require.Equal(t, "", formatFloat(math.NaN()))
require.Equal(t, "", formatFloat(math.Inf(1)))
require.Equal(t, "", formatFloat(math.Inf(-1)))
require.Equal(t, "0.0001", formatFloat(0.0001))
require.Equal(t, "118234.567", formatFloat(118234.567))
}