#[cfg(test)]
pub mod unified_execution_architecture_tests {
use crate::model::choice::Choice;
use crate::model::common::ExecutionMode;
use crate::model::muxbox::MuxBox;
use crate::tests::test_utils::TestDataFactory;
use crate::thread_manager::Message;
#[test]
fn test_unified_execution_all_modes_use_thread_manager() {
println!("=== Testing Unified ExecutionMode Architecture ===");
let modes = vec![
ExecutionMode::Immediate,
ExecutionMode::Thread,
ExecutionMode::Pty,
];
for mode in modes {
println!("Testing execution mode: {:?}", mode);
let choice = Choice {
id: format!("test_choice_{}", mode.as_stream_suffix()),
content: Some("Test Choice".to_string()),
selected: false,
hovered: false,
script: Some(vec!["echo hello".to_string()]),
execution_mode: mode.clone(),
redirect_output: None,
append_output: Some(false),
waiting: false,
};
assert_eq!(choice.execution_mode, mode);
let expected_stream_id = format!("{}_{}", choice.id, mode.as_stream_suffix());
let expected_suffix = mode.as_stream_suffix();
match mode {
ExecutionMode::Immediate => assert_eq!(expected_suffix, "immediate"),
ExecutionMode::Thread => assert_eq!(expected_suffix, "thread"),
ExecutionMode::Pty => assert_eq!(expected_suffix, "pty"),
}
println!(
"✓ Mode {:?} uses consistent stream ID format: {}",
mode, expected_stream_id
);
}
}
#[test]
fn test_pty_mode_supports_multiple_commands() {
println!("=== Testing PTY Multiple Commands Support ===");
let choice = Choice {
id: "multi_command_pty".to_string(),
content: Some("Multi-command PTY".to_string()),
selected: false,
script: Some(vec![
"echo 'First command'".to_string(),
"echo 'Second command'".to_string(),
"echo 'Third command'".to_string(),
]),
hovered: false,
execution_mode: ExecutionMode::Pty,
redirect_output: None,
append_output: Some(false),
waiting: false,
};
assert_eq!(choice.script.as_ref().unwrap().len(), 3);
assert_eq!(choice.execution_mode, ExecutionMode::Pty);
println!(
"✓ PTY mode supports {} commands",
choice.script.as_ref().unwrap().len()
);
for (i, cmd) in choice.script.as_ref().unwrap().iter().enumerate() {
println!(" Command {}: {}", i + 1, cmd);
}
}
#[test]
fn test_multiple_clicks_create_multiple_streams() {
println!("=== Testing Multiple Click Stream Creation ===");
let choice_template = Choice {
id: "sensitive_choice".to_string(),
content: Some("Sensitive Choice".to_string()),
selected: false,
hovered: false,
script: Some(vec!["echo test".to_string()]),
execution_mode: ExecutionMode::Pty,
redirect_output: None,
append_output: Some(false),
waiting: false,
};
let mut stream_ids = Vec::new();
for click_num in 1..=3 {
let stream_id = format!(
"{}_{}_click{}",
choice_template.id,
choice_template.execution_mode.as_stream_suffix(),
click_num
);
stream_ids.push(stream_id);
}
let mut unique_ids = stream_ids.clone();
unique_ids.sort();
unique_ids.dedup();
assert_eq!(
stream_ids.len(),
unique_ids.len(),
"All stream IDs should be unique"
);
for (i, stream_id) in stream_ids.iter().enumerate() {
println!("✓ Click {} creates stream: {}", i + 1, stream_id);
}
}
#[test]
fn test_consistent_stream_creation_message_format() {
println!("=== Testing Consistent Stream Creation Messages ===");
let choice = Choice {
id: "consistent_choice".to_string(),
content: Some("Consistent Choice".to_string()),
selected: false,
hovered: false,
script: Some(vec!["echo test".to_string()]),
execution_mode: ExecutionMode::Thread,
redirect_output: Some("target_box".to_string()),
append_output: Some(false),
waiting: false,
};
let expected_stream_id =
format!("{}_{}", choice.id, choice.execution_mode.as_stream_suffix());
let expected_target = choice.redirect_output.as_ref().unwrap();
println!("✓ Stream ID format: {}", expected_stream_id);
println!("✓ Target muxbox: {}", expected_target);
println!("✓ Execution mode: {:?}", choice.execution_mode);
assert!(expected_stream_id.contains(&choice.id));
assert!(expected_stream_id.contains("thread")); }
#[test]
fn test_legacy_boolean_fields_ignored() {
println!("=== Testing Legacy Boolean Fields Are Ignored ===");
let choice_with_legacy = Choice {
id: "legacy_test".to_string(),
content: Some("Legacy Test".to_string()),
selected: false,
script: Some(vec!["echo test".to_string()]),
hovered: false,
execution_mode: ExecutionMode::Immediate, redirect_output: None,
append_output: Some(false),
waiting: false,
};
assert_eq!(choice_with_legacy.execution_mode, ExecutionMode::Immediate);
println!(
"✓ ExecutionMode field: {:?} (takes precedence)",
choice_with_legacy.execution_mode
);
let stream_suffix = choice_with_legacy.execution_mode.as_stream_suffix();
assert_eq!(stream_suffix, "immediate");
println!(
"✓ Stream suffix correctly uses ExecutionMode: {}",
stream_suffix
);
}
#[test]
fn test_consistent_stream_labeling() {
println!("=== Testing Consistent Stream Labeling ===");
let modes = vec![
(ExecutionMode::Immediate, "immediate"),
(ExecutionMode::Thread, "thread"),
(ExecutionMode::Pty, "pty"),
];
for (mode, expected_suffix) in modes {
let choice = Choice {
id: format!("label_test_{}", expected_suffix),
content: Some(format!("Label Test {}", expected_suffix)),
selected: false,
hovered: false,
script: Some(vec!["echo test".to_string()]),
execution_mode: mode.clone(),
redirect_output: None,
append_output: Some(false),
waiting: false,
};
let stream_id = format!("{}_{}", choice.id, mode.as_stream_suffix());
let expected_label = format!("{} ({})", choice.id, expected_suffix);
assert_eq!(mode.as_stream_suffix(), expected_suffix);
println!(
"✓ Mode {:?}: stream_id={}, label={}",
mode, stream_id, expected_label
);
}
}
}