Fix godeps
Signed-off-by: Olivier Gambier <olivier@docker.com>
This commit is contained in:
parent
77e69b9cf3
commit
53e3c1d7b2
806 changed files with 431 additions and 1075412 deletions
229
vendor/github.com/mitchellh/mapstructure/decode_hooks_test.go
generated
vendored
229
vendor/github.com/mitchellh/mapstructure/decode_hooks_test.go
generated
vendored
|
@ -1,229 +0,0 @@
|
|||
package mapstructure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestComposeDecodeHookFunc(t *testing.T) {
|
||||
f1 := func(
|
||||
f reflect.Kind,
|
||||
t reflect.Kind,
|
||||
data interface{}) (interface{}, error) {
|
||||
return data.(string) + "foo", nil
|
||||
}
|
||||
|
||||
f2 := func(
|
||||
f reflect.Kind,
|
||||
t reflect.Kind,
|
||||
data interface{}) (interface{}, error) {
|
||||
return data.(string) + "bar", nil
|
||||
}
|
||||
|
||||
f := ComposeDecodeHookFunc(f1, f2)
|
||||
|
||||
result, err := DecodeHookExec(
|
||||
f, reflect.TypeOf(""), reflect.TypeOf([]byte("")), "")
|
||||
if err != nil {
|
||||
t.Fatalf("bad: %s", err)
|
||||
}
|
||||
if result.(string) != "foobar" {
|
||||
t.Fatalf("bad: %#v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestComposeDecodeHookFunc_err(t *testing.T) {
|
||||
f1 := func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) {
|
||||
return nil, errors.New("foo")
|
||||
}
|
||||
|
||||
f2 := func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) {
|
||||
panic("NOPE")
|
||||
}
|
||||
|
||||
f := ComposeDecodeHookFunc(f1, f2)
|
||||
|
||||
_, err := DecodeHookExec(
|
||||
f, reflect.TypeOf(""), reflect.TypeOf([]byte("")), 42)
|
||||
if err.Error() != "foo" {
|
||||
t.Fatalf("bad: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestComposeDecodeHookFunc_kinds(t *testing.T) {
|
||||
var f2From reflect.Kind
|
||||
|
||||
f1 := func(
|
||||
f reflect.Kind,
|
||||
t reflect.Kind,
|
||||
data interface{}) (interface{}, error) {
|
||||
return int(42), nil
|
||||
}
|
||||
|
||||
f2 := func(
|
||||
f reflect.Kind,
|
||||
t reflect.Kind,
|
||||
data interface{}) (interface{}, error) {
|
||||
f2From = f
|
||||
return data, nil
|
||||
}
|
||||
|
||||
f := ComposeDecodeHookFunc(f1, f2)
|
||||
|
||||
_, err := DecodeHookExec(
|
||||
f, reflect.TypeOf(""), reflect.TypeOf([]byte("")), "")
|
||||
if err != nil {
|
||||
t.Fatalf("bad: %s", err)
|
||||
}
|
||||
if f2From != reflect.Int {
|
||||
t.Fatalf("bad: %#v", f2From)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringToSliceHookFunc(t *testing.T) {
|
||||
f := StringToSliceHookFunc(",")
|
||||
|
||||
strType := reflect.TypeOf("")
|
||||
sliceType := reflect.TypeOf([]byte(""))
|
||||
cases := []struct {
|
||||
f, t reflect.Type
|
||||
data interface{}
|
||||
result interface{}
|
||||
err bool
|
||||
}{
|
||||
{sliceType, sliceType, 42, 42, false},
|
||||
{strType, strType, 42, 42, false},
|
||||
{
|
||||
strType,
|
||||
sliceType,
|
||||
"foo,bar,baz",
|
||||
[]string{"foo", "bar", "baz"},
|
||||
false,
|
||||
},
|
||||
{
|
||||
strType,
|
||||
sliceType,
|
||||
"",
|
||||
[]string{},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
actual, err := DecodeHookExec(f, tc.f, tc.t, tc.data)
|
||||
if tc.err != (err != nil) {
|
||||
t.Fatalf("case %d: expected err %#v", i, tc.err)
|
||||
}
|
||||
if !reflect.DeepEqual(actual, tc.result) {
|
||||
t.Fatalf(
|
||||
"case %d: expected %#v, got %#v",
|
||||
i, tc.result, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringToTimeDurationHookFunc(t *testing.T) {
|
||||
f := StringToTimeDurationHookFunc()
|
||||
|
||||
strType := reflect.TypeOf("")
|
||||
timeType := reflect.TypeOf(time.Duration(5))
|
||||
cases := []struct {
|
||||
f, t reflect.Type
|
||||
data interface{}
|
||||
result interface{}
|
||||
err bool
|
||||
}{
|
||||
{strType, timeType, "5s", 5 * time.Second, false},
|
||||
{strType, timeType, "5", time.Duration(0), true},
|
||||
{strType, strType, "5", "5", false},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
actual, err := DecodeHookExec(f, tc.f, tc.t, tc.data)
|
||||
if tc.err != (err != nil) {
|
||||
t.Fatalf("case %d: expected err %#v", i, tc.err)
|
||||
}
|
||||
if !reflect.DeepEqual(actual, tc.result) {
|
||||
t.Fatalf(
|
||||
"case %d: expected %#v, got %#v",
|
||||
i, tc.result, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWeaklyTypedHook(t *testing.T) {
|
||||
var f DecodeHookFunc = WeaklyTypedHook
|
||||
|
||||
boolType := reflect.TypeOf(true)
|
||||
strType := reflect.TypeOf("")
|
||||
sliceType := reflect.TypeOf([]byte(""))
|
||||
cases := []struct {
|
||||
f, t reflect.Type
|
||||
data interface{}
|
||||
result interface{}
|
||||
err bool
|
||||
}{
|
||||
// TO STRING
|
||||
{
|
||||
boolType,
|
||||
strType,
|
||||
false,
|
||||
"0",
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
boolType,
|
||||
strType,
|
||||
true,
|
||||
"1",
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
reflect.TypeOf(float32(1)),
|
||||
strType,
|
||||
float32(7),
|
||||
"7",
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
reflect.TypeOf(int(1)),
|
||||
strType,
|
||||
int(7),
|
||||
"7",
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
sliceType,
|
||||
strType,
|
||||
[]uint8("foo"),
|
||||
"foo",
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
reflect.TypeOf(uint(1)),
|
||||
strType,
|
||||
uint(7),
|
||||
"7",
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
actual, err := DecodeHookExec(f, tc.f, tc.t, tc.data)
|
||||
if tc.err != (err != nil) {
|
||||
t.Fatalf("case %d: expected err %#v", i, tc.err)
|
||||
}
|
||||
if !reflect.DeepEqual(actual, tc.result) {
|
||||
t.Fatalf(
|
||||
"case %d: expected %#v, got %#v",
|
||||
i, tc.result, actual)
|
||||
}
|
||||
}
|
||||
}
|
243
vendor/github.com/mitchellh/mapstructure/mapstructure_benchmark_test.go
generated
vendored
243
vendor/github.com/mitchellh/mapstructure/mapstructure_benchmark_test.go
generated
vendored
|
@ -1,243 +0,0 @@
|
|||
package mapstructure
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Benchmark_Decode(b *testing.B) {
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
Emails []string
|
||||
Extra map[string]string
|
||||
}
|
||||
|
||||
input := map[string]interface{}{
|
||||
"name": "Mitchell",
|
||||
"age": 91,
|
||||
"emails": []string{"one", "two", "three"},
|
||||
"extra": map[string]string{
|
||||
"twitter": "mitchellh",
|
||||
},
|
||||
}
|
||||
|
||||
var result Person
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(input, &result)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_DecodeBasic(b *testing.B) {
|
||||
input := map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"vint": 42,
|
||||
"Vuint": 42,
|
||||
"vbool": true,
|
||||
"Vfloat": 42.42,
|
||||
"vsilent": true,
|
||||
"vdata": 42,
|
||||
}
|
||||
|
||||
var result Basic
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(input, &result)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_DecodeEmbedded(b *testing.B) {
|
||||
input := map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"Basic": map[string]interface{}{
|
||||
"vstring": "innerfoo",
|
||||
},
|
||||
"vunique": "bar",
|
||||
}
|
||||
|
||||
var result Embedded
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(input, &result)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_DecodeTypeConversion(b *testing.B) {
|
||||
input := map[string]interface{}{
|
||||
"IntToFloat": 42,
|
||||
"IntToUint": 42,
|
||||
"IntToBool": 1,
|
||||
"IntToString": 42,
|
||||
"UintToInt": 42,
|
||||
"UintToFloat": 42,
|
||||
"UintToBool": 42,
|
||||
"UintToString": 42,
|
||||
"BoolToInt": true,
|
||||
"BoolToUint": true,
|
||||
"BoolToFloat": true,
|
||||
"BoolToString": true,
|
||||
"FloatToInt": 42.42,
|
||||
"FloatToUint": 42.42,
|
||||
"FloatToBool": 42.42,
|
||||
"FloatToString": 42.42,
|
||||
"StringToInt": "42",
|
||||
"StringToUint": "42",
|
||||
"StringToBool": "1",
|
||||
"StringToFloat": "42.42",
|
||||
"SliceToMap": []interface{}{},
|
||||
"MapToSlice": map[string]interface{}{},
|
||||
}
|
||||
|
||||
var resultStrict TypeConversionResult
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(input, &resultStrict)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_DecodeMap(b *testing.B) {
|
||||
input := map[string]interface{}{
|
||||
"vfoo": "foo",
|
||||
"vother": map[interface{}]interface{}{
|
||||
"foo": "foo",
|
||||
"bar": "bar",
|
||||
},
|
||||
}
|
||||
|
||||
var result Map
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(input, &result)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_DecodeMapOfStruct(b *testing.B) {
|
||||
input := map[string]interface{}{
|
||||
"value": map[string]interface{}{
|
||||
"foo": map[string]string{"vstring": "one"},
|
||||
"bar": map[string]string{"vstring": "two"},
|
||||
},
|
||||
}
|
||||
|
||||
var result MapOfStruct
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(input, &result)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_DecodeSlice(b *testing.B) {
|
||||
input := map[string]interface{}{
|
||||
"vfoo": "foo",
|
||||
"vbar": []string{"foo", "bar", "baz"},
|
||||
}
|
||||
|
||||
var result Slice
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(input, &result)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_DecodeSliceOfStruct(b *testing.B) {
|
||||
input := map[string]interface{}{
|
||||
"value": []map[string]interface{}{
|
||||
{"vstring": "one"},
|
||||
{"vstring": "two"},
|
||||
},
|
||||
}
|
||||
|
||||
var result SliceOfStruct
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(input, &result)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_DecodeWeaklyTypedInput(b *testing.B) {
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
Emails []string
|
||||
}
|
||||
|
||||
// This input can come from anywhere, but typically comes from
|
||||
// something like decoding JSON, generated by a weakly typed language
|
||||
// such as PHP.
|
||||
input := map[string]interface{}{
|
||||
"name": 123, // number => string
|
||||
"age": "42", // string => number
|
||||
"emails": map[string]interface{}{}, // empty map => empty array
|
||||
}
|
||||
|
||||
var result Person
|
||||
config := &DecoderConfig{
|
||||
WeaklyTypedInput: true,
|
||||
Result: &result,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
decoder.Decode(input)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_DecodeMetadata(b *testing.B) {
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
input := map[string]interface{}{
|
||||
"name": "Mitchell",
|
||||
"age": 91,
|
||||
"email": "foo@bar.com",
|
||||
}
|
||||
|
||||
var md Metadata
|
||||
var result Person
|
||||
config := &DecoderConfig{
|
||||
Metadata: &md,
|
||||
Result: &result,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
decoder.Decode(input)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_DecodeMetadataEmbedded(b *testing.B) {
|
||||
input := map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"vunique": "bar",
|
||||
}
|
||||
|
||||
var md Metadata
|
||||
var result EmbeddedSquash
|
||||
config := &DecoderConfig{
|
||||
Metadata: &md,
|
||||
Result: &result,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
b.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
decoder.Decode(input)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_DecodeTagged(b *testing.B) {
|
||||
input := map[string]interface{}{
|
||||
"foo": "bar",
|
||||
"bar": "value",
|
||||
}
|
||||
|
||||
var result Tagged
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(input, &result)
|
||||
}
|
||||
}
|
47
vendor/github.com/mitchellh/mapstructure/mapstructure_bugs_test.go
generated
vendored
47
vendor/github.com/mitchellh/mapstructure/mapstructure_bugs_test.go
generated
vendored
|
@ -1,47 +0,0 @@
|
|||
package mapstructure
|
||||
|
||||
import "testing"
|
||||
|
||||
// GH-1
|
||||
func TestDecode_NilValue(t *testing.T) {
|
||||
input := map[string]interface{}{
|
||||
"vfoo": nil,
|
||||
"vother": nil,
|
||||
}
|
||||
|
||||
var result Map
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("should not error: %s", err)
|
||||
}
|
||||
|
||||
if result.Vfoo != "" {
|
||||
t.Fatalf("value should be default: %s", result.Vfoo)
|
||||
}
|
||||
|
||||
if result.Vother != nil {
|
||||
t.Fatalf("Vother should be nil: %s", result.Vother)
|
||||
}
|
||||
}
|
||||
|
||||
// GH-10
|
||||
func TestDecode_mapInterfaceInterface(t *testing.T) {
|
||||
input := map[interface{}]interface{}{
|
||||
"vfoo": nil,
|
||||
"vother": nil,
|
||||
}
|
||||
|
||||
var result Map
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("should not error: %s", err)
|
||||
}
|
||||
|
||||
if result.Vfoo != "" {
|
||||
t.Fatalf("value should be default: %s", result.Vfoo)
|
||||
}
|
||||
|
||||
if result.Vother != nil {
|
||||
t.Fatalf("Vother should be nil: %s", result.Vother)
|
||||
}
|
||||
}
|
203
vendor/github.com/mitchellh/mapstructure/mapstructure_examples_test.go
generated
vendored
203
vendor/github.com/mitchellh/mapstructure/mapstructure_examples_test.go
generated
vendored
|
@ -1,203 +0,0 @@
|
|||
package mapstructure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func ExampleDecode() {
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
Emails []string
|
||||
Extra map[string]string
|
||||
}
|
||||
|
||||
// This input can come from anywhere, but typically comes from
|
||||
// something like decoding JSON where we're not quite sure of the
|
||||
// struct initially.
|
||||
input := map[string]interface{}{
|
||||
"name": "Mitchell",
|
||||
"age": 91,
|
||||
"emails": []string{"one", "two", "three"},
|
||||
"extra": map[string]string{
|
||||
"twitter": "mitchellh",
|
||||
},
|
||||
}
|
||||
|
||||
var result Person
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%#v", result)
|
||||
// Output:
|
||||
// mapstructure.Person{Name:"Mitchell", Age:91, Emails:[]string{"one", "two", "three"}, Extra:map[string]string{"twitter":"mitchellh"}}
|
||||
}
|
||||
|
||||
func ExampleDecode_errors() {
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
Emails []string
|
||||
Extra map[string]string
|
||||
}
|
||||
|
||||
// This input can come from anywhere, but typically comes from
|
||||
// something like decoding JSON where we're not quite sure of the
|
||||
// struct initially.
|
||||
input := map[string]interface{}{
|
||||
"name": 123,
|
||||
"age": "bad value",
|
||||
"emails": []int{1, 2, 3},
|
||||
}
|
||||
|
||||
var result Person
|
||||
err := Decode(input, &result)
|
||||
if err == nil {
|
||||
panic("should have an error")
|
||||
}
|
||||
|
||||
fmt.Println(err.Error())
|
||||
// Output:
|
||||
// 5 error(s) decoding:
|
||||
//
|
||||
// * 'Age' expected type 'int', got unconvertible type 'string'
|
||||
// * 'Emails[0]' expected type 'string', got unconvertible type 'int'
|
||||
// * 'Emails[1]' expected type 'string', got unconvertible type 'int'
|
||||
// * 'Emails[2]' expected type 'string', got unconvertible type 'int'
|
||||
// * 'Name' expected type 'string', got unconvertible type 'int'
|
||||
}
|
||||
|
||||
func ExampleDecode_metadata() {
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// This input can come from anywhere, but typically comes from
|
||||
// something like decoding JSON where we're not quite sure of the
|
||||
// struct initially.
|
||||
input := map[string]interface{}{
|
||||
"name": "Mitchell",
|
||||
"age": 91,
|
||||
"email": "foo@bar.com",
|
||||
}
|
||||
|
||||
// For metadata, we make a more advanced DecoderConfig so we can
|
||||
// more finely configure the decoder that is used. In this case, we
|
||||
// just tell the decoder we want to track metadata.
|
||||
var md Metadata
|
||||
var result Person
|
||||
config := &DecoderConfig{
|
||||
Metadata: &md,
|
||||
Result: &result,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := decoder.Decode(input); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Unused keys: %#v", md.Unused)
|
||||
// Output:
|
||||
// Unused keys: []string{"email"}
|
||||
}
|
||||
|
||||
func ExampleDecode_weaklyTypedInput() {
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
Emails []string
|
||||
}
|
||||
|
||||
// This input can come from anywhere, but typically comes from
|
||||
// something like decoding JSON, generated by a weakly typed language
|
||||
// such as PHP.
|
||||
input := map[string]interface{}{
|
||||
"name": 123, // number => string
|
||||
"age": "42", // string => number
|
||||
"emails": map[string]interface{}{}, // empty map => empty array
|
||||
}
|
||||
|
||||
var result Person
|
||||
config := &DecoderConfig{
|
||||
WeaklyTypedInput: true,
|
||||
Result: &result,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = decoder.Decode(input)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%#v", result)
|
||||
// Output: mapstructure.Person{Name:"123", Age:42, Emails:[]string{}}
|
||||
}
|
||||
|
||||
func ExampleDecode_tags() {
|
||||
// Note that the mapstructure tags defined in the struct type
|
||||
// can indicate which fields the values are mapped to.
|
||||
type Person struct {
|
||||
Name string `mapstructure:"person_name"`
|
||||
Age int `mapstructure:"person_age"`
|
||||
}
|
||||
|
||||
input := map[string]interface{}{
|
||||
"person_name": "Mitchell",
|
||||
"person_age": 91,
|
||||
}
|
||||
|
||||
var result Person
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%#v", result)
|
||||
// Output:
|
||||
// mapstructure.Person{Name:"Mitchell", Age:91}
|
||||
}
|
||||
|
||||
func ExampleDecode_embeddedStruct() {
|
||||
// Squashing multiple embedded structs is allowed using the squash tag.
|
||||
// This is demonstrated by creating a composite struct of multiple types
|
||||
// and decoding into it. In this case, a person can carry with it both
|
||||
// a Family and a Location, as well as their own FirstName.
|
||||
type Family struct {
|
||||
LastName string
|
||||
}
|
||||
type Location struct {
|
||||
City string
|
||||
}
|
||||
type Person struct {
|
||||
Family `mapstructure:",squash"`
|
||||
Location `mapstructure:",squash"`
|
||||
FirstName string
|
||||
}
|
||||
|
||||
input := map[string]interface{}{
|
||||
"FirstName": "Mitchell",
|
||||
"LastName": "Hashimoto",
|
||||
"City": "San Francisco",
|
||||
}
|
||||
|
||||
var result Person
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%s %s, %s", result.FirstName, result.LastName, result.City)
|
||||
// Output:
|
||||
// Mitchell Hashimoto, San Francisco
|
||||
}
|
954
vendor/github.com/mitchellh/mapstructure/mapstructure_test.go
generated
vendored
954
vendor/github.com/mitchellh/mapstructure/mapstructure_test.go
generated
vendored
|
@ -1,954 +0,0 @@
|
|||
package mapstructure
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type Basic struct {
|
||||
Vstring string
|
||||
Vint int
|
||||
Vuint uint
|
||||
Vbool bool
|
||||
Vfloat float64
|
||||
Vextra string
|
||||
vsilent bool
|
||||
Vdata interface{}
|
||||
}
|
||||
|
||||
type Embedded struct {
|
||||
Basic
|
||||
Vunique string
|
||||
}
|
||||
|
||||
type EmbeddedPointer struct {
|
||||
*Basic
|
||||
Vunique string
|
||||
}
|
||||
|
||||
type EmbeddedSquash struct {
|
||||
Basic `mapstructure:",squash"`
|
||||
Vunique string
|
||||
}
|
||||
|
||||
type Map struct {
|
||||
Vfoo string
|
||||
Vother map[string]string
|
||||
}
|
||||
|
||||
type MapOfStruct struct {
|
||||
Value map[string]Basic
|
||||
}
|
||||
|
||||
type Nested struct {
|
||||
Vfoo string
|
||||
Vbar Basic
|
||||
}
|
||||
|
||||
type NestedPointer struct {
|
||||
Vfoo string
|
||||
Vbar *Basic
|
||||
}
|
||||
|
||||
type Slice struct {
|
||||
Vfoo string
|
||||
Vbar []string
|
||||
}
|
||||
|
||||
type SliceOfStruct struct {
|
||||
Value []Basic
|
||||
}
|
||||
|
||||
type Tagged struct {
|
||||
Extra string `mapstructure:"bar,what,what"`
|
||||
Value string `mapstructure:"foo"`
|
||||
}
|
||||
|
||||
type TypeConversionResult struct {
|
||||
IntToFloat float32
|
||||
IntToUint uint
|
||||
IntToBool bool
|
||||
IntToString string
|
||||
UintToInt int
|
||||
UintToFloat float32
|
||||
UintToBool bool
|
||||
UintToString string
|
||||
BoolToInt int
|
||||
BoolToUint uint
|
||||
BoolToFloat float32
|
||||
BoolToString string
|
||||
FloatToInt int
|
||||
FloatToUint uint
|
||||
FloatToBool bool
|
||||
FloatToString string
|
||||
SliceUint8ToString string
|
||||
StringToInt int
|
||||
StringToUint uint
|
||||
StringToBool bool
|
||||
StringToFloat float32
|
||||
SliceToMap map[string]interface{}
|
||||
MapToSlice []interface{}
|
||||
}
|
||||
|
||||
func TestBasicTypes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"vint": 42,
|
||||
"Vuint": 42,
|
||||
"vbool": true,
|
||||
"Vfloat": 42.42,
|
||||
"vsilent": true,
|
||||
"vdata": 42,
|
||||
}
|
||||
|
||||
var result Basic
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Errorf("got an err: %s", err.Error())
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
if result.Vstring != "foo" {
|
||||
t.Errorf("vstring value should be 'foo': %#v", result.Vstring)
|
||||
}
|
||||
|
||||
if result.Vint != 42 {
|
||||
t.Errorf("vint value should be 42: %#v", result.Vint)
|
||||
}
|
||||
|
||||
if result.Vuint != 42 {
|
||||
t.Errorf("vuint value should be 42: %#v", result.Vuint)
|
||||
}
|
||||
|
||||
if result.Vbool != true {
|
||||
t.Errorf("vbool value should be true: %#v", result.Vbool)
|
||||
}
|
||||
|
||||
if result.Vfloat != 42.42 {
|
||||
t.Errorf("vfloat value should be 42.42: %#v", result.Vfloat)
|
||||
}
|
||||
|
||||
if result.Vextra != "" {
|
||||
t.Errorf("vextra value should be empty: %#v", result.Vextra)
|
||||
}
|
||||
|
||||
if result.vsilent != false {
|
||||
t.Error("vsilent should not be set, it is unexported")
|
||||
}
|
||||
|
||||
if result.Vdata != 42 {
|
||||
t.Error("vdata should be valid")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBasic_IntWithFloat(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vint": float64(42),
|
||||
}
|
||||
|
||||
var result Basic
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode_Embedded(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"Basic": map[string]interface{}{
|
||||
"vstring": "innerfoo",
|
||||
},
|
||||
"vunique": "bar",
|
||||
}
|
||||
|
||||
var result Embedded
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %s", err.Error())
|
||||
}
|
||||
|
||||
if result.Vstring != "innerfoo" {
|
||||
t.Errorf("vstring value should be 'innerfoo': %#v", result.Vstring)
|
||||
}
|
||||
|
||||
if result.Vunique != "bar" {
|
||||
t.Errorf("vunique value should be 'bar': %#v", result.Vunique)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode_EmbeddedPointer(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"Basic": map[string]interface{}{
|
||||
"vstring": "innerfoo",
|
||||
},
|
||||
"vunique": "bar",
|
||||
}
|
||||
|
||||
var result EmbeddedPointer
|
||||
err := Decode(input, &result)
|
||||
if err == nil {
|
||||
t.Fatal("should get error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode_EmbeddedSquash(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"vunique": "bar",
|
||||
}
|
||||
|
||||
var result EmbeddedSquash
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %s", err.Error())
|
||||
}
|
||||
|
||||
if result.Vstring != "foo" {
|
||||
t.Errorf("vstring value should be 'foo': %#v", result.Vstring)
|
||||
}
|
||||
|
||||
if result.Vunique != "bar" {
|
||||
t.Errorf("vunique value should be 'bar': %#v", result.Vunique)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode_DecodeHook(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vint": "WHAT",
|
||||
}
|
||||
|
||||
decodeHook := func(from reflect.Kind, to reflect.Kind, v interface{}) (interface{}, error) {
|
||||
if from == reflect.String && to != reflect.String {
|
||||
return 5, nil
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
var result Basic
|
||||
config := &DecoderConfig{
|
||||
DecodeHook: decodeHook,
|
||||
Result: &result,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
err = decoder.Decode(input)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %s", err)
|
||||
}
|
||||
|
||||
if result.Vint != 5 {
|
||||
t.Errorf("vint should be 5: %#v", result.Vint)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode_DecodeHookType(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vint": "WHAT",
|
||||
}
|
||||
|
||||
decodeHook := func(from reflect.Type, to reflect.Type, v interface{}) (interface{}, error) {
|
||||
if from.Kind() == reflect.String &&
|
||||
to.Kind() != reflect.String {
|
||||
return 5, nil
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
var result Basic
|
||||
config := &DecoderConfig{
|
||||
DecodeHook: decodeHook,
|
||||
Result: &result,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
err = decoder.Decode(input)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %s", err)
|
||||
}
|
||||
|
||||
if result.Vint != 5 {
|
||||
t.Errorf("vint should be 5: %#v", result.Vint)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode_Nil(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var input interface{} = nil
|
||||
result := Basic{
|
||||
Vstring: "foo",
|
||||
}
|
||||
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if result.Vstring != "foo" {
|
||||
t.Fatalf("bad: %#v", result.Vstring)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode_NonStruct(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"foo": "bar",
|
||||
"bar": "baz",
|
||||
}
|
||||
|
||||
var result map[string]string
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if result["foo"] != "bar" {
|
||||
t.Fatal("foo is not bar")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode_StructMatch(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vbar": Basic{
|
||||
Vstring: "foo",
|
||||
},
|
||||
}
|
||||
|
||||
var result Nested
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %s", err.Error())
|
||||
}
|
||||
|
||||
if result.Vbar.Vstring != "foo" {
|
||||
t.Errorf("bad: %#v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode_TypeConversion(t *testing.T) {
|
||||
input := map[string]interface{}{
|
||||
"IntToFloat": 42,
|
||||
"IntToUint": 42,
|
||||
"IntToBool": 1,
|
||||
"IntToString": 42,
|
||||
"UintToInt": 42,
|
||||
"UintToFloat": 42,
|
||||
"UintToBool": 42,
|
||||
"UintToString": 42,
|
||||
"BoolToInt": true,
|
||||
"BoolToUint": true,
|
||||
"BoolToFloat": true,
|
||||
"BoolToString": true,
|
||||
"FloatToInt": 42.42,
|
||||
"FloatToUint": 42.42,
|
||||
"FloatToBool": 42.42,
|
||||
"FloatToString": 42.42,
|
||||
"SliceUint8ToString": []uint8("foo"),
|
||||
"StringToInt": "42",
|
||||
"StringToUint": "42",
|
||||
"StringToBool": "1",
|
||||
"StringToFloat": "42.42",
|
||||
"SliceToMap": []interface{}{},
|
||||
"MapToSlice": map[string]interface{}{},
|
||||
}
|
||||
|
||||
expectedResultStrict := TypeConversionResult{
|
||||
IntToFloat: 42.0,
|
||||
IntToUint: 42,
|
||||
UintToInt: 42,
|
||||
UintToFloat: 42,
|
||||
BoolToInt: 0,
|
||||
BoolToUint: 0,
|
||||
BoolToFloat: 0,
|
||||
FloatToInt: 42,
|
||||
FloatToUint: 42,
|
||||
}
|
||||
|
||||
expectedResultWeak := TypeConversionResult{
|
||||
IntToFloat: 42.0,
|
||||
IntToUint: 42,
|
||||
IntToBool: true,
|
||||
IntToString: "42",
|
||||
UintToInt: 42,
|
||||
UintToFloat: 42,
|
||||
UintToBool: true,
|
||||
UintToString: "42",
|
||||
BoolToInt: 1,
|
||||
BoolToUint: 1,
|
||||
BoolToFloat: 1,
|
||||
BoolToString: "1",
|
||||
FloatToInt: 42,
|
||||
FloatToUint: 42,
|
||||
FloatToBool: true,
|
||||
FloatToString: "42.42",
|
||||
SliceUint8ToString: "foo",
|
||||
StringToInt: 42,
|
||||
StringToUint: 42,
|
||||
StringToBool: true,
|
||||
StringToFloat: 42.42,
|
||||
SliceToMap: map[string]interface{}{},
|
||||
MapToSlice: []interface{}{},
|
||||
}
|
||||
|
||||
// Test strict type conversion
|
||||
var resultStrict TypeConversionResult
|
||||
err := Decode(input, &resultStrict)
|
||||
if err == nil {
|
||||
t.Errorf("should return an error")
|
||||
}
|
||||
if !reflect.DeepEqual(resultStrict, expectedResultStrict) {
|
||||
t.Errorf("expected %v, got: %v", expectedResultStrict, resultStrict)
|
||||
}
|
||||
|
||||
// Test weak type conversion
|
||||
var decoder *Decoder
|
||||
var resultWeak TypeConversionResult
|
||||
|
||||
config := &DecoderConfig{
|
||||
WeaklyTypedInput: true,
|
||||
Result: &resultWeak,
|
||||
}
|
||||
|
||||
decoder, err = NewDecoder(config)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
err = decoder.Decode(input)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %s", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(resultWeak, expectedResultWeak) {
|
||||
t.Errorf("expected \n%#v, got: \n%#v", expectedResultWeak, resultWeak)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecoder_ErrorUnused(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vstring": "hello",
|
||||
"foo": "bar",
|
||||
}
|
||||
|
||||
var result Basic
|
||||
config := &DecoderConfig{
|
||||
ErrorUnused: true,
|
||||
Result: &result,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
err = decoder.Decode(input)
|
||||
if err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMap(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vfoo": "foo",
|
||||
"vother": map[interface{}]interface{}{
|
||||
"foo": "foo",
|
||||
"bar": "bar",
|
||||
},
|
||||
}
|
||||
|
||||
var result Map
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got an error: %s", err)
|
||||
}
|
||||
|
||||
if result.Vfoo != "foo" {
|
||||
t.Errorf("vfoo value should be 'foo': %#v", result.Vfoo)
|
||||
}
|
||||
|
||||
if result.Vother == nil {
|
||||
t.Fatal("vother should not be nil")
|
||||
}
|
||||
|
||||
if len(result.Vother) != 2 {
|
||||
t.Error("vother should have two items")
|
||||
}
|
||||
|
||||
if result.Vother["foo"] != "foo" {
|
||||
t.Errorf("'foo' key should be foo, got: %#v", result.Vother["foo"])
|
||||
}
|
||||
|
||||
if result.Vother["bar"] != "bar" {
|
||||
t.Errorf("'bar' key should be bar, got: %#v", result.Vother["bar"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapMerge(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vfoo": "foo",
|
||||
"vother": map[interface{}]interface{}{
|
||||
"foo": "foo",
|
||||
"bar": "bar",
|
||||
},
|
||||
}
|
||||
|
||||
var result Map
|
||||
result.Vother = map[string]string{"hello": "world"}
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got an error: %s", err)
|
||||
}
|
||||
|
||||
if result.Vfoo != "foo" {
|
||||
t.Errorf("vfoo value should be 'foo': %#v", result.Vfoo)
|
||||
}
|
||||
|
||||
expected := map[string]string{
|
||||
"foo": "foo",
|
||||
"bar": "bar",
|
||||
"hello": "world",
|
||||
}
|
||||
if !reflect.DeepEqual(result.Vother, expected) {
|
||||
t.Errorf("bad: %#v", result.Vother)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapOfStruct(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"value": map[string]interface{}{
|
||||
"foo": map[string]string{"vstring": "one"},
|
||||
"bar": map[string]string{"vstring": "two"},
|
||||
},
|
||||
}
|
||||
|
||||
var result MapOfStruct
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %s", err)
|
||||
}
|
||||
|
||||
if result.Value == nil {
|
||||
t.Fatal("value should not be nil")
|
||||
}
|
||||
|
||||
if len(result.Value) != 2 {
|
||||
t.Error("value should have two items")
|
||||
}
|
||||
|
||||
if result.Value["foo"].Vstring != "one" {
|
||||
t.Errorf("foo value should be 'one', got: %s", result.Value["foo"].Vstring)
|
||||
}
|
||||
|
||||
if result.Value["bar"].Vstring != "two" {
|
||||
t.Errorf("bar value should be 'two', got: %s", result.Value["bar"].Vstring)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNestedType(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vfoo": "foo",
|
||||
"vbar": map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"vint": 42,
|
||||
"vbool": true,
|
||||
},
|
||||
}
|
||||
|
||||
var result Nested
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %s", err.Error())
|
||||
}
|
||||
|
||||
if result.Vfoo != "foo" {
|
||||
t.Errorf("vfoo value should be 'foo': %#v", result.Vfoo)
|
||||
}
|
||||
|
||||
if result.Vbar.Vstring != "foo" {
|
||||
t.Errorf("vstring value should be 'foo': %#v", result.Vbar.Vstring)
|
||||
}
|
||||
|
||||
if result.Vbar.Vint != 42 {
|
||||
t.Errorf("vint value should be 42: %#v", result.Vbar.Vint)
|
||||
}
|
||||
|
||||
if result.Vbar.Vbool != true {
|
||||
t.Errorf("vbool value should be true: %#v", result.Vbar.Vbool)
|
||||
}
|
||||
|
||||
if result.Vbar.Vextra != "" {
|
||||
t.Errorf("vextra value should be empty: %#v", result.Vbar.Vextra)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNestedTypePointer(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vfoo": "foo",
|
||||
"vbar": &map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"vint": 42,
|
||||
"vbool": true,
|
||||
},
|
||||
}
|
||||
|
||||
var result NestedPointer
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %s", err.Error())
|
||||
}
|
||||
|
||||
if result.Vfoo != "foo" {
|
||||
t.Errorf("vfoo value should be 'foo': %#v", result.Vfoo)
|
||||
}
|
||||
|
||||
if result.Vbar.Vstring != "foo" {
|
||||
t.Errorf("vstring value should be 'foo': %#v", result.Vbar.Vstring)
|
||||
}
|
||||
|
||||
if result.Vbar.Vint != 42 {
|
||||
t.Errorf("vint value should be 42: %#v", result.Vbar.Vint)
|
||||
}
|
||||
|
||||
if result.Vbar.Vbool != true {
|
||||
t.Errorf("vbool value should be true: %#v", result.Vbar.Vbool)
|
||||
}
|
||||
|
||||
if result.Vbar.Vextra != "" {
|
||||
t.Errorf("vextra value should be empty: %#v", result.Vbar.Vextra)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSlice(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
inputStringSlice := map[string]interface{}{
|
||||
"vfoo": "foo",
|
||||
"vbar": []string{"foo", "bar", "baz"},
|
||||
}
|
||||
|
||||
inputStringSlicePointer := map[string]interface{}{
|
||||
"vfoo": "foo",
|
||||
"vbar": &[]string{"foo", "bar", "baz"},
|
||||
}
|
||||
|
||||
outputStringSlice := &Slice{
|
||||
"foo",
|
||||
[]string{"foo", "bar", "baz"},
|
||||
}
|
||||
|
||||
testSliceInput(t, inputStringSlice, outputStringSlice)
|
||||
testSliceInput(t, inputStringSlicePointer, outputStringSlice)
|
||||
}
|
||||
|
||||
func TestInvalidSlice(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vfoo": "foo",
|
||||
"vbar": 42,
|
||||
}
|
||||
|
||||
result := Slice{}
|
||||
err := Decode(input, &result)
|
||||
if err == nil {
|
||||
t.Errorf("expected failure")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceOfStruct(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"value": []map[string]interface{}{
|
||||
{"vstring": "one"},
|
||||
{"vstring": "two"},
|
||||
},
|
||||
}
|
||||
|
||||
var result SliceOfStruct
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got unexpected error: %s", err)
|
||||
}
|
||||
|
||||
if len(result.Value) != 2 {
|
||||
t.Fatalf("expected two values, got %d", len(result.Value))
|
||||
}
|
||||
|
||||
if result.Value[0].Vstring != "one" {
|
||||
t.Errorf("first value should be 'one', got: %s", result.Value[0].Vstring)
|
||||
}
|
||||
|
||||
if result.Value[1].Vstring != "two" {
|
||||
t.Errorf("second value should be 'two', got: %s", result.Value[1].Vstring)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidType(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vstring": 42,
|
||||
}
|
||||
|
||||
var result Basic
|
||||
err := Decode(input, &result)
|
||||
if err == nil {
|
||||
t.Fatal("error should exist")
|
||||
}
|
||||
|
||||
derr, ok := err.(*Error)
|
||||
if !ok {
|
||||
t.Fatalf("error should be kind of Error, instead: %#v", err)
|
||||
}
|
||||
|
||||
if derr.Errors[0] != "'Vstring' expected type 'string', got unconvertible type 'int'" {
|
||||
t.Errorf("got unexpected error: %s", err)
|
||||
}
|
||||
|
||||
inputNegIntUint := map[string]interface{}{
|
||||
"vuint": -42,
|
||||
}
|
||||
|
||||
err = Decode(inputNegIntUint, &result)
|
||||
if err == nil {
|
||||
t.Fatal("error should exist")
|
||||
}
|
||||
|
||||
derr, ok = err.(*Error)
|
||||
if !ok {
|
||||
t.Fatalf("error should be kind of Error, instead: %#v", err)
|
||||
}
|
||||
|
||||
if derr.Errors[0] != "cannot parse 'Vuint', -42 overflows uint" {
|
||||
t.Errorf("got unexpected error: %s", err)
|
||||
}
|
||||
|
||||
inputNegFloatUint := map[string]interface{}{
|
||||
"vuint": -42.0,
|
||||
}
|
||||
|
||||
err = Decode(inputNegFloatUint, &result)
|
||||
if err == nil {
|
||||
t.Fatal("error should exist")
|
||||
}
|
||||
|
||||
derr, ok = err.(*Error)
|
||||
if !ok {
|
||||
t.Fatalf("error should be kind of Error, instead: %#v", err)
|
||||
}
|
||||
|
||||
if derr.Errors[0] != "cannot parse 'Vuint', -42.000000 overflows uint" {
|
||||
t.Errorf("got unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetadata(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vfoo": "foo",
|
||||
"vbar": map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"Vuint": 42,
|
||||
"foo": "bar",
|
||||
},
|
||||
"bar": "nil",
|
||||
}
|
||||
|
||||
var md Metadata
|
||||
var result Nested
|
||||
config := &DecoderConfig{
|
||||
Metadata: &md,
|
||||
Result: &result,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
err = decoder.Decode(input)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err.Error())
|
||||
}
|
||||
|
||||
expectedKeys := []string{"Vbar", "Vbar.Vstring", "Vbar.Vuint", "Vfoo"}
|
||||
sort.Strings(md.Keys)
|
||||
if !reflect.DeepEqual(md.Keys, expectedKeys) {
|
||||
t.Fatalf("bad keys: %#v", md.Keys)
|
||||
}
|
||||
|
||||
expectedUnused := []string{"Vbar.foo", "bar"}
|
||||
if !reflect.DeepEqual(md.Unused, expectedUnused) {
|
||||
t.Fatalf("bad unused: %#v", md.Unused)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetadata_Embedded(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"vstring": "foo",
|
||||
"vunique": "bar",
|
||||
}
|
||||
|
||||
var md Metadata
|
||||
var result EmbeddedSquash
|
||||
config := &DecoderConfig{
|
||||
Metadata: &md,
|
||||
Result: &result,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
err = decoder.Decode(input)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err.Error())
|
||||
}
|
||||
|
||||
expectedKeys := []string{"Vstring", "Vunique"}
|
||||
|
||||
sort.Strings(md.Keys)
|
||||
if !reflect.DeepEqual(md.Keys, expectedKeys) {
|
||||
t.Fatalf("bad keys: %#v", md.Keys)
|
||||
}
|
||||
|
||||
expectedUnused := []string{}
|
||||
if !reflect.DeepEqual(md.Unused, expectedUnused) {
|
||||
t.Fatalf("bad unused: %#v", md.Unused)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNonPtrValue(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
err := Decode(map[string]interface{}{}, Basic{})
|
||||
if err == nil {
|
||||
t.Fatal("error should exist")
|
||||
}
|
||||
|
||||
if err.Error() != "result must be a pointer" {
|
||||
t.Errorf("got unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagged(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"foo": "bar",
|
||||
"bar": "value",
|
||||
}
|
||||
|
||||
var result Tagged
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
if result.Value != "bar" {
|
||||
t.Errorf("value should be 'bar', got: %#v", result.Value)
|
||||
}
|
||||
|
||||
if result.Extra != "value" {
|
||||
t.Errorf("extra should be 'value', got: %#v", result.Extra)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWeakDecode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := map[string]interface{}{
|
||||
"foo": "4",
|
||||
"bar": "value",
|
||||
}
|
||||
|
||||
var result struct {
|
||||
Foo int
|
||||
Bar string
|
||||
}
|
||||
|
||||
if err := WeakDecode(input, &result); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if result.Foo != 4 {
|
||||
t.Fatalf("bad: %#v", result)
|
||||
}
|
||||
if result.Bar != "value" {
|
||||
t.Fatalf("bad: %#v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func testSliceInput(t *testing.T, input map[string]interface{}, expected *Slice) {
|
||||
var result Slice
|
||||
err := Decode(input, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("got error: %s", err)
|
||||
}
|
||||
|
||||
if result.Vfoo != expected.Vfoo {
|
||||
t.Errorf("Vfoo expected '%s', got '%s'", expected.Vfoo, result.Vfoo)
|
||||
}
|
||||
|
||||
if result.Vbar == nil {
|
||||
t.Fatalf("Vbar a slice, got '%#v'", result.Vbar)
|
||||
}
|
||||
|
||||
if len(result.Vbar) != len(expected.Vbar) {
|
||||
t.Errorf("Vbar length should be %d, got %d", len(expected.Vbar), len(result.Vbar))
|
||||
}
|
||||
|
||||
for i, v := range result.Vbar {
|
||||
if v != expected.Vbar[i] {
|
||||
t.Errorf(
|
||||
"Vbar[%d] should be '%#v', got '%#v'",
|
||||
i, expected.Vbar[i], v)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue