ignore metatables with __metatable field set to non-nil non-table values

This commit is contained in:
IntendedConsequence 2018-02-18 22:59:44 +02:00
parent 78a91c40e5
commit b6bb292f68
2 changed files with 27 additions and 2 deletions

View File

@ -180,6 +180,7 @@ local function processRecursive(process, item, path, visited)
end end
local mt = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE), visited) local mt = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE), visited)
if type(mt) ~= 'table' then mt = nil end -- ignore not nil/table __metatable field
setmetatable(processedCopy, mt) setmetatable(processedCopy, mt)
processed = processedCopy processed = processedCopy
end end
@ -273,7 +274,7 @@ function Inspector:putTable(t)
count = count + 1 count = count + 1
end end
if mt then if type(mt) == 'table' then
if count > 0 then self:puts(',') end if count > 0 then self:puts(',') end
self:tabify() self:tabify()
self:puts('<metatable> = ') self:puts('<metatable> = ')
@ -281,7 +282,7 @@ function Inspector:putTable(t)
end end
end) end)
if #nonSequentialKeys > 0 or mt then -- result is multi-lined. Justify closing } if #nonSequentialKeys > 0 or type(mt) == 'table' then -- result is multi-lined. Justify closing }
self:tabify() self:tabify()
elseif sequenceLength > 0 then -- array tables have one extra space before closing } elseif sequenceLength > 0 then -- array tables have one extra space before closing }
self:puts(' ') self:puts(' ')

View File

@ -404,6 +404,30 @@ describe( 'inspect', function()
]]), inspect(t)) ]]), inspect(t))
end) end)
it('ignores metatables with __metatable field set to non-nil and non-table type', function()
local function process(item) return item end
local function inspector(data) return inspect(data, {process=process}) end
local foo = setmetatable({}, {__metatable=false})
local bar = setmetatable({}, {__metatable=true})
local baz = setmetatable({}, {__metatable=10})
local spam = setmetatable({}, {__metatable=nil})
local eggs = setmetatable({}, {__metatable={}})
assert.equals(unindent('{}'), inspector(foo))
assert.equals(unindent('{}'), inspector(bar))
assert.equals(unindent('{}'), inspector(baz))
assert.equals(unindent([[
{
<metatable> = {}
}
]]), inspector(spam))
assert.equals(unindent([[
{
<metatable> = {}
}
]]), inspector(eggs))
end)
describe('When a table is its own metatable', function() describe('When a table is its own metatable', function()
it('accepts a table that is its own metatable without stack overflowing', function() it('accepts a table that is its own metatable without stack overflowing', function()
local x = {} local x = {}