- Fix TypeError in check_steal_opportunity by properly mocking catcher defense - Correct tag_from_third test calculation to account for all adjustment conditions - Fix pitcher replacement test by setting appropriate allowed runners threshold - Add comprehensive test coverage for AI service business logic - Implement VS Code testing panel configuration with pytest integration - Create pytest.ini for consistent test execution and warning management - Add test isolation guidelines and factory pattern implementation - Establish 102 passing tests with zero failures 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
154 lines
4.3 KiB
Python
154 lines
4.3 KiB
Python
"""
|
|
ManagerAi factory for generating test data.
|
|
|
|
Provides methods to create unique, valid ManagerAi instances for testing
|
|
without conflicts between test runs.
|
|
"""
|
|
|
|
from app.models.manager_ai import ManagerAi
|
|
from tests.conftest import generate_unique_name
|
|
|
|
|
|
class ManagerAiFactory:
|
|
"""Factory for creating ManagerAi test instances."""
|
|
|
|
@staticmethod
|
|
def build(**kwargs):
|
|
"""
|
|
Build a ManagerAi instance without saving to database.
|
|
|
|
Args:
|
|
**kwargs: Override default field values
|
|
|
|
Returns:
|
|
ManagerAi: Configured manager AI instance
|
|
|
|
Example:
|
|
ai = ManagerAiFactory.build(name="Test AI")
|
|
ai = ManagerAiFactory.build(steal=10, running=8)
|
|
"""
|
|
defaults = {
|
|
'name': generate_unique_name("AI Manager"),
|
|
'steal': 5,
|
|
'running': 5,
|
|
'hold': 5,
|
|
'catcher_throw': 5,
|
|
'uncapped_home': 5,
|
|
'uncapped_third': 5,
|
|
'uncapped_trail': 5,
|
|
'bullpen_matchup': 5,
|
|
'behind_aggression': 5,
|
|
'ahead_aggression': 5,
|
|
'decide_throw': 5
|
|
}
|
|
defaults.update(kwargs)
|
|
return ManagerAi(**defaults)
|
|
|
|
@classmethod
|
|
def create(cls, session, **kwargs):
|
|
"""
|
|
Create and save a ManagerAi instance to database.
|
|
|
|
Args:
|
|
session: Database session
|
|
**kwargs: Override default field values
|
|
|
|
Returns:
|
|
ManagerAi: Saved manager AI instance
|
|
|
|
Example:
|
|
ai = ManagerAiFactory.create(session, steal=10)
|
|
"""
|
|
ai = cls.build(**kwargs)
|
|
session.add(ai)
|
|
session.flush() # Get ID without committing
|
|
return ai
|
|
|
|
@classmethod
|
|
def build_batch(cls, count, **kwargs):
|
|
"""
|
|
Build multiple ManagerAi instances.
|
|
|
|
Args:
|
|
count: Number of AIs to create
|
|
**kwargs: Common field values for all AIs
|
|
|
|
Returns:
|
|
list[ManagerAi]: List of AI instances
|
|
|
|
Example:
|
|
ais = ManagerAiFactory.build_batch(3, steal=8)
|
|
"""
|
|
return [cls.build(**kwargs) for _ in range(count)]
|
|
|
|
@classmethod
|
|
def create_batch(cls, session, count, **kwargs):
|
|
"""
|
|
Create and save multiple ManagerAi instances.
|
|
|
|
Args:
|
|
session: Database session
|
|
count: Number of AIs to create
|
|
**kwargs: Common field values for all AIs
|
|
|
|
Returns:
|
|
list[ManagerAi]: List of saved AI instances
|
|
|
|
Example:
|
|
ais = ManagerAiFactory.create_batch(session, 3, steal=8)
|
|
"""
|
|
ais = cls.build_batch(count, **kwargs)
|
|
session.add_all(ais)
|
|
session.flush()
|
|
return ais
|
|
|
|
# Preset factories for common AI configurations
|
|
@classmethod
|
|
def build_balanced(cls, **kwargs):
|
|
"""Build a balanced AI (all 5s)."""
|
|
defaults = {
|
|
'name': generate_unique_name("Balanced AI"),
|
|
# All defaults are already 5
|
|
}
|
|
defaults.update(kwargs)
|
|
return cls.build(**defaults)
|
|
|
|
@classmethod
|
|
def build_aggressive(cls, **kwargs):
|
|
"""Build an aggressive AI (YOLO preset)."""
|
|
defaults = {
|
|
'name': generate_unique_name("Aggressive AI"),
|
|
'steal': 10,
|
|
'running': 10,
|
|
'hold': 5,
|
|
'catcher_throw': 10,
|
|
'uncapped_home': 10,
|
|
'uncapped_third': 10,
|
|
'uncapped_trail': 10,
|
|
'bullpen_matchup': 3,
|
|
'behind_aggression': 10,
|
|
'ahead_aggression': 10,
|
|
'decide_throw': 10
|
|
}
|
|
defaults.update(kwargs)
|
|
return cls.build(**defaults)
|
|
|
|
@classmethod
|
|
def build_conservative(cls, **kwargs):
|
|
"""Build a conservative AI (Safe preset)."""
|
|
defaults = {
|
|
'name': generate_unique_name("Conservative AI"),
|
|
'steal': 3,
|
|
'running': 3,
|
|
'hold': 8,
|
|
'catcher_throw': 5,
|
|
'uncapped_home': 5,
|
|
'uncapped_third': 3,
|
|
'uncapped_trail': 5,
|
|
'bullpen_matchup': 8,
|
|
'behind_aggression': 5,
|
|
'ahead_aggression': 1,
|
|
'decide_throw': 1
|
|
}
|
|
defaults.update(kwargs)
|
|
return cls.build(**defaults) |