use crate::{grid::Grid, input::Nop, pos::Size};
use owo_colors::Style;
use crate::{
Event,
input::FrameInput,
output::StyledChar,
pos::{X, Y},
};
use super::Frame;
#[test]
fn empty_splits_are_empty() {
let (t, b) = Frame::nop(Size::ZERO).split_v(Y(0)).expect("couldn't split at y=0");
assert!(t.is_empty());
assert!(b.is_empty());
let (l, r) = Frame::nop(Size::ZERO).split_h(X(0)).expect("couldn't split at x=0");
assert!(l.is_empty());
assert!(r.is_empty());
}
#[test]
fn oob_splits_are_none() {
assert!(Frame::nop(Size::ZERO).split_v(Y(1)).is_none(), "could get 1st row of empty frame",);
assert!(Frame::nop(Size::ZERO).split_h(X(1)).is_none(), "could get 1st col of empty frame",);
}
const BLANK_CHAR: StyledChar = StyledChar::from_owo(Style::new().red().on_green().style('_'));
const WRITTEN_CHAR: StyledChar = StyledChar::from_owo(Style::new().yellow().on_black().style('#'));
fn cg(x: usize, y: usize) -> Grid<StyledChar> {
let mut res = Grid::<StyledChar>::new(Size::rnew(x, y));
res.all_cells().fill(BLANK_CHAR);
res
}
fn fill(name: &str, f: &mut Frame<impl FrameInput>) {
println!("filling {name}: {f:?}");
for y in f.rows() {
let mut row = f.row(y);
for (x, cell) in row.iter_mut().enumerate() {
if *cell != BLANK_CHAR {
panic!("{name}:{x},{y} was already written");
}
*cell = WRITTEN_CHAR;
}
}
for y in f.rows() {
f.row(y).fill(BLANK_CHAR);
}
}
macro_rules! assert_frame {
($frame:expr, ($x:literal, $y:literal; $w:literal, $h:literal)) => {
let mut frame = $frame;
assert_eq!(frame.area.bounds.tl, ($x, $y), concat!("'", stringify!($frame), "' pos is wrong"));
assert_eq!(frame.size(), ($w, $h), concat!("'", stringify!($frame), "' size is wrong"));
fill(stringify!($frame), &mut frame);
};
}
macro_rules! test_splits {
( $(
$name:ident: ($w:literal x $h:literal).$mthd:ident($pos:expr) =>
($x1:literal, $y1:literal, $w1:literal, $h1:literal),
($x2:literal, $y2:literal, $w2:literal, $h2:literal)
);* $(;)? ) => { $(
#[test]
fn $name() {
let mut v = cg($w, $h);
let frame = Frame::new(Nop, &mut v);
println!("frame: {frame:?}");
assert!(!frame.is_empty(), "can't test splits on empty frames");
let (s1, s2) = frame.$mthd($pos).expect("split was unexpectedly out of bounds");
println!("s1: {s1:?}");
println!("s2: {s2:?}");
assert_frame!(s1, ($x1, $y1; $w1, $h1));
assert_frame!(s2, ($x2, $y2; $w2, $h2));
}
)* }
}
test_splits! {
one_row_v0: (10 x 1).split_v(Y(0)) => (0, 0, 10, 0), (0, 0, 10, 1);
one_row_v1: (10 x 1).split_v(Y(1)) => (0, 0, 10, 1), (0, 0, 10, 0);
one_row_h0: (10 x 1).split_h(X(0)) => (0, 0, 0, 1), (0, 0, 10, 1);
one_row_h1: (10 x 1).split_h(X(1)) => (0, 0, 1, 1), (1, 0, 9, 1);
one_col_v0: (1 x 10).split_v(Y(0)) => (0, 0, 1, 0), (0, 0, 1, 10);
one_col_v1: (1 x 10).split_v(Y(1)) => (0, 0, 1, 1), (0, 1, 1, 9);
one_col_h0: (1 x 10).split_h(X(0)) => (0, 0, 0, 10), (0, 0, 1, 10);
one_col_h1: (1 x 10).split_h(X(1)) => (0, 0, 1, 10), (0, 0, 0, 10);
split_2x2_v0: (2 x 2).split_v(Y(0)) => (0, 0, 2, 0), (0, 0, 2, 2);
split_2x2_v1: (2 x 2).split_v(Y(1)) => (0, 0, 2, 1), (0, 1, 2, 1);
split_2x2_v2: (2 x 2).split_v(Y(2)) => (0, 0, 2, 2), (0, 0, 2, 0);
split_2x2_h0: (2 x 2).split_h(X(0)) => (0, 0, 0, 2), (0, 0, 2, 2);
split_2x2_h1: (2 x 2).split_h(X(1)) => (0, 0, 1, 2), (1, 0, 1, 2);
split_2x2_h2: (2 x 2).split_h(X(2)) => (0, 0, 2, 2), (0, 0, 0, 2);
}
#[test]
fn split_treely() {
let mut v = cg(10, 10);
let frame = Frame::new(Event::default(), &mut v);
assert_eq!(frame.size(), (10, 10));
let (mut t, mut b) = frame.split_v(Y(3)).unwrap();
assert_frame!(&mut t, (0, 0; 10, 3));
assert_frame!(&mut b, (0, 3; 10, 7));
let (mut tl, mut tr) = t.split_h(X(4)).unwrap();
assert_frame!(&mut tl, (0, 0; 4, 3));
assert_frame!(&mut tr, (4, 0; 6, 3));
let (mut bl, mut br) = b.split_h(X(8)).unwrap();
assert_frame!(&mut bl, (0, 3; 8, 7));
assert_frame!(&mut br, (8, 3; 2, 7));
let (mut tll, mut tlr) = tl.split_h(X(3)).unwrap();
assert_frame!(&mut tll, (0, 0; 3, 3));
assert_frame!(&mut tlr, (3, 0; 1, 3));
let (mut brt, mut brb) = br.split_v(Y(5)).unwrap();
assert_frame!(&mut brt, (8, 3; 2, 5));
assert_frame!(&mut brb, (8, 8; 2, 2));
}
#[test]
fn split_lots() {
let mut v = cg(10, 10);
let rest = Frame::new(Event::default(), &mut v);
let (h, mut rest) = rest.split_v(Y(1)).unwrap();
assert_frame!(h, (0, 0; 10, 1));
assert_frame!(&mut rest, (0, 1; 10, 9));
let (h, mut rest) = rest.split_v(Y(2)).unwrap();
assert_frame!(h, (0, 1; 10, 2));
assert_frame!(&mut rest, (0, 3; 10, 7));
let (h, mut rest) = rest.split_h(X(1)).unwrap();
assert_frame!(h, (0, 3; 1, 7));
assert_frame!(&mut rest, (1, 3; 9, 7));
let (h, mut rest) = rest.split_v(Y(1)).unwrap();
assert_frame!(h, (1, 3; 9, 1));
assert_frame!(&mut rest, (1, 4; 9, 6));
let (h, mut rest) = rest.split_h(X(2)).unwrap();
assert_frame!(h, (1, 4; 2, 6));
assert_frame!(&mut rest, (3, 4; 7, 6));
let (h, mut rest) = rest.split_h(X(1)).unwrap();
assert_frame!(h, (3, 4; 1, 6));
assert_frame!(&mut rest, (4, 4; 6, 6));
assert!(!rest.is_empty());
}