97 lines
3.6 KiB
Rust
97 lines
3.6 KiB
Rust
use std::{fs, path::Path, process::Command};
|
|
|
|
#[test]
|
|
fn local_variables_emit_llvm_storage_and_loads() {
|
|
let output = run_glagol(["../tests/local-variables.slo"]);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
|
|
assert!(
|
|
output.status.success(),
|
|
"compiler rejected local variable fixture\nstdout:\n{}\nstderr:\n{}",
|
|
stdout,
|
|
stderr
|
|
);
|
|
assert!(
|
|
stdout.contains("define i32 @add_local(i32 %a)")
|
|
&& stdout.contains("%total.addr = alloca i32")
|
|
&& stdout.contains("add i32 %a, 1")
|
|
&& stdout.contains("store i32")
|
|
&& stdout.contains("load i32")
|
|
&& stdout.contains("define i1 @keep_flag(i1 %flag)")
|
|
&& !stdout.contains("%local_flag.addr = alloca i1")
|
|
&& stdout.contains("define i1 @flip_flag(i1 %flag)")
|
|
&& stdout.contains("%current.addr = alloca i1")
|
|
&& stdout.contains("%count.addr = alloca i64")
|
|
&& stdout.contains("%amount.addr = alloca double"),
|
|
"LLVM output did not contain expected local variable value/storage shape\nstdout:\n{}",
|
|
stdout
|
|
);
|
|
assert!(
|
|
!stdout.contains("locals work")
|
|
&& !stdout.contains("bool let locals work")
|
|
&& !stdout.contains("bool let locals preserve false")
|
|
&& !stdout.contains("bool var set flips true")
|
|
&& !stdout.contains("bool var set flips false")
|
|
&& !stdout.contains("i64 var set works")
|
|
&& !stdout.contains("f64 var set works"),
|
|
"compiler emitted test metadata into LLVM output\nstdout:\n{}",
|
|
stdout
|
|
);
|
|
assert!(stderr.is_empty(), "compiler wrote stderr:\n{}", stderr);
|
|
}
|
|
|
|
#[test]
|
|
fn local_variables_work_in_top_level_tests() {
|
|
let output = run_glagol(["--run-tests", "../tests/local-variables.slo"]);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
|
|
assert!(
|
|
output.status.success(),
|
|
"test runner rejected local variable fixture\nstdout:\n{}\nstderr:\n{}",
|
|
stdout,
|
|
stderr
|
|
);
|
|
assert_eq!(
|
|
stdout,
|
|
concat!(
|
|
"test \"locals work\" ... ok\n",
|
|
"test \"bool let locals work\" ... ok\n",
|
|
"test \"bool let locals preserve false\" ... ok\n",
|
|
"test \"bool var set flips true\" ... ok\n",
|
|
"test \"bool var set flips false\" ... ok\n",
|
|
"test \"i64 var set works\" ... ok\n",
|
|
"test \"f64 var set works\" ... ok\n",
|
|
"7 test(s) passed\n",
|
|
),
|
|
"test runner output drifted"
|
|
);
|
|
assert!(stderr.is_empty(), "test runner wrote stderr:\n{}", stderr);
|
|
}
|
|
|
|
#[test]
|
|
fn local_variable_fixture_is_formatter_stable() {
|
|
let expected = fs::read_to_string("../tests/local-variables.slo").expect("read fixture");
|
|
let output = run_glagol(["--format", "../tests/local-variables.slo"]);
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
|
|
assert!(
|
|
output.status.success(),
|
|
"formatter rejected local variable fixture\nstdout:\n{}\nstderr:\n{}",
|
|
stdout,
|
|
stderr
|
|
);
|
|
assert_eq!(stdout, expected, "formatter output drifted");
|
|
assert!(stderr.is_empty(), "formatter wrote stderr:\n{}", 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")
|
|
}
|