textmachine/platform/internal/money/money_test.go

56 lines
1.6 KiB
Go

package money
import "testing"
// The whole point of the type is that these answers are exact. Mutation caught: implementing
// ParseUSD with strconv.ParseFloat and a multiplication.
func TestParseUSDIsExactAndRoundsUp(t *testing.T) {
cases := map[string]MicroUSD{
"0": 0,
"5": 5 * PerUSD,
"2.50": 2_500_000,
"0.1": 100_000, // 0.1 has no float64 representation; 0.1*1e6 is 100000.00000000001
"29.7": 29_700_000,
"0.000001": 1,
"0.0000001": 1, // a tenth of a micro-dollar still costs one
"1e-6": 1,
"-2.5": -2_500_000,
// Up means toward +infinity on BOTH sides of zero, which is what "never undercharge"
// means when the amount is a debit: a fraction of a micro-dollar owed is not owed.
"-0.0000001": 0,
"-1.9999999": -1_999_999,
" 1.25 ": 1_250_000,
"123456.7891": 123_456_789_100,
}
for in, want := range cases {
got, err := ParseUSD(in)
if err != nil {
t.Fatalf("ParseUSD(%q): %v", in, err)
}
if got != want {
t.Fatalf("ParseUSD(%q) = %d, want %d", in, got, want)
}
}
}
func TestParseUSDRefusesNonsense(t *testing.T) {
for _, in := range []string{"", "free", "5 dollars", "1e30", "0x10"} {
if got, err := ParseUSD(in); err == nil {
t.Fatalf("ParseUSD(%q) = %d, want an error", in, got)
}
}
}
func TestUSDRendersForOperatorsOnly(t *testing.T) {
cases := map[MicroUSD]string{
0: "0.000000",
5 * PerUSD: "5.000000",
1: "0.000001",
-2_500_000: "-2.500000",
}
for in, want := range cases {
if got := in.USD(); got != want {
t.Fatalf("%d.USD() = %q, want %q", int64(in), got, want)
}
}
}