add unit tests

saveload fixes
This commit is contained in:
2025-09-27 12:17:14 +04:00
parent 3e960a955c
commit dd0c1a123c
31 changed files with 3400 additions and 282 deletions

View File

@@ -1,10 +1,10 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Guidance for Claude Code (claude.ai/code) when working with this repository.
## Project Overview
"Skelly" is a Godot 4.4 mobile game project featuring multiple gameplay modes within a unified game framework. The project currently supports match-3 puzzle gameplay with planned support for clickomania gameplay. It includes a modular gameplay system, menu system, settings management, audio handling, localization support, and a comprehensive debug system.
"Skelly" is a Godot 4.4 mobile game project with multiple gameplay modes. Supports match-3 puzzle gameplay with planned clickomania gameplay. Includes modular gameplay system, menu system, settings management, audio handling, localization support, and debug system.
**For detailed project architecture, see `docs/MAP.md`**
@@ -41,48 +41,60 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
- New translations: Add to `project.godot` internationalization section
### Asset Management
- **CRITICAL**: Every asset must be documented in `assets/sources.yaml` before committing
- **Document every asset** in `assets/sources.yaml` before committing
- Include source, license, attribution, modifications, and usage information
- Verify license compatibility with project requirements
- Commit asset files and sources.yaml together in the same commit
- Verify license compatibility
- Commit asset files and sources.yaml together
## Key Development Guidelines
### Code Quality & Safety Standards
- **Memory Management**: Always use `queue_free()` instead of `free()` for node cleanup
- **Input Validation**: Validate all user inputs with bounds checking and type validation
- **Error Handling**: Implement comprehensive error handling with fallback mechanisms
- **Memory Management**: Use `queue_free()` instead of `free()`
- **Input Validation**: Validate user inputs with bounds checking and type validation
- **Error Handling**: Implement error handling with fallback mechanisms
- **Race Condition Prevention**: Use state flags to prevent concurrent operations
- **No Global State**: Avoid static variables; use instance-based architecture for testability
### Scene Management
- **ALWAYS** use `GameManager` for scene transitions - never call `get_tree().change_scene_to_file()` directly
- Scene paths are defined as constants in GameManager
- Error handling is built into GameManager for failed scene loads
- **Use `GameManager` for all scene transitions** - never call `get_tree().change_scene_to_file()` directly
- Scene paths defined as constants in GameManager
- Error handling built into GameManager for failed scene loads
- Use `GameManager.start_game_with_mode(mode)` to launch specific gameplay modes
- Supported gameplay modes: "match3", "clickomania" (validated with whitelist)
- Supported modes: "match3", "clickomania" (validated with whitelist)
- GameManager prevents concurrent scene changes with `is_changing_scene` protection
### Autoload Usage
- Use autoloads for global state management only
- Prefer signals over direct access for loose coupling
- Don't access autoloads from deeply nested components
- **SettingsManager**: Features comprehensive input validation and error recovery
- **SaveManager**: Save system with tamper detection, race condition protection, and permissive validation
- **SettingsManager**: Features input validation, NaN/Infinity checks, and security hardening
- **GameManager**: Protected against race conditions with state management
### Save System Security & Data Integrity
- **SaveManager implements security standards** for data protection
- **Tamper Detection**: Deterministic checksums detect save file modification or corruption
- **Race Condition Protection**: Save operation locking prevents concurrent conflicts
- **Permissive Validation**: Auto-repair system fixes corrupted data instead of rejecting saves
- **Type Safety**: NaN/Infinity/bounds checking for numeric values
- **Memory Protection**: File size limits prevent memory exhaustion attacks
- **Version Migration**: Backward-compatible system handles save format upgrades
- **Error Recovery**: Multi-layered backup and fallback systems ensure no data loss
- **Security Logging**: All save operations logged for monitoring and debugging
### Debug System Integration
- Connect to `DebugManager.debug_ui_toggled` signal for debug UI visibility
- Use F12 key for global debug toggle
- Remove debug prints before committing unless permanently useful
### Logging System Usage
- **CRITICAL**: ALL print() and push_error() statements have been migrated to DebugManager
- **ALWAYS** use `DebugManager` logging functions instead of `print()`, `push_error()`, etc.
- Use appropriate log levels: INFO for general messages, WARN for issues, ERROR for failures
- Include meaningful categories to organize log output, eg: `"GameManager"`, `"Match3"`, `"Settings"`, `"DebugMenu"`
- Leverage structured logging for better debugging and production monitoring
- **All print() and push_error() statements migrated to DebugManager**
- Use `DebugManager` logging functions instead of `print()`, `push_error()`, etc.
- Use log levels: INFO for general messages, WARN for issues, ERROR for failures
- Include categories to organize log output: `"GameManager"`, `"Match3"`, `"Settings"`, `"DebugMenu"`
- Use structured logging for better debugging and production monitoring
- Use `DebugManager.set_log_level()` to control verbosity during development and testing
- The logging system provides unified output across all game systems
- Logging system provides unified output across all game systems
## Important File References
@@ -95,10 +107,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
### Key Scripts to Understand
- `src/autoloads/GameManager.gd` - Scene transition patterns with race condition protection
- `src/autoloads/SettingsManager.gd` - Settings management with comprehensive error handling
- `src/autoloads/SaveManager.gd` - **Save system with security features**
- `src/autoloads/SettingsManager.gd` - Settings management with input validation and security
- `src/autoloads/DebugManager.gd` - Debug system integration
- `scenes/game/game.gd` - Main game scene with modular gameplay system
- `scenes/game/gameplays/match3_gameplay.gd` - Memory-safe Match-3 implementation with input validation
- `scenes/game/gameplays/match3_gameplay.gd` - Match-3 implementation with input validation
- `scenes/game/gameplays/tile.gd` - Instance-based tile behavior without global state
- `scenes/ui/DebugMenuBase.gd` - Unified debug menu base class
- `scenes/ui/SettingsMenu.gd` - Settings UI with input validation
@@ -108,18 +121,21 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Development Workflow
### Before Making Changes
1. Check `docs/MAP.md` for architecture understanding
1. Check `docs/MAP.md` for architecture
2. Review `docs/CODE_OF_CONDUCT.md` for coding standards
3. Understand existing patterns before implementing new features
3. Understand existing patterns before implementing features
4. If adding assets, prepare `assets/sources.yaml` documentation
### Testing Changes
- Run project with F5 in Godot Editor
- Test debug UI with F12 toggle
- Verify scene transitions work correctly
- Verify scene transitions work
- Check mobile compatibility if UI changes made
- Use relevant test scripts from `tests/` directory to validate system functionality
- Run `test_logging.gd` after making changes to the logging system
- Use test scripts from `tests/` directory to validate functionality
- Run `test_logging.gd` after logging system changes
- **Save system testing**: Run save/load test suites after SaveManager changes
- **Checksum validation**: Test `test_checksum_issue.gd` to verify deterministic checksums
- **Migration compatibility**: Run `test_migration_compatibility.gd` for version upgrades
### Common Implementation Patterns
- **Scene transitions**: Use `GameManager.start_game_with_mode()` with built-in validation
@@ -127,22 +143,23 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
- **Logging**: Use `DebugManager.log_*()` functions with appropriate levels and categories
- **Gameplay modes**: Implement in `scenes/game/gameplays/` directory following modular pattern
- **Scoring system**: Connect `score_changed` signal from gameplay to main game scene
- **Settings**: Use `SettingsManager` with automatic input validation and error recovery
- **Save/Load operations**: Use `SaveManager` with security and validation
- **Settings**: Use `SettingsManager` with input validation, NaN/Infinity checks, and security hardening
- **Audio**: Use `AudioManager` for music and sound effects
- **Localization**: Use `LocalizationManager` for language switching
- **UI Components**: Extend `DebugMenuBase` for debug menus to avoid code duplication
- **Value Selection**: Use `ValueStepper` component for discrete option selection (language, resolution, difficulty)
- **Memory Management**: Use `queue_free()` and await frame completion for safe cleanup
- **Input Validation**: Always validate user inputs with type checking and bounds validation
- **Input Validation**: Validate user inputs with type checking and bounds validation
### Logging Best Practices
```gdscript
# Good logging practices
# Good logging
DebugManager.log_info("Scene transition completed", "GameManager")
DebugManager.log_warn("Settings file not found, using defaults", "Settings")
DebugManager.log_error("Failed to load audio resource: " + audio_path, "AudioManager")
# Avoid these patterns
# Avoid
print("debug") # Use structured logging instead
push_error("error") # Use DebugManager.log_error() with category
```

