slovo/compiler/tests/standard_library_path_list_alpha.rs
2026-05-22 08:38:43 +02:00

109 lines
3.3 KiB
Rust

use std::{
env,
ffi::{OsStr, OsString},
fs,
path::{Path, PathBuf},
process::{Command, Output},
sync::atomic::{AtomicUsize, Ordering},
};
static NEXT_TEMP_ID: AtomicUsize = AtomicUsize::new(0);
const EXPECTED_OUTPUT: &str =
"test \"standard library path list discovery\" ... ok\n1 test(s) passed\n";
#[test]
fn slovo_std_path_accepts_os_path_list() {
let root = temp_root();
let first_std = root.join("first-empty-std");
let second_std = root.join("second-std");
let project = root.join("project");
let source_dir = project.join("src");
create_dir(&first_std);
create_dir(&second_std);
create_dir(&source_dir);
write(
&second_std.join("path_list_probe.slo"),
"(module path_list_probe (export value))\n\n(fn value () -> i32\n 51)\n",
);
write(
&project.join("slovo.toml"),
concat!(
"[project]\n",
"name = \"standard-library-path-list-alpha\"\n",
"source_root = \"src\"\n",
"entry = \"main\"\n",
),
);
write(
&source_dir.join("main.slo"),
concat!(
"(module main)\n\n",
"(import std.path_list_probe (value))\n\n",
"(fn main () -> i32\n",
" (value))\n\n",
"(test \"standard library path list discovery\"\n",
" (= (value) 51))\n",
),
);
let std_path = env::join_paths([first_std.as_os_str(), second_std.as_os_str()])
.expect("join std path list");
let check = run_glagol([OsStr::new("check"), project.as_os_str()], &root, &std_path);
assert_success_stdout(check, "", "standard library path list check");
let test = run_glagol([OsStr::new("test"), project.as_os_str()], &root, &std_path);
assert_success_stdout(test, EXPECTED_OUTPUT, "standard library path list test");
}
fn run_glagol<I, S>(args: I, cwd: &Path, std_path: &OsString) -> Output
where
I: IntoIterator<Item = S>,
S: AsRef<std::ffi::OsStr>,
{
Command::new(env!("CARGO_BIN_EXE_glagol"))
.args(args)
.current_dir(cwd)
.env("SLOVO_STD_PATH", std_path)
.output()
.expect("run 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));
}
fn temp_root() -> PathBuf {
let path = env::temp_dir().join(format!(
"glagol-standard-library-path-list-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);
}