mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-10 04:08:01 -06:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84caa6c25f | ||
|
|
f92c9175b9 | ||
|
|
d561b446c5 |
6
.github/workflows/coverage.yaml
vendored
6
.github/workflows/coverage.yaml
vendored
@@ -50,6 +50,12 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
just coverage
|
just coverage
|
||||||
|
|
||||||
|
- name: Upload coverage reports to Codecov
|
||||||
|
uses: codecov/codecov-action@v5
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
files: lcov.info
|
||||||
|
|
||||||
- name: Download Coveralls CLI
|
- name: Download Coveralls CLI
|
||||||
if: ${{ env.COVERALLS_REPO_TOKEN != '' }}
|
if: ${{ env.COVERALLS_REPO_TOKEN != '' }}
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -15,11 +15,3 @@ fn all_asset_paths_exist() {
|
|||||||
assert_that(&metadata.len()).is_greater_than(1024);
|
assert_that(&metadata.len()).is_greater_than(1024);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn asset_paths_are_non_empty() {
|
|
||||||
for asset in Asset::iter() {
|
|
||||||
let path = asset.path();
|
|
||||||
assert_that(&path.is_empty()).is_false();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
use pacman::constants::*;
|
|
||||||
use speculoos::prelude::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_raw_board_structure() {
|
|
||||||
// Test board dimensions match expected size
|
|
||||||
assert_that(&RAW_BOARD.len()).is_equal_to(BOARD_CELL_SIZE.y as usize);
|
|
||||||
for row in RAW_BOARD.iter() {
|
|
||||||
assert_that(&row.len()).is_equal_to(BOARD_CELL_SIZE.x as usize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test boundaries are properly walled
|
|
||||||
assert_that(&RAW_BOARD[0].chars().all(|c| c == '#')).is_true();
|
|
||||||
assert_that(&RAW_BOARD[RAW_BOARD.len() - 1].chars().all(|c| c == '#')).is_true();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_raw_board_contains_required_elements() {
|
|
||||||
// Test that essential game elements are present
|
|
||||||
assert_that(&RAW_BOARD.iter().any(|row| row.contains('X'))).is_true();
|
|
||||||
assert_that(&RAW_BOARD.iter().any(|row| row.contains("=="))).is_true();
|
|
||||||
assert_that(&RAW_BOARD.iter().any(|row| row.chars().any(|c| c == 'T'))).is_true();
|
|
||||||
assert_that(&RAW_BOARD.iter().any(|row| row.chars().any(|c| c == 'o'))).is_true();
|
|
||||||
}
|
|
||||||
@@ -1,76 +1,7 @@
|
|||||||
use pacman::error::{
|
use pacman::error::{GameError, GameResult, IntoGameError, OptionExt, ResultExt};
|
||||||
AssetError, EntityError, GameError, GameResult, IntoGameError, MapError, OptionExt, ParseError, ResultExt, TextureError,
|
|
||||||
};
|
|
||||||
use speculoos::prelude::*;
|
use speculoos::prelude::*;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_game_error_from_asset_error() {
|
|
||||||
let asset_error = AssetError::NotFound("test.png".to_string());
|
|
||||||
let game_error: GameError = asset_error.into();
|
|
||||||
assert_that(&matches!(game_error, GameError::Asset(_))).is_true();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_game_error_from_parse_error() {
|
|
||||||
let parse_error = ParseError::UnknownCharacter('Z');
|
|
||||||
let game_error: GameError = parse_error.into();
|
|
||||||
assert_that(&matches!(game_error, GameError::MapParse(_))).is_true();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_game_error_from_map_error() {
|
|
||||||
let map_error = MapError::NodeNotFound(42);
|
|
||||||
let game_error: GameError = map_error.into();
|
|
||||||
assert_that(&matches!(game_error, GameError::Map(_))).is_true();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_game_error_from_texture_error() {
|
|
||||||
let texture_error = TextureError::LoadFailed("Failed to load".to_string());
|
|
||||||
let game_error: GameError = texture_error.into();
|
|
||||||
assert_that(&matches!(game_error, GameError::Texture(_))).is_true();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_game_error_from_entity_error() {
|
|
||||||
let entity_error = EntityError::NodeNotFound(10);
|
|
||||||
let game_error: GameError = entity_error.into();
|
|
||||||
assert_that(&matches!(game_error, GameError::Entity(_))).is_true();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_game_error_from_io_error() {
|
|
||||||
let io_error = io::Error::new(io::ErrorKind::NotFound, "File not found");
|
|
||||||
let game_error: GameError = io_error.into();
|
|
||||||
assert_that(&matches!(game_error, GameError::Io(_))).is_true();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_asset_error_from_io_error() {
|
|
||||||
let io_error = io::Error::new(io::ErrorKind::PermissionDenied, "Permission denied");
|
|
||||||
let asset_error: AssetError = io_error.into();
|
|
||||||
assert_that(&matches!(asset_error, AssetError::Io(_))).is_true();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_error_display() {
|
|
||||||
let error = ParseError::UnknownCharacter('!');
|
|
||||||
assert_that(&error.to_string()).is_equal_to("Unknown character in board: !".to_string());
|
|
||||||
|
|
||||||
let error = ParseError::InvalidHouseDoorCount(3);
|
|
||||||
assert_that(&error.to_string()).is_equal_to("House door must have exactly 2 positions, found 3".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_entity_error_display() {
|
|
||||||
let error = EntityError::NodeNotFound(42);
|
|
||||||
assert_that(&error.to_string()).is_equal_to("Node not found in graph: 42".to_string());
|
|
||||||
|
|
||||||
let error = EntityError::EdgeNotFound { from: 1, to: 2 };
|
|
||||||
assert_that(&error.to_string()).is_equal_to("Edge not found: from 1 to 2".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_into_game_error_trait() {
|
fn test_into_game_error_trait() {
|
||||||
let result: Result<i32, io::Error> = Err(io::Error::new(io::ErrorKind::Other, "test error"));
|
let result: Result<i32, io::Error> = Err(io::Error::new(io::ErrorKind::Other, "test error"));
|
||||||
|
|||||||
@@ -73,25 +73,6 @@ fn test_default_zero_timing_for_unused_systems() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pre_populated_timing_entries() {
|
|
||||||
let timings = SystemTimings::default();
|
|
||||||
|
|
||||||
// Verify that we can add timing to any SystemId without panicking
|
|
||||||
// (this would fail with the old implementation if the entry didn't exist)
|
|
||||||
// Use the same tick for all systems to avoid zero-padding
|
|
||||||
for id in SystemId::iter() {
|
|
||||||
timings.add_timing(id, Duration::from_nanos(1), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify all systems now have non-zero timing
|
|
||||||
let stats = timings.get_stats(1);
|
|
||||||
for id in SystemId::iter() {
|
|
||||||
let (avg, _) = stats.get(&id).unwrap();
|
|
||||||
assert_that(&(*avg > Duration::ZERO)).is_true();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_total_system_timing() {
|
fn test_total_system_timing() {
|
||||||
let timings = SystemTimings::default();
|
let timings = SystemTimings::default();
|
||||||
|
|||||||
115
tests/ttf.rs
Normal file
115
tests/ttf.rs
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
use pacman::texture::ttf::{TtfAtlas, TtfRenderer};
|
||||||
|
use sdl2::pixels::Color;
|
||||||
|
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn text_width_calculates_correctly_for_empty_string() {
|
||||||
|
let (mut canvas, texture_creator, _sdl) = common::setup_sdl().unwrap();
|
||||||
|
let _ttf_context = sdl2::ttf::init().unwrap();
|
||||||
|
let font = _ttf_context.load_font("assets/game/TerminalVector.ttf", 16).unwrap();
|
||||||
|
|
||||||
|
let mut atlas = TtfAtlas::new(&texture_creator, &font).unwrap();
|
||||||
|
atlas.populate_atlas(&mut canvas, &texture_creator, &font).unwrap();
|
||||||
|
|
||||||
|
let renderer = TtfRenderer::new(1.0);
|
||||||
|
let width = renderer.text_width(&atlas, "");
|
||||||
|
|
||||||
|
assert_eq!(width, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn text_width_calculates_correctly_for_single_character() {
|
||||||
|
let (mut canvas, texture_creator, _sdl) = common::setup_sdl().unwrap();
|
||||||
|
let _ttf_context = sdl2::ttf::init().unwrap();
|
||||||
|
let font = _ttf_context.load_font("assets/game/TerminalVector.ttf", 16).unwrap();
|
||||||
|
|
||||||
|
let mut atlas = TtfAtlas::new(&texture_creator, &font).unwrap();
|
||||||
|
atlas.populate_atlas(&mut canvas, &texture_creator, &font).unwrap();
|
||||||
|
|
||||||
|
let renderer = TtfRenderer::new(1.0);
|
||||||
|
let width = renderer.text_width(&atlas, "A");
|
||||||
|
|
||||||
|
assert!(width > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn text_width_scales_correctly() {
|
||||||
|
let (mut canvas, texture_creator, _sdl) = common::setup_sdl().unwrap();
|
||||||
|
let _ttf_context = sdl2::ttf::init().unwrap();
|
||||||
|
let font = _ttf_context.load_font("assets/game/TerminalVector.ttf", 16).unwrap();
|
||||||
|
|
||||||
|
let mut atlas = TtfAtlas::new(&texture_creator, &font).unwrap();
|
||||||
|
atlas.populate_atlas(&mut canvas, &texture_creator, &font).unwrap();
|
||||||
|
|
||||||
|
let renderer1 = TtfRenderer::new(1.0);
|
||||||
|
let renderer2 = TtfRenderer::new(2.0);
|
||||||
|
|
||||||
|
let width1 = renderer1.text_width(&atlas, "Test");
|
||||||
|
let width2 = renderer2.text_width(&atlas, "Test");
|
||||||
|
|
||||||
|
assert_eq!(width2, width1 * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn text_height_returns_non_zero_for_valid_atlas() {
|
||||||
|
let (mut canvas, texture_creator, _sdl) = common::setup_sdl().unwrap();
|
||||||
|
let _ttf_context = sdl2::ttf::init().unwrap();
|
||||||
|
let font = _ttf_context.load_font("assets/game/TerminalVector.ttf", 16).unwrap();
|
||||||
|
|
||||||
|
let mut atlas = TtfAtlas::new(&texture_creator, &font).unwrap();
|
||||||
|
atlas.populate_atlas(&mut canvas, &texture_creator, &font).unwrap();
|
||||||
|
|
||||||
|
let renderer = TtfRenderer::new(1.0);
|
||||||
|
let height = renderer.text_height(&atlas);
|
||||||
|
|
||||||
|
assert!(height > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn text_height_scales_correctly() {
|
||||||
|
let (mut canvas, texture_creator, _sdl) = common::setup_sdl().unwrap();
|
||||||
|
let _ttf_context = sdl2::ttf::init().unwrap();
|
||||||
|
let font = _ttf_context.load_font("assets/game/TerminalVector.ttf", 16).unwrap();
|
||||||
|
|
||||||
|
let mut atlas = TtfAtlas::new(&texture_creator, &font).unwrap();
|
||||||
|
atlas.populate_atlas(&mut canvas, &texture_creator, &font).unwrap();
|
||||||
|
|
||||||
|
let renderer1 = TtfRenderer::new(1.0);
|
||||||
|
let renderer2 = TtfRenderer::new(2.0);
|
||||||
|
|
||||||
|
let height1 = renderer1.text_height(&atlas);
|
||||||
|
let height2 = renderer2.text_height(&atlas);
|
||||||
|
|
||||||
|
assert_eq!(height2, height1 * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn render_text_handles_empty_string() {
|
||||||
|
let (mut canvas, texture_creator, _sdl) = common::setup_sdl().unwrap();
|
||||||
|
let _ttf_context = sdl2::ttf::init().unwrap();
|
||||||
|
let font = _ttf_context.load_font("assets/game/TerminalVector.ttf", 16).unwrap();
|
||||||
|
|
||||||
|
let mut atlas = TtfAtlas::new(&texture_creator, &font).unwrap();
|
||||||
|
atlas.populate_atlas(&mut canvas, &texture_creator, &font).unwrap();
|
||||||
|
|
||||||
|
let renderer = TtfRenderer::new(1.0);
|
||||||
|
let result = renderer.render_text(&mut canvas, &mut atlas, "", glam::Vec2::new(0.0, 0.0), Color::WHITE);
|
||||||
|
|
||||||
|
assert!(result.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn render_text_handles_single_character() {
|
||||||
|
let (mut canvas, texture_creator, _sdl) = common::setup_sdl().unwrap();
|
||||||
|
let _ttf_context = sdl2::ttf::init().unwrap();
|
||||||
|
let font = _ttf_context.load_font("assets/game/TerminalVector.ttf", 16).unwrap();
|
||||||
|
|
||||||
|
let mut atlas = TtfAtlas::new(&texture_creator, &font).unwrap();
|
||||||
|
atlas.populate_atlas(&mut canvas, &texture_creator, &font).unwrap();
|
||||||
|
|
||||||
|
let renderer = TtfRenderer::new(1.0);
|
||||||
|
let result = renderer.render_text(&mut canvas, &mut atlas, "A", glam::Vec2::new(10.0, 10.0), Color::RED);
|
||||||
|
|
||||||
|
assert!(result.is_ok());
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user