Add incremental_svg parser (TDD) + fix pre-existing test regressions

New:
- incremental_svg.py: parse_to_valid(prefix) handles any partial SVG
  - Closes open tags, opens quotes, truncates partial tags
  - Strips reasoning text and markdown fences from prefix
  - stream_to_valid(chunks) generator for incremental updates
- tests/test_incremental_svg.py: 34 test cases including property-based

Fixed (regressions from earlier today):
- test_app.py: pass base_url and api_key to on_generate (new UI fields)
- test_app.py: on_mode_change defaults updated to n=1
- test_renderer.py: mock both resvg and cairosvg since resvg is now primary
- (manual fixes I did as owner, before letting streaming-client start)

All tests: 157 passed, 1 skipped, 0 failed
This commit is contained in:
Mavis
2026-06-13 15:54:11 +03:00
parent 2394eff1c0
commit 17a114e015
4 changed files with 744 additions and 8 deletions
+10 -2
View File
@@ -72,6 +72,8 @@ def _call_on_generate(**overrides: Any) -> Any:
image=None,
palette="",
model="test-model",
base_url="http://127.0.0.1:1234/v1",
api_key="lm-studio",
)
defaults.update(overrides)
# Патчим chat() так, чтобы on_generate не уходил в сеть и не упал уже
@@ -140,6 +142,8 @@ def test_on_generate_does_not_call_chat_on_precheck_fail():
image=None,
palette="",
model="x",
base_url="http://127.0.0.1:1234/v1",
api_key="lm-studio",
)
assert mock_chat.call_count == 0, (
"chat() был вызван, хотя pre-check должен был остановить поток"
@@ -158,6 +162,8 @@ def test_on_generate_does_not_call_chat_on_bad_mode():
image=None,
palette="",
model="x",
base_url="http://127.0.0.1:1234/v1",
api_key="lm-studio",
)
assert mock_chat.call_count == 0
@@ -190,6 +196,8 @@ def test_on_generate_with_valid_input_does_not_typeerror():
image=None,
palette="",
model="test",
base_url="http://127.0.0.1:1234/v1",
api_key="lm-studio",
)
except TypeError as exc:
pytest.fail(f"on_generate упал с TypeError на валидном входе: {exc}")
@@ -230,11 +238,11 @@ def test_on_mode_change_returns_icon_default_n():
update = on_mode_change("icon")
# gr.update — это dict-like объект, у него есть .value
assert update["value"] == 4
assert update["value"] == 1
def test_on_mode_change_returns_illustration_default_n():
from app import on_mode_change
update = on_mode_change("illustration")
assert update["value"] == 2
assert update["value"] == 1