| package mapstructure | 
 |  | 
 | import ( | 
 | 	"encoding/json" | 
 | 	"io" | 
 | 	"reflect" | 
 | 	"sort" | 
 | 	"strings" | 
 | 	"testing" | 
 | ) | 
 |  | 
 | type Basic struct { | 
 | 	Vstring     string | 
 | 	Vint        int | 
 | 	Vuint       uint | 
 | 	Vbool       bool | 
 | 	Vfloat      float64 | 
 | 	Vextra      string | 
 | 	vsilent     bool | 
 | 	Vdata       interface{} | 
 | 	VjsonInt    int | 
 | 	VjsonFloat  float64 | 
 | 	VjsonNumber json.Number | 
 | } | 
 |  | 
 | type BasicSquash struct { | 
 | 	Test Basic `mapstructure:",squash"` | 
 | } | 
 |  | 
 | type Embedded struct { | 
 | 	Basic | 
 | 	Vunique string | 
 | } | 
 |  | 
 | type EmbeddedPointer struct { | 
 | 	*Basic | 
 | 	Vunique string | 
 | } | 
 |  | 
 | type EmbeddedSquash struct { | 
 | 	Basic   `mapstructure:",squash"` | 
 | 	Vunique string | 
 | } | 
 |  | 
 | type SliceAlias []string | 
 |  | 
 | type EmbeddedSlice struct { | 
 | 	SliceAlias `mapstructure:"slice_alias"` | 
 | 	Vunique    string | 
 | } | 
 |  | 
 | type SquashOnNonStructType struct { | 
 | 	InvalidSquashType int `mapstructure:",squash"` | 
 | } | 
 |  | 
 | 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 NilInterface struct { | 
 | 	W io.Writer | 
 | } | 
 |  | 
 | type Slice struct { | 
 | 	Vfoo string | 
 | 	Vbar []string | 
 | } | 
 |  | 
 | type SliceOfStruct struct { | 
 | 	Value []Basic | 
 | } | 
 |  | 
 | type Func struct { | 
 | 	Foo func() string | 
 | } | 
 |  | 
 | 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, | 
 | 		"vjsonInt":    json.Number("1234"), | 
 | 		"vjsonFloat":  json.Number("1234.5"), | 
 | 		"vjsonNumber": json.Number("1234.5"), | 
 | 	} | 
 |  | 
 | 	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") | 
 | 	} | 
 |  | 
 | 	if result.VjsonInt != 1234 { | 
 | 		t.Errorf("vjsonint value should be 1234: %#v", result.VjsonInt) | 
 | 	} | 
 |  | 
 | 	if result.VjsonFloat != 1234.5 { | 
 | 		t.Errorf("vjsonfloat value should be 1234.5: %#v", result.VjsonFloat) | 
 | 	} | 
 |  | 
 | 	if !reflect.DeepEqual(result.VjsonNumber, json.Number("1234.5")) { | 
 | 		t.Errorf("vjsonnumber value should be '1234.5': %T, %#v", result.VjsonNumber, result.VjsonNumber) | 
 | 	} | 
 | } | 
 |  | 
 | 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 TestBasic_Merge(t *testing.T) { | 
 | 	t.Parallel() | 
 |  | 
 | 	input := map[string]interface{}{ | 
 | 		"vint": 42, | 
 | 	} | 
 |  | 
 | 	var result Basic | 
 | 	result.Vuint = 100 | 
 | 	err := Decode(input, &result) | 
 | 	if err != nil { | 
 | 		t.Fatalf("got an err: %s", err) | 
 | 	} | 
 |  | 
 | 	expected := Basic{ | 
 | 		Vint:  42, | 
 | 		Vuint: 100, | 
 | 	} | 
 | 	if !reflect.DeepEqual(result, expected) { | 
 | 		t.Fatalf("bad: %#v", result) | 
 | 	} | 
 | } | 
 |  | 
 | func TestDecode_BasicSquash(t *testing.T) { | 
 | 	t.Parallel() | 
 |  | 
 | 	input := map[string]interface{}{ | 
 | 		"vstring": "foo", | 
 | 	} | 
 |  | 
 | 	var result BasicSquash | 
 | 	err := Decode(input, &result) | 
 | 	if err != nil { | 
 | 		t.Fatalf("got an err: %s", err.Error()) | 
 | 	} | 
 |  | 
 | 	if result.Test.Vstring != "foo" { | 
 | 		t.Errorf("vstring value should be 'foo': %#v", result.Test.Vstring) | 
 | 	} | 
 | } | 
 |  | 
 | 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.Fatalf("err: %s", err) | 
 | 	} | 
 |  | 
 | 	expected := EmbeddedPointer{ | 
 | 		Basic: &Basic{ | 
 | 			Vstring: "innerfoo", | 
 | 		}, | 
 | 		Vunique: "bar", | 
 | 	} | 
 | 	if !reflect.DeepEqual(result, expected) { | 
 | 		t.Fatalf("bad: %#v", result) | 
 | 	} | 
 | } | 
 |  | 
 | func TestDecode_EmbeddedSlice(t *testing.T) { | 
 | 	t.Parallel() | 
 |  | 
 | 	input := map[string]interface{}{ | 
 | 		"slice_alias": []string{"foo", "bar"}, | 
 | 		"vunique":     "bar", | 
 | 	} | 
 |  | 
 | 	var result EmbeddedSlice | 
 | 	err := Decode(input, &result) | 
 | 	if err != nil { | 
 | 		t.Fatalf("got an err: %s", err.Error()) | 
 | 	} | 
 |  | 
 | 	if !reflect.DeepEqual(result.SliceAlias, SliceAlias([]string{"foo", "bar"})) { | 
 | 		t.Errorf("slice value: %#v", result.SliceAlias) | 
 | 	} | 
 |  | 
 | 	if result.Vunique != "bar" { | 
 | 		t.Errorf("vunique value should be 'bar': %#v", result.Vunique) | 
 | 	} | 
 | } | 
 |  | 
 | 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_SquashOnNonStructType(t *testing.T) { | 
 | 	t.Parallel() | 
 |  | 
 | 	input := map[string]interface{}{ | 
 | 		"InvalidSquashType": 42, | 
 | 	} | 
 |  | 
 | 	var result SquashOnNonStructType | 
 | 	err := Decode(input, &result) | 
 | 	if err == nil { | 
 | 		t.Fatal("unexpected success decoding invalid squash field type") | 
 | 	} else if !strings.Contains(err.Error(), "unsupported type for squash") { | 
 | 		t.Fatalf("unexpected error message for invalid squash field type: %s", err) | 
 | 	} | 
 | } | 
 |  | 
 | 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_NilInterfaceHook(t *testing.T) { | 
 | 	t.Parallel() | 
 |  | 
 | 	input := map[string]interface{}{ | 
 | 		"w": "", | 
 | 	} | 
 |  | 
 | 	decodeHook := func(f, t reflect.Type, v interface{}) (interface{}, error) { | 
 | 		if t.String() == "io.Writer" { | 
 | 			return nil, nil | 
 | 		} | 
 |  | 
 | 		return v, nil | 
 | 	} | 
 |  | 
 | 	var result NilInterface | 
 | 	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.W != nil { | 
 | 		t.Errorf("W should be nil: %#v", result.W) | 
 | 	} | 
 | } | 
 |  | 
 | func TestDecode_FuncHook(t *testing.T) { | 
 | 	t.Parallel() | 
 |  | 
 | 	input := map[string]interface{}{ | 
 | 		"foo": "baz", | 
 | 	} | 
 |  | 
 | 	decodeHook := func(f, t reflect.Type, v interface{}) (interface{}, error) { | 
 | 		if t.Kind() != reflect.Func { | 
 | 			return v, nil | 
 | 		} | 
 | 		val := v.(string) | 
 | 		return func() string { return val }, nil | 
 | 	} | 
 |  | 
 | 	var result Func | 
 | 	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.Foo() != "baz" { | 
 | 		t.Errorf("Foo call result should be 'baz': %s", result.Foo()) | 
 | 	} | 
 | } | 
 |  | 
 | 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 TestSliceToMap(t *testing.T) { | 
 | 	t.Parallel() | 
 |  | 
 | 	input := []map[string]interface{}{ | 
 | 		{ | 
 | 			"foo": "bar", | 
 | 		}, | 
 | 		{ | 
 | 			"bar": "baz", | 
 | 		}, | 
 | 	} | 
 |  | 
 | 	var result map[string]interface{} | 
 | 	err := WeakDecode(input, &result) | 
 | 	if err != nil { | 
 | 		t.Fatalf("got an error: %s", err) | 
 | 	} | 
 |  | 
 | 	expected := map[string]interface{}{ | 
 | 		"foo": "bar", | 
 | 		"bar": "baz", | 
 | 	} | 
 | 	if !reflect.DeepEqual(result, expected) { | 
 | 		t.Errorf("bad: %#v", result) | 
 | 	} | 
 | } | 
 |  | 
 | 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) | 
 | 		} | 
 | 	} | 
 | } |