use super::*;
fn picture(width: u32, height: u32, cells: Rect, source: (f64, f64, f64, f64)) -> Picture {
let data = ImageData::from_rgb(width, height, &vec![90; (width * height * 3) as usize]).expect("pixels");
let ground = Rgb::new(12, 12, 14);
Picture { data, fit: Fit::Cover, area: cells, cells, source, visible: cells, marker: marker(ground), ground }
}
fn cells_of(area: Rect, free: impl Fn(i32, i32) -> bool) -> Vec<(i32, i32)> {
(area.y..area.bottom())
.flat_map(|y| (area.x..area.right()).map(move |x| (x, y)))
.filter(|&(x, y)| free(x, y))
.collect()
}
#[test]
fn free_cells_around_a_hole_are_four_rectangles() {
let area = Rect::new(0, 0, 6, 4);
let hole = Rect::new(2, 1, 2, 2);
let rects = rectangles(&cells_of(area, |x, y| !hole.contains(x, y)), MOST_PLACES).expect("few enough");
assert_eq!(rects, [Rect::new(0, 0, 6, 1), Rect::new(0, 1, 2, 2), Rect::new(4, 1, 2, 2), Rect::new(0, 3, 6, 1)]);
}
#[test]
fn one_rectangle_of_free_cells_is_one_place() {
let area = Rect::new(3, 2, 5, 4);
assert_eq!(rectangles(&cells_of(area, |_, _| true), MOST_PLACES), Some(vec![area]));
assert_eq!(rectangles(&[], MOST_PLACES), Some(Vec::new()), "no free cell, no place");
}
#[test]
fn the_rectangles_cover_exactly_the_free_cells() {
let area = Rect::new(0, 0, 9, 7);
let free = |x: i32, y: i32| (x * 7 + y * 3) % 5 != 0;
let cells = cells_of(area, free);
let rects = rectangles(&cells, 1000).expect("under the cap");
let mut covered: Vec<(i32, i32)> = rects
.iter()
.flat_map(|rect| (rect.y..rect.bottom()).flat_map(move |y| (rect.x..rect.right()).map(move |x| (x, y))))
.collect();
let total = covered.len();
covered.sort_by_key(|&(x, y)| (y, x));
covered.dedup();
assert_eq!(covered.len(), total, "no cell in two rectangles");
assert_eq!(covered, cells, "every free cell, and no other");
}
#[test]
fn more_rectangles_than_the_cap_give_none() {
let area = Rect::new(0, 0, 8, 8);
let board = cells_of(area, |x, y| (x + y) % 2 == 0);
assert_eq!(rectangles(&board, 31), None, "32 lone cells over a cap of 31");
assert_eq!(rectangles(&board, 32).map(|rects| rects.len()), Some(32));
}
fn tiles(crops: &[(u32, u32)], first: u32, end: u32) {
assert_eq!(crops[0].0, first, "the first crop starts where the source does: {crops:?}");
for pair in crops.windows(2) {
assert_eq!(pair[0].0 + pair[0].1, pair[1].0, "neighbours meet at one pixel: {crops:?}");
}
let last = crops[crops.len() - 1];
assert_eq!(last.0 + last.1, end, "the last crop ends where the source does: {crops:?}");
}
#[test]
fn crops_of_neighbouring_rectangles_tile_the_source_exactly() {
let cells = Rect::new(4, 2, 7, 5);
let whole = picture(100, 37, cells, (0.0, 0.0, 100.0, 37.0));
let columns: Vec<(u32, u32)> = (0..7)
.map(|i| {
let (x, _, w, _) = crop(&whole, Rect::new(cells.x + i, cells.y, 1, 5));
(x, w)
})
.collect();
tiles(&columns, 0, 100);
let rows: Vec<(u32, u32)> = (0..5)
.map(|j| {
let (_, y, _, h) = crop(&whole, Rect::new(cells.x, cells.y + j, 7, 1));
(y, h)
})
.collect();
tiles(&rows, 0, 37);
let cut = picture(120, 40, cells, (10.3, 1.7, 99.4, 36.6));
let columns: Vec<(u32, u32)> = [(0, 3), (3, 1), (4, 3)]
.into_iter()
.map(|(from, width)| {
let (x, _, w, _) = crop(&cut, Rect::new(cells.x + from, cells.y, width, 5));
(x, w)
})
.collect();
tiles(&columns, 10, 110);
}