#![cfg(unix)]
#![allow(clippy::print_stderr)]
use std::path::Path;
use tempfile::TempDir;
use winx_code_agent::state::pty::{configured_shell_kind, PtyShell};
use winx_code_agent::utils::executable::{powershell_executable, ShellKind};
fn run(shell: &mut PtyShell, command: &str) -> anyhow::Result<(String, bool)> {
shell.send_command(command)?;
shell.read_output(15.0)
}
#[tokio::test(flavor = "multi_thread")]
#[ignore = "requires real PTY and pwsh; run in the PTY CI job"]
async fn powershell_shell_speaks_the_same_completion_contract() -> anyhow::Result<()> {
if powershell_executable().is_none() {
eprintln!("pwsh not installed; skipping");
return Ok(());
}
std::env::set_var("WINX_SHELL", "pwsh");
assert_eq!(configured_shell_kind(false), ShellKind::PowerShell);
let temp_dir = TempDir::new()?;
let mut shell = PtyShell::new(temp_dir.path(), false)?;
let (output, complete) = run(&mut shell, "Write-Output 'hello from pwsh'")?;
assert!(complete, "{output}");
assert!(output.contains("hello from pwsh"), "{output}");
assert_eq!(shell.last_exit_code, Some(0), "{output}");
let (output, complete) = run(&mut shell, "sh -c 'exit 3'")?;
assert!(complete, "{output}");
assert_eq!(shell.last_exit_code, Some(3), "{output}");
let (output, complete) = run(&mut shell, "Write-Output ok")?;
assert!(complete, "{output}");
assert_eq!(shell.last_exit_code, Some(0), "{output}");
let (output, complete) =
run(&mut shell, "Get-Item /definitely/not/here -ErrorAction SilentlyContinue")?;
assert!(complete, "{output}");
assert_eq!(shell.last_exit_code, Some(1), "{output}");
let nested = temp_dir.path().join("nested");
std::fs::create_dir(&nested)?;
let (output, complete) = run(&mut shell, &format!("Set-Location '{}'", nested.display()))?;
assert!(complete, "{output}");
let (output, complete) = run(&mut shell, "Get-Location | Select-Object -ExpandProperty Path")?;
assert!(complete, "{output}");
let canonical = nested.canonicalize()?;
assert!(output.contains(canonical.to_str().unwrap_or("")), "{output}");
assert!(
output
.lines()
.any(|line| line.starts_with("◉ ") && line.contains(canonical.to_str().unwrap_or("?"))),
"prompt marker must carry the cwd: {output}"
);
assert!(
PtyShell::new(Path::new("/tmp"), true).is_err()
|| configured_shell_kind(true) != ShellKind::PowerShell
);
Ok(())
}