use crate::ansi_processor::AnsiProcessor;
use crate::model::app::AppContext;
use crate::model::muxbox::MuxBox;
use crate::pty_manager::PtyManager;
use std::process::Command;
use std::thread;
use std::time::Duration;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ls_color_output_compatibility() {
let mut processor = AnsiProcessor::with_screen_size(80, 24);
let ls_output = "\x1b[0m\x1b[01;34mbin\x1b[0m \x1b[01;34mlib\x1b[0m \x1b[00msrc\x1b[0m \x1b[01;32mREADME.md\x1b[0m\n";
processor.process_bytes(ls_output.as_bytes());
let content = processor.get_processed_text();
assert!(content.contains("bin"));
assert!(content.contains("lib"));
assert!(content.contains("src"));
assert!(content.contains("README.md"));
assert!(!content.contains("\x1b["));
}
#[test]
fn test_cat_file_output_compatibility() {
let mut processor = AnsiProcessor::with_screen_size(80, 24);
let cat_output = "Hello World\nThis is a test file\nWith multiple lines\n";
processor.process_bytes(cat_output.as_bytes());
let content = processor.get_processed_text();
let lines: Vec<&str> = content.split('\n').collect();
assert_eq!(lines[0], "Hello World");
assert_eq!(lines[1], "This is a test file");
assert_eq!(lines[2], "With multiple lines");
}
#[test]
fn test_grep_output_compatibility() {
let mut processor = AnsiProcessor::with_screen_size(80, 24);
let grep_output = "\x1b[35m\x1b[Kmain.rs\x1b[m\x1b[K:\x1b[36m\x1b[K42\x1b[m\x1b[K:fn \x1b[01;31m\x1b[Kmain\x1b[m\x1b[K() {\n";
processor.process_bytes(grep_output.as_bytes());
let content = processor.get_processed_text();
assert!(content.contains("main.rs"));
assert!(content.contains("42"));
assert!(content.contains("fn main() {"));
}
#[test]
fn test_ps_output_compatibility() {
let mut processor = AnsiProcessor::with_screen_size(120, 24);
let ps_output = " PID TTY TIME CMD\n 1234 pts/0 00:00:01 boxmux\n 5678 pts/1 00:00:00 vim\n";
processor.process_bytes(ps_output.as_bytes());
let content = processor.get_processed_text();
let lines: Vec<&str> = content.split('\n').collect();
assert!(lines[0].contains("PID"));
assert!(lines[0].contains("TTY"));
assert!(lines[0].contains("CMD"));
assert!(lines[1].contains("1234"));
assert!(lines[1].contains("boxmux"));
assert!(lines[2].contains("5678"));
assert!(lines[2].contains("vim"));
}
#[test]
fn test_top_like_header_compatibility() {
let mut processor = AnsiProcessor::with_screen_size(80, 24);
let top_output = "\x1b[H\x1b[2Jtop - 12:34:56 up 1 day, 5:43, 3 users, load average: 0.45, 0.32, 0.28\n";
top_output
.chars()
.for_each(|c| processor.process_bytes(&[c as u8]));
let content = processor.get_processed_text();
assert!(content.contains("top -"));
assert!(content.contains("12:34:56"));
assert!(content.contains("load average"));
let state = processor.get_terminal_state();
assert_eq!(state.get_cursor().x, 0);
assert_eq!(state.get_cursor().y, 1); }
#[test]
fn test_vi_status_line_compatibility() {
let mut processor = AnsiProcessor::with_screen_size(80, 24);
let vi_output = "\x1b[24;1H\"main.rs\" 42L, 1337C\x1b[6n";
processor.process_bytes(vi_output.as_bytes());
let state = processor.get_terminal_state();
assert_eq!(state.get_cursor().y, 23); assert_eq!(state.get_cursor().x, 20);
let content = processor.get_processed_text();
assert!(content.contains("\"main.rs\""));
assert!(content.contains("42L"));
assert!(content.contains("1337C"));
}
#[test]
fn test_less_pager_compatibility() {
let mut processor = AnsiProcessor::with_screen_size(80, 24);
processor.process_bytes(b"Line 1\nLine 2\nLine 3\n");
processor.process_bytes(b"\x1b[24;1H:");
let content = processor.get_processed_text();
let lines: Vec<&str> = content.split('\n').collect();
assert!(lines[0].contains("Line 1"));
assert!(lines[1].contains("Line 2"));
assert!(lines[2].contains("Line 3"));
let state = processor.get_terminal_state();
assert_eq!(state.get_cursor().y, 23); }
#[test]
fn test_nano_editor_compatibility() {
let mut processor = AnsiProcessor::with_screen_size(80, 24);
let nano_output =
"\x1b[H\x1b[2J GNU nano 4.8 main.rs \n";
processor.process_bytes(nano_output.as_bytes());
let content = processor.get_processed_text();
assert!(content.contains("GNU nano"));
assert!(content.contains("main.rs"));
let state = processor.get_terminal_state();
assert_eq!(state.get_cursor().y, 1); }
#[test]
fn test_htop_process_list_compatibility() {
let mut processor = AnsiProcessor::with_screen_size(120, 30);
let htop_output = "\x1b[H\x1b[2J\x1b[1;32m PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND\x1b[0m\n";
htop_output
.chars()
.for_each(|c| processor.process_bytes(&[c as u8]));
let process_line = "\x1b[33m 1234\x1b[0m bahram 20 0 145768 12234 8956 S 0.3 0.8 0:01.23 \x1b[1mboxmux\x1b[0m\n";
processor.process_bytes(process_line.as_bytes());
let content = processor.get_processed_text();
assert!(content.contains("PID USER"));
assert!(content.contains("COMMAND"));
assert!(content.contains("1234"));
assert!(content.contains("bahram"));
assert!(content.contains("boxmux"));
}
#[test]
fn test_terminal_escape_sequence_compatibility() {
let mut processor = AnsiProcessor::with_screen_size(80, 24);
processor.process_bytes(b"\x1b[s"); processor.process_bytes(b"Hello");
processor.process_bytes(b"\x1b[u"); processor.process_bytes(b"World");
let content = processor.get_processed_text();
assert!(content.contains("World"));
processor.process_bytes(b"\x1b[H"); processor.process_bytes(b"Start");
processor.process_bytes(b"\x1b[2;1H"); processor.process_bytes(b"Second");
let final_content = processor.get_processed_text();
assert!(final_content.contains("Start"));
assert!(final_content.contains("Second"));
let state = processor.get_terminal_state();
assert_eq!(state.get_cursor().y, 1); assert_eq!(state.get_cursor().x, 6); }
#[test]
fn test_interactive_program_cursor_handling() {
let mut processor = AnsiProcessor::with_screen_size(80, 24);
processor.process_bytes(b"\x1b[H"); processor.process_bytes(b"Menu:");
processor.process_bytes(b"\x1b[2;5H"); processor.process_bytes(b"1. Option A");
processor.process_bytes(b"\x1b[3;5H"); processor.process_bytes(b"2. Option B");
processor.process_bytes(b"\x1b[2;3H");
let state = processor.get_terminal_state();
assert_eq!(state.get_cursor().y, 1); assert_eq!(state.get_cursor().x, 2);
let content = processor.get_processed_text();
assert!(content.contains("Menu:"));
assert!(content.contains("1. Option A"));
assert!(content.contains("2. Option B"));
}
fn create_test_pty_muxbox() -> MuxBox {
let mut muxbox = MuxBox::default();
muxbox.id = "test_pty".to_string();
muxbox.title = Some("PTY Test".to_string());
muxbox.execution_mode = crate::model::common::ExecutionMode::Pty;
muxbox.script = Some(vec!["echo 'PTY Test'".to_string()]);
muxbox
}
}