Every pack character's face is held to its picture: its eyes are filled cells, its mouth sits on the animal (the anchor is a filled cell, every cell it draws is on the animal or touching it) and never covers an eye, and the colours it draws with are the icon's own.
5use std::collections::HashSet;
7use pixel_mouth::{Level, rects}; 8use whiskers_art::PACK; 9use whiskers_icons::raster::Icon; 10 11fn icon(id: &str) -> Icon { 12 Icon::parse(whiskers_art::pack::pack(id).expect("a pack character").svg).expect("it rasterises") 13} 14 15#[test] 16fn every_face_is_on_its_picture_and_never_covers_an_eye() { 17 for p in PACK { 18 let icon = icon(p.id); 19 assert_eq!(icon.size, 9, "{}", p.id); 20 let filled: HashSet<(i32, i32)> = icon.cells.iter().map(|c| (c.x as i32, c.y as i32)).collect(); 21 let colours: HashSet<u32> = icon.cells.iter().map(|c| (u32::from(c.rgb[0]) << 16) | (u32::from(c.rgb[1]) << 8) | u32::from(c.rgb[2])).collect(); 22 for &(x, y) in p.eyes { 23 assert!(filled.contains(&(i32::from(x), i32::from(y))), "{}: an eye at ({x}, {y}) is not on the picture", p.id); 24 } 25 let (ax, ay) = (p.mouth.anchor.0 as i32, p.mouth.anchor.1 as i32); 26 assert!(filled.contains(&(ax, ay)), "{}: the anchor ({ax}, {ay}) is not on the picture", p.id); 27 assert!(!p.eyes.contains(&(ax as u8, ay as u8)), "{}: the anchor is an eye", p.id); 28 for level in Level::ALL { 29 for r in rects(&p.mouth, level) { 30 assert_eq!((r.x.fract(), r.y.fract(), r.w, r.h), (0.0, 0.0, 1.0, 1.0), "{} {level:?}: a mouth is whole cells", p.id); 31 let (x, y) = (r.x as i32, r.y as i32); 32 assert!((0..9).contains(&x) && (0..9).contains(&y), "{} {level:?}: ({x}, {y}) is off the grid", p.id); 33 let touches = filled.contains(&(x, y)) || [(1, 0), (-1, 0), (0, 1), (0, -1)].iter().any(|(dx, dy)| filled.contains(&(x + dx, y + dy))); 34 assert!(touches, "{} {level:?}: ({x}, {y}) floats off the animal", p.id); 35 assert!(!p.eyes.contains(&(x as u8, y as u8)), "{} {level:?}: the mouth covers the eye at ({x}, {y})", p.id); 36 assert!(colours.contains(&r.rgb), "{} {level:?}: colour {:06x} is not in the icon's palette", p.id, r.rgb); 37 } 38 } 39 } 40} 41 42#[test] 43fn every_open_shape_adds_cells_and_no_two_open_shapes_are_the_same() { 44 for p in PACK { 45 let shapes: Vec<_> = Level::ALL.iter().map(|l| rects(&p.mouth, *l).iter().map(|r| (r.x as i32, r.y as i32, r.rgb)).collect::<Vec<_>>()).collect(); 46 assert!(shapes[0].is_empty(), "{}: shut is the icon's own face", p.id); 47 for (i, a) in shapes.iter().enumerate().skip(1) { 48 assert!(!a.is_empty(), "{}: {:?} adds nothing", p.id, Level::ALL[i]); 49 for b in shapes.iter().skip(i + 1) { 50 assert_ne!(a, b, "{}: two shapes are alike", p.id); 51 } 52 } 53 } 54}