diff --git a/main.py b/main.py index 4b766144..fa96a48e 100644 --- a/main.py +++ b/main.py @@ -256,6 +256,16 @@ def print_plan_details(plan_entry: Dict[str, Any]) -> None: print("") +def format_duration(seconds: float) -> str: + """Formats duration in a human-readable way (e.g., 2m 05s).""" + if seconds < 60: + return f"{seconds:.1f}s" + + minutes = int(seconds // 60) + rem_seconds = int(seconds % 60) + return f"{minutes}m {rem_seconds:02d}s" + + def countdown_timer(seconds: int, message: str = "Waiting") -> None: """Shows a countdown timer if strictly in a TTY, otherwise just sleeps.""" if not USE_COLORS: @@ -836,7 +846,7 @@ def verify_access_and_get_folders( MAX_RETRIES, wait_time, ) - time.sleep(wait_time) + countdown_timer(int(wait_time), "Retrying") def get_all_existing_rules( @@ -1044,7 +1054,7 @@ def create_folder( log.info( f"Folder '{sanitize_for_log(name)}' not found yet. Retrying in {wait_time}s..." ) - time.sleep(wait_time) + countdown_timer(int(wait_time), "Waiting for folder") log.error( f"Folder {sanitize_for_log(name)} was not found after creation and retries." @@ -1651,7 +1661,7 @@ def validate_profile_input(value: str) -> bool: f"{res['profile']:<{profile_col_width}} | " f"{res['folders']:>10} | " f"{res['rules']:>10,} | " - f"{res['duration']:>9.1f}s | " + f"{format_duration(res['duration']):>10} | " f"{status_color}{res['status_label']:<15}{Colors.ENDC}" ) total_folders += res["folders"] @@ -1682,7 +1692,7 @@ def validate_profile_input(value: str) -> bool: f"{'TOTAL':<{profile_col_width}} | " f"{total_folders:>10} | " f"{total_rules:>10,} | " - f"{total_duration:>9.1f}s | " + f"{format_duration(total_duration):>10} | " f"{total_status_color}{total_status_text:<15}{Colors.ENDC}" ) print("=" * table_width + "\n") diff --git a/tests/test_ux.py b/tests/test_ux.py index 311b7e91..0e74d8e5 100644 --- a/tests/test_ux.py +++ b/tests/test_ux.py @@ -2,6 +2,7 @@ import sys from unittest.mock import MagicMock import main +import pytest def test_countdown_timer_visuals(monkeypatch): """Verify that countdown_timer writes a progress bar to stderr.""" @@ -44,3 +45,16 @@ def test_countdown_timer_no_colors(monkeypatch): mock_stderr.write.assert_not_called() # Should call sleep exactly once with full seconds mock_sleep.assert_called_once_with(3) + +@pytest.mark.parametrize("seconds, expected", [ + (5.2, "5.2s"), + (0.0, "0.0s"), + (59.9, "59.9s"), + (60.0, "1m 00s"), + (65.5, "1m 05s"), + (125.0, "2m 05s"), + (3600.0, "60m 00s"), +]) +def test_format_duration(seconds, expected): + """Verify format_duration output for various inputs.""" + assert main.format_duration(seconds) == expected