github.com/mailru/activerecord@v1.12.2/pkg/serializer/mapstructure_w_test.go (about) 1 package serializer 2 3 import ( 4 "errors" 5 "reflect" 6 "testing" 7 8 "github.com/mailru/activerecord/pkg/serializer/errs" 9 ) 10 11 type Services struct { 12 Quota uint64 13 Flags map[string]bool 14 Gift *Gift 15 Other map[string]interface{} `mapstructure:",remain"` 16 } 17 18 type Gift struct { 19 GiftInterval string `mapstructure:"gift_interval" json:"gift_interval"` 20 GiftQuota uint64 `mapstructure:"gift_quota" json:"gift_quota"` 21 GiftibleID string `mapstructure:"giftible_id" json:"giftible_id"` 22 } 23 24 func TestMapstructureUnmarshal(t *testing.T) { 25 type args struct { 26 val string 27 } 28 tests := []struct { 29 name string 30 args args 31 exec func(string) (any, error) 32 want any 33 wantErr error 34 }{ 35 { 36 name: "simple", 37 args: args{val: `{"quota": 2373874}`}, 38 exec: func(val string) (any, error) { 39 var got Services 40 err := MapstructureUnmarshal(val, &got) 41 return got, err 42 }, 43 want: Services{Quota: 2373874}, 44 wantErr: nil, 45 }, 46 { 47 name: "with nested map", 48 args: args{val: `{"quota": 234321523, "flags": {"UF": true, "OS": true}}`}, 49 exec: func(val string) (any, error) { 50 var got Services 51 err := MapstructureUnmarshal(val, &got) 52 return got, err 53 }, 54 want: Services{Quota: 234321523, Flags: map[string]bool{"UF": true, "OS": true}}, 55 wantErr: nil, 56 }, 57 { 58 name: "with nested struct", 59 args: args{val: `{"quota": 234321523, "gift": {"giftible_id": "year2020_333_1", "gift_quota": 2343432784}}`}, 60 exec: func(val string) (any, error) { 61 var got Services 62 err := MapstructureUnmarshal(val, &got) 63 return got, err 64 }, 65 want: Services{Quota: 234321523, Gift: &Gift{GiftibleID: "year2020_333_1", GiftQuota: 2343432784}}, 66 wantErr: nil, 67 }, 68 { 69 name: "bad input", 70 args: args{val: `{"quota": 234321523, "gift": }}}}}}}}}}`}, 71 exec: func(val string) (any, error) { 72 var got Services 73 err := MapstructureUnmarshal(val, &got) 74 return got, err 75 }, 76 want: nil, 77 wantErr: errs.ErrUnmarshalJSON, 78 }, 79 { 80 name: "mapstructure remain", 81 args: args{val: `{"quota": 234321523, "unknown_field": "unknown"}`}, 82 exec: func(val string) (any, error) { 83 var got Services 84 err := MapstructureUnmarshal(val, &got) 85 return got, err 86 }, 87 want: Services{Quota: 234321523, Other: map[string]interface{}{"unknown_field": "unknown"}}, 88 wantErr: nil, 89 }, 90 { 91 name: "mapstructure err unused", 92 args: args{val: `{"quota": 234321523, "unused_field": "unused"}`}, 93 exec: func(val string) (any, error) { 94 // Декодируем в структуру без поля c тегом `mapstructure:",remain"` 95 var got struct { 96 Quota uint64 97 } 98 err := MapstructureUnmarshal(val, &got) 99 return got, err 100 }, 101 want: nil, 102 wantErr: errs.ErrMapstructureDecode, 103 }, 104 { 105 name: "mapstructure err create decoder", 106 args: args{val: `{"quota": 2373874}`}, 107 exec: func(val string) (any, error) { 108 var got Services 109 // В mapstructurе вторым параметром надо отдавать pointer 110 err := MapstructureUnmarshal(val, got) 111 return got, err 112 }, 113 want: nil, 114 wantErr: errs.ErrMapstructureNewDecoder, 115 }, 116 } 117 118 for _, tt := range tests { 119 t.Run(tt.name, func(t *testing.T) { 120 got, err := tt.exec(tt.args.val) 121 if tt.wantErr != err && !errors.Is(err, tt.wantErr) { 122 t.Errorf("MapstructureUnmarshal() error = %v, wantErr %v", err, tt.wantErr) 123 } 124 if tt.wantErr == nil && !reflect.DeepEqual(got, tt.want) { 125 t.Errorf("MapstructureUnmarshal() = %v, want %v", got, tt.want) 126 } 127 }) 128 } 129 }