From 3fc81b66c69359a5c96c95797914e8eaf56595cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Wed, 31 Jul 2024 20:13:11 +0200 Subject: [PATCH] Register Go int as long in type resolver (#423) --- encoder_union_test.go | 133 ++++++++++++++++++++++++++++++++++++++++++ resolver.go | 1 + 2 files changed, 134 insertions(+) diff --git a/encoder_union_test.go b/encoder_union_test.go index ca9327ad..72c9d6e6 100644 --- a/encoder_union_test.go +++ b/encoder_union_test.go @@ -550,3 +550,136 @@ func TestEncoder_UnionInterfaceNotInSchema(t *testing.T) { assert.Error(t, err) } + +func TestEncoder_UnionResolver(t *testing.T) { + testCases := []struct { + name string + schema string + value any + want []byte + }{ + { + name: "Go int8 as Avro int", + schema: `["null","int"]`, + value: int8(27), + want: []byte{0x2, 0x36}, + }, + { + name: "Go int16 as Avro int", + schema: `["null","int"]`, + value: int16(27), + want: []byte{0x2, 0x36}, + }, + { + name: "Go int32 as Avro int", + schema: `["null","int"]`, + value: int32(27), + want: []byte{0x2, 0x36}, + }, + { + name: "Go int as Avro int", + schema: `["null","int"]`, + value: int(27), + want: []byte{0x2, 0x36}, + }, + { + name: "Go int as Avro long", + schema: `["null","long"]`, + value: int(2147483648), + want: []byte{0x2, 0x80, 0x80, 0x80, 0x80, 0x10}, + }, + { + name: "Go int64 as Avro long", + schema: `["null","long"]`, + value: int64(2147483648), + want: []byte{0x2, 0x80, 0x80, 0x80, 0x80, 0x10}, + }, + { + name: "Go float32 as Avro float", + schema: `["null","float"]`, + value: float32(1.15), + want: []byte{0x2, 0x33, 0x33, 0x93, 0x3F}, + }, + { + name: "Go float64 as Avro float", + schema: `["null","double"]`, + value: float64(1.15), + want: []byte{0x2, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xF2, 0x3F}, + }, + { + name: "Go string as Avro string", + schema: `["null","string"]`, + value: "foo", + want: []byte{0x2, 0x06, 0x66, 0x6F, 0x6F}, + }, + { + name: "Go []byte as Avro bytes", + schema: `["null","bytes"]`, + value: []byte{0xEC, 0xAB, 0x44, 0x00}, + want: []byte{0x2, 0x08, 0xEC, 0xAB, 0x44, 0x00}, + }, + { + name: "Go bool as Avro boolean", + schema: `["null","boolean"]`, + value: true, + want: []byte{0x2, 0x01}, + }, + { + name: "Go time.Time as Avro int.date", + schema: `["null",{"type":"int","logicalType":"date"}]`, + value: time.Date(2920, 1, 2, 0, 0, 0, 0, time.UTC), + want: []byte{0x2, 0xCA, 0xAD, 0x2A}, + }, + { + name: "Go time.Duration as Avro int.time-millis", + schema: `["null",{"type":"int","logicalType":"time-millis"}]`, + value: 123456789 * time.Millisecond, + want: []byte{0x2, 0xAA, 0xB4, 0xDE, 0x75}, + }, + { + name: "Go time.Time as Avro long.timestamp-millis", + schema: `["null",{"type":"long","logicalType":"timestamp-millis"}]`, + value: time.Date(2020, 1, 2, 3, 4, 5, 6, time.UTC), + want: []byte{0x2, 0x90, 0xB2, 0xAE, 0xC3, 0xEC, 0x5B}, + }, + { + name: "Go time.Time as Avro long.timestamp-micros", + schema: `["null",{"type":"long","logicalType":"timestamp-micros"}]`, + value: time.Date(2020, 1, 2, 3, 4, 5, 6, time.UTC), + want: []byte{0x2, 0x80, 0xCD, 0xB7, 0xA2, 0xEE, 0xC7, 0xCD, 0x05}, + }, + { + name: "Go time.Duration as Avro long.time-micros", + schema: `["null",{"type":"long","logicalType":"time-micros"}]`, + value: 123456789123 * time.Microsecond, + want: []byte{0x2, 0x86, 0xEA, 0xC8, 0xE9, 0x97, 0x07}, + }, + { + name: "Go big.Rat as Avro bytes.decimal", + schema: `["null",{"type":"bytes","logicalType":"decimal","precision":4,"scale":2}]`, + value: big.NewRat(1734, 5), + want: []byte{0x2, 0x6, 0x00, 0x87, 0x78}, + }, + { + name: "Go string as Avro string.uuid", + schema: `["null",{"type":"string","logicalType":"uuid"}]`, + value: "f36e589a-3a52-492b-b95c-dad345e8d2ac", + want: []byte{0x2, 0x48, 0x66, 0x33, 0x36, 0x65, 0x35, 0x38, 0x39, 0x61, 0x2d, 0x33, 0x61, 0x35, 0x32, 0x2d, 0x34, 0x39, 0x32, 0x62, 0x2d, 0x62, 0x39, 0x35, 0x63, 0x2d, 0x64, 0x61, 0x64, 0x33, 0x34, 0x35, 0x65, 0x38, 0x64, 0x32, 0x61, 0x63}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + defer ConfigTeardown() + + buf := bytes.NewBuffer([]byte{}) + enc, err := avro.NewEncoder(tc.schema, buf) + require.NoError(t, err) + + err = enc.Encode(tc.value) + + require.NoError(t, err) + assert.Equal(t, tc.want, buf.Bytes()) + }) + } +} diff --git a/resolver.go b/resolver.go index aabf4663..c1b6ab65 100644 --- a/resolver.go +++ b/resolver.go @@ -26,6 +26,7 @@ func NewTypeResolver() *TypeResolver { r.Register(string(Int), int16(0)) r.Register(string(Int), int32(0)) r.Register(string(Int), int(0)) + r.Register(string(Long), int(0)) r.Register(string(Long), int64(0)) r.Register(string(Float), float32(0)) r.Register(string(Double), float64(0))