Skip to content

Commit 5eb16cc

Browse files
committed
Fix returning gapped arrays
1 parent 58b64a6 commit 5eb16cc

File tree

4 files changed

+64
-30
lines changed

4 files changed

+64
-30
lines changed

graphql/execute.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ local function completeValue(fieldType, result, subSelections, context, opts)
208208

209209
local innerType = fieldType.ofType
210210
local values = {}
211-
for i, value in ipairs(result) do
211+
for i, value in pairs(result) do
212212
values[i] = completeValue(innerType, value, subSelections, context)
213213
end
214214

graphql/util.lua

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -213,37 +213,23 @@ local function check(obj, obj_name, type_1, type_2, type_3)
213213
end
214214
end
215215

216-
--- Check whether table is an array.
217-
---
218-
--- Based on [that][1] implementation.
219-
--- [1]: https://github.com/mpx/lua-cjson/blob/db122676/lua/cjson/util.lua
220-
---
221-
--- @tparam table table to check
222-
--- @return[1] `true` if passed table is an array (includes the empty table
223-
--- case)
224-
--- @return[2] `false` otherwise
225-
local function is_array(table)
226-
if type(table) ~= 'table' then
227-
return false
228-
end
229-
230-
local max = 0
231-
local count = 0
232-
for k, _ in pairs(table) do
233-
if type(k) == 'number' then
234-
if k > max then
235-
max = k
236-
end
237-
count = count + 1
238-
else
239-
return false
240-
end
241-
end
242-
if max > count * 2 then
216+
local function is_array(t)
217+
if type(t) ~= 'table' then
218+
return false
219+
end
220+
local n = #t
221+
if n > 0 then
222+
for k in next, t, n do
223+
if type(k) ~= 'number' or k < 0 then return false end
224+
end
225+
return true
226+
end
227+
for k in pairs(t) do
228+
if type(k) ~= 'number' or k < 0 then
243229
return false
244230
end
245-
246-
return max >= 0
231+
end
232+
return true
247233
end
248234

249235
-- Copied from tarantool/tap

test/integration/graphql_test.lua

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2147,3 +2147,36 @@ function g.test_non_finite_float()
21472147
query_schema, nil, nil, {variables = variables})
21482148
end
21492149
end
2150+
2151+
function g.test_gapped_arrays_output()
2152+
local query = [[
2153+
query ($x: [String]) { test(arg: $x) }
2154+
]]
2155+
2156+
local function callback(_, args)
2157+
setmetatable(args.arg, {__serialize='array'})
2158+
return args.arg
2159+
end
2160+
2161+
local query_schema = {
2162+
['test'] = {
2163+
kind = types.list(types.string),
2164+
arguments = {
2165+
arg = types.list(types.string),
2166+
},
2167+
resolve = callback,
2168+
}
2169+
}
2170+
2171+
local test_values = {
2172+
{[3] = 'a', [1] = 'b', [6] = 'c'},
2173+
{[3] = 'a', [1] = 'b', [7] = 'c'},
2174+
}
2175+
2176+
for _, v in ipairs(test_values) do
2177+
local variables = {x = v}
2178+
local res = check_request(query, query_schema, nil, nil, {variables = variables})
2179+
t.assert_type(res, 'table')
2180+
t.assert_equals(json.encode(res.test), json.encode(v))
2181+
end
2182+
end

test/unit/graphql_test.lua

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,3 +1092,18 @@ end
10921092
g.test_version = function()
10931093
t.assert_type(require('graphql').VERSION, 'string')
10941094
end
1095+
1096+
function g.test_is_array()
1097+
t.assert_equals(util.is_array({[3] = 'a', [1] = 'b', [6] = 'c'}), true)
1098+
t.assert_equals(util.is_array({[3] = 'a', [1] = 'b', [7] = 'c'}), true)
1099+
t.assert_equals(util.is_array({[3] = 'a', nil, [6] = 'c'}), true)
1100+
t.assert_equals(util.is_array({[3] = 'a', nil, [7] = 'c'}), true)
1101+
t.assert_equals(util.is_array({[0] = 'a', [1] = 'b', [6] = 'c'}), true)
1102+
t.assert_equals(util.is_array({[-1] = 'a', [1] = 'b', [6] = 'c'}), false)
1103+
t.assert_equals(util.is_array({[3] = 'a', b = 'b', [6] = 'c'}), false)
1104+
t.assert_equals(util.is_array({}), true)
1105+
t.assert_equals(util.is_array(), false)
1106+
t.assert_equals(util.is_array(''), false)
1107+
t.assert_equals(util.is_array({a = 'a', b = 'b', c = 'c'}), false)
1108+
t.assert_equals(util.is_array({a = 'a', nil, c = 'c'}), false)
1109+
end

0 commit comments

Comments
 (0)