test(maze): 88% coverage

This commit is contained in:
Kristofers Solo 2024-12-25 21:24:55 +02:00
parent 012d1e5cca
commit 43a669dee8
3 changed files with 175 additions and 179 deletions

View File

@ -22,6 +22,17 @@ pub struct HexMaze(HashMap<Hex, HexTile>);
impl HexMaze {
/// Creates a new empty maze
///
/// # Examples
///
/// ```
/// use hexlab::prelude::*;
///
/// let maze = HexMaze::new();
///
/// assert!(maze.is_empty());
/// assert_eq!(maze.len(), 0);
/// ```
#[cfg_attr(not(debug_assertions), inline)]
#[must_use]
pub fn new() -> Self {
@ -33,6 +44,20 @@ impl HexMaze {
/// # Arguments
///
/// - `coords` - The hexagonal coordinates where the tile should be added.
///
/// # Examples
///
/// ```
/// use hexlab::prelude::*;
///
/// let mut maze = HexMaze::new();
/// let coord = Hex::ZERO;
/// maze.add_tile(coord);
///
/// assert_eq!(maze.len(), 1);
/// assert!(!maze.is_empty());
/// assert!(!maze.get_tile(&coord).is_some());
/// ```
pub fn add_tile(&mut self, coords: Hex) {
let tile = HexTile::new(coords);
self.0.insert(coords, tile);
@ -44,6 +69,20 @@ impl HexMaze {
///
/// - `coord` - The hexagonal coordinates of the tile.
/// - `direction` - The direction in which to add the wall.
///
/// # Examples
///
/// ```
/// use hexlab::prelude::*;
///
/// let mut maze = HexMaze::new();
/// let coord = Hex::ZERO;
/// maze.add_tile(coord);
///
/// maze.add_wall(coord, EdgeDirection::FLAT_NORTH);
/// let walls = maze.get_walls(&coord).unwrap();
/// assert!(walls.contains(EdgeDirection::FLAT_NORTH));
/// ```
pub fn add_wall(&mut self, coord: Hex, direction: EdgeDirection) {
if let Some(tile) = self.0.get_mut(&coord) {
tile.walls.add(direction);
@ -55,6 +94,18 @@ impl HexMaze {
/// # Arguments
///
/// - `coord` - The hexagonal coordinates of the tile to retrieve.
///
/// # Examples
///
/// ```
/// use hexlab::prelude::*;
///
/// let mut maze = HexMaze::new();
/// let coord = Hex::ZERO;
/// maze.add_tile(coord);
///
/// assert!(!maze.get_tile(&coord).is_some());
/// ```
#[cfg_attr(not(debug_assertions), inline)]
#[must_use]
pub fn get_tile(&self, coord: &Hex) -> Option<&HexTile> {
@ -66,11 +117,40 @@ impl HexMaze {
/// # Arguments
///
/// - `coord` - The hexagonal coordinates of the tile whose walls to retrieve.
///
/// # Examples
///
/// ```
/// use hexlab::prelude::*;
///
/// let mut maze = HexMaze::new();
/// let coord = Hex::new(0, 0);
/// maze.add_tile(coord);
///
/// maze.add_wall(coord, EdgeDirection::FLAT_NORTH);
/// let walls = maze.get_walls(&coord).unwrap();
/// assert!(walls.contains(EdgeDirection::FLAT_NORTH));
/// ```
pub fn get_walls(&self, coord: &Hex) -> Option<&Walls> {
self.0.get(coord).map(HexTile::walls)
}
/// Returns the number of tiles in the maze.
///
/// # Examples
///
/// ```
/// use hexlab::prelude::*;
///
/// let mut maze = HexMaze::new();
/// assert_eq!(maze.len(), 0);
///
/// maze.add_tile(Hex::new(0, 0));
/// assert_eq!(maze.len(), 1);
///
/// maze.add_tile(Hex::new(1, -1));
/// assert_eq!(maze.len(), 2);
/// ```
#[cfg_attr(not(debug_assertions), inline)]
#[must_use]
pub fn len(&self) -> usize {
@ -78,6 +158,18 @@ impl HexMaze {
}
/// Returns `true` if the maze contains no tiles.
///
/// # Examples
///
/// ```
/// use hexlab::prelude::*;
///
/// let mut maze = HexMaze::new();
/// assert!(maze.is_empty());
///
/// maze.add_tile(Hex::ZERO);
/// assert!(!maze.is_empty());
/// ```
#[cfg_attr(not(debug_assertions), inline)]
#[must_use]
pub fn is_empty(&self) -> bool {
@ -90,6 +182,21 @@ impl HexMaze {
///
/// - `coord` - The hexagonal coordinates of the tile.
/// - `direction` - The direction of the wall to remove.
/// # Examples
///
/// ```
/// use hexlab::prelude::*;
///
/// let mut maze = HexMaze::new();
/// let coord = Hex::ZERO;
/// maze.add_tile(coord);
///
/// maze.add_wall(coord, EdgeDirection::FLAT_NORTH);
/// maze.remove_tile_wall(&coord, EdgeDirection::FLAT_NORTH);
///
/// let walls = maze.get_walls(&coord).unwrap();
/// assert!(!walls.contains(EdgeDirection::FLAT_NORTH));
/// ```
pub fn remove_tile_wall(&mut self, coord: &Hex, direction: EdgeDirection) {
if let Some(tile) = self.0.get_mut(coord) {
tile.walls.remove(direction);
@ -109,173 +216,3 @@ impl DerefMut for HexMaze {
&mut self.0
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn new_maze() {
let maze = HexMaze::default();
assert!(maze.is_empty(), "New maze should be empty");
assert_eq!(maze.len(), 0, "New maze should have zero tiles");
}
#[test]
fn add_tile() {
let mut maze = HexMaze::default();
let coords = [Hex::ZERO, Hex::new(1, -1), Hex::new(-1, 1)];
// Add tiles
for &coord in &coords {
maze.add_tile(coord);
assert!(
maze.get_tile(&coord).is_some(),
"Tile should exist after adding"
);
}
assert_eq!(
maze.len(),
coords.len(),
"Maze should contain all added tiles"
);
}
#[test]
fn wall_operations() {
let mut maze = HexMaze::default();
let coord = Hex::ZERO;
maze.add_tile(coord);
// Test adding walls
let directions = [
EdgeDirection::FLAT_TOP,
EdgeDirection::FLAT_BOTTOM,
EdgeDirection::POINTY_TOP_RIGHT,
];
for &direction in &directions {
maze.add_wall(coord, direction);
assert!(
maze.get_walls(&coord).unwrap().contains(direction),
"Wall should exist after adding"
);
}
}
#[test]
fn tile_iteration() {
let mut maze = HexMaze::default();
let coords = [Hex::ZERO, Hex::new(1, 0), Hex::new(0, 1)];
// Add tiles
for &coord in &coords {
maze.add_tile(coord);
}
// Test iterator
let collected = maze.iter().map(|(_, tile)| tile).collect::<Vec<_>>();
assert_eq!(
collected.len(),
coords.len(),
"Iterator should yield all tiles"
);
}
#[test]
fn maze_clone() {
let mut maze = HexMaze::default();
let coord = Hex::ZERO;
maze.add_tile(coord);
maze.add_wall(coord, EdgeDirection::FLAT_TOP);
// Test cloning
let cloned_maze = maze.clone();
assert_eq!(
maze.len(),
cloned_maze.len(),
"Cloned maze should have same size"
);
assert!(
cloned_maze
.get_walls(&coord)
.unwrap()
.contains(EdgeDirection::FLAT_TOP),
"Cloned maze should preserve wall state"
);
}
#[test]
fn empty_tile_operations() {
let mut maze = HexMaze::default();
let coord = Hex::ZERO;
// Operations on non-existent tile
assert!(
maze.get_tile(&coord).is_none(),
"Should return None for non-existent tile"
);
assert!(
maze.get_walls(&coord).is_none(),
"Should return None for non-existent walls"
);
// Adding wall to non-existent tile should not panic
maze.add_wall(coord, EdgeDirection::FLAT_TOP);
}
#[test]
fn maze_boundaries() {
let mut maze = HexMaze::default();
let extreme_coords = [
Hex::new(i32::MAX, i32::MIN),
Hex::new(i32::MIN, i32::MAX),
Hex::new(0, i32::MAX),
Hex::new(0, i32::MIN),
Hex::new(i32::MAX, 0),
Hex::new(i32::MIN, 0),
];
// Test with extreme coordinates
for &coord in &extreme_coords {
maze.add_tile(coord);
assert!(
maze.get_tile(&coord).is_some(),
"Should handle extreme coordinates"
);
}
}
#[test]
fn iterator_consistency() {
let mut maze = HexMaze::default();
let coords = [Hex::ZERO, Hex::new(1, -1), Hex::new(-1, 1)];
// Add tiles
for &coord in &coords {
maze.add_tile(coord);
}
// Verify iterator
let iter_coords = maze.iter().map(|(coord, _)| *coord).collect::<Vec<_>>();
assert_eq!(
iter_coords.len(),
coords.len(),
"Iterator should yield all coordinates"
);
for coord in coords {
assert!(
iter_coords.contains(&coord),
"Iterator should contain all added coordinates"
);
}
}
#[test]
fn empty_maze() {
let maze = HexMaze::default();
assert!(maze.is_empty(), "New maze should be empty");
}
}

View File

@ -93,15 +93,6 @@ fn maze_connectivity() {
}
}
#[test]
fn generator_type() {
let maze = assert_ok!(MazeBuilder::new()
.with_radius(3)
.with_generator(GeneratorType::RecursiveBacktracking)
.build());
claims::assert_gt!(maze.len(), 0);
}
#[test]
fn maze_boundaries() {
let radius = 3;

68
tests/maze.rs Normal file
View File

@ -0,0 +1,68 @@
use hexlab::prelude::*;
#[test]
fn hex_maze_creation_and_basic_operations() {
let mut maze = HexMaze::new();
assert!(maze.is_empty());
let center = Hex::ZERO;
maze.add_tile(center);
assert_eq!(maze.len(), 1);
assert!(!maze.is_empty());
let tile = maze.get_tile(&center);
assert!(tile.is_some());
assert_eq!(tile.unwrap().pos(), center);
}
#[test]
fn hex_maze_wall_operations() {
let mut maze = HexMaze::new();
let center = Hex::ZERO;
maze.add_tile(center);
// Add walls
for direction in EdgeDirection::ALL_DIRECTIONS {
maze.add_wall(center, direction);
}
let walls = maze.get_walls(&center).unwrap();
assert_eq!(walls.count(), 6);
// Remove walls
for direction in EdgeDirection::ALL_DIRECTIONS {
maze.remove_tile_wall(&center, direction);
}
let walls = maze.get_walls(&center).unwrap();
assert_eq!(walls.count(), 0);
}
#[test]
fn hex_maze_multiple_tiles() {
let mut maze = HexMaze::new();
let tiles = [Hex::ZERO, Hex::new(1, -1), Hex::new(0, 1), Hex::new(-1, 1)];
for &tile in &tiles {
maze.add_tile(tile);
}
assert_eq!(maze.len(), tiles.len());
for &tile in &tiles {
assert!(maze.get_tile(&tile).is_some());
}
}
#[test]
fn hex_maze_edge_cases() {
let mut maze = HexMaze::new();
let non_existent = Hex::new(10, 10);
// Operations on non-existent tiles should not panic
maze.add_wall(non_existent, EdgeDirection::FLAT_NORTH);
maze.remove_tile_wall(&non_existent, EdgeDirection::FLAT_NORTH);
assert!(maze.get_tile(&non_existent).is_none());
assert!(maze.get_walls(&non_existent).is_none());
}