#![cfg(feature = "bin")]
use std::process::{Command, Stdio};
const BURN: &str = env!("CARGO_BIN_EXE_burn");
fn run_eval(code: &str) -> std::process::Output {
Command::new(BURN)
.env("BURN_QUIET", "1")
.arg("-e")
.arg(code)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.expect("spawn burn")
}
#[test]
fn rejected_exported_promise_exits_nonzero_with_message() {
let out = run_eval("module.exports = Promise.reject(new Error('boom-rejected'))");
let stderr = String::from_utf8_lossy(&out.stderr);
assert_eq!(
out.status.code(),
Some(1),
"rejected exported promise must exit 1; stderr: {stderr}"
);
assert!(
stderr.contains("boom-rejected"),
"stderr must carry the rejection message; got: {stderr}"
);
assert!(
stderr.contains("at "),
"stderr must carry a stack trace; got: {stderr}"
);
}
#[test]
fn exported_async_throw_exits_nonzero_with_message() {
let out = run_eval("module.exports = (async () => { throw new Error('boom-async'); })()");
let stderr = String::from_utf8_lossy(&out.stderr);
assert_eq!(
out.status.code(),
Some(1),
"exported async throw must exit 1; stderr: {stderr}"
);
assert!(
stderr.contains("boom-async"),
"stderr must carry the thrown message; got: {stderr}"
);
}
#[test]
fn top_level_sync_throw_exits_nonzero_with_message() {
let out = run_eval("throw new Error('boom-sync')");
let stderr = String::from_utf8_lossy(&out.stderr);
assert_eq!(
out.status.code(),
Some(1),
"top-level throw must exit 1; stderr: {stderr}"
);
assert!(
stderr.contains("boom-sync"),
"stderr must carry the thrown message; got: {stderr}"
);
}
#[test]
fn resolved_exported_promise_still_exits_zero() {
let out = run_eval("module.exports = Promise.resolve(42); console.log('done-ok')");
let stderr = String::from_utf8_lossy(&out.stderr);
let stdout = String::from_utf8_lossy(&out.stdout);
assert_eq!(
out.status.code(),
Some(0),
"resolved exported promise must exit 0; stderr: {stderr}"
);
assert!(
stdout.contains("done-ok"),
"console output must still flow; got: {stdout}"
);
}
#[test]
fn run_file_with_rejected_exported_promise_exits_nonzero() {
let dir = std::env::temp_dir().join(format!("burn_exitcode_{}", std::process::id()));
std::fs::create_dir_all(&dir).expect("mkdir");
let file = dir.join("rejector.js");
std::fs::write(
&file,
"module.exports = Promise.reject(new Error('boom-file'));\n",
)
.expect("write script");
let out = Command::new(BURN)
.env("BURN_QUIET", "1")
.arg("run")
.arg(&file)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.expect("spawn burn");
let stderr = String::from_utf8_lossy(&out.stderr);
assert_eq!(
out.status.code(),
Some(1),
"burn run with rejected export must exit 1; stderr: {stderr}"
);
assert!(
stderr.contains("boom-file"),
"stderr must carry the rejection message; got: {stderr}"
);
let _ = std::fs::remove_dir_all(&dir);
}