package money_test import ( "errors" "testing" "github.com/wangjia/pay/internal/money" ) func TestParseFormatRoundTrip(t *testing.T) { cases := []struct { s, cur string minor int64 }{ {"12.3417", "USDT", 12341700}, {"0.01", "CNY", 1}, {"29.99", "USD", 2999}, {"199.99", "CNY", 19999}, {"1", "USDT", 1000000}, } for _, c := range cases { got, err := money.Parse(c.s, c.cur) if err != nil || got != c.minor { t.Fatalf("Parse(%q,%s)=%d,%v want %d", c.s, c.cur, got, err, c.minor) } back, err := money.Format(c.minor, c.cur) if err != nil { t.Fatalf("Format(%d,%s): %v", c.minor, c.cur, err) } // round-trip 回同一 minor(去尾零后可能字符串不同,再 Parse 校验) again, _ := money.Parse(back, c.cur) if again != c.minor { t.Fatalf("round-trip %d → %q → %d", c.minor, back, again) } } } func TestParseErrors(t *testing.T) { if _, err := money.Parse("1.00", "JPYX"); err == nil { t.Fatal("未知币种应报错") } if _, err := money.Parse("0.001", "CNY"); err == nil { t.Fatal("超精度(CNY 3 位小数)应报错") } if _, err := money.Parse("abc", "CNY"); err == nil { t.Fatal("非数字应报错") } } func TestFormatUnknownCurrency(t *testing.T) { _, err := money.Format(123, "JPYX") if err == nil { t.Fatal("未知币种应报错") } if !errors.Is(err, money.ErrUnknownCurrency) { t.Fatalf("want ErrUnknownCurrency, got %v", err) } } func TestParseOverflow(t *testing.T) { // whole part fits int64 on its own, but whole*mult(+frac) overflows int64. if _, err := money.Parse("92233720368547759", "CNY"); err == nil { t.Fatal("整数部分过大导致 minor 溢出 int64 应报错") } if _, err := money.Parse("92233720368547758.07", "CNY"); err != nil { t.Fatalf("恰好等于 int64 上限不应报错: %v", err) } } func TestParseFormatNegative(t *testing.T) { minor, err := money.Parse("-12.34", "CNY") if err != nil { t.Fatalf("Parse(-12.34): %v", err) } if minor != -1234 { t.Fatalf("Parse(-12.34)=%d want -1234", minor) } back, err := money.Format(-1234, "CNY") if err != nil { t.Fatalf("Format(-1234): %v", err) } again, err := money.Parse(back, "CNY") if err != nil { t.Fatalf("Parse(%q): %v", back, err) } if again != -1234 { t.Fatalf("round-trip -1234 → %q → %d", back, again) } }