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

128 lines
4.1 KiB
Rust

use std::{fs, path::Path, process::Command};
#[test]
fn while_fixture_emits_llvm_loop_shape() {
let output = run_glagol(["../tests/while.slo"]);
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
output.status.success(),
"compiler rejected while fixture\nstdout:\n{}\nstderr:\n{}",
stdout,
stderr
);
assert!(
stdout.contains("define i32 @count_to(i32 %limit)")
&& stdout.contains("while.cond")
&& stdout.contains("while.body")
&& stdout.contains("while.end")
&& stdout.contains("br i1")
&& stdout.contains("br label %while.cond"),
"LLVM output did not contain expected while loop shape\nstdout:\n{}",
stdout
);
assert!(
!stdout.contains("while counts"),
"compiler emitted test metadata into LLVM output\nstdout:\n{}",
stdout
);
assert!(stderr.is_empty(), "compiler wrote stderr:\n{}", stderr);
}
#[test]
fn while_fixture_runs_top_level_tests() {
let output = run_glagol(["--run-tests", "../tests/while.slo"]);
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
output.status.success(),
"test runner rejected while fixture\nstdout:\n{}\nstderr:\n{}",
stdout,
stderr
);
assert_eq!(
stdout,
concat!(
"test \"while counts\" ... ok\n",
"test \"while false skips\" ... ok\n",
"2 test(s) passed\n",
),
"test runner output drifted"
);
assert!(stderr.is_empty(), "test runner wrote stderr:\n{}", stderr);
}
#[test]
fn while_fixture_is_formatter_stable() {
let expected = fs::read_to_string("../tests/while.slo").expect("read fixture");
let output = run_glagol(["--format", "../tests/while.slo"]);
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
output.status.success(),
"formatter rejected while fixture\nstdout:\n{}\nstderr:\n{}",
stdout,
stderr
);
assert_eq!(stdout, expected, "formatter output drifted");
assert!(stderr.is_empty(), "formatter wrote stderr:\n{}", stderr);
}
#[test]
fn while_fixture_prints_lowered_shape() {
let surface = run_glagol(["--inspect-lowering=surface", "../tests/while.slo"]);
let surface_stdout = String::from_utf8_lossy(&surface.stdout);
let surface_stderr = String::from_utf8_lossy(&surface.stderr);
assert!(
surface.status.success(),
"surface lowering rejected while fixture\nstdout:\n{}\nstderr:\n{}",
surface_stdout,
surface_stderr
);
assert!(
surface_stdout.contains("while\n")
&& surface_stdout.contains("binary <")
&& surface_stdout.contains("set i"),
"surface lowering output lost while shape\nstdout:\n{}",
surface_stdout
);
assert!(
surface_stderr.is_empty(),
"surface lowering wrote stderr:\n{}",
surface_stderr
);
let checked = run_glagol(["--inspect-lowering=checked", "../tests/while.slo"]);
let checked_stdout = String::from_utf8_lossy(&checked.stdout);
let checked_stderr = String::from_utf8_lossy(&checked.stderr);
assert!(
checked.status.success(),
"checked lowering rejected while fixture\nstdout:\n{}\nstderr:\n{}",
checked_stdout,
checked_stderr
);
assert!(
checked_stdout.contains("while : unit")
&& checked_stdout.contains("binary < : bool")
&& checked_stdout.contains("set i : unit"),
"checked lowering output lost typed while shape\nstdout:\n{}",
checked_stdout
);
assert!(
checked_stderr.is_empty(),
"checked lowering wrote stderr:\n{}",
checked_stderr
);
}
fn run_glagol<const N: usize>(args: [&str; N]) -> std::process::Output {
Command::new(env!("CARGO_BIN_EXE_glagol"))
.args(args)
.current_dir(Path::new(env!("CARGO_MANIFEST_DIR")))
.output()
.expect("run glagol")
}