114 lines
2.6 KiB
Go
114 lines
2.6 KiB
Go
package core
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/benbjohnson/clock"
|
|
"github.com/evcc-io/evcc/api"
|
|
"github.com/jinzhu/now"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/suite"
|
|
)
|
|
|
|
func TestSolarRates(t *testing.T) {
|
|
suite.Run(t, new(solarTestSuite))
|
|
}
|
|
|
|
type solarTestSuite struct {
|
|
suite.Suite
|
|
clock *clock.Mock
|
|
rr api.Rates
|
|
}
|
|
|
|
func (t *solarTestSuite) rate(start int, val float64) api.Rate {
|
|
return api.Rate{
|
|
Start: t.clock.Now().Add(time.Duration(start) * time.Hour),
|
|
End: t.clock.Now().Add(time.Duration(start+1) * time.Hour),
|
|
Value: val,
|
|
}
|
|
}
|
|
|
|
func (t *solarTestSuite) SetupSuite() {
|
|
t.clock = clock.NewMock()
|
|
t.clock.Set(now.BeginningOfDay())
|
|
t.rr = api.Rates{t.rate(0, 0), t.rate(1, 1), t.rate(2, 2), t.rate(3, 3), t.rate(4, 4)}
|
|
}
|
|
|
|
func (t *solarTestSuite) TestIndex() {
|
|
for i, tc := range []struct {
|
|
ts float64
|
|
idx int
|
|
ok bool
|
|
}{
|
|
{-1, 0, false},
|
|
{0, 0, true},
|
|
{0.5, 1, false},
|
|
{1, 1, true},
|
|
{99, len(t.rr), false},
|
|
} {
|
|
ts := t.clock.Now().Add(time.Duration(float64(time.Hour) * tc.ts))
|
|
res, ok := search(t.rr, ts)
|
|
t.Equal(tc.idx, res, "%d. idx %+v", i+1, tc)
|
|
t.Equal(tc.ok, ok, "%d. ok %+v", i+1, tc)
|
|
}
|
|
}
|
|
|
|
func (t *solarTestSuite) TestEnergy() {
|
|
for i, tc := range []struct {
|
|
from, to float64
|
|
expected float64
|
|
}{
|
|
{-1, 0, 0},
|
|
{-2, -1, 0}, // whole interval before first entry
|
|
{-1, -0.5, 0}, // whole interval before first entry
|
|
{-1, 1, 0.5},
|
|
{-1, 90, 8},
|
|
{0, 0, 0},
|
|
{0, 0.5, 0.125},
|
|
{0, 1, 0.5},
|
|
{0, 1.5, 1.125},
|
|
{0, 2, 2},
|
|
{1, 2, 1.5},
|
|
{0.25, 0.75, 0.25},
|
|
{0.5, 1, 0.375},
|
|
{0.5, 3.5, 6},
|
|
{80, 90, 0},
|
|
} {
|
|
from := t.clock.Now().Add(time.Duration(float64(time.Hour) * tc.from))
|
|
to := t.clock.Now().Add(time.Duration(float64(time.Hour) * tc.to))
|
|
|
|
res := solarEnergy(t.rr, from, to)
|
|
t.Equal(tc.expected, res, "%d. %+v", i+1, tc)
|
|
}
|
|
}
|
|
|
|
func (t *solarTestSuite) TestShort() {
|
|
t.clock.Set(now.BeginningOfDay())
|
|
rr := api.Rates{t.rate(0, 0), t.rate(1, 1)}
|
|
|
|
for i, tc := range []struct {
|
|
from, to, energy, value float64
|
|
}{
|
|
{-1, 0, 0, 0},
|
|
// {-1, 0.5, 0.125, 0.5},
|
|
// {-1, 2, 0.5, 0},
|
|
{0, 0, 0, 0},
|
|
{0, 0.5, 0.125, 0.5},
|
|
{0, 1, 0.5, 1},
|
|
{0, 1.5, 0.5, 0},
|
|
{1.5, 2, 0, 0},
|
|
} {
|
|
from := t.clock.Now().Add(time.Duration(float64(time.Hour) * tc.from))
|
|
to := t.clock.Now().Add(time.Duration(float64(time.Hour) * tc.to))
|
|
|
|
t.Equal(tc.energy, solarEnergy(rr, from, to), "%d. energy %+v", i+1, tc)
|
|
}
|
|
}
|
|
|
|
func TestSolarEnergyNoRates(t *testing.T) {
|
|
// empty rate series must not panic and yields no energy
|
|
now := time.Now()
|
|
assert.Equal(t, 0.0, solarEnergy(api.Rates{}, now, now.Add(time.Hour)))
|
|
assert.Equal(t, 0.0, solarEnergy(nil, now, now.Add(time.Hour)))
|
|
}
|