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

     1  package dynamodbattribute
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/aavshr/aws-sdk-go/aws"
    10  	"github.com/aavshr/aws-sdk-go/aws/awserr"
    11  	"github.com/aavshr/aws-sdk-go/service/dynamodb"
    12  )
    13  
    14  func TestMarshalErrorTypes(t *testing.T) {
    15  	var _ awserr.Error = (*InvalidMarshalError)(nil)
    16  	var _ awserr.Error = (*unsupportedMarshalTypeError)(nil)
    17  }
    18  
    19  func TestMarshalShared(t *testing.T) {
    20  	for i, c := range sharedTestCases {
    21  		var opts []func(*Encoder)
    22  		if c.encoderOpts != nil {
    23  			opts = append(opts, c.encoderOpts)
    24  		}
    25  		e := NewEncoder(opts...)
    26  		av, err := e.Encode(c.expected)
    27  		assertConvertTest(t, i, av, c.in, err, c.err)
    28  	}
    29  }
    30  
    31  func TestMarshalListShared(t *testing.T) {
    32  	for i, c := range sharedListTestCases {
    33  		av, err := MarshalList(c.expected)
    34  		assertConvertTest(t, i, av, c.in, err, c.err)
    35  	}
    36  }
    37  
    38  func TestMarshalMapShared(t *testing.T) {
    39  	for i, c := range sharedMapTestCases {
    40  		av, err := MarshalMap(c.expected)
    41  		assertConvertTest(t, i, av, c.in, err, c.err)
    42  	}
    43  }
    44  
    45  type marshalMarshaler struct {
    46  	Value  string
    47  	Value2 int
    48  	Value3 bool
    49  	Value4 time.Time
    50  }
    51  
    52  func (m *marshalMarshaler) MarshalDynamoDBAttributeValue(av *dynamodb.AttributeValue) error {
    53  	av.M = map[string]*dynamodb.AttributeValue{
    54  		"abc": {S: &m.Value},
    55  		"def": {N: aws.String(fmt.Sprintf("%d", m.Value2))},
    56  		"ghi": {BOOL: &m.Value3},
    57  		"jkl": {S: aws.String(m.Value4.Format(time.RFC3339Nano))},
    58  	}
    59  
    60  	return nil
    61  }
    62  
    63  func TestMarshalMashaler(t *testing.T) {
    64  	m := &marshalMarshaler{
    65  		Value:  "value",
    66  		Value2: 123,
    67  		Value3: true,
    68  		Value4: testDate,
    69  	}
    70  
    71  	expect := &dynamodb.AttributeValue{
    72  		M: map[string]*dynamodb.AttributeValue{
    73  			"abc": {S: aws.String("value")},
    74  			"def": {N: aws.String("123")},
    75  			"ghi": {BOOL: aws.Bool(true)},
    76  			"jkl": {S: aws.String("2016-05-03T17:06:26.209072Z")},
    77  		},
    78  	}
    79  
    80  	actual, err := Marshal(m)
    81  	if err != nil {
    82  		t.Errorf("expect nil, got %v", err)
    83  	}
    84  
    85  	if e, a := expect, actual; !reflect.DeepEqual(e, a) {
    86  		t.Errorf("expect %v, got %v", e, a)
    87  	}
    88  }
    89  
    90  type testOmitEmptyElemListStruct struct {
    91  	Values []string `dynamodbav:",omitemptyelem"`
    92  }
    93  
    94  type testOmitEmptyElemMapStruct struct {
    95  	Values map[string]interface{} `dynamodbav:",omitemptyelem"`
    96  }
    97  
    98  func TestMarshalListOmitEmptyElem(t *testing.T) {
    99  	expect := &dynamodb.AttributeValue{
   100  		M: map[string]*dynamodb.AttributeValue{
   101  			"Values": {L: []*dynamodb.AttributeValue{
   102  				{S: aws.String("abc")},
   103  				{S: aws.String("123")},
   104  			}},
   105  		},
   106  	}
   107  
   108  	m := testOmitEmptyElemListStruct{Values: []string{"abc", "", "123"}}
   109  
   110  	actual, err := Marshal(m)
   111  	if err != nil {
   112  		t.Errorf("expect nil, got %v", err)
   113  	}
   114  	if e, a := expect, actual; !reflect.DeepEqual(e, a) {
   115  		t.Errorf("expect %v, got %v", e, a)
   116  	}
   117  }
   118  
   119  func TestMarshalMapOmitEmptyElem(t *testing.T) {
   120  	expect := &dynamodb.AttributeValue{
   121  		M: map[string]*dynamodb.AttributeValue{
   122  			"Values": {M: map[string]*dynamodb.AttributeValue{
   123  				"abc": {N: aws.String("123")},
   124  				"klm": {S: aws.String("abc")},
   125  			}},
   126  		},
   127  	}
   128  
   129  	m := testOmitEmptyElemMapStruct{Values: map[string]interface{}{
   130  		"abc": 123.,
   131  		"efg": nil,
   132  		"hij": "",
   133  		"klm": "abc",
   134  	}}
   135  
   136  	actual, err := Marshal(m)
   137  	if err != nil {
   138  		t.Errorf("expect nil, got %v", err)
   139  	}
   140  	if e, a := expect, actual; !reflect.DeepEqual(e, a) {
   141  		t.Errorf("expect %v, got %v", e, a)
   142  	}
   143  }
   144  
   145  type testOmitEmptyScalar struct {
   146  	IntZero       int  `dynamodbav:",omitempty"`
   147  	IntPtrNil     *int `dynamodbav:",omitempty"`
   148  	IntPtrSetZero *int `dynamodbav:",omitempty"`
   149  }
   150  
   151  func TestMarshalOmitEmpty(t *testing.T) {
   152  	expect := &dynamodb.AttributeValue{
   153  		M: map[string]*dynamodb.AttributeValue{
   154  			"IntPtrSetZero": {N: aws.String("0")},
   155  		},
   156  	}
   157  
   158  	m := testOmitEmptyScalar{IntPtrSetZero: aws.Int(0)}
   159  
   160  	actual, err := Marshal(m)
   161  	if err != nil {
   162  		t.Errorf("expect nil, got %v", err)
   163  	}
   164  	if e, a := expect, actual; !reflect.DeepEqual(e, a) {
   165  		t.Errorf("expect %v, got %v", e, a)
   166  	}
   167  }
   168  
   169  func TestEncodeEmbeddedPointerStruct(t *testing.T) {
   170  	type B struct {
   171  		Bint int
   172  	}
   173  	type C struct {
   174  		Cint int
   175  	}
   176  	type A struct {
   177  		Aint int
   178  		*B
   179  		*C
   180  	}
   181  	a := A{Aint: 321, B: &B{123}}
   182  	if e, a := 321, a.Aint; e != a {
   183  		t.Errorf("expect %v, got %v", e, a)
   184  	}
   185  	if e, a := 123, a.Bint; e != a {
   186  		t.Errorf("expect %v, got %v", e, a)
   187  	}
   188  	if a.C != nil {
   189  		t.Errorf("expect nil, got %v", a.C)
   190  	}
   191  
   192  	actual, err := Marshal(a)
   193  	if err != nil {
   194  		t.Errorf("expect nil, got %v", err)
   195  	}
   196  	expect := &dynamodb.AttributeValue{
   197  		M: map[string]*dynamodb.AttributeValue{
   198  			"Aint": {
   199  				N: aws.String("321"),
   200  			},
   201  			"Bint": {
   202  				N: aws.String("123"),
   203  			},
   204  		},
   205  	}
   206  	if e, a := expect, actual; !reflect.DeepEqual(e, a) {
   207  		t.Errorf("expect %v, got %v", e, a)
   208  	}
   209  }
   210  
   211  func TestEncodeUnixTime(t *testing.T) {
   212  	type A struct {
   213  		Normal time.Time
   214  		Tagged time.Time `dynamodbav:",unixtime"`
   215  		Typed  UnixTime
   216  	}
   217  
   218  	a := A{
   219  		Normal: time.Unix(123, 0).UTC(),
   220  		Tagged: time.Unix(456, 0),
   221  		Typed:  UnixTime(time.Unix(789, 0)),
   222  	}
   223  
   224  	actual, err := Marshal(a)
   225  	if err != nil {
   226  		t.Errorf("expect nil, got %v", err)
   227  	}
   228  	expect := &dynamodb.AttributeValue{
   229  		M: map[string]*dynamodb.AttributeValue{
   230  			"Normal": {
   231  				S: aws.String("1970-01-01T00:02:03Z"),
   232  			},
   233  			"Tagged": {
   234  				N: aws.String("456"),
   235  			},
   236  			"Typed": {
   237  				N: aws.String("789"),
   238  			},
   239  		},
   240  	}
   241  	if e, a := expect, actual; !reflect.DeepEqual(e, a) {
   242  		t.Errorf("expect %v, got %v", e, a)
   243  	}
   244  }
   245  
   246  type AliasedTime time.Time
   247  
   248  func TestEncodeAliasedUnixTime(t *testing.T) {
   249  	type A struct {
   250  		Normal AliasedTime
   251  		Tagged AliasedTime `dynamodbav:",unixtime"`
   252  	}
   253  
   254  	a := A{
   255  		Normal: AliasedTime(time.Unix(123, 0).UTC()),
   256  		Tagged: AliasedTime(time.Unix(456, 0)),
   257  	}
   258  
   259  	actual, err := Marshal(a)
   260  	if err != nil {
   261  		t.Errorf("expect no err, got %v", err)
   262  	}
   263  	expect := &dynamodb.AttributeValue{
   264  		M: map[string]*dynamodb.AttributeValue{
   265  			"Normal": {
   266  				S: aws.String("1970-01-01T00:02:03Z"),
   267  			},
   268  			"Tagged": {
   269  				N: aws.String("456"),
   270  			},
   271  		},
   272  	}
   273  	if e, a := expect, actual; !reflect.DeepEqual(e, a) {
   274  		t.Errorf("expect %v, got %v", e, a)
   275  	}
   276  }
   277  
   278  func TestEncoderFieldByIndex(t *testing.T) {
   279  	type (
   280  		Middle struct{ Inner int }
   281  		Outer  struct{ *Middle }
   282  	)
   283  
   284  	// nil embedded struct
   285  	outer := Outer{}
   286  	outerFields := unionStructFields(reflect.TypeOf(outer), MarshalOptions{})
   287  	innerField, _ := outerFields.FieldByName("Inner")
   288  
   289  	_, found := encoderFieldByIndex(reflect.ValueOf(&outer).Elem(), innerField.Index)
   290  	if found != false {
   291  		t.Error("expected found to be false when embedded struct is nil")
   292  	}
   293  
   294  	// non-nil embedded struct
   295  	outer = Outer{Middle: &Middle{Inner: 3}}
   296  	outerFields = unionStructFields(reflect.TypeOf(outer), MarshalOptions{})
   297  	innerField, _ = outerFields.FieldByName("Inner")
   298  
   299  	f, found := encoderFieldByIndex(reflect.ValueOf(&outer).Elem(), innerField.Index)
   300  	if !found {
   301  		t.Error("expected found to be true")
   302  	}
   303  	if f.Kind() != reflect.Int || f.Int() != int64(outer.Inner) {
   304  		t.Error("expected f to be of kind Int with value equal to outer.Inner")
   305  	}
   306  }