"""Tests for DebugLogger (backend/managers/debug_logger.py).""" import sys from pathlib import Path import pytest sys.path.insert(0, str(Path(__file__).parent.parent)) from backend.managers.debug_logger import DebugLogger # ── Fixtures ────────────────────────────────────────────────────────────────── @pytest.fixture def logger(): return DebugLogger() # ── Initialization ──────────────────────────────────────────────────────────── class TestInit: def test_logs_start_empty(self, logger): assert logger.logs == [] # ── log() ───────────────────────────────────────────────────────────────────── class TestLog: def test_log_appends_entry(self, logger): logger.log("started") assert len(logger.logs) == 1 def test_log_sets_level_info(self, logger): logger.log("started") assert logger.logs[0]["level"] == "INFO" def test_log_stores_message(self, logger): logger.log("executing file.py") assert logger.logs[0]["message"] == "executing file.py" def test_log_adds_timestamp(self, logger): logger.log("started") ts = logger.logs[0]["timestamp"] # HH:MM:SS format — exactly 8 chars with two colons assert len(ts) == 8 assert ts[2] == ":" and ts[5] == ":" # ── log_error() ─────────────────────────────────────────────────────────────── class TestLogError: def test_log_error_appends_entry(self, logger): logger.log_error("something broke") assert len(logger.logs) == 1 def test_log_error_sets_level_error(self, logger): logger.log_error("something broke") assert logger.logs[0]["level"] == "ERROR" def test_log_error_stores_message(self, logger): logger.log_error("exit code 1") assert logger.logs[0]["message"] == "exit code 1" def test_log_and_log_error_are_distinct_levels(self, logger): logger.log("info message") logger.log_error("error message") assert logger.logs[0]["level"] == "INFO" assert logger.logs[1]["level"] == "ERROR" # ── get_logs() ──────────────────────────────────────────────────────────────── class TestGetLogs: def test_get_logs_returns_all_entries(self, logger): logger.log("first") logger.log_error("second") assert len(logger.get_logs()) == 2 def test_get_logs_returns_internal_list(self, logger): assert logger.get_logs() is logger.logs # ── clear() ─────────────────────────────────────────────────────────────────── class TestClear: def test_clear_removes_all_entries(self, logger): logger.log("first") logger.log_error("second") logger.clear() assert logger.logs == [] def test_clear_on_empty_is_safe(self, logger): logger.clear() assert logger.logs == [] def test_log_after_clear_works(self, logger): logger.log("before") logger.clear() logger.log("after") assert len(logger.logs) == 1 assert logger.logs[0]["message"] == "after" # ── format_debug_output() ───────────────────────────────────────────────────── class TestFormatDebugOutput: def test_success_exit_code_shows_success(self, logger): result = logger.format_debug_output({"rc": 0, "stdout": "", "stderr": ""}) assert "[SUCCESS]" in result def test_nonzero_exit_code_shows_failed(self, logger): result = logger.format_debug_output({"rc": 1, "stdout": "", "stderr": ""}) assert "[FAILED]" in result def test_exit_code_included_in_output(self, logger): result = logger.format_debug_output({"rc": 42, "stdout": "", "stderr": ""}) assert "42" in result def test_stdout_included_when_present(self, logger): result = logger.format_debug_output({"rc": 0, "stdout": "Hello", "stderr": ""}) assert "Hello" in result assert "stdout" in result def test_stderr_included_when_present(self, logger): result = logger.format_debug_output({"rc": 1, "stdout": "", "stderr": "NameError"}) assert "NameError" in result assert "stderr" in result def test_no_output_message_when_both_empty(self, logger): result = logger.format_debug_output({"rc": 0, "stdout": "", "stderr": ""}) assert "No output produced." in result def test_log_entries_appended_to_output(self, logger): logger.log("Executing file.py...") logger.log_error("exit code 1") result = logger.format_debug_output({"rc": 1, "stdout": "", "stderr": ""}) assert "Executing file.py..." in result assert "exit code 1" in result def test_returns_string(self, logger): result = logger.format_debug_output({"rc": 0, "stdout": "", "stderr": ""}) assert isinstance(result, str) def test_missing_keys_do_not_raise(self, logger): # Defensive: format_debug_output uses .get() so missing keys are safe result = logger.format_debug_output({}) assert isinstance(result, str)