Run all lua examples in docs as doctests
This commit is contained in:
parent
81cd901ea6
commit
65b82fcd97
@ -224,9 +224,9 @@ impl lb_netlib {
|
|||||||
///
|
///
|
||||||
/// ```lua
|
/// ```lua
|
||||||
/// local net = require("lb:net")
|
/// local net = require("lb:net")
|
||||||
/// local socket = net.bind_tcp("127.0.0.1", 8080)
|
/// local socket = net.bind_tcp("127.0.0.1")
|
||||||
///
|
///
|
||||||
/// assert(socket:local_addr() == net.socketaddr("127.0.0.1:8080"))
|
/// assert(socket:local_addr():ip() == net.ipaddr("127.0.0.1"))
|
||||||
/// socket:set_nodelay(true)
|
/// socket:set_nodelay(true)
|
||||||
/// ```
|
/// ```
|
||||||
pub extern "Lua" fn bind_tcp(
|
pub extern "Lua" fn bind_tcp(
|
||||||
@ -257,15 +257,16 @@ impl lb_netlib {
|
|||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```lua
|
/// ```lua,no_run
|
||||||
/// local net = require("lb:net")
|
/// local net = require("lb:net")
|
||||||
/// local listener = net.listen_tcp("127.0.0.1", 1234)
|
/// local listener = net.listen_tcp("127.0.0.1")
|
||||||
///
|
///
|
||||||
/// assert(listener:local_addr() == net.socketaddr("127.0.0.1:1234"))
|
/// assert(listener:local_addr():ip() == net.ipaddr("127.0.0.1"))
|
||||||
///
|
///
|
||||||
/// for stream in listener do
|
/// for stream in listener do
|
||||||
/// print("client connected: ", stream:remote_addr())
|
/// print("client connected: ", stream:peer_addr())
|
||||||
/// end
|
/// end
|
||||||
|
/// ```
|
||||||
pub extern "Lua" fn listen_tcp(
|
pub extern "Lua" fn listen_tcp(
|
||||||
addr: OneOf<(&str, &lb_ipaddr, &lb_socketaddr)>,
|
addr: OneOf<(&str, &lb_ipaddr, &lb_socketaddr)>,
|
||||||
port: Option<u16>,
|
port: Option<u16>,
|
||||||
@ -287,9 +288,10 @@ impl lb_netlib {
|
|||||||
///
|
///
|
||||||
/// ```lua
|
/// ```lua
|
||||||
/// local net = require("lb:net")
|
/// local net = require("lb:net")
|
||||||
/// local stream = net.connect_tcp("127.0.0.1", 1234)
|
/// local listener = net.listen_tcp("127.0.0.1")
|
||||||
|
/// local stream = net.connect_tcp("127.0.0.1", listener:local_addr():port())
|
||||||
///
|
///
|
||||||
/// assert(stream:remote_addr() == net.socketaddr("127.0.0.1:1234"))
|
/// assert(stream:peer_addr():ip() == net.ipaddr("127.0.0.1"))
|
||||||
/// stream:write("Hello, server!\n")
|
/// stream:write("Hello, server!\n")
|
||||||
/// ```
|
/// ```
|
||||||
pub async extern "Lua" fn connect_tcp(
|
pub async extern "Lua" fn connect_tcp(
|
||||||
|
@ -183,7 +183,7 @@ impl lb_tcpsocket {
|
|||||||
///
|
///
|
||||||
/// This examples spawns a reader task and a writer task to operate on the stream concurrently.
|
/// This examples spawns a reader task and a writer task to operate on the stream concurrently.
|
||||||
///
|
///
|
||||||
/// ```lua
|
/// ```lua,no_run
|
||||||
/// local task = require("lb:task")
|
/// local task = require("lb:task")
|
||||||
/// local net = require("lb:net")
|
/// local net = require("lb:net")
|
||||||
/// local socket = net.connect_tcp("127.0.0.1:1234")
|
/// local socket = net.connect_tcp("127.0.0.1:1234")
|
||||||
@ -194,17 +194,17 @@ impl lb_tcpsocket {
|
|||||||
/// local reader = spawn(function()
|
/// local reader = spawn(function()
|
||||||
/// for chunk in socket, 1024 do
|
/// for chunk in socket, 1024 do
|
||||||
/// print("received: ", chunk)
|
/// print("received: ", chunk)
|
||||||
/// done
|
/// end
|
||||||
///
|
///
|
||||||
/// print("done reading")
|
/// print("done reading")
|
||||||
/// end)
|
/// end)
|
||||||
///
|
///
|
||||||
/// local writer = spawn(function()
|
/// local writer = spawn(function()
|
||||||
/// for i = 1, 10 do
|
/// for i = 1, 10 do
|
||||||
/// local msg = ("message %d\n"):format(i)
|
/// local msg = ("message %d"):format(i)
|
||||||
/// socket:write(msg)
|
/// socket:write(msg)
|
||||||
/// print("sent: ", msg)
|
/// print("sent: ", msg)
|
||||||
/// done
|
/// end
|
||||||
///
|
///
|
||||||
/// print("done writing")
|
/// print("done writing")
|
||||||
/// end)
|
/// end)
|
||||||
@ -215,7 +215,10 @@ impl lb_tcpsocket {
|
|||||||
/// The above example uses the socket as an iterator in a generic `for` loop to read data in chunks
|
/// The above example uses the socket as an iterator in a generic `for` loop to read data in chunks
|
||||||
/// of up to 1024 bytes. It is equivalent to the following:
|
/// of up to 1024 bytes. It is equivalent to the following:
|
||||||
///
|
///
|
||||||
/// ```lua
|
/// ```lua,no_run
|
||||||
|
/// local net = require("lb:net")
|
||||||
|
/// local socket = net.connect_tcp("127.0.0.1:1234")
|
||||||
|
///
|
||||||
/// while true do
|
/// while true do
|
||||||
/// local chunk = socket:read_partial(1024)
|
/// local chunk = socket:read_partial(1024)
|
||||||
/// if chunk == nil then break end
|
/// if chunk == nil then break end
|
||||||
@ -430,7 +433,7 @@ impl lb_tcpstream {
|
|||||||
///
|
///
|
||||||
/// The listener can be used as an iterator in a generic `for` loop to accept incoming connections:
|
/// The listener can be used as an iterator in a generic `for` loop to accept incoming connections:
|
||||||
///
|
///
|
||||||
/// ```lua
|
/// ```lua,no_run
|
||||||
/// local net = require("lb:net")
|
/// local net = require("lb:net")
|
||||||
/// local listener = net.listen_tcp("127.0.0.1")
|
/// local listener = net.listen_tcp("127.0.0.1")
|
||||||
///
|
///
|
||||||
|
@ -12,6 +12,7 @@ local color = {
|
|||||||
reset = "\x1b[0m",
|
reset = "\x1b[0m",
|
||||||
pass = "\x1b[32;1m", -- green
|
pass = "\x1b[32;1m", -- green
|
||||||
fail = "\x1b[31;1m", -- red
|
fail = "\x1b[31;1m", -- red
|
||||||
|
faint = "\x1b[2;39;49m", -- faint
|
||||||
}
|
}
|
||||||
|
|
||||||
local icon = {
|
local icon = {
|
||||||
@ -24,6 +25,12 @@ local function style(name, s)
|
|||||||
return ("%s%s%s"):format(color[name], s, color.reset)
|
return ("%s%s%s"):format(color[name], s, color.reset)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function rjust(s, w)
|
||||||
|
if w == nil then w = 12 end
|
||||||
|
if #s >= w then return s end
|
||||||
|
return (" "):rep(w - #s) .. s
|
||||||
|
end
|
||||||
|
|
||||||
local function create_test(name, f, group)
|
local function create_test(name, f, group)
|
||||||
local test = { type = "test", name = name or "", group = group, state = "pending", f = f }
|
local test = { type = "test", name = name or "", group = group, state = "pending", f = f }
|
||||||
local fenv = setmetatable({}, { __index = global, __newindex = global })
|
local fenv = setmetatable({}, { __index = global, __newindex = global })
|
||||||
@ -67,13 +74,13 @@ local function trace(msg)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function run_test(test)
|
local function run_test(test)
|
||||||
local ok, res = xpcall(test.f, trace, test)
|
local ok, trace = xpcall(test.f, trace, test)
|
||||||
if ok then
|
if ok then
|
||||||
test.state = "pass"
|
test.state = "pass"
|
||||||
print("", ("%s %s"):format(style("pass", "PASS"), name_test(test)))
|
print(("%s %s"):format(style("pass", rjust("PASS")), name_test(test)))
|
||||||
else
|
else
|
||||||
test.state = "fail"
|
test.state = "fail"
|
||||||
print("", ("%s %s\n\n%s\n"):format(style("fail", "FAIL"), name_test(test), res))
|
print(("%s %s\n\n%s\n"):format(style("fail", rjust("!!! FAIL")), name_test(test), trace))
|
||||||
end
|
end
|
||||||
collectgarbage() -- gc after each test to test destructors
|
collectgarbage() -- gc after each test to test destructors
|
||||||
return test
|
return test
|
||||||
@ -118,28 +125,28 @@ local function main(item)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
local elapsed = time:elapsed_secs()
|
local elapsed = time:elapsed_secs()
|
||||||
local code = 1
|
local retcode
|
||||||
if fail == 0 then
|
if fail == 0 then
|
||||||
print("", style("pass", ("%s %d tests passed"):format(icon.check, pass)))
|
print(style("pass", ("\t%s %d tests passed"):format(icon.check, pass)))
|
||||||
code = 0
|
retcode = 0
|
||||||
else
|
else
|
||||||
print(
|
print(
|
||||||
"",
|
("\t%s, %s"):format(
|
||||||
("%s, %s"):format(
|
|
||||||
style("pass", ("%s %d tests passed"):format(icon.check, pass)),
|
style("pass", ("%s %d tests passed"):format(icon.check, pass)),
|
||||||
style("fail", ("%s %d tests failed"):format(icon.cross, fail))
|
style("fail", ("%s %d tests failed"):format(icon.cross, fail))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
retcode = 1
|
||||||
end
|
end
|
||||||
if elapsed < 1000 then
|
if elapsed < 1000 then
|
||||||
print("", ("%s completed in %.2f ms"):format(icon.chevron, elapsed * 1000))
|
print(style("faint", ("\t%s completed in %.2f ms"):format(icon.chevron, elapsed * 1000)))
|
||||||
else
|
else
|
||||||
print("", ("%s completed in %.2f s"):format(icon.chevron, elapsed))
|
print(style("faint", ("\t%s completed in %.2f s"):format(icon.chevron, elapsed)))
|
||||||
end
|
end
|
||||||
cx = nil
|
cx = nil
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
check_refs()
|
check_refs() -- check that all refs were properly unref'ed in destructors
|
||||||
return code -- report error to cargo
|
return retcode -- report error to cargo
|
||||||
end
|
end
|
||||||
|
|
||||||
return main(create_group("", function()
|
return main(create_group("", function()
|
||||||
@ -152,6 +159,34 @@ return main(create_group("", function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function include_doctest(path, pat)
|
||||||
|
for entry in fs.glob_dir(path, pat) do
|
||||||
|
local line, doctest = 0, nil
|
||||||
|
for s in fs.read(entry:path()):gmatch("([^\n]*)\n?") do
|
||||||
|
line = line + 1
|
||||||
|
local prefix = s:match("^%s*///")
|
||||||
|
s = prefix and s:sub(#prefix + 1)
|
||||||
|
if s and not s:match("^%s*```%s*$") then
|
||||||
|
if s:match("^%s*```lua$") then
|
||||||
|
doctest = { line = line, col = #prefix + 2 }
|
||||||
|
elseif doctest then
|
||||||
|
table.insert(doctest, (" "):rep(#prefix) .. s)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if doctest then
|
||||||
|
local name = ("%s:%d:%d"):format(entry:path(), doctest.line, doctest.col)
|
||||||
|
local f, err = loadstring(table.concat(doctest, "\n"), "@" .. name)
|
||||||
|
if not f then error(err) end
|
||||||
|
test(("%s %s"):format(name, style("faint", "(doctest)")), f)
|
||||||
|
end
|
||||||
|
doctest = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
include("tests", "**/*.lua")
|
include("tests", "**/*.lua")
|
||||||
include("crates", "*/tests/**/*.lua")
|
include("crates", "*/tests/**/*.lua")
|
||||||
|
include_doctest("src", "**/*.rs")
|
||||||
|
include_doctest("crates", "*/src/**/*.rs")
|
||||||
end))
|
end))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user