use fusevm::shell_builtins::*;
#[test]
fn all_canonical_builtin_names_map_correctly() {
let cases: &[(&str, u16)] = &[
("cd", BUILTIN_CD),
("pwd", BUILTIN_PWD),
("echo", BUILTIN_ECHO),
("print", BUILTIN_PRINT),
("printf", BUILTIN_PRINTF),
("export", BUILTIN_EXPORT),
("unset", BUILTIN_UNSET),
("source", BUILTIN_SOURCE),
("exit", BUILTIN_EXIT),
("return", BUILTIN_RETURN),
("true", BUILTIN_TRUE),
("false", BUILTIN_FALSE),
("test", BUILTIN_TEST),
(":", BUILTIN_COLON),
("local", BUILTIN_LOCAL),
("declare", BUILTIN_TYPESET),
("readonly", BUILTIN_READONLY),
("integer", BUILTIN_INTEGER),
("float", BUILTIN_FLOAT),
("read", BUILTIN_READ),
("mapfile", BUILTIN_MAPFILE),
("break", BUILTIN_BREAK),
("continue", BUILTIN_CONTINUE),
("shift", BUILTIN_SHIFT),
("eval", BUILTIN_EVAL),
("exec", BUILTIN_EXEC),
("command", BUILTIN_COMMAND),
("builtin", BUILTIN_BUILTIN),
("let", BUILTIN_LET),
("jobs", BUILTIN_JOBS),
("fg", BUILTIN_FG),
("bg", BUILTIN_BG),
("kill", BUILTIN_KILL),
("disown", BUILTIN_DISOWN),
("wait", BUILTIN_WAIT),
("suspend", BUILTIN_SUSPEND),
("history", BUILTIN_HISTORY),
("fc", BUILTIN_FC),
("r", BUILTIN_R),
("alias", BUILTIN_ALIAS),
("unalias", BUILTIN_UNALIAS),
("set", BUILTIN_SET),
("setopt", BUILTIN_SETOPT),
("unsetopt", BUILTIN_UNSETOPT),
("shopt", BUILTIN_SHOPT),
("emulate", BUILTIN_EMULATE),
("getopts", BUILTIN_GETOPTS),
("autoload", BUILTIN_AUTOLOAD),
("functions", BUILTIN_FUNCTIONS),
("unfunction", BUILTIN_UNFUNCTION),
("trap", BUILTIN_TRAP),
("pushd", BUILTIN_PUSHD),
("popd", BUILTIN_POPD),
("dirs", BUILTIN_DIRS),
("type", BUILTIN_TYPE),
("whence", BUILTIN_WHENCE),
("where", BUILTIN_WHERE),
("which", BUILTIN_WHICH),
("hash", BUILTIN_HASH),
("rehash", BUILTIN_REHASH),
("unhash", BUILTIN_UNHASH),
("compgen", BUILTIN_COMPGEN),
("complete", BUILTIN_COMPLETE),
("compopt", BUILTIN_COMPOPT),
("compadd", BUILTIN_COMPADD),
("compset", BUILTIN_COMPSET),
("compdef", BUILTIN_COMPDEF),
("compinit", BUILTIN_COMPINIT),
("cdreplay", BUILTIN_CDREPLAY),
("zstyle", BUILTIN_ZSTYLE),
("zmodload", BUILTIN_ZMODLOAD),
("bindkey", BUILTIN_BINDKEY),
("zle", BUILTIN_ZLE),
("vared", BUILTIN_VARED),
("zcompile", BUILTIN_ZCOMPILE),
("zformat", BUILTIN_ZFORMAT),
("zparseopts", BUILTIN_ZPARSEOPTS),
("zregexparse", BUILTIN_ZREGEXPARSE),
("ulimit", BUILTIN_ULIMIT),
("limit", BUILTIN_LIMIT),
("unlimit", BUILTIN_UNLIMIT),
("umask", BUILTIN_UMASK),
("times", BUILTIN_TIMES),
("caller", BUILTIN_CALLER),
("help", BUILTIN_HELP),
("enable", BUILTIN_ENABLE),
("disable", BUILTIN_DISABLE),
("noglob", BUILTIN_NOGLOB),
("ttyctl", BUILTIN_TTYCTL),
("sync", BUILTIN_SYNC),
("mkdir", BUILTIN_MKDIR),
("strftime", BUILTIN_STRFTIME),
("zsleep", BUILTIN_ZSLEEP),
("zsystem", BUILTIN_ZSYSTEM),
("pcre_compile", BUILTIN_PCRE_COMPILE),
("pcre_match", BUILTIN_PCRE_MATCH),
("pcre_study", BUILTIN_PCRE_STUDY),
("ztie", BUILTIN_ZTIE),
("zuntie", BUILTIN_ZUNTIE),
("zgdbmpath", BUILTIN_ZGDBMPATH),
("promptinit", BUILTIN_PROMPTINIT),
("prompt", BUILTIN_PROMPT),
("async", BUILTIN_ASYNC),
("await", BUILTIN_AWAIT),
("pmap", BUILTIN_PMAP),
("pgrep", BUILTIN_PGREP),
("peach", BUILTIN_PEACH),
("barrier", BUILTIN_BARRIER),
("intercept", BUILTIN_INTERCEPT),
("intercept_proceed", BUILTIN_INTERCEPT_PROCEED),
("doctor", BUILTIN_DOCTOR),
("dbview", BUILTIN_DBVIEW),
("profile", BUILTIN_PROFILE),
("zprof", BUILTIN_ZPROF),
("cat", BUILTIN_CAT),
("head", BUILTIN_HEAD),
("tail", BUILTIN_TAIL),
("wc", BUILTIN_WC),
("basename", BUILTIN_BASENAME),
("dirname", BUILTIN_DIRNAME),
("touch", BUILTIN_TOUCH),
("realpath", BUILTIN_REALPATH),
("sort", BUILTIN_SORT),
("find", BUILTIN_FIND),
("uniq", BUILTIN_UNIQ),
("cut", BUILTIN_CUT),
("tr", BUILTIN_TR),
("seq", BUILTIN_SEQ),
("rev", BUILTIN_REV),
("tee", BUILTIN_TEE),
("sleep", BUILTIN_SLEEP),
("whoami", BUILTIN_WHOAMI),
("id", BUILTIN_ID),
("hostname", BUILTIN_HOSTNAME),
("uname", BUILTIN_UNAME),
("date", BUILTIN_DATE),
("mktemp", BUILTIN_MKTEMP),
];
for (name, id) in cases {
assert_eq!(builtin_id(name), Some(*id), "mismatch for {:?}", name);
assert!(is_builtin(name), "{:?} should be a builtin", name);
assert!(*id < BUILTIN_MAX, "{:?} id {} exceeds BUILTIN_MAX {}", name, id, BUILTIN_MAX);
}
}
#[test]
fn all_aliases_share_canonical_id() {
let alias_cases: &[(&str, &str)] = &[
("chdir", "cd"),
(".", "source"),
("bye", "exit"),
("logout", "exit"),
("[", "test"),
("typeset", "declare"),
("readarray", "mapfile"),
("bind", "bindkey"),
];
for (alias, canonical) in alias_cases {
assert_eq!(
builtin_id(alias),
builtin_id(canonical),
"alias {:?} should match canonical {:?}",
alias,
canonical
);
}
}
#[test]
fn unknown_names_return_none() {
let unknowns = [
"",
"ls",
"grep",
"awk",
"sed",
"definitely_not_a_builtin_xyz",
"CD",
"PWD",
"cd ",
" cd",
"\tcd",
"cd\n",
"echo;",
"cd/",
];
for name in unknowns {
assert!(builtin_id(name).is_none(), "{:?} should not be a builtin", name);
assert!(!is_builtin(name));
}
}
#[test]
fn is_builtin_is_consistent_with_builtin_id() {
let names = [
"cd", "echo", "true", "false", ":", "test", "[", "type", "source",
".", "ls", "rm", "definitely_no_such_thing",
];
for n in names {
assert_eq!(is_builtin(n), builtin_id(n).is_some());
}
}
#[test]
fn all_builtin_ids_are_below_max() {
let ids = [
BUILTIN_CD, BUILTIN_PWD, BUILTIN_ECHO, BUILTIN_PRINT, BUILTIN_PRINTF,
BUILTIN_EXPORT, BUILTIN_UNSET, BUILTIN_SOURCE, BUILTIN_EXIT,
BUILTIN_RETURN, BUILTIN_TRUE, BUILTIN_FALSE, BUILTIN_TEST,
BUILTIN_COLON, BUILTIN_DOT, BUILTIN_LOCAL, BUILTIN_DECLARE,
BUILTIN_TYPESET, BUILTIN_READONLY, BUILTIN_INTEGER, BUILTIN_FLOAT,
BUILTIN_READ, BUILTIN_MAPFILE, BUILTIN_BREAK, BUILTIN_CONTINUE,
BUILTIN_SHIFT, BUILTIN_EVAL, BUILTIN_EXEC, BUILTIN_COMMAND,
BUILTIN_BUILTIN, BUILTIN_MKTEMP,
];
for id in ids {
assert!(id < BUILTIN_MAX);
}
}
#[test]
fn declare_and_typeset_both_map_to_typeset_id() {
assert_eq!(builtin_id("declare"), Some(BUILTIN_TYPESET));
assert_eq!(builtin_id("typeset"), Some(BUILTIN_TYPESET));
}
#[test]
fn unicode_and_case_variants_not_builtins() {
let variants = ["Cd", "CD", "ECHO", "Source", "CD", "SOURCE"];
for v in variants {
assert!(!is_builtin(v), "{:?} should not be a builtin", v);
}
}
#[test]
fn special_one_char_builtins() {
assert_eq!(builtin_id(":"), Some(BUILTIN_COLON));
assert_eq!(builtin_id("."), Some(BUILTIN_SOURCE));
assert_eq!(builtin_id("["), Some(BUILTIN_TEST));
assert_eq!(builtin_id("r"), Some(BUILTIN_R));
}
#[test]
fn no_builtin_returns_id_equal_to_max() {
for name in &[
"cd", "mktemp", "zprof", "sync", "barrier", "intercept_proceed",
] {
let id = builtin_id(name).expect("known builtin");
assert!(id < BUILTIN_MAX);
}
}