From 3f2f50cdb99451a84710eca5d464863dc689cecd Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sun, 17 May 2026 22:25:48 -0400 Subject: [PATCH] fix(test): threshold test needs structured images (solid colors phash-collapse) Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/test_phash_dedup.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/test_phash_dedup.py b/tests/test_phash_dedup.py index cf5e603..3aeebce 100644 --- a/tests/test_phash_dedup.py +++ b/tests/test_phash_dedup.py @@ -52,6 +52,21 @@ def _write(path: Path, color, size): Image.new("RGB", size, color).save(path) +def _write_split(path: Path, orient, size): + """Structured (half black / half white) image — solid colors all + phash-collapse to the same value, so a real threshold test needs DCT + content. Vertical vs horizontal split = structurally far apart.""" + path.parent.mkdir(parents=True, exist_ok=True) + w, h = size + im = Image.new("L", size, 0) + px = im.load() + for y in range(h): + for x in range(w): + if (x / w if orient == "v" else y / h) >= 0.5: + px[x, y] = 255 + im.convert("RGB").save(path) + + def test_non_similar_imports_with_phash(importer, import_layout): import_root, _ = import_layout src = import_root / "a.png" @@ -127,15 +142,18 @@ def test_smaller_existing_is_superseded(importer, import_layout): def test_threshold_controls_match(importer, import_layout): + # Structurally distinct images (orthogonal splits) are far apart in + # phash space, so a tight threshold keeps them independent rather than + # collapsing the larger one into a supersede. import_root, _ = import_layout _set_threshold(importer, 0) a = import_root / "a.png" - _write(a, (100, 100, 100), (200, 200)) + _write_split(a, "v", (200, 200)) importer.import_one(a) b = import_root / "b.png" - _write(b, (104, 100, 100), (900, 900)) # tiny tweak + _write_split(b, "h", (900, 900)) # different structure, larger r = importer.import_one(b) - assert r.status == "imported" # threshold 0 → not treated as near-dup + assert r.status == "imported" # threshold 0 + far → independent import def test_import_task_maps_superseded_to_complete_and_requeues():