81 lines
3.2 KiB
Rust
81 lines
3.2 KiB
Rust
//! 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 <program> non-terminal.
|
|
assert!(
|
|
tree.contains("program"),
|
|
"parse tree does not mention <program>:\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}",
|
|
);
|
|
}
|