evcc-io/core/capable_test.go
andig 94c2606797
Some checks failed
Release / Demo (push) Has been cancelled
Release / call-build-workflow (push) Has been cancelled
Release / Publish Docker :release (push) Has been cancelled
Release / Github & APT (push) Has been cancelled
Release / Hassio Addon (push) Has been cancelled
Fix docorating by promoting embedded type methods as capabilities (#28995)
2026-04-10 15:48:23 +02:00

106 lines
2 KiB
Go

package core
import (
"reflect"
"testing"
"github.com/evcc-io/evcc/api"
"github.com/stretchr/testify/assert"
)
type charger struct {
caps map[reflect.Type]any
}
var _ api.Capable = (*charger)(nil)
func (c *charger) Capability(typ reflect.Type) (any, bool) {
cap, ok := c.caps[typ]
if !ok && reflect.TypeOf(c).Implements(typ) {
return c, true
}
return cap, ok
}
var _ api.Meter = (*charger)(nil)
func (c *charger) CurrentPower() (float64, error) {
return 0, nil
}
var _ api.BatteryCapacity = (*charger)(nil)
func (c *charger) Capacity() float64 {
return 0
}
var _ api.MeterEnergy = (*charger)(nil)
func (c *charger) TotalEnergy() (float64, error) {
return 0, nil
}
var _ api.Battery = (*batteryImpl)(nil)
type batteryImpl struct {
soc func() (float64, error)
}
func (impl *batteryImpl) Soc() (float64, error) {
return impl.soc()
}
func TestCapsWrapping(t *testing.T) {
// type is just a shortcut for something simple that is not a meter
var c api.BatteryCapacity
c = &charger{
caps: make(map[reflect.Type]any),
}
c.(*charger).caps[reflect.TypeFor[api.Battery]()] = &batteryImpl{
soc: func() (float64, error) {
return 0, nil
},
}
{
_, ok := c.(api.Meter)
assert.True(t, ok)
}
{
_, ok := c.(api.MeterEnergy)
assert.True(t, ok)
}
{
_, ok := c.(api.Battery)
assert.False(t, ok)
assert.True(t, api.HasCap[api.Battery](c))
}
var m api.Meter
if mt, ok := api.Cap[api.Meter](c); ok {
if c, ok := c.(api.Capable); ok {
m = &capableMeter{Meter: mt, Capable: c}
} else {
m = mt
}
}
{
_, ok := m.(api.MeterEnergy)
assert.False(t, ok, "unexpected promoted energy")
assert.True(t, api.HasCap[api.MeterEnergy](m), "missing promoted energy cap")
var mm any = m.(*capableMeter).Meter
_, ok = mm.(api.MeterEnergy)
assert.True(t, ok, "missing embedded energy")
assert.True(t, api.HasCap[api.MeterEnergy](mm), "missing embedded energy cap")
}
{
_, ok := m.(api.Battery)
assert.False(t, ok)
assert.True(t, api.HasCap[api.Battery](m), "missing battery cap")
}
}