157 lines
6.6 KiB
Rust
157 lines
6.6 KiB
Rust
use std::{fs, path::Path, process::Command};
|
|
|
|
#[test]
|
|
fn mutable_composite_locals_compile_lower_and_test() {
|
|
let fixture = "../examples/composite-locals.slo";
|
|
|
|
let compile = run_glagol([fixture]);
|
|
let llvm_stdout = String::from_utf8_lossy(&compile.stdout);
|
|
let llvm_stderr = String::from_utf8_lossy(&compile.stderr);
|
|
assert!(
|
|
compile.status.success(),
|
|
"compiler rejected mutable composite locals fixture\nstdout:\n{}\nstderr:\n{}",
|
|
llvm_stdout,
|
|
llvm_stderr
|
|
);
|
|
assert!(
|
|
llvm_stdout.contains("define ptr @swap_string(ptr %first, ptr %second)")
|
|
&& llvm_stdout.contains("define i64 @vec_i64_local_value()")
|
|
&& llvm_stdout.contains("define ptr @option_string_local_value()")
|
|
&& llvm_stdout.contains("define ptr @result_string_local_value()")
|
|
&& llvm_stdout.contains("define ptr @primitive_record_local_label()")
|
|
&& llvm_stdout.contains("define i32 @tagged_local_code()")
|
|
&& llvm_stdout.contains("alloca ptr")
|
|
&& llvm_stdout.contains("alloca { i1, ptr }")
|
|
&& llvm_stdout.contains("alloca { i1, ptr, i32 }")
|
|
&& llvm_stdout.contains("alloca { i32, i1, ptr }")
|
|
&& llvm_stdout.contains("alloca { i64, double }")
|
|
&& llvm_stdout.contains("alloca { i32, { i32, i32 } }"),
|
|
"LLVM output lost mutable composite local storage shape\nstdout:\n{}",
|
|
llvm_stdout
|
|
);
|
|
assert!(
|
|
llvm_stderr.is_empty(),
|
|
"compiler wrote stderr:\n{}",
|
|
llvm_stderr
|
|
);
|
|
|
|
let tests = run_glagol(["--run-tests", fixture]);
|
|
let tests_stdout = String::from_utf8_lossy(&tests.stdout);
|
|
let tests_stderr = String::from_utf8_lossy(&tests.stderr);
|
|
assert!(
|
|
tests.status.success(),
|
|
"test runner rejected mutable composite locals fixture\nstdout:\n{}\nstderr:\n{}",
|
|
tests_stdout,
|
|
tests_stderr
|
|
);
|
|
assert_eq!(
|
|
tests_stdout,
|
|
concat!(
|
|
"test \"mutable string local set works\" ... ok\n",
|
|
"test \"mutable vec i32 local set works\" ... ok\n",
|
|
"test \"mutable vec i64 local set works\" ... ok\n",
|
|
"test \"mutable vec f64 local set works\" ... ok\n",
|
|
"test \"mutable vec bool local set works\" ... ok\n",
|
|
"test \"mutable vec string local set works\" ... ok\n",
|
|
"test \"mutable option i32 local set works\" ... ok\n",
|
|
"test \"mutable option i64 local set works\" ... ok\n",
|
|
"test \"mutable option f64 local set works\" ... ok\n",
|
|
"test \"mutable option bool local set works\" ... ok\n",
|
|
"test \"mutable option string local set works\" ... ok\n",
|
|
"test \"mutable result i32 local set works\" ... ok\n",
|
|
"test \"mutable result i64 local set works\" ... ok\n",
|
|
"test \"mutable result f64 local set works\" ... ok\n",
|
|
"test \"mutable result bool local set works\" ... ok\n",
|
|
"test \"mutable result string local set works\" ... ok\n",
|
|
"test \"mutable plain struct local set works\" ... ok\n",
|
|
"test \"mutable primitive struct local set works\" ... ok\n",
|
|
"test \"mutable numeric struct local set works\" ... ok\n",
|
|
"test \"mutable payloadless enum local set works\" ... ok\n",
|
|
"test \"mutable payload enum local set works\" ... ok\n",
|
|
"test \"mutable enum struct local set works\" ... ok\n",
|
|
"22 test(s) passed\n",
|
|
),
|
|
"test runner output drifted"
|
|
);
|
|
assert!(
|
|
tests_stderr.is_empty(),
|
|
"test runner wrote stderr:\n{}",
|
|
tests_stderr
|
|
);
|
|
|
|
let expected = fs::read_to_string("../examples/composite-locals.slo").expect("read fixture");
|
|
let format = run_glagol(["--format", fixture]);
|
|
let format_stdout = String::from_utf8_lossy(&format.stdout);
|
|
let format_stderr = String::from_utf8_lossy(&format.stderr);
|
|
assert!(
|
|
format.status.success(),
|
|
"formatter rejected mutable composite locals fixture\nstdout:\n{}\nstderr:\n{}",
|
|
format_stdout,
|
|
format_stderr
|
|
);
|
|
assert_eq!(format_stdout, expected, "formatter output drifted");
|
|
assert!(
|
|
format_stderr.is_empty(),
|
|
"formatter wrote stderr:\n{}",
|
|
format_stderr
|
|
);
|
|
|
|
let surface = run_glagol(["--inspect-lowering=surface", fixture]);
|
|
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 mutable composite locals fixture\nstdout:\n{}\nstderr:\n{}",
|
|
surface_stdout,
|
|
surface_stderr
|
|
);
|
|
assert!(
|
|
surface_stdout.contains("local var current: string")
|
|
&& surface_stdout.contains("local var current: (vec i64)")
|
|
&& surface_stdout.contains("local var current: (option string)")
|
|
&& surface_stdout.contains("local var current: (result string i32)")
|
|
&& surface_stdout.contains("local var current: PrimitiveRecord")
|
|
&& surface_stdout.contains("local var current: Signal"),
|
|
"surface lowering lost mutable composite local declarations\nstdout:\n{}",
|
|
surface_stdout
|
|
);
|
|
assert!(
|
|
surface_stderr.is_empty(),
|
|
"surface lowering wrote stderr:\n{}",
|
|
surface_stderr
|
|
);
|
|
|
|
let checked = run_glagol(["--inspect-lowering=checked", fixture]);
|
|
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 mutable composite locals fixture\nstdout:\n{}\nstderr:\n{}",
|
|
checked_stdout,
|
|
checked_stderr
|
|
);
|
|
assert!(
|
|
checked_stdout.contains("var current : string")
|
|
&& checked_stdout.contains("var current : (vec i64)")
|
|
&& checked_stdout.contains("var current : (option string)")
|
|
&& checked_stdout.contains("var current : (result string i32)")
|
|
&& checked_stdout.contains("var current : PrimitiveRecord")
|
|
&& checked_stdout.contains("var current : Signal"),
|
|
"checked lowering lost typed mutable composite local flow\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")
|
|
}
|