github.com/hamba/avro@v1.8.0/encoder_record_test.go (about) 1 package avro_test 2 3 import ( 4 "bytes" 5 "testing" 6 7 "github.com/hamba/avro" 8 "github.com/stretchr/testify/assert" 9 ) 10 11 func TestEncoder_RecordStruct(t *testing.T) { 12 defer ConfigTeardown() 13 14 schema := `{ 15 "type": "record", 16 "name": "test", 17 "fields" : [ 18 {"name": "a", "type": "long"}, 19 {"name": "b", "type": "string"} 20 ] 21 }` 22 obj := TestRecord{A: 27, B: "foo"} 23 buf := &bytes.Buffer{} 24 enc, err := avro.NewEncoder(schema, buf) 25 assert.NoError(t, err) 26 27 err = enc.Encode(obj) 28 29 assert.NoError(t, err) 30 assert.Equal(t, []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}, buf.Bytes()) 31 } 32 33 func TestEncoder_RecordStructPtr(t *testing.T) { 34 defer ConfigTeardown() 35 36 schema := `{ 37 "type": "record", 38 "name": "test", 39 "fields" : [ 40 {"name": "a", "type": "long"}, 41 {"name": "b", "type": "string"} 42 ] 43 }` 44 obj := &TestRecord{A: 27, B: "foo"} 45 buf := &bytes.Buffer{} 46 enc, err := avro.NewEncoder(schema, buf) 47 assert.NoError(t, err) 48 49 err = enc.Encode(obj) 50 51 assert.NoError(t, err) 52 assert.Equal(t, []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}, buf.Bytes()) 53 } 54 55 func TestEncoder_RecordStructPtrNil(t *testing.T) { 56 defer ConfigTeardown() 57 58 schema := `{ 59 "type": "record", 60 "name": "test", 61 "fields" : [ 62 {"name": "a", "type": "long"}, 63 {"name": "b", "type": "string"} 64 ] 65 }` 66 var obj *TestRecord 67 buf := &bytes.Buffer{} 68 enc, err := avro.NewEncoder(schema, buf) 69 assert.NoError(t, err) 70 71 err = enc.Encode(obj) 72 73 assert.Error(t, err) 74 } 75 76 func TestEncoder_RecordStructMissingRequiredField(t *testing.T) { 77 defer ConfigTeardown() 78 79 schema := `{ 80 "type": "record", 81 "name": "test", 82 "fields" : [ 83 {"name": "a", "type": "long"}, 84 {"name": "b", "type": "string"} 85 ] 86 }` 87 obj := TestPartialRecord{B: "foo"} 88 buf := &bytes.Buffer{} 89 enc, err := avro.NewEncoder(schema, buf) 90 assert.NoError(t, err) 91 92 err = enc.Encode(obj) 93 94 assert.Error(t, err) 95 } 96 97 func TestEncoder_RecordStructWithDefault(t *testing.T) { 98 defer ConfigTeardown() 99 100 schema := `{ 101 "type": "record", 102 "name": "test", 103 "fields" : [ 104 {"name": "a", "type": "long", "default": 27}, 105 {"name": "b", "type": "string"} 106 ] 107 }` 108 obj := TestPartialRecord{B: "foo"} 109 buf := &bytes.Buffer{} 110 enc, err := avro.NewEncoder(schema, buf) 111 assert.NoError(t, err) 112 113 err = enc.Encode(obj) 114 115 assert.NoError(t, err) 116 assert.Equal(t, []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}, buf.Bytes()) 117 } 118 119 func TestEncoder_RecordStructPartialWithNullDefault(t *testing.T) { 120 defer ConfigTeardown() 121 122 schema := `{ 123 "type": "record", 124 "name": "test", 125 "fields" : [ 126 {"name": "a", "type": ["null", "string"], "default": null}, 127 {"name": "b", "type": "string"} 128 ] 129 }` 130 obj := TestPartialRecord{B: "foo"} 131 buf := &bytes.Buffer{} 132 enc, err := avro.NewEncoder(schema, buf) 133 assert.NoError(t, err) 134 135 err = enc.Encode(obj) 136 137 assert.NoError(t, err) 138 assert.Equal(t, []byte{0x00, 0x06, 0x66, 0x6f, 0x6f}, buf.Bytes()) 139 } 140 141 func TestEncoder_RecordStructWithNullDefault(t *testing.T) { 142 defer ConfigTeardown() 143 144 schema := `{ 145 "type": "record", 146 "name": "test", 147 "fields" : [ 148 {"name": "a", "type": "null", "default": null}, 149 {"name": "b", "type": "string"} 150 ] 151 }` 152 obj := TestPartialRecord{B: "foo"} 153 buf := &bytes.Buffer{} 154 enc, err := avro.NewEncoder(schema, buf) 155 assert.NoError(t, err) 156 157 err = enc.Encode(obj) 158 159 assert.NoError(t, err) 160 assert.Equal(t, []byte{0x06, 0x66, 0x6f, 0x6f}, buf.Bytes()) 161 } 162 163 func TestEncoder_RecordStructFieldError(t *testing.T) { 164 defer ConfigTeardown() 165 166 schema := `{ 167 "type": "record", 168 "name": "test", 169 "fields" : [ 170 {"name": "a", "type": "string"}, 171 {"name": "b", "type": "string"} 172 ] 173 }` 174 obj := TestRecord{A: 27, B: "foo"} 175 buf := &bytes.Buffer{} 176 enc, err := avro.NewEncoder(schema, buf) 177 assert.NoError(t, err) 178 179 err = enc.Encode(obj) 180 181 assert.Error(t, err) 182 } 183 184 func TestEncoder_RecordEmbeddedStruct(t *testing.T) { 185 defer ConfigTeardown() 186 187 schema := `{ 188 "type": "record", 189 "name": "test", 190 "fields" : [ 191 {"name": "a", "type": "long"}, 192 {"name": "b", "type": "string"} 193 ] 194 }` 195 obj := TestEmbeddedRecord{TestEmbed: TestEmbed{A: 27}, B: "foo"} 196 buf := &bytes.Buffer{} 197 enc, err := avro.NewEncoder(schema, buf) 198 assert.NoError(t, err) 199 200 err = enc.Encode(obj) 201 202 assert.NoError(t, err) 203 assert.Equal(t, []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}, buf.Bytes()) 204 } 205 206 func TestEncoder_RecordEmbeddedPtrStruct(t *testing.T) { 207 defer ConfigTeardown() 208 209 schema := `{ 210 "type": "record", 211 "name": "test", 212 "fields" : [ 213 {"name": "a", "type": "long"}, 214 {"name": "b", "type": "string"} 215 ] 216 }` 217 obj := TestEmbeddedPtrRecord{TestEmbed: &TestEmbed{A: 27}, B: "foo"} 218 buf := &bytes.Buffer{} 219 enc, err := avro.NewEncoder(schema, buf) 220 assert.NoError(t, err) 221 222 err = enc.Encode(obj) 223 224 assert.NoError(t, err) 225 assert.Equal(t, []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}, buf.Bytes()) 226 } 227 228 func TestEncoder_RecordEmbeddedPtrStructNull(t *testing.T) { 229 defer ConfigTeardown() 230 231 schema := `{ 232 "type": "record", 233 "name": "test", 234 "fields" : [ 235 {"name": "a", "type": "long"}, 236 {"name": "b", "type": "string"} 237 ] 238 }` 239 obj := TestEmbeddedPtrRecord{B: "foo"} 240 buf := &bytes.Buffer{} 241 enc, err := avro.NewEncoder(schema, buf) 242 assert.NoError(t, err) 243 244 err = enc.Encode(obj) 245 246 assert.Error(t, err) 247 } 248 249 func TestEncoder_RecordEmbeddedIntStruct(t *testing.T) { 250 defer ConfigTeardown() 251 252 schema := `{ 253 "type": "record", 254 "name": "test", 255 "fields" : [ 256 {"name": "a", "type": "long"}, 257 {"name": "b", "type": "string"} 258 ] 259 }` 260 obj := TestEmbeddedIntRecord{TestEmbedInt: 27, B: "foo"} 261 buf := &bytes.Buffer{} 262 enc, err := avro.NewEncoder(schema, buf) 263 assert.NoError(t, err) 264 265 err = enc.Encode(obj) 266 267 assert.Error(t, err) 268 } 269 270 func TestEncoder_RecordUnexportedStruct(t *testing.T) { 271 defer ConfigTeardown() 272 273 schema := `{ 274 "type": "record", 275 "name": "test", 276 "fields" : [ 277 {"name": "a", "type": "long"}, 278 {"name": "b", "type": "string"} 279 ] 280 }` 281 obj := TestUnexportedRecord{A: 27, b: "foo"} 282 buf := &bytes.Buffer{} 283 enc, err := avro.NewEncoder(schema, buf) 284 assert.NoError(t, err) 285 286 err = enc.Encode(obj) 287 288 assert.Error(t, err) 289 } 290 291 func TestEncoder_RecordMap(t *testing.T) { 292 defer ConfigTeardown() 293 294 schema := `{ 295 "type": "record", 296 "name": "test", 297 "fields" : [ 298 {"name": "a", "type": "long"}, 299 {"name": "b", "type": "string"} 300 ] 301 }` 302 obj := map[string]interface{}{"a": int64(27), "b": "foo"} 303 buf := &bytes.Buffer{} 304 enc, err := avro.NewEncoder(schema, buf) 305 assert.NoError(t, err) 306 307 err = enc.Encode(obj) 308 309 assert.NoError(t, err) 310 assert.Equal(t, []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}, buf.Bytes()) 311 } 312 313 func TestEncoder_RecordMapNested(t *testing.T) { 314 defer ConfigTeardown() 315 316 schema := `{ 317 "type": "record", 318 "name": "parent", 319 "fields" : [ 320 {"name": "a", "type": { 321 "type": "record", 322 "name": "test", 323 "fields" : [ 324 {"name": "a", "type": "long"}, 325 {"name": "b", "type": "string"} 326 ]} 327 }, 328 {"name": "b", "type": "string"} 329 ] 330 }` 331 obj := map[string]interface{}{"a": map[string]interface{}{ 332 "a": int64(27), 333 "b": "bar", 334 }, "b": "foo"} 335 buf := &bytes.Buffer{} 336 enc, err := avro.NewEncoder(schema, buf) 337 assert.NoError(t, err) 338 339 err = enc.Encode(obj) 340 341 assert.NoError(t, err) 342 assert.Equal(t, []byte{0x36, 0x6, 0x62, 0x61, 0x72, 0x6, 0x66, 0x6f, 0x6f}, buf.Bytes()) 343 } 344 345 func TestEncoder_RecordMapNilValue(t *testing.T) { 346 defer ConfigTeardown() 347 348 schema := `{ 349 "type": "record", 350 "name": "test", 351 "fields" : [ 352 {"name": "a", "type": "long"}, 353 {"name": "b", "type": "string"} 354 ] 355 }` 356 obj := map[string]interface{}{"a": int64(27), "b": nil} 357 buf := &bytes.Buffer{} 358 enc, err := avro.NewEncoder(schema, buf) 359 assert.NoError(t, err) 360 361 err = enc.Encode(obj) 362 363 assert.Error(t, err) 364 } 365 366 func TestEncoder_RecordMapMissingRequiredField(t *testing.T) { 367 defer ConfigTeardown() 368 369 schema := `{ 370 "type": "record", 371 "name": "test", 372 "fields" : [ 373 {"name": "a", "type": "long"}, 374 {"name": "b", "type": "string"} 375 ] 376 }` 377 obj := map[string]interface{}{"b": "foo"} 378 buf := &bytes.Buffer{} 379 enc, err := avro.NewEncoder(schema, buf) 380 assert.NoError(t, err) 381 382 err = enc.Encode(obj) 383 384 assert.Error(t, err) 385 } 386 387 func TestEncoder_RecordMapWithDefault(t *testing.T) { 388 defer ConfigTeardown() 389 390 schema := `{ 391 "type": "record", 392 "name": "test", 393 "fields" : [ 394 {"name": "a", "type": "long", "default": 27}, 395 {"name": "b", "type": "string"} 396 ] 397 }` 398 obj := map[string]interface{}{"b": "foo"} 399 buf := &bytes.Buffer{} 400 enc, err := avro.NewEncoder(schema, buf) 401 assert.NoError(t, err) 402 403 err = enc.Encode(obj) 404 405 assert.NoError(t, err) 406 assert.Equal(t, []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}, buf.Bytes()) 407 } 408 409 func TestEncoder_RecordMapWithNullDefault(t *testing.T) { 410 defer ConfigTeardown() 411 412 schema := `{ 413 "type": "record", 414 "name": "test", 415 "fields" : [ 416 {"name": "a", "type": "null", "default": null}, 417 {"name": "b", "type": "string"} 418 ] 419 }` 420 obj := map[string]interface{}{"b": "foo"} 421 buf := &bytes.Buffer{} 422 enc, err := avro.NewEncoder(schema, buf) 423 assert.NoError(t, err) 424 425 err = enc.Encode(obj) 426 427 assert.NoError(t, err) 428 assert.Equal(t, []byte{0x06, 0x66, 0x6f, 0x6f}, buf.Bytes()) 429 } 430 431 func TestEncoder_RecordMapWithUnionNullDefault(t *testing.T) { 432 defer ConfigTeardown() 433 434 schema := `{ 435 "type": "record", 436 "name": "test", 437 "fields" : [ 438 {"name": "a", "type": ["null", "string"], "default": null}, 439 {"name": "b", "type": "string"} 440 ] 441 }` 442 obj := map[string]interface{}{"b": "foo"} 443 buf := &bytes.Buffer{} 444 enc, err := avro.NewEncoder(schema, buf) 445 assert.NoError(t, err) 446 447 err = enc.Encode(obj) 448 449 assert.NoError(t, err) 450 assert.Equal(t, []byte{0x00, 0x06, 0x66, 0x6f, 0x6f}, buf.Bytes()) 451 } 452 453 func TestEncoder_RecordMapWithUnionStringDefault(t *testing.T) { 454 defer ConfigTeardown() 455 456 schema := `{ 457 "type": "record", 458 "name": "test", 459 "fields" : [ 460 {"name": "a", "type": ["string", "null"], "default": "test"}, 461 {"name": "b", "type": "string"} 462 ] 463 }` 464 obj := map[string]interface{}{"b": "foo"} 465 buf := &bytes.Buffer{} 466 enc, err := avro.NewEncoder(schema, buf) 467 assert.NoError(t, err) 468 469 err = enc.Encode(obj) 470 471 assert.NoError(t, err) 472 assert.Equal(t, []byte{0x0, 0x8, 0x74, 0x65, 0x73, 0x74, 0x6, 0x66, 0x6f, 0x6f}, buf.Bytes()) 473 } 474 475 func TestEncoder_RecordMapInvalidKeyType(t *testing.T) { 476 defer ConfigTeardown() 477 478 schema := `{ 479 "type": "record", 480 "name": "test", 481 "fields" : [ 482 {"name": "a", "type": "null", "default": null}, 483 {"name": "b", "type": "string"} 484 ] 485 }` 486 obj := map[int]interface{}{1: int64(27), 2: "foo"} 487 buf := &bytes.Buffer{} 488 enc, err := avro.NewEncoder(schema, buf) 489 assert.NoError(t, err) 490 491 err = enc.Encode(obj) 492 493 assert.Error(t, err) 494 } 495 496 func TestEncoder_RecordMapInvalidValueType(t *testing.T) { 497 defer ConfigTeardown() 498 499 schema := `{ 500 "type": "record", 501 "name": "test", 502 "fields" : [ 503 {"name": "a", "type": "null", "default": null}, 504 {"name": "b", "type": "string"} 505 ] 506 }` 507 obj := map[string]string{"a": "test", "b": "foo"} 508 buf := &bytes.Buffer{} 509 enc, err := avro.NewEncoder(schema, buf) 510 assert.NoError(t, err) 511 512 err = enc.Encode(obj) 513 514 assert.Error(t, err) 515 } 516 517 func TestEncoder_RefStruct(t *testing.T) { 518 defer ConfigTeardown() 519 520 schema := `{ 521 "type": "record", 522 "name": "parent", 523 "fields" : [ 524 {"name": "a", "type": { 525 "type": "record", 526 "name": "test", 527 "fields" : [ 528 {"name": "a", "type": "long"}, 529 {"name": "b", "type": "string"} 530 ]} 531 }, 532 {"name": "b", "type": "test"} 533 ] 534 }` 535 obj := TestNestedRecord{ 536 A: TestRecord{A: 27, B: "foo"}, 537 B: TestRecord{A: 27, B: "foo"}, 538 } 539 buf := &bytes.Buffer{} 540 enc, err := avro.NewEncoder(schema, buf) 541 assert.NoError(t, err) 542 543 err = enc.Encode(obj) 544 545 assert.NoError(t, err) 546 assert.Equal(t, []byte{0x36, 0x06, 0x66, 0x6f, 0x6f, 0x36, 0x06, 0x66, 0x6f, 0x6f}, buf.Bytes()) 547 }