183 lines
5.4 KiB
Python
183 lines
5.4 KiB
Python
# test_tqdm_mod.py
|
|
|
|
import io
|
|
import sys
|
|
from time import sleep
|
|
import pytest
|
|
import tqdm
|
|
from contextlib import redirect_stdout
|
|
import os
|
|
import re
|
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
from slic.utils.tqdm_mod import *
|
|
|
|
|
|
def extract_lines(output, label):
|
|
return [line for line in output.strip().splitlines() if label in line]
|
|
|
|
def get_bar_visual(line):
|
|
try:
|
|
return line.split("|")[1]
|
|
except IndexError:
|
|
return ""
|
|
|
|
# Tests
|
|
|
|
def test_complete_progress_bar():
|
|
f = io.StringIO()
|
|
with redirect_stdout(f):
|
|
for _ in tqdm_mod(range(3), desc="TestBar", file=f):
|
|
sleep(0.001)
|
|
lines = extract_lines(f.getvalue(), "TestBar")
|
|
last = lines[-1]
|
|
bar = get_bar_visual(last)
|
|
|
|
assert last.startswith("TestBar: 100%")
|
|
assert "3/3" in last
|
|
assert "Hz" in last
|
|
|
|
# Check that the bar us full
|
|
assert len(bar.replace("█", "").replace("#", "").strip()) == 0, f"Bar not full: '{bar}'"
|
|
|
|
|
|
def test_set_progress_multiple_points():
|
|
f = io.StringIO()
|
|
with redirect_stdout(f):
|
|
bar = tqdm_mod(total=5, desc="SetBar", file=f, miniters=1, mininterval=0)
|
|
bar.set(1.0)
|
|
bar.set(2.0)
|
|
bar.set(3.5)
|
|
bar.set(5.0)
|
|
bar.close()
|
|
|
|
lines = extract_lines(f.getvalue(), "SetBar")
|
|
|
|
for i, (expected_progress, expected_value) in enumerate([
|
|
("0%", "0/5"),
|
|
("20%", "1.0/5"),
|
|
("40%", "2.0/5"),
|
|
("70%", "3.5/5"),
|
|
("100%", "5.0/5"),
|
|
]):
|
|
assert re.search(r"^SetBar:\s+" + re.escape(expected_progress), lines[i])
|
|
assert expected_value in lines[i]
|
|
bar = get_bar_visual(lines[i])
|
|
|
|
def test_format_sizeof_alignment():
|
|
floats = [0.1, 1.3, 12.5, 99.9, 100.0, 100.1]
|
|
expected_outputs = [
|
|
" 0.1",
|
|
" 1.3",
|
|
" 12.5",
|
|
" 99.9",
|
|
"100.0",
|
|
"100.1",
|
|
]
|
|
|
|
for val, expected in zip(floats, expected_outputs):
|
|
result = format_sizeof(val)
|
|
assert result == expected, f"For {val}, expected '{expected}' but got '{result}'"
|
|
assert len(result) == 5, f"Length mismatch: got '{result}' of length {len(result)}"
|
|
|
|
|
|
# test format_sizeof rounding using tqdm
|
|
def test_float_alignment_in_bar():
|
|
# Capture the tqdm output into a string buffer
|
|
f = io.StringIO()
|
|
with redirect_stdout(f):
|
|
bar = tqdm_mod(total=100.12, desc="AlignBar", file=f, miniters=1, mininterval=0)
|
|
bar.set(1.3333)
|
|
bar.set(12.5)
|
|
bar.set(99.89)
|
|
bar.set(100.12)
|
|
bar.close()
|
|
|
|
# Extract lines containing the label
|
|
lines = extract_lines(f.getvalue(), "AlignBar")
|
|
|
|
# Expected formatted values using format_sizeof
|
|
expected_values = [
|
|
"1.3/100.1",
|
|
"12.5/100.1",
|
|
"99.9/100.1",
|
|
"100.1/100.1",
|
|
]
|
|
|
|
# Extract the actual padded float/total strings from the full lines
|
|
values = []
|
|
for line in lines:
|
|
match = re.search(r"(\d{1,3}\.\d)/100\.1", line)
|
|
if match:
|
|
values.append(match.group(0))
|
|
|
|
# Ensure raw 100.12 never appears : format_sizeof must have truncated it
|
|
assert all("100.12" not in line for line in lines), "Unrounded value '100.12' found in output!"
|
|
|
|
# Check all expected values appear rounded as expected by format_sizeof
|
|
for expected in expected_values:
|
|
assert expected in values, f"Missing expected value: {expected}"
|
|
|
|
# Check that all values are visually aligned, output with same length, to ensure that format_sizeof add the good number avec spaces
|
|
print("\n")
|
|
bar_segments = []
|
|
for line in lines:
|
|
match = re.search(r"^.*?\d{1,3}\.\d/100\.1", line)
|
|
if match:
|
|
seg = match.group(0)
|
|
# ignore starting automatique tqdm bar
|
|
if "0/100.1" not in seg:
|
|
bar_segments.append(seg)
|
|
print(seg)
|
|
|
|
lengths = [len(seg) for seg in bar_segments]
|
|
assert len(set(lengths)) == 1, f"Not aligned: {bar_segments} (lengths={lengths})"
|
|
|
|
|
|
|
|
def test_custom_unit():
|
|
f = io.StringIO()
|
|
with redirect_stdout(f):
|
|
for _ in tqdm_mod(range(4), desc="StepBar", unit="step", file=f):
|
|
sleep(0.001)
|
|
lines = extract_lines(f.getvalue(), "StepBar")
|
|
last = lines[-1]
|
|
bar = get_bar_visual(last)
|
|
|
|
assert last.startswith("StepBar: 100%")
|
|
assert "4/4" in last
|
|
assert "step/s" in last
|
|
assert len(bar.replace("█", "").replace("#", "").strip()) == 0, f"Bar not full: '{bar}'"
|
|
|
|
def test_clamp_above_total():
|
|
f = io.StringIO()
|
|
with redirect_stdout(f):
|
|
bar = tqdm_mod(total=10, desc="ClampBar", file=f)
|
|
bar.set(12)
|
|
bar.close()
|
|
lines = extract_lines(f.getvalue(), "ClampBar")
|
|
last = lines[-1]
|
|
bar = get_bar_visual(last)
|
|
|
|
assert last.startswith("ClampBar: 100%")
|
|
assert "10/10" in last
|
|
assert "Hz" in last
|
|
|
|
# Check that the bar us full
|
|
assert len(bar.replace("█", "").replace("#", "").strip()) == 0, f"Bar not full: '{bar}'"
|
|
|
|
def test_clamp_below_zero():
|
|
f = io.StringIO()
|
|
with redirect_stdout(f):
|
|
bar = tqdm_mod(total=10, desc="ClampBar", file=f)
|
|
bar.set(-1)
|
|
bar.close()
|
|
lines = extract_lines(f.getvalue(), "ClampBar")
|
|
last = lines[-1]
|
|
bar = get_bar_visual(last)
|
|
|
|
assert re.search(r"^ClampBar:\s+" + re.escape("0%"), last)
|
|
assert "0/10" in last
|
|
assert "Hz" in last
|
|
|
|
# Check that the bar us full
|
|
assert len(bar.replace(" ", "").strip()) == 0, f"Bar not empty: '{bar}'" |