Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
"""`hermes skin set` — deterministic single-color tweak of the active skin.
|
||||
|
||||
The whole point is that changing one token never disturbs the rest of the look
|
||||
(background especially), which hand-authoring kept getting wrong.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
|
||||
from hermes_cli import skin_cmd
|
||||
from hermes_constants import get_hermes_home
|
||||
|
||||
|
||||
def _skins():
|
||||
d = get_hermes_home() / "skins"
|
||||
d.mkdir(parents=True, exist_ok=True)
|
||||
return d
|
||||
|
||||
|
||||
def _activate(name: str) -> None:
|
||||
(get_hermes_home() / "config.yaml").write_text(f"display:\n skin: {name}\n", encoding="utf-8")
|
||||
|
||||
|
||||
def test_set_edits_active_user_skin_in_place_preserving_everything_else():
|
||||
(_skins() / "oasis.yaml").write_text(
|
||||
'name: oasis\ncolors:\n background: "#08201f"\n banner_title: "#f2dfb3"\n', encoding="utf-8"
|
||||
)
|
||||
_activate("oasis")
|
||||
|
||||
assert skin_cmd._skin_set("ui_tool", "#00FFFF", None) == 0
|
||||
|
||||
data = yaml.safe_load((_skins() / "oasis.yaml").read_text())
|
||||
assert data["colors"]["ui_tool"] == "#00FFFF"
|
||||
assert data["colors"]["background"] == "#08201f" # untouched — the whole point
|
||||
assert data["colors"]["banner_title"] == "#f2dfb3"
|
||||
assert data["name"] == "oasis" # no rename, no fork
|
||||
assert not (_skins() / "oasis-custom.yaml").exists()
|
||||
|
||||
|
||||
def test_set_forks_a_builtin_without_inventing_a_background():
|
||||
_activate("default") # a built-in — no file
|
||||
|
||||
assert skin_cmd._skin_set("ui_tool", "#00FFFF", None) == 0
|
||||
|
||||
fork = _skins() / "default-custom.yaml"
|
||||
assert fork.exists()
|
||||
data = yaml.safe_load(fork.read_text())
|
||||
assert data["colors"]["ui_tool"] == "#00FFFF"
|
||||
# default has no background, so the fork must not invent one (terminal stays put).
|
||||
assert "background" not in data["colors"]
|
||||
# full palette carried over, and it became active.
|
||||
assert data["colors"].get("banner_title")
|
||||
assert (get_hermes_home() / "config.yaml").read_text().find("default-custom") != -1
|
||||
|
||||
|
||||
def test_set_rejects_non_hex():
|
||||
_activate("default")
|
||||
assert skin_cmd._skin_set("ui_tool", "teal", None) == 1
|
||||
|
||||
|
||||
def test_set_persists_the_skin_durably():
|
||||
"""The palette must reach disk before ``skin set`` returns.
|
||||
|
||||
``write_text`` truncates and writes without ever calling ``fsync``, so a
|
||||
power loss or container kill right after the command "succeeds" can leave
|
||||
``<skin>.yaml`` zero-length. That is not transient: ``_skin_set`` is a
|
||||
read-modify-write and ``safe_load("")`` returns ``None``, which its
|
||||
``or {}`` turns into an empty palette — so the next tweak rewrites the
|
||||
file from that empty state and the rest of the palette is gone for good.
|
||||
The gateway's skin watcher repaints every live surface from this file
|
||||
within ~1s either way.
|
||||
"""
|
||||
path = _skins() / "oasis.yaml"
|
||||
path.write_text(
|
||||
'name: oasis\ncolors:\n background: "#08201f"\n banner_title: "#f2dfb3"\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
_activate("oasis")
|
||||
|
||||
synced = []
|
||||
real_fsync = os.fsync
|
||||
|
||||
def _tracking_fsync(fd):
|
||||
synced.append(fd)
|
||||
return real_fsync(fd)
|
||||
|
||||
with pytest.MonkeyPatch.context() as mp:
|
||||
mp.setattr(os, "fsync", _tracking_fsync)
|
||||
assert skin_cmd._skin_set("ui_tool", "#00FFFF", None) == 0
|
||||
|
||||
assert synced, "skin file written without fsync — a crash can leave it empty"
|
||||
|
||||
data = yaml.safe_load(path.read_text(encoding="utf-8"))
|
||||
assert data["colors"]["ui_tool"] == "#00FFFF"
|
||||
assert data["colors"]["background"] == "#08201f" # untouched — the whole point
|
||||
assert data["colors"]["banner_title"] == "#f2dfb3"
|
||||
assert [p.name for p in _skins().iterdir() if p.name.endswith(".tmp")] == []
|
||||
|
||||
|
||||
def test_set_preserves_a_symlinked_skin_file():
|
||||
"""Guard on the conversion, not a behavior change.
|
||||
|
||||
``write_text`` wrote through a symlink; a naive ``os.replace`` would
|
||||
detach it. ``atomic_replace`` resolves the link first (GitHub #16743),
|
||||
so a skin file symlinked out to a dotfiles repo must stay a symlink.
|
||||
"""
|
||||
real_dir = _skins().parent / "dotfiles"
|
||||
real_dir.mkdir(parents=True, exist_ok=True)
|
||||
real = real_dir / "oasis.yaml"
|
||||
real.write_text(
|
||||
'name: oasis\ncolors:\n background: "#08201f"\n', encoding="utf-8"
|
||||
)
|
||||
link = _skins() / "oasis.yaml"
|
||||
link.symlink_to(real)
|
||||
_activate("oasis")
|
||||
|
||||
assert skin_cmd._skin_set("ui_tool", "#00FFFF", None) == 0
|
||||
|
||||
assert link.is_symlink()
|
||||
data = yaml.safe_load(real.read_text(encoding="utf-8"))
|
||||
assert data["colors"]["ui_tool"] == "#00FFFF"
|
||||
assert data["colors"]["background"] == "#08201f"
|
||||
Reference in New Issue
Block a user