import logging import sys import hqt.logging as hqt_logging from hqt.config import Settings def test_setup_logging_does_not_write_to_terminal(tmp_path, monkeypatch): """setup_logging must NOT attach a StreamHandler that writes to the real terminal stderr/stdout. The TUI is a Textual app that paints to sys.__stderr__. A root-logger StreamHandler bound to that same fd writes raw log lines straight onto the pane Textual owns, corrupting tmux's grid — visible as rendering artifacts when switching back to the hqt window. Logs must go to file only. """ settings = Settings(db_path=tmp_path / "hqt.db") monkeypatch.setattr(hqt_logging, "get_settings", lambda: settings) root = logging.getLogger() saved_handlers = root.handlers[:] saved_level = root.level try: root.handlers.clear() hqt_logging.setup_logging() terminal_streams = {sys.stderr, sys.__stderr__, sys.stdout, sys.__stdout__} offending = [ h for h in root.handlers # FileHandler subclasses StreamHandler but writes to a file, not the terminal. if type(h) is logging.StreamHandler and getattr(h, "stream", None) in terminal_streams ] assert not offending, ( f"setup_logging attached a terminal StreamHandler: {offending}" ) # Logs are still captured to a file. assert any(isinstance(h, logging.FileHandler) for h in root.handlers) finally: root.handlers[:] = saved_handlers root.setLevel(saved_level)