#[cfg(test)]
mod tests {
use crate::draw_loop::{calculate_new_bounds, detect_resize_edge, ResizeEdge};
use crate::model::app::{save_muxbox_bounds_to_yaml, update_muxbox_bounds_recursive};
use crate::model::common::InputBounds;
use crate::tests::test_utils::TestDataFactory;
use std::fs;
use tempfile::NamedTempFile;
#[test]
fn test_resize_edge_detection() {
let mut muxbox = TestDataFactory::create_test_muxbox("test");
muxbox.position = InputBounds {
x1: "10%".to_string(),
y1: "10%".to_string(),
x2: "50%".to_string(),
y2: "50%".to_string(),
};
let bounds = muxbox.bounds();
println!(
"MuxBox bounds: ({}, {}) to ({}, {})",
bounds.x1, bounds.y1, bounds.x2, bounds.y2
);
let corner = detect_resize_edge(&muxbox, bounds.x2 as u16, bounds.y2 as u16);
assert_eq!(corner, Some(ResizeEdge::BottomRight));
if bounds.x2 > 0 && bounds.y2 > 0 {
let corner_near =
detect_resize_edge(&muxbox, (bounds.x2 - 1) as u16, (bounds.y2 - 1) as u16);
assert_eq!(corner_near, Some(ResizeEdge::BottomRight));
}
let right_edge = detect_resize_edge(
&muxbox,
bounds.x2 as u16,
(bounds.y1 + bounds.height() / 2) as u16,
);
assert_eq!(right_edge, None);
let bottom_edge = detect_resize_edge(
&muxbox,
(bounds.x1 + bounds.width() / 2) as u16,
bounds.y2 as u16,
);
assert_eq!(bottom_edge, None);
let no_edge = detect_resize_edge(
&muxbox,
(bounds.x1 + bounds.width() / 4) as u16,
(bounds.y1 + bounds.height() / 4) as u16,
);
assert_eq!(no_edge, None);
}
#[test]
fn test_bounds_calculation() {
let original_bounds = InputBounds {
x1: "10%".to_string(),
y1: "10%".to_string(),
x2: "50%".to_string(),
y2: "50%".to_string(),
};
let new_bounds = calculate_new_bounds(
&original_bounds,
&ResizeEdge::BottomRight,
50,
50, 60,
60, 100,
100, );
assert_eq!(new_bounds.x2, "60%"); assert_eq!(new_bounds.y2, "60%"); assert_eq!(new_bounds.x1, "10%"); assert_eq!(new_bounds.y1, "10%"); }
#[test]
fn test_yaml_bounds_update() {
let yaml_content = r#"
layouts:
- id: "test_layout"
children:
- id: "muxbox1"
x1: "10%"
y1: "10%"
x2: "50%"
y2: "50%"
content: "Test muxbox"
- id: "muxbox2"
x1: "60%"
y1: "10%"
x2: "90%"
y2: "50%"
content: "Another muxbox"
"#;
let mut temp_file = NamedTempFile::new().expect("Failed to create temp file");
fs::write(&temp_file, yaml_content).expect("Failed to write temp file");
let new_bounds = InputBounds {
x1: "10%".to_string(),
y1: "10%".to_string(),
x2: "60%".to_string(),
y2: "60%".to_string(),
};
let result =
save_muxbox_bounds_to_yaml(temp_file.path().to_str().unwrap(), "muxbox1", &new_bounds);
assert!(result.is_ok());
let updated_content = fs::read_to_string(&temp_file).expect("Failed to read updated file");
assert!(updated_content.contains("x2: 60%"));
assert!(updated_content.contains("y2: 60%"));
}
#[test]
fn test_recursive_bounds_update() {
let yaml_content = r#"
layouts:
- id: "test_layout"
children:
- id: "parent_muxbox"
x1: "0%"
y1: "0%"
x2: "100%"
y2: "100%"
children:
- id: "nested_muxbox"
x1: "20%"
y1: "20%"
x2: "80%"
y2: "80%"
content: "Nested muxbox"
"#;
let mut yaml_value: serde_yaml::Value = serde_yaml::from_str(yaml_content).unwrap();
let new_bounds = InputBounds {
x1: "20%".to_string(),
y1: "20%".to_string(),
x2: "90%".to_string(),
y2: "90%".to_string(),
};
let result = update_muxbox_bounds_recursive(&mut yaml_value, "nested_muxbox", &new_bounds);
assert!(result.is_ok());
assert!(result.unwrap());
let updated_yaml = serde_yaml::to_string(&yaml_value).unwrap();
assert!(updated_yaml.contains("x2: 90%"));
assert!(updated_yaml.contains("y2: 90%"));
}
#[test]
fn test_nonexistent_muxbox_bounds_update() {
let yaml_content = r#"
layouts:
- id: "test_layout"
children:
- id: "muxbox1"
x1: "10%"
y1: "10%"
x2: "50%"
y2: "50%"
"#;
let mut yaml_value: serde_yaml::Value = serde_yaml::from_str(yaml_content).unwrap();
let new_bounds = InputBounds {
x1: "10%".to_string(),
y1: "10%".to_string(),
x2: "60%".to_string(),
y2: "60%".to_string(),
};
let result = update_muxbox_bounds_recursive(&mut yaml_value, "nonexistent", &new_bounds);
assert!(result.is_ok());
assert!(!result.unwrap()); }
#[test]
fn test_minimum_width_constraint() {
let original_bounds = InputBounds {
x1: "10%".to_string(),
y1: "10%".to_string(),
x2: "20%".to_string(),
y2: "30%".to_string(),
};
let new_bounds = calculate_new_bounds(
&original_bounds,
&ResizeEdge::BottomRight,
20,
30, 12,
40, 100,
100, );
let x2_percent: f32 = new_bounds.x2.replace('%', "").parse().unwrap();
assert!(
x2_percent >= 12.0,
"Width constraint should prevent x2 < 12% (got {}%)",
x2_percent
);
}
#[test]
fn test_minimum_height_constraint() {
let original_bounds = InputBounds {
x1: "10%".to_string(),
y1: "20%".to_string(),
x2: "50%".to_string(),
y2: "30%".to_string(),
};
let new_bounds = calculate_new_bounds(
&original_bounds,
&ResizeEdge::BottomRight,
50,
30, 60,
22, 100,
100, );
let y2_percent: f32 = new_bounds.y2.replace('%', "").parse().unwrap();
assert!(
y2_percent >= 22.0,
"Height constraint should prevent y2 < 22% (got {}%)",
y2_percent
);
}
#[test]
fn test_normal_resize_unaffected() {
let original_bounds = InputBounds {
x1: "10%".to_string(),
y1: "10%".to_string(),
x2: "50%".to_string(),
y2: "50%".to_string(),
};
let new_bounds = calculate_new_bounds(
&original_bounds,
&ResizeEdge::BottomRight,
50,
50, 60,
60, 100,
100, );
assert_eq!(new_bounds.x2, "60%");
assert_eq!(new_bounds.y2, "60%");
assert_eq!(new_bounds.x1, "10%"); assert_eq!(new_bounds.y1, "10%"); }
#[test]
fn test_both_constraints_simultaneously() {
let original_bounds = InputBounds {
x1: "40%".to_string(),
y1: "30%".to_string(),
x2: "45%".to_string(),
y2: "35%".to_string(),
};
let new_bounds = calculate_new_bounds(
&original_bounds,
&ResizeEdge::BottomRight,
45,
35, 42,
31, 100,
100, );
let x2_percent: f32 = new_bounds.x2.replace('%', "").parse().unwrap();
let y2_percent: f32 = new_bounds.y2.replace('%', "").parse().unwrap();
assert!(
x2_percent >= 42.0,
"Width should be constrained to minimum (got {}%)",
x2_percent
);
assert!(
y2_percent >= 32.0,
"Height should be constrained to minimum (got {}%)",
y2_percent
);
}
#[test]
fn test_different_terminal_sizes() {
let original_bounds = InputBounds {
x1: "10%".to_string(),
y1: "10%".to_string(),
x2: "15%".to_string(),
y2: "15%".to_string(),
};
let new_bounds_large = calculate_new_bounds(
&original_bounds,
&ResizeEdge::BottomRight,
30,
30, 25,
25, 200,
200, );
let x2_percent: f32 = new_bounds_large.x2.replace('%', "").parse().unwrap();
let y2_percent: f32 = new_bounds_large.y2.replace('%', "").parse().unwrap();
assert!(
x2_percent >= 11.0,
"Large terminal width constraint failed (got {}%)",
x2_percent
);
assert!(
y2_percent >= 11.0,
"Large terminal height constraint failed (got {}%)",
y2_percent
);
}
}