106 lines
2.6 KiB
Python
106 lines
2.6 KiB
Python
|
|
"""Unit tests for the pypi-server.i80.dk catalog fetcher."""
|
||
|
|
|
||
|
|
import asyncio
|
||
|
|
from unittest.mock import patch
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
from ilsp.python_lsp.catalog import PypiCatalog
|
||
|
|
|
||
|
|
|
||
|
|
MOCK_HTML = """
|
||
|
|
<!DOCTYPE html>
|
||
|
|
<html><head><title>Simple Index</title></head>
|
||
|
|
<body>
|
||
|
|
<a href="/simple/azure-toolbox-database/">azure-toolbox-database</a>
|
||
|
|
<a href="/simple/devops-gitea-sdk/">devops-gitea-sdk</a>
|
||
|
|
<a href="/simple/toolbox-tests-framework/">toolbox-tests-framework</a>
|
||
|
|
</body></html>
|
||
|
|
"""
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture(autouse=True)
|
||
|
|
def reset_catalog():
|
||
|
|
PypiCatalog._packages = []
|
||
|
|
PypiCatalog._last_refresh = 0
|
||
|
|
yield
|
||
|
|
|
||
|
|
|
||
|
|
class _MockResponse:
|
||
|
|
def __init__(self, html: str):
|
||
|
|
self._html = html
|
||
|
|
self.status = 200
|
||
|
|
|
||
|
|
async def text(self):
|
||
|
|
return self._html
|
||
|
|
|
||
|
|
def raise_for_status(self):
|
||
|
|
pass
|
||
|
|
|
||
|
|
async def __aenter__(self):
|
||
|
|
return self
|
||
|
|
|
||
|
|
async def __aexit__(self, *_):
|
||
|
|
pass
|
||
|
|
|
||
|
|
|
||
|
|
class _MockSession:
|
||
|
|
def __init__(self, html: str):
|
||
|
|
self._html = html
|
||
|
|
|
||
|
|
def get(self, url):
|
||
|
|
return _MockResponse(self._html)
|
||
|
|
|
||
|
|
async def __aenter__(self):
|
||
|
|
return self
|
||
|
|
|
||
|
|
async def __aexit__(self, *_):
|
||
|
|
pass
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_fetch_parses_packages():
|
||
|
|
with patch("ilsp.python_lsp.catalog.aiohttp.ClientSession", return_value=_MockSession(MOCK_HTML)):
|
||
|
|
packages = await PypiCatalog._fetch()
|
||
|
|
|
||
|
|
assert len(packages) == 3
|
||
|
|
names = [p["name"] for p in packages]
|
||
|
|
assert "azure-toolbox-database" in names
|
||
|
|
assert "devops-gitea-sdk" in names
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_packages_have_sort_prefix():
|
||
|
|
with patch("ilsp.python_lsp.catalog.aiohttp.ClientSession", return_value=_MockSession(MOCK_HTML)):
|
||
|
|
packages = await PypiCatalog._fetch()
|
||
|
|
|
||
|
|
for pkg in packages:
|
||
|
|
assert pkg["sort_prefix"] == "0_i80_"
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_get_packages_triggers_refresh_when_empty():
|
||
|
|
with patch("ilsp.python_lsp.catalog.aiohttp.ClientSession", return_value=_MockSession(MOCK_HTML)):
|
||
|
|
packages = await PypiCatalog.get_packages()
|
||
|
|
|
||
|
|
assert len(packages) == 3
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_get_packages_uses_cache():
|
||
|
|
PypiCatalog._packages = [{"name": "cached-pkg", "sort_prefix": "0_i80_", "detail": "x"}]
|
||
|
|
PypiCatalog._last_refresh = 9_999_999_999
|
||
|
|
|
||
|
|
packages = await PypiCatalog.get_packages()
|
||
|
|
assert packages[0]["name"] == "cached-pkg"
|
||
|
|
|
||
|
|
|
||
|
|
def test_as_completion_items():
|
||
|
|
PypiCatalog._packages = [
|
||
|
|
{"name": "my-pkg", "detail": "i80", "sort_prefix": "0_i80_"},
|
||
|
|
]
|
||
|
|
items = PypiCatalog.as_completion_items()
|
||
|
|
assert len(items) == 1
|
||
|
|
assert items[0].label == "my-pkg"
|
||
|
|
assert items[0].sort_text == "0_i80_my-pkg"
|