Files
wehub-resource-sync 542cfa195c
CI / Frontend build (push) Failing after 9m6s
CI / Plugin validate (push) Failing after 9m27s
CI / Python lint (push) Failing after 16m1s
CI / Tests (push) Successful in 18m0s
Deploy / deploy (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:27 +08:00

89 lines
3.3 KiB
Python

"""Chunking tests — 2D tiling keeps every chunk within the render width.
The embedder skips any chunk wider than the render width (875px), so the chunker
must split wide tiles (PDFs, landscape pages) along the width as well as the
height. Narrow web tiles (<= viewport_width) must keep their old single-column
height-strip layout unchanged so existing indexes stay reproducible.
"""
import json
from PIL import Image
from pixelrag_embed.chunk import CHUNK_HEIGHT, chunk_article
def _make_tile(dir_path, w, h, viewport_width=None):
dir_path.mkdir(parents=True, exist_ok=True)
Image.new("RGB", (w, h), (255, 255, 255)).save(dir_path / "tile_0000.png")
meta = {"tiles": ["tile_0000.png"], "tile_height": 8192}
if viewport_width is not None:
meta["viewport_width"] = viewport_width
(dir_path / "tiles.json").write_text(json.dumps(meta))
return dir_path
def _chunks(dir_path):
return json.loads((dir_path / "chunks.json").read_text())["chunks"]
def test_narrow_tile_unchanged(tmp_path):
# 875-wide tall web tile: single-column height strips, exactly as before.
d = _make_tile(tmp_path / "a.png.tiles", 875, 3000)
chunk_article(str(d))
cs = _chunks(d)
assert [c["file"] for c in cs] == [
"chunk_0000_00.png",
"chunk_0000_01.png",
"chunk_0000_02.png",
]
assert [c["y_offset"] for c in cs] == [0, CHUNK_HEIGHT, 2 * CHUNK_HEIGHT]
assert all(c["x_offset"] == 0 and c["width"] == 875 for c in cs)
def test_short_narrow_tile_copied_whole(tmp_path):
# <= viewport_width and <= CHUNK_HEIGHT: one chunk, tile copied verbatim.
d = _make_tile(tmp_path / "a.png.tiles", 600, 500)
chunk_article(str(d))
cs = _chunks(d)
assert len(cs) == 1
assert cs[0]["file"] == "chunk_0000_00.png"
assert cs[0]["width"] == 600 and cs[0]["height"] == 500
def test_wide_tile_split_into_columns(tmp_path):
# Letter PDF at 200 DPI (~1700x2200): 2 columns x 3 rows, all <= 875 wide.
d = _make_tile(tmp_path / "a.png.tiles", 1700, 2200)
chunk_article(str(d))
cs = _chunks(d)
assert len(cs) == 6
assert all(c["width"] <= 875 for c in cs)
# every produced chunk file is on disk at its recorded size
for c in cs:
img = Image.open(d / c["file"])
assert img.size == (c["width"], c["height"])
# columns are full viewport_width (875) with the remainder last, covering
# the full width with no gaps
row0 = sorted((c for c in cs if c["y_offset"] == 0), key=lambda c: c["x_offset"])
assert [c["width"] for c in row0] == [875, 825]
assert row0[0]["x_offset"] == 0
assert row0[-1]["x_offset"] + row0[-1]["width"] == 1700
def test_very_wide_tile_never_exceeds_width(tmp_path):
# 19-inch landscape figure (3800px): many columns, still all <= 875, no skips.
d = _make_tile(tmp_path / "a.png.tiles", 3800, 2200)
chunk_article(str(d))
cs = _chunks(d)
assert cs, "wide tile must still produce chunks (not be skipped)"
assert max(c["width"] for c in cs) <= 875
def test_short_wide_tile_splits_width(tmp_path):
# Short but wide (was copied whole -> too wide -> skipped). Now splits width.
d = _make_tile(tmp_path / "a.png.tiles", 1700, 500)
chunk_article(str(d))
cs = _chunks(d)
assert len(cs) == 2
assert all(c["width"] <= 875 and c["height"] == 500 for c in cs)