nightshift/tests/test_terminal.py
2026-05-17 18:17:59 -07:00

71 lines
2.5 KiB
Python

from io import StringIO
from pathlib import Path
import tempfile
import unittest
from unittest.mock import patch
from nightshift.artifacts import ArtifactStore
from nightshift.runlog import RunLogger
from nightshift.terminal import format_banner, format_console_event_line
class FakeTTY(StringIO):
def isatty(self) -> bool:
return True
class TerminalStylingTests(unittest.TestCase):
def test_banner_is_plain_without_tty(self) -> None:
banner = format_banner(stream=StringIO())
self.assertIn("NightShift", banner)
self.assertNotIn("\x1b[", banner)
def test_banner_uses_ansi_when_tty(self) -> None:
banner = format_banner(stream=FakeTTY())
self.assertIn("NightShift", banner)
self.assertIn("\x1b[", banner)
def test_console_event_line_colors_success_and_failure(self) -> None:
success = format_console_event_line(
"2026-05-17T00:00:00Z",
"task.finish",
"Finished task",
{"status": "complete"},
stream=FakeTTY(),
)
failure = format_console_event_line(
"2026-05-17T00:00:00Z",
"task.finish",
"Finished task",
{"status": "failed"},
stream=FakeTTY(),
)
self.assertIn("\x1b[32m", success)
self.assertIn("\x1b[31m", failure)
self.assertTrue(success.endswith("\x1b[0m"))
self.assertTrue(failure.endswith("\x1b[0m"))
def test_run_logger_console_output_is_separate_from_run_log(self) -> None:
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
artifacts = ArtifactStore(root, ".nightshift", run_id="test-run")
console_lines: list[str] = []
logger = RunLogger(console=console_lines.append)
logger.bind(artifacts)
with patch(
"nightshift.runlog.format_console_event_line",
return_value="\x1b[32mstyled line\x1b[0m",
):
logger.event("task.finish", "Finished task", status="complete", token="abc")
self.assertEqual(console_lines[-1], "\x1b[32mstyled line\x1b[0m")
run_log = artifacts.run_log_path.read_text(encoding="utf-8")
self.assertIn("task.finish", run_log)
self.assertIn("status=complete", run_log)
self.assertNotIn("\x1b[", run_log)
self.assertNotIn("abc", run_log)
if __name__ == "__main__":
unittest.main()