marshaler_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. package dynamodbattribute
  2. import (
  3. "math"
  4. "reflect"
  5. "testing"
  6. "github.com/aws/aws-sdk-go/aws"
  7. "github.com/aws/aws-sdk-go/aws/awserr"
  8. "github.com/aws/aws-sdk-go/aws/awsutil"
  9. "github.com/aws/aws-sdk-go/service/dynamodb"
  10. )
  11. type simpleMarshalStruct struct {
  12. Byte []byte
  13. String string
  14. Int int
  15. Uint uint
  16. Float32 float32
  17. Float64 float64
  18. Bool bool
  19. Null *interface{}
  20. }
  21. type complexMarshalStruct struct {
  22. Simple []simpleMarshalStruct
  23. }
  24. type myByteStruct struct {
  25. Byte []byte
  26. }
  27. type myByteSetStruct struct {
  28. ByteSet [][]byte
  29. }
  30. type marshallerTestInput struct {
  31. input interface{}
  32. expected interface{}
  33. err awserr.Error
  34. }
  35. var marshalerScalarInputs = []marshallerTestInput{
  36. {
  37. input: nil,
  38. expected: &dynamodb.AttributeValue{NULL: &trueValue},
  39. },
  40. {
  41. input: "some string",
  42. expected: &dynamodb.AttributeValue{S: aws.String("some string")},
  43. },
  44. {
  45. input: true,
  46. expected: &dynamodb.AttributeValue{BOOL: &trueValue},
  47. },
  48. {
  49. input: false,
  50. expected: &dynamodb.AttributeValue{BOOL: &falseValue},
  51. },
  52. {
  53. input: 3.14,
  54. expected: &dynamodb.AttributeValue{N: aws.String("3.14")},
  55. },
  56. {
  57. input: math.MaxFloat32,
  58. expected: &dynamodb.AttributeValue{N: aws.String("340282346638528860000000000000000000000")},
  59. },
  60. {
  61. input: math.MaxFloat64,
  62. expected: &dynamodb.AttributeValue{N: aws.String("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")},
  63. },
  64. {
  65. input: 12,
  66. expected: &dynamodb.AttributeValue{N: aws.String("12")},
  67. },
  68. {
  69. input: Number("12"),
  70. expected: &dynamodb.AttributeValue{N: aws.String("12")},
  71. },
  72. {
  73. input: simpleMarshalStruct{},
  74. expected: &dynamodb.AttributeValue{
  75. M: map[string]*dynamodb.AttributeValue{
  76. "Byte": {NULL: &trueValue},
  77. "Bool": {BOOL: &falseValue},
  78. "Float32": {N: aws.String("0")},
  79. "Float64": {N: aws.String("0")},
  80. "Int": {N: aws.String("0")},
  81. "Null": {NULL: &trueValue},
  82. "String": {NULL: &trueValue},
  83. "Uint": {N: aws.String("0")},
  84. },
  85. },
  86. },
  87. }
  88. var marshallerMapTestInputs = []marshallerTestInput{
  89. // Scalar tests
  90. {
  91. input: nil,
  92. expected: map[string]*dynamodb.AttributeValue{},
  93. },
  94. {
  95. input: map[string]interface{}{"string": "some string"},
  96. expected: map[string]*dynamodb.AttributeValue{"string": {S: aws.String("some string")}},
  97. },
  98. {
  99. input: map[string]interface{}{"bool": true},
  100. expected: map[string]*dynamodb.AttributeValue{"bool": {BOOL: &trueValue}},
  101. },
  102. {
  103. input: map[string]interface{}{"bool": false},
  104. expected: map[string]*dynamodb.AttributeValue{"bool": {BOOL: &falseValue}},
  105. },
  106. {
  107. input: map[string]interface{}{"null": nil},
  108. expected: map[string]*dynamodb.AttributeValue{"null": {NULL: &trueValue}},
  109. },
  110. {
  111. input: map[string]interface{}{"float": 3.14},
  112. expected: map[string]*dynamodb.AttributeValue{"float": {N: aws.String("3.14")}},
  113. },
  114. {
  115. input: map[string]interface{}{"float": math.MaxFloat32},
  116. expected: map[string]*dynamodb.AttributeValue{"float": {N: aws.String("340282346638528860000000000000000000000")}},
  117. },
  118. {
  119. input: map[string]interface{}{"float": math.MaxFloat64},
  120. expected: map[string]*dynamodb.AttributeValue{"float": {N: aws.String("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")}},
  121. },
  122. {
  123. input: map[string]interface{}{"num": 12.},
  124. expected: map[string]*dynamodb.AttributeValue{"num": {N: aws.String("12")}},
  125. },
  126. {
  127. input: map[string]interface{}{"byte": []byte{48, 49}},
  128. expected: map[string]*dynamodb.AttributeValue{"byte": {B: []byte{48, 49}}},
  129. },
  130. {
  131. input: struct{ Byte []byte }{Byte: []byte{48, 49}},
  132. expected: map[string]*dynamodb.AttributeValue{"Byte": {B: []byte{48, 49}}},
  133. },
  134. {
  135. input: map[string]interface{}{"byte_set": [][]byte{{48, 49}, {50, 51}}},
  136. expected: map[string]*dynamodb.AttributeValue{"byte_set": {BS: [][]byte{{48, 49}, {50, 51}}}},
  137. },
  138. {
  139. input: struct{ ByteSet [][]byte }{ByteSet: [][]byte{{48, 49}, {50, 51}}},
  140. expected: map[string]*dynamodb.AttributeValue{"ByteSet": {BS: [][]byte{{48, 49}, {50, 51}}}},
  141. },
  142. // List
  143. {
  144. input: map[string]interface{}{"list": []interface{}{"a string", 12., 3.14, true, nil, false}},
  145. expected: map[string]*dynamodb.AttributeValue{
  146. "list": {
  147. L: []*dynamodb.AttributeValue{
  148. {S: aws.String("a string")},
  149. {N: aws.String("12")},
  150. {N: aws.String("3.14")},
  151. {BOOL: &trueValue},
  152. {NULL: &trueValue},
  153. {BOOL: &falseValue},
  154. },
  155. },
  156. },
  157. },
  158. // Map
  159. {
  160. input: map[string]interface{}{"map": map[string]interface{}{"nestednum": 12.}},
  161. expected: map[string]*dynamodb.AttributeValue{
  162. "map": {
  163. M: map[string]*dynamodb.AttributeValue{
  164. "nestednum": {
  165. N: aws.String("12"),
  166. },
  167. },
  168. },
  169. },
  170. },
  171. // Structs
  172. {
  173. input: simpleMarshalStruct{},
  174. expected: map[string]*dynamodb.AttributeValue{
  175. "Byte": {NULL: &trueValue},
  176. "Bool": {BOOL: &falseValue},
  177. "Float32": {N: aws.String("0")},
  178. "Float64": {N: aws.String("0")},
  179. "Int": {N: aws.String("0")},
  180. "Null": {NULL: &trueValue},
  181. "String": {NULL: &trueValue},
  182. "Uint": {N: aws.String("0")},
  183. },
  184. },
  185. {
  186. input: complexMarshalStruct{},
  187. expected: map[string]*dynamodb.AttributeValue{
  188. "Simple": {NULL: &trueValue},
  189. },
  190. },
  191. {
  192. input: struct {
  193. Simple []string `json:"simple"`
  194. }{},
  195. expected: map[string]*dynamodb.AttributeValue{
  196. "simple": {NULL: &trueValue},
  197. },
  198. },
  199. {
  200. input: struct {
  201. Simple []string `json:"simple,omitempty"`
  202. }{},
  203. expected: map[string]*dynamodb.AttributeValue{},
  204. },
  205. {
  206. input: struct {
  207. Simple []string `json:"-"`
  208. }{},
  209. expected: map[string]*dynamodb.AttributeValue{},
  210. },
  211. {
  212. input: complexMarshalStruct{Simple: []simpleMarshalStruct{{Int: -2}, {Uint: 5}}},
  213. expected: map[string]*dynamodb.AttributeValue{
  214. "Simple": {
  215. L: []*dynamodb.AttributeValue{
  216. {
  217. M: map[string]*dynamodb.AttributeValue{
  218. "Byte": {NULL: &trueValue},
  219. "Bool": {BOOL: &falseValue},
  220. "Float32": {N: aws.String("0")},
  221. "Float64": {N: aws.String("0")},
  222. "Int": {N: aws.String("-2")},
  223. "Null": {NULL: &trueValue},
  224. "String": {NULL: &trueValue},
  225. "Uint": {N: aws.String("0")},
  226. },
  227. },
  228. {
  229. M: map[string]*dynamodb.AttributeValue{
  230. "Byte": {NULL: &trueValue},
  231. "Bool": {BOOL: &falseValue},
  232. "Float32": {N: aws.String("0")},
  233. "Float64": {N: aws.String("0")},
  234. "Int": {N: aws.String("0")},
  235. "Null": {NULL: &trueValue},
  236. "String": {NULL: &trueValue},
  237. "Uint": {N: aws.String("5")},
  238. },
  239. },
  240. },
  241. },
  242. },
  243. },
  244. }
  245. var marshallerListTestInputs = []marshallerTestInput{
  246. {
  247. input: nil,
  248. expected: []*dynamodb.AttributeValue{},
  249. },
  250. {
  251. input: []interface{}{},
  252. expected: []*dynamodb.AttributeValue{},
  253. },
  254. {
  255. input: []simpleMarshalStruct{},
  256. expected: []*dynamodb.AttributeValue{},
  257. },
  258. {
  259. input: []interface{}{"a string", 12., 3.14, true, nil, false},
  260. expected: []*dynamodb.AttributeValue{
  261. {S: aws.String("a string")},
  262. {N: aws.String("12")},
  263. {N: aws.String("3.14")},
  264. {BOOL: &trueValue},
  265. {NULL: &trueValue},
  266. {BOOL: &falseValue},
  267. },
  268. },
  269. {
  270. input: []simpleMarshalStruct{{}},
  271. expected: []*dynamodb.AttributeValue{
  272. {
  273. M: map[string]*dynamodb.AttributeValue{
  274. "Byte": {NULL: &trueValue},
  275. "Bool": {BOOL: &falseValue},
  276. "Float32": {N: aws.String("0")},
  277. "Float64": {N: aws.String("0")},
  278. "Int": {N: aws.String("0")},
  279. "Null": {NULL: &trueValue},
  280. "String": {NULL: &trueValue},
  281. "Uint": {N: aws.String("0")},
  282. },
  283. },
  284. },
  285. },
  286. }
  287. func Test_New_Marshal(t *testing.T) {
  288. for _, test := range marshalerScalarInputs {
  289. testMarshal(t, test)
  290. }
  291. }
  292. func testMarshal(t *testing.T, test marshallerTestInput) {
  293. actual, err := Marshal(test.input)
  294. if test.err != nil {
  295. if err == nil {
  296. t.Errorf("Marshal with input %#v retured %#v, expected error `%s`", test.input, actual, test.err)
  297. } else if err.Error() != test.err.Error() {
  298. t.Errorf("Marshal with input %#v retured error `%s`, expected error `%s`", test.input, err, test.err)
  299. }
  300. } else {
  301. if err != nil {
  302. t.Errorf("Marshal with input %#v retured error `%s`", test.input, err)
  303. }
  304. compareObjects(t, test.expected, actual)
  305. }
  306. }
  307. func Test_New_Unmarshal(t *testing.T) {
  308. // Using the same inputs from Marshal, test the reverse mapping.
  309. for i, test := range marshalerScalarInputs {
  310. if test.input == nil {
  311. continue
  312. }
  313. actual := reflect.New(reflect.TypeOf(test.input)).Interface()
  314. if err := Unmarshal(test.expected.(*dynamodb.AttributeValue), actual); err != nil {
  315. t.Errorf("Unmarshal %d, with input %#v retured error `%s`", i+1, test.expected, err)
  316. }
  317. compareObjects(t, test.input, reflect.ValueOf(actual).Elem().Interface())
  318. }
  319. }
  320. func Test_New_UnmarshalError(t *testing.T) {
  321. // Test that we get an error using Unmarshal to convert to a nil value.
  322. expected := &InvalidUnmarshalError{Type: reflect.TypeOf(nil)}
  323. if err := Unmarshal(nil, nil); err == nil {
  324. t.Errorf("Unmarshal with input %T returned no error, expected error `%v`", nil, expected)
  325. } else if err.Error() != expected.Error() {
  326. t.Errorf("Unmarshal with input %T returned error `%v`, expected error `%v`", nil, err, expected)
  327. }
  328. // Test that we get an error using Unmarshal to convert to a non-pointer value.
  329. var actual map[string]interface{}
  330. expected = &InvalidUnmarshalError{Type: reflect.TypeOf(actual)}
  331. if err := Unmarshal(nil, actual); err == nil {
  332. t.Errorf("Unmarshal with input %T returned no error, expected error `%v`", actual, expected)
  333. } else if err.Error() != expected.Error() {
  334. t.Errorf("Unmarshal with input %T returned error `%v`, expected error `%v`", actual, err, expected)
  335. }
  336. // Test that we get an error using Unmarshal to convert to nil struct.
  337. var actual2 *struct{ A int }
  338. expected = &InvalidUnmarshalError{Type: reflect.TypeOf(actual2)}
  339. if err := Unmarshal(nil, actual2); err == nil {
  340. t.Errorf("Unmarshal with input %T returned no error, expected error `%v`", actual2, expected)
  341. } else if err.Error() != expected.Error() {
  342. t.Errorf("Unmarshal with input %T returned error `%v`, expected error `%v`", actual2, err, expected)
  343. }
  344. }
  345. func Test_New_MarshalMap(t *testing.T) {
  346. for _, test := range marshallerMapTestInputs {
  347. testMarshalMap(t, test)
  348. }
  349. }
  350. func testMarshalMap(t *testing.T, test marshallerTestInput) {
  351. actual, err := MarshalMap(test.input)
  352. if test.err != nil {
  353. if err == nil {
  354. t.Errorf("MarshalMap with input %#v retured %#v, expected error `%s`", test.input, actual, test.err)
  355. } else if err.Error() != test.err.Error() {
  356. t.Errorf("MarshalMap with input %#v retured error `%s`, expected error `%s`", test.input, err, test.err)
  357. }
  358. } else {
  359. if err != nil {
  360. t.Errorf("MarshalMap with input %#v retured error `%s`", test.input, err)
  361. }
  362. compareObjects(t, test.expected, actual)
  363. }
  364. }
  365. func Test_New_UnmarshalMap(t *testing.T) {
  366. // Using the same inputs from MarshalMap, test the reverse mapping.
  367. for i, test := range marshallerMapTestInputs {
  368. if test.input == nil {
  369. continue
  370. }
  371. actual := reflect.New(reflect.TypeOf(test.input)).Interface()
  372. if err := UnmarshalMap(test.expected.(map[string]*dynamodb.AttributeValue), actual); err != nil {
  373. t.Errorf("Unmarshal %d, with input %#v retured error `%s`", i+1, test.expected, err)
  374. }
  375. compareObjects(t, test.input, reflect.ValueOf(actual).Elem().Interface())
  376. }
  377. }
  378. func Test_New_UnmarshalMapError(t *testing.T) {
  379. // Test that we get an error using UnmarshalMap to convert to a nil value.
  380. expected := &InvalidUnmarshalError{Type: reflect.TypeOf(nil)}
  381. if err := UnmarshalMap(nil, nil); err == nil {
  382. t.Errorf("UnmarshalMap with input %T returned no error, expected error `%v`", nil, expected)
  383. } else if err.Error() != expected.Error() {
  384. t.Errorf("UnmarshalMap with input %T returned error `%v`, expected error `%v`", nil, err, expected)
  385. }
  386. // Test that we get an error using UnmarshalMap to convert to a non-pointer value.
  387. var actual map[string]interface{}
  388. expected = &InvalidUnmarshalError{Type: reflect.TypeOf(actual)}
  389. if err := UnmarshalMap(nil, actual); err == nil {
  390. t.Errorf("UnmarshalMap with input %T returned no error, expected error `%v`", actual, expected)
  391. } else if err.Error() != expected.Error() {
  392. t.Errorf("UnmarshalMap with input %T returned error `%v`, expected error `%v`", actual, err, expected)
  393. }
  394. // Test that we get an error using UnmarshalMap to convert to nil struct.
  395. var actual2 *struct{ A int }
  396. expected = &InvalidUnmarshalError{Type: reflect.TypeOf(actual2)}
  397. if err := UnmarshalMap(nil, actual2); err == nil {
  398. t.Errorf("UnmarshalMap with input %T returned no error, expected error `%v`", actual2, expected)
  399. } else if err.Error() != expected.Error() {
  400. t.Errorf("UnmarshalMap with input %T returned error `%v`, expected error `%v`", actual2, err, expected)
  401. }
  402. }
  403. func Test_New_MarshalList(t *testing.T) {
  404. for _, test := range marshallerListTestInputs {
  405. testMarshalList(t, test)
  406. }
  407. }
  408. func testMarshalList(t *testing.T, test marshallerTestInput) {
  409. actual, err := MarshalList(test.input)
  410. if test.err != nil {
  411. if err == nil {
  412. t.Errorf("MarshalList with input %#v retured %#v, expected error `%s`", test.input, actual, test.err)
  413. } else if err.Error() != test.err.Error() {
  414. t.Errorf("MarshalList with input %#v retured error `%s`, expected error `%s`", test.input, err, test.err)
  415. }
  416. } else {
  417. if err != nil {
  418. t.Errorf("MarshalList with input %#v retured error `%s`", test.input, err)
  419. }
  420. compareObjects(t, test.expected, actual)
  421. }
  422. }
  423. func Test_New_UnmarshalList(t *testing.T) {
  424. // Using the same inputs from MarshalList, test the reverse mapping.
  425. for i, test := range marshallerListTestInputs {
  426. if test.input == nil {
  427. continue
  428. }
  429. iv := reflect.ValueOf(test.input)
  430. actual := reflect.New(iv.Type())
  431. if iv.Kind() == reflect.Slice {
  432. actual.Elem().Set(reflect.MakeSlice(iv.Type(), iv.Len(), iv.Cap()))
  433. }
  434. if err := UnmarshalList(test.expected.([]*dynamodb.AttributeValue), actual.Interface()); err != nil {
  435. t.Errorf("Unmarshal %d, with input %#v retured error `%s`", i+1, test.expected, err)
  436. }
  437. compareObjects(t, test.input, actual.Elem().Interface())
  438. }
  439. }
  440. func Test_New_UnmarshalListError(t *testing.T) {
  441. // Test that we get an error using UnmarshalList to convert to a nil value.
  442. expected := &InvalidUnmarshalError{Type: reflect.TypeOf(nil)}
  443. if err := UnmarshalList(nil, nil); err == nil {
  444. t.Errorf("UnmarshalList with input %T returned no error, expected error `%v`", nil, expected)
  445. } else if err.Error() != expected.Error() {
  446. t.Errorf("UnmarshalList with input %T returned error `%v`, expected error `%v`", nil, err, expected)
  447. }
  448. // Test that we get an error using UnmarshalList to convert to a non-pointer value.
  449. var actual map[string]interface{}
  450. expected = &InvalidUnmarshalError{Type: reflect.TypeOf(actual)}
  451. if err := UnmarshalList(nil, actual); err == nil {
  452. t.Errorf("UnmarshalList with input %T returned no error, expected error `%v`", actual, expected)
  453. } else if err.Error() != expected.Error() {
  454. t.Errorf("UnmarshalList with input %T returned error `%v`, expected error `%v`", actual, err, expected)
  455. }
  456. // Test that we get an error using UnmarshalList to convert to nil struct.
  457. var actual2 *struct{ A int }
  458. expected = &InvalidUnmarshalError{Type: reflect.TypeOf(actual2)}
  459. if err := UnmarshalList(nil, actual2); err == nil {
  460. t.Errorf("UnmarshalList with input %T returned no error, expected error `%v`", actual2, expected)
  461. } else if err.Error() != expected.Error() {
  462. t.Errorf("UnmarshalList with input %T returned error `%v`, expected error `%v`", actual2, err, expected)
  463. }
  464. }
  465. // see github issue #1594
  466. func TestDecodeArrayType(t *testing.T) {
  467. cases := []struct {
  468. to, from interface{}
  469. }{
  470. {
  471. &[2]int{1, 2},
  472. &[2]int{},
  473. },
  474. {
  475. &[2]int64{1, 2},
  476. &[2]int64{},
  477. },
  478. {
  479. &[2]byte{1, 2},
  480. &[2]byte{},
  481. },
  482. {
  483. &[2]bool{true, false},
  484. &[2]bool{},
  485. },
  486. {
  487. &[2]string{"1", "2"},
  488. &[2]string{},
  489. },
  490. {
  491. &[2][]string{{"1", "2"}},
  492. &[2][]string{},
  493. },
  494. }
  495. for _, c := range cases {
  496. marshaled, err := Marshal(c.to)
  497. if err != nil {
  498. t.Errorf("expected no error, but received %v", err)
  499. }
  500. if err = Unmarshal(marshaled, c.from); err != nil {
  501. t.Errorf("expected no error, but received %v", err)
  502. }
  503. if !reflect.DeepEqual(c.to, c.from) {
  504. t.Errorf("expected %v, but received %v", c.to, c.from)
  505. }
  506. }
  507. }
  508. func compareObjects(t *testing.T, expected interface{}, actual interface{}) {
  509. if !reflect.DeepEqual(expected, actual) {
  510. ev := reflect.ValueOf(expected)
  511. av := reflect.ValueOf(actual)
  512. t.Errorf("\nExpected kind(%s,%T):\n%s\nActual kind(%s,%T):\n%s\n",
  513. ev.Kind(),
  514. ev.Interface(),
  515. awsutil.Prettify(expected),
  516. av.Kind(),
  517. ev.Interface(),
  518. awsutil.Prettify(actual))
  519. }
  520. }
  521. func BenchmarkMarshal(b *testing.B) {
  522. d := simpleMarshalStruct{
  523. String: "abc",
  524. Int: 123,
  525. Uint: 123,
  526. Float32: 123.321,
  527. Float64: 123.321,
  528. Bool: true,
  529. Null: nil,
  530. }
  531. for i := 0; i < b.N; i++ {
  532. _, err := Marshal(d)
  533. if err != nil {
  534. b.Fatal("unexpected error", err)
  535. }
  536. }
  537. }
  538. func Test_Encode_YAML_TagKey(t *testing.T) {
  539. input := struct {
  540. String string `yaml:"string"`
  541. EmptyString string `yaml:"empty"`
  542. OmitString string `yaml:"omitted,omitempty"`
  543. Ignored string `yaml:"-"`
  544. Byte []byte `yaml:"byte"`
  545. Float32 float32 `yaml:"float32"`
  546. Float64 float64 `yaml:"float64"`
  547. Int int `yaml:"int"`
  548. Uint uint `yaml:"uint"`
  549. Slice []string `yaml:"slice"`
  550. Map map[string]int `yaml:"map"`
  551. NoTag string
  552. }{
  553. String: "String",
  554. Ignored: "Ignored",
  555. Slice: []string{"one", "two"},
  556. Map: map[string]int{
  557. "one": 1,
  558. "two": 2,
  559. },
  560. NoTag: "NoTag",
  561. }
  562. expected := &dynamodb.AttributeValue{
  563. M: map[string]*dynamodb.AttributeValue{
  564. "string": {S: aws.String("String")},
  565. "empty": {NULL: &trueValue},
  566. "byte": {NULL: &trueValue},
  567. "float32": {N: aws.String("0")},
  568. "float64": {N: aws.String("0")},
  569. "int": {N: aws.String("0")},
  570. "uint": {N: aws.String("0")},
  571. "slice": {
  572. L: []*dynamodb.AttributeValue{
  573. {S: aws.String("one")},
  574. {S: aws.String("two")},
  575. },
  576. },
  577. "map": {
  578. M: map[string]*dynamodb.AttributeValue{
  579. "one": {N: aws.String("1")},
  580. "two": {N: aws.String("2")},
  581. },
  582. },
  583. "NoTag": {S: aws.String("NoTag")},
  584. },
  585. }
  586. enc := NewEncoder(func(e *Encoder) {
  587. e.TagKey = "yaml"
  588. })
  589. actual, err := enc.Encode(input)
  590. if err != nil {
  591. t.Errorf("Encode with input %#v retured error `%s`, expected nil", input, err)
  592. }
  593. compareObjects(t, expected, actual)
  594. }