package payments import "testing" func TestMoneyFromMinor(t *testing.T) { m, err := MoneyFromMinor(14950, CurrencyRUB) if err != nil { t.Fatalf("MoneyFromMinor: %v", err) } if m.Minor() != 14950 || m.Currency() != CurrencyRUB { t.Fatalf("got minor=%d currency=%s", m.Minor(), m.Currency()) } if _, err := MoneyFromMinor(1, Currency("EUR")); err == nil { t.Fatal("expected an error for an unknown currency") } } func TestMoneyFromMajor(t *testing.T) { cases := []struct { major int64 cur Currency minor int64 }{ {149, CurrencyRUB, 14900}, // roubles scale to kopecks {250, CurrencyStar, 250}, // Stars are whole units {7, CurrencyVote, 7}, {50, CurrencyChip, 50}, } for _, c := range cases { m, err := MoneyFromMajor(c.major, c.cur) if err != nil { t.Fatalf("MoneyFromMajor(%d,%s): %v", c.major, c.cur, err) } if m.Minor() != c.minor { t.Errorf("MoneyFromMajor(%d,%s): minor=%d, want %d", c.major, c.cur, m.Minor(), c.minor) } } if _, err := MoneyFromMajor(1<<62, CurrencyRUB); err == nil { t.Fatal("expected an overflow error") } } func TestParseMoneyExact(t *testing.T) { cases := []struct { text string cur Currency minor int64 }{ {"149.50", CurrencyRUB, 14950}, {"149", CurrencyRUB, 14900}, {"0.01", CurrencyRUB, 1}, {"0.10", CurrencyRUB, 10}, // 0.1 is inexact as a float; big.Rat keeps it exact {"-5.00", CurrencyRUB, -500}, {"250", CurrencyStar, 250}, {"7", CurrencyVote, 7}, {"50", CurrencyChip, 50}, } for _, c := range cases { m, err := ParseMoney(c.text, c.cur) if err != nil { t.Fatalf("ParseMoney(%q,%s): %v", c.text, c.cur, err) } if m.Minor() != c.minor { t.Errorf("ParseMoney(%q,%s): minor=%d, want %d", c.text, c.cur, m.Minor(), c.minor) } } } func TestParseMoneyRejectsFraction(t *testing.T) { // A whole-unit currency (Vote/Star/chip) must never accept a fraction, and // the rouble must never accept finer than a kopeck — the no-float gate. bad := []struct { text string cur Currency }{ {"250.5", CurrencyStar}, {"1.5", CurrencyChip}, {"7.01", CurrencyVote}, {"1.999", CurrencyRUB}, {"0.001", CurrencyRUB}, {"abc", CurrencyRUB}, {"12.34", Currency("EUR")}, // unknown currency } for _, c := range bad { if m, err := ParseMoney(c.text, c.cur); err == nil { t.Errorf("ParseMoney(%q,%s) = %d, want an error", c.text, c.cur, m.Minor()) } } } func TestMoneyAddCmp(t *testing.T) { a, _ := MoneyFromMinor(14900, CurrencyRUB) b, _ := MoneyFromMinor(50, CurrencyRUB) sum, err := a.Add(b) if err != nil || sum.Minor() != 14950 { t.Fatalf("Add: minor=%d err=%v", sum.Minor(), err) } if c, err := a.Cmp(b); err != nil || c != 1 { t.Fatalf("Cmp a>b: got %d err=%v", c, err) } if c, err := b.Cmp(a); err != nil || c != -1 { t.Fatalf("Cmp b