This commit is contained in:
2026-06-15 03:15:08 +00:00
parent 0c8ab6018a
commit f2e98942ff
18 changed files with 1484 additions and 261 deletions
+35 -8
View File
@@ -1,18 +1,34 @@
from app.homelab.anima_prompt import (
build_character_image_prompt,
build_draw_self_prompt,
build_scene_tags_prompt,
looks_like_booru_tags,
)
from app.homelab.scene_tags import extract_scene_tags, looks_like_booru_tags, rule_based_scene_tags
def test_build_draw_self_prompt_includes_appearance():
bundle = build_draw_self_prompt("silver_hair, wolf_ears, blue_eyes")
def test_build_character_image_prompt_full_body():
bundle = build_character_image_prompt(
"wolfgirl, white_hair, pumped_up",
action_tags="full_body, standing, looking_at_viewer",
outfit_tags="apron",
environment_tags="indoors, soft_lighting",
)
assert "full_body" in bundle.positive
assert "standing" in bundle.positive
assert "apron" in bundle.positive
assert "pumped_up" not in bundle.positive
assert "upper_body" not in bundle.positive
assert "portrait" not in bundle.positive
def test_build_draw_self_prompt_with_action():
bundle = build_draw_self_prompt(
"silver_hair, wolf_ears",
action_tags="full_body, standing",
outfit_tags="",
)
assert "full_body" in bundle.positive
assert "silver_hair" in bundle.positive
assert "wolf_ears" in bundle.positive
assert "looking_at_viewer" in bundle.positive
assert "POV:" not in bundle.positive
assert ". " not in bundle.positive
assert "worst quality" in bundle.negative
def test_build_draw_self_prompt_lora():
@@ -23,3 +39,14 @@ def test_build_draw_self_prompt_lora():
def test_looks_like_booru_tags():
assert looks_like_booru_tags("1girl, smile, indoors")
assert not looks_like_booru_tags("draw a picture of a cat on the moon")
def test_rule_based_full_body_russian():
tags = rule_based_scene_tags("Очень, а в полный рост можешь?", [])
assert "full_body" in tags["action_tags"]
assert "portrait" not in tags["action_tags"]
def test_rule_based_outfit_apron():
tags = rule_based_scene_tags("", [{"role": "assistant", "content": "В фартуке стою у плиты"}])
assert "apron" in tags["outfit_tags"]
+69
View File
@@ -0,0 +1,69 @@
from unittest.mock import patch
from app.homelab.openmeteo import (
RECOMMENDED_SYNC_DOMAINS,
RECOMMENDED_SYNC_VARIABLES,
SYNC_HINT,
_coverage_sufficient,
_field_coverage,
_hourly_start_index,
build_weather_dashboard,
)
def test_hourly_start_index_from_current():
times = ["2026-06-14T00:00", "2026-06-14T01:00", "2026-06-14T18:00", "2026-06-14T19:00"]
assert _hourly_start_index(times, "2026-06-14T18:15") == 2
def test_coverage_sufficient():
assert _coverage_sufficient({"current": ["temperature_2m"], "hourly": ["temperature_2m"]}) is False
assert _coverage_sufficient(
{
"current": ["temperature_2m", "weather_code", "wind_speed_10m"],
"hourly": ["temperature_2m", "precipitation_probability", "weather_code"],
}
) is True
def test_field_coverage_partial():
raw = {
"current": {"time": "2026-06-14T18:15", "temperature_2m": 20.6},
"hourly": {
"time": ["2026-06-14T18:00", "2026-06-14T19:00"],
"temperature_2m": [20.0, 19.5],
"precipitation": [0.0, 0.0],
},
}
coverage = _field_coverage(raw)
assert coverage["current"] == ["temperature_2m"]
assert "temperature_2m" in coverage["hourly"]
assert "precipitation" in coverage["hourly"]
assert "weather_code" not in coverage["hourly"]
def test_build_weather_dashboard_includes_sync_hint():
fake_weather = {
"ok": True,
"location": "Test",
"data_source": "local",
"local_field_coverage": {"current": ["temperature_2m"], "hourly": ["temperature_2m"]},
"field_coverage": {"current": ["temperature_2m"], "hourly": ["temperature_2m"]},
"sync_hint": SYNC_HINT,
"current": {"temperature_c": 10, "conditions": "неизвестно"},
"hourly": [],
}
with patch("app.homelab.openmeteo.OpenMeteoClient") as mock_cls:
client = mock_cls.return_value
client.fetch_current_and_hourly.return_value = fake_weather
client.rain_summary.return_value = "ok"
client.cache_status.return_value = {"source": "local", "has_data": True, "cached": True, "ttl_sec": 300}
client.location_name = "Test"
client.lat = 1.0
client.lon = 2.0
client.base_url = "http://local"
client.cache_ttl = 300
result = build_weather_dashboard()
assert result["sync_hint"]
assert result["recommended_sync"]["domains"] == RECOMMENDED_SYNC_DOMAINS
assert result["recommended_sync"]["variables"] == RECOMMENDED_SYNC_VARIABLES
+16
View File
@@ -0,0 +1,16 @@
import pytest
from app.homelab.scene_tags import rule_based_scene_tags
@pytest.mark.parametrize(
"user_request,expected",
[
("full body please", "full_body"),
("нарисуй в полный рост", "full_body"),
("portrait close up", "upper_body"),
],
)
def test_rule_based_framing(user_request: str, expected: str):
tags = rule_based_scene_tags(user_request, [])
assert expected in tags["action_tags"]
+57
View File
@@ -0,0 +1,57 @@
from unittest.mock import patch
from app.homelab.openmeteo import build_weather_dashboard
def test_build_weather_dashboard_structure():
fake_weather = {
"ok": True,
"location": "Test City",
"current": {
"time": "2026-06-13T12:00",
"temperature_c": 18.5,
"apparent_temperature_c": 17.0,
"humidity_pct": 55,
"precipitation_mm": 0.0,
"wind_speed_kmh": 12.0,
"weather_code": 2,
"conditions": "переменная облачность",
},
"hourly": [
{
"time": "2026-06-13T12:00",
"temperature_c": 18.5,
"precipitation_mm": 0.0,
"precipitation_probability": 10,
"weather_code": 2,
"conditions": "переменная облачность",
}
],
}
with patch("app.homelab.openmeteo.OpenMeteoClient") as mock_cls:
client = mock_cls.return_value
client.fetch_current_and_hourly.return_value = fake_weather
client.rain_summary.return_value = "Существенных осадков в ближайшие часы не ожидается."
client.cache_status.return_value = {
"has_data": True,
"cached": True,
"fetched_at": 1.0,
"age_sec": 10,
"ttl_sec": 300,
"expires_in_sec": 290,
}
client.location_name = "Test City"
client.lat = 59.9
client.lon = 30.3
client.base_url = "http://openmeteo.test"
client.cache_ttl = 300
result = build_weather_dashboard(hours_ahead=6)
assert result["weather"]["ok"] is True
assert "[Погода]" in result["assistant_context"]
assert "None" not in result["assistant_context"]
assert "temperature_2m" in result["available_fields"]["current"]
assert "get_weather" in result["assistant_tools"]
assert result["config"]["location"] == "Test City"