github.com/aavshr/aws-sdk-go@v1.41.3/service/dynamodb/dynamodbattribute/empty_collections_test.go (about)

     1  package dynamodbattribute
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/aavshr/aws-sdk-go/aws"
     8  	"github.com/aavshr/aws-sdk-go/service/dynamodb"
     9  )
    10  
    11  type testEmptyCollectionsNumericalScalars struct {
    12  	String string
    13  
    14  	Uint8  uint8
    15  	Uint16 uint16
    16  	Uint32 uint32
    17  	Uint64 uint64
    18  
    19  	Int8  int8
    20  	Int16 int16
    21  	Int32 int32
    22  	Int64 int64
    23  
    24  	Float32 float32
    25  	Float64 float64
    26  }
    27  
    28  type testEmptyCollectionsOmittedNumericalScalars struct {
    29  	String string `dynamodbav:",omitempty"`
    30  
    31  	Uint8  uint8  `dynamodbav:",omitempty"`
    32  	Uint16 uint16 `dynamodbav:",omitempty"`
    33  	Uint32 uint32 `dynamodbav:",omitempty"`
    34  	Uint64 uint64 `dynamodbav:",omitempty"`
    35  
    36  	Int8  int8  `dynamodbav:",omitempty"`
    37  	Int16 int16 `dynamodbav:",omitempty"`
    38  	Int32 int32 `dynamodbav:",omitempty"`
    39  	Int64 int64 `dynamodbav:",omitempty"`
    40  
    41  	Float32 float32 `dynamodbav:",omitempty"`
    42  	Float64 float64 `dynamodbav:",omitempty"`
    43  }
    44  
    45  type testEmptyCollectionsPtrScalars struct {
    46  	PtrString *string
    47  
    48  	PtrUint8  *uint8
    49  	PtrUint16 *uint16
    50  	PtrUint32 *uint32
    51  	PtrUint64 *uint64
    52  
    53  	PtrInt8  *int8
    54  	PtrInt16 *int16
    55  	PtrInt32 *int32
    56  	PtrInt64 *int64
    57  
    58  	PtrFloat32 *float32
    59  	PtrFloat64 *float64
    60  }
    61  
    62  type testEmptyCollectionsOmittedPtrNumericalScalars struct {
    63  	PtrUint8  *uint8  `dynamodbav:",omitempty"`
    64  	PtrUint16 *uint16 `dynamodbav:",omitempty"`
    65  	PtrUint32 *uint32 `dynamodbav:",omitempty"`
    66  	PtrUint64 *uint64 `dynamodbav:",omitempty"`
    67  
    68  	PtrInt8  *int8  `dynamodbav:",omitempty"`
    69  	PtrInt16 *int16 `dynamodbav:",omitempty"`
    70  	PtrInt32 *int32 `dynamodbav:",omitempty"`
    71  	PtrInt64 *int64 `dynamodbav:",omitempty"`
    72  
    73  	PtrFloat32 *float32 `dynamodbav:",omitempty"`
    74  	PtrFloat64 *float64 `dynamodbav:",omitempty"`
    75  }
    76  
    77  type testEmptyCollectionTypes struct {
    78  	Map       map[string]string
    79  	Slice     []string
    80  	ByteSlice []byte
    81  	ByteArray [4]byte
    82  	ZeroArray [0]byte
    83  	BinarySet [][]byte `dynamodbav:",binaryset"`
    84  	NumberSet []int    `dynamodbav:",numberset"`
    85  	StringSet []string `dynamodbav:",stringset"`
    86  }
    87  
    88  type testEmptyCollectionTypesOmitted struct {
    89  	Map       map[string]string `dynamodbav:",omitempty"`
    90  	Slice     []string          `dynamodbav:",omitempty"`
    91  	ByteSlice []byte            `dynamodbav:",omitempty"`
    92  	ByteArray [4]byte           `dynamodbav:",omitempty"`
    93  	ZeroArray [0]byte           `dynamodbav:",omitempty"`
    94  	BinarySet [][]byte          `dynamodbav:",binaryset,omitempty"`
    95  	NumberSet []int             `dynamodbav:",numberset,omitempty"`
    96  	StringSet []string          `dynamodbav:",stringset,omitempty"`
    97  }
    98  
    99  type testEmptyCollectionStruct struct {
   100  	Int int
   101  }
   102  
   103  type testEmptyCollectionStructOmitted struct {
   104  	Slice []string `dynamodbav:",omitempty"`
   105  }
   106  
   107  var sharedEmptyCollectionsTestCases = []struct {
   108  	encoderOpts      func(encoder *Encoder)
   109  	in               *dynamodb.AttributeValue
   110  	actual, expected interface{}
   111  	err              error
   112  }{
   113  	// scalars with zero value
   114  	0: {
   115  		in: &dynamodb.AttributeValue{
   116  			M: map[string]*dynamodb.AttributeValue{
   117  				"String":  {NULL: aws.Bool(true)},
   118  				"Uint8":   {N: aws.String("0")},
   119  				"Uint16":  {N: aws.String("0")},
   120  				"Uint32":  {N: aws.String("0")},
   121  				"Uint64":  {N: aws.String("0")},
   122  				"Int8":    {N: aws.String("0")},
   123  				"Int16":   {N: aws.String("0")},
   124  				"Int32":   {N: aws.String("0")},
   125  				"Int64":   {N: aws.String("0")},
   126  				"Float32": {N: aws.String("0")},
   127  				"Float64": {N: aws.String("0")},
   128  			},
   129  		},
   130  		actual:   &testEmptyCollectionsNumericalScalars{},
   131  		expected: testEmptyCollectionsNumericalScalars{},
   132  	},
   133  	// scalars with non-zero values
   134  	1: {
   135  		in: &dynamodb.AttributeValue{
   136  			M: map[string]*dynamodb.AttributeValue{
   137  				"String":  {S: aws.String("test string")},
   138  				"Uint8":   {N: aws.String("1")},
   139  				"Uint16":  {N: aws.String("2")},
   140  				"Uint32":  {N: aws.String("3")},
   141  				"Uint64":  {N: aws.String("4")},
   142  				"Int8":    {N: aws.String("-5")},
   143  				"Int16":   {N: aws.String("-6")},
   144  				"Int32":   {N: aws.String("-7")},
   145  				"Int64":   {N: aws.String("-8")},
   146  				"Float32": {N: aws.String("9.9")},
   147  				"Float64": {N: aws.String("10.1")},
   148  			},
   149  		},
   150  		actual: &testEmptyCollectionsNumericalScalars{},
   151  		expected: testEmptyCollectionsNumericalScalars{
   152  			String:  "test string",
   153  			Uint8:   1,
   154  			Uint16:  2,
   155  			Uint32:  3,
   156  			Uint64:  4,
   157  			Int8:    -5,
   158  			Int16:   -6,
   159  			Int32:   -7,
   160  			Int64:   -8,
   161  			Float32: 9.9,
   162  			Float64: 10.1,
   163  		},
   164  	},
   165  	// omittable scalars with zero value
   166  	2: {
   167  		in:       &dynamodb.AttributeValue{M: map[string]*dynamodb.AttributeValue{}},
   168  		actual:   &testEmptyCollectionsOmittedNumericalScalars{},
   169  		expected: testEmptyCollectionsOmittedNumericalScalars{},
   170  	},
   171  	// omittable scalars with non-zero value
   172  	3: {
   173  		in: &dynamodb.AttributeValue{
   174  			M: map[string]*dynamodb.AttributeValue{
   175  				"String":  {S: aws.String("test string")},
   176  				"Uint8":   {N: aws.String("1")},
   177  				"Uint16":  {N: aws.String("2")},
   178  				"Uint32":  {N: aws.String("3")},
   179  				"Uint64":  {N: aws.String("4")},
   180  				"Int8":    {N: aws.String("-5")},
   181  				"Int16":   {N: aws.String("-6")},
   182  				"Int32":   {N: aws.String("-7")},
   183  				"Int64":   {N: aws.String("-8")},
   184  				"Float32": {N: aws.String("9.9")},
   185  				"Float64": {N: aws.String("10.1")},
   186  			},
   187  		},
   188  		actual: &testEmptyCollectionsOmittedNumericalScalars{},
   189  		expected: testEmptyCollectionsOmittedNumericalScalars{
   190  			String:  "test string",
   191  			Uint8:   1,
   192  			Uint16:  2,
   193  			Uint32:  3,
   194  			Uint64:  4,
   195  			Int8:    -5,
   196  			Int16:   -6,
   197  			Int32:   -7,
   198  			Int64:   -8,
   199  			Float32: 9.9,
   200  			Float64: 10.1,
   201  		},
   202  	},
   203  	// nil pointer scalars
   204  	4: {
   205  		in: &dynamodb.AttributeValue{
   206  			M: map[string]*dynamodb.AttributeValue{
   207  				"PtrString":  {NULL: aws.Bool(true)},
   208  				"PtrUint8":   {NULL: aws.Bool(true)},
   209  				"PtrUint16":  {NULL: aws.Bool(true)},
   210  				"PtrUint32":  {NULL: aws.Bool(true)},
   211  				"PtrUint64":  {NULL: aws.Bool(true)},
   212  				"PtrInt8":    {NULL: aws.Bool(true)},
   213  				"PtrInt16":   {NULL: aws.Bool(true)},
   214  				"PtrInt32":   {NULL: aws.Bool(true)},
   215  				"PtrInt64":   {NULL: aws.Bool(true)},
   216  				"PtrFloat32": {NULL: aws.Bool(true)},
   217  				"PtrFloat64": {NULL: aws.Bool(true)},
   218  			},
   219  		},
   220  		actual:   &testEmptyCollectionsPtrScalars{},
   221  		expected: testEmptyCollectionsPtrScalars{},
   222  	},
   223  	// non-nil pointer to scalars with zero value
   224  	5: {
   225  		in: &dynamodb.AttributeValue{
   226  			M: map[string]*dynamodb.AttributeValue{
   227  				"PtrString":  {NULL: aws.Bool(true)},
   228  				"PtrUint8":   {N: aws.String("0")},
   229  				"PtrUint16":  {N: aws.String("0")},
   230  				"PtrUint32":  {N: aws.String("0")},
   231  				"PtrUint64":  {N: aws.String("0")},
   232  				"PtrInt8":    {N: aws.String("0")},
   233  				"PtrInt16":   {N: aws.String("0")},
   234  				"PtrInt32":   {N: aws.String("0")},
   235  				"PtrInt64":   {N: aws.String("0")},
   236  				"PtrFloat32": {N: aws.String("0")},
   237  				"PtrFloat64": {N: aws.String("0")},
   238  			},
   239  		},
   240  		actual: &testEmptyCollectionsPtrScalars{},
   241  		expected: testEmptyCollectionsPtrScalars{
   242  			PtrUint8:   aws.Uint8(0),
   243  			PtrUint16:  aws.Uint16(0),
   244  			PtrUint32:  aws.Uint32(0),
   245  			PtrUint64:  aws.Uint64(0),
   246  			PtrInt8:    aws.Int8(0),
   247  			PtrInt16:   aws.Int16(0),
   248  			PtrInt32:   aws.Int32(0),
   249  			PtrInt64:   aws.Int64(0),
   250  			PtrFloat32: aws.Float32(0),
   251  			PtrFloat64: aws.Float64(0),
   252  		},
   253  	},
   254  	// pointer scalars non-nil non-zero
   255  	6: {
   256  		in: &dynamodb.AttributeValue{
   257  			M: map[string]*dynamodb.AttributeValue{
   258  				"PtrString":  {S: aws.String("test string")},
   259  				"PtrUint8":   {N: aws.String("1")},
   260  				"PtrUint16":  {N: aws.String("2")},
   261  				"PtrUint32":  {N: aws.String("3")},
   262  				"PtrUint64":  {N: aws.String("4")},
   263  				"PtrInt8":    {N: aws.String("-5")},
   264  				"PtrInt16":   {N: aws.String("-6")},
   265  				"PtrInt32":   {N: aws.String("-7")},
   266  				"PtrInt64":   {N: aws.String("-8")},
   267  				"PtrFloat32": {N: aws.String("9.9")},
   268  				"PtrFloat64": {N: aws.String("10.1")},
   269  			},
   270  		},
   271  		actual: &testEmptyCollectionsPtrScalars{},
   272  		expected: testEmptyCollectionsPtrScalars{
   273  			PtrString:  aws.String("test string"),
   274  			PtrUint8:   aws.Uint8(1),
   275  			PtrUint16:  aws.Uint16(2),
   276  			PtrUint32:  aws.Uint32(3),
   277  			PtrUint64:  aws.Uint64(4),
   278  			PtrInt8:    aws.Int8(-5),
   279  			PtrInt16:   aws.Int16(-6),
   280  			PtrInt32:   aws.Int32(-7),
   281  			PtrInt64:   aws.Int64(-8),
   282  			PtrFloat32: aws.Float32(9.9),
   283  			PtrFloat64: aws.Float64(10.1),
   284  		},
   285  	},
   286  	// omittable nil pointer scalars
   287  	7: {
   288  		in: &dynamodb.AttributeValue{
   289  			M: map[string]*dynamodb.AttributeValue{},
   290  		},
   291  		actual:   &testEmptyCollectionsOmittedPtrNumericalScalars{},
   292  		expected: testEmptyCollectionsOmittedPtrNumericalScalars{},
   293  	},
   294  	// omittable non-nil pointer to scalars with zero value
   295  	8: {
   296  		in: &dynamodb.AttributeValue{
   297  			M: map[string]*dynamodb.AttributeValue{
   298  				"PtrUint8":   {N: aws.String("0")},
   299  				"PtrUint16":  {N: aws.String("0")},
   300  				"PtrUint32":  {N: aws.String("0")},
   301  				"PtrUint64":  {N: aws.String("0")},
   302  				"PtrInt8":    {N: aws.String("0")},
   303  				"PtrInt16":   {N: aws.String("0")},
   304  				"PtrInt32":   {N: aws.String("0")},
   305  				"PtrInt64":   {N: aws.String("0")},
   306  				"PtrFloat32": {N: aws.String("0")},
   307  				"PtrFloat64": {N: aws.String("0")},
   308  			},
   309  		},
   310  		actual: &testEmptyCollectionsOmittedPtrNumericalScalars{},
   311  		expected: testEmptyCollectionsOmittedPtrNumericalScalars{
   312  			PtrUint8:   aws.Uint8(0),
   313  			PtrUint16:  aws.Uint16(0),
   314  			PtrUint32:  aws.Uint32(0),
   315  			PtrUint64:  aws.Uint64(0),
   316  			PtrInt8:    aws.Int8(0),
   317  			PtrInt16:   aws.Int16(0),
   318  			PtrInt32:   aws.Int32(0),
   319  			PtrInt64:   aws.Int64(0),
   320  			PtrFloat32: aws.Float32(0),
   321  			PtrFloat64: aws.Float64(0),
   322  		},
   323  	},
   324  	// omittable non-nil pointer to non-zero scalar
   325  	9: {
   326  		in: &dynamodb.AttributeValue{
   327  			M: map[string]*dynamodb.AttributeValue{
   328  				"PtrUint8":   {N: aws.String("1")},
   329  				"PtrUint16":  {N: aws.String("2")},
   330  				"PtrUint32":  {N: aws.String("3")},
   331  				"PtrUint64":  {N: aws.String("4")},
   332  				"PtrInt8":    {N: aws.String("-5")},
   333  				"PtrInt16":   {N: aws.String("-6")},
   334  				"PtrInt32":   {N: aws.String("-7")},
   335  				"PtrInt64":   {N: aws.String("-8")},
   336  				"PtrFloat32": {N: aws.String("9.9")},
   337  				"PtrFloat64": {N: aws.String("10.1")},
   338  			},
   339  		},
   340  		actual: &testEmptyCollectionsOmittedPtrNumericalScalars{},
   341  		expected: testEmptyCollectionsOmittedPtrNumericalScalars{
   342  			PtrUint8:   aws.Uint8(1),
   343  			PtrUint16:  aws.Uint16(2),
   344  			PtrUint32:  aws.Uint32(3),
   345  			PtrUint64:  aws.Uint64(4),
   346  			PtrInt8:    aws.Int8(-5),
   347  			PtrInt16:   aws.Int16(-6),
   348  			PtrInt32:   aws.Int32(-7),
   349  			PtrInt64:   aws.Int64(-8),
   350  			PtrFloat32: aws.Float32(9.9),
   351  			PtrFloat64: aws.Float64(10.1),
   352  		},
   353  	},
   354  	// maps, slices nil values
   355  	10: {
   356  		in: &dynamodb.AttributeValue{
   357  			M: map[string]*dynamodb.AttributeValue{
   358  				"Map":       {NULL: aws.Bool(true)},
   359  				"Slice":     {NULL: aws.Bool(true)},
   360  				"ByteSlice": {NULL: aws.Bool(true)},
   361  				"ByteArray": {B: make([]byte, 4)},
   362  				"ZeroArray": {B: make([]byte, 0)},
   363  				"BinarySet": {NULL: aws.Bool(true)},
   364  				"NumberSet": {NULL: aws.Bool(true)},
   365  				"StringSet": {NULL: aws.Bool(true)},
   366  			},
   367  		},
   368  		actual:   &testEmptyCollectionTypes{},
   369  		expected: testEmptyCollectionTypes{},
   370  	},
   371  	// maps, slices zero values
   372  	11: {
   373  		in: &dynamodb.AttributeValue{
   374  			M: map[string]*dynamodb.AttributeValue{
   375  				"Map":       {M: map[string]*dynamodb.AttributeValue{}},
   376  				"Slice":     {L: []*dynamodb.AttributeValue{}},
   377  				"ByteSlice": {B: []byte{}},
   378  				"ByteArray": {B: make([]byte, 4)},
   379  				"ZeroArray": {B: make([]byte, 0)},
   380  				"BinarySet": {BS: [][]byte{}},
   381  				"NumberSet": {NS: []*string{}},
   382  				"StringSet": {SS: []*string{}},
   383  			},
   384  		},
   385  		actual: &testEmptyCollectionTypes{},
   386  		expected: testEmptyCollectionTypes{
   387  			Map:       map[string]string{},
   388  			Slice:     []string{},
   389  			ByteSlice: []byte{},
   390  			ByteArray: [4]byte{},
   391  			ZeroArray: [0]byte{},
   392  			BinarySet: [][]byte{},
   393  			NumberSet: []int{},
   394  			StringSet: []string{},
   395  		},
   396  	},
   397  	// maps, slices non-zero values
   398  	12: {
   399  		in: &dynamodb.AttributeValue{
   400  			M: map[string]*dynamodb.AttributeValue{
   401  				"Map": {
   402  					M: map[string]*dynamodb.AttributeValue{
   403  						"key": {S: aws.String("value")},
   404  					},
   405  				},
   406  				"Slice":     {L: []*dynamodb.AttributeValue{{S: aws.String("test")}, {S: aws.String("slice")}}},
   407  				"ByteSlice": {B: []byte{0, 1}},
   408  				"ByteArray": {B: []byte{0, 1, 2, 3}},
   409  				"ZeroArray": {B: make([]byte, 0)},
   410  				"BinarySet": {BS: [][]byte{{0, 1}, {2, 3}}},
   411  				"NumberSet": {NS: []*string{aws.String("0"), aws.String("1")}},
   412  				"StringSet": {SS: []*string{aws.String("test"), aws.String("slice")}},
   413  			},
   414  		},
   415  		actual: &testEmptyCollectionTypes{},
   416  		expected: testEmptyCollectionTypes{
   417  			Map:       map[string]string{"key": "value"},
   418  			Slice:     []string{"test", "slice"},
   419  			ByteSlice: []byte{0, 1},
   420  			ByteArray: [4]byte{0, 1, 2, 3},
   421  			ZeroArray: [0]byte{},
   422  			BinarySet: [][]byte{{0, 1}, {2, 3}},
   423  			NumberSet: []int{0, 1},
   424  			StringSet: []string{"test", "slice"},
   425  		},
   426  	},
   427  	// omittable maps, slices nil values
   428  	13: {
   429  		in: &dynamodb.AttributeValue{
   430  			M: map[string]*dynamodb.AttributeValue{
   431  				"ByteArray": {B: make([]byte, 4)},
   432  			},
   433  		},
   434  		actual:   &testEmptyCollectionTypesOmitted{},
   435  		expected: testEmptyCollectionTypesOmitted{},
   436  	},
   437  	// omittable maps, slices zero values
   438  	14: {
   439  		in: &dynamodb.AttributeValue{
   440  			M: map[string]*dynamodb.AttributeValue{
   441  				"Map":       {M: map[string]*dynamodb.AttributeValue{}},
   442  				"Slice":     {L: []*dynamodb.AttributeValue{}},
   443  				"ByteSlice": {B: []byte{}},
   444  				"ByteArray": {B: make([]byte, 4)},
   445  				"BinarySet": {BS: [][]byte{}},
   446  				"NumberSet": {NS: []*string{}},
   447  				"StringSet": {SS: []*string{}},
   448  			},
   449  		},
   450  		actual: &testEmptyCollectionTypesOmitted{},
   451  		expected: testEmptyCollectionTypesOmitted{
   452  			Map:       map[string]string{},
   453  			Slice:     []string{},
   454  			ByteSlice: []byte{},
   455  			ByteArray: [4]byte{},
   456  			BinarySet: [][]byte{},
   457  			NumberSet: []int{},
   458  			StringSet: []string{},
   459  		},
   460  	},
   461  	// omittable maps, slices non-zero values
   462  	15: {
   463  		in: &dynamodb.AttributeValue{
   464  			M: map[string]*dynamodb.AttributeValue{
   465  				"Map": {
   466  					M: map[string]*dynamodb.AttributeValue{
   467  						"key": {S: aws.String("value")},
   468  					},
   469  				},
   470  				"Slice":     {L: []*dynamodb.AttributeValue{{S: aws.String("test")}, {S: aws.String("slice")}}},
   471  				"ByteSlice": {B: []byte{0, 1}},
   472  				"ByteArray": {B: []byte{0, 1, 2, 3}},
   473  				"BinarySet": {BS: [][]byte{{0, 1}, {2, 3}}},
   474  				"NumberSet": {NS: []*string{aws.String("0"), aws.String("1")}},
   475  				"StringSet": {SS: []*string{aws.String("test"), aws.String("slice")}},
   476  			},
   477  		},
   478  		actual: &testEmptyCollectionTypesOmitted{},
   479  		expected: testEmptyCollectionTypesOmitted{
   480  			Map:       map[string]string{"key": "value"},
   481  			Slice:     []string{"test", "slice"},
   482  			ByteSlice: []byte{0, 1},
   483  			ByteArray: [4]byte{0, 1, 2, 3},
   484  			ZeroArray: [0]byte{},
   485  			BinarySet: [][]byte{{0, 1}, {2, 3}},
   486  			NumberSet: []int{0, 1},
   487  			StringSet: []string{"test", "slice"},
   488  		},
   489  	},
   490  	// structs with members zero
   491  	16: {
   492  		in: &dynamodb.AttributeValue{
   493  			M: map[string]*dynamodb.AttributeValue{
   494  				"Struct": {
   495  					M: map[string]*dynamodb.AttributeValue{
   496  						"Int": {N: aws.String("0")},
   497  					},
   498  				},
   499  				"PtrStruct": {NULL: aws.Bool(true)},
   500  			},
   501  		},
   502  		actual: &struct {
   503  			Struct    testEmptyCollectionStruct
   504  			PtrStruct *testEmptyCollectionStruct
   505  		}{},
   506  		expected: struct {
   507  			Struct    testEmptyCollectionStruct
   508  			PtrStruct *testEmptyCollectionStruct
   509  		}{},
   510  	},
   511  	// structs with members non-zero value
   512  	17: {
   513  		in: &dynamodb.AttributeValue{
   514  			M: map[string]*dynamodb.AttributeValue{
   515  				"Struct": {
   516  					M: map[string]*dynamodb.AttributeValue{
   517  						"Int": {N: aws.String("1")},
   518  					},
   519  				},
   520  				"PtrStruct": {
   521  					M: map[string]*dynamodb.AttributeValue{
   522  						"Int": {N: aws.String("1")},
   523  					},
   524  				},
   525  			},
   526  		},
   527  		actual: &struct {
   528  			Struct    testEmptyCollectionStruct
   529  			PtrStruct *testEmptyCollectionStruct
   530  		}{},
   531  		expected: struct {
   532  			Struct    testEmptyCollectionStruct
   533  			PtrStruct *testEmptyCollectionStruct
   534  		}{
   535  			Struct:    testEmptyCollectionStruct{Int: 1},
   536  			PtrStruct: &testEmptyCollectionStruct{Int: 1},
   537  		},
   538  	},
   539  	// struct with omittable members zero value
   540  	18: {
   541  		in: &dynamodb.AttributeValue{
   542  			M: map[string]*dynamodb.AttributeValue{
   543  				"Struct":    {M: map[string]*dynamodb.AttributeValue{}},
   544  				"PtrStruct": {NULL: aws.Bool(true)},
   545  			},
   546  		},
   547  		actual: &struct {
   548  			Struct    testEmptyCollectionStructOmitted
   549  			PtrStruct *testEmptyCollectionStructOmitted
   550  		}{},
   551  		expected: struct {
   552  			Struct    testEmptyCollectionStructOmitted
   553  			PtrStruct *testEmptyCollectionStructOmitted
   554  		}{},
   555  	},
   556  	// omittable struct with omittable members zero value
   557  	19: {
   558  		in: &dynamodb.AttributeValue{
   559  			M: map[string]*dynamodb.AttributeValue{
   560  				"Struct": {M: map[string]*dynamodb.AttributeValue{}},
   561  			},
   562  		},
   563  		actual: &struct {
   564  			Struct    testEmptyCollectionStructOmitted  `dynamodbav:",omitempty"`
   565  			PtrStruct *testEmptyCollectionStructOmitted `dynamodbav:",omitempty"`
   566  		}{},
   567  		expected: struct {
   568  			Struct    testEmptyCollectionStructOmitted  `dynamodbav:",omitempty"`
   569  			PtrStruct *testEmptyCollectionStructOmitted `dynamodbav:",omitempty"`
   570  		}{},
   571  	},
   572  	// omittable struct with omittable members non-zero value
   573  	20: {
   574  		in: &dynamodb.AttributeValue{
   575  			M: map[string]*dynamodb.AttributeValue{
   576  				"Struct": {
   577  					M: map[string]*dynamodb.AttributeValue{
   578  						"Slice": {L: []*dynamodb.AttributeValue{{S: aws.String("test")}}},
   579  					},
   580  				},
   581  				"InitPtrStruct": {
   582  					M: map[string]*dynamodb.AttributeValue{
   583  						"Slice": {L: []*dynamodb.AttributeValue{{S: aws.String("test")}}},
   584  					},
   585  				},
   586  			},
   587  		},
   588  		actual: &struct {
   589  			Struct        testEmptyCollectionStructOmitted  `dynamodbav:",omitempty"`
   590  			InitPtrStruct *testEmptyCollectionStructOmitted `dynamodbav:",omitempty"`
   591  		}{},
   592  		expected: struct {
   593  			Struct        testEmptyCollectionStructOmitted  `dynamodbav:",omitempty"`
   594  			InitPtrStruct *testEmptyCollectionStructOmitted `dynamodbav:",omitempty"`
   595  		}{
   596  			Struct:        testEmptyCollectionStructOmitted{Slice: []string{"test"}},
   597  			InitPtrStruct: &testEmptyCollectionStructOmitted{Slice: []string{"test"}},
   598  		},
   599  	},
   600  	21: { // empty slice and NullEmptyByteSlice disabled
   601  		encoderOpts: func(encoder *Encoder) {
   602  			encoder.NullEmptyByteSlice = false
   603  		},
   604  		in: &dynamodb.AttributeValue{
   605  			B: []byte{},
   606  		},
   607  		actual:   &[]byte{},
   608  		expected: []byte{},
   609  	},
   610  	22: { // empty slice and NullEmptyByteSlice disabled, and omitempty
   611  		encoderOpts: func(encoder *Encoder) {
   612  			encoder.NullEmptyByteSlice = false
   613  		},
   614  		in: &dynamodb.AttributeValue{
   615  			M: map[string]*dynamodb.AttributeValue{},
   616  		},
   617  		actual: &struct {
   618  			Value []byte `dynamodbav:",omitempty"`
   619  		}{},
   620  		expected: struct {
   621  			Value []byte `dynamodbav:",omitempty"`
   622  		}{},
   623  	},
   624  }
   625  
   626  func TestMarshalEmptyCollections(t *testing.T) {
   627  	for i, c := range sharedEmptyCollectionsTestCases {
   628  		encoder := NewEncoder(func(e *Encoder) {
   629  			e.EnableEmptyCollections = true
   630  			if c.encoderOpts != nil {
   631  				c.encoderOpts(e)
   632  			}
   633  		})
   634  		av, err := encoder.Encode(c.expected)
   635  		assertConvertTest(t, i, av, c.in, err, c.err)
   636  	}
   637  }
   638  
   639  func TestEmptyCollectionsSpecialCases(t *testing.T) {
   640  	// ptr string non nil with empty value
   641  
   642  	type SpecialCases struct {
   643  		PtrString        *string
   644  		OmittedPtrString *string `dynamodbav:",omitempty"`
   645  	}
   646  
   647  	expectedEncode := &dynamodb.AttributeValue{
   648  		M: map[string]*dynamodb.AttributeValue{
   649  			"PtrString": {NULL: aws.Bool(true)},
   650  		},
   651  	}
   652  	expectedDecode := SpecialCases{}
   653  
   654  	encoder := NewEncoder(func(encoder *Encoder) {
   655  		encoder.EnableEmptyCollections = true
   656  	})
   657  
   658  	actualEncode, err := encoder.Encode(&SpecialCases{
   659  		PtrString:        aws.String(""),
   660  		OmittedPtrString: aws.String(""),
   661  	})
   662  	if err != nil {
   663  		t.Fatalf("expected no err got %v", err)
   664  	}
   665  	if e, a := expectedEncode, actualEncode; !reflect.DeepEqual(e, a) {
   666  		t.Errorf("expected %v, got %v", e, a)
   667  	}
   668  
   669  	decoder := NewDecoder(func(decoder *Decoder) {
   670  		decoder.EnableEmptyCollections = true
   671  	})
   672  
   673  	var actualDecode SpecialCases
   674  	err = decoder.Decode(&dynamodb.AttributeValue{}, &actualDecode)
   675  	if err != nil {
   676  		t.Fatalf("expected no err got %v", err)
   677  	}
   678  	if e, a := expectedDecode, actualDecode; !reflect.DeepEqual(e, a) {
   679  		t.Errorf("expected %v, got %v", e, a)
   680  	}
   681  }
   682  
   683  func TestUnmarshalEmptyCollections(t *testing.T) {
   684  	for i, c := range sharedEmptyCollectionsTestCases {
   685  		decoder := NewDecoder(func(d *Decoder) {
   686  			d.EnableEmptyCollections = true
   687  		})
   688  		err := decoder.Decode(c.in, c.actual)
   689  		assertConvertTest(t, i, c.actual, c.expected, err, c.err)
   690  	}
   691  }