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

     1  package avro_test
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  
     7  	"github.com/hamba/avro/v2"
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestDecoder_RecordStruct(t *testing.T) {
    13  	defer ConfigTeardown()
    14  
    15  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}
    16  	schema := `{
    17  	"type": "record",
    18  	"name": "test",
    19  	"fields" : [
    20  		{"name": "a", "type": "long"},
    21  	    {"name": "b", "type": "string"}
    22  	]
    23  }`
    24  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
    25  	require.NoError(t, err)
    26  
    27  	var got TestRecord
    28  	err = dec.Decode(&got)
    29  
    30  	require.NoError(t, err)
    31  	assert.Equal(t, TestRecord{A: 27, B: "foo"}, got)
    32  }
    33  
    34  func TestDecoder_RecordStructPtr(t *testing.T) {
    35  	defer ConfigTeardown()
    36  
    37  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}
    38  	schema := `{
    39  	"type": "record",
    40  	"name": "test",
    41  	"fields" : [
    42  		{"name": "a", "type": "long"},
    43  	    {"name": "b", "type": "string"}
    44  	]
    45  }`
    46  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
    47  	require.NoError(t, err)
    48  
    49  	got := &TestRecord{}
    50  	err = dec.Decode(&got)
    51  
    52  	require.NoError(t, err)
    53  	assert.Equal(t, &TestRecord{A: 27, B: "foo"}, got)
    54  }
    55  
    56  func TestDecoder_RecordStructPtrNil(t *testing.T) {
    57  	defer ConfigTeardown()
    58  
    59  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}
    60  	schema := `{
    61  	"type": "record",
    62  	"name": "test",
    63  	"fields" : [
    64  		{"name": "a", "type": "long"},
    65  	    {"name": "b", "type": "string"}
    66  	]
    67  }`
    68  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
    69  	require.NoError(t, err)
    70  
    71  	var got *TestRecord
    72  	err = dec.Decode(&got)
    73  
    74  	require.NoError(t, err)
    75  	assert.Equal(t, &TestRecord{A: 27, B: "foo"}, got)
    76  }
    77  
    78  func TestDecoder_RecordStructWithFieldAlias(t *testing.T) {
    79  	defer ConfigTeardown()
    80  
    81  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}
    82  	schema := `{
    83  	"type": "record",
    84  	"name": "test",
    85  	"fields" : [
    86  		{"name": "c", "aliases": ["a"], "type": "long"},
    87  	    {"name": "b", "type": "string"}
    88  	]
    89  }`
    90  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
    91  	assert.NoError(t, err)
    92  
    93  	var got TestRecord
    94  	err = dec.Decode(&got)
    95  
    96  	assert.NoError(t, err)
    97  	assert.Equal(t, TestRecord{A: 27, B: "foo"}, got)
    98  }
    99  
   100  func TestDecoder_RecordPartialStruct(t *testing.T) {
   101  	defer ConfigTeardown()
   102  
   103  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}
   104  	schema := `{
   105  	"type": "record",
   106  	"name": "test",
   107  	"fields" : [
   108  		{"name": "a", "type": "long"},
   109  	    {"name": "b", "type": "string"}
   110  	]
   111  }`
   112  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   113  	require.NoError(t, err)
   114  
   115  	var got TestPartialRecord
   116  	err = dec.Decode(&got)
   117  
   118  	require.NoError(t, err)
   119  	assert.Equal(t, TestPartialRecord{B: "foo"}, got)
   120  }
   121  
   122  func TestDecoder_RecordStructInvalidData(t *testing.T) {
   123  	defer ConfigTeardown()
   124  
   125  	data := []byte{0xE2, 0xA2, 0xF3, 0xAD, 0xAD, 0xAD, 0xE2, 0xA2, 0xF3, 0xAD, 0xAD, 0x06, 0x66, 0x6f, 0x6f}
   126  	schema := `{
   127  	"type": "record",
   128  	"name": "test",
   129  	"fields" : [
   130  		{"name": "a", "type": "long"},
   131  	    {"name": "b", "type": "string"}
   132  	]
   133  }`
   134  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   135  	require.NoError(t, err)
   136  
   137  	var got TestRecord
   138  	err = dec.Decode(&got)
   139  
   140  	assert.Error(t, err)
   141  }
   142  
   143  func TestDecoder_RecordEmbeddedStruct(t *testing.T) {
   144  	defer ConfigTeardown()
   145  
   146  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f, 0x06, 0x62, 0x61, 0x72}
   147  	schema := `{
   148  	"type": "record",
   149  	"name": "test",
   150  	"fields" : [
   151  		{"name": "a", "type": "long"},
   152  	    {"name": "b", "type": "string"},
   153  	    {"name": "c", "type": "string"}
   154  	]
   155  }`
   156  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   157  	require.NoError(t, err)
   158  
   159  	var got TestEmbeddedRecord
   160  	err = dec.Decode(&got)
   161  
   162  	require.NoError(t, err)
   163  	assert.Equal(t, TestEmbeddedRecord{TestEmbed: TestEmbed{A: 27, B: "foo"}, C: "bar"}, got)
   164  }
   165  
   166  func TestDecoder_RecordEmbeddedPtrStruct(t *testing.T) {
   167  	defer ConfigTeardown()
   168  
   169  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f, 0x06, 0x62, 0x61, 0x72}
   170  	schema := `{
   171  	"type": "record",
   172  	"name": "test",
   173  	"fields" : [
   174  		{"name": "a", "type": "long"},
   175  	    {"name": "b", "type": "string"},
   176  	    {"name": "c", "type": "string"}
   177  	]
   178  }`
   179  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   180  	require.NoError(t, err)
   181  
   182  	var got TestEmbeddedPtrRecord
   183  	err = dec.Decode(&got)
   184  
   185  	require.NoError(t, err)
   186  	assert.Equal(t, TestEmbeddedPtrRecord{TestEmbed: &TestEmbed{A: 27, B: "foo"}, C: "bar"}, got)
   187  }
   188  
   189  func TestDecoder_RecordEmbeddedPtrStructNew(t *testing.T) {
   190  	defer ConfigTeardown()
   191  
   192  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f, 0x06, 0x62, 0x61, 0x72}
   193  	schema := `{
   194  	"type": "record",
   195  	"name": "test",
   196  	"fields" : [
   197  		{"name": "a", "type": "long"},
   198  	    {"name": "b", "type": "string"},
   199  	    {"name": "c", "type": "string"}
   200  	]
   201  }`
   202  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   203  	require.NoError(t, err)
   204  
   205  	var got TestEmbeddedPtrRecord
   206  	got.C = "nonzero" // non-zero value here triggers bug in allocating TestEmbed
   207  	err = dec.Decode(&got)
   208  
   209  	require.NoError(t, err)
   210  	assert.Equal(t, TestEmbeddedPtrRecord{TestEmbed: &TestEmbed{A: 27, B: "foo"}, C: "bar"}, got)
   211  }
   212  
   213  func TestDecoder_RecordEmbeddedIntStruct(t *testing.T) {
   214  	defer ConfigTeardown()
   215  
   216  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f, 0x06, 0x62, 0x61, 0x72}
   217  	schema := `{
   218  	"type": "record",
   219  	"name": "test",
   220  	"fields" : [
   221  		{"name": "a", "type": "long"},
   222  	    {"name": "b", "type": "string"},
   223  	    {"name": "c", "type": "string"}
   224  	]
   225  }`
   226  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   227  	require.NoError(t, err)
   228  
   229  	var got TestEmbeddedIntRecord
   230  	err = dec.Decode(&got)
   231  
   232  	require.NoError(t, err)
   233  	assert.Equal(t, TestEmbeddedIntRecord{B: "foo"}, got)
   234  }
   235  
   236  func TestDecoder_RecordMap(t *testing.T) {
   237  	defer ConfigTeardown()
   238  
   239  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}
   240  	schema := `{
   241  	"type": "record",
   242  	"name": "test",
   243  	"fields" : [
   244  		{"name": "a", "type": "long"},
   245  	    {"name": "b", "type": "string"}
   246  	]
   247  }`
   248  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   249  	require.NoError(t, err)
   250  
   251  	var got map[string]any
   252  	err = dec.Decode(&got)
   253  
   254  	require.NoError(t, err)
   255  	assert.Equal(t, map[string]any{"a": int64(27), "b": "foo"}, got)
   256  }
   257  
   258  func TestDecoder_RecordMapInvalidKey(t *testing.T) {
   259  	defer ConfigTeardown()
   260  
   261  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}
   262  	schema := `{
   263  	"type": "record",
   264  	"name": "test",
   265  	"fields" : [
   266  		{"name": "a", "type": "long"},
   267  	    {"name": "b", "type": "string"}
   268  	]
   269  }`
   270  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   271  	require.NoError(t, err)
   272  
   273  	var got map[int]any
   274  	err = dec.Decode(&got)
   275  
   276  	assert.Error(t, err)
   277  }
   278  
   279  func TestDecoder_RecordMapInvalidElem(t *testing.T) {
   280  	defer ConfigTeardown()
   281  
   282  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}
   283  	schema := `{
   284  	"type": "record",
   285  	"name": "test",
   286  	"fields" : [
   287  		{"name": "a", "type": "long"},
   288  	    {"name": "b", "type": "string"}
   289  	]
   290  }`
   291  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   292  	require.NoError(t, err)
   293  
   294  	var got map[string]string
   295  	err = dec.Decode(&got)
   296  
   297  	assert.Error(t, err)
   298  }
   299  
   300  func TestDecoder_RecordMapInvalidData(t *testing.T) {
   301  	defer ConfigTeardown()
   302  
   303  	data := []byte{0xE2, 0xA2, 0xF3, 0xAD, 0xAD, 0xAD, 0xE2, 0xA2, 0xF3, 0xAD, 0xAD, 0x06, 0x66, 0x6f, 0x6f}
   304  	schema := `{
   305  	"type": "record",
   306  	"name": "test",
   307  	"fields" : [
   308  		{"name": "a", "type": "long"},
   309  	    {"name": "b", "type": "string"}
   310  	]
   311  }`
   312  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   313  	require.NoError(t, err)
   314  
   315  	var got map[string]any
   316  	err = dec.Decode(&got)
   317  
   318  	assert.Error(t, err)
   319  }
   320  
   321  func TestDecoder_RecordInterface(t *testing.T) {
   322  	defer ConfigTeardown()
   323  
   324  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}
   325  	schema := `{
   326  	"type": "record",
   327  	"name": "test",
   328  	"fields" : [
   329  		{"name": "a", "type": "long"},
   330  	    {"name": "b", "type": "string"}
   331  	]
   332  }`
   333  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   334  	require.NoError(t, err)
   335  
   336  	var got TestInterface = &TestRecord{}
   337  	err = dec.Decode(&got)
   338  
   339  	require.NoError(t, err)
   340  	assert.Equal(t, &TestRecord{A: 27, B: "foo"}, got)
   341  }
   342  
   343  func TestDecoder_RecordEmptyInterface(t *testing.T) {
   344  	defer ConfigTeardown()
   345  
   346  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f}
   347  	schema := `{
   348  	"type": "record",
   349  	"name": "test",
   350  	"fields" : [
   351  		{"name": "a", "type": "long"},
   352  	    {"name": "b", "type": "string"}
   353  	]
   354  }`
   355  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   356  	require.NoError(t, err)
   357  
   358  	var got TestInterface
   359  	err = dec.Decode(&got)
   360  
   361  	assert.Error(t, err)
   362  }
   363  
   364  func TestDecoder_RefStruct(t *testing.T) {
   365  	defer ConfigTeardown()
   366  
   367  	data := []byte{0x36, 0x06, 0x66, 0x6f, 0x6f, 0x36, 0x06, 0x66, 0x6f, 0x6f}
   368  	schema := `{
   369  	"type": "record",
   370  	"name": "parent",
   371  	"fields" : [
   372  		{"name": "a", "type": {
   373  			"type": "record",
   374  			"name": "test",
   375  			"fields" : [
   376  				{"name": "a", "type": "long"},
   377  	    		{"name": "b", "type": "string"}
   378  			]}
   379  		},
   380  	    {"name": "b", "type": "test"}
   381  	]
   382  }`
   383  	dec, err := avro.NewDecoder(schema, bytes.NewReader(data))
   384  	require.NoError(t, err)
   385  
   386  	var got TestNestedRecord
   387  	err = dec.Decode(&got)
   388  
   389  	want := TestNestedRecord{
   390  		A: TestRecord{A: 27, B: "foo"},
   391  		B: TestRecord{A: 27, B: "foo"},
   392  	}
   393  	require.NoError(t, err)
   394  	assert.Equal(t, want, got)
   395  }