95 lines
3.0 KiB
Python
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()
|