use bssh::pty::{PtyConfig, utils::*};
use signal_hook::consts::SIGWINCH;
use std::time::Duration;
#[test]
fn test_pty_allocation_decision_logic() {
let config = PtyConfig {
force_pty: true,
disable_pty: false,
..Default::default()
};
let result = should_allocate_pty(&config);
assert!(result.is_ok());
assert!(result.unwrap(), "force_pty should always allocate PTY");
let config = PtyConfig {
force_pty: false,
disable_pty: true,
..Default::default()
};
let result = should_allocate_pty(&config);
assert!(result.is_ok());
assert!(!result.unwrap(), "disable_pty should never allocate PTY");
let config = PtyConfig {
force_pty: true,
disable_pty: true,
..Default::default()
};
let result = should_allocate_pty(&config);
assert!(result.is_ok());
assert!(!result.unwrap(), "disable_pty should override force_pty");
let config = PtyConfig {
force_pty: false,
disable_pty: false,
..Default::default()
};
let result = should_allocate_pty(&config);
assert!(result.is_ok());
}
#[test]
fn test_terminal_size_detection() {
let result = get_terminal_size();
assert!(result.is_ok(), "Terminal size detection should not fail");
let (width, height) = result.unwrap();
assert!(width > 0, "Terminal width should be positive");
assert!(height > 0, "Terminal height should be positive");
assert!(width >= 20, "Terminal width should be at least 20");
assert!(width <= 1000, "Terminal width should be reasonable (≤1000)");
assert!(height >= 10, "Terminal height should be at least 10");
assert!(height <= 200, "Terminal height should be reasonable (≤200)");
}
#[test]
fn test_terminal_size_fallback() {
let result = get_terminal_size();
assert!(result.is_ok());
let (width, height) = result.unwrap();
if width == 80 && height == 24 {
assert_eq!(width, 80);
assert_eq!(height, 24);
} else {
assert!(width > 0 && height > 0);
}
}
#[test]
fn test_resize_signal_handler_setup() {
let result = setup_resize_handler();
assert!(result.is_ok(), "Resize signal handler setup should succeed");
let signals = result.unwrap();
drop(signals); }
#[tokio::test]
async fn test_resize_signal_handler_timeout() {
let signals = setup_resize_handler();
assert!(signals.is_ok(), "Signal handler setup should succeed");
drop(signals);
}
#[test]
fn test_controlling_terminal_detection() {
let has_terminal = has_controlling_terminal();
match has_terminal {
true => {
println!("Running in interactive terminal");
}
false => {
println!("Running in non-interactive environment");
}
}
}
#[test]
fn test_pty_config_defaults() {
let config = PtyConfig::default();
assert_eq!(config.term_type, "xterm-256color");
assert!(!config.force_pty);
assert!(!config.disable_pty);
assert!(!config.enable_mouse);
assert_eq!(config.timeout, Duration::from_millis(10));
}
#[test]
fn test_pty_config_clone() {
let config1 = PtyConfig {
term_type: "custom-term".to_string(),
force_pty: true,
disable_pty: false,
enable_mouse: true,
timeout: Duration::from_secs(1),
};
let config2 = config1.clone();
assert_eq!(config1.term_type, config2.term_type);
assert_eq!(config1.force_pty, config2.force_pty);
assert_eq!(config1.disable_pty, config2.disable_pty);
assert_eq!(config1.enable_mouse, config2.enable_mouse);
assert_eq!(config1.timeout, config2.timeout);
}
#[test]
fn test_terminal_size_bounds_checking() {
let (width, height) = get_terminal_size().unwrap();
assert!(width >= 1, "Width should be at least 1");
assert!(height >= 1, "Height should be at least 1");
assert!(width <= 10000, "Width should not exceed 10000");
assert!(height <= 10000, "Height should not exceed 10000");
}
#[cfg(unix)]
#[test]
fn test_signal_constants() {
assert_eq!(SIGWINCH, 28); }
#[test]
fn test_multiple_resize_handler_setup() {
let handler1 = setup_resize_handler();
assert!(handler1.is_ok());
let handler2 = setup_resize_handler();
assert!(handler2.is_ok());
drop(handler1);
drop(handler2);
}
#[test]
fn test_pty_allocation_edge_cases() {
let config = PtyConfig {
term_type: String::new(),
force_pty: true,
..Default::default()
};
assert!(should_allocate_pty(&config).unwrap());
let config = PtyConfig {
term_type: "a".repeat(1000),
force_pty: true,
..Default::default()
};
assert!(should_allocate_pty(&config).unwrap());
let config = PtyConfig {
term_type: "xterm-256color-with-special-chars!@#$%^&*()".to_string(),
force_pty: true,
..Default::default()
};
assert!(should_allocate_pty(&config).unwrap());
}
#[test]
fn test_terminal_detection_consistency() {
let has_terminal = has_controlling_terminal();
for _ in 0..10 {
assert_eq!(has_controlling_terminal(), has_terminal);
}
}
#[tokio::test]
async fn test_concurrent_terminal_size_detection() {
let mut handles = Vec::new();
for _ in 0..10 {
let handle = tokio::spawn(async { get_terminal_size() });
handles.push(handle);
}
let mut results = Vec::new();
for handle in handles {
let result = handle.await.unwrap();
assert!(result.is_ok());
results.push(result.unwrap());
}
let first_result = results[0];
for result in results {
assert_eq!(
result, first_result,
"Terminal size should be consistent across threads"
);
}
}
#[test]
fn test_pty_config_validation() {
let valid_timeouts = vec![
Duration::from_millis(1),
Duration::from_millis(10),
Duration::from_millis(100),
Duration::from_secs(1),
Duration::from_secs(10),
];
for timeout in valid_timeouts {
let config = PtyConfig {
timeout,
..Default::default()
};
assert!(config.timeout >= Duration::from_millis(1));
}
}
#[test]
fn test_terminal_type_variations() {
let terminal_types = vec![
"xterm",
"xterm-256color",
"screen",
"screen-256color",
"tmux",
"tmux-256color",
"vt100",
"vt220",
"linux",
"ansi",
];
for term_type in terminal_types {
let config = PtyConfig {
term_type: term_type.to_string(),
force_pty: true,
..Default::default()
};
assert_eq!(config.term_type, term_type);
assert!(should_allocate_pty(&config).unwrap());
}
}
#[test]
fn test_pty_config_debug_format() {
let config = PtyConfig::default();
let debug_str = format!("{config:?}");
assert!(debug_str.contains("term_type"));
assert!(debug_str.contains("force_pty"));
assert!(debug_str.contains("disable_pty"));
assert!(debug_str.contains("enable_mouse"));
assert!(debug_str.contains("timeout"));
}
#[tokio::test]
async fn test_signal_handler_cleanup() {
{
let signals = setup_resize_handler().unwrap();
let handle = tokio::spawn(async move {
let _signals = signals;
tokio::time::sleep(Duration::from_millis(10)).await;
});
let result = handle.await;
assert!(result.is_ok());
}
let signals = setup_resize_handler();
assert!(signals.is_ok());
}
#[test]
fn test_pty_utility_error_handling() {
let result = get_terminal_size();
assert!(result.is_ok());
let result = setup_resize_handler();
assert!(result.is_ok());
let _has_terminal = has_controlling_terminal();
}
#[tokio::test]
async fn test_performance_terminal_size_detection() {
let start = std::time::Instant::now();
let iterations = 1000;
for _ in 0..iterations {
let _ = get_terminal_size().unwrap();
}
let elapsed = start.elapsed();
let avg_time = elapsed / iterations;
assert!(
avg_time < Duration::from_millis(1),
"Terminal size detection should be fast"
);
}
#[test]
fn test_pty_allocation_performance() {
let config = PtyConfig::default();
let start = std::time::Instant::now();
let iterations = 10000;
for _ in 0..iterations {
let _ = should_allocate_pty(&config).unwrap();
}
let elapsed = start.elapsed();
let avg_time = elapsed / iterations;
assert!(
avg_time < Duration::from_micros(10),
"PTY allocation decision should be very fast"
);
}
#[cfg(target_os = "macos")]
#[test]
fn test_macos_terminal_compatibility() {
let has_terminal = has_controlling_terminal();
let (width, height) = get_terminal_size().unwrap();
if has_terminal {
assert!(width >= 80);
assert!(height >= 24);
}
}
#[cfg(target_os = "linux")]
#[test]
fn test_linux_terminal_compatibility() {
let has_terminal = has_controlling_terminal();
let (width, height) = get_terminal_size().unwrap();
if has_terminal {
assert!(width >= 80);
assert!(height >= 24);
}
}
#[test]
fn test_extreme_terminal_sizes() {
let (width, height) = get_terminal_size().unwrap();
if width < 20 || height < 5 {
assert!(width > 0);
assert!(height > 0);
}
if width > 300 || height > 100 {
assert!(width <= 1000);
assert!(height <= 300);
}
}