github.com/hamba/avro/v2@v2.22.1-0.20240518180522-aff3955acf7d/encoder_map_test.go (about)

     1  package avro_test
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"strconv"
     7  	"testing"
     8  
     9  	"github.com/hamba/avro/v2"
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestEncoder_MapInvalidType(t *testing.T) {
    15  	defer ConfigTeardown()
    16  
    17  	schema := `{"type":"map", "values": "string"}`
    18  	buf := bytes.NewBuffer([]byte{})
    19  	enc, err := avro.NewEncoder(schema, buf)
    20  	require.NoError(t, err)
    21  
    22  	err = enc.Encode("test")
    23  
    24  	assert.Error(t, err)
    25  }
    26  
    27  func TestEncoder_Map(t *testing.T) {
    28  	defer ConfigTeardown()
    29  
    30  	schema := `{"type":"map", "values": "string"}`
    31  	buf := bytes.NewBuffer([]byte{})
    32  	enc, err := avro.NewEncoder(schema, buf)
    33  	require.NoError(t, err)
    34  
    35  	err = enc.Encode(map[string]string{})
    36  
    37  	require.NoError(t, err)
    38  	assert.Equal(t, []byte{0x00}, buf.Bytes())
    39  }
    40  
    41  func TestEncoder_MapEmpty(t *testing.T) {
    42  	defer ConfigTeardown()
    43  
    44  	schema := `{"type":"map", "values": "string"}`
    45  	buf := bytes.NewBuffer([]byte{})
    46  	enc, err := avro.NewEncoder(schema, buf)
    47  	require.NoError(t, err)
    48  
    49  	err = enc.Encode(map[string]string{"foo": "foo"})
    50  
    51  	require.NoError(t, err)
    52  	assert.Equal(t, []byte{0x01, 0x10, 0x06, 0x66, 0x6F, 0x6F, 0x06, 0x66, 0x6F, 0x6F, 0x00}, buf.Bytes())
    53  }
    54  
    55  func TestEncoder_MapOfStruct(t *testing.T) {
    56  	defer ConfigTeardown()
    57  
    58  	schema := `{"type":"map", "values": {"type": "record", "name": "test", "fields" : [{"name": "a", "type": "long"}, {"name": "b", "type": "string"}]}}`
    59  	buf := bytes.NewBuffer([]byte{})
    60  	enc, err := avro.NewEncoder(schema, buf)
    61  	require.NoError(t, err)
    62  
    63  	err = enc.Encode(map[string]TestRecord{"foo": {A: 27, B: "foo"}})
    64  
    65  	require.NoError(t, err)
    66  	assert.Equal(t, []byte{0x01, 0x12, 0x06, 0x66, 0x6F, 0x6F, 0x36, 0x06, 0x66, 0x6f, 0x6f, 0x0}, buf.Bytes())
    67  }
    68  
    69  func TestEncoder_MapInvalidKeyType(t *testing.T) {
    70  	defer ConfigTeardown()
    71  
    72  	schema := `{"type":"map", "values": "string"}`
    73  	buf := bytes.NewBuffer([]byte{})
    74  	enc, err := avro.NewEncoder(schema, buf)
    75  	require.NoError(t, err)
    76  
    77  	err = enc.Encode(map[int]string{1: "foo"})
    78  
    79  	assert.Error(t, err)
    80  }
    81  
    82  func TestEncoder_MapError(t *testing.T) {
    83  	defer ConfigTeardown()
    84  
    85  	schema := `{"type":"map", "values": "string"}`
    86  	buf := bytes.NewBuffer([]byte{})
    87  	enc, err := avro.NewEncoder(schema, buf)
    88  	require.NoError(t, err)
    89  
    90  	err = enc.Encode(map[string]int{"foo": 1})
    91  
    92  	assert.Error(t, err)
    93  }
    94  
    95  func TestEncoder_MapWithMoreThanBlockLengthKeys(t *testing.T) {
    96  	avro.DefaultConfig = avro.Config{
    97  		TagKey:               "avro",
    98  		BlockLength:          1,
    99  		UnionResolutionError: true,
   100  	}.Freeze()
   101  
   102  	schema := `{"type":"map", "values": "int"}`
   103  	buf := bytes.NewBuffer([]byte{})
   104  	enc, err := avro.NewEncoder(schema, buf)
   105  	require.NoError(t, err)
   106  
   107  	err = enc.Encode(map[string]int{"foo": 1, "bar": 2})
   108  
   109  	require.NoError(t, err)
   110  	assert.Condition(t, func() bool {
   111  		// {"foo": 1, "bar": 2}
   112  		foobar := bytes.Equal([]byte{0x01, 0x0a, 0x06, 0x66, 0x6F, 0x6F, 0x02, 0x01, 0x0a, 0x06, 0x62, 0x61, 0x72, 0x04, 0x0}, buf.Bytes())
   113  		// {"bar": 2, "foo": 1}
   114  		barfoo := bytes.Equal([]byte{0x01, 0x0a, 0x06, 0x62, 0x61, 0x72, 0x04, 0x01, 0x0a, 0x06, 0x66, 0x6F, 0x6F, 0x02, 0x0}, buf.Bytes())
   115  		return (foobar || barfoo)
   116  	})
   117  }
   118  
   119  type textMarshallerInt int
   120  
   121  func (t textMarshallerInt) MarshalText() (text []byte, err error) {
   122  	return []byte(strconv.Itoa(int(t))), nil
   123  }
   124  
   125  type textMarshallerError int
   126  
   127  func (t textMarshallerError) MarshalText() (text []byte, err error) {
   128  	return nil, errors.New("test")
   129  }
   130  
   131  func TestEncoder_MapMarshaller(t *testing.T) {
   132  	defer ConfigTeardown()
   133  
   134  	schema := `{"type":"map", "values": "string"}`
   135  	buf := bytes.NewBuffer([]byte{})
   136  	enc, err := avro.NewEncoder(schema, buf)
   137  	require.NoError(t, err)
   138  
   139  	err = enc.Encode(map[textMarshallerInt]string{
   140  		1: "test",
   141  	})
   142  
   143  	require.NoError(t, err)
   144  	want := []byte{0x1, 0xe, 0x2, 0x31, 0x8, 0x74, 0x65, 0x73, 0x74, 0x0}
   145  	assert.Equal(t, want, buf.Bytes())
   146  }
   147  
   148  func TestEncoder_MapMarshallerNil(t *testing.T) {
   149  	defer ConfigTeardown()
   150  
   151  	schema := `{"type":"map", "values": "string"}`
   152  	buf := bytes.NewBuffer([]byte{})
   153  	enc, err := avro.NewEncoder(schema, buf)
   154  	require.NoError(t, err)
   155  
   156  	err = enc.Encode(map[*textMarshallerError]int{
   157  		nil: 1,
   158  	})
   159  
   160  	require.Error(t, err)
   161  }
   162  
   163  func TestEncoder_MapMarshallerKeyError(t *testing.T) {
   164  	defer ConfigTeardown()
   165  
   166  	schema := `{"type":"map", "values": "string"}`
   167  	buf := bytes.NewBuffer([]byte{})
   168  	enc, err := avro.NewEncoder(schema, buf)
   169  	require.NoError(t, err)
   170  
   171  	err = enc.Encode(map[textMarshallerError]int{
   172  		1: 1,
   173  	})
   174  
   175  	require.Error(t, err)
   176  }
   177  
   178  func TestEncoder_MapMarshallerError(t *testing.T) {
   179  	defer ConfigTeardown()
   180  
   181  	schema := `{"type":"map", "values": "string"}`
   182  	buf := bytes.NewBuffer([]byte{})
   183  	enc, err := avro.NewEncoder(schema, buf)
   184  	require.NoError(t, err)
   185  
   186  	err = enc.Encode(map[textMarshallerInt]int{
   187  		1: 1,
   188  	})
   189  
   190  	require.Error(t, err)
   191  }