package calc import ( "errors" "reflect" "testing" "time" ) type staticProvider struct { rate Rate } func (p staticProvider) RateFor(country string, day time.Time) (Rate, error) { if p.rate.Country != country { return Rate{}, errors.New("country mismatch") } return p.rate, nil } func d(s string) time.Time { t, err := time.Parse("2006-01-02", s) if err != nil { panic(err) } return t } func TestCompute_SingleDay_PartialRate(t *testing.T) { legs := []Leg{{Country: "DE", FromDate: d("2026-10-02"), ToDate: d("2026-10-02")}} rate := Rate{RateID: "PDR-42", Country: "DE", Currency: "EUR", FullDay: "28.00", PartialDayMin8h: "14.00", ArrivalDay: "14.00", DepartureDay: "14.00", } got, err := Compute(legs, staticProvider{rate: rate}) if err != nil { t.Fatalf("unexpected error: %v", err) } want := []Item{{Type: PerDiemPartial, Amount: "14.00", IncurredOn: d("2026-10-02"), RateID: "PDR-42"}} if !reflect.DeepEqual(got, want) { t.Fatalf("got %+v want %+v", got, want) } } func TestCompute_ThreeDayTrip_ArrivalFullDeparture(t *testing.T) { legs := []Leg{{Country: "DE", FromDate: d("2026-10-01"), ToDate: d("2026-10-03")}} rate := Rate{RateID: "PDR-42", Country: "DE", Currency: "EUR", FullDay: "28.00", PartialDayMin8h: "14.00", ArrivalDay: "14.00", DepartureDay: "14.00", } got, err := Compute(legs, staticProvider{rate: rate}) if err != nil { t.Fatalf("unexpected error: %v", err) } want := []Item{ {Type: PerDiemArrival, Amount: "14.00", IncurredOn: d("2026-10-01"), RateID: "PDR-42"}, {Type: PerDiemFull, Amount: "28.00", IncurredOn: d("2026-10-02"), RateID: "PDR-42"}, {Type: PerDiemDeparture, Amount: "14.00", IncurredOn: d("2026-10-03"), RateID: "PDR-42"}, } if !reflect.DeepEqual(got, want) { t.Fatalf("got %+v want %+v", got, want) } } func TestCompute_InvertedDates_Rejected(t *testing.T) { legs := []Leg{{Country: "DE", FromDate: d("2026-10-05"), ToDate: d("2026-10-03")}} _, err := Compute(legs, staticProvider{rate: Rate{Country: "DE"}}) if err == nil { t.Fatal("expected error for inverted dates") } } func TestCompute_EmptyLegs_Rejected(t *testing.T) { _, err := Compute(nil, staticProvider{rate: Rate{Country: "DE"}}) if err == nil { t.Fatal("expected error for empty legs") } } func TestCompute_NilProvider_Rejected(t *testing.T) { legs := []Leg{{Country: "DE", FromDate: d("2026-10-01"), ToDate: d("2026-10-03")}} _, err := Compute(legs, nil) if err == nil { t.Fatal("expected error for nil provider") } }