View File

@@ -2,19 +2,19 @@
## Overview
This document establishes coding standards and development practices for the Skelly project. These guidelines are designed to help junior developers contribute effectively while maintaining code quality and project consistency.
Coding standards and development practices for the Skelly project. These guidelines help developers contribute effectively while maintaining code quality and project consistency.
## Core Principles
### 1. Code Clarity Over Cleverness
- Write code that is easy to read and understand
- Write code that is easy to read
- Use descriptive variable and function names
- Prefer explicit code over implicit or "clever" solutions
- Prefer explicit code over "clever" solutions
- Comment complex logic and business rules
### 2. Consistency First
- Follow existing code patterns in the project
- Use the same naming conventions throughout
- Follow existing code patterns
- Use same naming conventions throughout
- Maintain consistent indentation and formatting
- Follow Godot's GDScript style guide
@@ -22,7 +22,7 @@ This document establishes coding standards and development practices for the Ske
- Make small, focused commits
- Test changes before committing
- Don't break existing functionality
- Use the debug system to verify your changes
- Use debug system to verify changes
## GDScript Coding Standards
@@ -91,7 +91,7 @@ func _get_match_line(start: Vector2i, dir: Vector2i) -> Array:
## Project-Specific Guidelines
### Scene Management
- All scene transitions MUST go through `GameManager`
- All scene transitions go through `GameManager`
- Never use `get_tree().change_scene_to_file()` directly
- Define scene paths as constants in GameManager
@@ -100,7 +100,7 @@ func _get_match_line(start: Vector2i, dir: Vector2i) -> Array:
GameManager.start_match3_game()
# ❌ Wrong
GameManager.start_match3_game() # Use GameManager instead of direct scene loading
get_tree().change_scene_to_file("res://scenes/game.tscn")
```
### Autoload Usage
@@ -142,9 +142,9 @@ print(some_variable) # No context, use proper log level
```
### Logging Standards
- **ALWAYS** use `DebugManager.log_*()` functions instead of `print()` or `push_error()`
- Choose appropriate log levels based on message importance and audience
- Include meaningful categories to organize log output by system/component
- Use `DebugManager.log_*()` functions instead of `print()` or `push_error()`
- Choose log levels based on message importance and audience
- Include categories to organize log output by system/component
- Format messages with clear, descriptive text and relevant context
```gdscript
@@ -160,11 +160,11 @@ if debug_mode: print("debug info") # Use DebugManager.log_debug()
```
### Asset Management
- **MANDATORY**: Every asset added to the project must be documented in `assets/sources.yaml`
- Include complete source information, license details, and attribution requirements
- Document any modifications made to original assets
- Verify license compatibility with project usage before adding assets
- Update sources.yaml in the same commit as adding the asset
- **Document every asset** in `assets/sources.yaml`
- Include source information, license details, and attribution
- Document modifications made to original assets
- Verify license compatibility before adding assets
- Update sources.yaml in same commit as adding asset
```gdscript
# ✅ Correct asset addition workflow
@@ -184,13 +184,13 @@ if debug_mode: print("debug info") # Use DebugManager.log_debug()
```
### Error Handling
- Always check if resources loaded successfully
- Check if resources loaded successfully
- Use `DebugManager.log_error()` for critical failures
- Provide fallback behavior when possible
- Include meaningful context in error messages
```gdscript
# ✅ Correct error handling with structured logging
# Good error handling with structured logging
func load_scene(path: String) -> void:
var packed_scene := load(path)
if not packed_scene or not packed_scene is PackedScene:
@@ -209,12 +209,12 @@ func load_scene(path: String) -> void:
- Add body if needed for complex changes
```bash
# Good commit messages
# Good commit messages
Add gem pool management to match-3 system
Fix debug UI visibility toggle issue
Update documentation for new debug system
# Bad commit messages
# Bad commit messages
fix bug
update
wip
@@ -253,7 +253,7 @@ wip
### Manual Testing Requirements
- Test in Godot editor with F5 run
- Verify debug UI works with F12 toggle
- Check scene transitions work correctly
- Check scene transitions work
- Test on different screen sizes (mobile target)
- Verify audio and settings integration
@@ -261,53 +261,53 @@ wip
- Ensure debug panels appear/disappear correctly
- Test all debug buttons and controls
- Verify debug state persists across scene changes
- Check that debug code doesn't affect release builds
- Check debug code doesn't affect release builds
## Common Mistakes to Avoid
### Architecture Violations
```gdscript
# Don't bypass GameManager
# Don't bypass GameManager
get_tree().change_scene_to_file("some_scene.tscn")
# Don't hardcode paths
# Don't hardcode paths
var tile = load("res://scenes/game/gameplays/tile.tscn")
# Don't ignore null checks
# Don't ignore null checks
var node = get_node("SomeNode")
node.do_something() # Could crash if node doesn't exist
# Don't create global state in random scripts
# Don't create global state in random scripts
# Use autoloads instead
```
### Asset Management Violations
```gdscript
# Don't add assets without documentation
# Don't add assets without documentation
# Adding audio/new_music.mp3 without updating sources.yaml
# Don't use assets without verifying licenses
# Don't use assets without verifying licenses
# Using copyrighted music without permission
# Don't modify assets without documenting changes
# Don't modify assets without documenting changes
# Editing sprites without noting modifications in sources.yaml
# Don't commit assets and documentation separately
# Don't commit assets and documentation separately
git add assets/sprites/new_sprite.png
git commit -m "add sprite" # Missing sources.yaml update
# Correct approach
# Correct approach
git add assets/sprites/new_sprite.png assets/sources.yaml
git commit -m "add new sprite with attribution"
```
### Performance Issues
```gdscript
# Don't search nodes repeatedly
# Don't search nodes repeatedly
func _process(delta):
var ui = get_node("UI") # Expensive every frame
# Cache node references
# Cache node references
@onready var ui = $UI
func _process(delta):
ui.update_display() # Much better
@@ -315,11 +315,11 @@ func _process(delta):
### Debug System Misuse
```gdscript
# Don't create separate debug systems
# Don't create separate debug systems
var my_debug_enabled = false
print("debug: " + some_info) # Don't use plain print()
# Use the global debug and logging systems
# Use the global debug and logging systems
if DebugManager.is_debug_enabled():
show_debug_info()
DebugManager.log_debug("Debug information: " + some_info, "MyComponent")

