Skip to content

Commit 27992dd

Browse files
no1semanDifferentialOrange
authored andcommitted
Fix returning gapped arrays
1 parent 95ebf84 commit 27992dd

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
@@ -228,37 +228,23 @@ local function check(obj, obj_name, type_1, type_2, type_3)
228228
end
229229
end
230230

231-
--- Check whether table is an array.
232-
---
233-
--- Based on [that][1] implementation.
234-
--- [1]: https://github.com/mpx/lua-cjson/blob/db122676/lua/cjson/util.lua
235-
---
236-
--- @tparam table table to check
237-
--- @return[1] `true` if passed table is an array (includes the empty table
238-
--- case)
239-
--- @return[2] `false` otherwise
240-
local function is_array(table)
241-
if type(table) ~= 'table' then
242-
return false
243-
end
244-
245-
local max = 0
246-
local count = 0
247-
for k, _ in pairs(table) do
248-
if type(k) == 'number' then
249-
if k > max then
250-
max = k
251-
end
252-
count = count + 1
253-
else
254-
return false
255-
end
256-
end
257-
if max > count * 2 then
231+
local function is_array(t)
232+
if type(t) ~= 'table' then
233+
return false
234+
end
235+
local n = #t
236+
if n > 0 then
237+
for k in next, t, n do
238+
if type(k) ~= 'number' or k < 0 then return false end
239+
end
240+
return true
241+
end
242+
for k in pairs(t) do
243+
if type(k) ~= 'number' or k < 0 then
258244
return false
259245
end
260-
261-
return max >= 0
246+
end
247+
return true
262248
end
263249

264250
-- Copied from tarantool/tap

test/integration/graphql_test.lua

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,3 +2236,36 @@ function g.test_huge_cdata_number()
22362236
t.assert_equals(json.encode(res), v[2])
22372237
end
22382238
end
2239+
2240+
function g.test_gapped_arrays_output()
2241+
local query = [[
2242+
query ($x: [String]) { test(arg: $x) }
2243+
]]
2244+
2245+
local function callback(_, args)
2246+
setmetatable(args.arg, {__serialize='array'})
2247+
return args.arg
2248+
end
2249+
2250+
local query_schema = {
2251+
['test'] = {
2252+
kind = types.list(types.string),
2253+
arguments = {
2254+
arg = types.list(types.string),
2255+
},
2256+
resolve = callback,
2257+
}
2258+
}
2259+
2260+
local test_values = {
2261+
{[3] = 'a', [1] = 'b', [6] = 'c'},
2262+
{[3] = 'a', [1] = 'b', [7] = 'c'},
2263+
}
2264+
2265+
for _, v in ipairs(test_values) do
2266+
local variables = {x = v}
2267+
local res = check_request(query, query_schema, nil, nil, {variables = variables})
2268+
t.assert_type(res, 'table')
2269+
t.assert_equals(res.test, v)
2270+
end
2271+
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)