process option handles keys as well as items

This commit is contained in:
kikito 2014-08-16 19:44:35 +02:00
parent 5ecaca9205
commit 2961caa14a
2 changed files with 40 additions and 8 deletions

View File

@ -136,23 +136,34 @@ local function countTableAppearances(t, tableAppearances)
return tableAppearances
end
local copySequence = function(s)
local copy, len = {}, #s
for i=1, len do copy[i] = copy[i] end
return copy, len
end
local function makePath(path, key)
local newPath, len = {}, #path
for i=1, len do newPath[i] = path[i] end
newPath[len+1] = key
local newPath, len = copySequence(path)
newPath[len + 1] = key
return newPath
end
local function processRecursive(object, path, process)
local processed = process(object, path)
local function processRecursive(process, item, path)
if item == nil then return nil end
local processed = process(item, path)
if type(processed) == 'table' then
local processedCopy = {}
local processedKey
for k,v in pairs(processed) do
processedCopy[k] = processRecursive(v, makePath(path, k), process)
processedKey = processRecursive(process, k, makePath(path, '<key>'))
if processedKey ~= nil then
processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey))
end
end
local mt = processRecursive(getmetatable(processed), makePath(path, '<metatable>'), process)
local mt = processRecursive(process, getmetatable(processed), makePath(path, '<metatable>'))
setmetatable(processedCopy, mt)
processed = processedCopy
end
@ -165,7 +176,7 @@ function inspect.inspect(root, options)
local depth = options.depth or math.huge
local process = options.process
if process then
root = processRecursive(root, {}, process)
root = processRecursive(process, root, {})
end
local tableAppearances = countTableAppearances(root)

View File

@ -220,6 +220,27 @@ describe( 'inspect', function()
assert.equals(inspect(names, {process = removeNames}), 'nil')
end)
it('changes keys', function()
local dict = {a = 1}
local changeKey = function(item, path) return item == 'a' and 'x' or item end
assert.equals(inspect(dict, {process = changeKey}), '{\n x = 1\n}')
end)
it('nullifies keys', function()
local dict = {a = 1, b = 2}
local removeA = function(item, path) return item ~= 'a' and item or nil end
assert.equals(inspect(dict, {process = removeA}), '{\n b = 2\n}')
end)
it('marks key paths with <key>', function()
local names = {a = 1}
local paths = {}
local addPath = function(item, path) paths[#paths + 1] = path; return item end
inspect(names, {process = addPath})
assert.same(paths, { {}, {'<key>'}, {'a'} })
end)
end)
describe('metatables', function()