import numpy as np from edge.models import BBox from edge.snapshot import RingBuffer, FaceBlurrer, Snapshotter def _frame(val=128): return np.full((64, 64, 3), val, dtype=np.uint8) def test_ringbuffer_keeps_recent(): rb = RingBuffer(maxlen=3) for i in range(5): rb.push(float(i), _frame(i)) assert len(rb.frames) == 3 assert rb.frames[-1][0] == 4.0 def test_timeline_picks_frames_nearest_to_offsets(): rb = RingBuffer(maxlen=90) for i in range(6): # t = 0..5, 1초 간격 rb.push(float(i), _frame(i * 10), [BBox(i, 0, i + 1, 1)]) frames, boxes = rb.timeline(now=5.0, offsets_s=(2.5, 1.0, 0.0)) assert len(frames) == 3 # 과거→현재 순: 목표 2.5/4.0/5.0초에 가장 가까운 t=2(또는 3), 4, 5 assert frames[-1][0, 0, 0] == 50 # 마지막은 현재 프레임 assert boxes[-1][0].x1 == 5 # 각 프레임의 '자기 시점' 블러 박스 assert frames[0][0, 0, 0] < frames[1][0, 0, 0] < frames[2][0, 0, 0] def test_timeline_short_buffer_returns_fewer_without_duplicates(): rb = RingBuffer(maxlen=90) rb.push(0.0, _frame(10), []) frames, boxes = rb.timeline(now=0.0, offsets_s=(2.5, 1.0, 0.0)) assert len(frames) == 1 # 기동 직후: 있는 프레임 하나만, 중복 없음 assert len(boxes) == 1 def test_face_blur_changes_region(): fb = FaceBlurrer() f = _frame(0) f[0:10, 0:10] = 255 out = fb.blur(f.copy(), [BBox(0, 0, 10, 10)]) assert out is not None assert out.shape == f.shape def test_snapshotter_returns_jpeg_bytes(): snap = Snapshotter(FaceBlurrer()) imgs = snap.capture([_frame(100), _frame(120)], [[], []]) assert 1 <= len(imgs) <= 3 assert imgs[0][:2] == b"\xff\xd8" # JPEG magic