"""Tests for flow.commands.dotfiles — link/unlink/status logic.""" import json from pathlib import Path from unittest.mock import MagicMock import pytest from flow.commands.dotfiles import _discover_packages, _walk_package from flow.core.config import AppConfig, FlowContext from flow.core.console import ConsoleLogger from flow.core.platform import PlatformInfo @pytest.fixture def dotfiles_tree(tmp_path): """Create a sample dotfiles directory structure.""" common = tmp_path / "common" (common / "zsh").mkdir(parents=True) (common / "zsh" / ".zshrc").write_text("# zshrc") (common / "zsh" / ".zshenv").write_text("# zshenv") (common / "tmux").mkdir(parents=True) (common / "tmux" / ".tmux.conf").write_text("# tmux") profiles = tmp_path / "profiles" / "work" (profiles / "git").mkdir(parents=True) (profiles / "git" / ".gitconfig").write_text("[user]\nname = Work") return tmp_path def test_discover_packages_common(dotfiles_tree): packages = _discover_packages(dotfiles_tree) assert "zsh" in packages assert "tmux" in packages assert "git" not in packages # git is only in profiles def test_discover_packages_with_profile(dotfiles_tree): packages = _discover_packages(dotfiles_tree, profile="work") assert "zsh" in packages assert "tmux" in packages assert "git" in packages def test_discover_packages_profile_overrides(dotfiles_tree): # Add zsh to work profile work_zsh = dotfiles_tree / "profiles" / "work" / "zsh" work_zsh.mkdir(parents=True) (work_zsh / ".zshrc").write_text("# work zshrc") packages = _discover_packages(dotfiles_tree, profile="work") # Profile should override common assert packages["zsh"] == work_zsh def test_walk_package(dotfiles_tree): home = Path("/tmp/fakehome") source = dotfiles_tree / "common" / "zsh" pairs = list(_walk_package(source, home)) assert len(pairs) == 2 sources = {str(s.name) for s, _ in pairs} assert ".zshrc" in sources assert ".zshenv" in sources targets = {str(t) for _, t in pairs} assert str(home / ".zshrc") in targets assert str(home / ".zshenv") in targets