illuscape/tests/test_merge_prefs.py

140 lines
5.5 KiB
Python

"""Tests for scripts/merge_prefs.py"""
import shutil
import sys
from pathlib import Path
from xml.etree import ElementTree as ET
import pytest
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
import merge_prefs
FIXTURES = Path(__file__).parent / "fixtures"
def _parse(path: Path) -> ET.Element:
return ET.parse(path).getroot()
def _attr(root: ET.Element, *id_path: str) -> dict:
"""Walk id_path through nested <group id=...> elements, return attribs."""
node = root
for id_val in id_path:
node = next(
(c for c in node if c.get("id") == id_val), None
)
assert node is not None, f"Node with id={id_val!r} not found"
return dict(node.attrib)
# ── merge into existing prefs ─────────────────────────────────────────────────
def test_merge_changes_patched_attributes(tmp_path):
prefs = tmp_path / "preferences.xml"
shutil.copy(FIXTURES / "prefs-fresh.xml", prefs)
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cc")
root = _parse(prefs)
assert _attr(root, "options", "scroll")["mousewheel-zoom"] == "false"
assert _attr(root, "options", "zoom")["mousewheel-zoom-ctrl"] == "true"
assert _attr(root, "tools", "nodes")["square-handles"] == "true"
def test_merge_creates_missing_nodes(tmp_path):
prefs = tmp_path / "preferences.xml"
shutil.copy(FIXTURES / "prefs-fresh.xml", prefs)
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cc")
root = _parse(prefs)
assert _attr(root, "options", "new-group")["new-attr"] == "new-value"
def test_merge_preserves_user_nodes(tmp_path):
prefs = tmp_path / "preferences.xml"
shutil.copy(FIXTURES / "prefs-user-custom.xml", prefs)
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cc")
root = _parse(prefs)
assert _attr(root, "options", "user-custom-setting")["my-value"] == "keep-this"
assert _attr(root, "tools", "user-tool-pref")["color"] == "#ff0000"
def test_merge_preserves_existing_unknown_attributes(tmp_path):
prefs = tmp_path / "preferences.xml"
shutil.copy(FIXTURES / "prefs-user-custom.xml", prefs)
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cc")
root = _parse(prefs)
assert _attr(root, "tools", "nodes").get("user-pref") == "preserved"
def test_merge_is_idempotent(tmp_path):
prefs = tmp_path / "preferences.xml"
shutil.copy(FIXTURES / "prefs-fresh.xml", prefs)
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cc")
content_after_first = prefs.read_text()
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cc")
content_after_second = prefs.read_text()
assert content_after_first == content_after_second
# ── lenient: no prefs file ────────────────────────────────────────────────────
def test_merge_creates_prefs_when_missing(tmp_path):
prefs = tmp_path / "inkscape" / "preferences.xml"
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cc")
assert prefs.exists()
root = _parse(prefs)
assert _attr(root, "options", "scroll")["mousewheel-zoom"] == "false"
def test_merge_creates_parent_dirs_when_missing(tmp_path):
prefs = tmp_path / "deep" / "nested" / "dir" / "preferences.xml"
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cc")
assert prefs.exists()
# ── preset overrides ──────────────────────────────────────────────────────────
def test_preset_cc_sets_keys_file(tmp_path):
prefs = tmp_path / "preferences.xml"
shutil.copy(FIXTURES / "prefs-fresh.xml", prefs)
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cc")
root = _parse(prefs)
assert _attr(root, "options", "keyboard")["file"] == "illustrator-cc"
def test_preset_cs6_sets_keys_file(tmp_path):
prefs = tmp_path / "preferences.xml"
shutil.copy(FIXTURES / "prefs-fresh.xml", prefs)
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cs6")
root = _parse(prefs)
assert _attr(root, "options", "keyboard")["file"] == "illustrator-cs6"
def test_preset_cc_sets_px_units(tmp_path):
prefs = tmp_path / "preferences.xml"
shutil.copy(FIXTURES / "prefs-fresh.xml", prefs)
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cc")
root = _parse(prefs)
assert _attr(root, "options", "units")["doc"] == "px"
def test_preset_cs6_sets_pt_units(tmp_path):
prefs = tmp_path / "preferences.xml"
shutil.copy(FIXTURES / "prefs-fresh.xml", prefs)
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cs6")
root = _parse(prefs)
assert _attr(root, "options", "units")["doc"] == "pt"
# ── error handling ────────────────────────────────────────────────────────────
def test_merge_raises_on_malformed_prefs(tmp_path):
prefs = tmp_path / "preferences.xml"
prefs.write_text("this is not xml")
with pytest.raises(ET.ParseError):
merge_prefs.merge(prefs, FIXTURES / "patch-minimal.xml", "cc")
def test_merge_raises_on_missing_patch(tmp_path):
prefs = tmp_path / "preferences.xml"
shutil.copy(FIXTURES / "prefs-fresh.xml", prefs)
with pytest.raises(FileNotFoundError):
merge_prefs.merge(prefs, tmp_path / "nonexistent-patch.xml", "cc")