Replace combinatorial decorators with capability registry (BC) (#28565)
This commit is contained in:
parent
33d2de24c1
commit
00967eb57e
101 changed files with 2416 additions and 44670 deletions
89
api/capable_test.go
Normal file
89
api/capable_test.go
Normal 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)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue