// SPDX-FileCopyrightText: 2026 Milovann Yanatchkov // SPDX-License-Identifier: MIT //! cli end-to-end (plan 3, S5): `bimr-cli build` on the wall corpus //! produces the compact BIMR source — master's format, with the //! documented self-reference fix (`Wall(l1, …)` not `Wall(w1, …)`). use std::fs; use std::path::PathBuf; use std::process::Command; /// Master's checked-in ifcx artifact for the corpus — the byte-parity target. const EXPECTED_IFCX: &str = include_str!("../../samples/bimr/wall.ifcx"); /// Per-user, cargo-managed temp dir — never the shared /tmp (sticky-bit /// collisions across users, see the PermissionDenied incident). fn tmp(name: &str) -> PathBuf { PathBuf::from(env!("CARGO_TARGET_TMPDIR")).join(name) } fn run_build(sample: &str, output: &PathBuf) -> Result { let root = env!("CARGO_MANIFEST_DIR"); let input = PathBuf::from(root).join("../samples/bimr").join(sample); let out = Command::new(env!("CARGO_BIN_EXE_bimr-cli")) .args([ "build", input.to_str().expect("utf8 path"), "--output", output.to_str().expect("utf8 path"), ]) .output() .map_err(|e| format!("spawn: {e}"))?; if !out.status.success() { return Err(format!( "bimr-cli failed: {}", String::from_utf8_lossy(&out.stderr) )); } fs::read_to_string(output).map_err(|e| format!("read output: {e}")) } #[test] fn build_wall_bimr_emits_master_ifcx() { let content = run_build("wall.bimr", &tmp("wall_out.ifcx")).expect("build ok"); assert_eq!(content, EXPECTED_IFCX); } #[test] fn build_rejects_unknown_constructors_cleanly() { let sample = tmp("reject.bimr"); fs::write(&sample, "x = Frob(p1)\n").expect("write sample"); let out = Command::new(env!("CARGO_BIN_EXE_bimr-cli")) .args(["build", sample.to_str().expect("utf8")]) .output() .expect("spawn"); assert!(!out.status.success(), "List must be rejected"); let stderr = String::from_utf8_lossy(&out.stderr); assert!( stderr.contains("not supported"), "rejection must name the failure: {stderr}" ); } #[test] fn build_output_defaults_to_ifcx_extension() { // The cli default is .ifcx (master parity) — run on a copy in the // target tmpdir so the copied corpus is never rewritten. let input = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../samples/bimr/wall.bimr"); let copy = tmp("wall_copy.bimr"); fs::copy(&input, ©).expect("copy"); let out = Command::new(env!("CARGO_BIN_EXE_bimr-cli")) .args(["build", copy.to_str().expect("utf8")]) .output() .expect("spawn"); assert!(out.status.success()); let default_out = copy.with_extension("ifcx"); assert_eq!( fs::read_to_string(&default_out).expect("read"), EXPECTED_IFCX ); }