Port scripts/infer_payments.py parse_czk_amount to Go as internal/domain/money.ParseCZK. Preserves the Czech-locale heuristic (comma = decimal sep; 2+ dots = thousand seps; single dot = decimal) and returns (float64, error) so callers can opt into Python's silent-zero contract via v, _ := money.ParseCZK(s). All expected values verified against live Python on 2026-05-06. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
68 lines
2.0 KiB
Go
68 lines
2.0 KiB
Go
package money
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestParseCZK(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// All expected outputs verified against live Python implementation on 2026-05-06:
|
|
// PYTHONPATH=scripts:. python -c '
|
|
// from infer_payments import parse_czk_amount
|
|
// for v in [None, "", "0", "500", "500 Kč", "500 CZK",
|
|
// "1 500", "1500.00", "1 500.00",
|
|
// "1.500,00", "1500,5", "1.500.000",
|
|
// "1.500", "abc", " ", "100,5 Kč"]:
|
|
// print(repr(v), "->", parse_czk_amount(v))
|
|
// '
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
want float64
|
|
wantErr bool
|
|
}{
|
|
{"empty string", "", 0, false},
|
|
{"zero string", "0", 0, false},
|
|
{"plain integer", "500", 500, false},
|
|
{"with Kč suffix", "500 Kč", 500, false},
|
|
{"with CZK suffix", "500 CZK", 500, false},
|
|
{"space thousand sep", "1 500", 1500, false},
|
|
{"dot decimal", "1500.00", 1500, false},
|
|
{"space thousands dot decimal", "1 500.00", 1500, false},
|
|
{"dot thousand comma decimal", "1.500,00", 1500, false},
|
|
{"comma decimal no thousands", "1500,5", 1500.5, false},
|
|
{"multiple dot thousand seps", "1.500.000", 1500000, false},
|
|
{"single dot is decimal heuristic", "1.500", 1.5, false},
|
|
{"comma decimal with Kč", "100,5 Kč", 100.5, false},
|
|
{"garbage text", "abc", 0, true},
|
|
{"spaces only", " ", 0, true},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
got, err := ParseCZK(tc.input)
|
|
if (err != nil) != tc.wantErr {
|
|
t.Errorf("ParseCZK(%q) error = %v, wantErr %v", tc.input, err, tc.wantErr)
|
|
}
|
|
if got != tc.want {
|
|
t.Errorf("ParseCZK(%q) = %v, want %v", tc.input, got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestParseCZKSilentZero documents that discarding the error recovers Python's
|
|
// silent-zero behaviour for any garbage input.
|
|
func TestParseCZKSilentZero(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
for _, s := range []string{"abc", " ", "Kč", "CZK"} {
|
|
v, _ := ParseCZK(s)
|
|
if v != 0 {
|
|
t.Errorf("ParseCZK(%q) silent-zero: got %v, want 0", s, v)
|
|
}
|
|
}
|
|
}
|