local Case = require("evalframe.model.case")
local std = require("evalframe.std")
local M = {}
local function make_sandbox()
return {
pairs = pairs,
ipairs = ipairs,
type = type,
tostring = tostring,
tonumber = tonumber,
select = select,
unpack = unpack or table.unpack,
string = string,
table = table,
math = math,
}
end
local function load_sandboxed(content, chunkname)
local sandbox = make_sandbox()
if rawget(_G, "setfenv") then
local chunk, err = loadstring(content, chunkname)
if not chunk then return nil, err end
setfenv(chunk, sandbox)
return chunk
else
return load(content, chunkname, "t", sandbox)
end
end
function M.load_file(path)
local content = std.fs.read_file(path)
local chunk, err = load_sandboxed(content, "@" .. path)
if not chunk then
error(string.format("load_cases: compile error in %s: %s", path, err), 2)
end
local ok_exec, specs = pcall(chunk)
if not ok_exec then
error(string.format("load_cases: runtime error in %s: %s", path, tostring(specs)), 2)
end
if type(specs) ~= "table" then
error(string.format("load_cases: file must return a table (%s)", path), 2)
end
local cases = {}
for i, spec in ipairs(specs) do
local ok, c = pcall(Case.new, spec)
if not ok then
error(string.format("load_cases: case[%d] in %s: %s", i, path, c), 2)
end
cases[#cases + 1] = c
end
return cases
end
return M