Files

125 lines
3.7 KiB
Python

#!/usr/bin/env python3
"""
Verify year-based final statistics aggregation in organize.py.
Creates test images with different EXIF years (and some without EXIF),
runs the organize function, and checks the output summary.
"""
from __future__ import annotations
import io
import sys
import tempfile
from pathlib import Path
# Make sure we can import organize
HERE = Path(__file__).parent.absolute()
if str(HERE) not in sys.path:
sys.path.insert(0, str(HERE))
from PIL import Image
from PIL.ExifTags import Base as ExifBase
from organize import organize
def _make_image(tmpdir: Path, name: str, year: int | None = None) -> Path:
"""Create a test image. If *year* is given, embed EXIF DateTimeOriginal."""
img = Image.new("RGB", (16, 16), color="red")
path = tmpdir / name
if year is not None:
exif_data = img.getexif()
exif_data[ExifBase.DateTimeOriginal] = f"{year:04d}:06:15 12:00:00"
img.save(path, exif=exif_data.tobytes())
else:
img.save(path) # no EXIF
img.close()
return path
def test_stats_summary_format() -> None:
"""Check that the summary section is printed after per-line output."""
import io
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
# Create images with known years
_make_image(tmp, "img_2023.jpg", year=2023)
_make_image(tmp, "img_2024a.jpg", year=2024)
_make_image(tmp, "img_2024b.jpg", year=2024)
_make_image(tmp, "img_2025.jpg", year=2025)
_make_image(tmp, "no_exif.jpg", year=None) # skipped in our test
# We just check it doesn't crash and returns correct exit
# We'll capture stdout to verify the summary
old_stdout = sys.stdout
captured = io.StringIO()
sys.stdout = captured
try:
organize(tmp, no_color=True)
finally:
sys.stdout = old_stdout
output = captured.getvalue()
# Verify the summary section exists
assert "=== Year Summary ===" in output, "Year summary header missing"
# Verify per-year counts
assert "2023: 1 entries" in output, "Year 2023 count wrong"
assert "2024: 2 entries" in output, "Year 2024 count wrong"
assert "2025: 1 entries" in output, "Year 2025 count wrong"
# Verify category counts
assert "Total with EXIF date:" in output
assert "Total with FS date:" in output
assert "Total skipped:" in output
# Summary appears after per-line output (no interleaving check via text position)
print("test_stats_summary_format: PASS")
def test_stats_counts_match() -> None:
"""Verify that category totals add up correctly."""
with tempfile.TemporaryDirectory() as td:
tmp = Path(td)
# 3 with EXIF, 1 without (uses FS date via mtime)
_make_image(tmp, "a_2022.jpg", year=2022)
_make_image(tmp, "b_2023.jpg", year=2023)
_make_image(tmp, "c_2024.jpg", year=2024)
# Image without EXIF — falls back to FS date
img = Image.new("RGB", (8, 8), color="blue")
p = tmp / "no_exif.jpg"
img.save(p)
img.close()
old_stdout = sys.stdout
captured = io.StringIO()
sys.stdout = captured
try:
organize(tmp, no_color=True)
finally:
sys.stdout = old_stdout
output = captured.getvalue()
# Verify counts
assert "Total with EXIF date: 3" in output
assert "Total with FS date: 1" in output
assert "Total skipped: 0" in output
assert "Total processed: 4" in output
print("test_stats_counts_match: PASS")
if __name__ == "__main__":
test_stats_summary_format()
test_stats_counts_match()
print("All stats tests passed!")