148 lines
4.1 KiB
Rust
148 lines
4.1 KiB
Rust
use std::{
|
|
env,
|
|
ffi::OsStr,
|
|
fs,
|
|
path::{Path, PathBuf},
|
|
process::{Command, Output},
|
|
sync::atomic::{AtomicUsize, Ordering},
|
|
};
|
|
|
|
static NEXT_FIXTURE_ID: AtomicUsize = AtomicUsize::new(0);
|
|
|
|
const EXPECTED_TEST_OUTPUT: &str = concat!(
|
|
"test \"i32 bit and\" ... ok\n",
|
|
"test \"i32 bit or\" ... ok\n",
|
|
"test \"i32 bit xor\" ... ok\n",
|
|
"test \"i64 bit and\" ... ok\n",
|
|
"test \"i64 bit or\" ... ok\n",
|
|
"test \"i64 bit xor\" ... ok\n",
|
|
"test \"integer bitwise summary\" ... ok\n",
|
|
"7 test(s) passed\n",
|
|
);
|
|
|
|
#[test]
|
|
fn integer_bitwise_fixture_formats_lowers_and_runs() {
|
|
let fixture = Path::new(env!("CARGO_MANIFEST_DIR")).join("../examples/integer-bitwise.slo");
|
|
|
|
let fmt = run_glagol([
|
|
OsStr::new("fmt"),
|
|
OsStr::new("--check"),
|
|
fixture.as_os_str(),
|
|
]);
|
|
assert_success("format integer bitwise fixture", &fmt);
|
|
|
|
let check = run_glagol([OsStr::new("check"), fixture.as_os_str()]);
|
|
assert_success_stdout(check, "", "check integer bitwise fixture");
|
|
|
|
let llvm = run_glagol([fixture.as_os_str()]);
|
|
assert_success("compile integer bitwise fixture", &llvm);
|
|
let stdout = String::from_utf8_lossy(&llvm.stdout);
|
|
assert!(
|
|
stdout.contains("and i32")
|
|
&& stdout.contains("or i32")
|
|
&& stdout.contains("xor i32")
|
|
&& stdout.contains("and i64")
|
|
&& stdout.contains("or i64")
|
|
&& stdout.contains("xor i64"),
|
|
"integer bitwise LLVM shape drifted\nstdout:\n{}",
|
|
stdout
|
|
);
|
|
|
|
let tests = run_glagol([OsStr::new("test"), fixture.as_os_str()]);
|
|
assert_success_stdout(tests, EXPECTED_TEST_OUTPUT, "test integer bitwise fixture");
|
|
}
|
|
|
|
#[test]
|
|
fn integer_bitwise_rejections_are_explicit() {
|
|
let f64_fixture = write_fixture(
|
|
"f64-bitwise",
|
|
"(module main)\n\n(fn main () -> i32\n (if (= (bit_and 5.0 2.0) 0.0) 0 1))\n",
|
|
);
|
|
let f64_output = run_glagol([f64_fixture.as_os_str()]);
|
|
assert_failure_contains(
|
|
&f64_output,
|
|
"f64 bitwise rejection",
|
|
&[
|
|
"UnsupportedF64Bitwise",
|
|
"floating-point bitwise operations are not supported",
|
|
"f64 bitwise operations remain deferred",
|
|
],
|
|
);
|
|
}
|
|
|
|
fn run_glagol<I, S>(args: I) -> Output
|
|
where
|
|
I: IntoIterator<Item = S>,
|
|
S: AsRef<OsStr>,
|
|
{
|
|
Command::new(env!("CARGO_BIN_EXE_glagol"))
|
|
.args(args)
|
|
.current_dir(Path::new(env!("CARGO_MANIFEST_DIR")))
|
|
.output()
|
|
.expect("run glagol")
|
|
}
|
|
|
|
fn write_fixture(name: &str, source: &str) -> PathBuf {
|
|
let mut path = env::temp_dir();
|
|
path.push(format!(
|
|
"glagol-{}-{}-{}.slo",
|
|
name,
|
|
std::process::id(),
|
|
NEXT_FIXTURE_ID.fetch_add(1, Ordering::Relaxed)
|
|
));
|
|
fs::write(&path, source).unwrap_or_else(|err| panic!("write `{}`: {}", path.display(), err));
|
|
path
|
|
}
|
|
|
|
fn assert_success(context: &str, output: &Output) {
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
|
|
assert!(
|
|
output.status.success(),
|
|
"{} failed\nstdout:\n{}\nstderr:\n{}",
|
|
context,
|
|
stdout,
|
|
stderr
|
|
);
|
|
assert!(stderr.is_empty(), "{} wrote stderr:\n{}", context, stderr);
|
|
}
|
|
|
|
fn assert_success_stdout(output: Output, expected: &str, context: &str) {
|
|
assert_success(context, &output);
|
|
assert_eq!(
|
|
String::from_utf8_lossy(&output.stdout),
|
|
expected,
|
|
"{} stdout drifted",
|
|
context
|
|
);
|
|
}
|
|
|
|
fn assert_failure_contains(output: &Output, context: &str, expected: &[&str]) {
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
|
|
assert!(
|
|
!output.status.success(),
|
|
"{} unexpectedly succeeded\nstdout:\n{}\nstderr:\n{}",
|
|
context,
|
|
stdout,
|
|
stderr
|
|
);
|
|
assert!(
|
|
stdout.is_empty(),
|
|
"{} wrote stdout on failure:\n{}",
|
|
context,
|
|
stdout
|
|
);
|
|
for needle in expected {
|
|
assert!(
|
|
stderr.contains(needle),
|
|
"{} stderr missing `{}`\nstderr:\n{}",
|
|
context,
|
|
needle,
|
|
stderr
|
|
);
|
|
}
|
|
}
|