"""Offline unit tests: no network, no models. Exercise the pure-Python core.""" from __future__ import annotations import numpy as np from PIL import Image from veil_pgd.fitness.embed import cosine from veil_pgd.fitness.objective import combined_fitness, stealth_penalty from veil_pgd.render import render from veil_pgd.stealth import evaluate_stealth from veil_pgd.stealth.gate import StealthThresholds from veil_pgd.types import RenderSpec, StealthReport from veil_pgd.util.labels import normalize_label, parse_label_json def _img(seed=0): rng = np.random.default_rng(seed) return Image.fromarray(rng.integers(90, 140, (256, 256, 3)).astype("uint8")) def test_normalize_label(): assert normalize_label(" The Golden Retriever! ") == "golden retriever" def test_parse_label_json(): assert parse_label_json('{"label": "Fire Hydrant"}') == "fire hydrant" assert parse_label_json('noise {"label":"cat"} more') == "cat" assert parse_label_json("no json here") is None def test_cosine(): assert abs(cosine([1, 0], [1, 0]) - 1.0) < 1e-9 assert abs(cosine([1, 0], [0, 1])) < 1e-9 def test_render_and_stealth_faint_passes_gate(): img = _img() spec = RenderSpec(text="fire hydrant", font_px=14, alpha=0.2) out = render(img, spec) assert out.size == img.size rep = evaluate_stealth(img, out) # no lpips_fn -> lpips skipped assert rep.psnr > 30 assert rep.passed def test_high_opacity_hurts_stealth(): img = _img() faint = evaluate_stealth(img, render(img, RenderSpec(text="x" * 20, font_px=14, alpha=0.15))) loud = evaluate_stealth(img, render(img, RenderSpec(text="x" * 20, font_px=24, alpha=1.0, color_strategy="fixed", fixed_rgb=(255, 0, 0)))) assert loud.psnr < faint.psnr def test_combined_fitness_penalizes_gate_failures(): th = StealthThresholds() good = StealthReport(psnr=40, ssim=0.99, lpips=0.01, delta_e_p95=1.0, passed=True) bad = StealthReport(psnr=20, ssim=0.5, lpips=0.5, delta_e_p95=10.0, passed=False) assert stealth_penalty(good, th) == 0.0 assert stealth_penalty(bad, th) > 0.0 f_good = combined_fitness(0.8, 0.9, good, th) f_bad = combined_fitness(0.8, 0.9, bad, th) assert f_good > f_bad