Source code for tests.test_humanize
# Copyright Kevin Deldycke <[email protected]> and contributors.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""Tests for the human-readable renderings of machine quantities."""
from __future__ import annotations
import time
from datetime import date, datetime, timezone
import pytest
from repomatic.humanize import (
SECONDS_PER_DAY,
format_age,
format_countdown,
format_elapsed,
format_file_size,
utc_midnight,
)
[docs]
@pytest.mark.parametrize(
("size_bytes", "expected"),
[
(0, "0 B"),
(512, "512 B"),
(1023, "1,023 B"),
(1024, "1.0 KB"),
(1536, "1.5 KB"),
(10240, "10.0 KB"),
(1048576, "1.0 MB"),
(1572864, "1.5 MB"),
(1073741824, "1.0 GB"),
],
)
def test_format_file_size(size_bytes: int, expected: str) -> None:
"""Human-readable file size formatting."""
assert format_file_size(size_bytes) == expected
[docs]
@pytest.mark.parametrize(
("days_ago", "expected"),
[
(0, "today"),
(1, "1 day"),
(2, "2 days"),
(30, "30 days"),
],
)
def test_format_age(days_ago: int, expected: str) -> None:
"""An mtime renders as whole days, singular for one."""
# Offset by a few seconds so a boundary case never rounds up mid-test.
mtime = time.time() - days_ago * SECONDS_PER_DAY - 5
assert format_age(mtime) == expected
def _utc(year, month, day, hour=0, minute=0):
"""Shorthand for an aware UTC instant."""
return datetime(year, month, day, hour, minute, tzinfo=timezone.utc)
[docs]
def test_utc_midnight_starts_the_day() -> None:
"""A date carries no time of day, so it enters a countdown at midnight."""
assert utc_midnight(date(2026, 6, 21)) == _utc(2026, 6, 21)
[docs]
@pytest.mark.parametrize(
("deadline", "reference", "expected"),
[
(_utc(2026, 6, 25), _utc(2026, 6, 21), "2026-06-25 (in 4 days)"),
# Hours left, not a whole day: the countdown says so instead of
# collapsing to `just now`, which reads as a deadline already passed.
(_utc(2026, 6, 21, 14), _utc(2026, 6, 21, 9), "2026-06-21 (in 5 hours)"),
(_utc(2026, 6, 21, 9, 30), _utc(2026, 6, 21, 9), "2026-06-21 (in 30 minutes)"),
# Already passed: the countdown would read as noise, so it is dropped.
(_utc(2026, 6, 20), _utc(2026, 6, 21), "2026-06-20"),
(_utc(2026, 6, 21, 9), _utc(2026, 6, 21, 9), "2026-06-21"),
],
)
def test_format_countdown(deadline, reference, expected) -> None:
"""A countdown follows the precision of the instants it is given."""
assert format_countdown(deadline, reference) == expected
[docs]
@pytest.mark.parametrize(
("instant", "reference", "expected"),
[
(_utc(2026, 6, 21), _utc(2026, 6, 25), "2026-06-21 (4 days ago)"),
# Hours, not a whole day: the mirror of the countdown case above.
(_utc(2026, 6, 21, 9), _utc(2026, 6, 21, 14), "2026-06-21 (5 hours ago)"),
(_utc(2026, 6, 21, 9), _utc(2026, 6, 21, 9), "2026-06-21 (just now)"),
# Still ahead: `in 4 days` would contradict the column this sits in.
(_utc(2026, 6, 25), _utc(2026, 6, 21), "2026-06-25"),
],
)
def test_format_elapsed(instant, reference, expected) -> None:
"""The past-facing mirror drops its phrase in the other direction."""
assert format_elapsed(instant, reference) == expected