use std::path::Path;
use std::process::{Command, Output};
use tempfile::TempDir;
fn has_ansi(bytes: &[u8]) -> bool {
bytes.contains(&0x1b)
}
fn fixture_with_issue() -> TempDir {
let dir = TempDir::new().expect("failed to create temp dir");
std::fs::write(
dir.path().join("bad.php"),
"<?php\nfunction f() { echo $undefined; }\n",
)
.expect("failed to write fixture");
dir
}
fn run(dir: &Path, extra_args: &[&str], envs: &[(&str, &str)]) -> Output {
let mut cmd = Command::new(env!("CARGO_BIN_EXE_mir"));
cmd.env_clear();
for (k, v) in envs {
cmd.env(k, v);
}
cmd.args(["--no-cache", "--no-progress", "--stats"]);
cmd.args(extra_args);
cmd.arg(dir);
cmd.output().expect("failed to run mir binary")
}
#[test]
fn auto_defaults_to_plain_when_piped() {
let dir = fixture_with_issue();
let out = run(dir.path(), &[], &[]);
assert!(
!has_ansi(&out.stdout),
"stdout should be plain: {:?}",
String::from_utf8_lossy(&out.stdout)
);
assert!(
!has_ansi(&out.stderr),
"stderr should be plain: {:?}",
String::from_utf8_lossy(&out.stderr)
);
}
#[test]
fn color_always_forces_ansi_on_both_streams() {
let dir = fixture_with_issue();
let out = run(dir.path(), &["--color", "always"], &[]);
assert!(has_ansi(&out.stdout), "stdout should be colored");
assert!(has_ansi(&out.stderr), "stderr should be colored");
}
#[test]
fn color_never_forces_plain_even_under_clicolor_force() {
let dir = fixture_with_issue();
let out = run(
dir.path(),
&["--color", "never"],
&[("CLICOLOR_FORCE", "1")],
);
assert!(!has_ansi(&out.stdout));
assert!(!has_ansi(&out.stderr));
}
#[test]
fn explicit_flag_overrides_no_color_env() {
let dir = fixture_with_issue();
let out = run(dir.path(), &["--color", "always"], &[("NO_COLOR", "1")]);
assert!(has_ansi(&out.stdout));
assert!(has_ansi(&out.stderr));
}
#[test]
fn no_color_env_disables_auto_color() {
let dir = fixture_with_issue();
let out = run(dir.path(), &[], &[("NO_COLOR", "1")]);
assert!(!has_ansi(&out.stdout));
assert!(!has_ansi(&out.stderr));
}
#[test]
fn clicolor_force_enables_auto_color_when_piped() {
let dir = fixture_with_issue();
let out = run(dir.path(), &[], &[("CLICOLOR_FORCE", "1")]);
assert!(has_ansi(&out.stdout));
assert!(has_ansi(&out.stderr));
}
#[test]
fn clicolor_force_wins_over_no_color_in_auto_mode() {
let dir = fixture_with_issue();
let out = run(
dir.path(),
&[],
&[("NO_COLOR", "1"), ("CLICOLOR_FORCE", "1")],
);
assert!(has_ansi(&out.stdout));
assert!(has_ansi(&out.stderr));
}
#[test]
fn json_format_stdout_never_carries_ansi_even_when_forced() {
let dir = fixture_with_issue();
let out = run(dir.path(), &["--color", "always", "--format", "json"], &[]);
assert!(
!has_ansi(&out.stdout),
"JSON payload on stdout must stay machine-readable regardless of --color"
);
}