pypi-query-mcp/test_core_only.py
Ryan Malloy 8b43927493 chore: upgrade all Python packages and fix linting issues
- Update all dependencies to latest versions (fastmcp, httpx, packaging, etc.)
- Downgrade click from yanked 8.2.2 to stable 8.1.7
- Fix code formatting and linting issues with ruff
- Most tests passing (2 test failures in dependency resolver need investigation)
2025-08-15 20:23:14 -06:00

244 lines
8.3 KiB
Python

#!/usr/bin/env python3
"""Test script to verify the version parameter fix - core functionality only."""
import asyncio
import logging
import os
import sys
# Add the project root to the Python path
sys.path.insert(0, os.path.dirname(__file__))
# Set up logging
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
async def test_pypi_client():
"""Test the PyPIClient with version-specific queries."""
# Import only the core modules we need
from pypi_query_mcp.core.exceptions import PackageNotFoundError
from pypi_query_mcp.core.pypi_client import PyPIClient
async with PyPIClient() as client:
# Test 1: Django 4.2.0 (specific version)
logger.info("Testing Django 4.2.0...")
try:
data = await client.get_package_info("django", version="4.2.0")
actual_version = data.get("info", {}).get("version", "")
if actual_version in ["4.2", "4.2.0"]: # PyPI may normalize version numbers
logger.info(
f"✅ Django 4.2.0 test passed (got version: {actual_version})"
)
else:
logger.error(f"❌ Expected version 4.2.0, got {actual_version}")
return False
# Check dependencies
deps = data.get("info", {}).get("requires_dist", [])
logger.info(f" Dependencies found: {len(deps) if deps else 0}")
except Exception as e:
logger.error(f"❌ Django 4.2.0 test failed: {e}")
return False
# Test 2: Latest Django (no version)
logger.info("Testing Django latest...")
try:
data = await client.get_package_info("django", version=None)
actual_version = data.get("info", {}).get("version", "")
logger.info(f"✅ Django latest test passed - version: {actual_version}")
except Exception as e:
logger.error(f"❌ Django latest test failed: {e}")
return False
# Test 3: Non-existent version (should fail)
logger.info("Testing Django 999.999.999 (should fail)...")
try:
data = await client.get_package_info("django", version="999.999.999")
logger.error("❌ Expected error for non-existent version but got result")
return False
except PackageNotFoundError:
logger.info("✅ Non-existent version test passed (correctly failed)")
except Exception as e:
logger.error(f"❌ Unexpected error type: {e}")
return False
# Test 4: FastAPI 0.100.0
logger.info("Testing FastAPI 0.100.0...")
try:
data = await client.get_package_info("fastapi", version="0.100.0")
actual_version = data.get("info", {}).get("version", "")
if actual_version == "0.100.0":
logger.info("✅ FastAPI 0.100.0 test passed")
else:
logger.error(f"❌ Expected version 0.100.0, got {actual_version}")
return False
except Exception as e:
logger.error(f"❌ FastAPI 0.100.0 test failed: {e}")
return False
# Test 5: NumPy 1.20.0
logger.info("Testing NumPy 1.20.0...")
try:
data = await client.get_package_info("numpy", version="1.20.0")
actual_version = data.get("info", {}).get("version", "")
if actual_version == "1.20.0":
logger.info("✅ NumPy 1.20.0 test passed")
else:
logger.error(f"❌ Expected version 1.20.0, got {actual_version}")
return False
except Exception as e:
logger.error(f"❌ NumPy 1.20.0 test failed: {e}")
return False
return True
async def test_dependency_formatting():
"""Test the dependency formatting functions."""
from pypi_query_mcp.tools.package_query import (
format_dependency_info,
validate_version_format,
)
# Test version validation
logger.info("Testing version validation...")
test_versions = [
("1.0.0", True),
("2.1", True),
("1.0.0a1", True),
("1.0.0b2", True),
("1.0.0rc1", True),
("2.0.0.dev1", True),
("invalid.version!", False),
("", False),
(None, True),
]
for version, expected in test_versions:
result = validate_version_format(version)
if result == expected:
logger.info(f"✅ Version validation for '{version}': {result}")
else:
logger.error(
f"❌ Version validation for '{version}': expected {expected}, got {result}"
)
return False
# Test dependency formatting with mock data
logger.info("Testing dependency formatting...")
mock_data = {
"info": {
"name": "test-package",
"version": "1.0.0",
"requires_python": ">=3.8",
"requires_dist": [
"requests>=2.25.0",
"click>=8.0.0",
"pytest>=6.0.0; extra=='test'",
"black>=21.0.0; extra=='dev'",
],
}
}
result = format_dependency_info(mock_data)
expected_fields = [
"package_name",
"version",
"runtime_dependencies",
"dependency_summary",
]
for field in expected_fields:
if field not in result:
logger.error(f"❌ Missing field '{field}' in dependency formatting result")
return False
if len(result["runtime_dependencies"]) >= 2: # Should have requests and click
logger.info("✅ Dependency formatting test passed")
else:
logger.error(
f"❌ Expected at least 2 runtime dependencies, got {len(result['runtime_dependencies'])}"
)
return False
return True
async def test_comparison():
"""Test that version-specific queries return different results than latest."""
from pypi_query_mcp.core.pypi_client import PyPIClient
logger.info("Testing that version-specific queries work differently than latest...")
async with PyPIClient() as client:
# Get Django latest
latest_data = await client.get_package_info("django", version=None)
latest_version = latest_data.get("info", {}).get("version", "")
# Get Django 4.2.0 specifically
specific_data = await client.get_package_info("django", version="4.2.0")
specific_version = specific_data.get("info", {}).get("version", "")
logger.info(f"Latest Django version: {latest_version}")
logger.info(f"Specific Django version: {specific_version}")
# They should be different (unless 4.2.0 happens to be latest, which is unlikely)
if specific_version in ["4.2", "4.2.0"] and latest_version != specific_version:
logger.info(
"✅ Version-specific query returns different version than latest"
)
return True
elif specific_version in ["4.2", "4.2.0"]:
logger.info(
"⚠️ Specific version matches latest (this is fine, but less conclusive)"
)
return True
else:
logger.error(
f"❌ Specific version query failed: expected 4.2.0, got {specific_version}"
)
return False
async def main():
"""Run all tests."""
logger.info("Starting PyPI client and dependency query tests...")
success = True
# Test PyPI client
if await test_pypi_client():
logger.info("✅ PyPI client tests passed")
else:
logger.error("❌ PyPI client tests failed")
success = False
# Test dependency formatting
if await test_dependency_formatting():
logger.info("✅ Dependency formatting tests passed")
else:
logger.error("❌ Dependency formatting tests failed")
success = False
# Test comparison
if await test_comparison():
logger.info("✅ Version comparison test passed")
else:
logger.error("❌ Version comparison test failed")
success = False
if success:
logger.info("🎉 All tests passed!")
return 0
else:
logger.error("❌ Some tests failed!")
return 1
if __name__ == "__main__":
exit_code = asyncio.run(main())
sys.exit(exit_code)