add: main function
This commit is contained in:
80
tests/hello_rpg.rs
Normal file
80
tests/hello_rpg.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
//! 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}",
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user