mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-17 22:29:55 +05:00
Fixed MIssingStructField panic
This commit is contained in:
committed by
Dan Christian Bogos
parent
690504f14a
commit
b7a442083c
@@ -24,18 +24,41 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func fieldByIndexIsEmpty(v reflect.Value, index []int) bool {
|
||||
if len(index) == 1 {
|
||||
return valueIsEmpty(v.Field(index[0]))
|
||||
}
|
||||
for i, x := range index {
|
||||
if i > 0 {
|
||||
if v.Kind() == reflect.Ptr && v.Type().Elem().Kind() == reflect.Struct {
|
||||
if v.IsNil() {
|
||||
return true
|
||||
}
|
||||
v = v.Elem()
|
||||
}
|
||||
}
|
||||
v = v.Field(x)
|
||||
}
|
||||
return valueIsEmpty(v)
|
||||
}
|
||||
|
||||
func valueIsEmpty(fld reflect.Value) bool {
|
||||
if fld.Kind() == reflect.String && fld.CanSet() {
|
||||
fld.SetString(strings.TrimSpace(fld.String()))
|
||||
}
|
||||
return (fld.Kind() == reflect.String && fld.String() == EmptyString) ||
|
||||
((fld.Kind() == reflect.Slice || fld.Kind() == reflect.Map) && fld.Len() == 0) ||
|
||||
(fld.Kind() == reflect.Int && fld.Int() == 0)
|
||||
}
|
||||
|
||||
// Detects missing field values based on mandatory field names, s should be a pointer to a struct
|
||||
func MissingStructFields(s interface{}, mandatories []string) []string {
|
||||
missing := []string{}
|
||||
sValue := reflect.ValueOf(s).Elem()
|
||||
sType := sValue.Type()
|
||||
for _, fieldName := range mandatories {
|
||||
fld := reflect.ValueOf(s).Elem().FieldByName(fieldName)
|
||||
// sanitize the string fields before checking
|
||||
if fld.Kind() == reflect.String && fld.CanSet() {
|
||||
fld.SetString(strings.TrimSpace(fld.String()))
|
||||
}
|
||||
if (fld.Kind() == reflect.String && fld.String() == "") ||
|
||||
((fld.Kind() == reflect.Slice || fld.Kind() == reflect.Map) && fld.Len() == 0) ||
|
||||
(fld.Kind() == reflect.Int && fld.Int() == 0) {
|
||||
fldStr, ok := sType.FieldByName(fieldName)
|
||||
if !ok || fieldByIndexIsEmpty(sValue, fldStr.Index){
|
||||
missing = append(missing, fieldName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,37 @@ func TestMissingStructFieldsCorrect(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissingStructFieldsNilCorporate(t *testing.T) {
|
||||
tst := &TenantIDWithAPIOpts{
|
||||
APIOpts: map[string]interface{}{
|
||||
OptsAPIKey: "attr1234",
|
||||
},
|
||||
}
|
||||
if missing := MissingStructFields(tst,
|
||||
[]string{Tenant}); len(missing) != 1 {
|
||||
t.Errorf("TenantIDWithAPIOpts is missing from my struct: %v", missing)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissingStructFieldsNilCorporateTwoStructs(t *testing.T) {
|
||||
tst := &struct {
|
||||
APIOpts map[string]interface{}
|
||||
*TenantID
|
||||
*TenantWithAPIOpts
|
||||
}{
|
||||
APIOpts: map[string]interface{}{
|
||||
OptsAPIKey: "attr1234",
|
||||
},
|
||||
TenantID: &TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
},
|
||||
}
|
||||
if missing := MissingStructFields(tst,
|
||||
[]string{Tenant}); len(missing) != 1 {
|
||||
t.Errorf("TenantIDWithAPIOpts is missing from my struct: %v", missing)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateStructWithIfaceMap(t *testing.T) {
|
||||
type myStruct struct {
|
||||
String string
|
||||
|
||||
Reference in New Issue
Block a user