Files
MeshTerm/tests/conftest.py
T
Jean-Pierre MartineauandClaude Opus 5 f22ffa5011 Chat: a sender label is a name drawn as a path line's chip
A name standing alone above its messages was a coloured word with nothing
to say it was a label — at a glance it read like something someone typed.
It now sits in a chip, and not a chip of its own invention: ui/widgets.
name_chip builds a one-hop PathLine and asks it for its line, so the fill,
the ink, the padding, the rounded cap and the closing point are whatever a
route's segments are wearing today and cannot drift from them. A sender
wears exactly what that node wears as a hop — hue in the fill under dark
ink, the keyless grey where no key places them, and our own messages
headed by the ★ on its neutral grey rather than by the word "you".

Only the group header. An @mention inside a body is part of what was said,
and framing it would put a chip in the middle of a sentence.

Degrading comes free with the borrowing: where the terminal can't draw
separators — the PicoCalc console among them — a path line is arrow text
and one hop is just the name in its hue, which is what a sender label was
before it was framed. The specimen card grows a chips row, which doubles
as a one-hop sample of the route language.

And the unknown sender takes node.unknown rather than muted: one hex apart
here, a whole slot apart on the console, and an unidentified sender is
content you can still act on, not chrome.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-13 00:58:52 -04:00

86 lines
3.5 KiB
Python

"""Shared fixtures and helpers: plain-text screen reading, and pinned path rendering.
:func:`plain` is THE way a test reads a rendered screen — every screen test needs the
same move (strip the ANSI colour escapes, join the rendered lines) before it can assert
on content, and each file re-deriving it is how the copies drift.
The powerline verdict is environmental — the suite may run inside VS Code or Windows
Terminal (both chip-capable) or a bare CI shell (not) — and screen assertions must
not change with the developer's glass. ``MESHTERM_POWERLINE=0`` is the supported pin;
the cached verdict is cleared around each test so no ordering leaks it. Powerline-
specific tests pass explicit modes or monkeypatch the widget's own switch.
``NO_COLOR`` is environmental the same way: Rich honours it by stripping colour while
keeping attributes, which silently voids every colour assertion in the suite (a shell
run by an agent harness sets it). The autouse fixture below deletes it, so the tests
always see the colours the app really emits.
"""
from __future__ import annotations
import re
from typing import Callable, Iterable, Iterator, Union
import pytest
from meshterm.platforms import REGULAR, set_platform
from meshterm.ui.termfont import powerline_support
#: ANSI SGR escapes — the colour runs a rendered line carries between its characters.
_ANSI = re.compile(r"\x1b\[[0-9;]*m")
def plain(rendered: Union[str, Iterable[str]]) -> str:
"""The plain-text form of rendered screen output, for content assertions.
Takes what a render handed back — a list of ANSI lines (joined with newlines) or a
single already-joined string — and strips the colour escapes, so assertions read
the screen the way a viewer does.
"""
if not isinstance(rendered, str):
rendered = "\n".join(rendered)
return _ANSI.sub("", rendered)
@pytest.fixture(autouse=True)
def _plain_path_rendering(monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
monkeypatch.setenv("MESHTERM_POWERLINE", "0")
# An inherited NO_COLOR makes Rich strip colour (attributes kept) and every colour
# assertion silently reads bare text — see the module docstring.
monkeypatch.delenv("NO_COLOR", raising=False)
powerline_support.cache_clear()
yield
powerline_support.cache_clear()
@pytest.fixture
def powerline(monkeypatch: pytest.MonkeyPatch) -> Callable[[bool], None]:
"""Pin the powerline verdict for a test that is *about* chips.
The suite runs with ``MESHTERM_POWERLINE=0`` so screen assertions don't change with
the developer's glass (see the module docstring); a test of the chip language itself
needs the other answer, and asks for it through the supported override rather than by
reaching into the widget. ``monkeypatch`` restores the env and the autouse fixture
above clears the memoized verdict either side, so nothing leaks.
"""
def _set(on: bool) -> None:
monkeypatch.setenv("MESHTERM_POWERLINE", "1" if on else "0")
powerline_support.cache_clear()
return _set
@pytest.fixture(autouse=True)
def _reset_platform() -> Iterator[None]:
"""Every test starts and ends on :data:`~meshterm.platforms.REGULAR`.
A test that calls ``set_platform(PICOCALC)`` (directly, or via the gallery harness)
can't leak that choice into whatever runs next — regular is the suite's baseline, the
same way it is the default for a process that never passes ``--platform``/
``MESHTERM_PLATFORM`` (see :mod:`meshterm.platforms`).
"""
set_platform(REGULAR)
yield
set_platform(REGULAR)