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

     1  package avro_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"strconv"
     6  	"testing"
     7  
     8  	"github.com/hamba/avro/v2"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func TestSchema_JSON(t *testing.T) {
    14  	tests := []struct {
    15  		input string
    16  		json  string
    17  	}{
    18  		{
    19  			input: `"null"`,
    20  			json:  `"null"`,
    21  		},
    22  		{
    23  			input: `{"type":"null"}`,
    24  			json:  `"null"`,
    25  		},
    26  		{
    27  			input: `"boolean"`,
    28  			json:  `"boolean"`,
    29  		},
    30  		{
    31  			input: `{"type":"boolean"}`,
    32  			json:  `"boolean"`,
    33  		},
    34  		{
    35  			input: `"int"`,
    36  			json:  `"int"`,
    37  		},
    38  		{
    39  			input: `{"type":"int"}`,
    40  			json:  `"int"`,
    41  		},
    42  		{
    43  			input: `{"type":"int","logicalType":"date"}`,
    44  			json:  `{"type":"int","logicalType":"date"}`,
    45  		},
    46  		{
    47  			input: `{"type":"int","logicalType":"time-millis"}`,
    48  			json:  `{"type":"int","logicalType":"time-millis"}`,
    49  		},
    50  		{
    51  			input: `{"type":"int"}`,
    52  			json:  `"int"`,
    53  		},
    54  		{
    55  			input: `"long"`,
    56  			json:  `"long"`,
    57  		},
    58  		{
    59  			input: `{"type":"long"}`,
    60  			json:  `"long"`,
    61  		},
    62  		{
    63  			input: `{"property-b": "value-bar", "type":"long", "property-a": "value-foo"}`,
    64  			json:  `{"type":"long","property-a":"value-foo","property-b":"value-bar"}`,
    65  		},
    66  		{
    67  			input: `{"type":"long","logicalType":"time-micros"}`,
    68  			json:  `{"type":"long","logicalType":"time-micros"}`,
    69  		},
    70  		{
    71  			input: `{"type":"long","logicalType":"timestamp-millis"}`,
    72  			json:  `{"type":"long","logicalType":"timestamp-millis"}`,
    73  		},
    74  		{
    75  			input: `{"type":"long","logicalType":"timestamp-millis"}`,
    76  			json:  `{"type":"long","logicalType":"timestamp-millis"}`,
    77  		},
    78  		{
    79  			input: `"float"`,
    80  			json:  `"float"`,
    81  		},
    82  		{
    83  			input: `{"type":"float"}`,
    84  			json:  `"float"`,
    85  		},
    86  		{
    87  			input: `"double"`,
    88  			json:  `"double"`,
    89  		},
    90  		{
    91  			input: `{"type":"double"}`,
    92  			json:  `"double"`,
    93  		},
    94  		{
    95  			input: `"bytes"`,
    96  			json:  `"bytes"`,
    97  		},
    98  		{
    99  			input: `{"type":"bytes"}`,
   100  			json:  `"bytes"`,
   101  		},
   102  		{
   103  			input: `{"type":"bytes","logicalType":"decimal","precision":4,"scale":2}`,
   104  			json:  `{"type":"bytes","logicalType":"decimal","precision":4,"scale":2}`,
   105  		},
   106  		{
   107  			input: `{"type":"bytes","logicalType":"decimal","precision":4,"scale":0}`,
   108  			json:  `{"type":"bytes","logicalType":"decimal","precision":4}`,
   109  		},
   110  		{
   111  			input: `"string"`,
   112  			json:  `"string"`,
   113  		},
   114  		{
   115  			input: `{"type":"string"}`,
   116  			json:  `"string"`,
   117  		},
   118  		{
   119  			input: `{"type":"string","logicalType":"uuid"}`,
   120  			json:  `{"type":"string","logicalType":"uuid"}`,
   121  		},
   122  		{
   123  			input: `[  ]`,
   124  			json:  `[]`,
   125  		},
   126  		{
   127  			input: `[ "int"  ]`,
   128  			json:  `["int"]`,
   129  		},
   130  		{
   131  			input: `[ "int" , {"type":"boolean"} ]`,
   132  			json:  `["int","boolean"]`,
   133  		},
   134  		{
   135  			input: `{"fields":[], "type":"error", "name":"foo"}`,
   136  			json:  `{"name":"foo","type":"error","fields":[]}`,
   137  		},
   138  		{
   139  			input: `{"fields":[], "type":"record", "name":"foo"}`,
   140  			json:  `{"name":"foo","type":"record","fields":[]}`,
   141  		},
   142  		{
   143  			input: `{"fields":[], "type":"record", "name":"foo", "namespace":"x.y"}`,
   144  			json:  `{"name":"x.y.foo","type":"record","fields":[]}`,
   145  		},
   146  		{
   147  			input: `{"fields":[], "type":"record", "name":"a.b.foo", "namespace":"x.y"}`,
   148  			json:  `{"name":"a.b.foo","type":"record","fields":[]}`,
   149  		},
   150  		{
   151  			input: `{"fields":[], "type":"record", "name":"foo", "doc":"Useful info"}`,
   152  			json:  `{"name":"foo","doc":"Useful info","type":"record","fields":[]}`,
   153  		},
   154  		{
   155  			input: `{"fields":[], "type":"record", "name":"foo", "aliases":["foo","bar"]}`,
   156  			json:  `{"name":"foo","aliases":["foo","bar"],"type":"record","fields":[]}`,
   157  		},
   158  		{
   159  			input: `{"fields":[], "type":"record", "name":"foo", "doc":"foo", "aliases":["foo","bar"]}`,
   160  			json:  `{"name":"foo","aliases":["foo","bar"],"doc":"foo","type":"record","fields":[]}`,
   161  		},
   162  		{
   163  			input: `{"fields":[], "property-foo": "value-bar", "type":"record", "name":"foo", "doc":"foo", "aliases":["foo","bar"]}`,
   164  			json:  `{"name":"foo","aliases":["foo","bar"],"doc":"foo","type":"record","fields":[],"property-foo":"value-bar"}`,
   165  		},
   166  		{
   167  			input: `{"fields":[{"type":{"type":"boolean"}, "name":"f1"}], "type":"record", "name":"foo"}`,
   168  			json:  `{"name":"foo","type":"record","fields":[{"name":"f1","type":"boolean"}]}`,
   169  		},
   170  		{
   171  			input: `
   172  { "fields":[{"type":"boolean", "aliases":["foo"], "name":"f1", "default":true},
   173             {"order":"descending","name":"f2","doc":"Hello","type":"int"}],
   174   "type":"record", "name":"foo"
   175  }`,
   176  			json: `{"name":"foo","type":"record","fields":[{"name":"f1","aliases":["foo"],"type":"boolean","default":true},{"name":"f2","doc":"Hello","type":"int","order":"descending"}]}`,
   177  		},
   178  		{
   179  			input: `{"type":"enum", "name":"foo", "symbols":["A1"]}`,
   180  			json:  `{"name":"foo","type":"enum","symbols":["A1"]}`,
   181  		},
   182  		{
   183  			input: `{"namespace":"x.y.z", "type":"enum", "name":"foo", "doc":"foo bar", "symbols":["A1", "A2"]}`,
   184  			json:  `{"name":"x.y.z.foo","doc":"foo bar","type":"enum","symbols":["A1","A2"]}`,
   185  		},
   186  		{
   187  			input: `{"name":"foo","type":"fixed","size":15}`,
   188  			json:  `{"name":"foo","type":"fixed","size":15}`,
   189  		},
   190  		{
   191  			input: `{"name":"foo","type":"fixed","logicalType":"duration","size":12}`,
   192  			json:  `{"name":"foo","type":"fixed","size":12,"logicalType":"duration"}`,
   193  		},
   194  		{
   195  			input: `{"name":"foo","type":"fixed","logicalType":"decimal","size":12,"precision":4,"scale":2}`,
   196  			json:  `{"name":"foo","type":"fixed","size":12,"logicalType":"decimal","precision":4,"scale":2}`,
   197  		},
   198  		{
   199  			input: `{"name":"foo","type":"fixed","logicalType":"decimal","size":12,"precision":4,"scale":0}`,
   200  			json:  `{"name":"foo","type":"fixed","size":12,"logicalType":"decimal","precision":4}`,
   201  		},
   202  		{
   203  			input: `{"namespace":"x.y.z", "type":"fixed", "name":"foo", "size":32}`,
   204  			json:  `{"name":"x.y.z.foo","type":"fixed","size":32}`,
   205  		},
   206  		{
   207  			input: `{ "items":{"type":"null"}, "type":"array"}`,
   208  			json:  `{"type":"array","items":"null"}`,
   209  		},
   210  		{
   211  			input: `{ "values":"string", "type":"map"}`,
   212  			json:  `{"type":"map","values":"string"}`,
   213  		},
   214  		{
   215  			input: `
   216  
   217   {"name":"PigValue","type":"record",
   218    "fields":[{"name":"value", "type":["null", "int", "long", "PigValue"]}]}
   219  `,
   220  			json: `{"name":"PigValue","type":"record","fields":[{"name":"value","type":["null","int","long","PigValue"]}]}`,
   221  		},
   222  		{
   223  			input: `{
   224  				"type":"record",
   225  				"namespace": "org.hamba.avro",
   226  				"name":"X",
   227    				"fields":[
   228  					{"name":"value", "type":{
   229  						"type":"record",
   230  						"name":"Y",
   231  						"fields":[
   232  							{"name":"value", "type":"string"}
   233  						]
   234  					}}
   235  				]
   236  			}`,
   237  			json: `{"name":"org.hamba.avro.X","type":"record","fields":[{"name":"value","type":{"name":"org.hamba.avro.Y","type":"record","fields":[{"name":"value","type":"string"}]}}]}`,
   238  		},
   239  		{
   240  			input: `{
   241  				"type":"record",
   242  				"namespace": "org.hamba.avro",
   243  				"name":"X",
   244    				"fields":[
   245  					{"name":"value", "type":{
   246  						"type":"enum",
   247  						"name":"Y",
   248  						"symbols":["TEST"]
   249  					}}
   250  				]
   251  			}`,
   252  			json: `{"name":"org.hamba.avro.X","type":"record","fields":[{"name":"value","type":{"name":"org.hamba.avro.Y","type":"enum","symbols":["TEST"]}}]}`,
   253  		},
   254  		{
   255  			input: `{
   256  				"type":"record",
   257  				"namespace": "org.hamba.avro",
   258  				"name":"X",
   259    				"fields":[
   260  					{"name":"value", "type":{
   261  						"type":"fixed",
   262  						"name":"Y",
   263  						"size":15
   264  					}}
   265  				]
   266  			}`,
   267  			json: `{"name":"org.hamba.avro.X","type":"record","fields":[{"name":"value","type":{"name":"org.hamba.avro.Y","type":"fixed","size":15}}]}`,
   268  		},
   269  		{
   270  			input: `{
   271  				"type":"record",
   272  				"namespace": "org.hamba.avro",
   273  				"name":"X",
   274    				"fields":[
   275  					{"name":"union_no_def","type":["null", "int"]},
   276  					{"name":"union_with_def","type":["null", "string"],"default": null}
   277  				]
   278  			}`,
   279  			json: `{"name":"org.hamba.avro.X","type":"record","fields":[{"name":"union_no_def","type":["null","int"]},{"name":"union_with_def","type":["null","string"],"default":null}]}`,
   280  		},
   281  	}
   282  
   283  	for i, test := range tests {
   284  		test := test
   285  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   286  			t.Parallel()
   287  
   288  			schema, err := avro.ParseWithCache(test.input, "", &avro.SchemaCache{})
   289  			require.NoError(t, err)
   290  
   291  			b, err := json.Marshal(schema)
   292  
   293  			require.NoError(t, err)
   294  			assert.Equal(t, test.json, string(b))
   295  		})
   296  	}
   297  }