mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
* Fix leaderboard scrolling performance after PR #39 merge - Restore leaderboard background updates that were accidentally removed - Fix duration method call from get_dynamic_duration() back to get_duration() - Restore proper fallback duration (600s instead of 60s) for leaderboard - Add back sports manager updates that feed data to leaderboard - Fix leaderboard defer_update priority to prevent scrolling lag These changes restore the leaderboard's dynamic duration calculation and ensure it gets proper background updates for smooth scrolling. * Apply PR #60 leaderboard performance optimizations - Change scroll_delay from 0.05s to 0.01s (100fps instead of 20fps) - Remove conditional scrolling logic - scroll every frame for smooth animation - Add FPS tracking and logging for performance monitoring - Restore high-framerate scrolling that was working before PR #39 merge These changes restore the smooth leaderboard scrolling performance that was achieved in PR #60 but was lost during the PR #39 merge. * Fix critical bugs identified in PR #39 review - Fix record filtering logic bug: change away_record == set to away_record in set - Fix incorrect sport specification: change 'nfl' to 'ncaa_fb' for NCAA Football data requests - These bugs were causing incorrect data display and wrong sport data fetching Addresses issues found by cursor bot in PR #39 review: - Record filtering was always evaluating to False - NCAA Football was fetching NFL data instead of college football data * Enhance cache clearing implementation from PR #39 - Add detailed logging to cache clearing process for better visibility - Log cache clearing statistics (memory entries and file count) - Improve startup logging to show cache clearing and data refetch process - Addresses legoguy1000's comment about preventing stale data issues This enhances the cache clearing implementation that was added in PR #39 to help prevent legacy cache issues and stale data problems. * continuing on base_classes - added baseball and api extractor since we don't use ESPN api for all sports * tests * fix missing duration * ensure milb, mlb, ncaa bb are all using new baseball base class properly * cursor rule to help with PR creation * fix image call * fix _scoreboard suffix on milb, MLB
257 lines
9.4 KiB
Python
257 lines
9.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test Baseball Architecture
|
|
|
|
This test validates the new baseball base class and its integration
|
|
with the new architecture components.
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
import logging
|
|
from typing import Dict, Any
|
|
|
|
# Add src to path
|
|
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
|
|
|
def test_baseball_imports():
|
|
"""Test that baseball base classes can be imported."""
|
|
print("🧪 Testing Baseball Imports...")
|
|
|
|
try:
|
|
from src.base_classes.baseball import Baseball, BaseballLive, BaseballRecent, BaseballUpcoming
|
|
print("✅ Baseball base classes imported successfully")
|
|
return True
|
|
except Exception as e:
|
|
print(f"❌ Baseball import failed: {e}")
|
|
return False
|
|
|
|
def test_baseball_configuration():
|
|
"""Test baseball-specific configuration."""
|
|
print("\n🧪 Testing Baseball Configuration...")
|
|
|
|
try:
|
|
from src.base_classes.sport_configs import get_sport_config
|
|
|
|
# Test MLB configuration
|
|
mlb_config = get_sport_config('mlb', None)
|
|
|
|
# Validate MLB-specific settings
|
|
assert mlb_config.update_cadence == 'daily', "MLB should have daily updates"
|
|
assert mlb_config.season_length == 162, "MLB season should be 162 games"
|
|
assert mlb_config.games_per_week == 6, "MLB should have ~6 games per week"
|
|
assert mlb_config.data_source_type == 'mlb_api', "MLB should use MLB API"
|
|
|
|
# Test baseball-specific fields
|
|
expected_fields = ['inning', 'outs', 'bases', 'strikes', 'balls', 'pitcher', 'batter']
|
|
for field in expected_fields:
|
|
assert field in mlb_config.sport_specific_fields, f"Missing baseball field: {field}"
|
|
|
|
print("✅ Baseball configuration is correct")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Baseball configuration test failed: {e}")
|
|
return False
|
|
|
|
def test_baseball_api_extractor():
|
|
"""Test baseball API extractor."""
|
|
print("\n🧪 Testing Baseball API Extractor...")
|
|
|
|
try:
|
|
from src.base_classes.api_extractors import get_extractor_for_sport
|
|
logger = logging.getLogger('test')
|
|
|
|
# Get MLB extractor
|
|
mlb_extractor = get_extractor_for_sport('mlb', logger)
|
|
print(f"✅ MLB extractor: {type(mlb_extractor).__name__}")
|
|
|
|
# Test that extractor has baseball-specific methods
|
|
assert hasattr(mlb_extractor, 'extract_game_details')
|
|
assert hasattr(mlb_extractor, 'get_sport_specific_fields')
|
|
|
|
# Test with sample baseball data
|
|
sample_baseball_game = {
|
|
"id": "test_game",
|
|
"competitions": [{
|
|
"status": {"type": {"state": "in", "detail": "Top 3rd"}},
|
|
"competitors": [
|
|
{"homeAway": "home", "team": {"abbreviation": "NYY", "displayName": "Yankees"}, "score": "2"},
|
|
{"homeAway": "away", "team": {"abbreviation": "BOS", "displayName": "Red Sox"}, "score": "1"}
|
|
],
|
|
"situation": {
|
|
"inning": "3rd",
|
|
"outs": 2,
|
|
"bases": "1st, 3rd",
|
|
"strikes": 2,
|
|
"balls": 1,
|
|
"pitcher": "Gerrit Cole",
|
|
"batter": "Rafael Devers"
|
|
}
|
|
}],
|
|
"date": "2024-01-01T19:00:00Z"
|
|
}
|
|
|
|
# Test game details extraction
|
|
game_details = mlb_extractor.extract_game_details(sample_baseball_game)
|
|
if game_details:
|
|
print("✅ Baseball game details extracted successfully")
|
|
|
|
# Test sport-specific fields
|
|
sport_fields = mlb_extractor.get_sport_specific_fields(sample_baseball_game)
|
|
expected_fields = ['inning', 'outs', 'bases', 'strikes', 'balls', 'pitcher', 'batter']
|
|
|
|
for field in expected_fields:
|
|
assert field in sport_fields, f"Missing baseball field: {field}"
|
|
|
|
print("✅ Baseball sport-specific fields extracted")
|
|
else:
|
|
print("⚠️ Baseball game details extraction returned None")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Baseball API extractor test failed: {e}")
|
|
return False
|
|
|
|
def test_baseball_data_source():
|
|
"""Test baseball data source."""
|
|
print("\n🧪 Testing Baseball Data Source...")
|
|
|
|
try:
|
|
from src.base_classes.data_sources import get_data_source_for_sport
|
|
logger = logging.getLogger('test')
|
|
|
|
# Get MLB data source
|
|
mlb_data_source = get_data_source_for_sport('mlb', 'mlb_api', logger)
|
|
print(f"✅ MLB data source: {type(mlb_data_source).__name__}")
|
|
|
|
# Test that data source has required methods
|
|
assert hasattr(mlb_data_source, 'fetch_live_games')
|
|
assert hasattr(mlb_data_source, 'fetch_schedule')
|
|
assert hasattr(mlb_data_source, 'fetch_standings')
|
|
|
|
print("✅ Baseball data source is properly configured")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Baseball data source test failed: {e}")
|
|
return False
|
|
|
|
def test_baseball_sport_specific_logic():
|
|
"""Test baseball-specific logic without hardware dependencies."""
|
|
print("\n🧪 Testing Baseball Sport-Specific Logic...")
|
|
|
|
try:
|
|
# Test baseball-specific game data
|
|
sample_baseball_game = {
|
|
'inning': '3rd',
|
|
'outs': 2,
|
|
'bases': '1st, 3rd',
|
|
'strikes': 2,
|
|
'balls': 1,
|
|
'pitcher': 'Gerrit Cole',
|
|
'batter': 'Rafael Devers',
|
|
'is_live': True,
|
|
'is_final': False,
|
|
'is_upcoming': False
|
|
}
|
|
|
|
# Test that we can identify baseball-specific characteristics
|
|
assert sample_baseball_game['inning'] == '3rd'
|
|
assert sample_baseball_game['outs'] == 2
|
|
assert sample_baseball_game['bases'] == '1st, 3rd'
|
|
assert sample_baseball_game['strikes'] == 2
|
|
assert sample_baseball_game['balls'] == 1
|
|
|
|
print("✅ Baseball sport-specific logic is working")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Baseball sport-specific logic test failed: {e}")
|
|
return False
|
|
|
|
def test_baseball_vs_other_sports():
|
|
"""Test that baseball has different characteristics than other sports."""
|
|
print("\n🧪 Testing Baseball vs Other Sports...")
|
|
|
|
try:
|
|
from src.base_classes.sport_configs import get_sport_config
|
|
|
|
# Compare baseball with other sports
|
|
mlb_config = get_sport_config('mlb', None)
|
|
nfl_config = get_sport_config('nfl', None)
|
|
nhl_config = get_sport_config('nhl', None)
|
|
|
|
# Baseball should have different characteristics
|
|
assert mlb_config.season_length > nfl_config.season_length, "MLB season should be longer than NFL"
|
|
assert mlb_config.games_per_week > nfl_config.games_per_week, "MLB should have more games per week than NFL"
|
|
assert mlb_config.update_cadence == 'daily', "MLB should have daily updates"
|
|
assert nfl_config.update_cadence == 'weekly', "NFL should have weekly updates"
|
|
|
|
# Baseball should have different sport-specific fields
|
|
mlb_fields = set(mlb_config.sport_specific_fields)
|
|
nfl_fields = set(nfl_config.sport_specific_fields)
|
|
nhl_fields = set(nhl_config.sport_specific_fields)
|
|
|
|
# Baseball should have unique fields
|
|
assert 'inning' in mlb_fields, "Baseball should have inning field"
|
|
assert 'outs' in mlb_fields, "Baseball should have outs field"
|
|
assert 'bases' in mlb_fields, "Baseball should have bases field"
|
|
assert 'strikes' in mlb_fields, "Baseball should have strikes field"
|
|
assert 'balls' in mlb_fields, "Baseball should have balls field"
|
|
|
|
# Baseball should not have football/hockey fields
|
|
assert 'down' not in mlb_fields, "Baseball should not have down field"
|
|
assert 'distance' not in mlb_fields, "Baseball should not have distance field"
|
|
assert 'period' not in mlb_fields, "Baseball should not have period field"
|
|
|
|
print("✅ Baseball has distinct characteristics from other sports")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Baseball vs other sports test failed: {e}")
|
|
return False
|
|
|
|
def main():
|
|
"""Run all baseball architecture tests."""
|
|
print("⚾ Testing Baseball Architecture")
|
|
print("=" * 50)
|
|
|
|
# Configure logging
|
|
logging.basicConfig(level=logging.WARNING)
|
|
|
|
# Run all tests
|
|
tests = [
|
|
test_baseball_imports,
|
|
test_baseball_configuration,
|
|
test_baseball_api_extractor,
|
|
test_baseball_data_source,
|
|
test_baseball_sport_specific_logic,
|
|
test_baseball_vs_other_sports
|
|
]
|
|
|
|
passed = 0
|
|
total = len(tests)
|
|
|
|
for test in tests:
|
|
try:
|
|
if test():
|
|
passed += 1
|
|
except Exception as e:
|
|
print(f"❌ Test {test.__name__} failed with exception: {e}")
|
|
|
|
print("\n" + "=" * 50)
|
|
print(f"🏁 Baseball Test Results: {passed}/{total} tests passed")
|
|
|
|
if passed == total:
|
|
print("🎉 All baseball architecture tests passed! Baseball is ready to use.")
|
|
return True
|
|
else:
|
|
print("❌ Some baseball tests failed. Please check the errors above.")
|
|
return False
|
|
|
|
if __name__ == "__main__":
|
|
success = main()
|
|
sys.exit(0 if success else 1)
|