105 lines
2.7 KiB
Python
105 lines
2.7 KiB
Python
import io
|
|||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "tools"))
|
||
|
|
|
||
|
|
import rsync_progress # noqa: E402
|
||
|
|
|
||
|
|
|
||
|
|
class NotATerminal(io.StringIO):
|
||
|
|
def isatty(self):
|
||
|
|
return False
|
||
|
|
|
||
|
|
|
||
|
|
class Terminal(io.StringIO):
|
||
|
|
def isatty(self):
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def run(lines, total=0, out=None):
|
||
|
|
out = out or NotATerminal()
|
||
|
|
rsync_progress.main(["--total", str(total)], stream=io.StringIO(lines), out=out)
|
||
|
|
return out.getvalue()
|
||
|
|
|
||
|
|
|
||
|
|
def test_the_artist_and_album_are_pulled_from_the_path():
|
||
|
|
assert rsync_progress.album_of("Pendulum/Immersion/01 - Watercolour.mp3") == (
|
||
|
|
"Pendulum / Immersion"
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def test_a_shallower_path_degrades_rather_than_failing():
|
||
|
|
assert rsync_progress.album_of("Pendulum/loose.mp3") == "Pendulum"
|
||
|
|
assert rsync_progress.album_of("loose.mp3") == ""
|
||
|
|
|
||
|
|
|
||
|
|
def test_directories_are_not_counted():
|
||
|
|
"""rsync reports them too, and counting them puts the percentage past 100."""
|
||
|
|
output = run("Artist/\nArtist/Album/\nArtist/Album/track.mp3\n", total=1)
|
||
|
|
|
||
|
|
assert "1 / 1" in output
|
||
|
|
assert "100%" in output
|
||
|
|
|
||
|
|
|
||
|
|
def test_the_percentage_tracks_the_total():
|
||
|
|
output = run("".join(f"A/B/{i}.mp3\n" for i in range(5)), total=10)
|
||
|
|
|
||
|
|
assert "5 / 10" in output
|
||
|
|
assert " 50%" in output
|
||
|
|
|
||
|
|
|
||
|
|
def test_without_a_total_it_counts_instead_of_guessing():
|
||
|
|
output = run("A/B/one.mp3\nA/B/two.mp3\n")
|
||
|
|
|
||
|
|
assert "2 files" in output
|
||
|
|
assert "%" not in output
|
||
|
|
|
||
|
|
|
||
|
|
def test_a_final_line_is_always_printed():
|
||
|
|
"""Otherwise the last state of a rewriting line is whatever it happened to
|
||
|
|
be when the interval last elapsed."""
|
||
|
|
output = run("A/B/one.mp3\n", total=1)
|
||
|
|
|
||
|
|
assert output.endswith("\n")
|
||
|
|
assert "1 / 1" in output
|
||
|
|
|
||
|
|
|
||
|
|
def test_nothing_transferred_still_reports():
|
||
|
|
output = run("", total=0)
|
||
|
|
|
||
|
|
assert "0 files" in output
|
||
|
|
|
||
|
|
|
||
|
|
def test_a_log_gets_no_carriage_returns():
|
||
|
|
"""A non-terminal filling with \\r and escape codes is unreadable."""
|
||
|
|
output = run("".join(f"A/B/{i}.mp3\n" for i in range(50)), total=50)
|
||
|
|
|
||
|
|
assert "\r" not in output
|
||
|
|
assert "\033" not in output
|
||
|
|
|
||
|
|
|
||
|
|
def test_a_terminal_rewrites_one_line():
|
||
|
|
output = run("".join(f"A/B/{i}.mp3\n" for i in range(50)), total=50, out=Terminal())
|
||
|
|
|
||
|
|
assert "\r\033[2K" in output
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.parametrize(
|
||
|
|
("text", "width", "expected"),
|
||
|
|
[
|
||
|
|
("short", 20, "short"),
|
||
|
|
("King Gizzard / PetroDragonic Apocalypse", 20, "…agonic Apocalypse"),
|
||
|
|
],
|
||
|
|
)
|
||
|
|
def test_long_labels_are_trimmed_from_the_left(text, width, expected):
|
||
|
|
"""The album is the informative end, so the artist is what gets cut."""
|
||
|
|
trimmed = rsync_progress.fit(text, width)
|
||
|
|
|
||
|
|
assert len(trimmed) <= width
|
||
|
|
if len(text) > width:
|
||
|
|
assert trimmed.startswith("…")
|
||
|
|
assert text.endswith(trimmed.lstrip("…"))
|