mirror of
https://github.com/kristoferssolo/hexlab.git
synced 2025-10-21 19:40:34 +00:00
test(maze): 88% coverage
This commit is contained in:
parent
012d1e5cca
commit
43a669dee8
277
src/maze.rs
277
src/maze.rs
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
68
tests/maze.rs
Normal 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(¢er);
|
||||
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(¢er).unwrap();
|
||||
assert_eq!(walls.count(), 6);
|
||||
|
||||
// Remove walls
|
||||
for direction in EdgeDirection::ALL_DIRECTIONS {
|
||||
maze.remove_tile_wall(¢er, direction);
|
||||
}
|
||||
|
||||
let walls = maze.get_walls(¢er).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());
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user