Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(schema) fix errors when encoding default empty arrays #4257

Merged
merged 1 commit into from
Jan 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion kong/db/schema/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,14 @@ end
-- @param field The field definition table.
local function handle_missing_field(field, value)
if field.default ~= nil then
return tablex.deepcopy(field.default)
local copy = tablex.deepcopy(field.default)
if (field.type == "array" or field.type == "set")
and type(copy) == "table"
and not getmetatable(copy)
then
setmetatable(copy, cjson.array_mt)
end
return copy
end

-- If `nilable` (metaschema only), a default value is not necessary.
Expand Down
61 changes: 61 additions & 0 deletions spec/01-unit/01-db/01-schema/01-schema_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2004,6 +2004,67 @@ describe("schema", function()
assert.same({ r = { a = "nr", b = 123, }}, data.nested_record)
end)

it("detects an empty Lua table as a default for an set and marks it as a json array", function()
local Test = Schema.new({
fields = {
{ s = { type = "set",
elements = { type = "string" },
default = {} }, },
}
})
local data = Test:process_auto_fields({})
assert.equals('{"s":[]}', cjson.encode(data))
end)


it("detects an empty Lua table as a default for an array and marks it as a json array", function()
local Test = Schema.new({
fields = {
{ a = { type = "array",
elements = { type = "string" },
default = {} }, },
}
})
local data = Test:process_auto_fields({})
assert.equals('{"a":[]}', cjson.encode(data))
end)

it("accepts cjson.empty_array as a default for an array", function()
local Test = Schema.new({
fields = {
{ b = { type = "array",
elements = { type = "string" },
default = cjson.empty_array }, },
}
})
local data = Test:process_auto_fields({})
assert.equals('{"b":[]}', cjson.encode(data))
end)

it("accepts a table marked with cjson.empty_array_mt as a default for an array", function()
local Test = Schema.new({
fields = {
{ c = { type = "array",
elements = { type = "string" },
default = setmetatable({}, cjson.empty_array_mt) }, },
}
})
local data = Test:process_auto_fields({})
assert.equals('{"c":[]}', cjson.encode(data))
end)

it("accepts a table marked with cjson.array_mt as a default for an array", function()
local Test = Schema.new({
fields = {
{ d = { type = "array",
elements = { type = "string" },
default = setmetatable({}, cjson.array_mt) }, },
}
})
local data = Test:process_auto_fields({})
assert.equals('{"d":[]}', cjson.encode(data))
end)

it("nested defaults in required records produce a default record", function()
local Test = Schema.new({
fields = {
Expand Down