use crate::zone::test_support::{Item, b, params};
use crate::zone::{SplitDir, Zone, segment};
#[test]
fn empty_input_is_leaf() {
let z: Zone<Item> = segment(Vec::new(), ¶ms());
match z {
Zone::Leaf { items, .. } => assert!(items.is_empty()),
_ => panic!("expected leaf"),
}
}
#[test]
fn single_item_is_leaf() {
let items = vec![b(0.0, 0.0, 10.0, 10.0)];
let z = segment(items, ¶ms());
match z {
Zone::Leaf { items, .. } => assert_eq!(items.len(), 1),
_ => panic!("expected leaf"),
}
}
#[test]
fn single_column_is_leaf() {
let items = vec![
b(10.0, 90.0, 100.0, 100.0),
b(10.0, 80.0, 100.0, 90.0),
b(10.0, 70.0, 100.0, 80.0),
];
let z = segment(items, ¶ms());
match z {
Zone::Leaf { items, .. } => assert_eq!(items.len(), 3),
other => panic!("expected leaf, got {:?}", other),
}
}
#[test]
fn two_columns_split_vertical() {
let items = vec![
b(10.0, 90.0, 40.0, 100.0),
b(10.0, 70.0, 40.0, 80.0),
b(60.0, 90.0, 90.0, 100.0),
b(60.0, 70.0, 90.0, 80.0),
];
let z = segment(items, ¶ms());
match z {
Zone::Split { dir, children, .. } => {
assert_eq!(dir, SplitDir::Vertical);
assert_eq!(children.len(), 2);
let left_cx = children[0].bbox().x_center();
let right_cx = children[1].bbox().x_center();
assert!(left_cx < right_cx, "left should sort before right");
}
other => panic!("expected vertical split, got {:?}", other),
}
}
#[test]
fn header_then_body_horizontal_split() {
let items = vec![
b(10.0, 190.0, 100.0, 200.0),
b(10.0, 90.0, 100.0, 100.0),
b(10.0, 80.0, 100.0, 90.0),
];
let z = segment(items, ¶ms());
match z {
Zone::Split { dir, children, .. } => {
assert_eq!(dir, SplitDir::Horizontal);
assert_eq!(children.len(), 2);
assert!(children[0].bbox().y_center() > children[1].bbox().y_center());
}
other => panic!("expected horizontal split, got {:?}", other),
}
}
#[test]
fn three_by_three_grid_is_vertical_of_horizontals() {
let mut items = Vec::new();
for row in 0..3 {
for col in 0..3 {
let x_left = (col as f32) * 30.0;
let y_bottom = (2 - row) as f32 * 30.0;
items.push(b(x_left, y_bottom, x_left + 20.0, y_bottom + 20.0));
}
}
let z = segment(items, ¶ms());
match z {
Zone::Split {
dir: SplitDir::Vertical,
children: cols,
..
} => {
assert_eq!(cols.len(), 3, "expected 3 columns");
for col in &cols {
match col {
Zone::Split {
dir: SplitDir::Horizontal,
children: rows,
..
} => {
assert_eq!(rows.len(), 3, "expected 3 rows per column");
}
other => panic!("expected horizontal split inside column, got {:?}", other),
}
}
}
other => panic!("expected vertical split at top, got {:?}", other),
}
}
#[test]
fn no_split_when_gaps_below_threshold() {
let items = vec![
b(10.0, 0.0, 20.0, 10.0),
b(22.0, 0.0, 30.0, 10.0), ];
let z = segment(items, ¶ms());
match z {
Zone::Leaf { items, .. } => assert_eq!(items.len(), 2),
other => panic!("expected leaf, got {:?}", other),
}
}
#[test]
fn header_band_above_two_columns_lifts_horizontal() {
let items = vec![
b(200.0, 750.0, 450.0, 770.0),
b(80.0, 730.0, 180.0, 740.0),
b(80.0, 715.0, 180.0, 725.0),
b(80.0, 700.0, 180.0, 710.0),
b(80.0, 685.0, 180.0, 695.0),
b(80.0, 670.0, 180.0, 680.0),
b(80.0, 655.0, 180.0, 665.0),
b(250.0, 730.0, 440.0, 740.0),
b(250.0, 715.0, 440.0, 725.0),
b(250.0, 700.0, 440.0, 710.0),
b(250.0, 685.0, 440.0, 695.0),
b(250.0, 670.0, 440.0, 680.0),
b(250.0, 655.0, 440.0, 665.0),
];
let z = segment(items, ¶ms());
match z {
Zone::Split {
dir: SplitDir::Horizontal,
children,
..
} => {
assert_eq!(children.len(), 2, "expected [header, body]");
assert!(
children[0].bbox().y_center() > children[1].bbox().y_center(),
"header should sort above body"
);
match &children[1] {
Zone::Split {
dir: SplitDir::Vertical,
children: cols,
..
} => {
assert_eq!(cols.len(), 2, "expected 2 columns under header");
assert!(cols[0].bbox().x_center() < cols[1].bbox().x_center());
}
Zone::Table { rows, .. } => {
assert_eq!(rows.len(), 6, "expected 6 rows in table");
assert!(rows.iter().all(|r| r.len() == 2));
}
other => panic!(
"expected vertical split (2 cols) or Table under header, got {:?}",
other
),
}
}
other => panic!("expected horizontal split at top, got {:?}", other),
}
}
#[test]
fn largest_gap_wins_when_both_dimensions_have_gaps() {
let items = vec![
b(0.0, 200.0, 30.0, 210.0),
b(40.0, 200.0, 70.0, 210.0),
b(0.0, 100.0, 30.0, 110.0),
b(40.0, 100.0, 70.0, 110.0),
];
let z = segment(items, ¶ms());
match z {
Zone::Split { dir, .. } => {
assert_eq!(dir, SplitDir::Horizontal);
}
other => panic!("expected split, got {:?}", other),
}
}