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