Tariff: keep fixed tariff rates ordered when chargesZones markers are combined (#32165)
This commit is contained in:
parent
408f9a056b
commit
60f313cbfb
3 changed files with 76 additions and 15 deletions
|
|
@ -104,25 +104,18 @@ func (r Zones) TimeTableMarkers() []HourMin {
|
|||
}
|
||||
}
|
||||
|
||||
HOURS:
|
||||
// 1hr intervals
|
||||
for hour := range 24 {
|
||||
for _, m := range res {
|
||||
if m.Hour == hour && m.Min == 0 {
|
||||
continue HOURS
|
||||
hm := HourMin{Hour: hour}
|
||||
if !slices.Contains(res, hm) {
|
||||
res = append(res, hm)
|
||||
}
|
||||
}
|
||||
|
||||
// hour is missing
|
||||
for i, m := range res {
|
||||
if m.Hour >= hour {
|
||||
res = slices.Insert(res, i, HourMin{Hour: hour, Min: 0})
|
||||
continue HOURS
|
||||
}
|
||||
}
|
||||
|
||||
res = append(res, HourMin{Hour: hour, Min: 0})
|
||||
}
|
||||
// zones may be unsorted, e.g. when price and charges zones are combined
|
||||
slices.SortFunc(res, func(i, j HourMin) int {
|
||||
return i.Minutes() - j.Minutes()
|
||||
})
|
||||
|
||||
return res
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,3 +81,38 @@ func TestZonesTimeTableMarkers(t *testing.T) {
|
|||
|
||||
assert.Equal(t, expect, zones.TimeTableMarkers())
|
||||
}
|
||||
|
||||
func TestZonesTimeTableMarkersUnsorted(t *testing.T) {
|
||||
// price and charges zones are concatenated unsorted, see Fixed.Rates
|
||||
zones := Zones{
|
||||
{Hours: TimeRange{
|
||||
From: HourMin{12, 0},
|
||||
To: HourMin{14, 0},
|
||||
}},
|
||||
{Hours: TimeRange{
|
||||
From: HourMin{10, 15}, // minutes must not sort before the earlier hour's 9:45
|
||||
To: HourMin{11, 0},
|
||||
}},
|
||||
{Hours: TimeRange{
|
||||
From: HourMin{9, 45},
|
||||
To: HourMin{10, 0},
|
||||
}},
|
||||
{Hours: TimeRange{
|
||||
From: HourMin{0, 0},
|
||||
To: HourMin{5, 30},
|
||||
}},
|
||||
}
|
||||
|
||||
expect := []HourMin{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {5, 30}}
|
||||
for hour := 6; hour < 24; hour++ {
|
||||
expect = append(expect, HourMin{hour, 0})
|
||||
switch hour {
|
||||
case 9:
|
||||
expect = append(expect, HourMin{9, 45})
|
||||
case 10:
|
||||
expect = append(expect, HourMin{10, 15})
|
||||
}
|
||||
}
|
||||
|
||||
assert.Equal(t, expect, zones.TimeTableMarkers())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,3 +133,36 @@ func TestFixedChargesZonesMarkers(t *testing.T) {
|
|||
assert.Equal(t, dayStart.Add(5*time.Hour+30*time.Minute), rates[6].Start)
|
||||
assert.Equal(t, 0.5, rates[6].Value)
|
||||
}
|
||||
|
||||
func TestFixedChargesZonesOrder(t *testing.T) {
|
||||
at, err := NewFixedFromConfig(map[string]any{
|
||||
"price": 0.5,
|
||||
"zones": []struct {
|
||||
Price float64
|
||||
Hours string
|
||||
}{
|
||||
{0.2, "12-14"},
|
||||
},
|
||||
"chargesZones": []struct {
|
||||
Charges float64
|
||||
Hours string
|
||||
}{
|
||||
{0.1, "0-5:30"},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
tf := at.(*Fixed)
|
||||
tf.clock = clock.NewMock()
|
||||
|
||||
rates, err := tf.Rates()
|
||||
require.NoError(t, err)
|
||||
|
||||
// rates must stay ordered and contiguous even if charges zone markers don't align with price zones
|
||||
for i, r := range rates {
|
||||
require.True(t, r.End.After(r.Start), "invalid rate %d: %v", i, r)
|
||||
if i > 0 {
|
||||
require.Equal(t, rates[i-1].End, r.Start, "non-contiguous rate %d: %v", i, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue