Skip to content

Commit

Permalink
Upgrade prettyValue to preview tables
Browse files Browse the repository at this point in the history
  • Loading branch information
Derpius committed Dec 23, 2023
1 parent 9113f81 commit fb612bb
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 2 deletions.
93 changes: 91 additions & 2 deletions packages/lest/src/lua/utils/prettyValue.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,39 @@
--- Formats a value to look prettier
local MAX_TABLE_FIELDS = 3

--- Iterator function which returns elements in numeric then lexicographic order
---@param tbl table
---@return fun(): any, any
local function sortedPairs(tbl)
local keys = {}
for key in pairs(tbl) do
table.insert(keys, key)
end

table.sort(keys, function(a, b)
local aIsNumber = type(a) == "number"
local bIsNumber = type(b) == "number"

if aIsNumber then
return not bIsNumber or a < b
end

return not bIsNumber and tostring(a) < tostring(b)
end)

local i = 1
return function()
local key = keys[i]
if key ~= nil then
i = i + 1
return key, tbl[key]
end
end
end

--- Renders a primitive value, or table with tostring
---@param value any
---@return string
return function(value)
local function renderPrimitive(value)
if type(value) == "string" then
return '"' .. value .. '"'
end
Expand All @@ -20,3 +52,60 @@ return function(value)

return tostring(value)
end

--- Renders an inline truncated table
---@param tbl table
---@return string
local function renderTable(tbl)
local renderedFields = {}
local totalFields = 0

for key, value in sortedPairs(tbl) do
if #renderedFields < MAX_TABLE_FIELDS then
if type(key) == "number" then
table.insert(renderedFields, renderPrimitive(value))
elseif
type(key) == "string" and string.match(key, "^[_%a][_%a%d]*$")
then
table.insert(
renderedFields,
string.format("%s = %s", key, renderPrimitive(value))
)
else
table.insert(
renderedFields,
string.format(
"[%s] = %s",
renderPrimitive(key),
renderPrimitive(value)
)
)
end
end

totalFields = totalFields + 1
end

if #renderedFields < totalFields then
table.insert(
renderedFields,
string.format("...%d more", totalFields - #renderedFields)
)
end

return string.format("{ %s }", table.concat(renderedFields, ", "))
end

--- Formats a value to look prettier
---@param value any
---@return string
return function(value)
if
type(value) == "table"
and string.match(tostring(value), "table: [%a%d]+")
then
return renderTable(value)
end

return renderPrimitive(value)
end
49 changes: 49 additions & 0 deletions packages/lest/src/lua/utils/tests/pretty-value.test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
local prettyValue = require("utils.prettyValue")

test.each({
{ "string", "foo", [["foo"]] },
{ "number", 123, [[123]] },
{ "boolean", true, [[true]] },
{ "positive infinity", math.huge, [[inf]] },
{ "negative infinity", -math.huge, [[-inf]] },
{ "NaN", 0 / 0, [[NaN]] },
{
"table with tostring metamethod",
setmetatable({}, {
__tostring = function()
return "Blah"
end,
}),
[[Blah]],
},
{ "array-like table", { 1, "foo", 3 }, [[{ 1, "foo", 3 }]] },
{
"object-like table",
{ foo = true, ["b-ar"] = false },
[[{ ["b-ar"] = false, foo = true }]],
},
{
"mixed table",
{ 1, foo = 2, [true] = 3 },
[[{ 1, foo = 2, [true] = 3 }]],
},
{
"truncated array-like table",
{ 1, 2, 3, 4, 5 },
[[{ 1, 2, 3, ...2 more }]],
},
{
"truncated object-like table",
{ a = 1, ["b"] = 2, ["c-"] = 3, d = 4 },
[[{ a = 1, b = 2, ["c-"] = 3, ...1 more }]],
},
{
"truncated mixed table",
{ 1, foo = "bar", 2, 3, 4, 5, 6 },
[[{ 1, 2, 3, ...4 more }]],
},
})("prettifies %s", function(_, value, expected)
local rendered = prettyValue(value)

expect(rendered).toBe(expected)
end)

0 comments on commit fb612bb

Please sign in to comment.