//! Integration tests for the compiler binary against the Hello World program. use std::process::Command; /// `CARGO_BIN_EXE_rust-langrpg` is injected by Cargo for integration tests and /// always points at the freshly-built binary under `target/`. const BIN: &str = env!("CARGO_BIN_EXE_rust-langrpg"); /// Absolute path to hello.rpg, resolved at compile time relative to the crate /// root so the test works regardless of the working directory. const HELLO_RPG: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/hello.rpg"); // ───────────────────────────────────────────────────────────────────────────── // Helper // ───────────────────────────────────────────────────────────────────────────── fn run(args: &[&str]) -> std::process::Output { Command::new(BIN) .args(args) .output() .unwrap_or_else(|e| panic!("failed to spawn '{}': {e}", BIN)) } // ───────────────────────────────────────────────────────────────────────────── // Tests // ───────────────────────────────────────────────────────────────────────────── /// The compiler should exit 0 when given hello.rpg (no -o flag — tree is /// discarded but the parse must still succeed). #[test] fn hello_rpg_exits_ok() { let out = run(&[HELLO_RPG]); assert!( out.status.success(), "expected exit 0 for hello.rpg\nstderr: {}", String::from_utf8_lossy(&out.stderr), ); } /// When -o is supplied the output file must be created and contain a non-empty /// parse tree. #[test] fn hello_rpg_writes_tree() { let out_path = std::env::temp_dir().join("hello_rpg_test_tree.txt"); let out = run(&["-o", out_path.to_str().unwrap(), HELLO_RPG]); assert!( out.status.success(), "compiler failed with -o flag\nstderr: {}", String::from_utf8_lossy(&out.stderr), ); let tree = std::fs::read_to_string(&out_path) .unwrap_or_else(|e| panic!("could not read output file '{}': {e}", out_path.display())); assert!( !tree.trim().is_empty(), "output file is empty — expected a parse tree", ); // The tree should reference at least the top-level non-terminal. assert!( tree.contains("program"), "parse tree does not mention :\n{tree}", ); } /// The compiler must print the file name to stderr as "ok: hello.rpg" (or the /// full path) when the parse succeeds. #[test] fn hello_rpg_reports_ok_on_stderr() { let out = run(&[HELLO_RPG]); let stderr = String::from_utf8_lossy(&out.stderr); assert!( stderr.starts_with("ok:"), "expected stderr to start with 'ok:'\ngot: {stderr}", ); }