Initial commit with main funcs and tests

master
Alex 2020-01-14 23:20:23 +01:00
parent d58b07d9d3
commit 8e0406167b
11 changed files with 1013 additions and 2 deletions

93
.gitignore vendored Normal file
View File

@ -0,0 +1,93 @@
# Created by .ignore support plugin (hsz.mobi)
### macOS template
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Go template
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
vendor/
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
*.log
*.bak
#swagger.json
.cache/
coverage.*
data/

38
.travis.yml Normal file
View File

@ -0,0 +1,38 @@
language: go
cache:
directories:
- "$GOPATH/pkg/mod"
install: true
addons:
artifacts:
debug: true
go:
- 1.13.x
env:
global:
- GOPROXY=https://proxy.golang.org
- GO111MODULE=on
- GOARCH=amd64
- GO_FOR_RELEASE=1.13
jobs:
allow_failures:
- go: master
include:
- go: master
env: JOB=test
script:
- go test -race -coverprofile=coverage.txt -covermode=atomic ./...
after_success:
- bash <(curl -s https://codecov.io/bash)
deploy:
provider: releases
api_key:
secure: OU8Dv4Z7XKnXWcwVRSCiMfhgfLHXxUOqk0KF0qEKqxb61HFTFKHWci9bW47n4vYF3/2YI23d8UcFQJcTLMYEe8PdMkNa+yDu1A0mWIAcuVHQ/bKJNEhFklnfac9kzf8mDkpjMmY2jvHXeFolLBfoznluCV2A7YnbfBK/zJ0FG8OpaTZyziJV+61PqwDVou3Zk9jDUSF6Okzjcxsn8NqpultK9uQ46+/CVfoh6aQMWTLU58wuFk2VT46/BBfchyHZl2C+QX0kBrp2jlYNXrdVZXGQVJ2AK2Jzk5l9FO0g2LZT0Tg6CatiTvNUewdlnYrEldkRvWU96y8TcaokNnTVLoZSKxztPX3E1c0a8sFHFvam64IQytRg+Bb3g2yJv4G7H0iC0gJEOJIQRukKbqY+yKzmQWhUyLXNyAMkaD4EZsWI5ec9wvzaTXAviK8pAYsiCRO2h3X6SdiFyGxMUDRZUIq48776gOcXK0TsdTBLqYEHXc5BKIPyDfpo3AN+2wdRxeyWnKAXxJVHSKurYSnJjk/0HTcZlkKeEvZgG2K1o2/MksuUovF71aTGStcb4/ma9bO5O38ZAoBOivp1UvIa0kKu5N9x+OdOxXdQBBnIZo5S8/YRjyejL4p6dNRHGq4wNWfrw3lbZU4KNqmWzLtj1qzjcnBjiy02BOpS6dpxrm4=
skip_cleanup: true
on:
repo: go-convert/fields
tags: true
notifications:
email:
on_success: change
on_failure: always

View File

@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

176
README.md
View File

@ -1 +1,175 @@
# fields
[![Go Report Card](https://goreportcard.com/badge/github.com/go-convert/fields)](https://goreportcard.com/report/github.com/go-convert/fields)
[![Actions Status](https://github.com/go-convert/fields/workflows/Go/badge.svg)](https://github.com/go-convert/fields/actions)
[![Build Status](https://travis-ci.org/go-convert/fields.svg?branch=master)](https://travis-ci.org/go-convert/fields)
[![codecov](https://codecov.io/gh/go-convert/fields/branch/master/graph/badge.svg)](https://codecov.io/gh/go-convert/fields)
# golang convert fields lib
## Idea
Main idea was to build a lib/helper to simplify copying same-name fields from one struct object to another one.
## Examples
### Example 1: most common usage, with sub-cases
```go
import (
"log"
"encoding/json"
"github.com/go-convert/fields"
)
type FromStruct struct {
ID string `conv:"new,update"`
Field1 string `conv:"new,update"`
Field2 string `conv:"update"`
}
type ToStruct struct {
ID string
Field1 string
Field2 string
Field3 string
}
func main() {
fromDefault := FromStruct{
"1", "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 1.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 1.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))
}
```
After running `go run examples/example-1/main.go`
Result will be something like below:
```bash
2020/01/14 21:46:32 example 1.1 - new
2020/01/14 21:46:32 from {"ID":"1","Field1":"field 1 value","Field2":"field 2 value"} => to {"ID":"1","Field1":"field 1 value","Field2":"old field 2 value","Field3":"old field 3 value"}
2020/01/14 21:46:32 example 1.2 - update
2020/01/14 21:46:32 from {"ID":"1","Field1":"field 1 value","Field2":"field 2 value"} => to {"ID":"1","Field1":"field 1 value","Field2":"field 2 value","Field3":"old field 3 value"}
```
### Example 2: custom config setup usage, with sub-cases
* New name of tag: `copy`
* New tag value for omitting: `ignore`
* New tag value for omitting empty field: `noempty`
```go
import (
"log"
"encoding/json"
"github.com/go-convert/fields"
)
type FromStructCustom struct {
ID string `copy:"new,update"`
Field1 string `copy:"new,update"`
Field2 string `copy:"update"`
Field3 string `copy:"category-1,ignore"`
Field4 string `copy:"category-1,noempty"`
}
type ToStruct struct {
ID string
Field1 string
Field2 string
Field3 string
Field4 string
}
func main() {
fields.SetTagName("copy")
fields.SetOmitTagName("ignore")
fields.SetOmitEmptyTagName("noempty")
log.Print("example 2.1 - new")
from := FromStructCustom{
"1", "field 1 value", "field 2 value", "omitting", "not empty",
}
to := ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
}
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 2.2.1 - category-1")
from = FromStructCustom{
"1", "field 1 value", "field 2 value", "omitting", "not empty",
}
to = ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
}
fields.Сonvert(from, "category-1", &to)
fromB, _ = json.Marshal(from)
toB, _ = json.Marshal(to)
log.Printf("from %s => to %s", string(fromB), string(toB))
log.Print("example 2.2.2 - category-1")
from = FromStructCustom{
"1", "field 1 value", "field 2 value", "omitting", "",
}
to = ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
}
fields.Сonvert(from, "category-1", &to)
fromB, _ = json.Marshal(from)
toB, _ = json.Marshal(to)
log.Printf("from %s => to %s", string(fromB), string(toB))
}
```
After running `go run examples/example-1/main.go`
Result will be something like below:
```bash
2020/01/14 23:13:26 example 2.1 - new
2020/01/14 23:13:26 from {"ID":"1","Field1":"field 1 value","Field2":"field 2 value","Field3":"omitting","Field4":"not empty"} => to {"ID":"1","Field1":"field 1 value","Field2":"old field 2 value","Field3":"old field 3 value","Field4":"old field 4 value"}
2020/01/14 23:13:26 example 2.2.1 - category-1
2020/01/14 23:13:26 from {"ID":"1","Field1":"field 1 value","Field2":"field 2 value","Field3":"omitting","Field4":"not empty"} => to {"ID":"old val 1","Field1":"old field 1 value","Field2":"old field 2 value","Field3":"old field 3 value","Field4":"not empty"}
2020/01/14 23:13:26 example 2.2.2 - category-1
2020/01/14 23:13:26 from {"ID":"1","Field1":"field 1 value","Field2":"field 2 value","Field3":"omitting","Field4":""} => to {"ID":"old val 1","Field1":"old field 1 value","Field2":"old field 2 value","Field3":"old field 3 value","Field4":"old field 4 value"}
```
## License
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.

71
common.go Normal file
View File

@ -0,0 +1,71 @@
/*
* 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 14.01.2020
*
*/
package fields
const (
defaultTagName = "conv"
defaultOmitTagName = "omit"
defaultOmitEmptyTagName = "omitempty"
)
var (
tagName = defaultTagName
omitTagName = defaultOmitTagName
omitEmptyTagName = defaultOmitEmptyTagName
)
// ConvertTagName returns special tag name
func ConvertTagName() string {
return tagName
}
// OmitTagName returns omitting tag name
func OmitTagName() string {
return omitTagName
}
// OmitEmptyTagName returns omitting empty field tag name
func OmitEmptyTagName() string {
return omitEmptyTagName
}
// SetTagName sets special tag name
func SetTagName(value string) {
tagName = value
}
// SetOmitTagName sets omitting tag name
func SetOmitTagName(value string) {
omitTagName = value
}
// SetOmitEmptyTagName sets omitting empty field tag name
func SetOmitEmptyTagName(value string) {
omitEmptyTagName = value
}
// SetDefaults resets all configured tag names to defaults
func SetDefaults() {
SetTagName(defaultTagName)
SetOmitTagName(defaultOmitTagName)
SetOmitEmptyTagName(defaultOmitEmptyTagName)
}

View File

@ -0,0 +1,71 @@
/*
* 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 14.01.2020
*
*/
package main
import (
"encoding/json"
"log"
"github.com/go-convert/fields"
)
type fromStruct struct {
ID string `conv:"new,update"`
Field1 string `conv:"new,update"`
Field2 string `conv:"update"`
}
type toStruct struct {
ID string
Field1 string
Field2 string
Field3 string
}
func main() {
fromDefault := fromStruct{
"1", "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 1.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 1.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

@ -0,0 +1,93 @@
/*
* 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 14.01.2020
*
*/
package main
import (
"encoding/json"
"log"
"github.com/go-convert/fields"
)
type fromStructCustom struct {
ID string `copy:"new,update"`
Field1 string `copy:"new,update"`
Field2 string `copy:"update"`
Field3 string `copy:"category-1,ignore"`
Field4 string `copy:"category-1,noempty"`
}
type toStruct struct {
ID string
Field1 string
Field2 string
Field3 string
Field4 string
}
func main() {
fields.SetTagName("copy")
fields.SetOmitTagName("ignore")
fields.SetOmitEmptyTagName("noempty")
log.Print("example 2.1 - new")
from := fromStructCustom{
"1", "field 1 value", "field 2 value", "omitting", "not empty",
}
to := toStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
}
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 2.2.1 - category-1")
from = fromStructCustom{
"1", "field 1 value", "field 2 value", "omitting", "not empty",
}
to = toStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
}
fields.Сonvert(from, "category-1", &to)
fromB, _ = json.Marshal(from)
toB, _ = json.Marshal(to)
log.Printf("from %s => to %s", string(fromB), string(toB))
log.Print("example 2.2.2 - category-1")
from = fromStructCustom{
"1", "field 1 value", "field 2 value", "omitting", "",
}
to = toStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
}
fields.Сonvert(from, "category-1", &to)
fromB, _ = json.Marshal(from)
toB, _ = json.Marshal(to)
log.Printf("from %s => to %s", string(fromB), string(toB))
}

96
fields.go Normal file
View File

@ -0,0 +1,96 @@
/*
* 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 14.01.2020
*
*/
package fields
import (
"log"
"reflect"
"strings"
)
//Convert copies field values from one struct to another based on tags setup
func Сonvert(from interface{}, kind string, to interface{}) {
if nil == from {
log.Print("nil value is not supported")
return
}
v := reflect.ValueOf(from)
vt := reflect.ValueOf(to)
t := v.Type()
if t.Kind() != reflect.Struct {
log.Printf("type %s is not supported", t.Kind())
return
}
if vt.Kind() == reflect.Ptr {
vt = reflect.ValueOf(to).Elem()
}
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
// skip unexported fields. from godoc:
// PkgPath is the package path that qualifies a lower case (unexported)
// field name. It is empty for upper case (exported) field names.
if f.PkgPath != "" {
continue
}
fv := v.Field(i)
found, omit, omitempty := readTag(f, kind)
// skip if tag "omit" set.
if omit {
continue
}
// skip empty values when "omitempty" set.
if omitempty && fv.String() == "" {
continue
}
if found {
ft := vt.FieldByName(f.Name)
ft.Set(fv)
}
}
}
func readTag(f reflect.StructField, kind string) (bool, bool, bool) {
val, ok := f.Tag.Lookup(ConvertTagName())
if !ok {
return false, false, false
}
opts := strings.Split(val, ",")
return indexOf(opts, kind) > -1, indexOf(opts, OmitTagName()) > -1, indexOf(opts, OmitEmptyTagName()) > -1
}
func indexOf(a []string, x string) int {
for i, n := range a {
if x == n {
return i
}
}
return -1
}

359
fields_test.go Normal file
View File

@ -0,0 +1,359 @@
/*
* 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 14.01.2020
*
*/
package fields_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/go-convert/fields"
)
type FromStruct struct {
ID string `conv:"new,update"`
Field1 string `conv:"new,update"`
Field2 string `conv:"update"`
Field3 string `conv:"update,omit"`
Field4 string `conv:"category-1,omitempty"`
}
type FromStructNone struct {
ID string `conv1:"new,update"`
Field1 string `conv2:"new,update"`
Field2 string `conv3:"update"`
}
type ToStruct struct {
ID string
Field1 string
Field2 string
Field3 string
Field4 string
}
type FromStructCustom struct {
ID string `copy:"new,update"`
Field1 string `copy:"new,update"`
Field2 string `copy:"update"`
Field3 string `copy:"update,ignore"`
Field4 string `copy:"category-1,noempty"`
}
var (
// testsNormal provides normal test cases
testsNormal = []struct {
from FromStruct
kind string
to ToStruct
expectedTo ToStruct
}{
// case 1.1
{
FromStruct{
"1", "field 1 value", "field 2 value", "omitting", "",
},
"new",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
ToStruct{
"1", "field 1 value", "old field 2 value", "old field 3 value", "",
},
},
// case 1.2
{
FromStruct{
"1", "field 1 value", "field 2 value", "omitting", "",
},
"update",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
ToStruct{
"1", "field 1 value", "field 2 value", "old field 3 value", "",
},
},
// case 1.3.1
{
FromStruct{
"1", "field 1 value", "field 2 value", "omitting", "",
},
"category-1",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
},
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
},
},
// case 1.3.2
{
FromStruct{
"1", "field 1 value", "field 2 value", "omitting", "not empty",
},
"category-1",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
},
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "not empty",
},
},
}
// testsNone provides not applicable test cases
testsNone = []struct {
from FromStructNone
kind string
to ToStruct
expectedTo ToStruct
}{
// case 1.1
{
FromStructNone{
"1", "field 1 value", "field 2 value",
},
"new",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
},
// case 1.2
{
FromStructNone{
"1", "field 1 value", "field 2 value",
},
"update",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
},
}
// testsNegative provides failing test cases
testsNegative = []struct {
from interface{}
kind string
to ToStruct
expectedTo ToStruct
}{
// case 1
{
"string value",
"new",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
},
// case 2
{
1,
"update",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
},
// case 3
{
nil,
"update",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
},
}
// testsCustomNormal provides normal test cases with custom init config
testsCustomNormal = []struct {
from FromStructCustom
kind string
to ToStruct
expectedTo ToStruct
}{
// case 1.1
{
FromStructCustom{
"1", "field 1 value", "field 2 value", "omitting", "",
},
"new",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
ToStruct{
"1", "field 1 value", "old field 2 value", "old field 3 value", "",
},
},
// case 1.2
{
FromStructCustom{
"1", "field 1 value", "field 2 value", "omitting", "",
},
"update",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "",
},
ToStruct{
"1", "field 1 value", "field 2 value", "old field 3 value", "",
},
},
// case 1.3.1
{
FromStructCustom{
"1", "field 1 value", "field 2 value", "omitting", "",
},
"category-1",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
},
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
},
},
// case 1.3.2
{
FromStructCustom{
"1", "field 1 value", "field 2 value", "omitting", "not empty",
},
"category-1",
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "old field 4 value",
},
ToStruct{
"old val 1", "old field 1 value", "old field 2 value", "old field 3 value", "not empty",
},
},
}
)
func TestConvert_Normal(t *testing.T) {
for _, test := range testsNormal {
to := &ToStruct{}
*to = test.to
fields.Сonvert(test.from, test.kind, to)
assert.NotEmpty(t, *to)
assert.Equal(t, test.expectedTo, *to)
}
}
func TestConvert_None(t *testing.T) {
for _, test := range testsNone {
to := &ToStruct{}
*to = test.to
fields.Сonvert(test.from, test.kind, to)
assert.NotEmpty(t, *to)
assert.Equal(t, test.expectedTo, *to)
}
}
func TestConvert_Negative(t *testing.T) {
for _, test := range testsNegative {
to := &ToStruct{}
*to = test.to
fields.Сonvert(test.from, test.kind, to)
assert.NotEmpty(t, *to)
assert.Equal(t, test.expectedTo, *to)
}
}
func TestConvert_Custom(t *testing.T) {
fields.SetTagName("copy")
fields.SetOmitTagName("ignore")
fields.SetOmitEmptyTagName("noempty")
for _, test := range testsCustomNormal {
to := &ToStruct{}
*to = test.to
fields.Сonvert(test.from, test.kind, to)
assert.NotEmpty(t, *to)
assert.Equal(t, test.expectedTo, *to)
}
}
func TestSetDefaults(t *testing.T) {
// not default values after previous tests
assert.NotEqual(t, "conv", fields.ConvertTagName())
assert.NotEqual(t, "omit", fields.OmitTagName())
assert.NotEqual(t, "omitempty", fields.OmitEmptyTagName())
fields.SetDefaults()
assert.Equal(t, "conv", fields.ConvertTagName())
assert.Equal(t, "omit", fields.OmitTagName())
assert.Equal(t, "omitempty", fields.OmitEmptyTagName())
}
func TestConvertTagName(t *testing.T) {
defaultValue := fields.ConvertTagName()
assert.Equal(t, "conv", defaultValue)
newValue := "newTagName"
fields.SetTagName(newValue)
assert.Equal(t, newValue, fields.ConvertTagName())
}
func TestOmitTagName(t *testing.T) {
defaultValue := fields.OmitTagName()
assert.Equal(t, defaultValue, "omit")
newValue := "newOmitTagName"
fields.SetOmitTagName(newValue)
assert.Equal(t, newValue, fields.OmitTagName())
}
func TestOmitEmptyTagName(t *testing.T) {
defaultValue := fields.OmitEmptyTagName()
assert.Equal(t, defaultValue, "omitempty")
newValue := "newOmitEmptyTagName"
fields.SetOmitEmptyTagName(newValue)
assert.Equal(t, newValue, fields.OmitEmptyTagName())
}

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module github.com/go-convert/fields
go 1.13
require github.com/stretchr/testify v1.4.0

11
go.sum Normal file
View File

@ -0,0 +1,11 @@
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
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/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=