use super::*;
#[tokio::test]
async fn choose_tree_zw_runs_direct_command_only_on_accept() {
let handler = RequestHandler::new();
let attach_pid = std::process::id();
let alpha = SessionName::new("alpha").expect("valid session");
assert!(matches!(
handler
.handle(Request::NewSession(NewSessionRequest {
session_name: alpha.clone(),
detached: true,
size: Some(TerminalSize { cols: 80, rows: 24 }),
environment: None,
}))
.await,
Response::NewSession(_)
));
let (control_tx, _control_rx) = mpsc::unbounded_channel();
let _ = handler
.register_attach(attach_pid, alpha.clone(), control_tx)
.await;
let parsed = CommandParser::new()
.parse_arguments(["choose-tree", "-Zw", "set-buffer", "-b", "chosen", "%%"])
.expect("choose-tree parses");
let command = RequestHandler::parse_mode_tree_queue_command(parsed.commands()[0].clone())
.expect("mode-tree command parses")
.expect("mode-tree command recognized");
handler
.execute_queued_mode_tree(
attach_pid,
command,
&QueueExecutionContext::without_caller_cwd(),
)
.await
.expect("overlay opens");
{
let state = handler.state.lock().await;
assert!(
state.buffers.get("chosen").is_none(),
"direct command must not run before accept"
);
}
handler
.accept_mode_tree_selection(attach_pid)
.await
.expect("selection accept succeeds");
let state = handler.state.lock().await;
let chosen = state
.buffers
.get("chosen")
.expect("buffer created on accept");
assert_eq!(String::from_utf8_lossy(chosen), "=alpha:0.");
}
#[tokio::test]
async fn choose_client_from_unattached_request_activates_mode_tree_on_all_attaches() {
let handler = RequestHandler::new();
let alpha = SessionName::new("alpha").expect("valid session");
assert!(matches!(
handler
.handle(Request::NewSession(NewSessionRequest {
session_name: alpha.clone(),
detached: true,
size: Some(TerminalSize { cols: 80, rows: 24 }),
environment: None,
}))
.await,
Response::NewSession(_)
));
let (first_tx, _first_rx) = mpsc::unbounded_channel();
let (second_tx, _second_rx) = mpsc::unbounded_channel();
let first_pid = std::process::id();
let second_pid = first_pid.saturating_add(1);
let _ = handler
.register_attach(first_pid, alpha.clone(), first_tx)
.await;
let _ = handler.register_attach(second_pid, alpha, second_tx).await;
let parsed = CommandParser::new()
.parse_arguments(["choose-client"])
.expect("choose-client parses");
let command = RequestHandler::parse_mode_tree_queue_command(parsed.commands()[0].clone())
.expect("mode-tree command parses")
.expect("mode-tree command recognized");
handler
.execute_queued_mode_tree(
first_pid.saturating_add(10),
command,
&QueueExecutionContext::without_caller_cwd(),
)
.await
.expect("overlay opens");
let active_attach = handler.active_attach.lock().await;
assert!(active_attach
.by_pid
.get(&first_pid)
.and_then(|active| active.mode_tree.as_ref())
.is_some());
assert!(active_attach
.by_pid
.get(&second_pid)
.and_then(|active| active.mode_tree.as_ref())
.is_some());
}
#[tokio::test]
async fn choose_tree_zw_defers_parse_errors_until_accept() {
let handler = RequestHandler::new();
let attach_pid = std::process::id();
let alpha = SessionName::new("alpha").expect("valid session");
assert!(matches!(
handler
.handle(Request::NewSession(NewSessionRequest {
session_name: alpha.clone(),
detached: true,
size: Some(TerminalSize { cols: 80, rows: 24 }),
environment: None,
}))
.await,
Response::NewSession(_)
));
let (control_tx, _control_rx) = mpsc::unbounded_channel();
let _ = handler.register_attach(attach_pid, alpha, control_tx).await;
let parsed = CommandParser::new()
.parse_arguments(["choose-tree", "-Zw", "{"])
.expect("choose-tree parses");
let command = RequestHandler::parse_mode_tree_queue_command(parsed.commands()[0].clone())
.expect("mode-tree command parses")
.expect("mode-tree command recognized");
handler
.execute_queued_mode_tree(
attach_pid,
command,
&QueueExecutionContext::without_caller_cwd(),
)
.await
.expect("overlay opens despite invalid direct command");
let err = handler
.accept_mode_tree_selection(attach_pid)
.await
.expect_err("parse error should surface when accepting");
let RmuxError::Server(message) = err else {
panic!("expected server parse error");
};
assert!(message.starts_with("mode-tree command parse failed:"));
}