CLAUDE: Update REPL for new GameState and standardize UV commands
Updated terminal client REPL to work with refactored GameState structure where current_batter/pitcher/catcher are now LineupPlayerState objects instead of integer IDs. Also standardized all documentation to properly show 'uv run' prefixes for Python commands. REPL Updates: - terminal_client/display.py: Access lineup_id from LineupPlayerState objects - terminal_client/repl.py: Fix typos (self.current_game → self.current_game_id) - tests/unit/terminal_client/test_commands.py: Create proper LineupPlayerState objects in test fixtures (2 tests fixed, all 105 terminal client tests passing) Documentation Updates (100+ command examples): - CLAUDE.md: Updated pytest examples to use 'uv run' prefix - terminal_client/CLAUDE.md: Updated ~40 command examples - tests/CLAUDE.md: Updated all test commands (unit, integration, debugging) - app/*/CLAUDE.md: Updated test and server startup commands (5 files) All Python commands now consistently use 'uv run' prefix to align with project's UV migration, improving developer experience and preventing confusion about virtual environment activation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
7de70b34d5
commit
440adf2c26
@ -1158,13 +1158,13 @@ game_data = await db_ops.load_game_state(game_id)
|
||||
**Run Tests**:
|
||||
```bash
|
||||
# All unit tests
|
||||
pytest tests/unit/ -v
|
||||
uv run pytest tests/unit/ -v
|
||||
|
||||
# Integration tests (requires database)
|
||||
pytest tests/integration/ -v -m integration
|
||||
uv run pytest tests/integration/ -v -m integration
|
||||
|
||||
# Specific file
|
||||
pytest tests/unit/models/test_game_models.py -v
|
||||
uv run pytest tests/unit/models/test_game_models.py -v
|
||||
```
|
||||
|
||||
### Patterns Established
|
||||
@ -1559,7 +1559,7 @@ logger.info(f"Rebuilt state for game {state.game_id}: {state.play_count} plays,
|
||||
**Integration Tests**:
|
||||
- Known issue: Integration tests in `tests/integration/test_game_engine.py` must be run individually
|
||||
- Reason: Database connection pooling conflicts when running in parallel
|
||||
- Workaround: `pytest tests/integration/test_game_engine.py::TestClassName::test_method -v`
|
||||
- Workaround: `uv run pytest tests/integration/test_game_engine.py::TestClassName::test_method -v`
|
||||
- All tests pass when run individually
|
||||
|
||||
**Terminal Client**:
|
||||
|
||||
@ -426,7 +426,7 @@ const games = await api.get('/games/');
|
||||
5. **Test the endpoint**
|
||||
```bash
|
||||
# Start server
|
||||
python -m app.main
|
||||
uv run python -m app.main
|
||||
|
||||
# Test with curl
|
||||
curl -X POST http://localhost:8000/api/teams/ \
|
||||
@ -549,7 +549,7 @@ FastAPI automatically generates interactive API documentation:
|
||||
|
||||
1. Start the backend server:
|
||||
```bash
|
||||
python -m app.main
|
||||
uv run python -m app.main
|
||||
```
|
||||
|
||||
2. Open Swagger UI:
|
||||
|
||||
@ -917,13 +917,13 @@ if requires_cardset_validation(state.league_id):
|
||||
**Run Tests**:
|
||||
```bash
|
||||
# All config tests
|
||||
pytest tests/unit/config/ -v
|
||||
uv run pytest tests/unit/config/ -v
|
||||
|
||||
# Specific file
|
||||
pytest tests/unit/config/test_league_configs.py -v
|
||||
uv run pytest tests/unit/config/test_league_configs.py -v
|
||||
|
||||
# Specific test
|
||||
pytest tests/unit/config/test_play_outcome.py::test_is_hit -v
|
||||
uv run pytest tests/unit/config/test_play_outcome.py::test_is_hit -v
|
||||
```
|
||||
|
||||
### Test Examples
|
||||
|
||||
@ -1138,10 +1138,10 @@ state = await state_manager.recover_game(game_id)
|
||||
**Solution**:
|
||||
```bash
|
||||
# Run integration tests individually
|
||||
pytest tests/integration/test_game_engine.py::TestGameEngine::test_resolve_play -v
|
||||
uv run pytest tests/integration/test_game_engine.py::TestGameEngine::test_resolve_play -v
|
||||
|
||||
# Or use -x flag to stop on first failure
|
||||
pytest tests/integration/test_game_engine.py -x -v
|
||||
uv run pytest tests/integration/test_game_engine.py -x -v
|
||||
```
|
||||
|
||||
### Issue: Type errors with SQLAlchemy models
|
||||
@ -1163,27 +1163,27 @@ See `backend/CLAUDE.md` section on Type Checking for comprehensive guidance.
|
||||
|
||||
```bash
|
||||
# All core unit tests
|
||||
pytest tests/unit/core/ -v
|
||||
uv run pytest tests/unit/core/ -v
|
||||
|
||||
# Specific module
|
||||
pytest tests/unit/core/test_game_engine.py -v
|
||||
pytest tests/unit/core/test_play_resolver.py -v
|
||||
pytest tests/unit/core/test_runner_advancement.py -v # Groundball tests (30 tests)
|
||||
pytest tests/unit/core/test_flyball_advancement.py -v # Flyball tests (21 tests)
|
||||
pytest tests/unit/core/test_state_manager.py -v
|
||||
uv run pytest tests/unit/core/test_game_engine.py -v
|
||||
uv run pytest tests/unit/core/test_play_resolver.py -v
|
||||
uv run pytest tests/unit/core/test_runner_advancement.py -v # Groundball tests (30 tests)
|
||||
uv run pytest tests/unit/core/test_flyball_advancement.py -v # Flyball tests (21 tests)
|
||||
uv run pytest tests/unit/core/test_state_manager.py -v
|
||||
|
||||
# With coverage
|
||||
pytest tests/unit/core/ --cov=app.core --cov-report=html
|
||||
uv run pytest tests/unit/core/ --cov=app.core --cov-report=html
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
|
||||
```bash
|
||||
# All core integration tests
|
||||
pytest tests/integration/test_state_persistence.py -v
|
||||
uv run pytest tests/integration/test_state_persistence.py -v
|
||||
|
||||
# Run individually (recommended due to connection pooling)
|
||||
pytest tests/integration/test_game_engine.py::TestGameEngine::test_complete_game -v
|
||||
uv run pytest tests/integration/test_game_engine.py::TestGameEngine::test_complete_game -v
|
||||
```
|
||||
|
||||
### Terminal Client
|
||||
@ -1192,7 +1192,7 @@ Best tool for testing game engine in isolation:
|
||||
|
||||
```bash
|
||||
# Start REPL
|
||||
python -m terminal_client
|
||||
uv run python -m terminal_client
|
||||
|
||||
# Create and play game
|
||||
⚾ > new_game
|
||||
|
||||
@ -915,13 +915,13 @@ app/database/
|
||||
**Running Tests**:
|
||||
```bash
|
||||
# All database integration tests
|
||||
pytest tests/integration/database/ -v
|
||||
uv run pytest tests/integration/database/ -v
|
||||
|
||||
# Specific operation test
|
||||
pytest tests/integration/database/test_operations.py::TestGameOperations::test_create_game -v
|
||||
uv run pytest tests/integration/database/test_operations.py::TestGameOperations::test_create_game -v
|
||||
|
||||
# State persistence tests
|
||||
pytest tests/integration/test_state_persistence.py -v
|
||||
uv run pytest tests/integration/test_state_persistence.py -v
|
||||
```
|
||||
|
||||
**Test Requirements**:
|
||||
|
||||
@ -1050,16 +1050,16 @@ def test_advance_runner_scoring():
|
||||
|
||||
```bash
|
||||
# All model tests
|
||||
pytest tests/unit/models/ -v
|
||||
uv run pytest tests/unit/models/ -v
|
||||
|
||||
# Specific file
|
||||
pytest tests/unit/models/test_game_models.py -v
|
||||
uv run pytest tests/unit/models/test_game_models.py -v
|
||||
|
||||
# Specific test
|
||||
pytest tests/unit/models/test_game_models.py::test_advance_runner_scoring -v
|
||||
uv run pytest tests/unit/models/test_game_models.py::test_advance_runner_scoring -v
|
||||
|
||||
# With coverage
|
||||
pytest tests/unit/models/ --cov=app.models --cov-report=html
|
||||
uv run pytest tests/unit/models/ --cov=app.models --cov-report=html
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
[project]
|
||||
name = "paper-dynasty-backend"
|
||||
name = "strat-gameplay-backend"
|
||||
version = "0.1.0"
|
||||
description = "Paper Dynasty Real-Time Game Engine Backend - FastAPI with WebSocket support"
|
||||
description = "Strat Real-Time Game Engine Backend - FastAPI with WebSocket support"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
authors = [
|
||||
{ name = "Paper Dynasty Team" }
|
||||
{ name = "Cal Corum" }
|
||||
]
|
||||
dependencies = [
|
||||
"aiofiles==24.1.0",
|
||||
|
||||
@ -259,7 +259,7 @@ For running individual commands outside REPL mode.
|
||||
|
||||
### new-game
|
||||
```bash
|
||||
python -m terminal_client new-game [OPTIONS]
|
||||
uv run python -m terminal_client new-game [OPTIONS]
|
||||
|
||||
Options:
|
||||
--league TEXT League (sba or pd) [default: sba]
|
||||
@ -268,13 +268,13 @@ Options:
|
||||
--away-team INTEGER Away team ID [default: 2]
|
||||
|
||||
Example:
|
||||
python -m terminal_client start-game --league sba
|
||||
python -m terminal_client start-game --game-id <uuid> --home-team 5 --away-team 3
|
||||
uv run python -m terminal_client start-game --league sba
|
||||
uv run python -m terminal_client start-game --game-id <uuid> --home-team 5 --away-team 3
|
||||
```
|
||||
|
||||
### Defensive Decision
|
||||
```bash
|
||||
python -m terminal_client defensive [OPTIONS]
|
||||
uv run python -m terminal_client defensive [OPTIONS]
|
||||
|
||||
Options:
|
||||
--game-id TEXT Game UUID (uses current if not provided)
|
||||
@ -287,13 +287,13 @@ Options:
|
||||
--hold TEXT Comma-separated bases to hold (e.g., 1,3)
|
||||
|
||||
Example:
|
||||
python -m terminal_client defensive --alignment shifted_left
|
||||
python -m terminal_client defensive --infield double_play --hold 1,3
|
||||
uv run python -m terminal_client defensive --alignment shifted_left
|
||||
uv run python -m terminal_client defensive --infield double_play --hold 1,3
|
||||
```
|
||||
|
||||
### Offensive Decision
|
||||
```bash
|
||||
python -m terminal_client offensive [OPTIONS]
|
||||
uv run python -m terminal_client offensive [OPTIONS]
|
||||
|
||||
Options:
|
||||
--game-id TEXT Game UUID (uses current if not provided)
|
||||
@ -304,19 +304,19 @@ Options:
|
||||
--bunt Bunt attempt (flag)
|
||||
|
||||
Example:
|
||||
python -m terminal_client offensive --approach power
|
||||
python -m terminal_client offensive --steal 2 --hit-run
|
||||
uv run python -m terminal_client offensive --approach power
|
||||
uv run python -m terminal_client offensive --steal 2 --hit-run
|
||||
```
|
||||
|
||||
### Resolve Play
|
||||
```bash
|
||||
python -m terminal_client resolve [OPTIONS]
|
||||
uv run python -m terminal_client resolve [OPTIONS]
|
||||
|
||||
Options:
|
||||
--game-id TEXT Game UUID (uses current if not provided)
|
||||
|
||||
Example:
|
||||
python -m terminal_client resolve
|
||||
uv run python -m terminal_client resolve
|
||||
```
|
||||
|
||||
Resolves the current play using submitted defensive and offensive decisions.
|
||||
@ -324,37 +324,37 @@ Displays full play result with dice rolls, runner advancement, and updated game
|
||||
|
||||
### Game Status
|
||||
```bash
|
||||
python -m terminal_client status [OPTIONS]
|
||||
uv run python -m terminal_client status [OPTIONS]
|
||||
|
||||
Options:
|
||||
--game-id TEXT Game UUID (uses current if not provided)
|
||||
|
||||
Example:
|
||||
python -m terminal_client status
|
||||
uv run python -m terminal_client status
|
||||
```
|
||||
|
||||
### Box Score
|
||||
```bash
|
||||
python -m terminal_client box-score [OPTIONS]
|
||||
uv run python -m terminal_client box-score [OPTIONS]
|
||||
|
||||
Options:
|
||||
--game-id TEXT Game UUID (uses current if not provided)
|
||||
|
||||
Example:
|
||||
python -m terminal_client box-score
|
||||
uv run python -m terminal_client box-score
|
||||
```
|
||||
|
||||
### Quick Play
|
||||
```bash
|
||||
python -m terminal_client quick-play [OPTIONS]
|
||||
uv run python -m terminal_client quick-play [OPTIONS]
|
||||
|
||||
Options:
|
||||
--count INTEGER Number of plays to execute [default: 1]
|
||||
--game-id TEXT Game UUID (uses current if not provided)
|
||||
|
||||
Example:
|
||||
python -m terminal_client quick-play --count 10
|
||||
python -m terminal_client quick-play --count 27 # Full inning
|
||||
uv run python -m terminal_client quick-play --count 10
|
||||
uv run python -m terminal_client quick-play --count 27 # Full inning
|
||||
```
|
||||
|
||||
**Use Case**: Rapidly advance game state for testing specific scenarios (e.g., test 9th inning logic).
|
||||
@ -363,20 +363,20 @@ Submits default decisions (normal alignment, normal approach) and auto-resolves
|
||||
|
||||
### List Games
|
||||
```bash
|
||||
python -m terminal_client list-games
|
||||
uv run python -m terminal_client list-games
|
||||
|
||||
Example:
|
||||
python -m terminal_client list-games
|
||||
uv run python -m terminal_client list-games
|
||||
```
|
||||
|
||||
Shows all active games in the state manager.
|
||||
|
||||
### Use Game
|
||||
```bash
|
||||
python -m terminal_client use-game <game_id>
|
||||
uv run python -m terminal_client use-game <game_id>
|
||||
|
||||
Example:
|
||||
python -m terminal_client use-game a1b2c3d4-e5f6-7890-abcd-ef1234567890
|
||||
uv run python -m terminal_client use-game a1b2c3d4-e5f6-7890-abcd-ef1234567890
|
||||
```
|
||||
|
||||
Switch to a different game (sets as "current" game for subsequent commands).
|
||||
@ -387,7 +387,8 @@ Switch to a different game (sets as "current" game for subsequent commands).
|
||||
|
||||
```bash
|
||||
# Start REPL
|
||||
python -m terminal_client
|
||||
uv run python -m terminal_client
|
||||
# Or: source .venv/bin/activate && python -m terminal_client
|
||||
|
||||
# Create and play a game
|
||||
⚾ > new_game
|
||||
@ -415,45 +416,45 @@ python -m terminal_client
|
||||
|
||||
```bash
|
||||
# Test defensive shifts
|
||||
python -m terminal_client start-game
|
||||
python -m terminal_client defensive --alignment shifted_left --infield double_play
|
||||
python -m terminal_client offensive
|
||||
python -m terminal_client resolve
|
||||
uv run python -m terminal_client start-game
|
||||
uv run python -m terminal_client defensive --alignment shifted_left --infield double_play
|
||||
uv run python -m terminal_client offensive
|
||||
uv run python -m terminal_client resolve
|
||||
|
||||
# Test stealing
|
||||
python -m terminal_client start-game
|
||||
python -m terminal_client defensive
|
||||
python -m terminal_client offensive --steal 2,3 # Double steal
|
||||
python -m terminal_client resolve
|
||||
uv run python -m terminal_client start-game
|
||||
uv run python -m terminal_client defensive
|
||||
uv run python -m terminal_client offensive --steal 2,3 # Double steal
|
||||
uv run python -m terminal_client resolve
|
||||
|
||||
# Test hit-and-run
|
||||
python -m terminal_client defensive
|
||||
python -m terminal_client offensive --hit-run
|
||||
python -m terminal_client resolve
|
||||
uv run python -m terminal_client defensive
|
||||
uv run python -m terminal_client offensive --hit-run
|
||||
uv run python -m terminal_client resolve
|
||||
|
||||
# Advance to late game quickly
|
||||
python -m terminal_client start-game
|
||||
python -m terminal_client quick-play --count 50 # ~6 innings
|
||||
python -m terminal_client status
|
||||
uv run python -m terminal_client start-game
|
||||
uv run python -m terminal_client quick-play --count 50 # ~6 innings
|
||||
uv run python -m terminal_client status
|
||||
```
|
||||
|
||||
### Multiple Games
|
||||
|
||||
```bash
|
||||
# Start game 1
|
||||
python -m terminal_client start-game
|
||||
uv run python -m terminal_client start-game
|
||||
# ... play some ...
|
||||
|
||||
# Start game 2
|
||||
python -m terminal_client start-game
|
||||
uv run python -m terminal_client start-game
|
||||
# ... play some ...
|
||||
|
||||
# List all games
|
||||
python -m terminal_client list-games
|
||||
uv run python -m terminal_client list-games
|
||||
|
||||
# Switch back to game 1
|
||||
python -m terminal_client use-game <game-1-uuid>
|
||||
python -m terminal_client status
|
||||
uv run python -m terminal_client use-game <game-1-uuid>
|
||||
uv run python -m terminal_client status
|
||||
```
|
||||
|
||||
## Display Features
|
||||
@ -553,15 +554,15 @@ This allows direct async calls to GameEngine without WebSocket overhead.
|
||||
|
||||
```bash
|
||||
# Test game startup validation
|
||||
python -m terminal_client start-game
|
||||
uv run python -m terminal_client start-game
|
||||
# Should fail: No lineups set
|
||||
|
||||
# Test invalid decisions
|
||||
python -m terminal_client defensive --alignment invalid_value
|
||||
uv run python -m terminal_client defensive --alignment invalid_value
|
||||
# Should fail: ValidationError
|
||||
|
||||
# Test resolve without decisions
|
||||
python -m terminal_client resolve
|
||||
uv run python -m terminal_client resolve
|
||||
# Should fail: No decisions submitted
|
||||
```
|
||||
|
||||
@ -569,21 +570,21 @@ python -m terminal_client resolve
|
||||
|
||||
```bash
|
||||
# Full game flow
|
||||
python -m terminal_client start-game
|
||||
uv run python -m terminal_client start-game
|
||||
# ... set lineups via database directly ...
|
||||
python -m terminal_client start-game # Retry
|
||||
python -m terminal_client quick-play --count 100
|
||||
python -m terminal_client status
|
||||
uv run python -m terminal_client start-game # Retry
|
||||
uv run python -m terminal_client quick-play --count 100
|
||||
uv run python -m terminal_client status
|
||||
# Verify: Game status = "completed"
|
||||
|
||||
# State persistence
|
||||
python -m terminal_client start-game
|
||||
uv run python -m terminal_client start-game
|
||||
# Note the game UUID
|
||||
python -m terminal_client quick-play --count 10
|
||||
uv run python -m terminal_client quick-play --count 10
|
||||
# Kill terminal
|
||||
# Restart and use same UUID
|
||||
python -m terminal_client use-game <uuid>
|
||||
python -m terminal_client status
|
||||
uv run python -m terminal_client use-game <uuid>
|
||||
uv run python -m terminal_client status
|
||||
# Verify: State recovered from database
|
||||
```
|
||||
|
||||
@ -657,24 +658,29 @@ Logs appear in both terminal and `backend/logs/app_YYYYMMDD.log`.
|
||||
python terminal_client/main.py # ❌
|
||||
|
||||
# Correct
|
||||
python -m terminal_client start-game # ✅
|
||||
uv run python -m terminal_client start-game # ✅
|
||||
```
|
||||
|
||||
### Import Errors
|
||||
```bash
|
||||
# Ensure you're in backend directory
|
||||
cd backend
|
||||
source venv/bin/activate
|
||||
|
||||
# Recommended: Use UV (auto-activates venv)
|
||||
uv run python -m terminal_client start-game
|
||||
|
||||
# Alternative: Manually activate venv
|
||||
source .venv/bin/activate
|
||||
python -m terminal_client start-game
|
||||
```
|
||||
|
||||
### Game Not Found
|
||||
```bash
|
||||
# Check active games
|
||||
python -m terminal_client list-games
|
||||
uv run python -m terminal_client list-games
|
||||
|
||||
# Use specific game ID
|
||||
python -m terminal_client status --game-id <uuid>
|
||||
uv run python -m terminal_client status --game-id <uuid>
|
||||
```
|
||||
|
||||
### Validation Errors
|
||||
|
||||
@ -67,10 +67,12 @@ def display_game_state(state: GameState) -> None:
|
||||
state_text.append("Empty\n", style="dim")
|
||||
|
||||
# Current players
|
||||
if state.current_batter_lineup_id:
|
||||
state_text.append(f"\nBatter: Lineup #{state.current_batter_lineup_id}\n")
|
||||
if state.current_pitcher_lineup_id:
|
||||
state_text.append(f"Pitcher: Lineup #{state.current_pitcher_lineup_id}\n")
|
||||
if state.current_batter:
|
||||
state_text.append(f"\nBatter: Lineup #{state.current_batter.lineup_id}\n")
|
||||
if state.current_pitcher:
|
||||
state_text.append(f"Pitcher: Lineup #{state.current_pitcher.lineup_id}\n")
|
||||
if state.current_catcher:
|
||||
state_text.append(f"Catcher: Lineup #{state.current_catcher.lineup_id}\n")
|
||||
|
||||
# Pending decision - provide clear guidance
|
||||
if state.pending_decision:
|
||||
|
||||
@ -480,7 +480,7 @@ Press Ctrl+D or type 'quit' to exit.
|
||||
# Read physical card based on dice
|
||||
manual_outcome groundball_c SS
|
||||
"""
|
||||
game_id = self.current_game
|
||||
game_id = self.current_game_id
|
||||
if not game_id:
|
||||
display.print_error("No game selected. Create one with 'new_game'")
|
||||
return
|
||||
@ -509,7 +509,7 @@ Press Ctrl+D or type 'quit' to exit.
|
||||
|
||||
Note: Must call 'roll_dice' first before submitting outcome.
|
||||
"""
|
||||
game_id = self.current_game
|
||||
game_id = self.current_game_id
|
||||
if not game_id:
|
||||
display.print_error("No game selected. Create one with 'new_game'")
|
||||
return
|
||||
|
||||
@ -26,16 +26,16 @@ tests/
|
||||
**Fast, reliable, no database required**:
|
||||
```bash
|
||||
# All unit tests
|
||||
pytest tests/unit/ -v
|
||||
uv run pytest tests/unit/ -v
|
||||
|
||||
# Specific module
|
||||
pytest tests/unit/core/test_game_engine.py -v
|
||||
uv run pytest tests/unit/core/test_game_engine.py -v
|
||||
|
||||
# Specific test
|
||||
pytest tests/unit/core/test_game_engine.py::TestGameEngine::test_start_game -v
|
||||
uv run pytest tests/unit/core/test_game_engine.py::TestGameEngine::test_start_game -v
|
||||
|
||||
# With coverage
|
||||
pytest tests/unit/ --cov=app --cov-report=html
|
||||
uv run pytest tests/unit/ --cov=app --cov-report=html
|
||||
```
|
||||
|
||||
**Unit tests should always pass**. If they don't, it's a real code issue.
|
||||
@ -59,16 +59,16 @@ pytest tests/unit/ --cov=app --cov-report=html
|
||||
|
||||
```bash
|
||||
# Run one test at a time (always works)
|
||||
pytest tests/integration/database/test_operations.py::TestDatabaseOperationsGame::test_create_game -v
|
||||
uv run pytest tests/integration/database/test_operations.py::TestDatabaseOperationsGame::test_create_game -v
|
||||
|
||||
# Run test class serially
|
||||
pytest tests/integration/database/test_operations.py::TestDatabaseOperationsGame -v
|
||||
uv run pytest tests/integration/database/test_operations.py::TestDatabaseOperationsGame -v
|
||||
|
||||
# Run entire file (may have conflicts after first test)
|
||||
pytest tests/integration/database/test_operations.py -v
|
||||
uv run pytest tests/integration/database/test_operations.py -v
|
||||
|
||||
# Force serial execution (slower but more reliable)
|
||||
pytest tests/integration/ -v -x # -x stops on first failure
|
||||
uv run pytest tests/integration/ -v -x # -x stops on first failure
|
||||
```
|
||||
|
||||
**DO NOT**:
|
||||
@ -85,11 +85,11 @@ pytest tests/integration/ -v -x # -x stops on first failure
|
||||
|
||||
```bash
|
||||
# Run everything (expect integration failures due to connection issues)
|
||||
pytest tests/ -v
|
||||
uv run pytest tests/ -v
|
||||
|
||||
# Run with markers
|
||||
pytest tests/ -v -m "not integration" # Skip integration tests
|
||||
pytest tests/ -v -m integration # Only integration tests
|
||||
uv run pytest tests/ -v -m "not integration" # Skip integration tests
|
||||
uv run pytest tests/ -v -m integration # Only integration tests
|
||||
```
|
||||
|
||||
## Test Configuration
|
||||
@ -359,26 +359,26 @@ with time_machine.travel("2025-10-31 12:00:00", tick=False):
|
||||
|
||||
```bash
|
||||
# Show full output including print statements
|
||||
pytest tests/unit/core/test_game_engine.py -v -s
|
||||
uv run pytest tests/unit/core/test_game_engine.py -v -s
|
||||
|
||||
# Show local variables on failure
|
||||
pytest tests/unit/core/test_game_engine.py -v -l
|
||||
uv run pytest tests/unit/core/test_game_engine.py -v -l
|
||||
|
||||
# Stop on first failure
|
||||
pytest tests/unit/core/test_game_engine.py -v -x
|
||||
uv run pytest tests/unit/core/test_game_engine.py -v -x
|
||||
|
||||
# Show full traceback
|
||||
pytest tests/unit/core/test_game_engine.py -v --tb=long
|
||||
uv run pytest tests/unit/core/test_game_engine.py -v --tb=long
|
||||
```
|
||||
|
||||
### Interactive Debugging
|
||||
|
||||
```bash
|
||||
# Drop into debugger on failure
|
||||
pytest tests/unit/core/test_game_engine.py --pdb
|
||||
uv run pytest tests/unit/core/test_game_engine.py --pdb
|
||||
|
||||
# Drop into debugger on first failure
|
||||
pytest tests/unit/core/test_game_engine.py --pdb -x
|
||||
uv run pytest tests/unit/core/test_game_engine.py --pdb -x
|
||||
```
|
||||
|
||||
### Logging in Tests
|
||||
@ -386,7 +386,7 @@ pytest tests/unit/core/test_game_engine.py --pdb -x
|
||||
Tests capture logs by default. View with `-o log_cli=true`:
|
||||
|
||||
```bash
|
||||
pytest tests/unit/core/test_game_engine.py -v -o log_cli=true -o log_cli_level=DEBUG
|
||||
uv run pytest tests/unit/core/test_game_engine.py -v -o log_cli=true -o log_cli_level=DEBUG
|
||||
```
|
||||
|
||||
## CI/CD Considerations
|
||||
@ -396,13 +396,13 @@ pytest tests/unit/core/test_game_engine.py -v -o log_cli=true -o log_cli_level=D
|
||||
```yaml
|
||||
# Run fast unit tests on every commit
|
||||
- name: Unit Tests
|
||||
run: pytest tests/unit/ -v --cov=app
|
||||
run: uv run pytest tests/unit/ -v --cov=app
|
||||
|
||||
# Run integration tests serially (slower but reliable)
|
||||
- name: Integration Tests
|
||||
run: |
|
||||
pytest tests/integration/database/test_operations.py::TestDatabaseOperationsGame -v
|
||||
pytest tests/integration/database/test_operations.py::TestDatabaseOperationsLineup -v
|
||||
uv run pytest tests/integration/database/test_operations.py::TestDatabaseOperationsGame -v
|
||||
uv run pytest tests/integration/database/test_operations.py::TestDatabaseOperationsLineup -v
|
||||
# ... run each test class separately
|
||||
```
|
||||
|
||||
@ -422,11 +422,12 @@ pytest tests/unit/core/test_game_engine.py -v -o log_cli=true -o log_cli_level=D
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
# Set PYTHONPATH
|
||||
export PYTHONPATH=/mnt/NV2/Development/strat-gameplay-webapp/backend
|
||||
|
||||
# Or run from backend directory
|
||||
# Recommended: Use UV (handles PYTHONPATH automatically)
|
||||
cd /mnt/NV2/Development/strat-gameplay-webapp/backend
|
||||
uv run pytest tests/unit/ -v
|
||||
|
||||
# Alternative: Set PYTHONPATH manually
|
||||
export PYTHONPATH=/mnt/NV2/Development/strat-gameplay-webapp/backend
|
||||
pytest tests/unit/ -v
|
||||
```
|
||||
|
||||
|
||||
@ -27,12 +27,19 @@ async def test_create_new_game_success(game_commands):
|
||||
with patch('terminal_client.commands.uuid4', return_value=game_id):
|
||||
with patch('terminal_client.commands.Config') as mock_config:
|
||||
# Setup mocks
|
||||
from app.models.game_models import LineupPlayerState
|
||||
mock_batter = LineupPlayerState(
|
||||
lineup_id=1,
|
||||
card_id=100,
|
||||
position='CF',
|
||||
batting_order=1
|
||||
)
|
||||
mock_state = GameState(
|
||||
game_id=game_id,
|
||||
league_id='sba',
|
||||
home_team_id=1,
|
||||
away_team_id=2,
|
||||
current_batter_lineup_id=1,
|
||||
current_batter=mock_batter,
|
||||
inning=1,
|
||||
half='top'
|
||||
)
|
||||
@ -60,12 +67,19 @@ async def test_create_new_game_with_pd_league(game_commands):
|
||||
with patch('terminal_client.commands.uuid4', return_value=game_id):
|
||||
with patch('terminal_client.commands.Config') as mock_config:
|
||||
# Setup mocks
|
||||
from app.models.game_models import LineupPlayerState
|
||||
mock_batter = LineupPlayerState(
|
||||
lineup_id=1,
|
||||
card_id=200,
|
||||
position='SS',
|
||||
batting_order=1
|
||||
)
|
||||
mock_state = GameState(
|
||||
game_id=game_id,
|
||||
league_id='pd',
|
||||
home_team_id=3,
|
||||
away_team_id=5,
|
||||
current_batter_lineup_id=1,
|
||||
current_batter=mock_batter,
|
||||
inning=1,
|
||||
half='top'
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user