296 lines
11 KiB
Python
296 lines
11 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test script for the Pokemon data downloader.
|
|
|
|
This script tests the downloader with small data segments to ensure
|
|
everything works correctly before downloading larger datasets.
|
|
"""
|
|
|
|
import sys
|
|
import tempfile
|
|
import shutil
|
|
from pathlib import Path
|
|
import json
|
|
|
|
# Add the tools directory to Python path for imports
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from data.pokemon_downloader import PokemonDownloader
|
|
from data.schemas import DataValidator
|
|
from rich.console import Console
|
|
from rich.panel import Panel
|
|
|
|
console = Console()
|
|
|
|
|
|
def test_small_pokemon_download():
|
|
"""Test downloading a small set of Pokemon (first 3)."""
|
|
console.print(Panel.fit("🧪 Testing Pokemon Download (IDs 1-3)", style="bold yellow"))
|
|
|
|
# Create temporary directory for test output
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
downloader = PokemonDownloader(output_dir=Path(temp_dir))
|
|
|
|
# Download first 3 Pokemon
|
|
pokemon_data = downloader.download_pokemon_batch(1, 3, max_workers=2)
|
|
|
|
if not pokemon_data:
|
|
console.print("❌ Failed to download any Pokemon")
|
|
return False
|
|
|
|
console.print(f"✅ Downloaded {len(pokemon_data)} Pokemon:")
|
|
for pokemon_id, pokemon in pokemon_data.items():
|
|
console.print(f" - #{pokemon_id}: {pokemon.name.title()} ({', '.join(pokemon.types)})")
|
|
|
|
# Save and validate
|
|
downloader.save_pokemon_data(pokemon_data, "test_pokemon.json")
|
|
|
|
# Check the saved file
|
|
saved_file = Path(temp_dir) / "test_pokemon.json"
|
|
if saved_file.exists():
|
|
with open(saved_file) as f:
|
|
saved_data = json.load(f)
|
|
console.print(f"✅ Successfully saved {len(saved_data)} Pokemon to file")
|
|
|
|
# Show first Pokemon details
|
|
first_pokemon = list(saved_data.values())[0]
|
|
console.print(f"📊 Sample data for {first_pokemon['name']}:")
|
|
console.print(f" - Types: {first_pokemon['types']}")
|
|
console.print(f" - Base HP: {first_pokemon['base_stats']['hp']}")
|
|
console.print(f" - Abilities: {first_pokemon['abilities'][:2]}...") # Show first 2
|
|
console.print(f" - Move count: {len(first_pokemon['moves'])}")
|
|
|
|
return True
|
|
|
|
|
|
def test_moves_download():
|
|
"""Test downloading a small set of moves."""
|
|
console.print(Panel.fit("🧪 Testing Moves Download (IDs 1-5)", style="bold yellow"))
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
downloader = PokemonDownloader(output_dir=Path(temp_dir))
|
|
|
|
# Download first 5 moves
|
|
move_ids = [1, 2, 3, 4, 5] # Pound, Karate Chop, Double Slap, Comet Punch, Mega Punch
|
|
moves_data = downloader.download_moves_batch(move_ids, max_workers=2)
|
|
|
|
if not moves_data:
|
|
console.print("❌ Failed to download any moves")
|
|
return False
|
|
|
|
console.print(f"✅ Downloaded {len(moves_data)} moves:")
|
|
for move_id, move in moves_data.items():
|
|
power_str = f"{move.power} power" if move.power else "no power"
|
|
console.print(f" - #{move_id}: {move.name.title()} ({move.type}, {power_str})")
|
|
|
|
# Save and validate
|
|
downloader.save_moves_data(moves_data, "test_moves.json")
|
|
|
|
# Check the saved file
|
|
saved_file = Path(temp_dir) / "test_moves.json"
|
|
if saved_file.exists():
|
|
with open(saved_file) as f:
|
|
saved_data = json.load(f)
|
|
console.print(f"✅ Successfully saved {len(saved_data)} moves to file")
|
|
|
|
# Show move details
|
|
for move_data in list(saved_data.values())[:2]: # Show first 2 moves
|
|
console.print(f"📊 {move_data['name'].title()}:")
|
|
console.print(f" - Type: {move_data['type']}")
|
|
console.print(f" - Power: {move_data['power']}")
|
|
console.print(f" - Accuracy: {move_data['accuracy']}")
|
|
console.print(f" - PP: {move_data['pp']}")
|
|
|
|
return True
|
|
|
|
|
|
def test_type_effectiveness():
|
|
"""Test downloading type effectiveness data."""
|
|
console.print(Panel.fit("🧪 Testing Type Effectiveness Download", style="bold yellow"))
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
downloader = PokemonDownloader(output_dir=Path(temp_dir))
|
|
|
|
# Download type effectiveness
|
|
effectiveness_data = downloader.download_type_effectiveness()
|
|
|
|
if not effectiveness_data:
|
|
console.print("❌ Failed to download type effectiveness data")
|
|
return False
|
|
|
|
console.print(f"✅ Downloaded {len(effectiveness_data)} type effectiveness entries")
|
|
|
|
# Show some examples
|
|
console.print("📊 Sample type effectiveness entries:")
|
|
for entry in effectiveness_data[:5]:
|
|
factor_str = {0.0: "no effect", 0.5: "not very effective", 2.0: "super effective"}
|
|
console.print(f" - {entry.attacking_type} vs {entry.defending_type}: {factor_str.get(entry.damage_factor, str(entry.damage_factor))}")
|
|
|
|
# Save and validate
|
|
downloader.save_type_effectiveness(effectiveness_data, "test_types.json")
|
|
|
|
# Check the saved file
|
|
saved_file = Path(temp_dir) / "test_types.json"
|
|
if saved_file.exists():
|
|
with open(saved_file) as f:
|
|
saved_data = json.load(f)
|
|
console.print(f"✅ Successfully saved {len(saved_data)} type effectiveness entries to file")
|
|
|
|
return True
|
|
|
|
|
|
def test_validation():
|
|
"""Test the data validation system."""
|
|
console.print(Panel.fit("🧪 Testing Data Validation", style="bold yellow"))
|
|
|
|
validator = DataValidator()
|
|
|
|
# Test valid Pokemon data
|
|
valid_pokemon = {
|
|
"1": {
|
|
"id": 1,
|
|
"name": "bulbasaur",
|
|
"types": ["grass", "poison"],
|
|
"base_stats": {
|
|
"hp": 45,
|
|
"attack": 49,
|
|
"defense": 49,
|
|
"special_attack": 65,
|
|
"special_defense": 65,
|
|
"speed": 45
|
|
},
|
|
"abilities": ["overgrow", "chlorophyll"],
|
|
"moves": [1, 2, 3, 4],
|
|
"weight": 69,
|
|
"height": 7,
|
|
"base_experience": 64
|
|
}
|
|
}
|
|
|
|
errors = validator.validate_pokemon_collection(valid_pokemon)
|
|
if errors:
|
|
console.print(f"❌ Validation failed for valid data: {errors}")
|
|
return False
|
|
else:
|
|
console.print("✅ Valid Pokemon data passed validation")
|
|
|
|
# Test invalid Pokemon data
|
|
invalid_pokemon = {
|
|
"1": {
|
|
"id": 1,
|
|
"name": "bulbasaur",
|
|
"types": ["grass", "invalid_type"], # Invalid type
|
|
"base_stats": {
|
|
"hp": 45,
|
|
"attack": 49,
|
|
"defense": 49,
|
|
"special_attack": 65,
|
|
"special_defense": 65,
|
|
"speed": 45
|
|
},
|
|
"abilities": ["overgrow"],
|
|
"moves": [1, 2, 3, 4],
|
|
"weight": 69,
|
|
"height": 7,
|
|
"base_experience": 64
|
|
}
|
|
}
|
|
|
|
errors = validator.validate_pokemon_collection(invalid_pokemon)
|
|
if errors:
|
|
console.print(f"✅ Invalid Pokemon data correctly failed validation: {len(errors)} errors")
|
|
else:
|
|
console.print("❌ Invalid data should have failed validation")
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
def test_integrated_download():
|
|
"""Test downloading Pokemon with their moves in an integrated fashion."""
|
|
console.print(Panel.fit("🧪 Testing Integrated Pokemon + Moves Download", style="bold yellow"))
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
downloader = PokemonDownloader(output_dir=Path(temp_dir))
|
|
|
|
# Download a single Pokemon (Pikachu)
|
|
pokemon_data = downloader.download_pokemon_batch(25, 25, max_workers=1)
|
|
|
|
if not pokemon_data:
|
|
console.print("❌ Failed to download Pikachu")
|
|
return False
|
|
|
|
pikachu = pokemon_data[25]
|
|
console.print(f"✅ Downloaded {pikachu.name.title()}")
|
|
console.print(f" - Types: {pikachu.types}")
|
|
console.print(f" - Base stats total: {sum(pikachu.base_stats.__dict__.values())}")
|
|
console.print(f" - Can learn {len(pikachu.moves)} moves")
|
|
|
|
# Download first 10 moves that Pikachu can learn
|
|
pikachu_moves = pikachu.moves[:10]
|
|
moves_data = downloader.download_moves_batch(pikachu_moves, max_workers=3)
|
|
|
|
if moves_data:
|
|
console.print(f"✅ Downloaded {len(moves_data)} of Pikachu's moves:")
|
|
for move_id, move in list(moves_data.items())[:5]:
|
|
console.print(f" - {move.name.title()} ({move.type} type)")
|
|
|
|
# Save both datasets
|
|
downloader.save_pokemon_data(pokemon_data, "pikachu.json")
|
|
downloader.save_moves_data(moves_data, "pikachu_moves.json")
|
|
|
|
return True
|
|
|
|
|
|
def run_all_tests():
|
|
"""Run all tests."""
|
|
console.print(Panel.fit(
|
|
"🚀 Pokemon Data Downloader Test Suite",
|
|
style="bold green"
|
|
))
|
|
|
|
tests = [
|
|
("Pokemon Download", test_small_pokemon_download),
|
|
("Moves Download", test_moves_download),
|
|
("Type Effectiveness", test_type_effectiveness),
|
|
("Data Validation", test_validation),
|
|
("Integrated Download", test_integrated_download),
|
|
]
|
|
|
|
results = []
|
|
|
|
for test_name, test_func in tests:
|
|
console.print(f"\n{'='*50}")
|
|
try:
|
|
result = test_func()
|
|
results.append((test_name, result))
|
|
status = "✅ PASSED" if result else "❌ FAILED"
|
|
console.print(f"{test_name}: {status}")
|
|
except Exception as e:
|
|
results.append((test_name, False))
|
|
console.print(f"{test_name}: ❌ ERROR - {e}")
|
|
|
|
# Summary
|
|
console.print(f"\n{'='*50}")
|
|
console.print("TEST SUMMARY:")
|
|
passed = sum(1 for _, result in results if result)
|
|
total = len(results)
|
|
|
|
for test_name, result in results:
|
|
status = "✅" if result else "❌"
|
|
console.print(f" {status} {test_name}")
|
|
|
|
console.print(f"\nOverall: {passed}/{total} tests passed")
|
|
|
|
if passed == total:
|
|
console.print(Panel.fit("🎉 All tests passed! The downloader is ready to use.", style="bold green"))
|
|
else:
|
|
console.print(Panel.fit("⚠️ Some tests failed. Please check the errors above.", style="bold red"))
|
|
|
|
return passed == total
|
|
|
|
|
|
if __name__ == "__main__":
|
|
success = run_all_tests()
|
|
sys.exit(0 if success else 1)
|