Merge pull request #7 from CheyiLin/master

arbitrary type support (e.g., LuaJIT's cdata)
This commit is contained in:
Enrique García 2013-09-14 05:24:39 -07:00
commit 67f12d3664
2 changed files with 48 additions and 20 deletions

View File

@ -54,19 +54,24 @@ local function isIdentifier(str)
end end
local function isArrayKey(k, length) local function isArrayKey(k, length)
return type(k)=='number' and 1 <= k and k <= length return type(k) == 'number' and 1 <= k and k <= length
end end
local function isDictionaryKey(k, length) local function isDictionaryKey(k, length)
return not isArrayKey(k, length) return not isArrayKey(k, length)
end end
local sortOrdersByType = { local sortOrdersByType = setmetatable({
['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4, ['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4,
['function'] = 5, ['userdata'] = 6, ['thread'] = 7 ['function'] = 5, ['userdata'] = 6, ['thread'] = 7
} },
{ __index = function (t, k)
if not rawget(t, k) then
return math.huge
end
end })
local function sortKeys(a,b) local function sortKeys(a, b)
local ta, tb = type(a), type(b) local ta, tb = type(a), type(b)
if ta ~= tb then return sortOrdersByType[ta] < sortOrdersByType[tb] end if ta ~= tb then return sortOrdersByType[ta] < sortOrdersByType[tb] end
if ta == 'string' or ta == 'number' then return a < b end if ta == 'string' or ta == 'number' then return a < b end
@ -77,7 +82,7 @@ local function getDictionaryKeys(t)
local length = #t local length = #t
local keys = {} local keys = {}
for k,_ in pairs(t) do for k,_ in pairs(t) do
if isDictionaryKey(k, length) then table.insert(keys,k) end if isDictionaryKey(k, length) then table.insert(keys, k) end
end end
table.sort(keys, sortKeys) table.sort(keys, sortKeys)
return keys return keys
@ -93,6 +98,26 @@ local function getToStringResultSafely(t, mt)
return string return string
end end
local inspectorMaxIdsMetaTable = {
__index = function (t, k)
if not rawget(t, k) then
rawset(t, k, 0)
end
return 0
end
}
local inspectorIdsMetaTable = {
__index = function (t, k)
local v = rawget(t, k)
if not v then
rawset(t, k, setmetatable({}, {__mode = "kv"}))
v = rawget(t, k)
end
return v
end
}
local Inspector = {} local Inspector = {}
function Inspector:new(t, depth) function Inspector:new(t, depth)
@ -100,18 +125,8 @@ function Inspector:new(t, depth)
buffer = {}, buffer = {},
depth = depth, depth = depth,
level = 0, level = 0,
maxIds = { maxIds = setmetatable({}, inspectorMaxIdsMetaTable),
['function'] = 0, ids = setmetatable({}, inspectorIdsMetaTable),
['userdata'] = 0,
['thread'] = 0,
['table'] = 0
},
ids = {
['function'] = setmetatable({}, {__mode = "kv"}),
['userdata'] = setmetatable({}, {__mode = "kv"}),
['thread'] = setmetatable({}, {__mode = "kv"}),
['table'] = setmetatable({}, {__mode = "kv"})
},
tableAppearances = setmetatable({}, {__mode = "k"}) tableAppearances = setmetatable({}, {__mode = "k"})
} }

View File

@ -1,4 +1,5 @@
local inspect = require 'inspect' local inspect = require 'inspect'
local is_luajit, ffi = pcall(require, 'ffi')
describe( 'inspect', function() describe( 'inspect', function()
@ -42,6 +43,14 @@ describe( 'inspect', function()
assert.equals(inspect(false), 'false') assert.equals(inspect(false), 'false')
end) end)
if is_luajit then
describe('luajit cdata', function()
it('works with luajit cdata', function()
assert.equals(inspect({ ffi.new("int", 1), ffi.typeof("int"), ffi.typeof("int")(1) }), '{ <cdata 1>, <cdata 2>, <cdata 3> }')
end)
end)
end
describe('tables', function() describe('tables', function()
it('works with simple array-like tables', function() it('works with simple array-like tables', function()
@ -61,7 +70,7 @@ describe( 'inspect', function()
[print] = 1, ["buy more"] = 1, a = 1, [print] = 1, ["buy more"] = 1, a = 1,
[14] = 1, [{c=2}] = 1, [true]= 1 [14] = 1, [{c=2}] = 1, [true]= 1
} }
assert.equals(inspect(t), [[{ 1, 2, 3, local s = [[{ 1, 2, 3,
[14] = 1, [14] = 1,
[true] = 1, [true] = 1,
a = 1, a = 1,
@ -69,8 +78,12 @@ describe( 'inspect', function()
[{ [{
c = 2 c = 2
}] = 1, }] = 1,
[<function 1>] = 1 [<function 1>] = 1]]
}]]) if is_luajit then
t[ffi.new("int", 1)] = 1
s = s .. ",\n [<cdata 1>] = 1"
end
assert.equals(inspect(t), s .. "\n}")
end) end)
it('works with nested dictionary tables', function() it('works with nested dictionary tables', function()