use super::*;
fn mock_app() -> AppState {
let mut app = AppState::new("test_session".to_string());
app.window_base_index = 0;
app.pane_base_index = 0;
app
}
fn make_window(name: &str, id: usize) -> crate::types::Window {
crate::types::Window {
root: Node::Split { kind: LayoutKind::Horizontal, sizes: vec![], children: vec![] },
active_path: vec![],
name: name.to_string(),
id,
activity_flag: false,
bell_flag: false,
silence_flag: false,
last_output_time: std::time::Instant::now(),
last_seen_version: 0,
manual_rename: false,
layout_index: 0,
pane_mru: vec![],
zoom_saved: None,
linked_from: None,
}
}
fn mock_app_with_window() -> AppState {
let mut app = mock_app();
app.windows.push(make_window("shell", 0));
app
}
fn mock_app_with_windows(names: &[&str]) -> AppState {
let mut app = mock_app();
for (i, name) in names.iter().enumerate() {
app.windows.push(make_window(name, i));
}
app
}
fn is_popup(app: &AppState) -> bool {
matches!(&app.mode, Mode::PopupMode { .. })
}
fn popup_output(app: &AppState) -> String {
match &app.mode {
Mode::PopupMode { output, .. } => output.clone(),
_ => String::new(),
}
}
fn is_popup_with_text(app: &AppState, text: &str) -> bool {
match &app.mode {
Mode::PopupMode { output, .. } => output.contains(text),
_ => false,
}
}
#[test]
fn issue36_set_option_mouse_on() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "set-option -g mouse on").unwrap();
assert!(app.mouse_enabled, "#36: set-option mouse on should enable mouse");
}
#[test]
fn issue36_set_option_mouse_off() {
let mut app = mock_app_with_window();
app.mouse_enabled = true;
execute_command_string(&mut app, "set-option -g mouse off").unwrap();
assert!(!app.mouse_enabled, "#36: set-option mouse off should disable mouse");
}
#[test]
fn issue36_set_option_base_index() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "set-option -g base-index 1").unwrap();
assert_eq!(app.window_base_index, 1, "#36: base-index should be 1");
}
#[test]
fn issue36_set_option_escape_time() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "set-option -g escape-time 50").unwrap();
assert_eq!(app.escape_time_ms, 50, "#36: escape-time should be 50");
}
#[test]
fn issue63_set_option_status_off() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "set-option -g status off").unwrap();
assert!(!app.status_visible, "#63: status off should disable status bar");
}
#[test]
fn issue63_set_option_status_on() {
let mut app = mock_app_with_window();
app.status_visible = false;
execute_command_string(&mut app, "set-option -g status on").unwrap();
assert!(app.status_visible, "#63: status on should enable status bar");
}
#[test]
fn issue36_set_option_history_limit() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "set-option -g history-limit 9999").unwrap();
assert_eq!(app.history_limit, 9999, "#36: history-limit should be 9999");
}
#[test]
fn issue36_set_option_status_style() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, r#"set-option -g status-style "bg=red""#).unwrap();
assert_eq!(app.status_style, "bg=red", "#36: status-style should be bg=red");
}
#[test]
fn issue36_set_option_status_left() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, r#"set-option -g status-left "TEST""#).unwrap();
assert_eq!(app.status_left, "TEST", "#36: status-left should be TEST");
}
#[test]
fn issue36_set_option_status_right() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, r#"set-option -g status-right "RIGHT""#).unwrap();
assert_eq!(app.status_right, "RIGHT", "#36: status-right should be RIGHT");
}
#[test]
fn issue215_set_user_option() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "set-option -g @my-plugin-opt value1").unwrap();
assert_eq!(
app.user_options.get("@my-plugin-opt").map(|s| s.as_str()),
Some("value1"),
"#215: @user-option should be stored"
);
}
#[test]
fn issue105_user_option_does_not_leak() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "set-option -g @plugin-internal secret").unwrap();
assert!(
app.user_options.contains_key("@plugin-internal"),
"#105: @option should be in user_options"
);
}
#[test]
fn issue215_show_options_dispatches() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "show-options").unwrap();
if is_popup(&app) {
let output = popup_output(&app);
assert!(output.contains("mouse") || output.contains("status") || output.len() > 10,
"#215: show-options popup should contain options. Got: {}", output);
}
}
#[test]
fn issue215_show_options_v_returns_value() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "set-option -g @test215 myval").unwrap();
execute_command_string(&mut app, "show-options -v @test215").unwrap();
if is_popup(&app) {
let output = popup_output(&app);
assert!(output.contains("myval"), "#215: show-options -v should contain 'myval'. Got: {}", output);
}
}
#[test]
fn issue19_bind_key_basic() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "bind-key x split-window -v").unwrap();
let table = app.key_tables.get("prefix").expect("prefix table should exist");
let found = table.iter().any(|kb| {
kb.key.0 == crossterm::event::KeyCode::Char('x')
});
assert!(found, "#19: bind-key x should be in prefix table");
}
#[test]
fn issue19_bind_key_root_table() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "bind-key -T root F5 split-window -v").unwrap();
let table = app.key_tables.get("root").expect("root table should exist");
let found = table.iter().any(|kb| {
kb.key.0 == crossterm::event::KeyCode::F(5)
});
assert!(found, "#19: bind-key -T root F5 should be in root table");
}
#[test]
fn issue108_bind_key_ctrl_tab() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "bind-key -T root C-Tab next-window").unwrap();
let table = app.key_tables.get("root").expect("root table should exist");
let found = table.iter().any(|kb| {
kb.key.0 == crossterm::event::KeyCode::Tab
&& kb.key.1.contains(crossterm::event::KeyModifiers::CONTROL)
});
assert!(found, "#108: bind-key C-Tab should register in root table");
}
#[test]
fn issue133_set_hook_registers() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, r#"set-hook -g after-new-window "display-message hello""#).unwrap();
assert!(
app.hooks.contains_key("after-new-window"),
"#133: after-new-window hook should be registered"
);
}
#[test]
fn issue133_set_hook_append() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, r#"set-hook -g after-new-window "display-message first""#).unwrap();
execute_command_string(&mut app, r#"set-hook -ga after-new-window "display-message second""#).unwrap();
let hooks = app.hooks.get("after-new-window").unwrap();
assert!(
hooks.len() >= 2,
"#133: set-hook -ga should append, got {} hooks",
hooks.len()
);
}
#[test]
fn issue125_new_window_via_command() {
let mut app = mock_app_with_window();
let before = app.windows.len();
execute_command_string(&mut app, "new-window").unwrap();
assert!(
!is_popup_with_text(&app, "cannot"),
"#125: new-window should not show blocking popup"
);
}
#[test]
fn issue82_split_window_v() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "split-window -v").unwrap();
assert!(
!is_popup_with_text(&app, "cannot"),
"#82: split-window -v should not show blocking popup"
);
}
#[test]
fn issue82_split_window_h() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "split-window -h").unwrap();
assert!(
!is_popup_with_text(&app, "cannot"),
"#82: split-window -h should not show blocking popup"
);
}
#[test]
fn issue94_split_window_percent() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "split-window -v -p 25").unwrap();
assert!(
!is_popup_with_text(&app, "invalid"),
"#94: split-window -p 25 should not error"
);
}
#[test]
fn issue70_select_pane_by_index() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "select-pane -t 0").unwrap();
}
#[test]
fn issue134_select_pane_directional_up() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "select-pane -U").unwrap();
}
#[test]
fn issue134_select_pane_directional_down() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "select-pane -D").unwrap();
}
#[test]
fn issue134_select_pane_directional_left() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "select-pane -L").unwrap();
}
#[test]
fn issue134_select_pane_directional_right() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "select-pane -R").unwrap();
}
#[test]
fn issue82_resize_pane_zoom() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "resize-pane -Z").unwrap();
}
#[test]
fn issue42_display_message_basic() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, r#"display-message "hello world""#).unwrap();
}
#[test]
fn issue42_display_message_format_session_name() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "display-message -p '#{session_name}'").unwrap();
}
#[test]
fn issue209_display_message_with_duration() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, r#"display-message -d 5000 "duration test""#).unwrap();
}
#[test]
fn issue146_list_commands() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "list-commands").unwrap();
if is_popup(&app) {
let output = popup_output(&app);
assert!(
output.contains("new-session") || output.contains("split-window"),
"#146: list-commands should include known commands. Got: {}",
&output[..output.len().min(200)]
);
}
}
#[test]
fn issue146_list_windows() {
let mut app = mock_app_with_windows(&["win0", "win1"]);
app.active_idx = 0;
execute_command_string(&mut app, "list-windows").unwrap();
if is_popup(&app) {
let output = popup_output(&app);
assert!(
output.contains("win0") || output.contains("win1"),
"#146: list-windows should show window names"
);
}
}
#[test]
fn issue146_list_sessions() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "list-sessions").unwrap();
if is_popup(&app) {
let output = popup_output(&app);
assert!(
output.contains("test_session") || output.len() > 0,
"#146: list-sessions should show session info"
);
}
}
#[test]
fn issue95_choose_tree_dispatches() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "choose-tree").unwrap();
}
#[test]
fn issue95_choose_session_dispatches() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "choose-session").unwrap();
}
#[test]
fn issue95_choose_window_dispatches() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "choose-window").unwrap();
}
#[test]
fn issue201_rename_session() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "rename-session newname").unwrap();
assert_eq!(app.session_name, "newname", "#201: rename-session should change session_name");
}
#[test]
fn issue169_rename_window() {
let mut app = mock_app_with_windows(&["shell"]);
app.active_idx = 0;
execute_command_string(&mut app, "rename-window mywindow").unwrap();
assert_eq!(app.windows[0].name, "mywindow", "#169: rename-window should change name");
assert!(app.windows[0].manual_rename, "#169: rename-window should set manual_rename flag");
}
#[test]
fn issue71_kill_pane_dispatches() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "kill-pane").unwrap();
}
#[test]
fn issue71_kill_window_dispatches() {
let mut app = mock_app_with_windows(&["w0", "w1"]);
app.active_idx = 0;
execute_command_string(&mut app, "kill-window").unwrap();
}
#[test]
fn command_prompt_set_option() {
let mut app = mock_app_with_window();
app.mode = Mode::CommandPrompt {
input: "set-option -g escape-time 42".to_string(),
cursor: 0,
};
execute_command_prompt(&mut app).unwrap();
assert_eq!(app.escape_time_ms, 42, "Command prompt should execute set-option");
}
#[test]
fn command_prompt_rename_session() {
let mut app = mock_app_with_window();
app.mode = Mode::CommandPrompt {
input: "rename-session prompt_renamed".to_string(),
cursor: 0,
};
execute_command_prompt(&mut app).unwrap();
assert_eq!(app.session_name, "prompt_renamed", "Command prompt rename-session");
}
#[test]
fn command_prompt_list_windows() {
let mut app = mock_app_with_windows(&["w0", "w1"]);
app.active_idx = 0;
app.mode = Mode::CommandPrompt {
input: "list-windows".to_string(),
cursor: 0,
};
execute_command_prompt(&mut app).unwrap();
}
#[test]
fn command_prompt_chained_commands() {
let mut app = mock_app_with_window();
app.mode = Mode::CommandPrompt {
input: r#"set-option -g @chain1 v1 \; set-option -g @chain2 v2"#.to_string(),
cursor: 0,
};
execute_command_prompt(&mut app).unwrap();
assert_eq!(
app.user_options.get("@chain1").map(|s| s.as_str()),
Some("v1"),
"#192: First chained command from prompt"
);
assert_eq!(
app.user_options.get("@chain2").map(|s| s.as_str()),
Some("v2"),
"#192: Second chained command from prompt"
);
}
#[test]
fn issue171_select_layout_tiled() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "select-layout tiled").unwrap();
}
#[test]
fn issue171_select_layout_even_horizontal() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "select-layout even-horizontal").unwrap();
}
#[test]
fn issue171_select_layout_even_vertical() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "select-layout even-vertical").unwrap();
}
#[test]
fn issue171_select_layout_main_horizontal() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "select-layout main-horizontal").unwrap();
}
#[test]
fn issue171_select_layout_main_vertical() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "select-layout main-vertical").unwrap();
}
#[test]
fn next_window_command() {
let mut app = mock_app_with_windows(&["w0", "w1"]);
app.active_idx = 0;
execute_command_string(&mut app, "next-window").unwrap();
assert_eq!(app.active_idx, 1, "next-window should advance to window 1");
}
#[test]
fn previous_window_command() {
let mut app = mock_app_with_windows(&["w0", "w1"]);
app.active_idx = 1;
execute_command_string(&mut app, "previous-window").unwrap();
assert_eq!(app.active_idx, 0, "previous-window should go back to window 0");
}
#[test]
fn next_window_wraps() {
let mut app = mock_app_with_windows(&["w0", "w1"]);
app.active_idx = 1;
execute_command_string(&mut app, "next-window").unwrap();
assert_eq!(app.active_idx, 0, "next-window should wrap to 0");
}
#[test]
fn select_window_by_index() {
let mut app = mock_app_with_windows(&["w0", "w1", "w2"]);
app.active_idx = 0;
execute_command_string(&mut app, "select-window -t 2").unwrap();
assert_eq!(app.active_idx, 2, "select-window -t 2 should go to window 2");
}
#[test]
fn issue81_resize_pane_down() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "resize-pane -D 3").unwrap();
}
#[test]
fn issue81_resize_pane_up() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "resize-pane -U 3").unwrap();
}
#[test]
fn issue81_resize_pane_left() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "resize-pane -L 3").unwrap();
}
#[test]
fn issue81_resize_pane_right() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "resize-pane -R 3").unwrap();
}
#[test]
fn issue145_source_file_dispatches() {
let mut app = mock_app_with_window();
let _ = execute_command_string(&mut app, "source-file /nonexistent/path/test.conf");
}
#[test]
fn send_keys_dispatches() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, r#"send-keys "hello" Enter"#).unwrap();
}
#[test]
fn empty_command_string_does_not_crash() {
let mut app = mock_app_with_window();
let _ = execute_command_string(&mut app, "");
}
#[test]
fn whitespace_only_command_does_not_crash() {
let mut app = mock_app_with_window();
let _ = execute_command_string(&mut app, " ");
}
#[test]
fn unknown_command_does_not_crash() {
let mut app = mock_app_with_window();
let _ = execute_command_string(&mut app, "nonexistent-command --flag value");
}
#[test]
fn command_with_quoted_args() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, r#"set-option -g status-left "hello world""#).unwrap();
assert_eq!(app.status_left, "hello world");
}
#[test]
fn command_with_single_quoted_args() {
let mut app = mock_app_with_window();
execute_command_string(&mut app, "set-option -g status-left 'single quoted'").unwrap();
assert_eq!(app.status_left, "single quoted");
}