use ascfix::{
normalizer::{
align_horizontal_arrows, align_vertical_arrows, balance_horizontal_boxes,
normalize_box_widths, normalize_nested_boxes, normalize_padding,
},
primitives::{Box as DiagramBox, BoxStyle, PrimitiveInventory, TextRow},
renderer::render_diagram,
};
#[allow(dead_code)]
const fn is_border_char_of_box(ch: char, b: &DiagramBox) -> bool {
let chars = b.style.chars();
if ch == chars.top_left
|| ch == chars.top_right
|| ch == chars.bottom_left
|| ch == chars.bottom_right
{
return true;
}
if ch == chars.horizontal {
return true;
}
if ch == chars.vertical {
return true;
}
false
}
#[test]
fn test_parent_expands_to_contain_children() {
let mut inventory = PrimitiveInventory::default();
inventory.boxes.push(DiagramBox {
top_left: (0, 0),
bottom_right: (4, 15), style: BoxStyle::Single,
parent_idx: None,
child_indices: vec![1, 2],
});
inventory.boxes.push(DiagramBox {
top_left: (2, 2),
bottom_right: (4, 10), style: BoxStyle::Single,
parent_idx: Some(0),
child_indices: Vec::new(),
});
inventory.boxes.push(DiagramBox {
top_left: (2, 12),
bottom_right: (4, 20), style: BoxStyle::Single,
parent_idx: Some(0),
child_indices: Vec::new(),
});
inventory.text_rows.push(TextRow {
row: 3,
start_col: 3,
end_col: 9,
content: "Child A".to_string(),
});
inventory.text_rows.push(TextRow {
row: 3,
start_col: 13,
end_col: 19,
content: "Child B".to_string(),
});
let after_widths = normalize_box_widths(&inventory);
println!("After normalize_box_widths:");
for (i, b) in after_widths.boxes.iter().enumerate() {
println!(
" Box {}: ({},{}) -> ({},{})",
i, b.top_left.0, b.top_left.1, b.bottom_right.0, b.bottom_right.1
);
}
let after_nested = normalize_nested_boxes(&after_widths);
println!("After normalize_nested_boxes:");
for (i, b) in after_nested.boxes.iter().enumerate() {
println!(
" Box {}: ({},{}) -> ({},{})",
i, b.top_left.0, b.top_left.1, b.bottom_right.0, b.bottom_right.1
);
}
let after_arrows_h = align_horizontal_arrows(&after_nested);
println!("After align_horizontal_arrows:");
for (i, b) in after_arrows_h.boxes.iter().enumerate() {
println!(
" Box {}: ({},{}) -> ({},{})",
i, b.top_left.0, b.top_left.1, b.bottom_right.0, b.bottom_right.1
);
}
let after_arrows_v = align_vertical_arrows(&after_arrows_h);
println!("After align_vertical_arrows:");
for (i, b) in after_arrows_v.boxes.iter().enumerate() {
println!(
" Box {}: ({},{}) -> ({},{})",
i, b.top_left.0, b.top_left.1, b.bottom_right.0, b.bottom_right.1
);
}
let after_balance = balance_horizontal_boxes(&after_arrows_v);
println!("After balance_horizontal_boxes:");
for (i, b) in after_balance.boxes.iter().enumerate() {
println!(
" Box {}: ({},{}) -> ({},{})",
i, b.top_left.0, b.top_left.1, b.bottom_right.0, b.bottom_right.1
);
}
let normalized = normalize_padding(&after_balance);
println!("Text rows after normalization:");
for (i, row) in normalized.text_rows.iter().enumerate() {
println!(
" Text row {}: row={}, col={}-{}, content='{}'",
i, row.row, row.start_col, row.end_col, row.content
);
}
let result_grid = render_diagram(&normalized);
println!("Row 3 contents:");
for col in 0..result_grid.width() {
let ch = result_grid.get(3, col).unwrap_or('?');
print!("{ch}");
}
println!();
let _result = result_grid.render();
assert!(
normalized.boxes[0].width() >= 22,
"Parent should be at least 22 wide, got {}",
normalized.boxes[0].width()
);
}
#[test]
fn test_three_level_nesting() {
let mut inventory = PrimitiveInventory::default();
inventory.boxes.push(DiagramBox {
top_left: (0, 0),
bottom_right: (10, 25),
style: BoxStyle::Single,
parent_idx: None,
child_indices: vec![1],
});
inventory.boxes.push(DiagramBox {
top_left: (2, 2),
bottom_right: (8, 23),
style: BoxStyle::Double,
parent_idx: Some(0),
child_indices: vec![2],
});
inventory.boxes.push(DiagramBox {
top_left: (4, 5),
bottom_right: (6, 15),
style: BoxStyle::Rounded,
parent_idx: Some(1),
child_indices: Vec::new(),
});
let normalized = normalize_box_widths(&inventory);
let normalized = normalize_nested_boxes(&normalized);
let normalized = align_horizontal_arrows(&normalized);
let normalized = align_vertical_arrows(&normalized);
let normalized = balance_horizontal_boxes(&normalized);
let normalized = normalize_padding(&normalized);
let result_grid = render_diagram(&normalized);
assert_eq!(result_grid.get(0, 0), Some('┌')); assert_eq!(result_grid.get(2, 2), Some('╔')); assert_eq!(result_grid.get(4, 5), Some('╭'));
let _result = result_grid.render();
}
#[test]
fn test_parent_child_rendering() {
let mut inventory = PrimitiveInventory::default();
inventory.boxes.push(DiagramBox {
top_left: (0, 0),
bottom_right: (6, 15), style: BoxStyle::Single,
parent_idx: None,
child_indices: vec![1],
});
inventory.boxes.push(DiagramBox {
top_left: (2, 2),
bottom_right: (4, 10), style: BoxStyle::Single,
parent_idx: Some(0),
child_indices: Vec::new(),
});
inventory.text_rows.push(TextRow {
row: 3,
start_col: 3, end_col: 9,
content: "Hello".to_string(),
});
let normalized = normalize_box_widths(&inventory);
let normalized = normalize_nested_boxes(&normalized);
let normalized = normalize_padding(&normalized);
println!("Final boxes:");
for (i, b) in normalized.boxes.iter().enumerate() {
println!(
" Box {}: ({},{}) -> ({},{})",
i, b.top_left.0, b.top_left.1, b.bottom_right.0, b.bottom_right.1
);
}
println!("Final text:");
for (i, row) in normalized.text_rows.iter().enumerate() {
println!(
" Text {}: row={}, col={}-{}, content='{}'",
i, row.row, row.start_col, row.end_col, row.content
);
}
let result_grid = render_diagram(&normalized);
let result = result_grid.render();
println!("Result:\n{result}");
let lines: Vec<&str> = result.lines().collect();
if lines.len() > 3 {
let row3 = lines[3];
println!("Row 3: '{row3}'");
}
}