Spaces:
Running on Zero
Running on Zero
File size: 6,298 Bytes
7dff04f | 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 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | """WP-0: Tests for the Gradio application — build_app constructs successfully."""
from __future__ import annotations
import gradio as gr
class TestBuildApp:
def test_build_app_returns_blocks(self):
from app.main import build_app
demo = build_app()
assert isinstance(demo, gr.Blocks)
def test_build_app_has_expected_components(self):
from app.main import build_app
demo = build_app()
# Blocks should be a non-empty layout tree
assert demo is not None
def test_build_app_idempotent(self):
from app.main import build_app
demo1 = build_app()
demo2 = build_app()
assert isinstance(demo1, gr.Blocks)
assert isinstance(demo2, gr.Blocks)
class TestProcessNegativeWP13:
"""WP-13 D5: process_negative runs green with affine/flat_guard wiring."""
def test_process_negative_on_fixture(self):
import numpy as np
from PIL import Image
from app.main import process_negative
data = np.load("synth/fixtures/case_000.npz")
scan = data["scan"].astype(np.float32)
upload = Image.fromarray((scan * 255.0).clip(0, 255).astype(np.uint8))
out = process_negative(
upload,
film_stock="Generic",
physics_weight=1.0,
perceptual_weight=0.5,
num_candidates=3,
include_deep_prior=False,
full_res_export=False,
scan_type="Positive",
scan_calibration="auto-exposed",
auto_trim=False,
)
# 11-tuple return
assert len(out) == 11
positive_pil, recombined_pil, img_a, img_b, status, best_state, ranked, gallery, conf, fa, fb = out
assert img_a is not None and img_b is not None
assert ranked is not None and len(ranked) >= 1
assert "Error" not in (status or "")
# Affine ranking path should produce finite hybrid scores
assert np.isfinite(ranked[0].score.total_loss)
# Best must not be a flat solid pair when structured candidates exist
from app.scoring import _is_flat_pair
obs = np.asarray(positive_pil.convert("RGB"), dtype=np.float32) / 255.0
# Use preprocessed observed from best_state if available
if best_state and best_state.get("observed_rgb") is not None:
obs = best_state["observed_rgb"]
a = ranked[0].separation.image_a
b = ranked[0].separation.image_b
# With guard on, if anything non-flat exists best should not be flat
assert not _is_flat_pair(a, b, obs) or len(ranked) == 1
class TestAsymmetricWP14:
"""WP-14 D3: checkbox OFF byte-identical; ON offline asym_sub + note."""
def _upload(self):
import numpy as np
from PIL import Image
data = np.load("synth/fixtures/case_000.npz")
scan = data["scan"].astype(np.float32)
return Image.fromarray((scan * 255.0).clip(0, 255).astype(np.uint8))
def test_checkbox_off_byte_identical_population(self):
"""Default path (asym OFF) matches explicit asymmetric_recovery=False."""
import os
from app.main import process_negative
upload = self._upload()
kwargs = dict(
film_stock="Generic",
physics_weight=1.0,
perceptual_weight=0.5,
num_candidates=3,
include_deep_prior=False,
full_res_export=False,
scan_type="Positive",
scan_calibration="auto-exposed",
auto_trim=False,
)
# Ensure no accidental key influence
old = os.environ.pop("REPLICATE_API_TOKEN", None)
try:
out_default = process_negative(upload, **kwargs)
out_off = process_negative(upload, **kwargs, asymmetric_recovery=False)
finally:
if old is not None:
os.environ["REPLICATE_API_TOKEN"] = old
ranked_d = out_default[6]
ranked_o = out_off[6]
assert ranked_d is not None and ranked_o is not None
ids_d = [r.candidate_id for r in ranked_d]
ids_o = [r.candidate_id for r in ranked_o]
assert ids_d == ids_o
# No asym candidates when off
assert "asym_sub" not in ids_d
assert "asym_fill" not in ids_d
# Scores byte-identical
for a, b in zip(ranked_d, ranked_o):
assert a.candidate_id == b.candidate_id
assert abs(a.score.total_loss - b.score.total_loss) < 1e-12
def test_checkbox_on_offline_asym_sub_no_network(self):
"""ON without keys → asym_sub present; offline note; no network attempted."""
import os
from unittest.mock import patch
from app.main import process_negative, ASYM_CONSENT
upload = self._upload()
old_r = os.environ.pop("REPLICATE_API_TOKEN", None)
old_a = os.environ.pop("ANTHROPIC_API_KEY", None)
try:
with patch("app.asymmetric._replicate_inpaint") as mock_inpaint:
mock_inpaint.side_effect = AssertionError("network must not be called")
out = process_negative(
upload,
film_stock="Generic",
physics_weight=1.0,
perceptual_weight=0.5,
num_candidates=3,
include_deep_prior=False,
full_res_export=False,
scan_type="Positive",
scan_calibration="auto-exposed",
auto_trim=False,
asymmetric_recovery=True,
asymmetric_anchor="Auto",
)
mock_inpaint.assert_not_called()
finally:
if old_r is not None:
os.environ["REPLICATE_API_TOKEN"] = old_r
if old_a is not None:
os.environ["ANTHROPIC_API_KEY"] = old_a
status = out[4] or ""
ranked = out[6]
assert ranked is not None
ids = [r.candidate_id for r in ranked]
assert "asym_sub" in ids, f"asym_sub missing from {ids}"
assert "asym_fill" not in ids
assert "offline" in status.lower() or "no REPLICATE" in status or ASYM_CONSENT[:40] in status
assert "Asymmetric recovery" in status
|