56 lines
1.6 KiB
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)
|
|
}
|
|
}
|
|
}
|