mirror of
https://github.com/alexpasmantier/television.git
synced 2025-07-29 06:11:37 +00:00

- Allow users to specify a custom input prompt string via the `input_prompt` setting in the configuration file. - Document the new `input_prompt` option in `.config/config.toml` with a commented example. - Add a test to ensure that the input prompt is correctly loaded from the user configuration file.
525 lines
17 KiB
Rust
525 lines
17 KiB
Rust
//! Tests for CLI UI/layout options: --layout, --input-header, --ui-scale, --no-remote, --no-status-bar.
|
||
//!
|
||
//! These tests verify Television's user interface customization capabilities,
|
||
//! ensuring users can adapt the layout and appearance to their preferences and needs.
|
||
|
||
use television::tui::TESTING_ENV_VAR;
|
||
|
||
use super::common::*;
|
||
|
||
/// Tests that --layout landscape arranges panels side-by-side.
|
||
#[test]
|
||
fn test_layout_landscape() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This sets the interface to use side-by-side panel arrangement
|
||
let cmd = tv_local_config_and_cable_with_args(&[
|
||
"files",
|
||
"--layout",
|
||
"landscape",
|
||
]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the TUI started successfully in landscape layout
|
||
tester.assert_tui_frame_contains(
|
||
"╭───────────────────────── files ──────────────────────────╮╭─",
|
||
); // Should be in landscape layout
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --layout portrait arranges panels vertically stacked.
|
||
#[test]
|
||
fn test_layout_portrait() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This sets the interface to use vertically stacked panel arrangement
|
||
let cmd = tv_local_config_and_cable_with_args(&[
|
||
"files", "--layout", "portrait",
|
||
]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the TUI started successfully in portrait layout
|
||
tester.assert_tui_frame_contains("╭─────────────────────────────────────────────────────── files ────────────────────────────────────────────────────────╮");
|
||
tester.assert_tui_frame_contains("Hide Preview"); // Should be in portrait layout
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --input-header customizes the text above the search input in Channel Mode.
|
||
#[test]
|
||
fn test_input_header_in_channel_mode() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This overrides the channel's default input header with custom text
|
||
let mut cmd = tv_local_config_and_cable_with_args(&["files"]);
|
||
cmd.args(["--input-header", "UNIQUE16CHARID"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the custom input header is displayed
|
||
tester.assert_tui_frame_contains("UNIQUE16CHARID");
|
||
tester.assert_tui_frame_contains("CHANNEL files");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --input-header works in Ad-hoc Mode.
|
||
#[test]
|
||
fn test_input_header_in_adhoc_mode() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This provides a custom input header for an ad-hoc channel
|
||
let mut cmd =
|
||
tv_local_config_and_cable_with_args(&["--source-command", "ls"]);
|
||
cmd.args(["--input-header", "UNIQUE16CHARID"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the custom input header is displayed
|
||
tester.assert_tui_frame_contains("UNIQUE16CHARID");
|
||
tester.assert_tui_frame_contains("CHANNEL custom");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --input-prompt customizes the prompt symbol in Channel Mode.
|
||
#[test]
|
||
fn test_input_prompt_in_channel_mode() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This overrides the channel's default input prompt with custom symbol
|
||
let mut cmd = tv_local_config_and_cable_with_args(&["files"]);
|
||
cmd.args(["--input-prompt", "❯ "]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the custom input prompt is displayed
|
||
tester.assert_tui_frame_contains("❯ ");
|
||
tester.assert_tui_frame_contains("CHANNEL files");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --input-prompt works in Ad-hoc Mode.
|
||
#[test]
|
||
fn test_input_prompt_in_adhoc_mode() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This provides a custom input prompt for an ad-hoc channel
|
||
let mut cmd =
|
||
tv_local_config_and_cable_with_args(&["--source-command", "ls"]);
|
||
cmd.args(["--input-prompt", "→ "]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the custom input prompt is displayed
|
||
tester.assert_tui_frame_contains("→ ");
|
||
tester.assert_tui_frame_contains("CHANNEL custom");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that the default input prompt "> " is used when no custom prompt is specified.
|
||
#[test]
|
||
fn test_default_input_prompt() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This uses the default input prompt
|
||
let cmd = tv_local_config_and_cable_with_args(&["files"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the default input prompt is displayed
|
||
tester.assert_tui_frame_contains("> ");
|
||
tester.assert_tui_frame_contains("CHANNEL files");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --ui-scale adjusts the overall interface size.
|
||
#[test]
|
||
fn test_ui_scale() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This scales the entire interface to 80% of normal size
|
||
let cmd =
|
||
tv_local_config_and_cable_with_args(&["files", "--ui-scale", "80"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the interface is scaled (smaller panels visible in output)
|
||
tester.assert_tui_frame_contains(
|
||
"╭─────────────────── files ────────────────────╮╭─",
|
||
);
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --no-remote hides the remote control panel.
|
||
#[test]
|
||
fn test_no_remote_hides_remote_panel() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This disables the remote control panel display
|
||
let cmd = tv_local_config_and_cable_with_args(&["files", "--no-remote"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the remote control panel is hidden
|
||
tester.assert_not_tui_frame_contains("── Channels ──");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --no-status-bar hides the bottom status bar.
|
||
#[test]
|
||
fn test_no_status_bar_hides_status_bar() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This disables the bottom status bar display
|
||
let cmd =
|
||
tv_local_config_and_cable_with_args(&["files", "--no-status-bar"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the status bar is hidden
|
||
tester.assert_not_tui_frame_contains("CHANNEL files");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --hide-status-bar starts the interface with the status bar hidden.
|
||
#[test]
|
||
fn test_hide_status_bar_flag_hides_status_bar() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// Start with the files channel and hide the status bar
|
||
let cmd =
|
||
tv_local_config_and_cable_with_args(&["files", "--hide-status-bar"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the status bar is hidden
|
||
tester.assert_not_tui_frame_contains("CHANNEL files");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --show-status-bar ensures the status bar is visible.
|
||
#[test]
|
||
fn test_show_status_bar_flag_shows_status_bar() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// Start with the files channel and force the status bar visible
|
||
let cmd =
|
||
tv_local_config_and_cable_with_args(&["files", "--show-status-bar"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the status bar is visible
|
||
tester.assert_tui_frame_contains("CHANNEL files");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --hide-status-bar conflicts with --no-status-bar.
|
||
#[test]
|
||
fn test_hide_status_bar_conflicts_with_no_status_bar() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This should fail because the flags are mutually exclusive
|
||
let cmd = tv_local_config_and_cable_with_args(&[
|
||
"files",
|
||
"--hide-status-bar",
|
||
"--no-status-bar",
|
||
]);
|
||
tester.spawn_command(cmd);
|
||
|
||
// CLI should exit with error message, not show TUI
|
||
tester.assert_raw_output_contains("cannot be used with");
|
||
}
|
||
|
||
/// Tests that --hide-status-bar and --show-status-bar cannot be used together.
|
||
#[test]
|
||
fn test_hide_and_show_status_bar_conflict_errors() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This should fail because the flags are mutually exclusive
|
||
let cmd = tv_local_config_and_cable_with_args(&[
|
||
"files",
|
||
"--hide-status-bar",
|
||
"--show-status-bar",
|
||
]);
|
||
tester.spawn_command(cmd);
|
||
|
||
// CLI should exit with error message, not show TUI
|
||
tester.assert_raw_output_contains("cannot be used with");
|
||
}
|
||
|
||
/// Tests that --show-remote starts the interface with the remote control panel visible.
|
||
#[test]
|
||
fn test_show_remote_flag_shows_remote_panel() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// Start with the files channel and show the remote control panel
|
||
let cmd = tv_local_config_and_cable_with_args(&["files", "--show-remote"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify the remote control panel is visible (channel indicators)
|
||
tester.assert_tui_frame_contains("(1) (2) (3)");
|
||
|
||
// Send Ctrl+C to remote control
|
||
tester.send(&ctrl('c'));
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --hide-remote prevents the remote control panel from showing at startup.
|
||
#[test]
|
||
fn test_hide_remote_flag_hides_remote_panel() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// Start with the files channel and hide the remote control panel
|
||
let cmd = tv_local_config_and_cable_with_args(&["files", "--hide-remote"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
tester.assert_not_tui_frame_contains("(1) (2) (3)");
|
||
tester.assert_not_tui_frame_contains("── Channels ──");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --hide-remote conflicts with --no-remote.
|
||
#[test]
|
||
fn test_hide_remote_conflicts_with_no_remote() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This should fail because the flags are mutually exclusive
|
||
let cmd = tv_local_config_and_cable_with_args(&[
|
||
"files",
|
||
"--hide-remote",
|
||
"--no-remote",
|
||
]);
|
||
tester.spawn_command(cmd);
|
||
|
||
// CLI should exit with error message, not show TUI
|
||
tester.assert_raw_output_contains("cannot be used with");
|
||
}
|
||
|
||
/// Tests that --hide-remote and --show-remote cannot be used together.
|
||
#[test]
|
||
fn test_hide_and_show_remote_conflict_errors() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This should fail because the flags are mutually exclusive
|
||
let cmd = tv_local_config_and_cable_with_args(&[
|
||
"files",
|
||
"--hide-remote",
|
||
"--show-remote",
|
||
]);
|
||
tester.spawn_command(cmd);
|
||
|
||
// CLI should exit with error message, not show TUI
|
||
tester.assert_raw_output_contains("cannot be used with");
|
||
}
|
||
|
||
/// Tests that --no-help-panel disables the help panel entirely.
|
||
#[test]
|
||
fn test_no_help_panel_disables_help_panel() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This disables the help panel entirely
|
||
let cmd =
|
||
tv_local_config_and_cable_with_args(&["files", "--no-help-panel"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Send Ctrl+H to try to open help panel (should not work)
|
||
tester.send(&ctrl('h'));
|
||
|
||
// Verify help panel is not displayed
|
||
tester.assert_not_tui_frame_contains("───── Help ─────");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --hide-help-panel starts the interface with the help panel hidden.
|
||
#[test]
|
||
fn test_hide_help_panel_starts_with_help_hidden() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// Start with the files channel and hide the help panel
|
||
let cmd =
|
||
tv_local_config_and_cable_with_args(&["files", "--hide-help-panel"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Send Ctrl+H to open help panel (should still work since it's just hidden)
|
||
tester.send(&ctrl('h'));
|
||
|
||
// Verify help panel can be toggled visible
|
||
tester.assert_tui_frame_contains("───── Help ─────");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --show-help-panel ensures the help panel is visible.
|
||
#[test]
|
||
fn test_show_help_panel_starts_with_help_visible() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// Start with the files channel and force the help panel visible
|
||
let cmd =
|
||
tv_local_config_and_cable_with_args(&["files", "--show-help-panel"]);
|
||
let mut child = tester.spawn_command_tui(cmd);
|
||
|
||
// Verify help panel is initially visible
|
||
tester.assert_tui_frame_contains("───── Help ─────");
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
}
|
||
|
||
/// Tests that --hide-help-panel conflicts with --no-help-panel.
|
||
#[test]
|
||
fn test_hide_help_panel_conflicts_with_no_help_panel() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This should fail because the flags are mutually exclusive
|
||
let cmd = tv_local_config_and_cable_with_args(&[
|
||
"files",
|
||
"--hide-help-panel",
|
||
"--no-help-panel",
|
||
]);
|
||
tester.spawn_command(cmd);
|
||
|
||
// CLI should exit with error message, not show TUI
|
||
tester.assert_raw_output_contains("cannot be used with");
|
||
}
|
||
|
||
/// Tests that --hide-help-panel and --show-help-panel cannot be used together.
|
||
#[test]
|
||
fn test_hide_and_show_help_panel_conflict_errors() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This should fail because the flags are mutually exclusive
|
||
let cmd = tv_local_config_and_cable_with_args(&[
|
||
"files",
|
||
"--hide-help-panel",
|
||
"--show-help-panel",
|
||
]);
|
||
tester.spawn_command(cmd);
|
||
|
||
// CLI should exit with error message, not show TUI
|
||
tester.assert_raw_output_contains("cannot be used with");
|
||
}
|
||
|
||
/// Tests that --no-help-panel conflicts with --show-help-panel.
|
||
#[test]
|
||
fn test_no_help_panel_conflicts_with_show_help_panel() {
|
||
let mut tester = PtyTester::new();
|
||
|
||
// This should fail because the flags are mutually exclusive
|
||
let cmd = tv_local_config_and_cable_with_args(&[
|
||
"files",
|
||
"--no-help-panel",
|
||
"--show-help-panel",
|
||
]);
|
||
tester.spawn_command(cmd);
|
||
|
||
// CLI should exit with error message, not show TUI
|
||
tester.assert_raw_output_contains("cannot be used with");
|
||
}
|
||
|
||
#[test]
|
||
fn test_tui_with_height_and_width() {
|
||
unsafe { std::env::set_var(TESTING_ENV_VAR, "1") };
|
||
let mut tester = PtyTester::new();
|
||
|
||
// Test TUI with height 20 and width 80
|
||
let mut child =
|
||
tester.spawn_command_tui(tv_local_config_and_cable_with_args(&[
|
||
"files", "--height", "20", "--width", "80",
|
||
]));
|
||
|
||
// Check that 'files' appears in the frame content
|
||
tester.assert_tui_frame_contains("CHANNEL files");
|
||
|
||
// Validate frame dimensions (20 rows × 80 columns)
|
||
let frame = tester.get_tui_frame();
|
||
let non_empty_lines: Vec<&str> =
|
||
frame.lines().filter(|l| !l.trim().is_empty()).collect();
|
||
assert_eq!(
|
||
non_empty_lines.len(),
|
||
20,
|
||
"Expected 20 rows, got {}",
|
||
non_empty_lines.len()
|
||
);
|
||
let max_width = non_empty_lines
|
||
.iter()
|
||
.map(|l| l.chars().count())
|
||
.max()
|
||
.unwrap_or(0);
|
||
assert_eq!(max_width, 80, "Expected 80 columns, got {}", max_width);
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
unsafe { std::env::remove_var(TESTING_ENV_VAR) };
|
||
}
|
||
|
||
#[test]
|
||
// FIXME: needs https://github.com/crossterm-rs/crossterm/pull/957
|
||
#[ignore = "needs https://github.com/crossterm-rs/crossterm/pull/957"]
|
||
fn test_tui_with_height_only() {
|
||
unsafe { std::env::set_var(TESTING_ENV_VAR, "1") };
|
||
let mut tester = PtyTester::new();
|
||
|
||
// Test TUI with only height specified
|
||
let mut child =
|
||
tester.spawn_command_tui(tv_local_config_and_cable_with_args(&[
|
||
"files", "--height", "15",
|
||
]));
|
||
|
||
// Check that 'files' appears in the frame content
|
||
tester.assert_tui_frame_contains("CHANNEL files");
|
||
|
||
// Validate frame height (15 rows)
|
||
let frame = tester.get_tui_frame();
|
||
let non_empty_lines: Vec<&str> =
|
||
frame.lines().filter(|l| !l.trim().is_empty()).collect();
|
||
assert_eq!(
|
||
non_empty_lines.len(),
|
||
15,
|
||
"Expected 15 rows, got {}",
|
||
non_empty_lines.len()
|
||
);
|
||
|
||
// Send Ctrl+C to exit
|
||
tester.send(&ctrl('c'));
|
||
PtyTester::assert_exit_ok(&mut child, DEFAULT_DELAY);
|
||
unsafe { std::env::remove_var(TESTING_ENV_VAR) };
|
||
}
|