diff options
| author | Duncan Ogilvie <mr.exodia.tpodt@gmail.com> | 2026-08-17 15:21:59 +0200 |
|---|---|---|
| committer | Duncan Ogilvie <mr.exodia.tpodt@gmail.com> | 2026-08-17 15:21:59 +0200 |
| commit | 61b93538fe6e03f175b907c19c2d196ecd860782 (patch) | |
| tree | 822b667f5b1a6ea5b8358e2bc473d0069b0d1402 /tests | |
| parent | docs: be honest that the triskel fork is unpublished (diff) | |
| download | ida-tui-61b93538fe6e03f175b907c19c2d196ecd860782.tar.gz ida-tui-61b93538fe6e03f175b907c19c2d196ecd860782.tar.xz ida-tui-61b93538fe6e03f175b907c19c2d196ecd860782.zip | |
Add kitty graphics fallback for Windows support
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_kittygfx.py | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/tests/test_kittygfx.py b/tests/test_kittygfx.py new file mode 100644 index 0000000..74b6bb7 --- /dev/null +++ b/tests/test_kittygfx.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +"""Cross-platform checks for the optional kitty-graphics startup splash. + +Pure: stdlib only, no terminal, Textual, Code Mode, or IDA. +""" +from __future__ import annotations + +import builtins +import os +import sys + +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +NEEDS_IDA = False + +from idatui import kittygfx # noqa: E402 + +PASS = FAIL = 0 + + +def check(name, ok, detail=""): + global PASS, FAIL + if ok: + PASS += 1 + print(f" ok {name}") + else: + FAIL += 1 + print(f" FAIL {name} {detail}") + + +def t_no_termios_falls_back(): + """Native Windows has no termios; the splash must simply use ANSI art.""" + original_import = builtins.__import__ + + def without_termios(name, *args, **kwargs): + if name == "termios": + raise ModuleNotFoundError("No module named 'termios'") + return original_import(name, *args, **kwargs) + + builtins.__import__ = without_termios + try: + check("missing termios disables graphics", kittygfx._query_tty(0) is False) + except Exception as exc: # the original Windows startup crash + check("missing termios does not escape", False, + f"{type(exc).__name__}: {exc}") + finally: + builtins.__import__ = original_import + + +def t_probe_failure_is_never_fatal(): + """Even an unexpected platform/probe error cannot prevent TUI startup.""" + original_query = kittygfx._query_tty + original_stdout = sys.__stdout__ + original_supported = kittygfx._supported + old_env = os.environ.pop("IDATUI_KITTY", None) + + class Tty: + def isatty(self): + return True + + def broken_query(): + raise RuntimeError("terminal API failed") + + try: + sys.__stdout__ = Tty() + kittygfx._query_tty = broken_query + kittygfx._supported = None + check("probe exception disables graphics", kittygfx.supported() is False) + check("failed result is cached", kittygfx.supported() is False) + except Exception as exc: + check("probe exception does not escape", False, + f"{type(exc).__name__}: {exc}") + finally: + kittygfx._query_tty = original_query + kittygfx._supported = original_supported + sys.__stdout__ = original_stdout + if old_env is not None: + os.environ["IDATUI_KITTY"] = old_env + + +def main() -> int: + for fn in (t_no_termios_falls_back, t_probe_failure_is_never_fatal): + print(f"\n{fn.__name__}") + fn() + print(f"\n{PASS} passed, {FAIL} failed") + return 1 if FAIL else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) |
