Unquoted tokens are now expanded through a tilde → brace → glob pipeline
in parse_argv. Quoted tokens (single, double, or backslash) suppress all
expansion. Uses glob(3) with GLOB_NOCHECK for wildcard matching and manual
implementations for tilde (~→$HOME) and brace ({a,b,c}) expansion.
136 lines
3.5 KiB
Lua
136 lines
3.5 KiB
Lua
-- testes/lush/globbing.lua
|
|
-- Tests for shell globbing (#13) and tilde expansion (#18).
|
|
|
|
print "testing globbing and tilde expansion"
|
|
|
|
-- === wildcard expansion ===
|
|
|
|
-- *.lua should expand to matching files (we know lush test files exist)
|
|
do
|
|
local r = `echo *.c`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
-- should NOT be the literal "*.c" since .c files exist in the project
|
|
assert(out ~= "*.c", "expected *.c to expand, got literal: " .. out)
|
|
assert(out:find("lcmd.c"), "expected lcmd.c in expansion, got: " .. out)
|
|
end
|
|
|
|
-- no match: keeps literal pattern (GLOB_NOCHECK)
|
|
do
|
|
local r = `echo *.nonexistent_xyz_9876`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
assert(out == "*.nonexistent_xyz_9876",
|
|
"expected literal, got: " .. out)
|
|
end
|
|
|
|
-- ? single-char wildcard
|
|
do
|
|
-- create temp files to test ? pattern
|
|
os.execute("mkdir -p /tmp/_lush_glob_test")
|
|
os.execute("touch /tmp/_lush_glob_test/a1 /tmp/_lush_glob_test/b2")
|
|
local r = `echo /tmp/_lush_glob_test/?1`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
assert(out == "/tmp/_lush_glob_test/a1",
|
|
"expected ?1 match, got: " .. out)
|
|
os.execute("rm -rf /tmp/_lush_glob_test")
|
|
end
|
|
|
|
|
|
-- === quoting suppresses expansion ===
|
|
|
|
-- double-quoted glob stays literal
|
|
do
|
|
local r = `echo "*.c"`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
assert(out == "*.c", "double-quoted glob expanded: " .. out)
|
|
end
|
|
|
|
-- single-quoted glob stays literal
|
|
do
|
|
local r = `echo '*.c'`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
assert(out == "*.c", "single-quoted glob expanded: " .. out)
|
|
end
|
|
|
|
-- backslash-escaped glob stays literal
|
|
do
|
|
local r = `echo \*.c`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
assert(out == "*.c", "backslash-escaped glob expanded: " .. out)
|
|
end
|
|
|
|
|
|
-- === brace expansion ===
|
|
|
|
do
|
|
local r = `echo {a,b,c}`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
assert(out == "a b c", "brace expansion failed, got: " .. out)
|
|
end
|
|
|
|
-- brace with prefix
|
|
do
|
|
local r = `echo hello{world,there}`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
assert(out == "helloworld hellothere",
|
|
"brace prefix expansion failed, got: " .. out)
|
|
end
|
|
|
|
-- space inside braces: no expansion (treated as separate tokens)
|
|
do
|
|
local r = `echo {a, b}`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
-- with space after comma, the shell splits into tokens "{a," and "b}"
|
|
assert(out == "{a, b}", "space-in-braces should not expand, got: " .. out)
|
|
end
|
|
|
|
|
|
-- === tilde expansion ===
|
|
|
|
-- ~ expands to $HOME
|
|
do
|
|
local home = os.getenv("HOME")
|
|
local r = `echo ~`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
assert(out == home, "~ did not expand to HOME, got: " .. out)
|
|
end
|
|
|
|
-- ~/path expands to $HOME/path
|
|
do
|
|
local home = os.getenv("HOME")
|
|
local r = `echo ~/foo`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
assert(out == home .. "/foo",
|
|
"~/foo did not expand, got: " .. out)
|
|
end
|
|
|
|
-- quoted ~ stays literal
|
|
do
|
|
local r = `echo "~"`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
assert(out == "~", "quoted ~ expanded: " .. out)
|
|
end
|
|
|
|
-- cd ~ should work (builtin receives expanded path)
|
|
do
|
|
local before = `pwd`.stdout:gsub("\n$", "")
|
|
local home = os.getenv("HOME")
|
|
local r = `cd ~`
|
|
assert(r.code == 0, "cd ~ failed: " .. r.stderr)
|
|
local after = `pwd`.stdout:gsub("\n$", "")
|
|
assert(after == home, "cd ~ did not go home, got: " .. after)
|
|
`cd ${before}`
|
|
end
|
|
|
|
|
|
-- === expansion in pipelines ===
|
|
|
|
do
|
|
local r = `echo *.c | head -1`
|
|
local out = r.stdout:gsub("\n$", "")
|
|
-- pipeline should have expanded *.c before piping
|
|
assert(out ~= "*.c", "glob not expanded in pipeline, got: " .. out)
|
|
end
|
|
|
|
|
|
print "OK"
|