Files
emoji/tests/conftest.py
Ismo Vuorinen a5222ec8fe feat: add pytest unit tests and CI workflow (#38)
* feat: add pytest unit tests and CI workflow

Add 67 tests covering both create_listing.py and dedup.py with shared
Pillow-based image fixtures. Add GitHub Actions workflow to run tests
on Python file changes.

* fix: address PR review feedback

- Use monkeypatch.chdir(tmp_path) so tests write to temp dirs instead
  of polluting the repo's README.md and index.html
- Strengthen unicode filename test to assert URL-encoded form (%C3%A9)
- Move hashlib import to module level in test_dedup.py
- Remove unused _zero_hash helper and Path import
- Prefix unused tuple unpacking variables with underscore

* fix: add docstrings and strengthen degenerate hash test

- Add docstrings to all test classes, methods, and helper functions
  to achieve 100% docstring coverage
- Strengthen test_skips_degenerate_hashes to assert groups == []
  instead of only checking for no-crash

* fix: use hardcoded MD5 digests and add fixture validation

- Replace hashlib.md5() calls with known digest constants to remove
  hashlib import from test module
- Add input validation to _make_gif fixture for clear error messages
  on empty colors or mismatched durations length
2026-03-02 01:03:35 +02:00

90 lines
2.3 KiB
Python

"""Shared test fixtures for emoji project tests."""
from pathlib import Path
import pytest
from PIL import Image
@pytest.fixture
def make_png():
"""Factory fixture: creates a small PNG image and returns its Path."""
def _make_png(
directory: Path,
name: str,
color: tuple = (255, 0, 0, 255),
size: tuple[int, int] = (4, 4),
) -> Path:
img = Image.new("RGBA", size, color)
path = directory / name
img.save(path, "PNG")
return path
return _make_png
@pytest.fixture
def make_gif():
"""Factory fixture: creates an animated GIF with multiple frames and returns its Path."""
def _make_gif(
directory: Path,
name: str,
colors: list[tuple],
durations: list[int],
size: tuple[int, int] = (4, 4),
) -> Path:
if not colors:
raise ValueError("colors must not be empty")
if len(durations) != len(colors):
raise ValueError(f"durations length ({len(durations)}) must match colors length ({len(colors)})")
frames = [Image.new("RGBA", size, c) for c in colors]
path = directory / name
frames[0].save(
path,
save_all=True,
append_images=frames[1:],
duration=durations,
loop=0,
)
return path
return _make_gif
@pytest.fixture
def make_jpg():
"""Factory fixture: creates a small JPEG image and returns its Path."""
def _make_jpg(
directory: Path,
name: str,
color: tuple = (255, 0, 0),
size: tuple[int, int] = (4, 4),
) -> Path:
img = Image.new("RGB", size, color)
path = directory / name
img.save(path, "JPEG")
return path
return _make_jpg
@pytest.fixture
def emoji_dir(tmp_path, make_png, make_gif, make_jpg):
"""Creates a temp directory with several named test images."""
d = tmp_path / "emoji"
d.mkdir()
make_png(d, "alpha.png", color=(255, 0, 0, 255))
make_png(d, "beta.png", color=(0, 255, 0, 255))
make_png(d, "gamma.png", color=(0, 0, 255, 255))
make_jpg(d, "delta.jpg", color=(128, 128, 0))
make_gif(
d,
"animated.gif",
colors=[(255, 0, 0, 255), (0, 255, 0, 255)],
durations=[100, 100],
)
return d