use assert_cmd::Command;
use predicates::prelude::*;
use predicates::str::contains;
use std::fs;
#[test]
fn help_is_generic_about_targets() {
Command::cargo_bin("hypothalamus")
.expect("binary should build")
.arg("--help")
.assert()
.success()
.stdout(contains("Hypothalamus - Brainfuck AOT compiler"))
.stdout(contains("--target <TARGET>"))
.stdout(contains("--list-targets"))
.stdout(contains("--gba-gcc").not());
}
#[test]
fn version_prints_package_version() {
Command::cargo_bin("hypothalamus")
.expect("binary should build")
.arg("--version")
.assert()
.success()
.stdout(contains(format!(
"hypothalamus {}",
env!("CARGO_PKG_VERSION")
)));
}
#[test]
fn list_targets_includes_current_presets() {
Command::cargo_bin("hypothalamus")
.expect("binary should build")
.arg("--list-targets")
.assert()
.success()
.stdout(contains("native"))
.stdout(contains("x86_64-none"))
.stdout(contains("i386-none"))
.stdout(contains("nds-arm9"))
.stdout(contains("gba"));
}
#[test]
fn emits_llvm_ir_to_stdout() {
Command::cargo_bin("hypothalamus")
.expect("binary should build")
.args(["--emit", "llvm-ir", "-o", "-", "examples/hello.bf"])
.assert()
.success()
.stdout(contains("; Generated by hypothalamus."))
.stdout(contains("define i32 @main()"))
.stdout(contains("@putchar"));
}
#[test]
fn writes_llvm_ir_to_output_file() {
let temp_dir = tempfile::tempdir().expect("create temp dir");
let output = temp_dir.path().join("hello.ll");
Command::cargo_bin("hypothalamus")
.expect("binary should build")
.args(["--emit", "llvm-ir", "examples/hello.bf", "-o"])
.arg(&output)
.assert()
.success();
let ir = fs::read_to_string(output).expect("read generated LLVM IR");
assert!(ir.contains("; Generated by hypothalamus."));
assert!(ir.contains("define i32 @main()"));
}
#[test]
fn rejects_stdout_output_for_non_llvm_ir_modes() {
for args in [
["--emit", "obj", "-o", "-", "examples/hello.bf"],
["--emit", "asm", "-o", "-", "examples/hello.bf"],
["--target", "gba", "-o", "-", "examples/hello.bf"],
] {
Command::cargo_bin("hypothalamus")
.expect("binary should build")
.args(args)
.assert()
.code(1)
.stderr(contains("--emit llvm-ir"));
}
}
#[test]
fn emits_custom_freestanding_symbols_to_stdout() {
Command::cargo_bin("hypothalamus")
.expect("binary should build")
.args([
"--freestanding",
"--entry",
"kernel_bf_main",
"--putchar-symbol",
"serial_write_byte",
"--getchar-symbol",
"serial_read_byte",
"--emit",
"llvm-ir",
"-o",
"-",
"examples/hello.bf",
])
.assert()
.success()
.stdout(contains("define void @kernel_bf_main()"))
.stdout(contains("declare void @serial_write_byte(i8)"))
.stdout(contains("declare i32 @serial_read_byte()"))
.stdout(contains("define i32 @main()").not());
}
#[test]
fn nds_arm9_target_emits_freestanding_llvm_ir() {
Command::cargo_bin("hypothalamus")
.expect("binary should build")
.args([
"--target",
"nds-arm9",
"--emit",
"llvm-ir",
"-o",
"-",
"examples/hello.bf",
])
.assert()
.success()
.stdout(contains("target triple = \"armv5te-none-eabi\""))
.stdout(contains("define void @bf_main()"))
.stdout(contains("declare void @bf_putchar(i8)"))
.stdout(contains("define i32 @main()").not());
}