use super::*;
const HELLO_SCRIPT: &str = "#!/usr/bin/env bash
echo hello
";
#[test]
fn finds_executable() {
let tmp = tempdir();
let path = PathBuf::from(tmp.path());
Test::with_tempdir(tmp)
.justfile("p := which('hello.exe')")
.args(["--evaluate", "p"])
.write("hello.exe", HELLO_SCRIPT)
.make_executable("hello.exe")
.env("PATH", path.to_str().unwrap())
.env("JUST_UNSTABLE", "1")
.stdout(path.join("hello.exe").display().to_string())
.run();
}
#[test]
fn prints_empty_string_for_missing_executable() {
let tmp = tempdir();
let path = PathBuf::from(tmp.path());
Test::with_tempdir(tmp)
.justfile("p := which('goodbye.exe')")
.args(["--evaluate", "p"])
.write("hello.exe", HELLO_SCRIPT)
.make_executable("hello.exe")
.env("PATH", path.to_str().unwrap())
.env("JUST_UNSTABLE", "1")
.run();
}
#[test]
fn skips_non_executable_files() {
let tmp = tempdir();
let path = PathBuf::from(tmp.path());
Test::with_tempdir(tmp)
.justfile("p := which('hi')")
.args(["--evaluate", "p"])
.write("hello.exe", HELLO_SCRIPT)
.make_executable("hello.exe")
.write("hi", "just some regular file")
.env("PATH", path.to_str().unwrap())
.env("JUST_UNSTABLE", "1")
.run();
}
#[test]
fn supports_multiple_paths() {
let tmp = tempdir();
let path = PathBuf::from(tmp.path());
let path_var = env::join_paths([
path.join("subdir1").to_str().unwrap(),
path.join("subdir2").to_str().unwrap(),
])
.unwrap();
Test::with_tempdir(tmp)
.justfile("p := which('hello1.exe') + '+' + which('hello2.exe')")
.args(["--evaluate", "p"])
.write("subdir1/hello1.exe", HELLO_SCRIPT)
.make_executable("subdir1/hello1.exe")
.write("subdir2/hello2.exe", HELLO_SCRIPT)
.make_executable("subdir2/hello2.exe")
.env("PATH", path_var.to_str().unwrap())
.env("JUST_UNSTABLE", "1")
.stdout(format!(
"{}+{}",
path.join("subdir1").join("hello1.exe").display(),
path.join("subdir2").join("hello2.exe").display(),
))
.run();
}
#[test]
fn supports_shadowed_executables() {
enum Variation {
Dir1Dir2, Dir2Dir1, }
for variation in [Variation::Dir1Dir2, Variation::Dir2Dir1] {
let tmp = tempdir();
let path = PathBuf::from(tmp.path());
let path_var = match variation {
Variation::Dir1Dir2 => env::join_paths([
path.join("dir1").to_str().unwrap(),
path.join("dir2").to_str().unwrap(),
]),
Variation::Dir2Dir1 => env::join_paths([
path.join("dir2").to_str().unwrap(),
path.join("dir1").to_str().unwrap(),
]),
}
.unwrap();
let stdout = match variation {
Variation::Dir1Dir2 => format!("{}", path.join("dir1").join("shadowed.exe").display()),
Variation::Dir2Dir1 => format!("{}", path.join("dir2").join("shadowed.exe").display()),
};
Test::with_tempdir(tmp)
.justfile("p := which('shadowed.exe')")
.args(["--evaluate", "p"])
.write("dir1/shadowed.exe", HELLO_SCRIPT)
.make_executable("dir1/shadowed.exe")
.write("dir2/shadowed.exe", HELLO_SCRIPT)
.make_executable("dir2/shadowed.exe")
.env("PATH", path_var.to_str().unwrap())
.env("JUST_UNSTABLE", "1")
.stdout(stdout)
.run();
}
}
#[test]
fn ignores_nonexecutable_candidates() {
let tmp = tempdir();
let path = PathBuf::from(tmp.path());
let path_var = env::join_paths([
path.join("dummy").to_str().unwrap(),
path.join("subdir").to_str().unwrap(),
path.join("dummy").to_str().unwrap(),
])
.unwrap();
let dummy_exe = if cfg!(windows) {
"dummy/foo"
} else {
"dummy/foo.exe"
};
Test::with_tempdir(tmp)
.justfile("p := which('foo.exe')")
.args(["--evaluate", "p"])
.write("subdir/foo.exe", HELLO_SCRIPT)
.make_executable("subdir/foo.exe")
.write(dummy_exe, HELLO_SCRIPT)
.env("PATH", path_var.to_str().unwrap())
.env("JUST_UNSTABLE", "1")
.stdout(path.join("subdir").join("foo.exe").display().to_string())
.run();
}
#[test]
fn handles_absolute_path() {
let tmp = tempdir();
let path = PathBuf::from(tmp.path());
let abspath = path.join("subdir").join("foo.exe");
Test::with_tempdir(tmp)
.justfile(format!("p := which('{}')", abspath.display()))
.write("subdir/foo.exe", HELLO_SCRIPT)
.make_executable("subdir/foo.exe")
.write("pathdir/foo.exe", HELLO_SCRIPT)
.make_executable("pathdir/foo.exe")
.env("PATH", path.join("pathdir").to_str().unwrap())
.env("JUST_UNSTABLE", "1")
.args(["--evaluate", "p"])
.stdout(abspath.display().to_string())
.run();
}
#[test]
fn handles_dotslash() {
let tmp = tempdir();
let path = if cfg!(windows) {
tmp.path().into()
} else {
tmp.path().canonicalize().unwrap()
};
Test::with_tempdir(tmp)
.justfile("p := which('./foo.exe')")
.args(["--evaluate", "p"])
.write("foo.exe", HELLO_SCRIPT)
.make_executable("foo.exe")
.write("pathdir/foo.exe", HELLO_SCRIPT)
.make_executable("pathdir/foo.exe")
.env("PATH", path.join("pathdir").to_str().unwrap())
.env("JUST_UNSTABLE", "1")
.stdout(path.join("foo.exe").display().to_string())
.run();
}
#[test]
fn handles_dir_slash() {
let tmp = tempdir();
let path = if cfg!(windows) {
tmp.path().into()
} else {
tmp.path().canonicalize().unwrap()
};
Test::with_tempdir(tmp)
.justfile("p := which('subdir/foo.exe')")
.args(["--evaluate", "p"])
.write("subdir/foo.exe", HELLO_SCRIPT)
.make_executable("subdir/foo.exe")
.write("pathdir/foo.exe", HELLO_SCRIPT)
.make_executable("pathdir/foo.exe")
.env("PATH", path.join("pathdir").to_str().unwrap())
.env("JUST_UNSTABLE", "1")
.stdout(path.join("subdir").join("foo.exe").display().to_string())
.run();
}
#[test]
fn is_unstable() {
let tmp = tempdir();
let path = PathBuf::from(tmp.path());
Test::with_tempdir(tmp)
.justfile("p := which('hello.exe')")
.args(["--evaluate", "p"])
.write("hello.exe", HELLO_SCRIPT)
.make_executable("hello.exe")
.env("PATH", path.to_str().unwrap())
.stderr_regex(r".*The `which\(\)` function is currently unstable\..*")
.status(EXIT_FAILURE)
.run();
}
#[test]
fn require_error() {
Test::new()
.justfile("p := require('asdfasdf')")
.args(["--evaluate", "p"])
.stderr(
"
error: Call to function `require` failed: could not find executable `asdfasdf`
——▶ justfile:1:6
│
1 │ p := require('asdfasdf')
│ ^^^^^^^
",
)
.status(EXIT_FAILURE)
.run();
}
#[test]
fn require_success() {
let tmp = tempdir();
let path = PathBuf::from(tmp.path());
Test::with_tempdir(tmp)
.justfile("p := require('hello.exe')")
.args(["--evaluate", "p"])
.write("hello.exe", HELLO_SCRIPT)
.make_executable("hello.exe")
.env("PATH", path.to_str().unwrap())
.stdout(path.join("hello.exe").display().to_string())
.run();
}