File size: 2,641 Bytes
acc1fa9
 
 
 
 
 
 
 
 
be27f23
acc1fa9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ee6a661
acc1fa9
 
 
 
 
 
be27f23
 
5911228
be27f23
 
 
5911228
 
acc1fa9
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
"""Self-check for the demo's pure helpers: `python test_app.py`.

The model-running paths need torch and the Hub; these are the bits that can be
silently wrong (frame ordering, padded-index mapping, box geometry).
"""

import tempfile
from pathlib import Path

from app import build_animation, collect_frames, draw_boxes, input_index, tube_color
from PIL import Image


def test_input_index():
    # No padding: identity.
    assert [input_index(i, []) for i in range(3)] == [0, 1, 2]
    # Frames 0 and 3 are synthetic duplicates; the rest shift down past them.
    assert input_index(0, [0, 3]) is None
    assert input_index(1, [0, 3]) == 0
    assert input_index(2, [0, 3]) == 1
    assert input_index(3, [0, 3]) is None
    assert input_index(4, [0, 3]) == 2


def test_collect_frames_orders_by_filename():
    with tempfile.TemporaryDirectory() as tmp:
        work = Path(tmp)
        unordered = [str(work / "b_02.jpg"), str(work / "a_01.jpg")]
        assert [p.name for p in collect_frames(unordered, None, 8, work)] == [
            "a_01.jpg",
            "b_02.jpg",
        ]


def test_collect_frames_rejects_non_images():
    with tempfile.TemporaryDirectory() as tmp:
        work = Path(tmp)
        try:
            collect_frames([str(work / "notes.txt")], None, 8, work)
        except Exception as e:
            assert "notes.txt" in str(e)
        else:
            raise AssertionError("expected a rejection")


def test_draw_boxes_marks_the_box_pixels():
    with tempfile.TemporaryDirectory() as tmp:
        path = Path(tmp) / "frame.jpg"
        Image.new("RGB", (200, 100), "black").save(path)
        # Centred box, half the frame: outline lands on the mid-height edges.
        out = draw_boxes(path, [((0.5, 0.5, 0.5, 0.5), 0.42, "#ff0000")])
        assert out.size == (200, 100)
        assert out.getpixel((50, 50))[0] > 100, "left edge should be drawn"
        assert out.getpixel((150, 50))[0] > 100, "right edge should be drawn"
        assert out.getpixel((100, 50)) == (0, 0, 0), "box interior stays untouched"


def test_build_animation_is_animated_and_downscaled():
    assert build_animation([]) is None
    frames = [Image.new("RGB", (1800, 900), c) for c in ("red", "green", "blue")]
    anim = Image.open(build_animation(frames))
    assert anim.n_frames == 3
    assert anim.size == (900, 450), "wider frames scale down to ANIM_MAX_WIDTH"


def test_tube_color_cycles():
    assert tube_color(0) == tube_color(10) != tube_color(1)


if __name__ == "__main__":
    for name, fn in sorted(globals().items()):
        if name.startswith("test_"):
            fn()
            print(f"ok {name}")