use std::{ fs, path::PathBuf, process::{Command, Output}, sync::atomic::{AtomicUsize, Ordering}, }; static NEXT_ID: AtomicUsize = AtomicUsize::new(0); #[test] fn beta_scaffolded_project_runs_current_v1_7_gate_workflow() { let project = unique_path("beta-project"); let scaffold = run_glagol(["new".as_ref(), project.as_os_str()]); assert_success("beta scaffold", &scaffold); fs::write( project.join("src/main.slo"), "(module main)\n\n(fn main () -> i32\n (let values (array i32 3) (array i32 2 3 4))\n (std.io.print_i32 (index values 1))\n 0)\n\n(test \"fixed array collection subset\"\n (= (index (array i32 1 2 3) 2) 3))\n", ) .expect("write beta project main"); let fmt_check = run_glagol(["fmt".as_ref(), "--check".as_ref(), project.as_os_str()]); assert_success("beta project fmt --check", &fmt_check); let test = run_glagol(["test".as_ref(), project.as_os_str()]); assert_success("beta project test", &test); assert_eq!( String::from_utf8_lossy(&test.stdout), "test \"fixed array collection subset\" ... ok\n1 test(s) passed\n" ); let docs = unique_path("beta-project-docs"); let doc = run_glagol([ "doc".as_ref(), project.as_os_str(), "-o".as_ref(), docs.as_os_str(), ]); assert_success("beta project doc", &doc); let doc_index = fs::read_to_string(docs.join("index.md")).expect("read beta docs"); assert!(doc_index.contains("# Project glagol-beta-")); assert!(doc_index.contains("- `main() -> i32`")); assert!(doc_index.contains("- `fixed array collection subset`")); let binary = unique_path("beta-project-bin"); let build = run_glagol([ "build".as_ref(), project.as_os_str(), "-o".as_ref(), binary.as_os_str(), ]); if build.status.success() { let run = Command::new(&binary).output().expect("run beta project"); assert_success("beta project binary", &run); assert_eq!(String::from_utf8_lossy(&run.stdout), "3\n"); } else { assert_stderr_contains("beta project build", &build, "ToolchainUnavailable"); } } fn unique_path(name: &str) -> PathBuf { let id = NEXT_ID.fetch_add(1, Ordering::Relaxed); let nanos = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .expect("system clock before UNIX_EPOCH") .as_nanos(); std::env::temp_dir().join(format!( "glagol-beta-{}-{}-{}-{}", std::process::id(), nanos, id, name )) } fn run_glagol(args: I) -> Output where I: IntoIterator, S: AsRef, { Command::new(env!("CARGO_BIN_EXE_glagol")) .args(args) .output() .expect("run glagol") } fn assert_success(context: &str, output: &Output) { assert!( output.status.success(), "{} failed\nstdout:\n{}\nstderr:\n{}", context, String::from_utf8_lossy(&output.stdout), String::from_utf8_lossy(&output.stderr) ); } fn assert_stderr_contains(context: &str, output: &Output, needle: &str) { let stderr = String::from_utf8_lossy(&output.stderr); assert!( stderr.contains(needle), "{} stderr did not contain `{}`:\n{}", context, needle, stderr ); }