File size: 3,177 Bytes
fcc874d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
"""Build the whole Gradio graph with the models stubbed out.

Catches component, parameter and event-wiring mistakes without a GPU, which is most of what
breaks a Space on first deploy. The model path itself is not covered here.

    uv run --no-project --python 3.12 --with pytest --with "gradio==5.50.0" --with spaces \
        --with pillow --with numpy --with imageio --with imageio-ffmpeg \
        pytest space/test_app_smoke.py -q
"""
import os
import sys
import types

import numpy as np
import pytest
from PIL import Image


@pytest.fixture(scope="module")
def app():
    """Import app.py with `zoom` replaced by a stub that skips the GPU work."""
    import geometry

    stub = types.ModuleType("zoom")
    stub.REPO = "dipta007/OracleZoom"
    stub.Models = type("Models", (), {"__init__": lambda self, weights=None: None})

    def fake_zoom(models, image, levels=4, upscale=4, center=(0.5, 0.5)):
        cur = geometry.resize_and_center_crop(image)
        yield 0, 1, "", cur, cur
        for i in range(levels):
            blurry = geometry.zoom_window(cur, upscale, center).resize(cur.size, Image.BICUBIC)
            yield i + 1, upscale ** (i + 1), f"tag {i}", blurry, blurry
            cur = blurry

    stub.zoom = fake_zoom
    sys.modules["zoom"] = stub
    import app as module
    return module


@pytest.fixture
def photo():
    rng = np.random.default_rng(0)
    return Image.fromarray(rng.integers(0, 255, (700, 900, 3), dtype=np.uint8))


def test_the_interface_builds(app):
    assert app.demo.blocks and app.demo.fns


def test_preview_returns_a_canvas_and_tolerates_no_image(app, photo):
    assert app.preview(photo, 4, 0.3, 0.7).size == (512, 512)
    assert app.preview(None, 4, 0.5, 0.5) is None


def test_declared_duration_grows_with_depth(app, photo):
    got = [app.estimate_duration(photo, n, 0.5, 0.5) for n in (1, 2, 3, 4)]
    assert got == sorted(got) and all(isinstance(v, int) for v in got)


def test_the_shipped_example_assets_exist(app):
    for path in [app.EXAMPLE_CLIP, *app.EXAMPLE_COMPARE, *(p for p, _ in app.EXAMPLE_LEVELS)]:
        assert os.path.getsize(path) > 1000, path
    assert [label for _, label in app.EXAMPLE_LEVELS] == ["input", "4x", "16x", "64x", "256x"]


def test_every_sample_named_for_the_examples_is_present(app):
    for name in app.SAMPLES:
        assert os.path.exists(f"samples/{name}.png")


def test_run_streams_one_update_per_level_then_the_clip(app, photo):
    yields = list(app.run(photo, 3, 0.5, 0.5))
    assert len(yields) == 5                       # entry level, 3 zoom steps, then the clip
    assert all(len(y) == 5 for y in yields)
    assert yields[0][1] is None                   # first yield clears any stale clip
    status, clip, gallery, compare, prompts = yields[-1]
    assert [label for _, label in gallery] == ["input", "4x", "16x", "64x"]
    assert compare is not None and len(compare) == 2
    assert prompts.count("tag") == 3
    try:
        assert os.path.getsize(clip) > 10_000
    finally:
        os.remove(clip)


def test_run_rejects_an_empty_upload(app):
    import gradio as gr
    with pytest.raises(gr.Error):
        next(app.run(None, 4, 0.5, 0.5))