View File

@@ -1,7 +1,7 @@
# Skelly - Project Structure Map
## Overview
Skelly is a Godot 4.4 game project featuring multiple gameplay modes with skeleton character themes. The project supports match-3 puzzle gameplay with planned clickomania gameplay through a modular gameplay architecture. It follows a modular structure with clear separation between scenes, autoloads, assets, and data.
Skelly is a Godot 4.4 game project featuring multiple gameplay modes. The project supports match-3 puzzle gameplay with planned clickomania gameplay through a modular gameplay architecture. It follows a modular structure with clear separation between scenes, autoloads, assets, and data.
## Project Root Structure
@@ -25,43 +25,8 @@ skelly/
### Autoloads (Global Singletons)
Located in `src/autoloads/`, these scripts are automatically loaded when the game starts:
1. **SettingsManager** (`src/autoloads/SettingsManager.gd`)
- Manages game settings and user preferences with comprehensive error handling
- Robust configuration file I/O with fallback mechanisms
- Input validation for all setting values and range checking
- JSON parsing with detailed error recovery and default language fallback
- Provides language selection functionality with validation
- Dependencies: `localization/languages.json`
2. **AudioManager** (`src/autoloads/AudioManager.gd`)
- Controls music and sound effects
- Manages audio bus configuration
- Uses: `data/default_bus_layout.tres`
3. **GameManager** (`src/autoloads/GameManager.gd`)
- Central game state management and gameplay mode coordination with race condition protection
- Safe scene transitions with concurrent change prevention and validation
- Gameplay mode selection and launching with input validation (match3, clickomania)
- Error handling for scene loading failures and fallback mechanisms
- Navigation flow control with state protection
- References: main.tscn, game.tscn and individual gameplay scenes
4. **LocalizationManager** (`src/autoloads/LocalizationManager.gd`)
- Language switching functionality
- Works with Godot's built-in internationalization system
- Uses translation files in `localization/`
5. **DebugManager** (`src/autoloads/DebugManager.gd`)
- Global debug state management and centralized logging system
- Debug UI visibility control
- F12 toggle functionality
- Signal-based debug system
- Structured logging with configurable log levels (TRACE, DEBUG, INFO, WARN, ERROR, FATAL)
- Timestamp-based log formatting with category support
- Runtime log level filtering for development and production builds
6. **SaveManager** (`src/autoloads/SaveManager.gd`)
- Persistent game data management with comprehensive validation
1. **SaveManager** (`src/autoloads/SaveManager.gd`)
- Persistent game data management with validation
- High score tracking and current score management
- Game statistics (games played, total score)
- Grid state persistence for match-3 gameplay continuity
@@ -70,6 +35,42 @@ Located in `src/autoloads/`, these scripts are automatically loaded when the gam
- Robust error handling with backup restoration capabilities
- Uses: `user://savegame.save` for persistent storage
2. **SettingsManager** (`src/autoloads/SettingsManager.gd`)
- Manages game settings and user preferences
- Configuration file I/O
- input validation
- JSON parsing
- Provides language selection functionality
- Dependencies: `localization/languages.json`
3. **AudioManager** (`src/autoloads/AudioManager.gd`)
- Controls music and sound effects
- Manages audio bus configuration
- Uses: `data/default_bus_layout.tres`
4. **GameManager** (`src/autoloads/GameManager.gd`)
- Game state management and gameplay mode coordination with race condition protection
- Scene transitions with concurrent change prevention and validation
- Gameplay mode selection and launching with input validation (match3, clickomania)
- Error handling for scene loading failures and fallback mechanisms
- Navigation flow control with state protection
- References: main.tscn, game.tscn and individual gameplay scenes
5. **LocalizationManager** (`src/autoloads/LocalizationManager.gd`)
- Language switching functionality
- Works with Godot's built-in internationalization system
- Uses translation files in `localization/`
6. **DebugManager** (`src/autoloads/DebugManager.gd`)
- Global debug state management and centralized logging system
- Debug UI visibility control
- F12 toggle functionality
- Signal-based debug system
- Structured logging with configurable log levels (TRACE, DEBUG, INFO, WARN, ERROR, FATAL)
- Timestamp-based log formatting with category support
- Runtime log level filtering
## Scene Hierarchy & Flow
### Main Scenes
@@ -130,12 +131,12 @@ scenes/ui/
└── SettingsMenu.tscn + SettingsMenu.gd # With comprehensive input validation
```
**Code Quality Improvements:**
**Quality Improvements:**
- **ValueStepper Component**: Reusable arrow-based selector for discrete values (language, resolution, difficulty)
- **DebugMenuBase.gd**: Eliminates 90% code duplication between debug menu classes
- **Input Validation**: All user inputs are validated and sanitized before processing
- **Error Recovery**: Robust error handling with fallback mechanisms throughout UI
- **Navigation Support**: Full gamepad/keyboard navigation across all menus
- **Input Validation**: User inputs are validated and sanitized before processing
- **Error Recovery**: Error handling with fallback mechanisms throughout UI
- **Navigation Support**: Gamepad/keyboard navigation across menus
## Modular Gameplay System
@@ -152,12 +153,12 @@ The game now uses a modular gameplay architecture where different game modes can
#### Match-3 Mode (`scenes/game/gameplays/match3_gameplay.tscn`)
1. **Match3 Controller** (`scenes/game/gameplays/match3_gameplay.gd`)
- Grid management (8x8 default) with memory-safe node cleanup
- Match detection algorithms with bounds checking and null validation
- Tile dropping and refilling with proper signal connections
- Match detection algorithms with bounds checking and validation
- Tile dropping and refilling with signal connections
- Gem pool management (3-8 gem types) with instance-based architecture
- Debug UI integration with input validation
- Debug UI integration with validation
- Score reporting via `score_changed` signal
- **Memory Safety**: Uses `queue_free()` with proper frame waiting to prevent crashes
- **Memory Safety**: Uses `queue_free()` with frame waiting to prevent crashes
- **Gem Movement System**: Keyboard and gamepad input for tile selection and swapping
- State machine: WAITING → SELECTING → SWAPPING → PROCESSING
- Adjacent tile validation (horizontal/vertical neighbors only)
@@ -166,29 +167,29 @@ The game now uses a modular gameplay architecture where different game modes can
- Cursor-based navigation with visual highlighting and bounds checking
2. **Tile System** (`scenes/game/gameplays/tile.gd` + `Tile.tscn`)
- Individual tile behavior with instance-based architecture (no global state)
- Gem type management with input validation and bounds checking
- Visual representation with scaling and color modulation
- Tile behavior with instance-based architecture (no global state)
- Gem type management with validation and bounds checking
- Visual representation with scaling and color
- Group membership for coordination
- **Visual Feedback System**: Multi-state display for game interaction
- Selection visual feedback (scale and color modulation)
- State management (normal, highlighted, selected)
- Signal-based communication with gameplay controller
- Smooth animations with Tween system
- **Memory Safety**: Proper resource management and cleanup
- **Memory Safety**: Resource management and cleanup
#### Clickomania Mode (`scenes/game/gameplays/clickomania_gameplay.tscn`)
- Planned implementation for clickomania-style gameplay
- Will integrate with same scoring and UI systems as match-3
### Debug System
- Global debug state via DebugManager with proper initialization
- Global debug state via DebugManager with initialization
- Debug toggle available on all major scenes (MainMenu, SettingsMenu, PressAnyKeyScreen, Game)
- Match-3 specific debug UI panel with gem count controls and difficulty presets
- Gem count controls (+/- buttons) with difficulty presets (Easy: 3, Normal: 5, Hard: 8)
- Board reroll functionality for testing
- F12 toggle support across all scenes
- Debug prints reduced in production code
- Fewer debug prints in production code
## Asset Organization
@@ -262,8 +263,12 @@ sprites:
### Testing & Validation (`tests/`)
- `test_logging.gd` - DebugManager logging system validation
- **`test_checksum_issue.gd`** - SaveManager checksum validation and deterministic hashing
- **`test_migration_compatibility.gd`** - SaveManager version migration and backward compatibility
- **`test_save_system_integration.gd`** - Complete save/load workflow integration testing
- **`test_checksum_fix_verification.gd`** - JSON serialization checksum fix verification
- `README.md` - Brief directory overview (see docs/TESTING.md for full guidelines)
- Future test scripts for individual components and integration testing
- Comprehensive test scripts for save system security and data integrity validation
- Temporary test utilities for development and debugging
### Project Configuration

View File

@@ -1,10 +1,10 @@
# Tests Directory
This directory contains test scripts and utilities for validating various systems and components in the Skelly project.
Test scripts and utilities for validating Skelly project systems.
## Overview
The `tests/` directory is designed to house:
The `tests/` directory contains:
- System validation scripts
- Component testing utilities
- Integration tests
@@ -14,14 +14,14 @@ The `tests/` directory is designed to house:
## Current Test Files
### `test_logging.gd`
Comprehensive test script for the DebugManager logging system.
Test script for DebugManager logging system.
**Features:**
- Tests all log levels (TRACE, DEBUG, INFO, WARN, ERROR, FATAL)
- Validates log level filtering functionality
- Tests category-based logging organization
- Validates log level filtering
- Tests category-based logging
- Verifies debug mode integration
- Demonstrates proper logging usage patterns
- Demonstrates logging usage patterns
**Usage:**
```gdscript
@@ -37,15 +37,15 @@ add_child(test_script)
```
**Expected Output:**
The script will output formatted log messages demonstrating:
- Proper timestamp formatting
- Log level filtering behavior
Formatted log messages showing:
- Timestamp formatting
- Log level filtering
- Category organization
- Debug mode dependency for TRACE/DEBUG levels
## Adding New Tests
When creating new test files, follow these conventions:
Follow these conventions for new test files:
### File Naming
- Use descriptive names starting with `test_`
@@ -87,33 +87,37 @@ func test_error_conditions():
### Testing Guidelines
1. **Independence**: Each test should be self-contained and not depend on other tests
2. **Cleanup**: Restore original state after testing (settings, debug modes, etc.)
3. **Clear Output**: Use descriptive print statements to show test progress
4. **Error Handling**: Test both success and failure conditions
5. **Documentation**: Include comments explaining complex test scenarios
1. **Independence**: Each test is self-contained
2. **Cleanup**: Restore original state after testing
3. **Clear Output**: Use descriptive print statements
4. **Error Handling**: Test success and failure conditions
5. **Documentation**: Comment complex test scenarios
### Integration with Main Project
- **Temporary Usage**: Test files are meant to be added temporarily during development
- **Not in Production**: These files should not be included in release builds
- **Temporary Usage**: Add test files temporarily during development
- **Not in Production**: Exclude from release builds
- **Autoload Testing**: Add to autoloads temporarily for automatic execution
- **Manual Testing**: Run individually when testing specific components
- **Manual Testing**: Run individually for specific components
## Test Categories
### System Tests
Test core autoload managers and global systems:
- `test_logging.gd` - DebugManager logging system
- Future: `test_settings.gd` - SettingsManager functionality
- Future: `test_audio.gd` - AudioManager functionality
- Future: `test_scene_management.gd` - GameManager transitions
- `test_checksum_issue.gd` - SaveManager checksum validation and deterministic hashing
- `test_migration_compatibility.gd` - SaveManager version migration and backward compatibility
- `test_save_system_integration.gd` - Complete save/load workflow integration testing
- `test_checksum_fix_verification.gd` - Verification of JSON serialization checksum fixes
- `test_settings_manager.gd` - SettingsManager security validation, input validation, and error handling
- `test_game_manager.gd` - GameManager scene transitions, race condition protection, and input validation
- `test_audio_manager.gd` - AudioManager functionality, resource loading, and volume management
### Component Tests
Test individual game components:
- Future: `test_match3.gd` - Match-3 gameplay mechanics
- Future: `test_tile_system.gd` - Tile behavior and interactions
- Future: `test_ui_components.gd` - Menu and UI functionality
- `test_match3_gameplay.gd` - Match-3 gameplay mechanics, grid management, and match detection
- `test_tile.gd` - Tile component behavior, visual feedback, and memory safety
- `test_value_stepper.gd` - ValueStepper UI component functionality and settings integration
### Integration Tests
Test system interactions and workflows:
@@ -121,36 +125,141 @@ Test system interactions and workflows:
- Future: `test_debug_system.gd` - Debug UI integration
- Future: `test_localization.gd` - Language switching and translations
## Save System Testing Protocols
SaveManager implements security features requiring testing for modifications.
### Critical Test Suites
#### **`test_checksum_issue.gd`** - Checksum Validation
**Tests**: Checksum generation, JSON serialization consistency, save/load cycles
**Usage**: Run after checksum algorithm changes
#### **`test_migration_compatibility.gd`** - Version Migration
**Tests**: Backward compatibility, missing field addition, data structure normalization
**Usage**: Test save format upgrades
#### **`test_save_system_integration.gd`** - End-to-End Integration
**Tests**: Save/load workflow, grid state serialization, race condition prevention
**Usage**: Run after SaveManager modifications
#### **`test_checksum_fix_verification.gd`** - JSON Serialization Fix
**Tests**: Checksum consistency, int/float conversion, type safety validation
**Usage**: Test JSON type conversion fixes
### Save System Security Testing
#### **Required Tests Before SaveManager Changes**
1. Run 4 save system test suites
2. Test tamper detection by modifying save files
3. Validate error recovery by corrupting files
4. Check race condition protection
5. Verify permissive validation
#### **Performance Benchmarks**
- Checksum calculation: < 1ms
- Memory usage: File size limits prevent exhaustion
- Error recovery: Never crash regardless of corruption
- Data preservation: User scores survive migration
#### **Test Sequence After Modifications**
1. `test_checksum_issue.gd` - Verify checksum consistency
2. `test_migration_compatibility.gd` - Check version upgrades
3. `test_save_system_integration.gd` - Validate workflow
4. Manual testing with corrupted files
5. Performance validation
**Failure Response**: Test failure indicates corruption risk. Do not commit until all tests pass.
## Running Tests
### During Development
1. Copy or symlink the test file to your scene
2. Add as a child node or autoload temporarily
3. Run the project and observe console output
4. Remove from project when testing is complete
### Manual Test Execution
### Automated Testing
While Godot doesn't have built-in unit testing, these scripts provide:
- Consistent validation approach
- Repeatable test scenarios
- Clear pass/fail output
- System behavior documentation
#### **Direct Script Execution (Recommended)**
```bash
# Run specific test
godot --headless --script tests/test_checksum_issue.gd
# Run all save system tests
godot --headless --script tests/test_checksum_issue.gd
godot --headless --script tests/test_migration_compatibility.gd
godot --headless --script tests/test_save_system_integration.gd
```
#### **Other Methods**
- **Temporary Autoload**: Add to project.godot autoloads temporarily, run with F5
- **Scene-based**: Create temporary scene, add test script as child, run with F6
- **Editor**: Open test file, attach to scene, run with F6
### Automated Test Execution
Use provided scripts `run_tests.bat` (Windows) or `run_tests.sh` (Linux/Mac) to run all tests sequentially.
For CI/CD integration:
```yaml
- name: Run Test Suite
run: |
godot --headless --script tests/test_checksum_issue.gd
godot --headless --script tests/test_migration_compatibility.gd
# Add other tests as needed
```
### Expected Test Output
#### **Successful Test Run:**
```
=== Testing Checksum Issue Fix ===
Testing checksum consistency across save/load cycles...
✅ SUCCESS: Checksums are deterministic
✅ SUCCESS: JSON serialization doesn't break checksums
✅ SUCCESS: Save/load cycle maintains checksum integrity
=== Test Complete ===
```
#### **Failed Test Run:**
```
=== Testing Checksum Issue Fix ===
Testing checksum consistency across save/load cycles...
❌ FAILURE: Checksum mismatch detected
Expected: 1234567890
Got: 9876543210
=== Test Failed ===
```
### Test Execution Best Practices
**Before**: Remove existing save files, verify autoloads configured, run one test at a time
**During**: Monitor console output, note timing (tests complete within seconds)
**After**: Clean up temporary files, document issues
### Troubleshooting
**Common Issues:**
- Permission errors: Run with elevated permissions if needed
- Missing dependencies: Ensure autoloads configured
- Timeout issues: Add timeout for hung tests
- Path issues: Use absolute paths if relative paths fail
### Performance Benchmarks
Expected execution times: Individual tests < 5 seconds, total suite < 35 seconds.
If tests take longer, investigate file I/O issues, memory leaks, infinite loops, or external dependencies.
## Best Practices
1. **Document Expected Behavior**: Include comments about what should happen
2. **Test Boundary Conditions**: Include edge cases and error conditions
3. **Measure Performance**: Add timing for performance-critical components
4. **Visual Validation**: For UI components, include visual checks
5. **Cleanup After Tests**: Restore initial state to avoid side effects
1. Document expected behavior
2. Test boundary conditions and edge cases
3. Measure performance for critical components
4. Include visual validation for UI components
5. Cleanup after tests
## Contributing
When adding new test files:
1. Follow the naming and structure conventions
2. Update this README with new test descriptions
When adding test files:
1. Follow naming and structure conventions
2. Update this README with test descriptions
3. Ensure tests are self-contained and documented
4. Test both success and failure scenarios
5. Include performance considerations where relevant
4. Test success and failure scenarios
This testing approach helps maintain code quality and provides validation tools for system changes and refactoring.
This testing approach maintains code quality and provides validation tools for system changes.