Add lush feature tests and fix /dev/full test for macOS
Add test suite under testes/lush/ covering backtick commands, argv
parsing, ${} interpolation, and $NAME environment variables. Wire
them into testes/all.lua so they run with the full Lua 5.5 suite.
Skip /dev/full test in files.lua when the device doesn't exist
(macOS has no /dev/full).
This commit is contained in:
@@ -199,6 +199,12 @@ dofile('bitwise.lua')
|
||||
assert(dofile('verybig.lua', true) == 10); collectgarbage()
|
||||
dofile('files.lua')
|
||||
|
||||
-- lush shell feature tests
|
||||
dofile('lush/commands.lua')
|
||||
dofile('lush/argv.lua')
|
||||
dofile('lush/interpolation.lua')
|
||||
dofile('lush/envvars.lua')
|
||||
|
||||
if #msgs > 0 then
|
||||
local m = table.concat(msgs, "\n ")
|
||||
warn("#tests not performed:\n ", m, "\n")
|
||||
|
||||
@@ -471,13 +471,15 @@ do print("testing flush")
|
||||
assert(io.flush()) -- write to device
|
||||
assert(f:close())
|
||||
|
||||
local f = io.output("/dev/full")
|
||||
local ok, f = pcall(io.output, "/dev/full")
|
||||
if ok then -- /dev/full exists (Linux); skip on macOS
|
||||
assert(f:write("abcd")) -- write to buffer
|
||||
assert(not f:flush()) -- cannot write to device
|
||||
assert(f:write("abcd")) -- write to buffer
|
||||
assert(not io.flush()) -- cannot write to device
|
||||
assert(f:close())
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- test for multiple arguments in 'lines'
|
||||
|
||||
53
testes/lush/argv.lua
Normal file
53
testes/lush/argv.lua
Normal file
@@ -0,0 +1,53 @@
|
||||
-- testes/lush/argv.lua
|
||||
-- Tests for argv parsing (issue #04).
|
||||
|
||||
print "testing argv parsing"
|
||||
|
||||
-- simple whitespace splitting
|
||||
do
|
||||
local r = `echo a b c`
|
||||
assert(r.stdout == "a b c\n")
|
||||
end
|
||||
|
||||
-- single-quoted strings (literal, no escapes)
|
||||
do
|
||||
local r = `echo 'hello world'`
|
||||
assert(r.stdout == "hello world\n")
|
||||
end
|
||||
|
||||
-- double-quoted strings
|
||||
do
|
||||
local r = `echo "hello world"`
|
||||
assert(r.stdout == "hello world\n")
|
||||
end
|
||||
|
||||
-- multiple quoted arguments
|
||||
do
|
||||
local r = `echo "a b" "c d"`
|
||||
assert(r.stdout == "a b c d\n")
|
||||
end
|
||||
|
||||
-- backslash escaping outside quotes
|
||||
do
|
||||
local r = `echo hello\ world`
|
||||
assert(r.stdout == "hello world\n")
|
||||
end
|
||||
|
||||
-- double-quote escapes: \" and \\
|
||||
do
|
||||
local r = `echo "hello\"world"`
|
||||
assert(r.stdout == 'hello"world\n')
|
||||
end
|
||||
|
||||
do
|
||||
local r = `echo "hello\\world"`
|
||||
assert(r.stdout == "hello\\world\n")
|
||||
end
|
||||
|
||||
-- tab escape in double quotes
|
||||
do
|
||||
local r = `echo "a\tb"`
|
||||
assert(r.stdout == "a\tb\n")
|
||||
end
|
||||
|
||||
print "OK"
|
||||
90
testes/lush/commands.lua
Normal file
90
testes/lush/commands.lua
Normal file
@@ -0,0 +1,90 @@
|
||||
-- testes/lush/commands.lua
|
||||
-- Tests for backtick command execution (issues #02, #03).
|
||||
|
||||
print "testing backtick commands"
|
||||
|
||||
-- basic command, result is a table with code/stdout/stderr
|
||||
do
|
||||
local r = `echo hello`
|
||||
assert(type(r) == "table")
|
||||
assert(type(r.code) == "number")
|
||||
assert(type(r.stdout) == "string")
|
||||
assert(type(r.stderr) == "string")
|
||||
end
|
||||
|
||||
-- successful command returns exit code 0
|
||||
do
|
||||
local r = `true`
|
||||
assert(r.code == 0)
|
||||
end
|
||||
|
||||
-- failed command returns non-zero exit code
|
||||
do
|
||||
local r = `false`
|
||||
assert(r.code == 1)
|
||||
end
|
||||
|
||||
-- specific exit codes are preserved
|
||||
do
|
||||
local r = `sh -c "exit 42"`
|
||||
assert(r.code == 42)
|
||||
end
|
||||
|
||||
-- command not found returns 127
|
||||
do
|
||||
local r = `nonexistent_command_xyz_999`
|
||||
assert(r.code == 127)
|
||||
end
|
||||
|
||||
-- stdout capture
|
||||
do
|
||||
local r = `echo hello`
|
||||
assert(r.stdout == "hello\n")
|
||||
end
|
||||
|
||||
-- stderr capture
|
||||
do
|
||||
local r = `sh -c "echo err >&2"`
|
||||
assert(r.stderr == "err\n")
|
||||
assert(r.stdout == "")
|
||||
end
|
||||
|
||||
-- stdout and stderr are independent
|
||||
do
|
||||
local r = `sh -c "echo out; echo err >&2"`
|
||||
assert(r.stdout == "out\n")
|
||||
assert(r.stderr == "err\n")
|
||||
end
|
||||
|
||||
-- empty command returns code 0 and empty strings
|
||||
do
|
||||
local r = ``
|
||||
assert(r.code == 0)
|
||||
assert(r.stdout == "")
|
||||
assert(r.stderr == "")
|
||||
end
|
||||
|
||||
-- multi-word output preserved
|
||||
do
|
||||
local r = `echo hello world`
|
||||
assert(r.stdout == "hello world\n")
|
||||
end
|
||||
|
||||
-- backtick as statement (result discarded, no error)
|
||||
do
|
||||
`true`
|
||||
end
|
||||
|
||||
-- backtick result used inline
|
||||
do
|
||||
local code = `true`.code
|
||||
assert(code == 0)
|
||||
end
|
||||
|
||||
-- multiline output captured
|
||||
do
|
||||
local r = `printf "a\nb\nc\n"`
|
||||
assert(r.stdout == "a\nb\nc\n")
|
||||
end
|
||||
|
||||
print "OK"
|
||||
69
testes/lush/envvars.lua
Normal file
69
testes/lush/envvars.lua
Normal file
@@ -0,0 +1,69 @@
|
||||
-- testes/lush/envvars.lua
|
||||
-- Tests for environment variable access with $NAME syntax (issue #05).
|
||||
|
||||
print "testing environment variables"
|
||||
|
||||
-- $NAME reads an existing environment variable
|
||||
do
|
||||
local p = $PATH
|
||||
assert(type(p) == "string")
|
||||
assert(#p > 0)
|
||||
end
|
||||
|
||||
-- $NAME returns nil for unset variable
|
||||
do
|
||||
local v = $_LUSH_TEST_UNSET_VAR
|
||||
assert(v == nil)
|
||||
end
|
||||
|
||||
-- $NAME = expr sets an environment variable
|
||||
do
|
||||
$_LUSH_TEST_A = "hello"
|
||||
assert($_LUSH_TEST_A == "hello")
|
||||
end
|
||||
|
||||
-- $NAME = expr with number coerces to string
|
||||
do
|
||||
$_LUSH_TEST_B = 42
|
||||
assert($_LUSH_TEST_B == "42")
|
||||
end
|
||||
|
||||
-- $NAME = nil unsets the variable
|
||||
do
|
||||
$_LUSH_TEST_C = "temp"
|
||||
assert($_LUSH_TEST_C == "temp")
|
||||
$_LUSH_TEST_C = nil
|
||||
assert($_LUSH_TEST_C == nil)
|
||||
end
|
||||
|
||||
-- env vars are visible to child processes
|
||||
do
|
||||
$_LUSH_TEST_D = "from_lush"
|
||||
local r = `sh -c "echo $_LUSH_TEST_D"`
|
||||
-- the $_LUSH_TEST_D here is NOT lush interpolation (no {}),
|
||||
-- it's a literal string passed to sh which expands it
|
||||
assert(r.stdout == "from_lush\n", r.stdout)
|
||||
end
|
||||
|
||||
-- overwriting an env var
|
||||
do
|
||||
$_LUSH_TEST_E = "first"
|
||||
$_LUSH_TEST_E = "second"
|
||||
assert($_LUSH_TEST_E == "second")
|
||||
end
|
||||
|
||||
-- env var used in interpolation
|
||||
do
|
||||
$_LUSH_TEST_F = "works"
|
||||
local r = `echo ${$_LUSH_TEST_F}`
|
||||
assert(r.stdout == "works\n")
|
||||
end
|
||||
|
||||
-- clean up
|
||||
$_LUSH_TEST_A = nil
|
||||
$_LUSH_TEST_B = nil
|
||||
$_LUSH_TEST_D = nil
|
||||
$_LUSH_TEST_E = nil
|
||||
$_LUSH_TEST_F = nil
|
||||
|
||||
print "OK"
|
||||
55
testes/lush/interpolation.lua
Normal file
55
testes/lush/interpolation.lua
Normal file
@@ -0,0 +1,55 @@
|
||||
-- testes/lush/interpolation.lua
|
||||
-- Tests for ${expr} interpolation in backtick commands (issue #02).
|
||||
|
||||
print "testing string interpolation"
|
||||
|
||||
-- single interpolation
|
||||
do
|
||||
local name = "world"
|
||||
local r = `echo ${name}`
|
||||
assert(r.stdout == "world\n")
|
||||
end
|
||||
|
||||
-- multiple interpolations
|
||||
do
|
||||
local a = "hello"
|
||||
local b = "world"
|
||||
local r = `echo ${a} ${b}`
|
||||
assert(r.stdout == "hello world\n")
|
||||
end
|
||||
|
||||
-- interpolation with number
|
||||
do
|
||||
local n = 42
|
||||
local r = `echo ${n}`
|
||||
assert(r.stdout == "42\n")
|
||||
end
|
||||
|
||||
-- interpolation with expression
|
||||
do
|
||||
local x = 3
|
||||
local r = `echo ${x + 1}`
|
||||
assert(r.stdout == "4\n")
|
||||
end
|
||||
|
||||
-- interpolation with string concatenation
|
||||
do
|
||||
local prefix = "hello"
|
||||
local r = `echo ${prefix .. " world"}`
|
||||
assert(r.stdout == "hello world\n")
|
||||
end
|
||||
|
||||
-- interpolation surrounded by literal text
|
||||
do
|
||||
local mid = "b"
|
||||
local r = `echo a${mid}c`
|
||||
assert(r.stdout == "abc\n")
|
||||
end
|
||||
|
||||
-- literal $ (not followed by {) is kept
|
||||
do
|
||||
local r = `echo $`
|
||||
assert(r.stdout == "$\n")
|
||||
end
|
||||
|
||||
print "OK"
|
||||
Reference in New Issue
Block a user