Files
glances/tests/test_plugin_folders_render_curses_v5.py
2026-07-19 14:50:58 +02:00

158 lines
5.3 KiB
Python
Executable File

#!/usr/bin/env python
#
# Glances - An eye on your system
#
# SPDX-FileCopyrightText: 2026 Nicolas Hennion <nicolas@nicolargo.com>
#
# SPDX-License-Identifier: LGPL-3.0-only
#
"""Glances v5 — tests for the folders plugin's curses renderer."""
from __future__ import annotations
from glances.outputs.curses_renderer_v5 import ColorRole
from glances.plugins.folders.render_curses_v5 import render
def _payload(items, levels=None):
return {"data": items, "_levels": levels or {}}
def _folder(path="/tmp", size=1000, errno=0):
return {"path": path, "size": size, "errno": errno}
def test_empty_returns_nothing():
assert render(_payload([])) == []
def test_missing_data_key_returns_nothing():
assert render({}) == []
def test_title_row_is_folders_header():
rows = render(_payload([_folder()]))
assert rows[0].cells[0].text.strip() == "FOLDERS"
assert rows[0].cells[0].color == ColorRole.HEADER
assert rows[0].cells[0].bold is True
assert len(rows[0].cells) == 1 # no column headers — v4 parity
def test_one_row_per_folder():
rows = render(_payload([_folder("/tmp"), _folder("/home")]))
assert len(rows) == 3 # title + 2 folders
def test_short_path_not_truncated():
rows = render(_payload([_folder("/tmp")]))
assert rows[1].cells[0].text.strip() == "/tmp"
def test_long_path_truncated_from_left_with_underscore():
long_path = "/very/long/path/that/exceeds/the/name/column/width/tail-marker"
rows = render(_payload([_folder(long_path)]))
cell_text = rows[1].cells[0].text
assert cell_text.startswith("_")
assert cell_text.strip().endswith("tail-marker")
assert len(cell_text) == 24 # _NAME_MAX_WIDTH
def test_path_at_exactly_name_max_width_not_truncated():
path_24 = "/" + "a" * 23 # exactly _NAME_MAX_WIDTH (24) chars
assert len(path_24) == 24
rows = render(_payload([_folder(path_24)]))
cell_text = rows[1].cells[0].text
assert cell_text == path_24
assert not cell_text.startswith("_")
def test_path_one_over_name_max_width_is_truncated():
path_25 = "/" + "a" * 24 # one over _NAME_MAX_WIDTH (24) chars
assert len(path_25) == 25
rows = render(_payload([_folder(path_25)]))
cell_text = rows[1].cells[0].text
assert cell_text.startswith("_")
assert len(cell_text) == 24
def test_size_formatted_and_right_aligned():
rows = render(_payload([_folder("/tmp", size=125 * 1024 * 1024)]))
size_text = rows[1].cells[1].text
assert len(size_text) == 9
assert size_text == " 125.0M" # right-justified: padding on the left
assert size_text.rstrip() == size_text # no trailing padding
def test_errno_prefixes_question_mark():
rows = render(_payload([_folder("/missing", size=0, errno=2)]))
size_text = rows[1].cells[1].text
assert len(size_text) == 9
assert size_text == "? 0B" # right-justified: "0B" preceded by spaces
assert size_text.startswith("?")
assert size_text.rstrip() == size_text # no trailing padding
def test_size_none_renders_dash_and_stays_padded():
rows = render(_payload([_folder("/tmp", size=None)]))
size_text = rows[1].cells[1].text
assert len(size_text) == 9
assert size_text == " -" # right-justified: "-" preceded by 8 spaces
def test_size_none_with_errno_prefixes_question_mark():
rows = render(_payload([_folder("/missing", size=None, errno=2)]))
size_text = rows[1].cells[1].text
assert len(size_text) == 9
assert size_text == "? -"
def test_size_colour_careful():
levels = {"/tmp": {"size": {"level": "careful", "prominent": False}}}
rows = render(_payload([_folder("/tmp", size=5_000_000)], levels))
assert rows[1].cells[1].color == ColorRole.CAREFUL
def test_errno_renders_bold_default_not_alert_coloured():
# v4 parity: a broken folder is never alert-coloured, even if a
# (synthetic, shouldn't-happen) _levels entry is present for its path —
# errno rendering must win outright.
levels = {"/missing": {"size": {"level": "critical", "prominent": True}}}
rows = render(_payload([_folder("/missing", size=0, errno=2)], levels))
cell = rows[1].cells[1]
assert cell.color == ColorRole.DEFAULT
assert cell.bold is True
assert cell.prominent is False
def test_errno_renders_bold_default_with_no_levels_entry():
# The real-world case: the model emits no _levels entry at all for a
# broken folder.
rows = render(_payload([_folder("/missing", size=0, errno=2)], {}))
cell = rows[1].cells[1]
assert cell.color == ColorRole.DEFAULT
assert cell.bold is True
def test_no_level_entry_defaults_to_default_color():
rows = render(_payload([_folder("/tmp")]))
assert rows[1].cells[1].color == ColorRole.DEFAULT
def test_size_prominent_forwarded_when_levels_carry_it():
levels = {"/tmp": {"size": {"level": "critical", "prominent": True}}}
rows = render(_payload([_folder("/tmp", size=5_000_000)], levels))
assert rows[1].cells[1].prominent is True
def test_size_prominent_not_set_when_levels_lack_it():
levels = {"/tmp": {"size": {"level": "critical"}}}
rows = render(_payload([_folder("/tmp", size=5_000_000)], levels))
assert rows[1].cells[1].prominent is False
def test_render_works_with_one_positional_arg():
# A bare render(payload) call must work — fields_desc/view both default.
rows = render(_payload([_folder()]))
assert rows