144 lines
4.1 KiB
Rust
144 lines
4.1 KiB
Rust
use std::{
|
|
env,
|
|
ffi::OsStr,
|
|
fs,
|
|
path::Path,
|
|
process::{Command, Output},
|
|
sync::atomic::{AtomicUsize, Ordering},
|
|
};
|
|
|
|
static NEXT_TEMP_ID: AtomicUsize = AtomicUsize::new(0);
|
|
|
|
const EXPECTED_OUTPUT: &str =
|
|
"test \"installed stdlib source discovery\" ... ok\n1 test(s) passed\n";
|
|
|
|
#[test]
|
|
fn copied_binary_discovers_installed_share_slovo_std() {
|
|
let root = temp_root();
|
|
let bin_dir = root.join("bin");
|
|
let std_dir = root.join("share/slovo/std");
|
|
let project = root.join("project");
|
|
let source_dir = project.join("src");
|
|
let installed_glagol = bin_dir.join("glagol");
|
|
|
|
create_dir(&bin_dir);
|
|
create_dir(&std_dir);
|
|
create_dir(&source_dir);
|
|
|
|
fs::copy(env!("CARGO_BIN_EXE_glagol"), &installed_glagol).unwrap_or_else(|err| {
|
|
panic!(
|
|
"copy glagol binary to `{}` failed: {}",
|
|
installed_glagol.display(),
|
|
err
|
|
)
|
|
});
|
|
make_executable(&installed_glagol);
|
|
|
|
write(
|
|
&std_dir.join("installed_probe.slo"),
|
|
"(module installed_probe (export value))\n\n(fn value () -> i32\n 42)\n",
|
|
);
|
|
write(
|
|
&project.join("slovo.toml"),
|
|
concat!(
|
|
"[project]\n",
|
|
"name = \"installed-stdlib-discovery-alpha\"\n",
|
|
"source_root = \"src\"\n",
|
|
"entry = \"main\"\n",
|
|
),
|
|
);
|
|
write(
|
|
&source_dir.join("main.slo"),
|
|
concat!(
|
|
"(module main)\n\n",
|
|
"(import std.installed_probe (value))\n\n",
|
|
"(fn main () -> i32\n",
|
|
" (value))\n\n",
|
|
"(test \"installed stdlib source discovery\"\n",
|
|
" (= (value) 42))\n",
|
|
),
|
|
);
|
|
|
|
assert!(
|
|
!project.join("src/installed_probe.slo").exists(),
|
|
"fixture must not carry a local installed_probe module copy"
|
|
);
|
|
|
|
let check = run_installed_glagol(
|
|
&installed_glagol,
|
|
[OsStr::new("check"), project.as_os_str()],
|
|
&root,
|
|
);
|
|
assert_success_stdout(check, "", "installed stdlib discovery check");
|
|
|
|
let test = run_installed_glagol(
|
|
&installed_glagol,
|
|
[OsStr::new("test"), project.as_os_str()],
|
|
&root,
|
|
);
|
|
assert_success_stdout(test, EXPECTED_OUTPUT, "installed stdlib discovery test");
|
|
}
|
|
|
|
fn run_installed_glagol<I, S>(binary: &Path, args: I, cwd: &Path) -> Output
|
|
where
|
|
I: IntoIterator<Item = S>,
|
|
S: AsRef<std::ffi::OsStr>,
|
|
{
|
|
Command::new(binary)
|
|
.args(args)
|
|
.current_dir(cwd)
|
|
.env_remove("SLOVO_STD_PATH")
|
|
.output()
|
|
.expect("run installed glagol")
|
|
}
|
|
|
|
fn write(path: &Path, content: &str) {
|
|
fs::write(path, content).unwrap_or_else(|err| panic!("write `{}`: {}", path.display(), err));
|
|
}
|
|
|
|
fn create_dir(path: &Path) {
|
|
fs::create_dir_all(path).unwrap_or_else(|err| panic!("create `{}`: {}", path.display(), err));
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
fn make_executable(path: &Path) {
|
|
use std::os::unix::fs::PermissionsExt;
|
|
|
|
let mut permissions = fs::metadata(path)
|
|
.unwrap_or_else(|err| panic!("metadata `{}`: {}", path.display(), err))
|
|
.permissions();
|
|
permissions.set_mode(permissions.mode() | 0o755);
|
|
fs::set_permissions(path, permissions)
|
|
.unwrap_or_else(|err| panic!("chmod `{}`: {}", path.display(), err));
|
|
}
|
|
|
|
#[cfg(not(unix))]
|
|
fn make_executable(_path: &Path) {}
|
|
|
|
fn temp_root() -> std::path::PathBuf {
|
|
let path = env::temp_dir().join(format!(
|
|
"glagol-installed-stdlib-discovery-alpha-{}-{}",
|
|
std::process::id(),
|
|
NEXT_TEMP_ID.fetch_add(1, Ordering::Relaxed)
|
|
));
|
|
let _ = fs::remove_dir_all(&path);
|
|
fs::create_dir_all(&path).unwrap_or_else(|err| panic!("create `{}`: {}", path.display(), err));
|
|
path
|
|
}
|
|
|
|
fn assert_success_stdout(output: Output, expected: &str, context: &str) {
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
|
|
assert!(
|
|
output.status.success(),
|
|
"{} failed\nstatus: {:?}\nstdout:\n{}\nstderr:\n{}",
|
|
context,
|
|
output.status.code(),
|
|
stdout,
|
|
stderr
|
|
);
|
|
assert_eq!(stdout, expected, "{}", context);
|
|
assert!(stderr.is_empty(), "{} wrote stderr:\n{}", context, stderr);
|
|
}
|