Implement basic lua test harness
This commit is contained in:
parent
db4faea821
commit
40829cdfc6
@ -1,5 +1,9 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
||||
"runtime.version": "LuaJIT",
|
||||
"diagnostics.disable": ["redefined-local", "lowercase-global"]
|
||||
"diagnostics.disable": [
|
||||
"undefined-global",
|
||||
"redefined-local",
|
||||
"lowercase-global"
|
||||
]
|
||||
}
|
||||
|
@ -30,6 +30,10 @@ repository.workspace = true
|
||||
dev.panic = "abort"
|
||||
release.panic = "abort"
|
||||
|
||||
[[test]]
|
||||
name = "main"
|
||||
harness = false
|
||||
|
||||
[features]
|
||||
default = ["task", "fs", "net"]
|
||||
task = ["lb/task"]
|
||||
|
17
src/main.rs
17
src/main.rs
@ -219,17 +219,14 @@ fn init_tokio(args: &Args) -> tokio::runtime::Runtime {
|
||||
fn init_lua(args: &Args) -> lb::runtime::Runtime {
|
||||
let mut rt = {
|
||||
let mut rt = lb::runtime::Builder::new();
|
||||
rt.unhandled_error(error_cb);
|
||||
luby::open(&mut rt);
|
||||
|
||||
if args.dump.iter().find(|s| *s == "cdef").is_some() {
|
||||
print!("{}", rt.registry()); // for debugging
|
||||
print!("{}", rt.registry()); // for cdef debugging
|
||||
}
|
||||
|
||||
rt
|
||||
}
|
||||
.build()
|
||||
.unwrap();
|
||||
rt.unhandled_error(error_cb).build().unwrap()
|
||||
};
|
||||
|
||||
for arg in args.jit.iter() {
|
||||
let mut s = rt.guard();
|
||||
@ -281,10 +278,10 @@ async fn main_async(args: Args, cx: &mut lb::runtime::Context) -> Result<(), Exi
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(err) = cx.load(&luajit::Chunk::new(chunk).path(path)) {
|
||||
cx.report_error(&err);
|
||||
} else if let Err(err) = cx.call_async(0, 0).await {
|
||||
cx.report_error(&err);
|
||||
if let Err(ref err) = cx.load(&luajit::Chunk::new(chunk).path(path)) {
|
||||
cx.report_error(err);
|
||||
} else if let Err(ref err) = cx.call_async(0, 0).await {
|
||||
cx.report_error(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
97
tests/main.lua
Normal file
97
tests/main.lua
Normal file
@ -0,0 +1,97 @@
|
||||
if (...) ~= nil and (...).type == "group" then return end -- prevent recursive main call
|
||||
local fs = require("lb:fs")
|
||||
local global = _G
|
||||
local colors = {
|
||||
reset = "\x1b[0m",
|
||||
pass = "\x1b[32;1m",
|
||||
fail = "\x1b[31;1m",
|
||||
}
|
||||
|
||||
local function color(name, s)
|
||||
return colors[name] .. s .. colors.reset
|
||||
end
|
||||
|
||||
local function create_test(name, f, group)
|
||||
local test = { type = "test", name = name or "", group = group, state = "pending", f = f }
|
||||
local fenv = setmetatable({}, { __index = global })
|
||||
setfenv(f, fenv)
|
||||
return test
|
||||
end
|
||||
|
||||
local function create_group(name, f, parent)
|
||||
local group = { type = "group", name = name or "", parent = parent, items = {} }
|
||||
local fenv = setmetatable({
|
||||
describe = function(name, f)
|
||||
local item = create_group(name, f, group)
|
||||
table.insert(group.items, item)
|
||||
return item
|
||||
end,
|
||||
|
||||
test = function(name, f)
|
||||
local item = create_test(name, f, group)
|
||||
table.insert(group.items, item)
|
||||
return item
|
||||
end,
|
||||
}, { __index = global })
|
||||
|
||||
setfenv(f, fenv)
|
||||
f(group)
|
||||
return group
|
||||
end
|
||||
|
||||
local function name_test(test)
|
||||
local name = test.name
|
||||
local group = test.group
|
||||
while group ~= nil do
|
||||
if group.name ~= "" then name = group.name .. " › " .. name end
|
||||
group = group.parent
|
||||
end
|
||||
return name
|
||||
end
|
||||
|
||||
local function trace(msg)
|
||||
return color("fail", msg) .. debug.traceback("", 2):sub(("\nstack traceback:"):len() + 1)
|
||||
end
|
||||
|
||||
local function run_test(test)
|
||||
local ok, res = xpcall(test.f, trace, test)
|
||||
if ok then
|
||||
test.state = "pass"
|
||||
print("", color("pass", "PASS") .. " " .. name_test(test))
|
||||
else
|
||||
test.state = "fail"
|
||||
print("", color("fail", "FAIL") .. " " .. name_test(test) .. "\n")
|
||||
print(res .. "\n")
|
||||
end
|
||||
return test
|
||||
end
|
||||
|
||||
local function start(cx, item)
|
||||
if item.type == "test" then
|
||||
table.insert(cx.tasks, spawn(run_test, item))
|
||||
elseif item.type == "group" then
|
||||
for _, item in ipairs(item.items) do
|
||||
start(cx, item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function run(item)
|
||||
local cx = { tasks = {} }
|
||||
local pass = true
|
||||
start(cx, item)
|
||||
for _, task in ipairs(cx.tasks) do
|
||||
if task:await().state ~= "pass" then pass = false end
|
||||
end
|
||||
if pass then return 0 end -- report status to cargo
|
||||
return 1
|
||||
end
|
||||
|
||||
return run(create_group("", function()
|
||||
for entry in fs:glob("{tests,crates/*/tests}/**/*.lua") do
|
||||
local path = entry:path():sub(3)
|
||||
local f, err = loadfile(path)
|
||||
if not f then error(err) end
|
||||
describe(path, f)
|
||||
end
|
||||
end))
|
44
tests/main.rs
Normal file
44
tests/main.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use luajit::Chunk;
|
||||
use owo_colors::OwoColorize;
|
||||
use std::{
|
||||
fs,
|
||||
process::{self, ExitCode},
|
||||
};
|
||||
|
||||
fn main() -> ExitCode {
|
||||
let tokio = tokio::runtime::Runtime::new().unwrap();
|
||||
let lua = {
|
||||
let mut rt = lb::runtime::Builder::new();
|
||||
luby::open(&mut rt);
|
||||
rt.unhandled_error(error_cb).build().unwrap()
|
||||
};
|
||||
|
||||
let path = "tests/main.lua";
|
||||
let main = lua.spawn(async move |s| {
|
||||
if let Err(ref err) = s.load(Chunk::new(fs::read(path).unwrap()).path(path)) {
|
||||
s.report_error(err);
|
||||
} else if let Err(ref err) = s.call_async(0, 1).await {
|
||||
s.report_error(err);
|
||||
}
|
||||
|
||||
if s.slot(1).integer().unwrap_or(1) == 0 {
|
||||
ExitCode::SUCCESS
|
||||
} else {
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
});
|
||||
|
||||
tokio.block_on(async move {
|
||||
lua.await;
|
||||
main.await.unwrap()
|
||||
})
|
||||
}
|
||||
|
||||
fn error_cb(err: &luajit::Error) {
|
||||
match err.trace() {
|
||||
Some(trace) => eprintln!("{}\n{trace}", err.red().bold()),
|
||||
None => eprintln!("{}", err.red().bold()),
|
||||
}
|
||||
|
||||
process::exit(1);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user