Improvements to embedded struct support(uuid and similar tag names) and extra tests

This commit is contained in:
Alex 2020-01-26 23:11:36 +01:00
parent 41412ed76e
commit bf847e845e
5 changed files with 195 additions and 3 deletions

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2020 Alex aka mailoman <alex@webz.asia>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @author Alex aka mailoman <alex@webz.asia>
* @copyright Copyright (c) 2020 Alex aka mailoman <alex@webz.asia>
* @since 26.01.2020
*
*/
package main
import (
"encoding/json"
"log"
"github.com/go-convert/fields"
"github.com/satori/go.uuid"
)
type FromStructBase struct {
ID uuid.UUID `conv:"new,update"`
Field1 string `conv:"new,update"`
}
type fromStruct struct {
FromStructBase `conv:"new,update"`
Field2 string `conv:"update"`
}
type toStruct struct {
Id string
Field1 string
Field2 string
Field3 string
}
func main() {
fromDefault := fromStruct{
FromStructBase{uuid.FromStringOrNil("bb9f2a39-1dbd-4929-8e87-4863696d9cb3"), "field 1 value"}, "field 2 value",
}
toDefault := toStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value",
}
log.Print("example 4.1 - new")
from := fromDefault
to := toDefault
fields.Сonvert(from, "new", &to)
fromB, _ := json.Marshal(from)
toB, _ := json.Marshal(to)
log.Printf("from %s => to %s", string(fromB), string(toB))
log.Print("example 4.2 - update")
from = fromDefault
to = toDefault
fields.Сonvert(from, "update", &to)
fromB, _ = json.Marshal(from)
toB, _ = json.Marshal(to)
log.Printf("from %s => to %s", string(fromB), string(toB))
}

View File

@ -25,6 +25,8 @@ import (
"log" "log"
"reflect" "reflect"
"strings" "strings"
"github.com/satori/go.uuid"
) )
//Convert copies field values from one struct to another based on tags setup //Convert copies field values from one struct to another based on tags setup
@ -70,10 +72,23 @@ func Сonvert(from interface{}, kind string, to interface{}) {
if found { if found {
ft := vt.FieldByName(f.Name) ft := vt.FieldByName(f.Name)
if f.Name == strings.ToUpper(f.Name) && !ft.IsValid() {
// was uppercase and not valid => to Capitalize first letter
ft = vt.FieldByName(strings.Title(strings.ToLower(f.Name)))
}
if !ft.IsValid() && fv.Kind() == reflect.Struct { if !ft.IsValid() && fv.Kind() == reflect.Struct {
Сonvert(fv.Interface(), kind, to) Сonvert(fv.Interface(), kind, to)
} else { } else {
ft.Set(fv) if ft.IsValid() {
switch f.Type.String() {
case "uuid.UUID":
mv := fv.Interface().(uuid.UUID)
ft.SetString(mv.String())
default:
ft.Set(fv)
}
}
} }
} }
} }

View File

