|  | 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) | 
|  | } | 
|  | } | 
|  |  | 
|  | // #48 | 
|  | func TestNestedTypePointerWithDefaults(t *testing.T) { | 
|  | t.Parallel() | 
|  |  | 
|  | input := map[string]interface{}{ | 
|  | "vfoo": "foo", | 
|  | "vbar": map[string]interface{}{ | 
|  | "vstring": "foo", | 
|  | "vint":    42, | 
|  | "vbool":   true, | 
|  | }, | 
|  | } | 
|  |  | 
|  | result := NestedPointer{ | 
|  | Vbar: &Basic{ | 
|  | Vuint: 42, | 
|  | }, | 
|  | } | 
|  | 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) | 
|  | } | 
|  |  | 
|  | // this is the error | 
|  | if result.Vbar.Vuint != 42 { | 
|  | t.Errorf("vuint value should be 42: %#v", result.Vbar.Vuint) | 
|  | } | 
|  |  | 
|  | } | 
|  |  | 
|  | type NestedSlice struct { | 
|  | Vfoo   string | 
|  | Vbars  []Basic | 
|  | Vempty []Basic | 
|  | } | 
|  |  | 
|  | // #48 | 
|  | func TestNestedTypeSliceWithDefaults(t *testing.T) { | 
|  | t.Parallel() | 
|  |  | 
|  | input := map[string]interface{}{ | 
|  | "vfoo": "foo", | 
|  | "vbars": []map[string]interface{}{ | 
|  | {"vstring": "foo", "vint": 42, "vbool": true}, | 
|  | {"vint": 42, "vbool": true}, | 
|  | }, | 
|  | "vempty": []map[string]interface{}{ | 
|  | {"vstring": "foo", "vint": 42, "vbool": true}, | 
|  | {"vint": 42, "vbool": true}, | 
|  | }, | 
|  | } | 
|  |  | 
|  | result := NestedSlice{ | 
|  | Vbars: []Basic{ | 
|  | {Vuint: 42}, | 
|  | {Vstring: "foo"}, | 
|  | }, | 
|  | } | 
|  | 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.Vbars[0].Vstring != "foo" { | 
|  | t.Errorf("vstring value should be 'foo': %#v", result.Vbars[0].Vstring) | 
|  | } | 
|  | // this is the error | 
|  | if result.Vbars[0].Vuint != 42 { | 
|  | t.Errorf("vuint value should be 42: %#v", result.Vbars[0].Vuint) | 
|  | } | 
|  | } | 
|  |  | 
|  | // #48 workaround | 
|  | func TestNestedTypeWithDefaults(t *testing.T) { | 
|  | t.Parallel() | 
|  |  | 
|  | input := map[string]interface{}{ | 
|  | "vfoo": "foo", | 
|  | "vbar": map[string]interface{}{ | 
|  | "vstring": "foo", | 
|  | "vint":    42, | 
|  | "vbool":   true, | 
|  | }, | 
|  | } | 
|  |  | 
|  | result := Nested{ | 
|  | Vbar: Basic{ | 
|  | Vuint: 42, | 
|  | }, | 
|  | } | 
|  | 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) | 
|  | } | 
|  |  | 
|  | // this is the error | 
|  | if result.Vbar.Vuint != 42 { | 
|  | t.Errorf("vuint value should be 42: %#v", result.Vbar.Vuint) | 
|  | } | 
|  |  | 
|  | } | 
|  |  | 
|  | // #67 panic() on extending slices (decodeSlice with disabled ZeroValues) | 
|  | func TestDecodeSliceToEmptySliceWOZeroing(t *testing.T) { | 
|  | t.Parallel() | 
|  |  | 
|  | type TestStruct struct { | 
|  | Vfoo []string | 
|  | } | 
|  |  | 
|  | decode := func(m interface{}, rawVal interface{}) error { | 
|  | config := &DecoderConfig{ | 
|  | Metadata:   nil, | 
|  | Result:     rawVal, | 
|  | ZeroFields: false, | 
|  | } | 
|  |  | 
|  | decoder, err := NewDecoder(config) | 
|  | if err != nil { | 
|  | return err | 
|  | } | 
|  |  | 
|  | return decoder.Decode(m) | 
|  | } | 
|  |  | 
|  | { | 
|  | input := map[string]interface{}{ | 
|  | "vfoo": []string{"1"}, | 
|  | } | 
|  |  | 
|  | result := &TestStruct{} | 
|  |  | 
|  | err := decode(input, &result) | 
|  | if err != nil { | 
|  | t.Fatalf("got an err: %s", err.Error()) | 
|  | } | 
|  | } | 
|  |  | 
|  | { | 
|  | input := map[string]interface{}{ | 
|  | "vfoo": []string{"1"}, | 
|  | } | 
|  |  | 
|  | result := &TestStruct{ | 
|  | Vfoo: []string{}, | 
|  | } | 
|  |  | 
|  | err := decode(input, &result) | 
|  | if err != nil { | 
|  | t.Fatalf("got an err: %s", err.Error()) | 
|  | } | 
|  | } | 
|  |  | 
|  | { | 
|  | input := map[string]interface{}{ | 
|  | "vfoo": []string{"2", "3"}, | 
|  | } | 
|  |  | 
|  | result := &TestStruct{ | 
|  | Vfoo: []string{"1"}, | 
|  | } | 
|  |  | 
|  | err := decode(input, &result) | 
|  | if err != nil { | 
|  | t.Fatalf("got an err: %s", err.Error()) | 
|  | } | 
|  | } | 
|  | } |