"""Tests for dependency resolver."""
|
|
import pytest
|
from unittest.mock import AsyncMock, patch
|
|
from archrepobuild.resolver import DependencyResolver, Dependency, DependencyType, BuildOrder
|
|
|
class TestDependency:
|
"""Tests for Dependency class."""
|
|
def test_parse_simple(self):
|
"""Test parsing simple dependency name."""
|
dep = Dependency.parse("packagename")
|
assert dep.name == "packagename"
|
assert dep.version_constraint is None
|
assert dep.dep_type == DependencyType.RUNTIME
|
|
def test_parse_with_gte(self):
|
"""Test parsing with >= constraint."""
|
dep = Dependency.parse("package>=1.0")
|
assert dep.name == "package"
|
assert dep.version_constraint == ">=1.0"
|
|
def test_parse_with_lte(self):
|
"""Test parsing with <= constraint."""
|
dep = Dependency.parse("package<=2.0")
|
assert dep.name == "package"
|
assert dep.version_constraint == "<=2.0"
|
|
def test_parse_build_dep(self):
|
"""Test parsing as build dependency."""
|
dep = Dependency.parse("makedep", DependencyType.BUILD)
|
assert dep.dep_type == DependencyType.BUILD
|
|
|
class TestBuildOrder:
|
"""Tests for BuildOrder class."""
|
|
def test_iteration(self):
|
"""Test BuildOrder iteration."""
|
order = BuildOrder(packages=["a", "b", "c"])
|
assert list(order) == ["a", "b", "c"]
|
|
def test_length(self):
|
"""Test BuildOrder length."""
|
order = BuildOrder(packages=["a", "b"])
|
assert len(order) == 2
|
|
|
class TestDependencyResolver:
|
"""Tests for DependencyResolver."""
|
|
@pytest.fixture
|
def mock_aur_client(self):
|
"""Create mock AUR client."""
|
client = AsyncMock()
|
return client
|
|
def test_topological_sort_simple(self, mock_aur_client):
|
"""Test topological sort with simple graph."""
|
resolver = DependencyResolver(mock_aur_client)
|
|
# A depends on B, B depends on C
|
graph = {
|
"A": {"B"},
|
"B": {"C"},
|
"C": set(),
|
}
|
|
order = resolver._topological_sort(graph)
|
|
# C must come before B, B must come before A
|
assert order.index("C") < order.index("B")
|
assert order.index("B") < order.index("A")
|
|
def test_topological_sort_parallel(self, mock_aur_client):
|
"""Test topological sort with parallel dependencies."""
|
resolver = DependencyResolver(mock_aur_client)
|
|
# A depends on B and C (parallel)
|
graph = {
|
"A": {"B", "C"},
|
"B": set(),
|
"C": set(),
|
}
|
|
order = resolver._topological_sort(graph)
|
|
# B and C must come before A
|
assert order.index("B") < order.index("A")
|
assert order.index("C") < order.index("A")
|
|
def test_detect_cycles_no_cycle(self, mock_aur_client):
|
"""Test cycle detection with no cycles."""
|
resolver = DependencyResolver(mock_aur_client)
|
|
graph = {
|
"A": {"B"},
|
"B": {"C"},
|
"C": set(),
|
}
|
|
cycles = resolver.detect_cycles(graph)
|
assert len(cycles) == 0
|
|
def test_detect_cycles_with_cycle(self, mock_aur_client):
|
"""Test cycle detection with cycle."""
|
resolver = DependencyResolver(mock_aur_client)
|
|
# A -> B -> C -> A (cycle)
|
graph = {
|
"A": {"B"},
|
"B": {"C"},
|
"C": {"A"},
|
}
|
|
cycles = resolver.detect_cycles(graph)
|
assert len(cycles) > 0
|
|
@patch("archrepobuild.resolver.subprocess.run")
|
def test_is_in_official_repos(self, mock_run, mock_aur_client):
|
"""Test checking official repos."""
|
mock_run.return_value.returncode = 0
|
mock_run.return_value.stdout = "base\ngit\nvim\n"
|
|
resolver = DependencyResolver(mock_aur_client)
|
resolver._refresh_pacman_cache()
|
|
assert resolver.is_in_official_repos("git")
|
assert not resolver.is_in_official_repos("yay")
|