@ -24,6 +24,7 @@ package fields_test
import ( import (
"testing" "testing"
"github.com/satori/go.uuid"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/go-convert/fields" "github.com/go-convert/fields"
@ -51,6 +52,14 @@ type ToStruct struct {
Field4 string Field4 string
} }
type ToStruct2 struct {
Id string
Field1 string
Field2 string
Field3 string
Field4 string
}
type FromStructCustom struct { type FromStructCustom struct {
ID string `copy:"new,update"` ID string `copy:"new,update"`
Field1 string `copy:"new,update"` Field1 string `copy:"new,update"`
@ -64,6 +73,11 @@ type FromStructBase struct {
Field1 string `conv:"new,update"` Field1 string `conv:"new,update"`
} }
type FromStructExtraBase struct {
ID uuid.UUID `conv:"new,update"`
Field1 string `conv:"new,update"`
}
type FromStructCombined struct { type FromStructCombined struct {
FromStructBase `conv:"new,update"` FromStructBase `conv:"new,update"`
Field2 string `conv:"update"` Field2 string `conv:"update"`
@ -71,6 +85,13 @@ type FromStructCombined struct {
Field4 string `conv:"category-1,omitempty"` Field4 string `conv:"category-1,omitempty"`
} }
type FromStructCombinedExtra struct {
FromStructExtraBase `conv:"new,update"`
Field2 uuid.UUID `conv:"update"`
Field3 string `conv:"update,omit"`
Field4 string `conv:"category-1,omitempty"`
}
var ( var (
// testsNormal provides normal test cases // testsNormal provides normal test cases
testsNormal = []struct { testsNormal = []struct {
@ -271,7 +292,7 @@ var (
}, },
} }
// testsCombinedNormal provides normal test cases with custom init config // testsCombinedNormal provides normal test cases with embedded structs
testsCombinedNormal = []struct { testsCombinedNormal = []struct {
from FromStructCombined from FromStructCombined
kind string kind string
@ -331,6 +352,67 @@ var (
}, },
}, },
} }
// testsCombinedExtra provides normal test cases with embedded structs with more features
testsCombinedExtra = []struct {
from FromStructCombinedExtra
kind string
to ToStruct2
expectedTo ToStruct2
}{
// case 4.1
{
FromStructCombinedExtra{
FromStructExtraBase{uuid.FromStringOrNil("bb9f2a39-1dbd-4929-8e87-4863696d9cb3"), "field 1 value"}, uuid.FromStringOrNil("d039089d-27f5-438b-8b70-90eb3df0d79b"), "omitting", "",
},
"new",
ToStruct2{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
ToStruct2{
"bb9f2a39-1dbd-4929-8e87-4863696d9cb3", "field 1 value", "old field 2 value", "old field 3 value", "",
},
},
// case 4.2
{
FromStructCombinedExtra{
FromStructExtraBase{uuid.FromStringOrNil("bb9f2a39-1dbd-4929-8e87-4863696d9cb3"), "field 1 value"}, uuid.FromStringOrNil("d039089d-27f5-438b-8b70-90eb3df0d79b"), "omitting", "",
},
"update",
ToStruct2{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
ToStruct2{
"bb9f2a39-1dbd-4929-8e87-4863696d9cb3", "field 1 value", "d039089d-27f5-438b-8b70-90eb3df0d79b", "old field 3 value", "",
},
},
// case 4.3.1
{
FromStructCombinedExtra{
FromStructExtraBase{uuid.FromStringOrNil("bb9f2a39-1dbd-4929-8e87-4863696d9cb3"), "field 1 value"}, uuid.FromStringOrNil("d039089d-27f5-438b-8b70-90eb3df0d79b"), "omitting", "",
},
"category-1",
ToStruct2{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
},
ToStruct2{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
},
},
// case 4.3.2
{
FromStructCombinedExtra{
FromStructExtraBase{uuid.FromStringOrNil("bb9f2a39-1dbd-4929-8e87-4863696d9cb3"), "field 1 value"}, uuid.FromStringOrNil("d039089d-27f5-438b-8b70-90eb3df0d79b"), "omitting", "not empty",
},
"category-1",
ToStruct2{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
},
ToStruct2{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "not empty",
},
},
}
) )
func TestConvert_Normal(t *testing.T) { func TestConvert_Normal(t *testing.T) {
@ -444,3 +526,17 @@ func TestConvert_CombinedNormal(t *testing.T) {
assert.Equal(t, test.expectedTo, *to) assert.Equal(t, test.expectedTo, *to)
} }
} }
func TestConvert_CombinedExtra(t *testing.T) {
fields.SetDefaults()
for _, test := range testsCombinedExtra {
to := &ToStruct2{}
*to = test.to
fields.Сonvert(test.from, test.kind, to)
assert.NotEmpty(t, *to)
assert.Equal(t, test.expectedTo, *to)
}
}

5
go.mod
View File

@ -2,4 +2,7 @@ module github.com/go-convert/fields
go 1.13 go 1.13
require github.com/stretchr/testify v1.4.0 require (
github.com/satori/go.uuid v1.2.0
github.com/stretchr/testify v1.4.0
)

2
go.sum
View File

@ -2,6 +2,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=