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  }