283 lines
9.2 KiB
Python
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())
|