mirror of
https://github.com/kikito/inspect.lua.git
synced 2024-12-15 14:34:21 +00:00
first tests with dictionary-type table are passing!
This commit is contained in:
parent
ecf208a938
commit
51153a31c6
102
inspect.lua
102
inspect.lua
@ -16,60 +16,108 @@ local function smartQuote(str)
|
|||||||
return string.format("%q", str )
|
return string.format("%q", str )
|
||||||
end
|
end
|
||||||
|
|
||||||
local unescapedChars = {
|
local controlCharsTranslation = {
|
||||||
["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n",
|
["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n",
|
||||||
["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v", ["\\"] = "\\\\"
|
["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v", ["\\"] = "\\\\"
|
||||||
}
|
}
|
||||||
|
|
||||||
local function unescapeChar(c)
|
local function unescapeChar(c) return controlCharsTranslation[c] end
|
||||||
return unescapedChars[c]
|
|
||||||
end
|
|
||||||
|
|
||||||
local function unescape(str)
|
local function unescape(str)
|
||||||
return string.gsub( str, "(%c)", unescapeChar )
|
return string.gsub( str, "(%c)", unescapeChar )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function isIdentifier(str)
|
||||||
|
return string.match( str, "^[_%a][_%a%d]*$" )
|
||||||
|
end
|
||||||
|
|
||||||
local Buffer = {}
|
local function isArrayKey(k, length)
|
||||||
|
return type(k)=='number' and 1 <= k and k <= length
|
||||||
|
end
|
||||||
|
|
||||||
function Buffer:new()
|
local function isDictionaryKey(k, length)
|
||||||
return setmetatable( { data = {} }, {
|
return not isArrayKey(k, length)
|
||||||
__index = Buffer,
|
end
|
||||||
__tostring = function(instance) return table.concat(instance.data) end
|
|
||||||
|
local function isDictionary(t)
|
||||||
|
local length = #t
|
||||||
|
for k,_ in pairs(t) do
|
||||||
|
if isDictionaryKey(k, length) then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local Inspector = {}
|
||||||
|
|
||||||
|
function Inspector:new()
|
||||||
|
return setmetatable( { buffer = {} }, {
|
||||||
|
__index = Inspector,
|
||||||
|
__tostring = function(instance) return table.concat(instance.buffer) end
|
||||||
} )
|
} )
|
||||||
end
|
end
|
||||||
|
|
||||||
function Buffer:add(...)
|
function Inspector:puts(...)
|
||||||
local args = {...}
|
local args = {...}
|
||||||
for i=1, #args do
|
for i=1, #args do
|
||||||
table.insert(self.data, tostring(args[i]))
|
table.insert(self.buffer, tostring(args[i]))
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function Buffer:addValue(v)
|
function Inspector:tabify(level)
|
||||||
local tv = type(v)
|
self:puts("\n", string.rep(" ", level))
|
||||||
|
return self
|
||||||
if tv == 'string' then
|
end
|
||||||
self:add(smartQuote(unescape(v)))
|
|
||||||
elseif tv == 'number' or tv == 'boolean' then
|
function Inspector:addTable(t, level)
|
||||||
self:add(tostring(v))
|
self:puts('{')
|
||||||
elseif tv == 'table' then
|
local length = #t
|
||||||
self:add('{')
|
local needsComma = false
|
||||||
for i=1, #v do
|
for i=1, length do
|
||||||
if i > 1 then self:add(', ') end
|
if i > 1 then
|
||||||
self:addValue(v[i])
|
self:puts(', ')
|
||||||
|
needsComma = true
|
||||||
end
|
end
|
||||||
self:add('}')
|
self:addValue(t[i], level + 1)
|
||||||
else
|
|
||||||
self:add('<',tv,'>')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for k,v in pairs(t) do
|
||||||
|
if isDictionaryKey(k, length) then
|
||||||
|
if needsComma then self:puts(',') end
|
||||||
|
needsComma = true
|
||||||
|
self:tabify(level+1):addKey(k):puts(' = '):addValue(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if isDictionary(t) then self:tabify(level) end
|
||||||
|
self:puts('}')
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Inspector:addValue(v, level)
|
||||||
|
local tv = type(v)
|
||||||
|
|
||||||
|
if tv == 'string' then
|
||||||
|
self:puts(smartQuote(unescape(v)))
|
||||||
|
elseif tv == 'number' or tv == 'boolean' then
|
||||||
|
self:puts(tostring(v))
|
||||||
|
elseif tv == 'table' then
|
||||||
|
self:addTable(v, level)
|
||||||
|
else
|
||||||
|
self:puts('<',tv,'>')
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function Inspector:addKey(k, level)
|
||||||
|
if type(k) == "string" and isIdentifier(k) then
|
||||||
|
return self:puts(k)
|
||||||
|
end
|
||||||
|
return self:puts( "[" ):addValue(k, level):puts("]")
|
||||||
|
end
|
||||||
|
|
||||||
local function inspect(t)
|
local function inspect(t)
|
||||||
return tostring(Buffer:new():addValue(t))
|
return tostring(Inspector:new():addValue(t,0))
|
||||||
end
|
end
|
||||||
|
|
||||||
return inspect
|
return inspect
|
||||||
|
@ -51,7 +51,11 @@ context( 'inspect', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
test('Should work with nested arrays', function()
|
test('Should work with nested arrays', function()
|
||||||
assert_equal(inspect({1,2,3, {4,5}, 6}), "{1, 2, 3, {4, 5}, 6}" )
|
assert_equal(inspect({'a','b','c', {'d','e'}, 'f'}), '{"a", "b", "c", {"d", "e"}, "f"}' )
|
||||||
|
end)
|
||||||
|
|
||||||
|
test('Should work with simple hash-like tables', function()
|
||||||
|
assert_equal(inspect({a = 1, b = 2}), "{\n a = 1,\n b = 2\n}")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user