Spaces:
Sleeping
Sleeping
| """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 | |
| 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 | |
| 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)) | |