"""Tests for flow.commands.dotfiles discovery and path resolution.""" import pytest from flow.commands.dotfiles import _discover_packages, _resolve_edit_target, _walk_package def _make_tree(tmp_path): flow_root = tmp_path shared = flow_root / "_shared" (shared / "zsh").mkdir(parents=True) (shared / "zsh" / ".zshrc").write_text("# zsh") (shared / "tmux").mkdir(parents=True) (shared / "tmux" / ".tmux.conf").write_text("# tmux") profile = flow_root / "work" (profile / "git").mkdir(parents=True) (profile / "git" / ".gitconfig").write_text("[user]\nname = Work") return tmp_path def test_discover_packages_shared_only(tmp_path): tree = _make_tree(tmp_path) packages = _discover_packages(tree) assert "zsh" in packages assert "tmux" in packages assert "git" not in packages def test_discover_packages_with_profile(tmp_path): tree = _make_tree(tmp_path) packages = _discover_packages(tree, profile="work") assert "zsh" in packages assert "tmux" in packages assert "git" in packages def test_discover_packages_profile_overrides_shared(tmp_path): tree = _make_tree(tmp_path) profile_zsh = tree / "work" / "zsh" profile_zsh.mkdir(parents=True) (profile_zsh / ".zshrc").write_text("# work zsh") with pytest.raises(RuntimeError, match="Conflicting dotfile targets"): from flow.commands.dotfiles import _collect_home_specs _collect_home_specs(tree, tmp_path / "home", "work", set(), None) def test_walk_package_returns_relative_paths(tmp_path): tree = _make_tree(tmp_path) source = tree / "_shared" / "zsh" pairs = list(_walk_package(source)) assert len(pairs) == 1 src, rel = pairs[0] assert src.name == ".zshrc" assert str(rel) == ".zshrc" def test_resolve_edit_target_package(tmp_path): tree = _make_tree(tmp_path) target = _resolve_edit_target("zsh", dotfiles_dir=tree) assert target == tree / "_shared" / "zsh" def test_resolve_edit_target_repo_path(tmp_path): tree = _make_tree(tmp_path) target = _resolve_edit_target("_shared/zsh/.zshrc", dotfiles_dir=tree) assert target == tree / "_shared" / "zsh" / ".zshrc" def test_resolve_edit_target_missing_returns_none(tmp_path): tree = _make_tree(tmp_path) assert _resolve_edit_target("does-not-exist", dotfiles_dir=tree) is None