File size: 2,171 Bytes
2857cf3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
from __future__ import annotations

from io import StringIO

import pytest
from rich.console import Console

from kneiff.cli.progress import CliProgress
from kneiff.progress import ProgressUpdate, report_progress


def test_progress_update_rejects_negative_work() -> None:
    with pytest.raises(ValueError, match="advance"):
        ProgressUpdate("invalid", advance=-1)
    with pytest.raises(ValueError, match="total"):
        ProgressUpdate("invalid", additional_total=-1)


def test_report_progress_sends_one_immutable_event() -> None:
    updates: list[ProgressUpdate] = []

    report_progress(
        updates.append,
        "Discovered work",
        advance=2,
        additional_total=3,
    )

    assert updates == [
        ProgressUpdate(
            description="Discovered work",
            advance=2,
            additional_total=3,
        )
    ]


def test_cli_progress_applies_dynamic_total_in_terminal() -> None:
    output = StringIO()
    console = Console(
        file=output,
        force_terminal=True,
        color_system=None,
        width=100,
    )

    with CliProgress("Preparing", console=console) as progress:
        assert progress.is_terminal is True
        progress.apply(
            ProgressUpdate(
                description="Image 1/2",
                advance=1,
                additional_total=2,
            )
        )
        progress.apply(ProgressUpdate(description="Image 2/2", advance=1))

    assert progress.total == 2
    rendered = output.getvalue()
    assert "Image 2/2" in rendered
    assert "2/2" in rendered


def test_cli_progress_is_silent_when_redirected_except_explicit_logs() -> None:
    output = StringIO()
    console = Console(file=output, force_terminal=False, color_system=None)

    with CliProgress("Hidden", total=1, console=console) as progress:
        assert progress.is_terminal is False
        progress.apply(ProgressUpdate(description="Done", advance=1))
        progress.log("suppressed", echo=False)

    assert output.getvalue() == ""

    with CliProgress("Hidden", console=console) as progress:
        progress.log("visible")

    assert output.getvalue() == "visible\n"