diff --git a/spine/feature_local_test.go b/spine/feature_local_test.go index f6d12df..4765a5e 100644 --- a/spine/feature_local_test.go +++ b/spine/feature_local_test.go @@ -44,8 +44,8 @@ func (s *LocalFeatureTestSuite) BeforeTest(suiteName, testName string) { _, s.localServerFeatureWrite = createLocalFeatures(s.localEntity, s.subFeatureType, s.serverWriteFunction) remoteDevice := createRemoteDevice(s.localDevice, s.senderMock) - s.remoteFeature, s.remoteServerFeature = createRemoteEntityAndFeature(remoteDevice, 1, s.featureType) - s.remoteSubFeature, _ = createRemoteEntityAndFeature(remoteDevice, 2, s.subFeatureType) + s.remoteFeature, s.remoteServerFeature = createRemoteEntityAndFeature(remoteDevice, 1, s.featureType, s.function) + s.remoteSubFeature, _ = createRemoteEntityAndFeature(remoteDevice, 2, s.subFeatureType, s.serverWriteFunction) } func (s *LocalFeatureTestSuite) TestDeviceClassification_Functions() { diff --git a/spine/function_data_cmd.go b/spine/function_data_cmd.go index 850e915..3118454 100644 --- a/spine/function_data_cmd.go +++ b/spine/function_data_cmd.go @@ -62,23 +62,23 @@ func (r *FunctionDataCmd[T]) NotifyOrWriteCmdType(deleteSelector, partialSelecto } func filtersForSelectorsElements(functionType model.FunctionType, filters []model.FilterType, deleteSelector, partialSelector any, deleteElements, readElements any) []model.FilterType { - if deleteSelector != nil || deleteElements != nil { + if !util.IsNil(deleteSelector) || !util.IsNil(deleteElements) { filter := model.FilterType{CmdControl: &model.CmdControlType{Delete: &model.ElementTagType{}}} - if deleteSelector != nil { + if !util.IsNil(deleteSelector) { filter = addSelectorToFilter(filter, functionType, &deleteSelector) } - if deleteElements != nil { + if !util.IsNil(deleteElements) { filter = addElementToFilter(filter, functionType, &deleteElements) } filters = append(filters, filter) } - if partialSelector != nil || readElements != nil { + if !util.IsNil(partialSelector) || !util.IsNil(readElements) { filter := model.FilterType{CmdControl: &model.CmdControlType{Partial: &model.ElementTagType{}}} - if partialSelector != nil { + if !util.IsNil(partialSelector) { filter = addSelectorToFilter(filter, functionType, partialSelector) } - if readElements != nil { + if !util.IsNil(readElements != nil) { filter = addElementToFilter(filter, functionType, readElements) } filters = append(filters, filter) diff --git a/spine/helper_test.go b/spine/helper_test.go index 1030d64..3a04a75 100644 --- a/spine/helper_test.go +++ b/spine/helper_test.go @@ -197,12 +197,22 @@ func createRemoteDevice(localDevice *DeviceLocal, sender api.SenderInterface) *D return remoteDevice } -func createRemoteEntityAndFeature(remoteDevice *DeviceRemote, entityId uint, featureType model.FeatureTypeType) (api.FeatureRemoteInterface, api.FeatureRemoteInterface) { +func createRemoteEntityAndFeature(remoteDevice *DeviceRemote, entityId uint, featureType model.FeatureTypeType, functionType model.FunctionType) (api.FeatureRemoteInterface, api.FeatureRemoteInterface) { remoteEntity := NewEntityRemote(remoteDevice, model.EntityTypeTypeEVSE, []model.AddressEntityType{model.AddressEntityType(entityId)}) remoteDevice.AddEntity(remoteEntity) remoteFeature := NewFeatureRemote(remoteEntity.NextFeatureId(), remoteEntity, featureType, model.RoleTypeClient) remoteEntity.AddFeature(remoteFeature) remoteServerFeature := NewFeatureRemote(remoteEntity.NextFeatureId(), remoteEntity, featureType, model.RoleTypeServer) + remoteServerFeature.SetOperations([]model.FunctionPropertyType{ + { + Function: util.Ptr(functionType), + PossibleOperations: &model.PossibleOperationsType{ + Read: &model.PossibleOperationsReadType{ + Partial: &model.ElementTagType{}, + }, + }, + }, + }) remoteEntity.AddFeature(remoteServerFeature) return remoteFeature, remoteServerFeature diff --git a/spine/nodemanagement_test.go b/spine/nodemanagement_test.go index 6079739..93e41f2 100644 --- a/spine/nodemanagement_test.go +++ b/spine/nodemanagement_test.go @@ -21,7 +21,7 @@ func TestNodemanagement_BindingCalls(t *testing.T) { _, serverFeature := createLocalFeatures(localEntity, featureType, "") remoteDevice := createRemoteDevice(localDevice, senderMock) - clientFeature, _ := createRemoteEntityAndFeature(remoteDevice, bindingEntityId, featureType) + clientFeature, _ := createRemoteEntityAndFeature(remoteDevice, bindingEntityId, featureType, "") senderMock.On("Reply", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { cmd := args.Get(2).(model.CmdType) @@ -94,7 +94,7 @@ func TestNodemanagement_SubscriptionCalls(t *testing.T) { _, serverFeature := createLocalFeatures(localEntity, featureType, "") remoteDevice := createRemoteDevice(localDevice, senderMock) - clientFeature, _ := createRemoteEntityAndFeature(remoteDevice, subscriptionEntityId, featureType) + clientFeature, _ := createRemoteEntityAndFeature(remoteDevice, subscriptionEntityId, featureType, "") senderMock.On("Reply", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { cmd := args.Get(2).(model.CmdType) diff --git a/util/helper.go b/util/helper.go index b67faff..2e0eee0 100644 --- a/util/helper.go +++ b/util/helper.go @@ -2,6 +2,7 @@ package util import ( "encoding/json" + "reflect" ) // quick way to a struct into another @@ -9,3 +10,19 @@ func DeepCopy[A any](source, dest A) { byt, _ := json.Marshal(source) _ = json.Unmarshal(byt, dest) } + +// checck if a value is nil for any type +func IsNil(data any) bool { + if data == nil { + return true + } + switch reflect.TypeOf(data).Kind() { + case reflect.Ptr, + reflect.Map, + reflect.Array, + reflect.Chan, + reflect.Slice: + return reflect.ValueOf(data).IsNil() + } + return false +}