Skip to content

Commit

Permalink
fix(schema) fix errors when encoding default empty arrays
Browse files Browse the repository at this point in the history
Previously, a schema such as this:
```
{ type = "array",
  default = {},
  elements = { type = "string" },
}
```
would be encoded in json as a `{}` instead of as a `[]` (the Lua table given for the default value would be copied, and its metatable would remain)

This change sets the metatable to `cjson.array_mt` and also adds tests for other possible values given to the default (i.e. `cjson.empty_array`).
  • Loading branch information
kikito committed Jan 29, 2019
1 parent f87a82f commit 79282b8
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
6 changes: 5 additions & 1 deletion kong/db/schema/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,11 @@ 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" 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
48 changes: 48 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,54 @@ 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 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

0 comments on commit 79282b8

Please sign in to comment.