# 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}'"