Replace combinatorial decorators with capability registry (BC) (#28565)

This commit is contained in:
Maschga 2026-03-27 09:17:19 +01:00 • committed by GitHub
parent 33d2de24c1
commit 00967eb57e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
101 changed files with 2416 additions and 44670 deletions

89
api/capable_test.go Normal file
View file

@ -0,0 +1,89 @@
package api
import (
"reflect"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// mock decorated type with capability registry
type decoratedMeter struct {
Meter
caps map[reflect.Type]any
}
func (d *decoratedMeter) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type testMeterEnergyImpl struct{}
func (t *testMeterEnergyImpl) TotalEnergy() (float64, error) {
return 99.0, nil
}
type testMeterImpl struct{}
func (t *testMeterImpl) CurrentPower() (float64, error) {
return 100.0, nil
}
func TestCap_DirectTypeAssertion(t *testing.T) {
// concrete type that directly implements MeterEnergy
impl := &testMeterEnergyImpl{}
me, ok := Cap[MeterEnergy](impl)
require.True(t, ok)
energy, err := me.TotalEnergy()
assert.NoError(t, err)
assert.Equal(t, 99.0, energy)
}
func TestCap_CapableRegistryLookup(t *testing.T) {
base := &testMeterImpl{}
decorated := &decoratedMeter{
Meter: base,
caps: map[reflect.Type]any{
reflect.TypeFor[MeterEnergy](): &testMeterEnergyImpl{},
},
}
// should find MeterEnergy via registry
me, ok := Cap[MeterEnergy](decorated)
require.True(t, ok)
energy, err := me.TotalEnergy()
assert.NoError(t, err)
assert.Equal(t, 99.0, energy)
// should NOT find PhaseCurrents (not registered)
_, ok = Cap[PhaseCurrents](decorated)
assert.False(t, ok)
}
func TestCap_NilValue(t *testing.T) {
_, ok := Cap[MeterEnergy](nil)
assert.False(t, ok)
}
func TestCap_DirectTakesPrecedence(t *testing.T) {
// type that both directly implements AND has registry
type directAndCapable struct {
testMeterEnergyImpl
caps map[reflect.Type]any //nolint:unused
}
v := &directAndCapable{}
me, ok := Cap[MeterEnergy](v)
require.True(t, ok)
energy, err := me.TotalEnergy()
assert.NoError(t, err)
assert.Equal(t, 99.0, energy)
}