Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| Component tests for surf spot finder | |
| Tests individual parts without complex imports | |
| """ | |
| import json | |
| import os | |
| import sys | |
| from geopy.geocoders import Nominatim | |
| from geopy.distance import geodesic | |
| # Add parent directory to path to access the mcp_server modules | |
| sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) | |
| def test_database(): | |
| """Test surf spots database loading""" | |
| print("ποΈ Testing Database Loading...") | |
| try: | |
| spots_path = os.path.join(os.path.dirname(__file__), "..", "data", "surf_spots.json") | |
| with open(spots_path, 'r') as f: | |
| data = json.load(f) | |
| spots = data["spots"] | |
| print(f"β Loaded {len(spots)} surf spots:") | |
| for spot in spots[:3]: # Show first 3 | |
| print(f" β’ {spot['name']} ({spot['location']}) - {spot['latitude']}, {spot['longitude']}") | |
| return spots | |
| except Exception as e: | |
| print(f"β Database test failed: {e}") | |
| return [] | |
| def test_geocoding(): | |
| """Test location resolution""" | |
| print("\nπ Testing Geocoding...") | |
| try: | |
| geolocator = Nominatim(user_agent="surf-spot-finder-test") | |
| test_locations = ["Tarifa, Spain", "Lisbon, Portugal"] | |
| for location in test_locations: | |
| result = geolocator.geocode(location, timeout=10) | |
| if result: | |
| print(f" β {location} β {result.latitude:.3f}, {result.longitude:.3f}") | |
| else: | |
| print(f" β {location} β Failed to resolve") | |
| return True | |
| except Exception as e: | |
| print(f"β Geocoding test failed: {e}") | |
| return False | |
| def test_distance_calculation(): | |
| """Test distance calculations""" | |
| print("\nπ Testing Distance Calculations...") | |
| try: | |
| # Test distance between Tarifa and nearby spots | |
| tarifa = (36.013, -5.605) | |
| nearby_spots = [ | |
| ("Ericeira, Portugal", 39.001, -9.416), | |
| ("Mundaka, Spain", 43.407, -2.699) | |
| ] | |
| for name, lat, lon in nearby_spots: | |
| distance = geodesic(tarifa, (lat, lon)).kilometers | |
| print(f" π Tarifa to {name}: {distance:.1f}km") | |
| return True | |
| except Exception as e: | |
| print(f"β Distance test failed: {e}") | |
| return False | |
| def test_surf_evaluation(): | |
| """Test basic surf evaluation logic""" | |
| print("\nπββοΈ Testing Surf Evaluation Logic...") | |
| try: | |
| # Sample spot data | |
| spot = { | |
| "name": "Tarifa", | |
| "optimal_conditions": { | |
| "swell_direction": [180, 270], | |
| "wind_direction": [90, 180], | |
| "min_wave_height": 0.5, | |
| "max_wave_height": 4.0 | |
| }, | |
| "characteristics": { | |
| "skill_level": ["beginner", "intermediate", "advanced"] | |
| } | |
| } | |
| # Sample conditions | |
| conditions = { | |
| "wave_height": 1.5, | |
| "wind_speed": 10, | |
| "wind_direction": 135, | |
| "swell_direction": 225 | |
| } | |
| # Simple scoring logic | |
| score = 0 | |
| explanation = [] | |
| # Wave height check | |
| if conditions["wave_height"] >= spot["optimal_conditions"]["min_wave_height"]: | |
| score += 25 | |
| explanation.append(f"β Wave height {conditions['wave_height']}m is suitable") | |
| # Wind speed check (prefer < 15kt) | |
| if conditions["wind_speed"] < 15: | |
| score += 20 | |
| explanation.append(f"β Wind speed {conditions['wind_speed']}kt is manageable") | |
| # Basic direction checks | |
| swell_dir = conditions["swell_direction"] | |
| opt_swell = spot["optimal_conditions"]["swell_direction"] | |
| if opt_swell[0] <= swell_dir <= opt_swell[1]: | |
| score += 30 | |
| explanation.append(f"β Swell direction {swell_dir}Β° is optimal") | |
| wind_dir = conditions["wind_direction"] | |
| opt_wind = spot["optimal_conditions"]["wind_direction"] | |
| if opt_wind[0] <= wind_dir <= opt_wind[1]: | |
| score += 25 | |
| explanation.append(f"β Wind direction {wind_dir}Β° is favorable") | |
| print(f" π {spot['name']} Score: {score}/100") | |
| for exp in explanation: | |
| print(f" {exp}") | |
| return score > 50 | |
| except Exception as e: | |
| print(f"β Evaluation test failed: {e}") | |
| return False | |
| # Note: Advanced evaluation test with async removed for now | |
| # Will test this as part of integration testing | |
| def main(): | |
| """Run all tests""" | |
| print("π Surf Spot Finder - Component Tests") | |
| print("=" * 50) | |
| # Run tests | |
| spots = test_database() | |
| geocoding_ok = test_geocoding() | |
| distance_ok = test_distance_calculation() | |
| evaluation_ok = test_surf_evaluation() | |
| # Summary | |
| print("\n" + "=" * 50) | |
| print("π Test Summary:") | |
| print(f" Database: {'β ' if spots else 'β'}") | |
| print(f" Geocoding: {'β ' if geocoding_ok else 'β'}") | |
| print(f" Distance: {'β ' if distance_ok else 'β'}") | |
| print(f" Basic Evaluation: {'β ' if evaluation_ok else 'β'}") | |
| all_passed = spots and geocoding_ok and distance_ok and evaluation_ok | |
| if all_passed: | |
| print("\nπ All basic components working!") | |
| print("π Next steps:") | |
| print(" 1. Test API integration (Stormglass)") | |
| print(" 2. Test complete workflow") | |
| print(" 3. Add LLM integration") | |
| else: | |
| print("\nβ οΈ Some tests failed. Fix issues before proceeding.") | |
| return all_passed | |
| if __name__ == "__main__": | |
| main() |