Files
flow/tests/test_dotfiles_folding.py
2026-02-13 12:15:46 +02:00

95 lines
3.0 KiB
Python

"""Tests for flat-layout dotfiles helpers and state format."""
import json
from pathlib import Path
import pytest
from flow.commands.dotfiles import (
LinkSpec,
_collect_home_specs,
_collect_root_specs,
_list_profiles,
_load_link_specs_from_state,
_save_link_specs_to_state,
)
def _make_flow_tree(tmp_path: Path) -> Path:
flow_root = tmp_path
(flow_root / "_shared" / "git").mkdir(parents=True)
(flow_root / "_shared" / "git" / ".gitconfig").write_text("shared")
(flow_root / "_shared" / "tmux").mkdir(parents=True)
(flow_root / "_shared" / "tmux" / ".tmux.conf").write_text("tmux")
(flow_root / "work" / "git").mkdir(parents=True)
(flow_root / "work" / "git" / ".gitconfig").write_text("profile")
(flow_root / "work" / "nvim").mkdir(parents=True)
(flow_root / "work" / "nvim" / ".config" / "nvim").mkdir(parents=True)
(flow_root / "work" / "nvim" / ".config" / "nvim" / "init.lua").write_text("-- init")
(flow_root / "_root" / "general" / "etc").mkdir(parents=True)
(flow_root / "_root" / "general" / "etc" / "hostname").write_text("devbox")
return flow_root
def test_list_profiles_ignores_reserved_dirs(tmp_path):
flow_root = _make_flow_tree(tmp_path)
profiles = _list_profiles(flow_root)
assert profiles == ["work"]
def test_collect_home_specs_conflict_fails(tmp_path):
flow_root = _make_flow_tree(tmp_path)
home = tmp_path / "home"
home.mkdir()
with pytest.raises(RuntimeError, match="Conflicting dotfile targets"):
_collect_home_specs(flow_root, home, "work", set(), None)
def test_collect_root_specs_maps_to_absolute_paths(tmp_path):
flow_root = _make_flow_tree(tmp_path)
specs = _collect_root_specs(flow_root, set(), include_root=True)
assert Path("/etc/hostname") in specs
assert specs[Path("/etc/hostname")].package == "_root/general"
def test_state_round_trip(tmp_path, monkeypatch):
state_file = tmp_path / "linked.json"
monkeypatch.setattr("flow.commands.dotfiles.LINKED_STATE", state_file)
specs = {
Path("/home/user/.gitconfig"): LinkSpec(
source=Path("/repo/_shared/git/.gitconfig"),
target=Path("/home/user/.gitconfig"),
package="_shared/git",
)
}
_save_link_specs_to_state(specs)
loaded = _load_link_specs_from_state()
assert Path("/home/user/.gitconfig") in loaded
assert loaded[Path("/home/user/.gitconfig")].package == "_shared/git"
def test_state_old_format_rejected(tmp_path, monkeypatch):
state_file = tmp_path / "linked.json"
monkeypatch.setattr("flow.commands.dotfiles.LINKED_STATE", state_file)
state_file.write_text(
json.dumps(
{
"links": {
"zsh": {
"/home/user/.zshrc": "/repo/.zshrc",
}
}
}
)
)
with pytest.raises(RuntimeError, match="Unsupported linked state format"):
_load_link_specs_from_state()