unindent in specs

This commit is contained in:
kikito 2014-09-07 22:32:31 +02:00
parent 9ce951f6af
commit b9b780caad
2 changed files with 161 additions and 96 deletions

View File

@ -1,4 +1,5 @@
local inspect = require 'inspect' local inspect = require 'inspect'
local unindent = require 'spec.unindent'
local is_luajit, ffi = pcall(require, 'ffi') local is_luajit, ffi = pcall(require, 'ffi')
describe( 'inspect', function() describe( 'inspect', function()
@ -82,9 +83,11 @@ describe( 'inspect', function()
it('sorts keys in dictionary tables', function() it('sorts keys in dictionary tables', function()
local t = { 1,2,3, local t = { 1,2,3,
[print] = 1, ["buy more"] = 1, a = 1, [print] = 1, ["buy more"] = 1, a = 1,
[coroutine.create(function() end)] = 1,
[14] = 1, [{c=2}] = 1, [true]= 1 [14] = 1, [{c=2}] = 1, [true]= 1
} }
local s = [[{ 1, 2, 3, assert.equals(inspect(t), unindent([[
{ 1, 2, 3,
[14] = 1, [14] = 1,
[true] = 1, [true] = 1,
a = 1, a = 1,
@ -92,31 +95,33 @@ describe( 'inspect', function()
[{ [{
c = 2 c = 2
}] = 1, }] = 1,
[<function 1>] = 1]] [<function 1>] = 1,
if is_luajit then [<thread 1>] = 1
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()
assert.equals(inspect( {d=3, b={c=2}, a=1} ), [[{ assert.equals(inspect( {d=3, b={c=2}, a=1} ), unindent([[{
a = 1, a = 1,
b = { b = {
c = 2 c = 2
}, },
d = 3 d = 3
}]]) }]]))
end) end)
it('works with hybrid tables', function() it('works with hybrid tables', function()
assert.equals(inspect({ 'a', {b = 1}, 2, c = 3, ['ahoy you'] = 4 }), [[{ "a", { assert.equals(
inspect({ 'a', {b = 1}, 2, c = 3, ['ahoy you'] = 4 }),
unindent([[
{ "a", {
b = 1 b = 1
}, 2, }, 2,
["ahoy you"] = 4, ["ahoy you"] = 4,
c = 3 c = 3
}]]) }
]]))
end) end)
it('displays <table x> instead of repeating an already existing table', function() it('displays <table x> instead of repeating an already existing table', function()
@ -133,7 +138,8 @@ describe( 'inspect', function()
local keys = { [level5] = true } local keys = { [level5] = true }
it('has infinite depth by default', function() it('has infinite depth by default', function()
assert.equals(inspect(level5), [[{ 1, 2, 3, assert.equals(inspect(level5), unindent([[
{ 1, 2, 3,
a = { a = {
b = { b = {
c = { c = {
@ -143,19 +149,26 @@ describe( 'inspect', function()
} }
} }
} }
}]]) }
]]))
end) end)
it('is modifiable by the user', function() it('is modifiable by the user', function()
assert.equals(inspect(level5, {depth = 2}), [[{ 1, 2, 3, assert.equals(inspect(level5, {depth = 2}), unindent([[
{ 1, 2, 3,
a = { a = {
b = {...} b = {...}
} }
}]]) }
assert.equals(inspect(level5, {depth = 1}), [[{ 1, 2, 3, ]]))
assert.equals(inspect(level5, {depth = 1}), unindent([[
{ 1, 2, 3,
a = {...} a = {...}
}]]) }
assert.equals(inspect(level5, {depth = 0}), "{...}") ]]))
assert.equals(inspect(level5, {depth = 4}), [[{ 1, 2, 3,
assert.equals(inspect(level5, {depth = 4}), unindent([[
{ 1, 2, 3,
a = { a = {
b = { b = {
c = { c = {
@ -163,12 +176,15 @@ describe( 'inspect', function()
} }
} }
} }
}]]) }
]]))
assert.equals(inspect(level5, {depth = 0}), "{...}")
end) end)
it('respects depth on keys', function() it('respects depth on keys', function()
assert.equals(inspect(keys, {depth = 4}), [[{ assert.equals(inspect(keys, {depth = 4}), unindent([[
{
[{ 1, 2, 3, [{ 1, 2, 3,
a = { a = {
b = { b = {
@ -176,7 +192,8 @@ describe( 'inspect', function()
} }
} }
}] = true }] = true
}]]) }
]]))
end) end)
end) end)
@ -248,58 +265,67 @@ describe( 'inspect', function()
it('includes the metatable as an extra hash attribute', function() it('includes the metatable as an extra hash attribute', function()
local foo = { foo = 1, __mode = 'v' } local foo = { foo = 1, __mode = 'v' }
local bar = setmetatable({a = 1}, foo) local bar = setmetatable({a = 1}, foo)
assert.equals(inspect(bar), [[{ assert.equals(inspect(bar), unindent([[
{
a = 1, a = 1,
<metatable> = { <metatable> = {
__mode = "v", __mode = "v",
foo = 1 foo = 1
} }
}]]) }
]]))
end) end)
it('includes the __tostring metamethod if it exists', function() it('includes the __tostring metamethod if it exists', function()
local foo = { foo = 1, __tostring = function() return 'hello\nworld' end } local foo = { foo = 1, __tostring = function() return 'hello\nworld' end }
local bar = setmetatable({a = 1}, foo) local bar = setmetatable({a = 1}, foo)
assert.equals(inspect(bar), [[{ -- hello\nworld assert.equals(inspect(bar), unindent([[
{ -- hello\nworld
a = 1, a = 1,
<metatable> = { <metatable> = {
__tostring = <function 1>, __tostring = <function 1>,
foo = 1 foo = 1
} }
}]]) }
]]))
end) end)
it('includes an error string if __tostring metamethod throws an error', function() it('includes an error string if __tostring metamethod throws an error', function()
local foo = { foo = 1, __tostring = function() error('hello', 0) end } local foo = { foo = 1, __tostring = function() error('hello', 0) end }
local bar = setmetatable({a = 1}, foo) local bar = setmetatable({a = 1}, foo)
assert.equals(inspect(bar), [[{ -- error: hello assert.equals(inspect(bar), unindent([[
{ -- error: hello
a = 1, a = 1,
<metatable> = { <metatable> = {
__tostring = <function 1>, __tostring = <function 1>,
foo = 1 foo = 1
} }
}]]) }
]]))
end) 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 = {}
setmetatable(x,x) setmetatable(x,x)
assert.equals(inspect(x), [[<1>{ assert.equals(inspect(x), unindent([[
<1>{
<metatable> = <table 1> <metatable> = <table 1>
}]]) }
]]))
end) end)
it('can invoke the __tostring method without stack overflowing', function() it('can invoke the __tostring method without stack overflowing', function()
local t = {} local t = {}
t.__index = t t.__index = t
setmetatable(t,t) setmetatable(t,t)
assert.equals(inspect(t), [[<1>{ assert.equals(inspect(t), unindent([[
<1>{
__index = <table 1>, __index = <table 1>,
<metatable> = <table 1> <metatable> = <table 1>
}]]) }
end) ]]))
end)
end) end)
end) end)
end) end)

39
spec/unindent.lua Normal file
View File

@ -0,0 +1,39 @@
-- Unindenting transforms a string like this:
-- [[
-- {
-- foo = 1,
-- bar = 2
-- }
-- ]]
--
-- Into the same one without indentation, nor start/end newlines
--
-- [[{
-- foo = 1,
-- bar = 2
-- }]]
--
-- This makes the strings look and read better in the tests
--
local getIndentPreffix = function(str)
local level = math.huge
local minPreffix = ""
local len
for preffix in str:gmatch("\n( +)") do
len = #preffix
if len < level then
level = len
minPreffix = preffix
end
end
return minPreffix
end
local unindent = function(str)
str = str:gsub(" +$", ""):gsub("^ +", "") -- remove spaces at start and end
local preffix = getIndentPreffix(str)
return (str:gsub("\n" .. preffix, "\n"):gsub("\n$", ""))
end
return unindent