Skip to content

Commit ebbb32e

Browse files
committed
fix collapse nullable scalar on export
Closes #74
1 parent fc18753 commit ebbb32e

File tree

3 files changed

+31
-23
lines changed

3 files changed

+31
-23
lines changed

avro_schema/frontend.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,12 @@ export_helper = function(node, already_built)
11851185
if primitive_type[xtype] then
11861186
local res = table.deepcopy(node)
11871187
pack_nullable_to_type(res)
1188+
-- if `type` is the only field in `res` then the type
1189+
-- should be canonized: {type="int"} -> "int"
1190+
assert(res.type)
1191+
if utils.has_only(res, "type") then
1192+
return res.type
1193+
end
11881194
return res
11891195
elseif xtype == 'record' then
11901196
if already_built[node.name] then

avro_schema/utils.lua

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,16 @@ local function copy_fields(from, to, opts)
4545
end
4646
end
4747
end
48+
--
49+
--- Check if given table has only one specific key.
50+
function has_only(t, key)
51+
local fst_key = next(t)
52+
local snd_key = next(t, fst_key)
53+
return fst_key == key and snd_key == nil
54+
end
4855

4956
return {
5057
table_contains = table_contains,
51-
copy_fields = copy_fields
58+
copy_fields = copy_fields,
59+
has_only = has_only
5260
}

test/api_tests/export.lua

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ local msgpack = require('msgpack')
55

66
local test = tap.test('api-tests')
77

8-
test:plan(27)
8+
test:plan(35)
99

1010
-- nested records, union, reference to earlier declared type
1111
local foobar_decl = {
@@ -37,6 +37,17 @@ for _, type in ipairs(
3737
test:is_deeply(schema.export(res[2]), type, 'schema normalization '..type)
3838
end
3939

40+
-- nullable scalar export
41+
for _, type in ipairs(
42+
{
43+
"int*", "string*", "null*", "boolean*", "long*",
44+
"float", "double*", "bytes*"
45+
}) do
46+
res = {schema.create({type=type})}
47+
test:is_deeply(schema.export(res[2]), type,
48+
'nullable scalar normalization '..type)
49+
end
50+
4051
-- fingerprint tests
4152
local fingerprint_testcases = {
4253
{
@@ -266,35 +277,18 @@ local nullable_orig = [[ {
266277
{"name": "v2", "type": "string*"} ] } },
267278
{ "name": "r2", "type": "tr1*"},
268279
{ "name": "dummy", "type": {
269-
"name": "td", "type": "array", "items": "int" }},
280+
"type": "array", "items": "int" }},
270281
{ "name": "r3", "type": {
271282
"name": "tr2", "type": "record*", "fields": [
272283
{"name": "v1", "type": "string"} ,
273284
{"name": "v2", "type": "int*"} ] } },
274285
{ "name": "r4", "type": "tr2" }]
275286
}]]
276-
277-
-- TODO: the `nullable_orig` should be used after #74
278-
local nullable_exported = [[
279-
{"type":"record","fields":
280-
[{"name":"r1","type":
281-
{"type":"record","fields":
282-
[{"name":"v1","type":"int"},
283-
{"name":"v2","type":{"type":"string*"}}],
284-
"name":"tr1"}},
285-
{"name":"r2","type":"tr1*"},
286-
{"name":"dummy","type":{"type":"array","items":"int"}},
287-
{"name":"r3","type":
288-
{"type":"record*","name":"tr2","fields":
289-
[{"name":"v1","type":"string"},
290-
{"name":"v2","type":{"type":"int*"}}]}},
291-
{"name":"r4","type":"tr2"}],
292-
"name":"outer"}
293-
]]
294-
res = {schema.create(json.decode(nullable_orig))}
287+
nullable_orig = json.decode(nullable_orig)
288+
res = {schema.create(nullable_orig)}
295289
test:is(res[1], true, "Schema created successfully")
296290
res = schema.export(res[2])
297-
test:is_deeply(res, json.decode(nullable_exported), "Exported schema is valid.")
291+
test:is_deeply(res, nullable_orig, "Exported schema is valid.")
298292

299293
-- check if nullable reference is not exported as a definition
300294
local nullable_reference = {

0 commit comments

Comments
 (0)