"""HUD rendering - pure functions, no Gradio runtime or model needed.""" import pytest pytest.importorskip("gradio") from jailbreak_dojo.levels import load_levels # noqa: E402 from jailbreak_dojo.ui import ( # noqa: E402 FORGE_PRESETS, _meter, _parse_forge_query, _share_link, _shields_panel, _trail, make_custom_level, render_hud, shield_card, ) LEVELS = load_levels() def test_trail_marks_done_current_and_locked(): html = _trail(LEVELS, current_id=3, won_levels=[1, 2]) assert html.count("node done") == 2 assert html.count("node current") == 1 assert html.count("node locked") == 2 # levels 4 and 5 def test_shields_panel_shows_open_gate_at_l1(): assert "gate stands open" in _shields_panel(LEVELS[0]) # L1: no defenses def test_shields_panel_lights_all_five_at_l5(): # regex + crescendo + wardings + ML + warden assert _shields_panel(LEVELS[4]).count("chip on") == 5 def test_shields_panel_is_honest_when_ml_did_not_load(): assert "degraded to regex" in _shields_panel(LEVELS[4], ml_ok=False) def test_meter_flips_to_over_budget_past_1000(): assert 'class="fill"' in _meter(300) assert "fill over" in _meter(1200) def test_render_hud_includes_level_palette_and_panels(): html = render_hud(LEVELS, LEVELS[4], won_levels=[1, 2, 3, 4], tokens=1180) assert "level-5" in html and 'class="trail"' in html assert 'class="meter"' in html and 'class="shields"' in html def test_shield_card_names_the_ml_sentinel(): class _S: stage, subcategory, reason = "model", "span_model", "looks like an injection" assert "Sentinel (ML)" in shield_card(_S()) def test_shield_card_escapes_html_in_evidence(): class _S: stage, subcategory, reason = "regex", "