Tests hardcoded ./lua and assumed CWD was the project root. Add shared testutil.lua module to derive interpreter path from arg table, and use temp directories for glob tests instead of relying on .c files in CWD.
143 lines
3.6 KiB
Lua
143 lines
3.6 KiB
Lua
-- testes/lush/builtins.lua
|
|
-- Tests for shell builtins (issue #15): cd, exec, umask.
|
|
|
|
print "testing shell builtins"
|
|
|
|
local interp = require("lush.testutil").INTERP
|
|
|
|
-- === __builtins is NOT in _G (internal, stored in registry) ===
|
|
|
|
do
|
|
assert(__builtins == nil, "__builtins should not be in _G")
|
|
end
|
|
|
|
|
|
-- === cd ===
|
|
|
|
-- cd to absolute path
|
|
do
|
|
local before = `pwd`.stdout:gsub("\n$", "")
|
|
local r = `cd /tmp`
|
|
assert(r.code == 0, "cd /tmp failed: " .. r.stderr)
|
|
local after = `pwd`.stdout:gsub("\n$", "")
|
|
assert(after == "/private/tmp" or after == "/tmp",
|
|
"expected /tmp, got: " .. after)
|
|
`cd ${before}`
|
|
end
|
|
|
|
-- cd with no arg goes to $HOME
|
|
do
|
|
local before = `pwd`.stdout:gsub("\n$", "")
|
|
local home = os.getenv("HOME")
|
|
local r = `cd`
|
|
assert(r.code == 0, "cd (no arg) failed: " .. r.stderr)
|
|
local after = `pwd`.stdout:gsub("\n$", "")
|
|
assert(after == home, "expected HOME=" .. home .. ", got: " .. after)
|
|
`cd ${before}`
|
|
end
|
|
|
|
-- cd - goes to OLDPWD
|
|
do
|
|
local start = `pwd`.stdout:gsub("\n$", "")
|
|
`cd /tmp`
|
|
local r = `cd -`
|
|
assert(r.code == 0, "cd - failed: " .. r.stderr)
|
|
local after = `pwd`.stdout:gsub("\n$", "")
|
|
assert(after == start, "expected " .. start .. ", got: " .. after)
|
|
`cd ${start}`
|
|
end
|
|
|
|
-- cd updates $PWD and $OLDPWD
|
|
do
|
|
local before = `pwd`.stdout:gsub("\n$", "")
|
|
`cd /tmp`
|
|
local pwd = os.getenv("PWD")
|
|
local oldpwd = os.getenv("OLDPWD")
|
|
assert(pwd == "/private/tmp" or pwd == "/tmp",
|
|
"PWD not updated: " .. tostring(pwd))
|
|
assert(oldpwd == before,
|
|
"OLDPWD not updated: expected " .. before .. ", got: " .. tostring(oldpwd))
|
|
`cd ${before}`
|
|
end
|
|
|
|
-- cd to nonexistent directory returns error
|
|
do
|
|
local r = `cd /nonexistent_dir_xyz_999`
|
|
assert(r.code == 1)
|
|
assert(r.stderr:find("cd:"), "expected cd error, got: " .. r.stderr)
|
|
end
|
|
|
|
-- cd to relative path
|
|
do
|
|
local before = `pwd`.stdout:gsub("\n$", "")
|
|
`cd /tmp`
|
|
os.execute("mkdir -p /tmp/_lush_test_cd")
|
|
local r = `cd _lush_test_cd`
|
|
assert(r.code == 0, "cd relative failed: " .. r.stderr)
|
|
local after = `pwd`.stdout:gsub("\n$", "")
|
|
assert(after:find("_lush_test_cd"),
|
|
"expected to be in _lush_test_cd, got: " .. after)
|
|
`cd ${before}`
|
|
os.execute("rmdir /tmp/_lush_test_cd")
|
|
end
|
|
|
|
|
|
-- === umask ===
|
|
|
|
-- query umask (no arg)
|
|
do
|
|
local r = `umask`
|
|
assert(r.code == 0, "umask query failed: " .. r.stderr)
|
|
assert(r.stdout:match("^%d+"), "expected octal, got: " .. r.stdout)
|
|
end
|
|
|
|
-- set and restore umask
|
|
do
|
|
local orig = `umask`.stdout:gsub("%s+$", "")
|
|
local r = `umask 0077`
|
|
assert(r.code == 0, "umask set failed: " .. r.stderr)
|
|
local now = `umask`.stdout:gsub("%s+$", "")
|
|
assert(now == "0077", "expected 0077, got: " .. now)
|
|
-- restore original
|
|
`umask ${orig}`
|
|
local restored = `umask`.stdout:gsub("%s+$", "")
|
|
assert(restored == orig,
|
|
"expected " .. orig .. ", got: " .. restored)
|
|
end
|
|
|
|
-- invalid octal
|
|
do
|
|
local r = `umask banana`
|
|
assert(r.code == 1)
|
|
assert(r.stderr:find("invalid mode"),
|
|
"expected 'invalid mode', got: " .. r.stderr)
|
|
end
|
|
|
|
|
|
-- === exec ===
|
|
|
|
-- exec with no command returns error (tested via backtick)
|
|
do
|
|
local r = `exec`
|
|
assert(r.code == 1)
|
|
assert(r.stderr:find("command required"),
|
|
"expected 'command required', got: " .. r.stderr)
|
|
end
|
|
|
|
-- exec nonexistent command returns error
|
|
do
|
|
local r = `exec nonexistent_cmd_xyz_999`
|
|
assert(r.code == 1)
|
|
assert(r.stderr:find("exec:"),
|
|
"expected exec error, got: " .. r.stderr)
|
|
end
|
|
|
|
-- exec replaces process (test in subprocess)
|
|
do
|
|
local r = lush.capture("sh -c '" .. interp .. " -e \"os.exit(42)\"'")
|
|
assert(r.code == 42, "subprocess exit code: " .. tostring(r.code))
|
|
end
|
|
|
|
|
|
print "OK"
|