made test_downloader.py compatible with pytest
This commit is contained in:
@@ -1,295 +0,0 @@
|
||||
#!/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)
|
||||
326
tools/testing/test_downloader.py
Normal file
326
tools/testing/test_downloader.py
Normal file
@@ -0,0 +1,326 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Pytest test suite for the Pokemon data downloader.
|
||||
|
||||
This module contains pytest-compatible tests for the downloader with small data segments
|
||||
to ensure everything works correctly before downloading larger datasets.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import tempfile
|
||||
import json
|
||||
from pathlib import Path
|
||||
import pytest
|
||||
|
||||
# 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()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def temp_output_dir():
|
||||
"""Fixture providing a temporary directory for test outputs."""
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
yield Path(temp_dir)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def downloader(temp_output_dir):
|
||||
"""Fixture providing a PokemonDownloader instance with temporary output directory."""
|
||||
return PokemonDownloader(output_dir=temp_output_dir)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def data_validator():
|
||||
"""Fixture providing a DataValidator instance."""
|
||||
return DataValidator()
|
||||
|
||||
|
||||
def test_small_pokemon_download(downloader, temp_output_dir):
|
||||
"""Test downloading a small set of Pokemon (first 3)."""
|
||||
console.print(Panel.fit("🧪 Testing Pokemon Download (IDs 1-3)", style="bold yellow"))
|
||||
|
||||
# Download first 3 Pokemon
|
||||
pokemon_data = downloader.download_pokemon_batch(1, 3, max_workers=2)
|
||||
|
||||
# Assertions using pytest
|
||||
assert pokemon_data is not None, "Failed to download any Pokemon"
|
||||
assert len(pokemon_data) > 0, "Pokemon data should not be empty"
|
||||
assert len(pokemon_data) <= 3, "Should not download more than 3 Pokemon"
|
||||
|
||||
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)})")
|
||||
# Assert each pokemon has required attributes
|
||||
assert hasattr(pokemon, 'name'), f"Pokemon {pokemon_id} missing name"
|
||||
assert hasattr(pokemon, 'types'), f"Pokemon {pokemon_id} missing types"
|
||||
assert len(pokemon.types) > 0, f"Pokemon {pokemon_id} should have at least one type"
|
||||
|
||||
# Save and validate
|
||||
downloader.save_pokemon_data(pokemon_data, "test_pokemon.json")
|
||||
|
||||
# Check the saved file
|
||||
saved_file = temp_output_dir / "test_pokemon.json"
|
||||
assert saved_file.exists(), "Saved Pokemon file should exist"
|
||||
|
||||
with open(saved_file) as f:
|
||||
saved_data = json.load(f)
|
||||
|
||||
assert len(saved_data) == len(pokemon_data), "Saved data should match downloaded data length"
|
||||
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'])}")
|
||||
|
||||
# Assert the structure of saved data
|
||||
assert 'name' in first_pokemon, "Pokemon should have name"
|
||||
assert 'types' in first_pokemon, "Pokemon should have types"
|
||||
assert 'base_stats' in first_pokemon, "Pokemon should have base_stats"
|
||||
assert 'hp' in first_pokemon['base_stats'], "Pokemon should have HP stat"
|
||||
|
||||
|
||||
def test_moves_download(downloader, temp_output_dir):
|
||||
"""Test downloading a small set of moves."""
|
||||
console.print(Panel.fit("🧪 Testing Moves Download (IDs 1-5)", style="bold yellow"))
|
||||
|
||||
# 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)
|
||||
|
||||
# Assertions using pytest
|
||||
assert moves_data is not None, "Failed to download any moves"
|
||||
assert len(moves_data) > 0, "Moves data should not be empty"
|
||||
assert len(moves_data) <= 5, "Should not download more than 5 moves"
|
||||
|
||||
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})")
|
||||
|
||||
# Assert each move has required attributes
|
||||
assert hasattr(move, 'name'), f"Move {move_id} missing name"
|
||||
assert hasattr(move, 'type'), f"Move {move_id} missing type"
|
||||
assert move.name, f"Move {move_id} should have a non-empty name"
|
||||
|
||||
# Save and validate
|
||||
downloader.save_moves_data(moves_data, "test_moves.json")
|
||||
|
||||
# Check the saved file
|
||||
saved_file = temp_output_dir / "test_moves.json"
|
||||
assert saved_file.exists(), "Saved moves file should exist"
|
||||
|
||||
with open(saved_file) as f:
|
||||
saved_data = json.load(f)
|
||||
|
||||
assert len(saved_data) == len(moves_data), "Saved data should match downloaded data length"
|
||||
console.print(f"✅ Successfully saved {len(saved_data)} moves to file")
|
||||
|
||||
# Show move details and assert structure
|
||||
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']}")
|
||||
|
||||
# Assert the structure of saved move data
|
||||
assert 'name' in move_data, "Move should have name"
|
||||
assert 'type' in move_data, "Move should have type"
|
||||
assert 'power' in move_data, "Move should have power (can be None)"
|
||||
assert 'accuracy' in move_data, "Move should have accuracy"
|
||||
assert 'pp' in move_data, "Move should have PP"
|
||||
|
||||
|
||||
def test_type_effectiveness(downloader, temp_output_dir):
|
||||
"""Test downloading type effectiveness data."""
|
||||
console.print(Panel.fit("🧪 Testing Type Effectiveness Download", style="bold yellow"))
|
||||
|
||||
# Download type effectiveness
|
||||
effectiveness_data = downloader.download_type_effectiveness()
|
||||
|
||||
# Assertions using pytest
|
||||
assert effectiveness_data is not None, "Failed to download type effectiveness data"
|
||||
assert len(effectiveness_data) > 0, "Type effectiveness data should not be empty"
|
||||
|
||||
console.print(f"✅ Downloaded {len(effectiveness_data)} type effectiveness entries")
|
||||
|
||||
# Show some examples and validate structure
|
||||
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))}")
|
||||
|
||||
# Assert each entry has required attributes
|
||||
assert hasattr(entry, 'attacking_type'), "Entry missing attacking_type"
|
||||
assert hasattr(entry, 'defending_type'), "Entry missing defending_type"
|
||||
assert hasattr(entry, 'damage_factor'), "Entry missing damage_factor"
|
||||
assert isinstance(entry.damage_factor, (int, float)), "Damage factor should be numeric"
|
||||
|
||||
# Save and validate
|
||||
downloader.save_type_effectiveness(effectiveness_data, "test_types.json")
|
||||
|
||||
# Check the saved file
|
||||
saved_file = temp_output_dir / "test_types.json"
|
||||
assert saved_file.exists(), "Saved type effectiveness file should exist"
|
||||
|
||||
with open(saved_file) as f:
|
||||
saved_data = json.load(f)
|
||||
|
||||
assert len(saved_data) == len(effectiveness_data), "Saved data should match downloaded data length"
|
||||
console.print(f"✅ Successfully saved {len(saved_data)} type effectiveness entries to file")
|
||||
|
||||
|
||||
def test_validation(data_validator):
|
||||
"""Test the data validation system."""
|
||||
console.print(Panel.fit("🧪 Testing Data Validation", style="bold yellow"))
|
||||
|
||||
# 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 = data_validator.validate_pokemon_collection(valid_pokemon)
|
||||
assert not errors, f"Validation should pass for valid data, but got errors: {errors}"
|
||||
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 = data_validator.validate_pokemon_collection(invalid_pokemon)
|
||||
assert errors, "Invalid Pokemon data should fail validation"
|
||||
assert len(errors) > 0, "Should have validation errors for invalid data"
|
||||
console.print(f"✅ Invalid Pokemon data correctly failed validation: {len(errors)} errors")
|
||||
|
||||
|
||||
def test_integrated_download(downloader, temp_output_dir):
|
||||
"""Test downloading Pokemon with their moves in an integrated fashion."""
|
||||
console.print(Panel.fit("🧪 Testing Integrated Pokemon + Moves Download", style="bold yellow"))
|
||||
|
||||
# Download a single Pokemon (Pikachu)
|
||||
pokemon_data = downloader.download_pokemon_batch(25, 25, max_workers=1)
|
||||
|
||||
assert pokemon_data is not None, "Failed to download Pikachu"
|
||||
assert 25 in pokemon_data, "Pikachu (ID 25) should be in the downloaded data"
|
||||
|
||||
pikachu = pokemon_data[25]
|
||||
assert pikachu.name.lower() == "pikachu", "Downloaded Pokemon should be Pikachu"
|
||||
assert len(pikachu.types) > 0, "Pikachu should have at least one type"
|
||||
assert len(pikachu.moves) > 0, "Pikachu should have moves"
|
||||
|
||||
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)
|
||||
|
||||
assert moves_data is not None, "Should successfully download Pikachu's moves"
|
||||
assert len(moves_data) > 0, "Should download at least some of Pikachu's moves"
|
||||
|
||||
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)")
|
||||
assert hasattr(move, 'name'), f"Move {move_id} should have a name"
|
||||
assert hasattr(move, 'type'), f"Move {move_id} should have a type"
|
||||
|
||||
# Save both datasets
|
||||
downloader.save_pokemon_data(pokemon_data, "pikachu.json")
|
||||
downloader.save_moves_data(moves_data, "pikachu_moves.json")
|
||||
|
||||
# Verify files were saved
|
||||
assert (temp_output_dir / "pikachu.json").exists(), "Pikachu data file should be saved"
|
||||
assert (temp_output_dir / "pikachu_moves.json").exists(), "Pikachu moves data file should be saved"
|
||||
|
||||
|
||||
# Parametrized tests for better pytest organization
|
||||
@pytest.mark.parametrize("pokemon_range", [(1, 3), (4, 6)])
|
||||
def test_pokemon_download_ranges(downloader, temp_output_dir, pokemon_range):
|
||||
"""Test downloading different ranges of Pokemon."""
|
||||
start_id, end_id = pokemon_range
|
||||
pokemon_data = downloader.download_pokemon_batch(start_id, end_id, max_workers=2)
|
||||
|
||||
assert pokemon_data is not None, f"Failed to download Pokemon {start_id}-{end_id}"
|
||||
assert len(pokemon_data) > 0, "Pokemon data should not be empty"
|
||||
|
||||
for pokemon_id, pokemon in pokemon_data.items():
|
||||
assert start_id <= pokemon_id <= end_id, f"Pokemon ID {pokemon_id} should be in range {start_id}-{end_id}"
|
||||
assert hasattr(pokemon, 'name'), f"Pokemon {pokemon_id} missing name"
|
||||
assert hasattr(pokemon, 'types'), f"Pokemon {pokemon_id} missing types"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("move_ids", [[1, 2, 3], [10, 11, 12, 13]])
|
||||
def test_moves_download_batches(downloader, temp_output_dir, move_ids):
|
||||
"""Test downloading different batches of moves."""
|
||||
moves_data = downloader.download_moves_batch(move_ids, max_workers=2)
|
||||
|
||||
assert moves_data is not None, f"Failed to download moves {move_ids}"
|
||||
assert len(moves_data) > 0, "Moves data should not be empty"
|
||||
|
||||
for move_id, move in moves_data.items():
|
||||
assert move_id in move_ids, f"Move ID {move_id} should be in requested list"
|
||||
assert hasattr(move, 'name'), f"Move {move_id} missing name"
|
||||
assert hasattr(move, 'type'), f"Move {move_id} missing type"
|
||||
|
||||
|
||||
# Test that can be run directly with python for debugging
|
||||
if __name__ == "__main__":
|
||||
# This allows the file to be run directly for debugging, but pytest is preferred
|
||||
console.print(Panel.fit(
|
||||
"🚀 Pokemon Data Downloader Tests\n\nFor full test suite, please use: pytest tools/data/test_downloader.py",
|
||||
style="bold yellow"
|
||||
))
|
||||
console.print("\nRunning basic validation test...")
|
||||
|
||||
# Just run a quick validation test when run directly
|
||||
validator = DataValidator()
|
||||
test_validation(validator)
|
||||
console.print("\n✅ Basic test passed! Use pytest for full test suite.")
|
||||
Reference in New Issue
Block a user