feat: add all domain layers (dotfiles, packages, remote, containers)
- Dotfiles: models, module resolution, path resolution, link planning - Packages: models, catalog parsing, resolution, install/remove planning - Remote: target parsing, SSH command building - Containers: image refs, mount resolution, container specs All domain code is pure functions + frozen dataclasses. 88 tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
187
tests/test_domain_packages.py
Normal file
187
tests/test_domain_packages.py
Normal file
@@ -0,0 +1,187 @@
|
||||
"""Tests for packages catalog and resolution."""
|
||||
|
||||
import pytest
|
||||
|
||||
from flow.core.errors import ConfigError, FlowError
|
||||
from flow.domain.packages.catalog import normalize_profile_entry, parse_catalog
|
||||
from flow.domain.packages.resolution import (
|
||||
detect_package_manager,
|
||||
pm_install_command,
|
||||
pm_update_command,
|
||||
resolve_binary_asset,
|
||||
resolve_download_url,
|
||||
resolve_source_name,
|
||||
resolve_spec,
|
||||
)
|
||||
from flow.domain.packages.models import PackageDef, ProfilePackageRef
|
||||
|
||||
|
||||
class TestParseCatalog:
|
||||
def test_list_format(self):
|
||||
manifest = {"packages": [
|
||||
{"name": "fd", "type": "pkg", "apt": "fd-find"},
|
||||
{"name": "ripgrep", "type": "pkg"},
|
||||
]}
|
||||
catalog = parse_catalog(manifest)
|
||||
assert "fd" in catalog
|
||||
assert catalog["fd"].sources.get("apt") == "fd-find"
|
||||
assert "ripgrep" in catalog
|
||||
|
||||
def test_dict_format(self):
|
||||
manifest = {"packages": {
|
||||
"fd": {"type": "pkg", "apt": "fd-find"},
|
||||
}}
|
||||
catalog = parse_catalog(manifest)
|
||||
assert "fd" in catalog
|
||||
assert catalog["fd"].type == "pkg"
|
||||
|
||||
def test_empty_manifest(self):
|
||||
assert parse_catalog({}) == {}
|
||||
|
||||
|
||||
class TestNormalizeProfileEntry:
|
||||
def test_string_shorthand_with_type(self):
|
||||
ref = normalize_profile_entry("binary/neovim")
|
||||
assert ref.name == "neovim"
|
||||
assert ref.type == "binary"
|
||||
|
||||
def test_plain_name(self):
|
||||
ref = normalize_profile_entry("fd")
|
||||
assert ref.name == "fd"
|
||||
assert ref.type is None
|
||||
|
||||
def test_dict_entry(self):
|
||||
ref = normalize_profile_entry({"name": "nvim", "type": "binary", "version": "0.10"})
|
||||
assert ref.name == "nvim"
|
||||
assert ref.type == "binary"
|
||||
assert ref.version == "0.10"
|
||||
|
||||
|
||||
class TestResolveSpec:
|
||||
def test_merge_with_catalog(self):
|
||||
catalog = {"fd": PackageDef(
|
||||
name="fd", type="pkg", sources={"apt": "fd-find"},
|
||||
source=None, version=None, asset_pattern=None,
|
||||
platform_map={}, extract_dir=None, install={},
|
||||
post_install=None, allow_sudo=False,
|
||||
)}
|
||||
ref = ProfilePackageRef(name="fd", type=None, source=None, version="1.0", asset_pattern=None)
|
||||
result = resolve_spec(ref, catalog)
|
||||
assert result.type == "pkg" # from catalog
|
||||
assert result.version == "1.0" # from profile
|
||||
assert result.sources == {"apt": "fd-find"} # from catalog
|
||||
|
||||
def test_not_in_catalog(self):
|
||||
ref = ProfilePackageRef(name="unknown", type="binary", source="github:u/r", version=None, asset_pattern=None)
|
||||
result = resolve_spec(ref, {})
|
||||
assert result.name == "unknown"
|
||||
assert result.type == "binary"
|
||||
|
||||
|
||||
class TestResolveSourceName:
|
||||
def test_with_pm_mapping(self):
|
||||
pkg = PackageDef(
|
||||
name="fd", type="pkg", sources={"apt": "fd-find"},
|
||||
source=None, version=None, asset_pattern=None,
|
||||
platform_map={}, extract_dir=None, install={},
|
||||
post_install=None, allow_sudo=False,
|
||||
)
|
||||
assert resolve_source_name(pkg, "apt") == "fd-find"
|
||||
|
||||
def test_fallback_to_name(self):
|
||||
pkg = PackageDef(
|
||||
name="fd", type="pkg", sources={},
|
||||
source=None, version=None, asset_pattern=None,
|
||||
platform_map={}, extract_dir=None, install={},
|
||||
post_install=None, allow_sudo=False,
|
||||
)
|
||||
assert resolve_source_name(pkg, "apt") == "fd"
|
||||
|
||||
|
||||
class TestResolveBinaryAsset:
|
||||
def test_platform_map(self):
|
||||
pkg = PackageDef(
|
||||
name="nvim", type="binary", sources={},
|
||||
source="github:neovim/neovim",
|
||||
version="v0.10.4",
|
||||
asset_pattern=None,
|
||||
platform_map={"linux-x64": "nvim-linux-x86_64.tar.gz"},
|
||||
extract_dir=None, install={},
|
||||
post_install=None, allow_sudo=False,
|
||||
)
|
||||
assert resolve_binary_asset(pkg, "linux-x64") == "nvim-linux-x86_64.tar.gz"
|
||||
|
||||
def test_asset_pattern(self):
|
||||
pkg = PackageDef(
|
||||
name="fd", type="binary", sources={},
|
||||
source="github:sharkdp/fd",
|
||||
version="v10.2.0",
|
||||
asset_pattern="fd-v10.2.0-{arch}-unknown-{os}-gnu.tar.gz",
|
||||
platform_map={},
|
||||
extract_dir=None, install={},
|
||||
post_install=None, allow_sudo=False,
|
||||
)
|
||||
result = resolve_binary_asset(pkg, "linux-x64")
|
||||
assert "x64" in result
|
||||
assert "linux" in result
|
||||
|
||||
|
||||
class TestResolveDownloadUrl:
|
||||
def test_github_shorthand_with_version(self):
|
||||
pkg = PackageDef(
|
||||
name="nvim", type="binary", sources={},
|
||||
source="github:neovim/neovim",
|
||||
version="v0.10.4",
|
||||
asset_pattern=None, platform_map={},
|
||||
extract_dir=None, install={},
|
||||
post_install=None, allow_sudo=False,
|
||||
)
|
||||
url = resolve_download_url(pkg, "nvim.tar.gz")
|
||||
assert "github.com/neovim/neovim" in url
|
||||
assert "v0.10.4" in url
|
||||
|
||||
def test_github_latest(self):
|
||||
pkg = PackageDef(
|
||||
name="nvim", type="binary", sources={},
|
||||
source="github:neovim/neovim",
|
||||
version=None,
|
||||
asset_pattern=None, platform_map={},
|
||||
extract_dir=None, install={},
|
||||
post_install=None, allow_sudo=False,
|
||||
)
|
||||
url = resolve_download_url(pkg, "nvim.tar.gz")
|
||||
assert "latest" in url
|
||||
|
||||
def test_direct_url(self):
|
||||
pkg = PackageDef(
|
||||
name="x", type="binary", sources={},
|
||||
source="https://example.com/download/",
|
||||
version=None,
|
||||
asset_pattern=None, platform_map={},
|
||||
extract_dir=None, install={},
|
||||
post_install=None, allow_sudo=False,
|
||||
)
|
||||
url = resolve_download_url(pkg, "x.tar.gz")
|
||||
assert url == "https://example.com/download/x.tar.gz"
|
||||
|
||||
|
||||
class TestPmCommands:
|
||||
def test_apt_update(self):
|
||||
assert "apt-get update" in pm_update_command("apt")
|
||||
|
||||
def test_dnf_update(self):
|
||||
assert "dnf" in pm_update_command("dnf")
|
||||
|
||||
def test_brew_install(self):
|
||||
cmd = pm_install_command("brew", ["fd", "rg"])
|
||||
assert "brew install" in cmd
|
||||
assert "fd" in cmd
|
||||
|
||||
def test_apt_install(self):
|
||||
cmd = pm_install_command("apt", ["fd-find"])
|
||||
assert "apt-get install" in cmd
|
||||
|
||||
def test_detect_package_manager_returns_something(self):
|
||||
# Just verify it doesn't error
|
||||
result = detect_package_manager()
|
||||
assert result is None or result in ("apt", "dnf", "brew")
|
||||
Reference in New Issue
Block a user