#![cfg(windows)]
mod common_cross;
use std::error::Error;
use common_cross::CrossPlatformHarness;
#[test]
fn display_message_queued_path_preserves_dollar_regex_anchor() -> Result<(), Box<dyn Error>> {
let harness = CrossPlatformHarness::new("windows-queued-dollar-anchor")?;
harness.success(["new-session", "-d", "-s", "alpha"])?;
let format = "#{s/$/Z/:session_name}";
let direct = harness.stdout(["display-message", "-p", format])?;
let queued = harness.stdout(["display-message", "-p", "-t", "alpha:0.0", format])?;
assert_eq!(direct.trim(), "alphaZ");
assert_eq!(queued, direct);
Ok(())
}
#[test]
fn display_message_queued_path_preserves_windows_quoting_and_dollar_anchor(
) -> Result<(), Box<dyn Error>> {
let harness = CrossPlatformHarness::new("windows-queued-path-quoting")?;
harness.success(["new-session", "-d", "-s", "alpha"])?;
let format = r##"C:\Users\RMUX User\quoted "dir"\#{s/$/Z/:session_name}"##;
let direct = harness.stdout(["display-message", "-p", format])?;
let queued = harness.stdout(["display-message", "-p", "-t", "alpha:0.0", format])?;
assert_eq!(direct, "C:\\Users\\RMUX User\\quoted \"dir\"\\alphaZ\n");
assert_eq!(queued, direct);
Ok(())
}
#[test]
fn set_option_unset_scope_matrix_matches_tmux() -> Result<(), Box<dyn Error>> {
let harness = CrossPlatformHarness::new("windows-set-option-unset-scope-matrix")?;
harness.success(["new-session", "-d", "-s", "alpha"])?;
let set_all = |harness: &CrossPlatformHarness| -> Result<(), Box<dyn Error>> {
harness.success(["set-option", "-t", "alpha", "@agent.state", "session"])?;
harness.success([
"set-option",
"-w",
"-t",
"alpha:0",
"@agent.state",
"window",
])?;
harness.success([
"set-option",
"-p",
"-t",
"alpha:0.0",
"@agent.state",
"pane",
])?;
Ok(())
};
let values =
|harness: &CrossPlatformHarness| -> Result<(String, String, String), Box<dyn Error>> {
Ok((
harness
.stdout(["show-options", "-qv", "-t", "alpha", "@agent.state"])?
.trim_end()
.to_owned(),
harness
.stdout(["show-options", "-wqv", "-t", "alpha:0", "@agent.state"])?
.trim_end()
.to_owned(),
harness
.stdout(["show-options", "-pqv", "-t", "alpha:0.0", "@agent.state"])?
.trim_end()
.to_owned(),
))
};
set_all(&harness)?;
harness.success(["set-option", "-U", "-t", "alpha:0.0", "@agent.state"])?;
assert_eq!(
values(&harness)?,
(String::new(), "window".to_owned(), "pane".to_owned()),
"plain -U unsets the session copy only"
);
set_all(&harness)?;
harness.success(["set-option", "-pU", "-t", "alpha:0.0", "@agent.state"])?;
assert_eq!(
values(&harness)?,
("session".to_owned(), "window".to_owned(), String::new()),
"-pU unsets the pane copy only"
);
set_all(&harness)?;
harness.success(["set-option", "-wU", "-t", "alpha:0", "@agent.state"])?;
assert_eq!(
values(&harness)?,
("session".to_owned(), String::new(), String::new()),
"-wU unsets the window copy and clears pane overrides"
);
Ok(())
}
#[test]
fn deferred_pane_pid_is_ready_before_queued_format_evaluation() -> Result<(), Box<dyn Error>> {
let harness = CrossPlatformHarness::new("windows-deferred-pane-pid-format")?;
let rendered = harness.stdout([
"new-session",
"-d",
"-s",
"race",
";",
"if-shell",
"-F",
"-t",
"race",
"#{pane_pid}",
"display-message -p TRUE",
"display-message -p FALSE",
])?;
assert_eq!(rendered.trim(), "TRUE");
let pane_pid = harness.stdout(["list-panes", "-t", "race", "-F", "#{pane_pid}"])?;
assert!(
pane_pid.trim().parse::<u32>().is_ok(),
"deferred pane did not publish a numeric PID: {pane_pid:?}"
);
Ok(())
}
#[test]
fn deferred_pane_pid_is_ready_before_list_filters() -> Result<(), Box<dyn Error>> {
let harness = CrossPlatformHarness::new("windows-deferred-pane-pid-list-filter")?;
let panes = harness.stdout([
"new-session",
"-d",
"-s",
"filter-race",
";",
"list-panes",
"-t",
"filter-race",
"-f",
"#{pane_pid}",
"-F",
"#{pane_pid}",
])?;
assert!(
panes.trim().parse::<u32>().is_ok(),
"list-panes filtered out the deferred PID: {panes:?}"
);
let windows = harness.stdout([
"new-session",
"-d",
"-s",
"window-filter-race",
";",
"list-windows",
"-t",
"window-filter-race",
"-f",
"#{pane_pid}",
"-F",
"#{pane_pid}",
])?;
assert!(
windows.trim().parse::<u32>().is_ok(),
"list-windows filtered out the deferred PID: {windows:?}"
);
Ok(())
}
#[test]
fn rejected_respawn_preserves_deferred_pane_queued_input() -> Result<(), Box<dyn Error>> {
let harness = CrossPlatformHarness::new("windows-respawn-deferred-input-rollback")?;
let marker = "RMUX_RESPAWN_REJECTED_QUEUED_INPUT_SURVIVES";
let echo_marker = format!("echo {marker}");
let output = harness.run([
"new-session",
"-d",
"-s",
"respawn-rollback",
";",
"send-keys",
"-t",
"respawn-rollback:0.0",
echo_marker.as_str(),
"Enter",
";",
"respawn-pane",
"-k",
"-t",
"respawn-rollback:0.0",
"-e",
"INVALID",
])?;
assert!(
!output.status.success(),
"invalid respawn environment must be rejected"
);
harness.wait_for_capture_contains("respawn-rollback:0.0", marker)?;
Ok(())
}