Files
fuj-management/go/internal/domain/money/money_test.go
Jan Novak d24d20553a feat(go/M2.5): port domain/money.ParseCZK
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>
2026-05-06 09:38:28 +02:00

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)
}
}
}