chartbastan/backend/tests/test_energy_manual.py
2026-02-01 09:31:38 +01:00

283 lines
9.2 KiB
Python

"""
Manual test script for energy calculator.
This script runs basic tests to verify the energy calculator implementation.
"""
from datetime import datetime, timedelta
from app.ml.energy_calculator import (
calculate_energy_score,
apply_source_weights,
adjust_weights_for_degraded_mode,
apply_temporal_weighting,
normalize_score,
calculate_confidence
)
def test_apply_source_weights():
"""Test source weight application."""
print("\n=== Test: Apply Source Weights ===")
# Test with all sources
weighted_score = apply_source_weights(
twitter_score=50.0,
reddit_score=40.0,
rss_score=30.0,
available_sources=['twitter', 'reddit', 'rss']
)
expected = (50.0 * 0.60) + (40.0 * 0.25) + (30.0 * 0.15)
assert weighted_score == expected, f"Expected {expected}, got {weighted_score}"
print(f"✓ All sources: {weighted_score} (expected: {expected})")
# Test with Twitter only
weighted_score = apply_source_weights(
twitter_score=50.0,
reddit_score=0.0,
rss_score=0.0,
available_sources=['twitter']
)
assert weighted_score == 50.0, f"Expected 50.0, got {weighted_score}"
print(f"✓ Twitter only: {weighted_score}")
def test_adjust_weights_for_degraded_mode():
"""Test degraded mode weight adjustment."""
print("\n=== Test: Adjust Weights for Degraded Mode ===")
original_weights = {
'twitter': 0.60,
'reddit': 0.25,
'rss': 0.15
}
# Test with Twitter and Reddit only
adjusted = adjust_weights_for_degraded_mode(
original_weights=original_weights,
available_sources=['twitter', 'reddit']
)
total_weight = sum(adjusted.values())
assert abs(total_weight - 1.0) < 0.001, f"Total weight should be 1.0, got {total_weight}"
print(f"✓ Twitter+Reddit weights: {adjusted} (total: {total_weight})")
# Test with only Twitter
adjusted = adjust_weights_for_degraded_mode(
original_weights=original_weights,
available_sources=['twitter']
)
total_weight = sum(adjusted.values())
assert adjusted['twitter'] == 1.0, f"Twitter weight should be 1.0, got {adjusted['twitter']}"
print(f"✓ Twitter only: {adjusted}")
def test_normalize_score():
"""Test score normalization."""
print("\n=== Test: Normalize Score ===")
# Test negative score
normalized = normalize_score(-10.0)
assert normalized == 0.0, f"Expected 0.0, got {normalized}"
print(f"✓ Negative score: -10.0 → {normalized}")
# Test score above 100
normalized = normalize_score(150.0)
assert normalized == 100.0, f"Expected 100.0, got {normalized}"
print(f"✓ Score above 100: 150.0 → {normalized}")
# Test score in range
normalized = normalize_score(50.0)
assert normalized == 50.0, f"Expected 50.0, got {normalized}"
print(f"✓ Score in range: 50.0 → {normalized}")
def test_calculate_confidence():
"""Test confidence calculation."""
print("\n=== Test: Calculate Confidence ===")
# Test with all sources
confidence = calculate_confidence(
available_sources=['twitter', 'reddit', 'rss'],
total_weight=1.0
)
assert confidence > 0.6, f"Confidence should be > 0.6, got {confidence}"
print(f"✓ All sources: {confidence}")
# Test with single source (Twitter)
confidence = calculate_confidence(
available_sources=['twitter'],
total_weight=0.6
)
assert confidence == 0.6, f"Expected 0.6, got {confidence}"
print(f"✓ Twitter only: {confidence}")
# Test with no sources
confidence = calculate_confidence(
available_sources=[],
total_weight=0.0
)
assert confidence == 0.0, f"Expected 0.0, got {confidence}"
print(f"✓ No sources: {confidence}")
def test_apply_temporal_weighting():
"""Test temporal weighting."""
print("\n=== Test: Apply Temporal Weighting ===")
base_score = 50.0
now = datetime.utcnow()
# Test with recent tweets (within 1 hour)
recent_tweets = [
{
'compound': 0.5,
'created_at': now - timedelta(minutes=30)
},
{
'compound': 0.6,
'created_at': now - timedelta(minutes=15)
}
]
weighted_score = apply_temporal_weighting(
base_score=base_score,
tweets_with_timestamps=recent_tweets
)
assert 0 <= weighted_score <= 100, f"Score should be between 0 and 100, got {weighted_score}"
print(f"✓ Recent tweets: {base_score}{weighted_score}")
# Test with old tweets (24+ hours)
old_tweets = [
{
'compound': 0.5,
'created_at': now - timedelta(hours=30)
},
{
'compound': 0.6,
'created_at': now - timedelta(hours=25)
}
]
weighted_score = apply_temporal_weighting(
base_score=base_score,
tweets_with_timestamps=old_tweets
)
assert 0 <= weighted_score <= 100, f"Score should be between 0 and 100, got {weighted_score}"
print(f"✓ Old tweets: {base_score}{weighted_score}")
def test_calculate_energy_score_all_sources():
"""Test energy score calculation with all sources."""
print("\n=== Test: Calculate Energy Score (All Sources) ===")
twitter_sentiments = [
{'compound': 0.5, 'positive': 0.6, 'negative': 0.2, 'neutral': 0.2, 'sentiment': 'positive'},
{'compound': 0.7, 'positive': 0.7, 'negative': 0.1, 'neutral': 0.2, 'sentiment': 'positive'}
]
reddit_sentiments = [
{'compound': 0.3, 'positive': 0.4, 'negative': 0.3, 'neutral': 0.3, 'sentiment': 'positive'}
]
rss_sentiments = [
{'compound': 0.4, 'positive': 0.5, 'negative': 0.2, 'neutral': 0.3, 'sentiment': 'positive'}
]
result = calculate_energy_score(
match_id=1,
team_id=1,
twitter_sentiments=twitter_sentiments,
reddit_sentiments=reddit_sentiments,
rss_sentiments=rss_sentiments
)
assert 'score' in result, "Result should contain 'score'"
assert 'confidence' in result, "Result should contain 'confidence'"
assert 'sources_used' in result, "Result should contain 'sources_used'"
assert 0 <= result['score'] <= 100, f"Score should be between 0 and 100, got {result['score']}"
assert len(result['sources_used']) == 3, f"Should use 3 sources, got {len(result['sources_used'])}"
assert result['confidence'] > 0.6, f"Confidence should be > 0.6, got {result['confidence']}"
print(f"✓ Score: {result['score']}")
print(f"✓ Confidence: {result['confidence']}")
print(f"✓ Sources used: {result['sources_used']}")
def test_calculate_energy_score_degraded_mode():
"""Test energy score calculation in degraded mode."""
print("\n=== Test: Calculate Energy Score (Degraded Mode) ===")
twitter_sentiments = [
{'compound': 0.5, 'positive': 0.6, 'negative': 0.2, 'neutral': 0.2, 'sentiment': 'positive'}
]
result = calculate_energy_score(
match_id=1,
team_id=1,
twitter_sentiments=twitter_sentiments,
reddit_sentiments=[],
rss_sentiments=[]
)
assert result['score'] >= 0, f"Score should be >= 0, got {result['score']}"
assert result['confidence'] < 0.6, f"Confidence should be < 0.6 in degraded mode, got {result['confidence']}"
assert len(result['sources_used']) == 1, f"Should use 1 source, got {len(result['sources_used'])}"
assert 'twitter' in result['sources_used'], "Should use Twitter"
print(f"✓ Score: {result['score']}")
print(f"✓ Confidence: {result['confidence']} (lower in degraded mode)")
print(f"✓ Sources used: {result['sources_used']}")
def test_calculate_energy_score_no_data():
"""Test energy score calculation with no data."""
print("\n=== Test: Calculate Energy Score (No Data) ===")
result = calculate_energy_score(
match_id=1,
team_id=1,
twitter_sentiments=[],
reddit_sentiments=[],
rss_sentiments=[]
)
assert result['score'] == 0.0, f"Score should be 0.0, got {result['score']}"
assert result['confidence'] == 0.0, f"Confidence should be 0.0, got {result['confidence']}"
assert len(result['sources_used']) == 0, f"Should use 0 sources, got {len(result['sources_used'])}"
print(f"✓ Score: {result['score']}")
print(f"✓ Confidence: {result['confidence']}")
print(f"✓ Sources used: {result['sources_used']}")
def main():
"""Run all manual tests."""
print("=" * 60)
print("MANUAL TESTS FOR ENERGY CALCULATOR")
print("=" * 60)
try:
test_apply_source_weights()
test_adjust_weights_for_degraded_mode()
test_normalize_score()
test_calculate_confidence()
test_apply_temporal_weighting()
test_calculate_energy_score_all_sources()
test_calculate_energy_score_degraded_mode()
test_calculate_energy_score_no_data()
print("\n" + "=" * 60)
print("✅ ALL TESTS PASSED!")
print("=" * 60)
return 0
except AssertionError as e:
print(f"\n❌ TEST FAILED: {e}")
return 1
except Exception as e:
print(f"\n❌ UNEXPECTED ERROR: {e}")
import traceback
traceback.print_exc()
return 1
if __name__ == '__main__':
exit(main())