"""Portable local-launcher rendering and filesystem contracts.""" from __future__ import annotations import sys from types import SimpleNamespace from unittest.mock import Mock, mock_open from obliteratus import local_ui class _EncodingOnlyStdout: def __init__(self, encoding: str | None) -> None: self.encoding = encoding def test_local_ui_banner_degrades_to_ascii_on_cp1252(monkeypatch): monkeypatch.setattr(local_ui.sys, "stdout", _EncodingOnlyStdout("cp1252")) banner = local_ui._banner_for_console() assert "OBLITERATUS" in banner assert banner.isascii() def test_local_ui_banner_keeps_block_art_on_utf8(monkeypatch): monkeypatch.setattr(local_ui.sys, "stdout", _EncodingOnlyStdout("utf-8")) assert "░" in local_ui._banner_for_console() def test_system_info_queries_the_platform_temp_directory(monkeypatch, tmp_path): disk_free = Mock(return_value=12.5) monkeypatch.setattr(local_ui.tempfile, "gettempdir", lambda: str(tmp_path)) monkeypatch.setattr(local_ui, "_get_disk_free_gb", disk_free) monkeypatch.setattr(local_ui, "console", Mock()) local_ui._print_system_info([]) disk_free.assert_called_once_with(str(tmp_path)) def test_ram_detection_falls_back_from_broken_psutil_to_proc(monkeypatch): broken_psutil = SimpleNamespace( virtual_memory=Mock(side_effect=OSError("unavailable")), ) monkeypatch.setitem(sys.modules, "psutil", broken_psutil) monkeypatch.setattr( "builtins.open", mock_open(read_data="MemTotal: 2097152 kB\n"), ) assert local_ui._get_ram_gb() == 2.0 def test_ram_detection_uses_posix_sysconf_without_psutil_or_proc(monkeypatch): monkeypatch.setitem(sys.modules, "psutil", None) monkeypatch.setattr("builtins.open", Mock(side_effect=OSError("no procfs"))) values = {"SC_PHYS_PAGES": 1_048_576, "SC_PAGE_SIZE": 4096} sysconf = Mock(side_effect=values.__getitem__) monkeypatch.setattr(local_ui.os, "sysconf", sysconf) assert local_ui._get_ram_gb() == 4.0 assert [call.args[0] for call in sysconf.call_args_list] == [ "SC_PHYS_PAGES", "SC_PAGE_SIZE", ] def test_ram_detection_fails_closed_when_all_probes_are_unavailable(monkeypatch): monkeypatch.setitem(sys.modules, "psutil", None) monkeypatch.setattr("builtins.open", Mock(side_effect=OSError("no procfs"))) monkeypatch.setattr(local_ui.os, "sysconf", Mock(side_effect=OSError("unsupported"))) assert local_ui._get_ram_gb() == 0.0